summaryrefslogtreecommitdiffstats
path: root/tcllib/modules/stringprep
diff options
context:
space:
mode:
Diffstat (limited to 'tcllib/modules/stringprep')
-rw-r--r--tcllib/modules/stringprep/ChangeLog78
-rw-r--r--tcllib/modules/stringprep/pkgIndex.tcl5
-rw-r--r--tcllib/modules/stringprep/stringprep.man151
-rw-r--r--tcllib/modules/stringprep/stringprep.tcl278
-rw-r--r--tcllib/modules/stringprep/stringprep.test164
-rw-r--r--tcllib/modules/stringprep/stringprep_data.man21
-rw-r--r--tcllib/modules/stringprep/stringprep_data.tcl1034
-rw-r--r--tcllib/modules/stringprep/tools/gen_stringprep_data.tcl524
-rw-r--r--tcllib/modules/stringprep/tools/gen_unicode_data.tcl867
-rw-r--r--tcllib/modules/stringprep/tools/gen_unicode_test.tcl247
-rw-r--r--tcllib/modules/stringprep/unicode.man83
-rw-r--r--tcllib/modules/stringprep/unicode.tcl292
-rw-r--r--tcllib/modules/stringprep/unicode.test1732
-rw-r--r--tcllib/modules/stringprep/unicode_data.man21
-rw-r--r--tcllib/modules/stringprep/unicode_data.tcl1547
15 files changed, 7044 insertions, 0 deletions
diff --git a/tcllib/modules/stringprep/ChangeLog b/tcllib/modules/stringprep/ChangeLog
new file mode 100644
index 0000000..cb4ec0e
--- /dev/null
+++ b/tcllib/modules/stringprep/ChangeLog
@@ -0,0 +1,78 @@
+2013-02-01 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+ *
+ * Released and tagged Tcllib 1.15 ========================
+ *
+
+2011-12-13 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+ *
+ * Released and tagged Tcllib 1.14 ========================
+ *
+
+2011-01-24 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+ *
+ * Released and tagged Tcllib 1.13 ========================
+ *
+
+2009-12-07 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+ *
+ * Released and tagged Tcllib 1.12 ========================
+ *
+
+2009-11-02 Andreas Kupries <andreask@activestate.com>
+
+ * stringprep.man: Updated version numbers in the documentation
+ * stringprep_data.man: as well.
+
+2009-11-02 Pat Thoyts <patthoyts@users.sourceforge.net>
+
+ * stringprep.tcl: Applied patch from Sergei Golovan to fix
+ * stringprep.test: the failing tests.
+ * stringprep_data.tcl:
+ * tools/gen_stringprep_data.tcl:
+
+2008-12-12 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+ *
+ * Released and tagged Tcllib 1.11.1 ========================
+ *
+
+2008-10-16 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+ *
+ * Released and tagged Tcllib 1.11 ========================
+ *
+
+2008-03-19 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+ * unicode.man: Added the standard section about feedback.
+ * stringprep.man:
+
+ * stringprep_data.man: Wrote documentation for the two helper
+ * unicode_data.man: packages holding the data tables for the main
+ (public) packages.
+
+2008-03-14 Andreas Kupries <andreask@activestate.com>
+
+ * stringprep.man: Cleaned up a bit, replaced deprecated [nl] usage
+ with [para].
+
+2008-03-06 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+ * stringprep.test: Marked the tests with known trouble as with
+ constraint 'knownBug'.
+
+2008-01-29 Andreas Kupries <andreask@activestate.com>
+
+ * unicode.man: Replaced bad backslash-quoted brackets with proper
+ [lb], [rb] markup.
+
+ * stringprep.man: Fixed missing closing bracket.
+
+2008-01-29 Pat Thoyts <patthoyts@users.sourceforge.net>
+
+ * stringprep: Initial import of an RFC 3454 'StringPrep' implementation
+ * unicode: provided by Sergei Golovan.
diff --git a/tcllib/modules/stringprep/pkgIndex.tcl b/tcllib/modules/stringprep/pkgIndex.tcl
new file mode 100644
index 0000000..952fbaa
--- /dev/null
+++ b/tcllib/modules/stringprep/pkgIndex.tcl
@@ -0,0 +1,5 @@
+package ifneeded stringprep 1.0.1 [list source [file join $dir stringprep.tcl]]
+package ifneeded stringprep::data 1.0.1 [list source [file join $dir stringprep_data.tcl]]
+package ifneeded unicode 1.0.0 [list source [file join $dir unicode.tcl]]
+package ifneeded unicode::data 1.0.0 [list source [file join $dir unicode_data.tcl]]
+
diff --git a/tcllib/modules/stringprep/stringprep.man b/tcllib/modules/stringprep/stringprep.man
new file mode 100644
index 0000000..1038d25
--- /dev/null
+++ b/tcllib/modules/stringprep/stringprep.man
@@ -0,0 +1,151 @@
+[comment {-*- tcl -*- doctools manpage}]
+[manpage_begin stringprep n 1.0.1]
+[see_also unicode(n)]
+[keywords stringprep]
+[keywords unicode]
+[copyright {2007-2009, Sergei Golovan <sgolovan@nes.ru>}]
+[moddesc {Preparation of Internationalized Strings}]
+[titledesc {Implementation of stringprep}]
+[require Tcl 8.3]
+[require stringprep 1.0.1]
+[description]
+[para]
+
+This is an implementation in Tcl of the Preparation of Internationalized
+Strings ("stringprep"). It allows to define stringprep profiles and use
+them to prepare Unicode strings for comparison as defined in RFC-3454.
+
+[section "COMMANDS"]
+
+[list_begin definitions]
+[call [cmd "::stringprep::register"] \
+ [arg profile] \
+ [opt [arg "-mapping list"]] \
+ [opt [arg "-normalization form"]] \
+ [opt [arg "-prohibited list"]] \
+ [opt [arg "-prohibitedList list"]] \
+ [opt [arg "-prohibitedCommand command"]] \
+ [opt [arg "-prohibitedBidi boolean"]]]
+
+Register the [package stringprep] profile named [arg profile]. Options
+are the following.
+
+[para]
+
+Option [arg -mapping] specifies [package stringprep] mapping tables.
+This parameter takes list of tables from appendix B of RFC-3454. The usual
+list values are {B.1 B.2} or {B.1 B.3} where B.1 contains characters which
+commonly map to nothing, B.3 specifies case folding, and B.2 is used in
+profiles with unicode normalization form KC. Defult value is {} which means
+no mapping.
+
+[para]
+
+Option [arg -normalization] takes a string and if it is nonempty then it
+uses as a name of Unicode normalization form. Any value of "D", "C", "KD"
+or "KC" may be used, though RFC-3454 defines only two options: no
+normalization or normalization using form KC.
+
+[para]
+
+Option [arg -prohibited] takes a list of RFC-3454 tables with prohibited
+characters. Current version does allow to prohibit either all tables from
+C.3 to C.9 or neither of them. An example of this list for RFC-3491 is
+{A.1 C.1.2 C.2.2 C.3 C.4 C.5 C.6 C.7 C.8 C.9}.
+
+[para]
+
+Option [arg -prohibitedList] specifies a list of additional prohibited
+characters. The list contains not characters themselves but their Unicode
+numbers. For example, Nodeprep specification from RFC-3920 forbids the
+following codes: {0x22 0x26 0x27 0x2f 0x3a 0x3c 0x3e 0x40} (\" \& \' / : < > @).
+
+[para]
+
+Option [arg -prohibitedCommand] specifies a command which is called for
+every character code in mapped and normalized string. If the command returns
+true then the character is considered prohibited. This option is useful when
+a list for [arg -prohibitedList] is too large.
+
+[para]
+
+Option [arg -prohibitedBidi] takes boolean value and if it is true then the
+bidirectional character processing rules defined in section 6 of RFC-3454 are
+used.
+
+[call [cmd "::stringprep::stringprep"] \
+ [arg profile] \
+ [arg string]]
+
+Performs [package stringprep] operations defined in profile [arg profile]
+to string [arg string]. Result is a prepared string or one of the following
+errors: [arg invalid_profile] (profile [arg profile] is not defined),
+[arg prohibited_character] (string [arg string] contains a prohibited character)
+or [arg prohibited_bidi] (string [arg string] contains a prohibited bidirectional
+sequence).
+
+[call [cmd "::stringprep::compare"] \
+ [arg profile] \
+ [arg string1] \
+ [arg string2]]
+
+Compares two unicode strings prepared accordingly to [package stringprep]
+profile [arg profile]. The command returns 0 if prepared strings are equal,
+-1 if [arg string1] is lexicographically less than [arg string2], or
+1 if [arg string1] is lexicographically greater than [arg string2].
+
+[list_end]
+
+[section EXAMPLES]
+
+Nameprep profile definition (see RFC-3491):
+
+[example {
+::stringprep::register nameprep \
+ -mapping {B.1 B.2} \
+ -normalization KC \
+ -prohibited {A.1 C.1.2 C.2.2 C.3 C.4 C.5 C.6 C.7 C.8 C.9} \
+ -prohibitedBidi 1
+}]
+
+Nodeprep and resourceprep profile definitions (see RFC-3920):
+
+[example {
+::stringprep::register nodeprep \
+ -mapping {B.1 B.2} \
+ -normalization KC \
+ -prohibited {A.1 C.1.1 C.1.2 C.2.1 C.2.2 C.3 C.4 C.5 C.6 C.7 C.8 C.9} \
+ -prohibitedList {0x22 0x26 0x27 0x2f 0x3a 0x3c 0x3e 0x40} \
+ -prohibitedBidi 1
+
+::stringprep::register resourceprep \
+ -mapping {B.1} \
+ -normalization KC \
+ -prohibited {A.1 C.1.2 C.2.1 C.2.2 C.3 C.4 C.5 C.6 C.7 C.8 C.9} \
+ -prohibitedBidi 1
+}]
+
+[section "REFERENCES"]
+
+[list_begin enum]
+
+[enum]
+ "Preparation of Internationalized Strings ('stringprep')",
+ ([uri http://www.ietf.org/rfc/rfc3454.txt])
+
+[enum]
+ "Nameprep: A Stringprep Profile for Internationalized Domain Names (IDN)",
+ ([uri http://www.ietf.org/rfc/rfc3491.txt])
+
+[enum]
+ "Extensible Messaging and Presence Protocol (XMPP): Core",
+ ([uri http://www.ietf.org/rfc/rfc3920.txt])
+
+[list_end]
+
+[section "AUTHORS"]
+Sergei Golovan
+
+[vset CATEGORY stringprep]
+[include ../doctools2base/include/feedback.inc]
+[manpage_end]
diff --git a/tcllib/modules/stringprep/stringprep.tcl b/tcllib/modules/stringprep/stringprep.tcl
new file mode 100644
index 0000000..70d14f6
--- /dev/null
+++ b/tcllib/modules/stringprep/stringprep.tcl
@@ -0,0 +1,278 @@
+# stringprep.tcl -*- tcl -*-
+#
+# Implementation of RFC 3454 "Preparation of Internationalized Strings"
+#
+# Copyright (c) 2007 Sergei Golovan
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# RCS: @(#) $Id: stringprep.tcl,v 1.2 2009/11/02 00:26:44 patthoyts Exp $
+
+package require stringprep::data 1.0
+package require unicode 1.0
+
+namespace eval ::stringprep {
+ variable profiles
+ array unset profiles
+}
+
+########################################################################
+# Register new stringprep profile
+
+proc ::stringprep::register {profile args} {
+ variable profiles
+
+ array set props [list -mapping "" \
+ -normalization "" \
+ -prohibited 0 \
+ -prohibitedList {} \
+ -prohibitedCommand "" \
+ -prohibitedBidi 0]
+
+ foreach {opt val} $args {
+ switch -- $opt {
+ -mapping {
+ foreach tab $val {
+ switch -- $tab {
+ B.1 - B.2 - B.3 {}
+ default {
+ return -code error \
+ "::stringprep::register -mapping: Only\
+ B.1, B.2, B.3 tables are allowed"
+ }
+ }
+ }
+ set props(-mapping) $val
+ }
+ -normalization {
+ switch -- $val {
+ D - C - KD - KC - "" {
+ set props(-normalization) $val
+ }
+ default {
+ return -code error \
+ "::stringprep::register -normalization: Only\
+ D, C, KD, KC or empty normalization is allowed"
+ }
+ }
+ }
+ -prohibited {
+ set mask 0
+ set c39count 0
+ foreach tab $val {
+ switch -- $tab {
+ A.1 { set mask [expr {$mask | $data::A1Mask}] }
+ C.1.1 { set mask [expr {$mask | $data::C11Mask}] }
+ C.1.2 { set mask [expr {$mask | $data::C12Mask}] }
+ C.2.1 { set mask [expr {$mask | $data::C21Mask}] }
+ C.2.2 { set mask [expr {$mask | $data::C22Mask}] }
+ C.3 - C.4 - C.5 - C.6 - C.7 - C.8 -
+ C.9 { incr c39count }
+ default {
+ return -code error \
+ "::stringprep::register -prohibited: Only\
+ tables A.1, C.* are allowed to prohibit"
+ }
+ }
+ }
+ if {$c39count > 0 && $c39count < 7} {
+ return -code error \
+ "::stringprep::register -prohibited: Must prohibit\
+ all C.3--C.9 tables or none of them"
+ }
+ if {$c39count > 0} {
+ set mask [expr {$mask | $data::C39Mask}]
+ }
+ set props(-prohibited) $mask
+ }
+ -prohibitedList {
+ if {[catch {
+ foreach uc $val {
+ if {![string is integer -strict $uc]} {
+ error not_integer
+ } else {
+ lappend props(-prohibitedList) [expr {$uc}]
+ }
+ }}]} {
+ return -code error \
+ "::stringprep::register -prohibitedList: List\
+ of integers expected"
+ }
+ }
+ -prohibitedCommand {
+ set props(-prohibitedCommand) $val
+ }
+ -prohibitedBidi {
+ if {[string is true -strict $val]} {
+ set props(-prohibitedBidi) 1
+ } elseif {[string is false -strict $val]} {
+ set props(-prohibitedBidi) 0
+ } else {
+ return -code error \
+ "::stringprep::register -prohibitedBidi: Boolean\
+ value expected"
+ }
+ }
+ }
+ }
+ set profiles($profile) [array get props]
+}
+
+########################################################################
+# Register identity profile
+
+::stringprep::register none \
+ -mapping {} \
+ -normalization {} \
+ -prohibited {} \
+ -prohibitedBidi 0
+
+########################################################################
+
+proc ::stringprep::stringprep {profile str} {
+ variable profiles
+
+ if {![info exists profiles($profile)]} {
+ return -code error invalid_profile
+ }
+
+ set uclist [::unicode::fromstring $str]
+
+ set uclist [map $profile $uclist]
+ if {[llength $uclist] == 0} {
+ return ""
+ }
+
+ set uclist [normalize $profile $uclist]
+
+ if {[prohibited $profile $uclist]} {
+ return -code error prohibited_character
+ }
+
+ if {[prohibited_bidi $profile $uclist]} {
+ return -code error prohibited_bidi
+ }
+
+ ::unicode::tostring $uclist
+}
+
+########################################################################
+
+proc ::stringprep::compare {profile str1 str2} {
+ string compare [stringprep $profile $str1] [stringprep $profile $str2]
+}
+
+########################################################################
+# Mapping (section 3)
+
+proc ::stringprep::map {profile uclist} {
+ variable profiles
+
+ array set props $profiles($profile)
+
+ set B1Mask 0
+ set B3Mask 0
+ set B2 0
+ foreach tab $props(-mapping) {
+ switch -- $tab {
+ B.1 { set B1Mask $data::B1Mask }
+ B.2 { set B2 1 }
+ B.3 { set B3Mask $data::B3Mask }
+ }
+ }
+
+ set res {}
+ foreach uc $uclist {
+ set info [data::GetUniCharInfo $uc]
+
+ if {$info & $B1Mask} {
+ # Map to nothing
+ continue
+ }
+
+ if {$B2 || ($info & $B3Mask)} {
+ if {$info & $data::MCMask} {
+ set res [concat $res [data::GetMC $info]]
+ } else {
+ lappend res [expr {$uc + [data::GetDelta $info]}]
+ }
+ } else {
+ lappend res $uc
+ }
+ }
+ return $res
+}
+
+########################################################################
+# Normalization (section 4)
+
+proc ::stringprep::normalize {profile uclist} {
+ variable profiles
+
+ array set props $profiles($profile)
+
+ switch -- $props(-normalization) {
+ D - C - KD - KC {
+ return [::unicode::normalize $props(-normalization) $uclist]
+ }
+ default { return $uclist }
+ }
+}
+
+########################################################################
+# Prohibit (section 5)
+
+proc ::stringprep::prohibited {profile uclist} {
+ variable profiles
+
+ array set props $profiles($profile)
+
+ foreach uc $uclist {
+ set info [data::GetUniCharInfo $uc]
+ if {($info & $props(-prohibited)) || \
+ [lsearch -exact $props(-prohibitedList) $uc] >= 0} {
+ return 1
+ } elseif {$props(-prohibitedCommand) != "" && \
+ [uplevel #0 $props(-prohibitedCommand) [list $uc]]} {
+ return 1
+ }
+ }
+ return 0
+}
+
+########################################################################
+# Check bidi (section 6)
+
+proc ::stringprep::prohibited_bidi {profile uclist} {
+ variable profiles
+
+ array set props $profiles($profile)
+
+ if {!$props(-prohibitedBidi)} {
+ return 0
+ }
+
+ set info [data::GetUniCharInfo [lindex $uclist 0]]
+ set first_ral [expr {$info & $data::D1Mask}]
+ set last_ral 0
+ set have_ral 0
+ set have_l 0
+ foreach uc $uclist {
+ set info [data::GetUniCharInfo $uc]
+ set last_ral [expr {$info & $data::D1Mask}]
+ set have_ral [expr {$have_ral || $last_ral}]
+ set have_l [expr {$have_l || ($info & $data::D2Mask)}]
+ }
+ if {$have_ral && (!$first_ral || !$last_ral || $have_l)} {
+ return 1
+ } else {
+ return 0
+ }
+}
+
+########################################################################
+
+package provide stringprep 1.0.1
+
+########################################################################
diff --git a/tcllib/modules/stringprep/stringprep.test b/tcllib/modules/stringprep/stringprep.test
new file mode 100644
index 0000000..c353925
--- /dev/null
+++ b/tcllib/modules/stringprep/stringprep.test
@@ -0,0 +1,164 @@
+# stringprep.test -*- tcl -*-
+#
+# Tests for the stringprep package.
+#
+# Copyright (c) 2007 Sergei Golovan
+# Copyright (c) 2007 Pat Thoyts
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# RCS: @(#) $Id: stringprep.test,v 1.3 2009/11/02 00:26:44 patthoyts Exp $
+
+# -------------------------------------------------------------------------
+
+source [file join \
+ [file dirname [file dirname [file join [pwd] [info script]]]] \
+ devtools testutilities.tcl]
+
+testsNeedTcl 8.3
+testsNeedTcltest 1.0
+
+testing {
+ useLocalFile unicode_data.tcl
+ useLocalFile unicode.tcl
+ useLocalFile stringprep_data.tcl
+ useLocalFile stringprep.tcl
+}
+
+# -------------------------------------------------------------------------
+# Define two stringprep profiles
+
+# IDN Nameprep: http://www.ietf.org/rfc/rfc3491.txt
+::stringprep::register nameprep \
+ -mapping {B.1 B.2} \
+ -normalization KC \
+ -prohibited {A.1 C.1.2 C.2.2 C.3 C.4 C.5 C.6 C.7 C.8 C.9} \
+ -prohibitedBidi 1
+
+# XMPP Nodeprep: http://www.ietf.org/rfc/rfc3920.txt
+::stringprep::register nodeprep \
+ -mapping {B.1 B.2} \
+ -normalization KC \
+ -prohibited {A.1 C.1.1 C.1.2 C.2.1 C.2.2 C.3 C.4 C.5 C.6 C.7 C.8 C.9} \
+ -prohibitedList {0x22 0x26 0x27 0x2f 0x3a 0x3c 0x3e 0x40} \
+ -prohibitedBidi 1
+
+# -------------------------------------------------------------------------
+
+test stringprep-1.1 {register: bad -mapping table} {
+ catch {::stringprep::register type -mapping {B.4}} result
+ set result
+} {::stringprep::register -mapping: Only B.1, B.2, B.3 tables are allowed}
+
+test stringprep-1.2 {register: bad -normalization option} {
+ catch {::stringprep::register type -normalization KK} result
+ set result
+} {::stringprep::register -normalization: Only D, C, KD, KC or empty normalization is allowed}
+
+test stringprep-1.3 {register: bad -prohibited table} {
+ catch {::stringprep::register type -prohibited {B.1}} result
+ set result
+} {::stringprep::register -prohibited: Only tables A.1, C.* are allowed to prohibit}
+
+test stringprep-1.4 {register: bad -prohibited table 2} {
+ catch {::stringprep::register type -prohibited {C.4}} result
+ set result
+} {::stringprep::register -prohibited: Must prohibit all C.3--C.9 tables or none of them}
+
+test stringprep-1.5 {register: bad -prohibitedList list} {
+ catch {::stringprep::register type -prohibitedList {1 2 3 a b c}} result
+ set result
+} {::stringprep::register -prohibitedList: List of integers expected}
+
+test stringprep-1.6 {register: bad -prohibitedBidi value} {
+ catch {::stringprep::register type -prohibitedBidi yesss} result
+ set result
+} {::stringprep::register -prohibitedBidi: Boolean value expected}
+
+test stringprep-2.1 {stringprep: bad profile} {
+ catch {::stringprep::stringprep unknown ""} result
+ set result
+} {invalid_profile}
+
+test stringprep-2.2 {stringprep: prohibited character} {
+ catch {::stringprep::stringprep nodeprep "user@host"} result
+ set result
+} {prohibited_character}
+
+test stringprep-2.3 {stringprep: prohibited bidi} {
+ catch {::stringprep::stringprep nameprep "\u0627\u0031"} result
+ set result
+} {prohibited_bidi}
+
+
+# -------------------------------------------------------------------------
+# nameprep test vectors
+# http://www.gnu.org/software/libidn/draft-josefsson-idn-test-vectors.html
+#
+# list of: comment, input, output
+
+set vectors {
+ { "Map to nothing"
+ "foo\xC2\xAD\xCD\x8F\xE1\xA0\x86\xE1\xA0\x8B.bar\xE2\x80\x8B\xE2\x81\xA0.baz\xEF\xB8\x80\xEF\xB8\x88\xEF\xB8\x8F\xEF\xBB\xBF"
+ "foo.bar.baz" }
+ { "Case folding ASCII U+0043 U+0041 U+0046 U+0045" "CAFE" "cafe" }
+ { "Case folding 8bit U+00DF (german sharp s)" "\xC3\x9F" "ss" }
+ { "Case folding U+0130 (turkish capital I with dot)" "\xC4\xB0" "i\xcc\x87" }
+ { "Case folding multibyte U+0143 U+037A" "\xC5\x83\xCD\xBA" "\xC5\x84 \xCE\xB9" }
+ { "Case folding U+2121 U+33C6 U+1D7BB (Tcl cannot represent U+1D7BB)"
+ "\xE2\x84\xA1\xE3\x8F\x86\xF0\x9D\x9E\xBB"
+ "telc\xE2\x88\x95kg\xCF\x83" }
+ { "Normalization of U+006a U+030c U+00A0 U+00AA" "\x6A\xCC\x8C\xC2\xA0\xC2\xAA"
+ "\xC7\xB0 a" }
+ { "Case folding U+1FB7 and normalization" "\xE1\xBE\xB7" "\xE1\xBE\xB6\xCE\xB9" }
+ { "Case folding U+2121 U+33C6" "\xE2\x84\xA1\xE3\x8F\x86"
+ "telc\xE2\x88\x95kg" }
+}
+
+set id 0
+foreach vector $vectors {
+ foreach {comment input output} $vector break
+
+ if {$id == 5} {
+ test nameprep-$id $comment knownBug {
+ list [catch {::stringprep::stringprep nameprep \
+ [encoding convertfrom utf-8 $input]} res] $res
+ } [list 0 [encoding convertfrom utf-8 $output]]
+ } else {
+ test nameprep-$id $comment {
+ list [catch {::stringprep::stringprep nameprep \
+ [encoding convertfrom utf-8 $input]} res] $res
+ } [list 0 [encoding convertfrom utf-8 $output]]
+ }
+ incr id
+}
+
+# -------------------------------------------------------------------------
+# SASLPrep: http://www.ietf.org/rfc/rfc4013.txt
+
+::stringprep::register saslprep \
+ -mapping {B.1} \
+ -normalization KC \
+ -prohibited {A.1 C.1.2 C.2.1 C.2.2 C.3 C.4 C.5 C.6 C.7 C.8 C.9} \
+ -prohibitedBidi 1
+
+foreach {n input result title} {
+ 1 "I\u00ADX" {0 IX} "SOFT HYPHEN mapped to nothing"
+ 2 "user" {0 user} "no transformation"
+ 3 "USER" {0 USER} "case preserved, will not match #2"
+ 4 "\u00AA" {0 a} "output is NFKC, input in ISO 8859-1"
+ 5 "\u2168" {0 IX} "output is NFKC, will match #1"
+ 6 "\u0007" {1 prohibited_character} "Error - prohibited character"
+ 7 "\u0627\u0031" {1 prohibited_bidi} "Error - bidirectional check"
+} {
+ test saslprep-1.$n $title {
+ list [catch {::stringprep::stringprep saslprep $input} res] $res
+ } $result
+}
+
+# -------------------------------------------------------------------------
+
+::tcltest::cleanupTests
+
+# -------------------------------------------------------------------------
diff --git a/tcllib/modules/stringprep/stringprep_data.man b/tcllib/modules/stringprep/stringprep_data.man
new file mode 100644
index 0000000..63b35f6
--- /dev/null
+++ b/tcllib/modules/stringprep/stringprep_data.man
@@ -0,0 +1,21 @@
+[comment {-*- tcl -*- doctools manpage}]
+[manpage_begin stringprep::data n 1.0.1]
+[keywords stringprep]
+[keywords unicode]
+[copyright {2007-2009, Sergei Golovan <sgolovan@nes.ru>}]
+[moddesc {Preparation of Internationalized Strings}]
+[titledesc {stringprep data tables, generated, internal}]
+[require Tcl 8.3]
+[require stringprep::data 1.0.1]
+[description]
+[para]
+
+The [package stringprep::data] package is a helper for
+[package stringprep], providing it with the data tables needed to
+perform its functions. It is an [emph internal] package which should
+not be accessed on its own. Because of that it has no publicly
+documented API either. Its implementation is generated by a script.
+
+[vset CATEGORY stringprep]
+[include ../doctools2base/include/feedback.inc]
+[manpage_end]
diff --git a/tcllib/modules/stringprep/stringprep_data.tcl b/tcllib/modules/stringprep/stringprep_data.tcl
new file mode 100644
index 0000000..7c76426
--- /dev/null
+++ b/tcllib/modules/stringprep/stringprep_data.tcl
@@ -0,0 +1,1034 @@
+# stringprep_data.tcl --
+#
+# Declarations of Unicode character information tables. This file is
+# automatically generated by the gen_stringprep_data.tcl script. Do not
+# modify this file by hand.
+#
+# Copyright (c) 1998 Scriptics Corporation.
+# Copyright (c) 2007 Alexey Shchepin
+# Copyright (c) 2008 Sergei Golovan
+#
+# RCS: @(#) $Id: stringprep_data.tcl,v 1.2 2009/11/02 00:26:44 patthoyts Exp $
+#
+
+package provide stringprep::data 1.0.1
+
+namespace eval ::stringprep::data {
+
+#
+# A 16-bit Unicode character is split into two parts in order to index
+# into the following tables. The lower OFFSET_BITS comprise an offset
+# into a page of characters. The upper bits comprise the page number.
+#
+
+set OFFSET_BITS 7
+
+#
+# The pageMap is indexed by page number and returns an alternate page number
+# that identifies a unique page of characters. Many Unicode characters map
+# to the same alternate page number.
+#
+
+array unset pageMap
+array set pageMap [list \
+ 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 11 12 12 13 13 14 14 \
+ 15 15 18 17 19 18 20 19 21 20 22 21 23 22 24 23 25 24 26 25 27 26 28 27 \
+ 29 28 30 29 31 30 32 31 33 32 34 33 35 34 36 35 37 36 38 37 39 38 40 39 \
+ 41 40 42 40 43 40 44 41 45 42 46 43 47 44 48 45 49 46 60 47 61 48 62 49 \
+ 63 50 64 51 65 52 66 53 67 54 68 55 69 55 70 56 71 57 72 58 73 59 74 55 \
+ 75 55 76 60 77 61 78 62 79 63 80 55 81 55 82 55 83 55 84 55 85 55 93 64 \
+ 94 55 95 65 96 66 97 67 98 68 99 69 100 70 101 71 102 72 103 73 104 40 \
+ 105 40 106 40 107 40 108 40 109 40 110 40 111 40 112 40 113 40 114 40 \
+ 115 40 116 40 117 40 118 40 119 40 120 40 121 40 122 40 123 40 124 40 \
+ 125 40 126 40 127 40 128 40 129 40 130 40 131 40 132 40 133 40 134 40 \
+ 135 40 136 40 137 40 138 40 139 40 140 40 141 40 142 40 143 40 144 40 \
+ 145 40 146 40 147 40 148 40 149 40 150 40 151 40 152 40 153 40 154 40 \
+ 155 74 156 40 157 40 158 40 159 40 160 40 161 40 162 40 163 40 164 40 \
+ 165 40 166 40 167 40 168 40 169 40 170 40 171 40 172 40 173 40 174 40 \
+ 175 40 176 40 177 40 178 40 179 40 180 40 181 40 182 40 183 40 184 40 \
+ 185 40 186 40 187 40 188 40 189 40 190 40 191 40 192 40 193 40 194 40 \
+ 195 40 196 40 197 40 198 40 199 40 200 40 201 40 202 40 203 40 204 40 \
+ 205 40 206 40 207 40 208 40 209 40 210 40 211 40 212 40 213 40 214 40 \
+ 215 40 216 40 217 40 218 40 219 40 220 40 221 40 222 40 223 40 224 40 \
+ 225 40 226 40 227 40 228 40 229 40 230 40 231 40 232 40 233 40 234 40 \
+ 235 40 236 40 237 40 238 40 239 40 240 40 241 40 242 40 243 40 244 40 \
+ 245 40 246 40 247 40 248 40 249 40 250 40 251 40 252 40 253 40 254 40 \
+ 255 40 256 40 257 40 258 40 259 40 260 40 261 40 262 40 263 40 264 40 \
+ 265 40 266 40 267 40 268 40 269 40 270 40 271 40 272 40 273 40 274 40 \
+ 275 40 276 40 277 40 278 40 279 40 280 40 281 40 282 40 283 40 284 40 \
+ 285 40 286 40 287 40 288 40 289 40 290 40 291 40 292 40 293 40 294 40 \
+ 295 40 296 40 297 40 298 40 299 40 300 40 301 40 302 40 303 40 304 40 \
+ 305 40 306 40 307 40 308 40 309 40 310 40 311 40 312 40 313 40 314 40 \
+ 315 40 316 40 317 40 318 40 319 75 320 40 321 40 322 40 323 40 324 40 \
+ 325 40 326 40 327 40 328 40 329 76 344 40 345 40 346 40 347 40 348 40 \
+ 349 40 350 40 351 40 352 40 353 40 354 40 355 40 356 40 357 40 358 40 \
+ 359 40 360 40 361 40 362 40 363 40 364 40 365 40 366 40 367 40 368 40 \
+ 369 40 370 40 371 40 372 40 373 40 374 40 375 40 376 40 377 40 378 40 \
+ 379 40 380 40 381 40 382 40 383 40 384 40 385 40 386 40 387 40 388 40 \
+ 389 40 390 40 391 40 392 40 393 40 394 40 395 40 396 40 397 40 398 40 \
+ 399 40 400 40 401 40 402 40 403 40 404 40 405 40 406 40 407 40 408 40 \
+ 409 40 410 40 411 40 412 40 413 40 414 40 415 40 416 40 417 40 418 40 \
+ 419 40 420 40 421 40 422 40 423 40 424 40 425 40 426 40 427 40 428 40 \
+ 429 40 430 40 431 77 432 78 433 78 434 78 435 78 436 78 437 78 438 78 \
+ 439 78 440 78 441 78 442 78 443 78 444 78 445 78 446 78 447 78 448 78 \
+ 449 78 450 78 451 78 452 78 453 78 454 78 455 78 456 78 457 78 458 78 \
+ 459 78 460 78 461 78 462 78 463 78 464 78 465 78 466 78 467 78 468 78 \
+ 469 78 470 78 471 78 472 78 473 78 474 78 475 78 476 78 477 78 478 78 \
+ 479 78 480 78 481 78 482 78 483 78 484 78 485 78 486 78 487 78 488 78 \
+ 489 78 490 78 491 78 492 78 493 78 494 78 495 78 496 78 497 78 498 40 \
+ 499 40 500 79 502 80 503 81 504 82 505 82 506 83 507 84 508 85 509 86 \
+ 510 87 511 88 518 89 520 90 928 40 929 91 930 92 931 93 936 94 937 95 \
+ 938 96 939 97 940 98 941 99 942 100 943 101 1023 102 1024 40 1025 40 \
+ 1026 40 1027 40 1028 40 1029 40 1030 40 1031 40 1032 40 1033 40 1034 40 \
+ 1035 40 1036 40 1037 40 1038 40 1039 40 1040 40 1041 40 1042 40 1043 40 \
+ 1044 40 1045 40 1046 40 1047 40 1048 40 1049 40 1050 40 1051 40 1052 40 \
+ 1053 40 1054 40 1055 40 1056 40 1057 40 1058 40 1059 40 1060 40 1061 40 \
+ 1062 40 1063 40 1064 40 1065 40 1066 40 1067 40 1068 40 1069 40 1070 40 \
+ 1071 40 1072 40 1073 40 1074 40 1075 40 1076 40 1077 40 1078 40 1079 40 \
+ 1080 40 1081 40 1082 40 1083 40 1084 40 1085 40 1086 40 1087 40 1088 40 \
+ 1089 40 1090 40 1091 40 1092 40 1093 40 1094 40 1095 40 1096 40 1097 40 \
+ 1098 40 1099 40 1100 40 1101 40 1102 40 1103 40 1104 40 1105 40 1106 40 \
+ 1107 40 1108 40 1109 40 1110 40 1111 40 1112 40 1113 40 1114 40 1115 40 \
+ 1116 40 1117 40 1118 40 1119 40 1120 40 1121 40 1122 40 1123 40 1124 40 \
+ 1125 40 1126 40 1127 40 1128 40 1129 40 1130 40 1131 40 1132 40 1133 40 \
+ 1134 40 1135 40 1136 40 1137 40 1138 40 1139 40 1140 40 1141 40 1142 40 \
+ 1143 40 1144 40 1145 40 1146 40 1147 40 1148 40 1149 40 1150 40 1151 40 \
+ 1152 40 1153 40 1154 40 1155 40 1156 40 1157 40 1158 40 1159 40 1160 40 \
+ 1161 40 1162 40 1163 40 1164 40 1165 40 1166 40 1167 40 1168 40 1169 40 \
+ 1170 40 1171 40 1172 40 1173 40 1174 40 1175 40 1176 40 1177 40 1178 40 \
+ 1179 40 1180 40 1181 40 1182 40 1183 40 1184 40 1185 40 1186 40 1187 40 \
+ 1188 40 1189 40 1190 40 1191 40 1192 40 1193 40 1194 40 1195 40 1196 40 \
+ 1197 40 1198 40 1199 40 1200 40 1201 40 1202 40 1203 40 1204 40 1205 40 \
+ 1206 40 1207 40 1208 40 1209 40 1210 40 1211 40 1212 40 1213 40 1214 40 \
+ 1215 40 1216 40 1217 40 1218 40 1219 40 1220 40 1221 40 1222 40 1223 40 \
+ 1224 40 1225 40 1226 40 1227 40 1228 40 1229 40 1230 40 1231 40 1232 40 \
+ 1233 40 1234 40 1235 40 1236 40 1237 40 1238 40 1239 40 1240 40 1241 40 \
+ 1242 40 1243 40 1244 40 1245 40 1246 40 1247 40 1248 40 1249 40 1250 40 \
+ 1251 40 1252 40 1253 40 1254 40 1255 40 1256 40 1257 40 1258 40 1259 40 \
+ 1260 40 1261 40 1262 40 1263 40 1264 40 1265 40 1266 40 1267 40 1268 40 \
+ 1269 40 1270 40 1271 40 1272 40 1273 40 1274 40 1275 40 1276 40 1277 40 \
+ 1278 40 1279 40 1280 40 1281 40 1282 40 1283 40 1284 40 1285 40 1286 40 \
+ 1287 40 1288 40 1289 40 1290 40 1291 40 1292 40 1293 40 1294 40 1295 40 \
+ 1296 40 1297 40 1298 40 1299 40 1300 40 1301 40 1302 40 1303 40 1304 40 \
+ 1305 40 1306 40 1307 40 1308 40 1309 40 1310 40 1311 40 1312 40 1313 40 \
+ 1314 40 1315 40 1316 40 1317 40 1318 40 1319 40 1320 40 1321 40 1322 40 \
+ 1323 40 1324 40 1325 40 1326 40 1327 40 1328 40 1329 40 1330 40 1331 40 \
+ 1332 40 1333 40 1334 40 1335 40 1336 40 1337 40 1338 40 1339 40 1340 40 \
+ 1341 40 1342 40 1343 40 1344 40 1345 40 1346 40 1347 40 1348 40 1349 40 \
+ 1350 40 1351 40 1352 40 1353 40 1354 40 1355 40 1356 40 1357 103 1520 40 \
+ 1521 40 1522 40 1523 40 1524 104 1535 102 2047 102 2559 102 3071 102 \
+ 3583 102 4095 102 4607 102 5119 102 5631 102 6143 102 6655 102 7167 102 \
+ 7168 105 7679 102 7680 78 7681 78 7682 78 7683 78 7684 78 7685 78 7686 78 \
+ 7687 78 7688 78 7689 78 7690 78 7691 78 7692 78 7693 78 7694 78 7695 78 \
+ 7696 78 7697 78 7698 78 7699 78 7700 78 7701 78 7702 78 7703 78 7704 78 \
+ 7705 78 7706 78 7707 78 7708 78 7709 78 7710 78 7711 78 7712 78 7713 78 \
+ 7714 78 7715 78 7716 78 7717 78 7718 78 7719 78 7720 78 7721 78 7722 78 \
+ 7723 78 7724 78 7725 78 7726 78 7727 78 7728 78 7729 78 7730 78 7731 78 \
+ 7732 78 7733 78 7734 78 7735 78 7736 78 7737 78 7738 78 7739 78 7740 78 \
+ 7741 78 7742 78 7743 78 7744 78 7745 78 7746 78 7747 78 7748 78 7749 78 \
+ 7750 78 7751 78 7752 78 7753 78 7754 78 7755 78 7756 78 7757 78 7758 78 \
+ 7759 78 7760 78 7761 78 7762 78 7763 78 7764 78 7765 78 7766 78 7767 78 \
+ 7768 78 7769 78 7770 78 7771 78 7772 78 7773 78 7774 78 7775 78 7776 78 \
+ 7777 78 7778 78 7779 78 7780 78 7781 78 7782 78 7783 78 7784 78 7785 78 \
+ 7786 78 7787 78 7788 78 7789 78 7790 78 7791 78 7792 78 7793 78 7794 78 \
+ 7795 78 7796 78 7797 78 7798 78 7799 78 7800 78 7801 78 7802 78 7803 78 \
+ 7804 78 7805 78 7806 78 7807 78 7808 78 7809 78 7810 78 7811 78 7812 78 \
+ 7813 78 7814 78 7815 78 7816 78 7817 78 7818 78 7819 78 7820 78 7821 78 \
+ 7822 78 7823 78 7824 78 7825 78 7826 78 7827 78 7828 78 7829 78 7830 78 \
+ 7831 78 7832 78 7833 78 7834 78 7835 78 7836 78 7837 78 7838 78 7839 78 \
+ 7840 78 7841 78 7842 78 7843 78 7844 78 7845 78 7846 78 7847 78 7848 78 \
+ 7849 78 7850 78 7851 78 7852 78 7853 78 7854 78 7855 78 7856 78 7857 78 \
+ 7858 78 7859 78 7860 78 7861 78 7862 78 7863 78 7864 78 7865 78 7866 78 \
+ 7867 78 7868 78 7869 78 7870 78 7871 78 7872 78 7873 78 7874 78 7875 78 \
+ 7876 78 7877 78 7878 78 7879 78 7880 78 7881 78 7882 78 7883 78 7884 78 \
+ 7885 78 7886 78 7887 78 7888 78 7889 78 7890 78 7891 78 7892 78 7893 78 \
+ 7894 78 7895 78 7896 78 7897 78 7898 78 7899 78 7900 78 7901 78 7902 78 \
+ 7903 78 7904 78 7905 78 7906 78 7907 78 7908 78 7909 78 7910 78 7911 78 \
+ 7912 78 7913 78 7914 78 7915 78 7916 78 7917 78 7918 78 7919 78 7920 78 \
+ 7921 78 7922 78 7923 78 7924 78 7925 78 7926 78 7927 78 7928 78 7929 78 \
+ 7930 78 7931 78 7932 78 7933 78 7934 78 7935 78 7936 78 7937 78 7938 78 \
+ 7939 78 7940 78 7941 78 7942 78 7943 78 7944 78 7945 78 7946 78 7947 78 \
+ 7948 78 7949 78 7950 78 7951 78 7952 78 7953 78 7954 78 7955 78 7956 78 \
+ 7957 78 7958 78 7959 78 7960 78 7961 78 7962 78 7963 78 7964 78 7965 78 \
+ 7966 78 7967 78 7968 78 7969 78 7970 78 7971 78 7972 78 7973 78 7974 78 \
+ 7975 78 7976 78 7977 78 7978 78 7979 78 7980 78 7981 78 7982 78 7983 78 \
+ 7984 78 7985 78 7986 78 7987 78 7988 78 7989 78 7990 78 7991 78 7992 78 \
+ 7993 78 7994 78 7995 78 7996 78 7997 78 7998 78 7999 78 8000 78 8001 78 \
+ 8002 78 8003 78 8004 78 8005 78 8006 78 8007 78 8008 78 8009 78 8010 78 \
+ 8011 78 8012 78 8013 78 8014 78 8015 78 8016 78 8017 78 8018 78 8019 78 \
+ 8020 78 8021 78 8022 78 8023 78 8024 78 8025 78 8026 78 8027 78 8028 78 \
+ 8029 78 8030 78 8031 78 8032 78 8033 78 8034 78 8035 78 8036 78 8037 78 \
+ 8038 78 8039 78 8040 78 8041 78 8042 78 8043 78 8044 78 8045 78 8046 78 \
+ 8047 78 8048 78 8049 78 8050 78 8051 78 8052 78 8053 78 8054 78 8055 78 \
+ 8056 78 8057 78 8058 78 8059 78 8060 78 8061 78 8062 78 8063 78 8064 78 \
+ 8065 78 8066 78 8067 78 8068 78 8069 78 8070 78 8071 78 8072 78 8073 78 \
+ 8074 78 8075 78 8076 78 8077 78 8078 78 8079 78 8080 78 8081 78 8082 78 \
+ 8083 78 8084 78 8085 78 8086 78 8087 78 8088 78 8089 78 8090 78 8091 78 \
+ 8092 78 8093 78 8094 78 8095 78 8096 78 8097 78 8098 78 8099 78 8100 78 \
+ 8101 78 8102 78 8103 78 8104 78 8105 78 8106 78 8107 78 8108 78 8109 78 \
+ 8110 78 8111 78 8112 78 8113 78 8114 78 8115 78 8116 78 8117 78 8118 78 \
+ 8119 78 8120 78 8121 78 8122 78 8123 78 8124 78 8125 78 8126 78 8127 78 \
+ 8128 78 8129 78 8130 78 8131 78 8132 78 8133 78 8134 78 8135 78 8136 78 \
+ 8137 78 8138 78 8139 78 8140 78 8141 78 8142 78 8143 78 8144 78 8145 78 \
+ 8146 78 8147 78 8148 78 8149 78 8150 78 8151 78 8152 78 8153 78 8154 78 \
+ 8155 78 8156 78 8157 78 8158 78 8159 78 8160 78 8161 78 8162 78 8163 78 \
+ 8164 78 8165 78 8166 78 8167 78 8168 78 8169 78 8170 78 8171 78 8172 78 \
+ 8173 78 8174 78 8175 78 8176 78 8177 78 8178 78 8179 78 8180 78 8181 78 \
+ 8182 78 8183 78 8184 78 8185 78 8186 78 8187 78 8188 78 8189 78 8190 78 \
+ 8191 106 8192 78 8193 78 8194 78 8195 78 8196 78 8197 78 8198 78 8199 78 \
+ 8200 78 8201 78 8202 78 8203 78 8204 78 8205 78 8206 78 8207 78 8208 78 \
+ 8209 78 8210 78 8211 78 8212 78 8213 78 8214 78 8215 78 8216 78 8217 78 \
+ 8218 78 8219 78 8220 78 8221 78 8222 78 8223 78 8224 78 8225 78 8226 78 \
+ 8227 78 8228 78 8229 78 8230 78 8231 78 8232 78 8233 78 8234 78 8235 78 \
+ 8236 78 8237 78 8238 78 8239 78 8240 78 8241 78 8242 78 8243 78 8244 78 \
+ 8245 78 8246 78 8247 78 8248 78 8249 78 8250 78 8251 78 8252 78 8253 78 \
+ 8254 78 8255 78 8256 78 8257 78 8258 78 8259 78 8260 78 8261 78 8262 78 \
+ 8263 78 8264 78 8265 78 8266 78 8267 78 8268 78 8269 78 8270 78 8271 78 \
+ 8272 78 8273 78 8274 78 8275 78 8276 78 8277 78 8278 78 8279 78 8280 78 \
+ 8281 78 8282 78 8283 78 8284 78 8285 78 8286 78 8287 78 8288 78 8289 78 \
+ 8290 78 8291 78 8292 78 8293 78 8294 78 8295 78 8296 78 8297 78 8298 78 \
+ 8299 78 8300 78 8301 78 8302 78 8303 78 8304 78 8305 78 8306 78 8307 78 \
+ 8308 78 8309 78 8310 78 8311 78 8312 78 8313 78 8314 78 8315 78 8316 78 \
+ 8317 78 8318 78 8319 78 8320 78 8321 78 8322 78 8323 78 8324 78 8325 78 \
+ 8326 78 8327 78 8328 78 8329 78 8330 78 8331 78 8332 78 8333 78 8334 78 \
+ 8335 78 8336 78 8337 78 8338 78 8339 78 8340 78 8341 78 8342 78 8343 78 \
+ 8344 78 8345 78 8346 78 8347 78 8348 78 8349 78 8350 78 8351 78 8352 78 \
+ 8353 78 8354 78 8355 78 8356 78 8357 78 8358 78 8359 78 8360 78 8361 78 \
+ 8362 78 8363 78 8364 78 8365 78 8366 78 8367 78 8368 78 8369 78 8370 78 \
+ 8371 78 8372 78 8373 78 8374 78 8375 78 8376 78 8377 78 8378 78 8379 78 \
+ 8380 78 8381 78 8382 78 8383 78 8384 78 8385 78 8386 78 8387 78 8388 78 \
+ 8389 78 8390 78 8391 78 8392 78 8393 78 8394 78 8395 78 8396 78 8397 78 \
+ 8398 78 8399 78 8400 78 8401 78 8402 78 8403 78 8404 78 8405 78 8406 78 \
+ 8407 78 8408 78 8409 78 8410 78 8411 78 8412 78 8413 78 8414 78 8415 78 \
+ 8416 78 8417 78 8418 78 8419 78 8420 78 8421 78 8422 78 8423 78 8424 78 \
+ 8425 78 8426 78 8427 78 8428 78 8429 78 8430 78 8431 78 8432 78 8433 78 \
+ 8434 78 8435 78 8436 78 8437 78 8438 78 8439 78 8440 78 8441 78 8442 78 \
+ 8443 78 8444 78 8445 78 8446 78 8447 78 8448 78 8449 78 8450 78 8451 78 \
+ 8452 78 8453 78 8454 78 8455 78 8456 78 8457 78 8458 78 8459 78 8460 78 \
+ 8461 78 8462 78 8463 78 8464 78 8465 78 8466 78 8467 78 8468 78 8469 78 \
+ 8470 78 8471 78 8472 78 8473 78 8474 78 8475 78 8476 78 8477 78 8478 78 \
+ 8479 78 8480 78 8481 78 8482 78 8483 78 8484 78 8485 78 8486 78 8487 78 \
+ 8488 78 8489 78 8490 78 8491 78 8492 78 8493 78 8494 78 8495 78 8496 78 \
+ 8497 78 8498 78 8499 78 8500 78 8501 78 8502 78 8503 78 8504 78 8505 78 \
+ 8506 78 8507 78 8508 78 8509 78 8510 78 8511 78 8512 78 8513 78 8514 78 \
+ 8515 78 8516 78 8517 78 8518 78 8519 78 8520 78 8521 78 8522 78 8523 78 \
+ 8524 78 8525 78 8526 78 8527 78 8528 78 8529 78 8530 78 8531 78 8532 78 \
+ 8533 78 8534 78 8535 78 8536 78 8537 78 8538 78 8539 78 8540 78 8541 78 \
+ 8542 78 8543 78 8544 78 8545 78 8546 78 8547 78 8548 78 8549 78 8550 78 \
+ 8551 78 8552 78 8553 78 8554 78 8555 78 8556 78 8557 78 8558 78 8559 78 \
+ 8560 78 8561 78 8562 78 8563 78 8564 78 8565 78 8566 78 8567 78 8568 78 \
+ 8569 78 8570 78 8571 78 8572 78 8573 78 8574 78 8575 78 8576 78 8577 78 \
+ 8578 78 8579 78 8580 78 8581 78 8582 78 8583 78 8584 78 8585 78 8586 78 \
+ 8587 78 8588 78 8589 78 8590 78 8591 78 8592 78 8593 78 8594 78 8595 78 \
+ 8596 78 8597 78 8598 78 8599 78 8600 78 8601 78 8602 78 8603 78 8604 78 \
+ 8605 78 8606 78 8607 78 8608 78 8609 78 8610 78 8611 78 8612 78 8613 78 \
+ 8614 78 8615 78 8616 78 8617 78 8618 78 8619 78 8620 78 8621 78 8622 78 \
+ 8623 78 8624 78 8625 78 8626 78 8627 78 8628 78 8629 78 8630 78 8631 78 \
+ 8632 78 8633 78 8634 78 8635 78 8636 78 8637 78 8638 78 8639 78 8640 78 \
+ 8641 78 8642 78 8643 78 8644 78 8645 78 8646 78 8647 78 8648 78 8649 78 \
+ 8650 78 8651 78 8652 78 8653 78 8654 78 8655 78 8656 78 8657 78 8658 78 \
+ 8659 78 8660 78 8661 78 8662 78 8663 78 8664 78 8665 78 8666 78 8667 78 \
+ 8668 78 8669 78 8670 78 8671 78 8672 78 8673 78 8674 78 8675 78 8676 78 \
+ 8677 78 8678 78 8679 78 8680 78 8681 78 8682 78 8683 78 8684 78 8685 78 \
+ 8686 78 8687 78 8688 78 8689 78 8690 78 8691 78 8692 78 8693 78 8694 78 \
+ 8695 78 8696 78 8697 78 8698 78 8699 78 8700 78 8701 78 8702 78 8703 106 \
+ ]
+
+set COMMON_PAGE_MAP 16
+
+#
+# The groupMap is indexed by combining the alternate page number with
+# the page offset and returns a group number that identifies a unique
+# set of character attributes.
+#
+
+set groupMap [list \
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 \
+ 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 \
+ 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 2 2 2 2 0 5 5 5 5 5 5 5 5 \
+ 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 6 2 2 2 2 2 2 2 2 2 \
+ 4 2 2 7 2 2 2 2 2 2 2 8 2 2 2 2 4 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 \
+ 3 3 3 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 9 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 2 4 4 4 4 4 4 4 4 10 4 10 4 10 4 10 4 10 4 10 4 10 \
+ 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 \
+ 10 4 10 4 10 4 10 4 11 4 10 4 10 4 10 4 4 10 4 10 4 10 4 10 4 10 4 \
+ 10 4 10 4 10 4 12 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 \
+ 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 13 \
+ 10 4 10 4 10 4 14 4 15 10 4 10 4 16 10 4 17 17 10 4 4 18 19 20 10 4 \
+ 17 21 4 22 23 10 4 4 4 22 24 4 25 10 4 10 4 10 4 26 10 4 26 4 4 10 \
+ 4 26 10 4 27 27 10 4 10 4 28 10 4 4 4 10 4 4 4 4 4 4 4 29 10 4 29 10 \
+ 4 29 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 4 10 4 10 4 10 4 \
+ 10 4 10 4 10 4 10 4 10 4 10 4 30 29 10 4 10 4 31 32 10 4 10 4 10 4 \
+ 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 \
+ 4 10 4 10 4 10 4 33 34 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 34 34 4 4 4 4 4 4 4 4 4 2 2 4 4 4 4 4 4 4 2 2 2 2 2 2 2 2 2 2 2 2 2 \
+ 2 4 4 2 2 2 2 2 2 2 2 2 2 2 2 2 2 4 4 4 4 4 2 2 2 2 2 2 2 2 2 4 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 2 2 2 2 2 2 2 2 2 2 \
+ 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 \
+ 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 35 35 2 2 2 36 2 2 2 2 2 2 \
+ 2 2 2 7 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 2 2 2 2 2 2 \
+ 2 2 2 2 2 2 2 2 2 2 34 34 34 34 2 2 34 34 34 34 37 34 34 34 2 34 34 \
+ 34 34 34 2 2 38 2 39 39 39 34 40 34 41 41 42 3 3 3 3 3 3 3 3 3 3 3 \
+ 3 3 3 3 3 3 34 3 3 3 3 3 3 3 3 3 4 4 4 4 43 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 10 4 4 4 4 4 4 4 4 4 4 4 4 34 44 45 46 47 48 49 50 4 10 4 \
+ 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 51 52 53 4 54 \
+ 55 2 34 34 34 34 34 34 34 34 34 56 56 56 56 56 56 56 56 56 56 56 56 \
+ 56 56 56 56 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 \
+ 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 10 4 10 4 10 4 10 4 10 4 10 4 10 \
+ 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 4 2 2 2 2 34 2 \
+ 2 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 \
+ 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 \
+ 4 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 34 10 4 10 4 10 4 10 4 10 4 \
+ 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 \
+ 4 34 34 10 4 34 34 34 34 34 34 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 \
+ 4 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 57 57 57 57 57 57 57 57 57 57 57 57 \
+ 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 \
+ 57 57 57 34 34 4 4 4 4 4 4 4 34 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 58 34 4 2 34 34 34 34 34 34 \
+ 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 34 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 \
+ 2 2 2 2 2 2 2 2 34 2 2 2 59 2 59 2 2 59 2 34 34 34 34 34 34 34 34 34 \
+ 34 34 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 \
+ 59 59 59 59 59 59 34 34 34 34 34 59 59 59 59 59 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 2 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 59 34 34 34 59 34 59 59 59 59 59 59 59 59 59 \
+ 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 34 34 34 34 34 59 \
+ 59 59 59 59 59 59 59 59 59 59 2 2 2 2 2 2 2 2 2 2 2 34 34 34 34 34 \
+ 34 34 34 34 34 2 2 2 2 2 2 2 2 2 2 2 2 2 59 59 59 2 59 59 59 59 59 \
+ 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 \
+ 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 \
+ 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 \
+ 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 \
+ 59 59 59 59 2 2 2 2 2 2 2 60 2 2 2 2 2 2 2 59 59 2 2 2 2 2 2 2 34 34 \
+ 2 2 2 2 2 2 2 2 2 2 59 59 59 59 59 34 59 59 59 59 59 59 59 59 59 59 \
+ 59 59 59 59 34 5 59 2 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 \
+ 59 59 59 59 59 59 59 59 59 59 59 59 34 34 34 2 2 2 2 2 2 2 2 2 2 2 \
+ 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 59 59 59 59 59 \
+ 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 \
+ 59 59 59 59 59 59 59 59 59 59 2 2 2 2 2 2 2 2 2 2 2 59 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 2 2 4 34 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 34 34 2 4 4 4 4 2 2 2 2 2 2 2 2 \
+ 4 4 4 4 2 34 34 4 2 2 2 2 34 34 34 4 4 4 4 4 4 4 4 4 4 2 2 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 2 \
+ 4 4 34 4 4 4 4 4 4 4 4 34 34 4 4 34 34 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 34 4 4 4 4 4 4 4 34 4 34 34 34 4 4 4 4 34 34 2 34 4 \
+ 4 4 2 2 2 2 34 34 4 4 34 34 4 4 2 34 34 34 34 34 34 34 34 34 4 34 34 \
+ 34 34 4 4 34 4 4 4 2 2 34 34 4 4 4 4 4 4 4 4 4 4 4 4 2 2 4 4 4 4 4 \
+ 4 4 34 34 34 34 34 34 34 2 34 34 4 4 4 4 4 4 34 34 34 34 4 4 34 34 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 34 4 4 4 4 4 4 4 34 4 4 \
+ 34 4 4 34 4 4 34 34 2 34 4 4 4 2 2 34 34 34 34 2 2 34 34 2 2 2 34 34 \
+ 34 34 34 34 34 34 34 34 34 4 4 4 4 34 4 34 34 34 34 34 34 34 4 4 4 \
+ 4 4 4 4 4 4 4 2 2 4 4 4 34 34 34 34 34 34 34 34 34 34 34 34 2 2 4 34 \
+ 4 4 4 4 4 4 4 34 4 34 4 4 4 34 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 34 4 4 4 4 4 4 4 34 4 4 34 4 4 4 4 4 34 34 2 4 4 4 4 2 2 2 \
+ 2 2 34 2 2 4 34 4 4 2 34 34 4 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 4 34 34 34 34 34 4 4 4 4 4 4 4 4 4 4 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 2 4 4 34 4 4 4 4 4 4 4 4 34 34 4 4 34 34 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 34 4 4 4 4 4 4 4 34 4 4 \
+ 34 34 4 4 4 4 34 34 2 4 4 2 4 2 2 2 34 34 34 4 4 34 34 4 4 2 34 34 \
+ 34 34 34 34 34 34 2 4 34 34 34 34 4 4 34 4 4 4 34 34 34 34 4 4 4 4 \
+ 4 4 4 4 4 4 4 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 2 \
+ 4 34 4 4 4 4 4 4 34 34 34 4 4 4 34 4 4 4 4 34 34 34 4 4 34 4 34 4 4 \
+ 34 34 34 4 4 34 34 34 4 4 4 34 34 34 4 4 4 4 4 4 4 4 34 4 4 4 34 34 \
+ 34 34 4 4 2 4 4 34 34 34 4 4 4 34 4 4 4 2 34 34 34 34 34 34 34 34 34 \
+ 4 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 34 34 34 34 34 34 34 34 34 34 34 34 34 34 4 4 4 34 4 4 4 4 4 4 \
+ 4 4 34 4 4 4 34 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 34 4 \
+ 4 4 4 4 4 4 4 4 4 34 4 4 4 4 4 34 34 34 34 2 2 2 4 4 4 4 34 2 2 2 34 \
+ 2 2 2 2 34 34 34 34 34 34 34 2 2 34 34 34 34 34 34 34 34 34 4 4 34 \
+ 34 34 34 4 4 4 4 4 4 4 4 4 4 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 4 4 34 4 4 4 4 4 4 4 4 34 4 4 4 34 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 34 4 4 4 4 4 4 4 4 4 4 34 4 4 4 4 4 34 \
+ 34 34 34 4 2 4 4 4 4 4 34 2 4 4 34 4 4 2 2 34 34 34 34 34 34 34 4 4 \
+ 34 34 34 34 34 34 34 4 34 4 4 34 34 34 34 4 4 4 4 4 4 4 4 4 4 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 4 4 34 4 4 4 4 4 4 \
+ 4 4 34 4 4 4 34 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 34 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 34 34 34 34 4 4 4 2 2 2 34 34 4 4 4 34 \
+ 4 4 4 2 34 34 34 34 34 34 34 34 34 4 34 34 34 34 34 34 34 34 4 4 34 \
+ 34 34 34 4 4 4 4 4 4 4 4 4 4 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 4 4 34 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 34 34 34 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 34 4 4 4 4 4 4 4 4 \
+ 4 34 4 34 34 4 4 4 4 4 4 4 34 34 34 2 34 34 34 34 4 4 4 2 2 2 34 2 \
+ 34 4 4 4 4 4 4 4 4 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 4 4 4 34 34 34 34 34 34 34 34 34 34 34 34 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 2 4 4 2 2 2 2 2 2 2 34 34 34 34 2 4 4 4 4 4 4 4 2 2 2 2 2 2 \
+ 2 2 4 4 4 4 4 4 4 4 4 4 4 4 4 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 4 4 34 4 34 34 4 4 34 4 34 34 4 34 34 34 34 34 34 4 4 4 4 34 4 4 \
+ 4 4 4 4 4 34 4 4 4 34 4 34 4 34 34 4 4 34 4 4 4 4 2 4 4 2 2 2 2 2 2 \
+ 34 2 2 4 34 34 4 4 4 4 4 34 4 34 2 2 2 2 2 2 34 34 4 4 4 4 4 4 4 4 \
+ 4 4 34 34 4 4 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 2 2 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 2 4 2 4 2 2 2 2 2 4 4 4 4 4 4 4 4 4 4 34 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 34 34 34 \
+ 34 34 34 2 2 2 2 2 2 2 2 2 2 2 2 2 2 4 2 2 2 2 2 4 2 2 4 4 4 4 34 34 \
+ 34 34 2 2 2 2 2 2 2 2 34 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 \
+ 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 34 4 4 4 4 4 4 4 4 2 4 4 4 4 4 4 34 34 \
+ 4 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 34 4 4 4 4 4 34 4 4 34 4 2 2 2 2 4 2 34 34 34 2 2 4 2 34 \
+ 34 34 34 34 34 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 2 2 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 34 34 34 34 34 34 34 34 34 34 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 34 34 4 34 \
+ 34 34 34 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 34 34 34 34 34 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 34 34 34 34 34 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 34 34 34 34 34 34 4 4 4 \
+ 4 4 4 4 34 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 34 4 34 4 4 4 4 34 34 4 4 4 4 4 4 4 34 4 34 4 4 4 4 34 34 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 34 4 34 4 4 4 4 34 34 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 34 4 34 4 4 4 4 34 34 4 4 4 4 4 4 4 34 4 34 4 4 4 \
+ 4 34 34 4 4 4 4 4 4 4 34 4 4 4 4 4 4 4 34 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 34 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 34 4 34 4 4 4 4 34 34 4 4 4 4 4 4 4 34 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 34 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 34 34 34 34 34 34 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 34 34 34 34 34 34 34 34 34 6 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 2 2 34 34 34 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 34 4 4 4 4 2 2 2 34 34 34 34 34 34 34 34 34 34 34 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 2 2 2 4 4 34 34 34 34 34 34 34 34 34 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 2 2 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 4 4 4 4 4 4 4 4 4 4 4 4 4 34 4 4 4 34 2 2 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 2 2 2 2 2 2 2 \
+ 4 4 4 4 4 4 4 4 2 4 4 2 2 2 2 2 2 2 2 2 2 2 4 4 4 4 4 4 4 2 4 34 34 \
+ 34 4 4 4 4 4 4 4 4 4 4 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 2 2 2 2 2 2 7 2 2 2 2 7 7 7 5 34 4 4 4 4 4 4 4 \
+ 4 4 4 34 34 34 34 34 34 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 34 \
+ 34 34 34 34 34 34 34 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 2 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 \
+ 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 \
+ 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 \
+ 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 \
+ 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 \
+ 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 61 62 63 64 \
+ 65 66 34 34 34 34 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 \
+ 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 \
+ 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 \
+ 10 4 10 4 10 4 10 4 10 4 10 4 10 4 10 4 34 34 34 34 34 34 4 4 4 4 4 \
+ 4 4 4 67 67 67 67 67 67 67 67 4 4 4 4 4 4 34 34 67 67 67 67 67 67 34 \
+ 34 4 4 4 4 4 4 4 4 67 67 67 67 67 67 67 67 4 4 4 4 4 4 4 4 67 67 67 \
+ 67 67 67 67 67 4 4 4 4 4 4 34 34 67 67 67 67 67 67 34 34 68 4 69 4 \
+ 70 4 71 4 34 67 34 67 34 67 34 67 4 4 4 4 4 4 4 4 67 67 67 67 67 67 \
+ 67 67 4 4 4 4 4 4 4 4 4 4 4 4 4 4 34 34 72 73 74 75 76 77 78 79 80 \
+ 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 \
+ 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 \
+ 4 4 120 121 122 34 123 124 67 67 125 125 126 2 127 2 2 2 128 129 130 \
+ 34 131 132 133 133 133 133 134 2 2 2 4 4 135 136 34 34 137 138 67 67 \
+ 139 139 34 2 2 2 4 4 140 141 142 4 143 144 67 67 145 145 146 2 2 2 \
+ 34 34 147 148 149 34 150 151 152 152 153 153 154 2 2 34 6 6 6 6 6 6 \
+ 6 6 6 6 6 155 156 156 157 158 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 \
+ 2 2 2 2 2 5 5 35 35 35 35 35 6 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 \
+ 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 34 34 34 34 2 34 34 34 34 34 34 34 \
+ 6 156 5 5 5 34 34 34 34 34 34 159 159 159 159 159 159 2 4 34 34 2 2 \
+ 2 2 2 2 2 2 2 2 2 4 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 2 2 2 2 2 2 2 2 160 2 2 2 2 2 2 2 \
+ 2 2 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 \
+ 2 2 2 2 2 2 2 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 2 2 161 162 2 2 2 163 2 164 4 165 166 167 4 4 168 169 170 \
+ 4 2 168 171 2 2 172 172 172 173 174 2 2 175 176 177 2 173 2 178 2 179 \
+ 2 180 181 182 182 2 4 183 183 2 184 4 4 4 4 4 4 2 34 34 4 185 186 2 \
+ 2 2 2 2 187 4 4 4 4 2 2 34 34 34 34 34 34 34 2 2 2 2 2 2 2 2 2 2 2 \
+ 2 2 188 188 188 188 188 188 188 188 188 188 188 188 188 188 188 188 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 \
+ 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 \
+ 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 \
+ 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 \
+ 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 \
+ 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 \
+ 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 \
+ 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 \
+ 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 2 2 2 2 2 2 \
+ 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 4 2 2 2 2 2 2 2 2 2 2 2 2 2 \
+ 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 \
+ 2 2 2 2 2 2 2 2 2 2 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 \
+ 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 2 2 2 2 2 2 2 2 2 2 \
+ 2 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 2 \
+ 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 \
+ 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 189 189 189 189 189 189 189 189 189 \
+ 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 2 2 2 2 2 2 2 2 \
+ 2 2 2 2 2 2 2 2 2 2 2 2 2 34 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 \
+ 2 34 34 2 2 34 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 \
+ 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 \
+ 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 \
+ 2 2 2 2 2 2 2 34 34 2 2 2 2 2 2 2 2 2 2 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 2 2 2 2 34 2 \
+ 2 2 2 34 34 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 \
+ 34 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 \
+ 2 2 2 34 2 34 2 2 2 2 34 34 34 2 34 2 2 2 2 2 2 2 34 34 2 2 2 2 2 2 \
+ 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 \
+ 2 2 2 2 2 2 2 2 2 2 2 2 34 34 34 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 \
+ 2 2 2 2 2 2 2 34 2 2 2 2 2 2 2 2 2 2 2 2 2 2 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 \
+ 2 2 2 2 2 2 2 2 34 34 34 34 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 \
+ 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 34 2 2 2 2 2 2 2 2 2 2 \
+ 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 \
+ 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 \
+ 2 2 2 2 2 2 2 2 2 2 2 34 34 34 34 34 34 34 34 34 34 34 34 2 2 2 2 2 \
+ 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 \
+ 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 \
+ 2 2 2 2 2 2 2 2 2 2 2 2 2 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 35 35 35 35 35 35 35 35 35 35 35 \
+ 35 34 34 34 34 6 2 2 2 2 4 4 4 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 \
+ 2 2 2 2 2 2 2 4 4 4 4 4 4 4 4 4 2 2 2 2 2 2 2 4 4 4 4 4 2 2 4 4 4 4 \
+ 4 2 2 2 34 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 34 34 2 2 2 2 4 4 4 \
+ 2 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 2 4 4 4 4 34 34 34 34 \
+ 34 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 34 34 34 34 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 34 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 34 34 34 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 34 34 34 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 2 2 2 2 \
+ 2 2 2 2 2 2 2 2 2 2 2 4 4 4 4 4 4 4 4 4 4 4 4 34 34 34 34 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 34 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 190 4 191 4 192 4 34 34 34 \
+ 34 4 4 4 4 4 193 194 195 196 197 198 199 200 4 4 201 202 203 4 4 4 \
+ 204 205 206 207 208 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 209 210 \
+ 211 212 4 4 4 4 4 4 4 213 214 215 216 217 218 219 220 221 222 223 224 \
+ 225 226 4 227 4 4 228 229 230 231 4 232 4 233 234 4 4 4 4 4 4 4 4 235 \
+ 4 236 237 4 238 239 34 34 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 34 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 4 4 4 4 4 4 4 4 4 4 4 4 4 34 34 34 2 2 2 2 2 2 2 2 2 \
+ 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 \
+ 2 2 2 2 2 2 2 2 2 2 2 2 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 157 \
+ 157 157 157 157 157 157 157 157 157 157 157 157 157 157 157 157 157 \
+ 157 157 157 157 157 157 157 157 157 157 157 157 157 157 157 157 157 \
+ 157 157 157 157 157 157 157 157 157 157 157 157 157 157 157 157 157 \
+ 157 157 157 157 157 157 157 157 157 157 157 157 157 157 157 157 157 \
+ 157 157 157 157 157 157 157 157 157 157 157 157 157 157 157 157 157 \
+ 157 157 157 157 157 157 157 157 157 157 157 157 157 157 157 157 157 \
+ 157 157 157 157 157 157 157 157 157 157 157 157 157 157 157 157 157 \
+ 157 157 157 157 157 157 157 157 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 34 34 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 240 241 242 243 244 245 246 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 247 248 249 250 251 34 34 34 34 \
+ 34 59 2 59 59 59 59 59 59 59 59 59 59 2 59 59 59 59 59 59 59 59 59 \
+ 59 59 59 59 34 59 59 59 59 59 34 59 34 59 59 34 59 59 34 59 59 59 59 \
+ 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 \
+ 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 \
+ 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 \
+ 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 \
+ 59 59 59 59 59 59 59 59 59 59 59 59 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 59 \
+ 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 \
+ 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 \
+ 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 \
+ 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 \
+ 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 \
+ 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 \
+ 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 \
+ 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 \
+ 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 \
+ 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 \
+ 59 59 59 59 2 2 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 59 \
+ 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 \
+ 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 \
+ 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 34 34 59 59 59 59 \
+ 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 \
+ 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 \
+ 59 59 59 59 34 34 34 34 34 34 34 34 35 35 35 35 35 35 35 35 35 35 35 \
+ 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 59 59 \
+ 59 59 59 59 59 59 59 59 59 59 59 34 34 34 7 7 7 7 7 7 7 7 7 7 7 7 7 \
+ 7 7 7 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 2 2 2 2 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 \
+ 2 2 2 2 34 34 2 2 2 2 2 2 2 2 2 2 34 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 \
+ 2 2 2 2 34 2 2 2 2 34 34 34 34 59 59 59 59 59 34 59 59 59 59 59 59 \
+ 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 \
+ 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 \
+ 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 \
+ 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 \
+ 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 \
+ 59 59 59 59 59 59 59 59 59 59 59 59 59 59 34 34 156 34 2 2 2 2 2 2 \
+ 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 \
+ 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 2 2 2 2 2 2 2 2 2 2 2 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 34 34 34 4 4 4 4 4 4 34 34 4 4 4 4 4 4 \
+ 34 34 4 4 4 4 4 4 34 34 4 4 4 34 34 34 2 2 2 2 2 2 2 34 2 2 2 2 2 2 \
+ 2 34 34 34 34 34 34 34 34 34 34 159 159 159 159 35 35 35 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 34 4 4 4 4 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 252 252 252 252 252 252 252 \
+ 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 \
+ 252 252 252 252 252 252 252 252 252 252 252 252 252 252 34 34 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 34 34 34 34 34 34 34 \
+ 34 34 34 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 34 34 34 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 2 2 2 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 2 2 2 2 2 2 \
+ 2 2 4 4 2 2 2 2 2 2 2 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 2 2 2 2 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 253 253 253 253 253 253 253 253 253 253 253 253 253 \
+ 253 253 253 253 253 253 253 253 253 253 253 253 253 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 254 254 254 254 254 254 254 254 \
+ 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 \
+ 254 4 4 4 4 4 4 4 34 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 255 255 255 \
+ 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 \
+ 255 255 255 255 255 255 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 256 34 256 256 34 34 256 34 34 256 256 34 34 256 256 256 256 \
+ 34 256 256 256 256 256 256 256 256 4 4 4 4 34 4 34 4 4 4 4 34 4 4 34 \
+ 4 4 4 4 4 4 4 4 4 4 4 257 257 257 257 257 257 257 257 257 257 257 257 \
+ 257 257 257 257 257 257 257 257 257 257 257 257 257 257 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 258 258 34 258 258 258 258 \
+ 34 34 258 258 258 258 258 258 258 258 34 258 258 258 258 258 258 258 \
+ 34 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 259 259 34 259 \
+ 259 259 259 34 259 259 259 259 259 34 259 34 34 34 259 259 259 259 \
+ 259 259 259 34 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 260 260 260 260 260 260 260 260 260 260 260 260 260 260 260 260 260 \
+ 260 260 260 260 260 260 260 260 260 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 261 261 261 261 261 261 261 261 261 261 261 261 \
+ 261 261 261 261 261 261 261 261 261 261 261 261 261 261 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 262 262 262 262 262 262 262 \
+ 262 262 262 262 262 262 262 262 262 262 262 262 262 262 262 262 262 \
+ 262 262 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 263 263 \
+ 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 \
+ 263 263 263 263 263 263 263 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 264 264 264 264 264 264 264 264 264 264 264 264 264 264 \
+ 264 264 264 264 264 264 264 264 264 264 264 264 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 265 265 265 265 265 265 265 265 265 \
+ 265 265 265 265 265 265 265 265 265 265 265 265 265 265 265 265 265 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 34 34 34 34 266 \
+ 266 266 266 266 266 266 266 266 266 266 266 266 266 266 266 266 267 \
+ 266 266 266 266 266 266 266 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 268 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 269 269 269 269 269 269 269 269 269 269 \
+ 269 269 269 269 269 269 269 270 269 269 269 269 269 269 269 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 271 4 4 4 4 4 4 4 4 4 4 4 4 4 4 272 272 \
+ 272 272 272 272 272 272 272 272 272 272 272 272 272 272 272 273 272 \
+ 272 272 272 272 272 272 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 274 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 275 275 275 275 275 275 275 275 275 275 275 \
+ 275 275 275 275 275 275 276 275 275 275 275 275 275 275 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 277 4 4 4 4 4 4 4 4 4 4 4 4 4 4 278 278 278 \
+ 278 278 278 278 278 278 278 278 278 278 278 278 278 278 279 278 278 \
+ 278 278 278 278 278 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 280 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 34 34 34 34 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 \
+ 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 35 35 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 \
+ 4 4 4 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 4 4 4 4 \
+ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 35 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 \
+ 34 34 34 34 34 34 34 34 34 34 35 35 35 35 35 35 35 35 35 35 35 35 35 \
+ 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 \
+ 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 \
+ 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 \
+ 35 35 35 35 35 35 35 35 35 35 35 35 35 35 157 157 157 157 157 157 157 \
+ 157 157 157 157 157 157 157 157 157 157 157 157 157 157 157 157 157 \
+ 157 157 157 157 157 157 157 157 157 157 157 157 157 157 157 157 157 \
+ 157 157 157 157 157 157 157 157 157 157 157 157 157 157 157 157 157 \
+ 157 157 157 157 157 157 157 157 157 157 157 157 157 157 157 157 157 \
+ 157 157 157 157 157 157 157 157 157 157 157 157 157 157 157 157 157 \
+ 157 157 157 157 157 157 157 157 157 157 157 157 157 157 157 157 157 \
+ 157 157 157 157 157 157 157 157 157 157 157 157 157 157 157 157 157 \
+ 35 35]
+
+#
+# Each group represents a unique set of character attributes. The attributes
+# are encoded into a 32-bit value as follows:
+#
+# Bit 0 A.1
+#
+# Bit 1 B.1
+#
+# Bit 2 B.3
+#
+# Bit 3 C.1.1
+#
+# Bit 4 C.1.2
+#
+# Bit 5 C.2.1
+#
+# Bit 6 C.2.2
+#
+# Bit 7 C.3--C.9
+#
+# Bit 8 D.1
+#
+# Bit 9 D.2
+#
+# Bit 10 Case maps to several characters
+#
+# Bits 11-31 Case delta: delta for case conversions. This should be the
+# highest field so we can easily sign extend.
+#
+
+set groups [list \
+ 32 8 0 66052 512 64 16 2 1587716 1540 2564 3588 5636 -247292 -548348 \
+ 430596 422404 420356 162308 414212 416260 424452 432644 428548 \
+ 436740 438788 446980 444932 449028 4612 7684 -198140 -114172 -265724 \
+ 1 128 237572 9728 78340 76292 131588 129540 11780 13828 -60924 \
+ -50684 -26112 -11776 -17920 -30204 -44540 -110076 -97788 -95740 \
+ -122364 -130556 164356 98820 15876 256 320 17924 19972 22020 24068 \
+ 26116 -118268 -15868 28164 30212 32260 34308 36356 38404 40452 \
+ 42500 44548 46596 48644 50692 52740 54788 56836 58884 60932 62980 \
+ 65028 67076 69124 71172 73220 75268 77316 79364 81412 83460 85508 \
+ 87556 89604 91652 93700 95748 97796 99844 101892 103940 105988 \
+ 108036 110084 112132 114180 116228 118276 120324 122372 124420 \
+ 126468 128516 130564 132612 134660 136708 138756 140804 142852 \
+ -151036 144900 -14689788 146948 148996 151044 153092 155140 -175612 \
+ 157188 159236 161284 163332 165380 -204284 167428 169476 171524 \
+ 173572 175620 -228860 -13820 177668 179716 181764 183812 185860 \
+ -261628 -257532 187908 18 66 640 384 192 189440 -17102336 191488 \
+ -16080384 193536 -17110528 -17112576 -17114624 -17118720 -17120768 \
+ -17116672 195584 -17122816 -17124864 -17126912 197632 199680 201728 \
+ -15394300 -17133056 -17167868 -16920060 -17190400 -17192448 -17182208 \
+ -15488512 -15463936 -17237504 33284 53764 204288 206336 208384 \
+ 210432 212480 214528 216576 218624 220672 222720 224768 226816 \
+ 228864 230912 232960 235008 237056 239104 241152 243200 245248 \
+ 247296 249344 251392 253440 255488 257536 259584 261632 263680 \
+ 265728 267776 269824 271872 273920 275968 278016 280064 282112 \
+ 284160 286208 288256 290304 292352 294400 296448 298496 300544 \
+ 302592 304640 306692 308740 310788 312836 314884 316932 318980 \
+ 321028 323076 325124 327172 329220 82436 -245167616 -245274112 \
+ -245380608 -245487104 -245593600 -245700096 -245806592 -245913088 \
+ -246019584 -246126080 -246232576 -246339072 -246445568 -244823552 \
+ -244844032 -244874752 -244942336 -244962816 -244993536 -245061120 \
+ -245081600 -245112320 -245179904 -245200384 -245231104 -245298688 \
+ -245319168 -245349888]
+
+#
+# Table for characters that lowercased to multiple ones
+#
+
+set multiCaseTable [list \
+ {115 115} \
+ {105 775} \
+ {700 110} \
+ {106 780} \
+ {32 953} \
+ {953 776 769} \
+ {965 776 769} \
+ {1381 1410} \
+ {104 817} \
+ {116 776} \
+ {119 778} \
+ {121 778} \
+ {97 702} \
+ {965 787} \
+ {965 787 768} \
+ {965 787 769} \
+ {965 787 834} \
+ {7936 953} \
+ {7937 953} \
+ {7938 953} \
+ {7939 953} \
+ {7940 953} \
+ {7941 953} \
+ {7942 953} \
+ {7943 953} \
+ {7936 953} \
+ {7937 953} \
+ {7938 953} \
+ {7939 953} \
+ {7940 953} \
+ {7941 953} \
+ {7942 953} \
+ {7943 953} \
+ {7968 953} \
+ {7969 953} \
+ {7970 953} \
+ {7971 953} \
+ {7972 953} \
+ {7973 953} \
+ {7974 953} \
+ {7975 953} \
+ {7968 953} \
+ {7969 953} \
+ {7970 953} \
+ {7971 953} \
+ {7972 953} \
+ {7973 953} \
+ {7974 953} \
+ {7975 953} \
+ {8032 953} \
+ {8033 953} \
+ {8034 953} \
+ {8035 953} \
+ {8036 953} \
+ {8037 953} \
+ {8038 953} \
+ {8039 953} \
+ {8032 953} \
+ {8033 953} \
+ {8034 953} \
+ {8035 953} \
+ {8036 953} \
+ {8037 953} \
+ {8038 953} \
+ {8039 953} \
+ {8048 953} \
+ {945 953} \
+ {940 953} \
+ {945 834} \
+ {945 834 953} \
+ {945 953} \
+ {8052 953} \
+ {951 953} \
+ {942 953} \
+ {951 834} \
+ {951 834 953} \
+ {951 953} \
+ {953 776 768} \
+ {953 776 769} \
+ {953 834} \
+ {953 776 834} \
+ {965 776 768} \
+ {965 776 769} \
+ {961 787} \
+ {965 834} \
+ {965 776 834} \
+ {8060 953} \
+ {969 953} \
+ {974 953} \
+ {969 834} \
+ {969 834 953} \
+ {969 953} \
+ {114 115} \
+ {176 99} \
+ {176 102} \
+ {110 111} \
+ {115 109} \
+ {116 101 108} \
+ {116 109} \
+ {104 112 97} \
+ {97 117} \
+ {111 118} \
+ {112 97} \
+ {110 97} \
+ {956 97} \
+ {109 97} \
+ {107 97} \
+ {107 98} \
+ {109 98} \
+ {103 98} \
+ {112 102} \
+ {110 102} \
+ {956 102} \
+ {104 122} \
+ {107 104 122} \
+ {109 104 122} \
+ {103 104 122} \
+ {116 104 122} \
+ {112 97} \
+ {107 112 97} \
+ {109 112 97} \
+ {103 112 97} \
+ {112 118} \
+ {110 118} \
+ {956 118} \
+ {109 118} \
+ {107 118} \
+ {109 118} \
+ {112 119} \
+ {110 119} \
+ {956 119} \
+ {109 119} \
+ {107 119} \
+ {109 119} \
+ {107 969} \
+ {109 969} \
+ {98 113} \
+ {99 8725 107 103} \
+ {99 111 46} \
+ {100 98} \
+ {103 121} \
+ {104 112} \
+ {107 107} \
+ {107 109} \
+ {112 104} \
+ {112 112 109} \
+ {112 114} \
+ {115 118} \
+ {119 98} \
+ {102 102} \
+ {102 105} \
+ {102 108} \
+ {102 102 105} \
+ {102 102 108} \
+ {115 116} \
+ {115 116} \
+ {1396 1398} \
+ {1396 1381} \
+ {1396 1387} \
+ {1406 1398} \
+ {1396 1389} \
+]
+
+#
+# The following constants are used to determine the category of a
+# Unicode character.
+#
+
+set A1Mask [expr {1 << 0}]
+set B1Mask [expr {1 << 1}]
+set B3Mask [expr {1 << 2}]
+set C11Mask [expr {1 << 3}]
+set C12Mask [expr {1 << 4}]
+set C21Mask [expr {1 << 5}]
+set C22Mask [expr {1 << 6}]
+set C39Mask [expr {1 << 7}]
+set D1Mask [expr {1 << 8}]
+set D2Mask [expr {1 << 9}]
+set MCMask [expr {1 << 10}]
+
+#
+# The following procs extract the fields of the character info.
+#
+
+proc GetCaseType {info} {expr {($info & 0xE0) >> 5}}
+proc GetCategory {info} {expr {$info & 0x1F}}
+proc GetDelta {info} {expr {$info >> 11}}
+proc GetMC {info} {
+ variable multiCaseTable
+ lindex $multiCaseTable [GetDelta $info]
+}
+
+#
+# This proc extracts the information about a character from the
+# Unicode character tables.
+#
+
+proc GetUniCharInfo {uc} {
+ variable OFFSET_BITS
+ variable COMMON_PAGE_MAP
+ variable pageMap
+ variable groupMap
+ variable groups
+
+ set page [expr {($uc & 0x1fffff) >> $OFFSET_BITS}]
+ if {[info exists pageMap($page)]} {
+ set apage $pageMap($page)
+ } else {
+ set apage $COMMON_PAGE_MAP
+ }
+
+ lindex $groups \
+ [lindex $groupMap \
+ [expr {($apage << $OFFSET_BITS) | \
+ ($uc & ((1 << $OFFSET_BITS) - 1))}]]
+}
+
+} ; # namespace eval ::stringprep::data
+
diff --git a/tcllib/modules/stringprep/tools/gen_stringprep_data.tcl b/tcllib/modules/stringprep/tools/gen_stringprep_data.tcl
new file mode 100644
index 0000000..9b30a6e
--- /dev/null
+++ b/tcllib/modules/stringprep/tools/gen_stringprep_data.tcl
@@ -0,0 +1,524 @@
+#!/usr/bin/env tclsh
+
+# gen_stringprep_data.tcl --
+#
+# This program parses the RFC 3454 file and generates the
+# corresponding stringprep_data.tcl file with compressed character
+# data tables. The input to this program should be rfc3454.txt.
+# It can be downloaded from http://www.ietf.org/rfc/rfc3454.txt
+#
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# All rights reserved.
+#
+# Modified for ejabberd by Alexey Shchepin
+# Modified for Tcl stringprep by Sergei Golovan
+#
+# Usage: gen_stringprep_data.tcl infile outdir
+#
+# RCS: @(#) $Id: gen_stringprep_data.tcl,v 1.2 2009/11/02 00:26:44 patthoyts Exp $
+
+
+namespace eval uni {
+ set shift 7; # number of bits of data within a page
+ # This value can be adjusted to find the
+ # best split to minimize table size
+
+ variable pMap; # map from page to page index, each entry is
+ # an index into the pages table, indexed by
+ # page number
+ variable pages; # map from page index to page info, each
+ # entry is a list of indices into the groups
+ # table, the list is indexed by the offset
+ variable groups; # list of character info values, indexed by
+ # group number, initialized with the
+ # unassigned character group
+}
+
+proc uni::getValue {i} {
+ variable casemap
+ variable casemap2
+ variable tablemap
+
+ if {[info exists tablemap($i)]} {
+ set tables $tablemap($i)
+ } else {
+ set tables {}
+ }
+
+ if {[info exists casemap2($i)]} {
+ set multicase 1
+ set delta $casemap2($i)
+ } else {
+ set multicase 0
+ if {[info exists casemap($i)]} {
+ set delta $casemap($i)
+ } else {
+ set delta 0
+ }
+ }
+
+ if {abs($delta) > 0xFFFFF} {
+ puts "delta must be less than 22 bits wide"
+ exit
+ }
+
+ set a1 0
+ set b1 0
+ set b2 0
+ set b3 0
+ set c11 0
+ set c12 0
+ set c21 0
+ set c22 0
+ set c3 0
+ set c4 0
+ set c5 0
+ set c6 0
+ set c7 0
+ set c8 0
+ set c9 0
+ set d1 0
+ set d2 0
+
+ foreach tab $tables {
+ switch -glob -- $tab {
+ A.1 {set a1 1}
+ B.1 {set b1 1}
+ B.2 {set b2 1}
+ B.3 {set b3 1}
+ C.1.1 {set c11 1}
+ C.1.2 {set c12 1}
+ C.2.1 {set c21 1}
+ C.2.2 {set c22 1}
+ C.3 {set c3 1}
+ C.4 {set c4 1}
+ C.5 {set c5 1}
+ C.6 {set c6 1}
+ C.7 {set c7 1}
+ C.8 {set c8 1}
+ C.9 {set c9 1}
+ D.1 {set d1 1}
+ D.2 {set d2 1}
+ }
+ }
+
+ set val [expr {($a1 << 0) |
+ ($b1 << 1) |
+ ($b3 << 2) |
+ ($c11 << 3) |
+ ($c12 << 4) |
+ ($c21 << 5) |
+ ($c22 << 6) |
+ (($c3 | $c4 | $c5 | $c6 | $c7 | $c8 | $c9) << 7) |
+ ($d1 << 8) |
+ ($d2 << 9) |
+ ($multicase << 10) |
+ ($delta << 11)}]
+
+ return $val
+}
+
+proc uni::getGroup {value} {
+ variable groups
+
+ set gIndex [lsearch -exact $groups $value]
+ if {$gIndex == -1} {
+ set gIndex [llength $groups]
+ lappend groups $value
+ }
+ return $gIndex
+}
+
+proc uni::addPage {info} {
+ variable pMap
+ variable pages
+ variable pages_map
+
+ if {[info exists pages_map($info)]} {
+ lappend pMap $pages_map($info)
+ } else {
+ set pIndex [llength $pages]
+ lappend pages $info
+ set pages_map($info) $pIndex
+ lappend pMap $pIndex
+ }
+ return
+}
+
+
+proc uni::load_tables {data} {
+ variable casemap
+ variable casemap2
+ variable multicasemap
+ variable tablemap
+
+ set multicasemap {}
+ set table ""
+
+ foreach line [split $data \n] {
+ if {$table == ""} {
+ if {[regexp { ----- Start Table (.*) -----} $line temp table]} {
+ #puts "Start table '$table'"
+ }
+ } else {
+ if {[regexp { ----- End Table (.*) -----} $line temp table1]} {
+ set table ""
+ } else {
+ if {$table == "B.1"} {
+ if {[regexp {^ ([[:xdigit:]]+); ;} $line \
+ temp val]} {
+ scan $val %x val
+ if {$val <= 0x10ffff} {
+ lappend tablemap($val) $table
+ }
+ }
+ } elseif {$table == "B.2"} {
+ # B.2 table is used for mapping with normalisation
+ if {[regexp {^ ([[:xdigit:]]+); ([[:xdigit:]]+);} $line \
+ temp from to]} {
+ scan $from %x from
+ scan $to %x to
+ if {$from <= 0x10ffff && $to <= 0x10ffff} {
+ set casemap($from) [expr {$to - $from}]
+ }
+ } elseif {[regexp {^ ([[:xdigit:]]+); ([[:xdigit:]]+) ([[:xdigit:]]+);} $line \
+ temp from to1 to2]} {
+ scan $from %x from
+ scan $to1 %x to1
+ scan $to2 %x to2
+ if {$from <= 0x10ffff && \
+ $to1 <= 0x10ffff && $to2 <= 0x10ffff} {
+ set casemap2($from) [llength $multicasemap]
+ lappend multicasemap [list $to1 $to2]
+ }
+ } elseif {[regexp {^ ([[:xdigit:]]+); ([[:xdigit:]]+) ([[:xdigit:]]+) ([[:xdigit:]]+);} $line \
+ temp from to1 to2 to3]} {
+ scan $from %x from
+ scan $to1 %x to1
+ scan $to2 %x to2
+ scan $to3 %x to3
+ if {$from <= 0x10ffff && \
+ $to1 <= 0x10ffff && $to2 <= 0x10ffff && \
+ $to3 <= 0x10ffff} {
+ set casemap2($from) [llength $multicasemap]
+ lappend multicasemap [list $to1 $to2 $to3]
+ }
+ } elseif {[regexp {^ ([[:xdigit:]]+); ([[:xdigit:]]+) ([[:xdigit:]]+) ([[:xdigit:]]+) ([[:xdigit:]]+);} $line \
+ temp from to1 to2 to3 to4]} {
+ scan $from %x from
+ scan $to1 %x to1
+ scan $to2 %x to2
+ scan $to3 %x to3
+ scan $to4 %x to4
+ if {$from <= 0x10ffff && \
+ $to1 <= 0x10ffff && $to2 <= 0x10ffff && \
+ $to3 <= 0x10ffff && $to4 <= 0x10ffff} {
+ set casemap2($from) [llength $multicasemap]
+ lappend multicasemap [list $to1 $to2 $to3 $to4]
+ }
+ } else {
+ #puts "missed: $line"
+ }
+
+ } elseif {$table == "B.3"} {
+ # B.3 table is used for mapping without normalisation (B.3 is a subset of B.2)
+ if {[regexp {^ ([[:xdigit:]]+);} $line temp from]} {
+ scan $from %x from
+ if {$from <= 0x10ffff} {
+ lappend tablemap($from) $table
+ }
+ }
+ } else {
+ if {[regexp {^ ([[:xdigit:]]+)-([[:xdigit:]]+)} $line \
+ temp from to]} {
+ scan $from %x from
+ scan $to %x to
+ for {set i $from} {$i <= $to && $i <= 0x10ffff} {incr i} {
+ lappend tablemap($i) $table
+ }
+ } elseif {[regexp {^ ([[:xdigit:]]+)} $line \
+ temp val]} {
+ scan $val %x val
+ if {$val <= 0x10ffff} {
+ lappend tablemap($val) $table
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+proc uni::buildTables {} {
+ variable shift
+
+ variable casemap
+ variable tablemap
+
+ variable pMap {}
+ variable pages {}
+ variable groups {}
+ set info {} ;# temporary page info
+
+ set mask [expr {(1 << $shift) - 1}]
+
+ set next 0
+
+ for {set i 0} {$i <= 0x10ffff} {incr i} {
+ set gIndex [getGroup [getValue $i]]
+
+ # Split character index into offset and page number
+ set offset [expr {$i & $mask}]
+ set page [expr {($i >> $shift)}]
+
+ # Add the group index to the info for the current page
+ lappend info $gIndex
+
+ # If this is the last entry in the page, add the page
+ if {$offset == $mask} {
+ addPage $info
+ set info {}
+ }
+ }
+ return
+}
+
+proc uni::main {} {
+ global argc argv0 argv
+ variable pMap
+ variable pages
+ variable groups
+ variable shift
+ variable multicasemap
+
+ if {$argc != 2} {
+ puts stderr "\nusage: $argv0 <datafile> <outdir>\n"
+ exit 1
+ }
+ set f [open [lindex $argv 0] r]
+ set data [read $f]
+ close $f
+
+ load_tables $data
+ buildTables
+ #puts "X = [llength $pMap] Y= [llength $pages] A= [llength $groups]"
+ #set size [expr {[llength $pMap] + [llength $pages]*(1<<$shift)}]
+ #puts "shift = $shift, space = $size"
+
+ set f [open [file join [lindex $argv 1] stringprep_data.tcl] w]
+ fconfigure $f -translation lf
+ puts $f \
+"# stringprep_data.tcl --
+#
+# Declarations of Unicode character information tables. This file is
+# automatically generated by the gen_stringprep_data.tcl script. Do not
+# modify this file by hand.
+#
+# Copyright (c) 1998 Scriptics Corporation.
+# Copyright (c) 2007 Alexey Shchepin
+# Copyright (c) 2008 Sergei Golovan
+#
+# RCS: @(#) \$Id\$
+#
+
+package provide stringprep::data 1.0.1
+
+namespace eval ::stringprep::data {
+
+#
+# A 16-bit Unicode character is split into two parts in order to index
+# into the following tables. The lower OFFSET_BITS comprise an offset
+# into a page of characters. The upper bits comprise the page number.
+#
+
+set OFFSET_BITS $shift
+
+#
+# The pageMap is indexed by page number and returns an alternate page number
+# that identifies a unique page of characters. Many Unicode characters map
+# to the same alternate page number.
+#
+
+array unset pageMap
+array set pageMap \[list \\"
+ array unset tmp
+ foreach idx $pMap {
+ if {![info exists tmp($idx)]} {
+ set tmp($idx) 1
+ } else {
+ incr tmp($idx)
+ }
+ }
+ set max 0
+ set max_id 0
+ foreach idx [array names tmp] {
+ if {$tmp($idx) > $max} {
+ set max $tmp($idx)
+ set max_id $idx
+ }
+ }
+ set line " "
+ set last [expr {[llength $pMap] - 1}]
+ for {set i 0} {$i <= $last} {incr i} {
+ set num [lindex $pMap $i]
+ if {$num != $max_id} {
+ append line " $i $num"
+ }
+ if {[string length $line] > 70} {
+ puts $f "$line \\"
+ set line " "
+ }
+ }
+ puts $f "$line\]
+
+set COMMON_PAGE_MAP $max_id
+
+#
+# The groupMap is indexed by combining the alternate page number with
+# the page offset and returns a group number that identifies a unique
+# set of character attributes.
+#
+
+set groupMap \[list \\"
+ set line " "
+ set lasti [expr {[llength $pages] - 1}]
+ for {set i 0} {$i <= $lasti} {incr i} {
+ set page [lindex $pages $i]
+ set lastj [expr {[llength $page] - 1}]
+ for {set j 0} {$j <= $lastj} {incr j} {
+ append line [lindex $page $j]
+ if {$j != $lastj || $i != $lasti} {
+ append line " "
+ }
+ if {[string length $line] > 70} {
+ puts $f "$line\\"
+ set line " "
+ }
+ }
+ }
+ puts $f "$line\]
+
+#
+# Each group represents a unique set of character attributes. The attributes
+# are encoded into a 32-bit value as follows:
+#
+# Bit 0 A.1
+#
+# Bit 1 B.1
+#
+# Bit 2 B.3
+#
+# Bit 3 C.1.1
+#
+# Bit 4 C.1.2
+#
+# Bit 5 C.2.1
+#
+# Bit 6 C.2.2
+#
+# Bit 7 C.3--C.9
+#
+# Bit 8 D.1
+#
+# Bit 9 D.2
+#
+# Bit 10 Case maps to several characters
+#
+# Bits 11-31 Case delta: delta for case conversions. This should be the
+# highest field so we can easily sign extend.
+#
+
+set groups \[list \\"
+ set line " "
+ set last [expr {[llength $groups] - 1}]
+ for {set i 0} {$i <= $last} {incr i} {
+ set val [lindex $groups $i]
+
+ append line [format "%d" $val]
+ if {$i != $last} {
+ append line " "
+ }
+ if {[string length $line] > 65} {
+ puts $f "$line\\"
+ set line " "
+ }
+ }
+ puts $f "$line\]
+
+#
+# Table for characters that lowercased to multiple ones
+#
+
+set multiCaseTable \[list \\"
+ set last [expr {[llength $multicasemap] - 1}]
+ for {set i 0} {$i <= $last} {incr i} {
+ set val [lindex $multicasemap $i]
+
+ set line " "
+ append line "{" [join $val " "] "}"
+ puts $f "$line \\"
+ }
+ puts $f "\]
+
+#
+# The following constants are used to determine the category of a
+# Unicode character.
+#
+
+set A1Mask \[expr {1 << 0}\]
+set B1Mask \[expr {1 << 1}\]
+set B3Mask \[expr {1 << 2}\]
+set C11Mask \[expr {1 << 3}\]
+set C12Mask \[expr {1 << 4}\]
+set C21Mask \[expr {1 << 5}\]
+set C22Mask \[expr {1 << 6}\]
+set C39Mask \[expr {1 << 7}\]
+set D1Mask \[expr {1 << 8}\]
+set D2Mask \[expr {1 << 9}\]
+set MCMask \[expr {1 << 10}\]
+
+#
+# The following procs extract the fields of the character info.
+#
+
+proc GetCaseType {info} {expr {(\$info & 0xE0) >> 5}}
+proc GetCategory {info} {expr {\$info & 0x1F}}
+proc GetDelta {info} {expr {\$info >> 11}}
+proc GetMC {info} {
+ variable multiCaseTable
+ lindex \$multiCaseTable \[GetDelta \$info\]
+}
+
+#
+# This proc extracts the information about a character from the
+# Unicode character tables.
+#
+
+proc GetUniCharInfo {uc} {
+ variable OFFSET_BITS
+ variable COMMON_PAGE_MAP
+ variable pageMap
+ variable groupMap
+ variable groups
+
+ set page \[expr {(\$uc & 0x1fffff) >> \$OFFSET_BITS}\]
+ if {\[info exists pageMap(\$page)\]} {
+ set apage \$pageMap(\$page)
+ } else {
+ set apage \$COMMON_PAGE_MAP
+ }
+
+ lindex \$groups \\
+ \[lindex \$groupMap \\
+ \[expr {(\$apage << \$OFFSET_BITS) | \\
+ (\$uc & ((1 << \$OFFSET_BITS) - 1))}\]\]
+}
+
+} ; # namespace eval ::stringprep::data
+"
+ close $f
+}
+
+uni::main
+
+return
diff --git a/tcllib/modules/stringprep/tools/gen_unicode_data.tcl b/tcllib/modules/stringprep/tools/gen_unicode_data.tcl
new file mode 100644
index 0000000..5b61faa
--- /dev/null
+++ b/tcllib/modules/stringprep/tools/gen_unicode_data.tcl
@@ -0,0 +1,867 @@
+#!/usr/bin/env tclsh
+
+# gen_unicode_data.tcl --
+#
+# This program parses the UnicodeData files and generates the
+# corresponding unicode_data.tcl file with compressed character
+# data tables. The input to this program should be
+# UnicodeData.txt and CompositionExclusions.txt files
+# from: ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt
+# and ftp://ftp.unicode.org/Public/UNIDATA/CompositionExclusions.txt
+#
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# All rights reserved.
+#
+# Modified for ejabberd by Alexey Shchepin
+# Modified for Tcl stringprep by Sergei Golovan
+#
+# Usage: gen_unicode_data.tcl infile1 infile2 outdir
+#
+# RCS: @(#) $Id: gen_unicode_data.tcl,v 1.1 2008/01/29 02:18:10 patthoyts Exp $
+
+
+namespace eval uni {
+ set cclass_shift 2
+ set decomp_shift 3
+ set comp_shift 1
+ set shift 5; # number of bits of data within a page
+ # This value can be adjusted to find the
+ # best split to minimize table size
+
+ variable pMap; # map from page to page index, each entry is
+ # an index into the pages table, indexed by
+ # page number
+ variable pages; # map from page index to page info, each
+ # entry is a list of indices into the groups
+ # table, the list is indexed by the offset
+ variable groups; # list of character info values, indexed by
+ # group number, initialized with the
+ # unassigned character group
+
+ variable categories {
+ Cn Lu Ll Lt Lm Lo Mn Me Mc Nd Nl No Zs Zl Zp
+ Cc Cf Co Cs Pc Pd Ps Pe Pi Pf Po Sm Sc Sk So
+ }; # Ordered list of character categories, must
+ # match the enumeration in the header file.
+
+ variable titleCount 0; # Count of the number of title case
+ # characters. This value is used in the
+ # regular expression code to allocate enough
+ # space for the title case variants.
+}
+
+proc uni::getValue {items index} {
+ variable categories
+ variable titleCount
+
+ # Extract character info
+
+ set category [lindex $items 2]
+ if {[scan [lindex $items 12] %4x toupper] == 1} {
+ set toupper [expr {$index - $toupper}]
+ } else {
+ set toupper {}
+ }
+ if {[scan [lindex $items 13] %4x tolower] == 1} {
+ set tolower [expr {$tolower - $index}]
+ } else {
+ set tolower {}
+ }
+ if {[scan [lindex $items 14] %4x totitle] == 1} {
+ set totitle [expr {$index - $totitle}]
+ } else {
+ set totitle {}
+ }
+
+ set categoryIndex [lsearch -exact $categories $category]
+ if {$categoryIndex < 0} {
+ puts "Unexpected character category: $index($category)"
+ set categoryIndex 0
+ } elseif {$category == "Lt"} {
+ incr titleCount
+ }
+
+ return "$categoryIndex,$toupper,$tolower,$totitle"
+}
+
+proc uni::getGroup {value} {
+ variable groups
+
+ set gIndex [lsearch -exact $groups $value]
+ if {$gIndex == -1} {
+ set gIndex [llength $groups]
+ lappend groups $value
+ }
+ return $gIndex
+}
+
+proc uni::addPage {info} {
+ variable pMap
+ variable pages
+
+ set pIndex [lsearch -exact $pages $info]
+ if {$pIndex == -1} {
+ set pIndex [llength $pages]
+ lappend pages $info
+ }
+ lappend pMap $pIndex
+ return
+}
+
+proc uni::addPage {map_var pages_var info} {
+ variable $map_var
+ variable $pages_var
+
+ set pIndex [lsearch -exact [set $pages_var] $info]
+ if {$pIndex == -1} {
+ set pIndex [llength [set $pages_var]]
+ lappend $pages_var $info
+ }
+ lappend $map_var $pIndex
+ return
+}
+
+proc uni::load_exclusions {data} {
+ variable exclusions
+
+ foreach line [split $data \n] {
+ if {$line == ""} continue
+
+ set items [split $line " "]
+
+ if {[lindex $items 0] == "#"} continue
+
+ scan [lindex $items 0] %x index
+
+ set exclusions($index) ""
+ }
+}
+
+proc uni::load_tables {data} {
+ variable cclass_map
+ variable decomp_map
+ variable decomp_compat
+ variable comp_map
+ variable comp_first
+ variable comp_second
+ variable exclusions
+
+ foreach line [split $data \n] {
+ if {$line == ""} continue
+
+ set items [split $line \;]
+
+ scan [lindex $items 0] %x index
+ set cclass [lindex $items 3]
+ set decomp [lindex $items 5]
+
+ set cclass_map($index) $cclass
+ #set decomp_map($index) $cclass
+
+ if {$decomp != ""} {
+ set decomp_compat($index) 0
+ if {[string index [lindex $decomp 0] 0] == "<"} {
+ set decomp_compat($index) 1
+ set decomp1 [lreplace $decomp 0 0]
+ set decomp {}
+ foreach ch $decomp1 {
+ scan $ch %x ch
+ lappend decomp $ch
+ }
+ set decomp_map($index) $decomp
+ } else {
+ switch -- [llength $decomp] {
+ 1 {
+ scan $decomp %x ch
+ set decomp_map($index) $ch
+ }
+ 2 {
+ scan $decomp "%x %x" ch1 ch2
+ set decomp [list $ch1 $ch2]
+ set decomp_map($index) $decomp
+ # hackish
+ if {(![info exists cclass_map($ch1)] || \
+ $cclass_map($ch1) == 0) && \
+ ![info exists exclusions($index)]} {
+ if {[info exists comp_first($ch1)]} {
+ incr comp_first($ch1)
+ } else {
+ set comp_first($ch1) 1
+ }
+ if {[info exists comp_second($ch2)]} {
+ incr comp_second($ch2)
+ } else {
+ set comp_second($ch2) 1
+ }
+ set comp_map($decomp) $index
+ } else {
+ #puts "Excluded $index"
+ }
+ }
+ default {
+ puts "Bad canonical decomposition: $line"
+ }
+ }
+ }
+
+ #puts "[format 0x%0.4x $index]\t$cclass\t$decomp_map($index)"
+ }
+ }
+ #puts [array get comp_first]
+ #puts [array get comp_second]
+}
+
+proc uni::buildTables {} {
+ variable cclass_shift
+ variable decomp_shift
+ variable comp_shift
+
+ variable cclass_map
+ variable cclass_pmap {}
+ variable cclass_pages {}
+ variable decomp_map
+ variable decomp_compat
+ variable decomp_pmap {}
+ variable decomp_pages {}
+ variable decomp_list {}
+ variable comp_map
+ variable comp_pmap {}
+ variable comp_pages {}
+ variable comp_first
+ variable comp_second
+ variable comp_first_list {}
+ variable comp_second_list {}
+ variable comp_x_list {}
+ variable comp_y_list {}
+ variable comp_both_map {}
+
+ set cclass_info {}
+ set decomp_info {}
+ set comp_info {}
+
+ set cclass_mask [expr {(1 << $cclass_shift) - 1}]
+ set decomp_mask [expr {(1 << $decomp_shift) - 1}]
+ set comp_mask [expr {(1 << $comp_shift) - 1}]
+
+ foreach comp [array names comp_map] {
+ set ch1 [lindex $comp 0]
+ if {[info exists comp_first($ch1)] && $comp_first($ch1) > 0 && \
+ [info exists comp_second($ch1)] && $comp_second($ch1) > 0} {
+ if {[lsearch -exact $comp_x_list $ch1] < 0} {
+ set i [llength $comp_x_list]
+ lappend comp_x_list $ch1
+ set comp_info_map($ch1) $i
+ lappend comp_y_list $ch1
+ set comp_info_map($ch1) $i
+ puts "There should be no symbols which appears on"
+ puts "both first and second place in composition"
+ exit 1
+ }
+ }
+ }
+
+ foreach comp [array names comp_map] {
+ set ch1 [lindex $comp 0]
+ set ch2 [lindex $comp 1]
+
+ if {$comp_first($ch1) == 1 && ![info exists comp_second($ch1)]} {
+ set i [llength $comp_first_list]
+ lappend comp_first_list [list $ch2 $comp_map($comp)]
+ set comp_info_map($ch1) [expr {$i | (1 << 16)}]
+ } elseif {$comp_second($ch2) == 1 && ![info exists comp_first($ch2)]} {
+ set i [llength $comp_second_list]
+ lappend comp_second_list [list $ch1 $comp_map($comp)]
+ set comp_info_map($ch2) [expr {$i | (1 << 16) | (1 << 17)}]
+ } else {
+ if {[lsearch -exact $comp_x_list $ch1] < 0} {
+ set i [llength $comp_x_list]
+ lappend comp_x_list $ch1
+ set comp_info_map($ch1) $i
+ }
+ if {[lsearch -exact $comp_y_list $ch2] < 0} {
+ set i [llength $comp_y_list]
+ lappend comp_y_list $ch2
+ set comp_info_map($ch2) [expr {$i | (1 << 17)}]
+ }
+ }
+ }
+
+ set next 0
+
+ for {set i 0} {$i <= 0x10ffff} {incr i} {
+ #set gIndex [getGroup [getValue $i]]
+
+ set cclass_offset [expr {$i & $cclass_mask}]
+
+ if {[info exists cclass_map($i)]} {
+ set cclass $cclass_map($i)
+ } else {
+ set cclass 0
+ }
+ lappend cclass_info $cclass
+
+ if {$cclass_offset == $cclass_mask} {
+ addPage cclass_pmap cclass_pages $cclass_info
+ set cclass_info {}
+ }
+
+
+ set decomp_offset [expr {$i & $decomp_mask}]
+
+ if {[info exists decomp_map($i)]} {
+ set decomp $decomp_map($i)
+ if {[llength $decomp] > (1 << 14)} {
+ puts "Too long decomp for $i"
+ exit 1
+ }
+
+ if {[info exists decomp_used($decomp)]} {
+ lappend decomp_info [expr {$decomp_used($decomp) | ($decomp_compat($i) << 16)}]
+ } else {
+ set val [expr {([llength $decomp] << 17) + \
+ [llength $decomp_list]}]
+ set decomp_used($decomp) $val
+ lappend decomp_info [expr {$val | ($decomp_compat($i) << 16)}]
+ #puts "$val $decomp"
+ foreach d $decomp {
+ lappend decomp_list $d
+ }
+ }
+ } else {
+ lappend decomp_info -1
+ }
+
+ if {$decomp_offset == $decomp_mask} {
+ addPage decomp_pmap decomp_pages $decomp_info
+ set decomp_info {}
+ }
+
+
+ set comp_offset [expr {$i & $comp_mask}]
+
+ if {[info exists comp_info_map($i)]} {
+ set comp $comp_info_map($i)
+ } else {
+ set comp -1
+ }
+ lappend comp_info $comp
+
+ if {$comp_offset == $comp_mask} {
+ addPage comp_pmap comp_pages $comp_info
+ set comp_info {}
+ }
+ }
+
+ #puts [array get decomp_map]
+ #puts $decomp_list
+
+ return
+}
+
+proc uni::main {} {
+ global argc argv0 argv
+ variable cclass_shift
+ variable cclass_pmap
+ variable cclass_pages
+ variable decomp_shift
+ variable decomp_pmap
+ variable decomp_pages
+ variable decomp_list
+ variable comp_shift
+ variable comp_map
+ variable comp_pmap
+ variable comp_pages
+ variable comp_first_list
+ variable comp_second_list
+ variable comp_x_list
+ variable comp_y_list
+ variable pages
+ variable groups {}
+ variable titleCount
+
+ if {$argc != 3} {
+ puts stderr "\nusage: $argv0 <datafile> <exclusionsfile> <outdir>\n"
+ exit 1
+ }
+ set f [open [lindex $argv 1] r]
+ set data [read $f]
+ close $f
+
+ load_exclusions $data
+
+ set f [open [lindex $argv 0] r]
+ set data [read $f]
+ close $f
+
+ load_tables $data
+ buildTables
+ #puts "X = [llength $pMap] Y= [llength $pages] A= [llength $groups]"
+ #set size [expr {[llength $pMap] + [llength $pages]*(1<<$shift)}]
+ #puts "shift = 6, space = $size"
+ #puts "title case count = $titleCount"
+
+ set f [open [file join [lindex $argv 2] unicode_data.tcl] w]
+ fconfigure $f -translation lf
+ puts $f \
+"# unicode_data.tcl --
+#
+# Declarations of Unicode character information tables. This file is
+# automatically generated by the gen_unicode_data.tcl script. Do not
+# modify this file by hand.
+#
+# Copyright (c) 1998 Scriptics Corporation.
+# Copyright (c) 2007 Alexey Shchepin
+# Copyright (c) 2007 Sergei Golovan
+#
+# See the file \"license.terms\" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# RCS: @(#) \$Id\$
+
+#
+# A 16-bit Unicode character is split into two parts in order to index
+# into the following tables. The lower CCLASS_OFFSET_BITS comprise an offset
+# into a page of characters. The upper bits comprise the page number.
+#
+
+package provide unicode::data 1.0.0
+
+namespace eval ::unicode::data {
+
+set CCLASS_OFFSET_BITS $cclass_shift
+
+#
+# The cclassPageMap is indexed by page number and returns an alternate page number
+# that identifies a unique page of characters. Many Unicode characters map
+# to the same alternate page number.
+#
+
+array unset cclassPageMap
+array set cclassPageMap \[list \\"
+ array unset tmp
+ foreach idx $cclass_pmap {
+ if {![info exists tmp($idx)]} {
+ set tmp($idx) 1
+ } else {
+ incr tmp($idx)
+ }
+ }
+ set max 0
+ set max_id 0
+ foreach idx [array names tmp] {
+ if {$tmp($idx) > $max} {
+ set max $tmp($idx)
+ set max_id $idx
+ }
+ }
+ set line " "
+ set last [expr {[llength $cclass_pmap] - 1}]
+ for {set i 0} {$i <= $last} {incr i} {
+ set num [lindex $cclass_pmap $i]
+ if {$num != $max_id} {
+ append line " $i $num"
+ }
+ if {[string length $line] > 70} {
+ puts $f "$line \\"
+ set line " "
+ }
+ }
+ puts $f "$line\]
+
+set CCLASS_COMMON_PAGE_MAP $max_id
+
+#
+# The cclassGroupMap is indexed by combining the alternate page number with
+# the page offset and returns a combining class number.
+#
+
+set cclassGroupMap \[list \\"
+ set line " "
+ set lasti [expr {[llength $cclass_pages] - 1}]
+ for {set i 0} {$i <= $lasti} {incr i} {
+ set page [lindex $cclass_pages $i]
+ set lastj [expr {[llength $page] - 1}]
+ for {set j 0} {$j <= $lastj} {incr j} {
+ append line [lindex $page $j]
+ if {$j != $lastj || $i != $lasti} {
+ append line " "
+ }
+ if {[string length $line] > 70} {
+ puts $f "$line\\"
+ set line " "
+ }
+ }
+ }
+ puts $f "$line\]
+
+proc GetUniCharCClass {uc} {
+ variable CCLASS_OFFSET_BITS
+ variable CCLASS_COMMON_PAGE_MAP
+ variable cclassPageMap
+ variable cclassGroupMap
+
+ set page \[expr {(\$uc & 0x1fffff) >> \$CCLASS_OFFSET_BITS}\]
+ if {\[info exists cclassPageMap(\$page)\]} {
+ set apage \$cclassPageMap(\$page)
+ } else {
+ set apage \$CCLASS_COMMON_PAGE_MAP
+ }
+
+ lindex \$cclassGroupMap \\
+ \[expr {(\$apage << \$CCLASS_OFFSET_BITS) | \\
+ (\$uc & ((1 << \$CCLASS_OFFSET_BITS) - 1))}\]
+}
+
+
+set DECOMP_OFFSET_BITS $decomp_shift
+
+#
+# The pageMap is indexed by page number and returns an alternate page number
+# that identifies a unique page of characters. Many Unicode characters map
+# to the same alternate page number.
+#
+
+array unset decompPageMap
+array set decompPageMap \[list \\"
+ array unset tmp
+ foreach idx $decomp_pmap {
+ if {![info exists tmp($idx)]} {
+ set tmp($idx) 1
+ } else {
+ incr tmp($idx)
+ }
+ }
+ set max 0
+ set max_id 0
+ foreach idx [array names tmp] {
+ if {$tmp($idx) > $max} {
+ set max $tmp($idx)
+ set max_id $idx
+ }
+ }
+ set line " "
+ set last [expr {[llength $decomp_pmap] - 1}]
+ for {set i 0} {$i <= $last} {incr i} {
+ set num [lindex $decomp_pmap $i]
+ if {$num != $max_id} {
+ append line " $i $num"
+ }
+ if {[string length $line] > 70} {
+ puts $f "$line \\"
+ set line " "
+ }
+ }
+ puts $f "$line\]
+
+set DECOMP_COMMON_PAGE_MAP $max_id
+
+#
+# The decompGroupMap is indexed by combining the alternate page number with
+# the page offset and returns a group number that identifies a length and
+# shift of decomposition sequence in decompList
+#
+
+set decompGroupMap \[list \\"
+ set line " "
+ set lasti [expr {[llength $decomp_pages] - 1}]
+ for {set i 0} {$i <= $lasti} {incr i} {
+ set page [lindex $decomp_pages $i]
+ set lastj [expr {[llength $page] - 1}]
+ for {set j 0} {$j <= $lastj} {incr j} {
+ append line [lindex $page $j]
+ if {$j != $lastj || $i != $lasti} {
+ append line " "
+ }
+ if {[string length $line] > 70} {
+ puts $f "$line\\"
+ set line " "
+ }
+ }
+ }
+ puts $f "$line\]
+
+#
+# List of decomposition sequences
+#
+
+set decompList \[list \\"
+ set line " "
+ set last [expr {[llength $decomp_list] - 1}]
+ for {set i 0} {$i <= $last} {incr i} {
+ set val [lindex $decomp_list $i]
+
+ append line [format "%d" $val]
+ if {$i != $last} {
+ append line " "
+ }
+ if {[string length $line] > 70} {
+ puts $f "$line\\"
+ set line " "
+ }
+ }
+ puts $f "$line\]
+
+set DECOMP_COMPAT_MASK [expr {1 << 16}]
+set DECOMP_INFO_BITS 17
+
+#
+# This macro extracts the information about a character from the
+# Unicode character tables.
+#
+
+proc GetUniCharDecompCompatInfo {uc} {
+ variable DECOMP_OFFSET_BITS
+ variable DECOMP_COMMON_PAGE_MAP
+ variable decompPageMap
+ variable decompGroupMap
+
+ set page \[expr {(\$uc & 0x1fffff) >> \$DECOMP_OFFSET_BITS}\]
+ if {\[info exists decompPageMap(\$page)\]} {
+ set apage \$decompPageMap(\$page)
+ } else {
+ set apage \$DECOMP_COMMON_PAGE_MAP
+ }
+
+ lindex \$decompGroupMap \\
+ \[expr {(\$apage << \$DECOMP_OFFSET_BITS) | \\
+ (\$uc & ((1 << \$DECOMP_OFFSET_BITS) - 1))}\]
+}
+
+proc GetUniCharDecompInfo {uc} {
+ variable DECOMP_COMPAT_MASK
+
+ set info \[GetUniCharDecompCompatInfo \$uc\]
+ if {\$info & \$DECOMP_COMPAT_MASK} {
+ return -1
+ } else {
+ return \$info
+ }
+}
+
+proc GetDecompList {info} {
+ variable DECOMP_INFO_BITS
+ variable decompList
+
+ set decomp_len \[expr {\$info >> \$DECOMP_INFO_BITS}\]
+ set decomp_shift \[expr {\$info & ((1 << (\$DECOMP_INFO_BITS - 1)) - 1)}\]
+
+ lrange \$decompList \$decomp_shift \[expr {\$decomp_shift + \$decomp_len - 1}\]
+}
+
+set COMP_OFFSET_BITS $comp_shift
+
+#
+# The pageMap is indexed by page number and returns an alternate page number
+# that identifies a unique page of characters. Many Unicode characters map
+# to the same alternate page number.
+#
+
+array unset compPageMap
+array set compPageMap \[list \\"
+ array unset tmp
+ foreach idx $comp_pmap {
+ if {![info exists tmp($idx)]} {
+ set tmp($idx) 1
+ } else {
+ incr tmp($idx)
+ }
+ }
+ set max 0
+ set max_id 0
+ foreach idx [array names tmp] {
+ if {$tmp($idx) > $max} {
+ set max $tmp($idx)
+ set max_id $idx
+ }
+ }
+ set line " "
+ set last [expr {[llength $comp_pmap] - 1}]
+ for {set i 0} {$i <= $last} {incr i} {
+ set num [lindex $comp_pmap $i]
+ if {$num != $max_id} {
+ append line " $i $num"
+ }
+ if {[string length $line] > 70} {
+ puts $f "$line \\"
+ set line " "
+ }
+ }
+ puts $f "$line\]
+
+set COMP_COMMON_PAGE_MAP $max_id
+
+#
+# The groupMap is indexed by combining the alternate page number with
+# the page offset and returns a group number that identifies a unique
+# set of character attributes.
+#
+
+set compGroupMap \[list \\"
+ set line " "
+ set lasti [expr {[llength $comp_pages] - 1}]
+ for {set i 0} {$i <= $lasti} {incr i} {
+ set page [lindex $comp_pages $i]
+ set lastj [expr {[llength $page] - 1}]
+ for {set j 0} {$j <= $lastj} {incr j} {
+ append line [lindex $page $j]
+ if {$j != $lastj || $i != $lasti} {
+ append line " "
+ }
+ if {[string length $line] > 70} {
+ puts $f "$line\\"
+ set line " "
+ }
+ }
+ }
+ puts $f "$line\]
+
+#
+# Lists of compositions for characters that appears only in one composition
+#
+
+set compFirstList \[list \\"
+ set line " "
+ set last [expr {[llength $comp_first_list] - 1}]
+ for {set i 0} {$i <= $last} {incr i} {
+ set val [lindex $comp_first_list $i]
+
+ append line [format "{%d %d}" [lindex $val 0] [lindex $val 1]]
+ if {$i != $last} {
+ append line " "
+ }
+ if {[string length $line] > 60} {
+ puts $f "$line\\"
+ set line " "
+ }
+ }
+ puts $f "$line\]
+
+set compSecondList \[list \\"
+ set line " "
+ set last [expr {[llength $comp_second_list] - 1}]
+ for {set i 0} {$i <= $last} {incr i} {
+ set val [lindex $comp_second_list $i]
+
+ append line [format "{%d %d}" [lindex $val 0] [lindex $val 1]]
+ if {$i != $last} {
+ append line " "
+ }
+ if {[string length $line] > 60} {
+ puts $f "$line\\"
+ set line " "
+ }
+ }
+ puts $f "$line\]
+
+#
+# Compositions matrix
+#
+
+array unset compBothMap
+array set compBothMap \[list \\"
+ set lastx [expr {[llength $comp_x_list] - 1}]
+ set lasty [expr {[llength $comp_y_list] - 1}]
+ set line " "
+ for {set i 0} {$i <= $lastx} {incr i} {
+ for {set j 0} {$j <= $lasty} {incr j} {
+ set comp [list [lindex $comp_x_list $i] [lindex $comp_y_list $j]]
+ if {[info exists comp_map($comp)]} {
+ append line " " [expr {$i*[llength $comp_x_list]+$j}] \
+ " " [format "%d" $comp_map($comp)]
+ }
+ if {[string length $line] > 70} {
+ puts $f "$line \\"
+ set line " "
+ }
+ }
+ }
+ puts $f "$line\]
+
+
+proc GetUniCharCompInfo {uc} {
+ variable COMP_OFFSET_BITS
+ variable COMP_COMMON_PAGE_MAP
+ variable compPageMap
+ variable compGroupMap
+
+ set page \[expr {(\$uc & 0x1fffff) >> \$COMP_OFFSET_BITS}\]
+ if {\[info exists compPageMap(\$page)\]} {
+ set apage \$compPageMap(\$page)
+ } else {
+ set apage \$COMP_COMMON_PAGE_MAP
+ }
+
+ lindex \$compGroupMap \\
+ \[expr {(\$apage << \$COMP_OFFSET_BITS) | \\
+ (\$uc & ((1 << \$COMP_OFFSET_BITS) - 1))}\]
+}
+
+set COMP_SINGLE_MASK [expr {1 << 16}]
+set COMP_SECOND_MASK [expr {1 << 17}]
+set COMP_MASK [expr {(1 << 16) - 1}]
+set COMP_LENGTH1 [llength $comp_x_list]
+
+proc GetCompFirst {uc info} {
+ variable COMP_SINGLE_MASK
+ variable COMP_SECOND_MASK
+ variable COMP_MASK
+ variable compFirstList
+
+ if {\$info == -1 || !(\$info & \$COMP_SINGLE_MASK)} {
+ return -1
+ }
+ if {!(\$info & \$COMP_SECOND_MASK)} {
+ set comp \[lindex \$compFirstList \[expr {\$info & \$COMP_MASK}\]\]
+ if {\$uc == \[lindex \$comp 0\]} {
+ return \[lindex \$comp 1\]
+ }
+ }
+ return 0
+}
+
+proc GetCompSecond {uc info} {
+ variable COMP_SINGLE_MASK
+ variable COMP_SECOND_MASK
+ variable COMP_MASK
+ variable compSecondList
+
+ if {\$info == -1 || !(\$info & \$COMP_SINGLE_MASK)} {
+ return -1
+ }
+ if {\$info & \$COMP_SECOND_MASK} {
+ set comp \[lindex \$compSecondList \[expr {\$info & \$COMP_MASK}\]\]
+ if {\$uc == \[lindex \$comp 0\]} {
+ return \[lindex \$comp 1\]
+ }
+ }
+ return 0
+}
+
+proc GetCompBoth {info1 info2} {
+ variable COMP_SECOND_MASK
+ variable COMP_MASK
+ variable COMP_LENGTH1
+ variable compBothMap
+
+ if {\$info1 != -1 && \$info2 != -1 && \
+ !(\$info1 & \$COMP_SECOND_MASK) && (\$info2 & \$COMP_SECOND_MASK)} {
+ set idx \[expr {\$COMP_LENGTH1 * \$info1 + (\$info2 & \$COMP_MASK)}\]
+ if {\[info exists compBothMap(\$idx)\]} {
+ return \$compBothMap(\$idx)
+ } else {
+ return 0
+ }
+ } else {
+ return 0
+ }
+}
+
+} ; # namespace eval ::unicode::data
+"
+
+ close $f
+}
+
+uni::main
+
+return
diff --git a/tcllib/modules/stringprep/tools/gen_unicode_test.tcl b/tcllib/modules/stringprep/tools/gen_unicode_test.tcl
new file mode 100644
index 0000000..ec9b2c3
--- /dev/null
+++ b/tcllib/modules/stringprep/tools/gen_unicode_test.tcl
@@ -0,0 +1,247 @@
+#!/usr/bin/tclsh
+
+# gen_unicode_test.tcl --
+#
+# This program parses the RFC 3454 file and generates the
+# corresponding unicode.test file with unicode package tests.
+# The input to this program should be NormalizationTest.txt.
+# It can be downloaded from:
+# ftp://ftp.unicode.org/Public/UNIDATA/NormalizationTest.txt
+# Short test suite is generated by default. If you want to generate
+# all tests (more than 300000 test cases) add suffix 'full' as the
+# third argument.
+#
+# Usage: gen_unicode_test.tcl infile outdir ?full?
+#
+# RCS: @(#) $Id: gen_unicode_test.tcl,v 1.1 2008/01/29 02:18:10 patthoyts Exp $
+
+package require struct::list
+
+set short_test_list [list \
+ "LATIN CAPITAL LETTER D, COMBINING DOT ABOVE, COMBINING DOT BELOW" \
+ "NO-BREAK SPACE" \
+ "VULGAR FRACTION ONE HALF" \
+ "ORIYA LETTER RRA" \
+ "KANNADA VOWEL SIGN EE" \
+ "TIBETAN LETTER GHA" \
+ "MODIFIER LETTER CAPITAL A" \
+ "GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA" \
+ "KANGXI RADICAL SPROUT" \
+ "HIRAGANA LETTER DE" \
+ "KATAKANA LETTER PA" \
+ "HANGUL LETTER SIOS-PIEUP" \
+ "HANGUL SYLLABLE GYANG" \
+ "CJK COMPATIBILITY IDEOGRAPH-F98E" \
+ "ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM" \
+ "ARABIC LIGATURE AIN WITH JEEM ISOLATED FORM" \
+ "FULLWIDTH DIGIT THREE" \
+ "LATIN SMALL LETTER A, COMBINING CYRILLIC TITLO, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B" \
+ "LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, COMBINING RING OVERLAY, LATIN SMALL LETTER B" \
+ "HANGUL SYLLABLE BYO, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT"]
+
+set fd [open [lindex $argv 0]]
+
+set all_tests {}
+set n 0
+while {[gets $fd line] >= 0} {
+ set line [string trim $line]
+ if {![regexp \
+ {^([ [:xdigit:]]+);([ [:xdigit:]]+);([ [:xdigit:]]+);([ [:xdigit:]]+);([ [:xdigit:]]+);.*\) (.*)} \
+ $line -> c(1) c(2) c(3) c(4) c(5) title]} continue
+
+ set q 1
+ foreach i {1 2 3 4 5} {
+ set s($i) {}
+ set us($i) ""
+ foreach xnum $c($i) {
+ set uc [scan $xnum %x]
+ if {$uc > 0xffff} {
+ set q 0
+ }
+ lappend s($i) $uc
+ append us($i) \\u$xnum
+ }
+ }
+ if {!$q} {
+ # Test case contains character which is greater than 0xFFFF and can't
+ # be represented in Tcl
+ continue
+ }
+ set test($n) [list $s(1) $s(2) $s(3) $s(4) $s(5) $title]
+ set test1($n) [list $us(1) $us(2) $us(3) $us(4) $us(5) $title]
+ if {[lsearch $short_test_list $title] >= 0} {
+ lappend all_tests $n
+ }
+ incr n
+}
+
+close $fd
+
+if {[string equal [lindex $argv 2] full]} {
+ set all_tests [struct::list iota $n]
+}
+
+set f [open [file join [lindex $argv 1] unicode.test] w]
+fconfigure $f -translation lf
+puts $f \
+"# unicode.test
+#
+# Tests for the unicode package. This file is automatically generated by
+# the gen_unicode_test.tcl script. Do not modify this file by hands.
+#
+# RCS: @(#) \$Id\$
+
+# -------------------------------------------------------------------------
+
+source \[file join \\
+ \[file dirname \[file dirname \[file join \[pwd\] \[info script\]\]\]\] \\
+ devtools testutilities.tcl\]
+
+testsNeedTcl 8.3
+testsNeedTcltest 1.0
+
+testing {
+ useLocalFile unicode_data.tcl
+ useLocalFile unicode.tcl
+}
+
+# -------------------------------------------------------------------------
+"
+
+set j 0
+foreach i $all_tests {
+ puts $f \
+"
+test unicode-1.[incr j] {normalizeS D: [lindex $test1($i) 5]} {
+ unicode::normalizeS D \"[lindex $test1($i) 0]\"
+} \"[lindex $test1($i) 2]\"
+
+test unicode-1.[incr j] {normalize D: [lindex $test($i) 5]} {
+ unicode::normalize D [list [lindex $test($i) 1]]
+} {[lindex $test($i) 2]}
+
+test unicode-1.[incr j] {normalize D: [lindex $test($i) 5]} {
+ unicode::normalize D [list [lindex $test($i) 2]]
+} {[lindex $test($i) 2]}
+
+test unicode-1.[incr j] {normalize D: [lindex $test($i) 5]} {
+ unicode::normalize D [list [lindex $test($i) 3]]
+} {[lindex $test($i) 4]}
+
+test unicode-1.[incr j] {normalize D: [lindex $test($i) 5]} {
+ unicode::normalize D [list [lindex $test($i) 4]]
+} {[lindex $test($i) 4]}
+"
+}
+
+set j 0
+foreach i $all_tests {
+ puts $f \
+"
+test unicode-2.[incr j] {normalize C: [lindex $test($i) 5]} {
+ unicode::normalize C [list [lindex $test($i) 0]]
+} {[lindex $test($i) 1]}
+
+test unicode-2.[incr j] {normalizeS C: [lindex $test1($i) 5]} {
+ unicode::normalizeS C \"[lindex $test1($i) 1]\"
+} \"[lindex $test1($i) 1]\"
+
+test unicode-2.[incr j] {normalize C: [lindex $test($i) 5]} {
+ unicode::normalize C [list [lindex $test($i) 2]]
+} {[lindex $test($i) 1]}
+
+test unicode-2.[incr j] {normalize C: [lindex $test($i) 5]} {
+ unicode::normalize C [list [lindex $test($i) 3]]
+} {[lindex $test($i) 3]}
+
+test unicode-2.[incr j] {normalize C: [lindex $test($i) 5]} {
+ unicode::normalize C [list [lindex $test($i) 4]]
+} {[lindex $test($i) 3]}
+"
+}
+
+set j 0
+foreach i $all_tests {
+ puts $f \
+"
+test unicode-3.[incr j] {normalize KD: [lindex $test($i) 5]} {
+ unicode::normalize KD [list [lindex $test($i) 0]]
+} {[lindex $test($i) 4]}
+
+test unicode-3.[incr j] {normalize KD: [lindex $test($i) 5]} {
+ unicode::normalize KD [list [lindex $test($i) 1]]
+} {[lindex $test($i) 4]}
+
+test unicode-3.[incr j] {normalizeS KD: [lindex $test1($i) 5]} {
+ unicode::normalizeS KD \"[lindex $test1($i) 2]\"
+} \"[lindex $test1($i) 4]\"
+
+test unicode-3.[incr j] {normalize KD: [lindex $test($i) 5]} {
+ unicode::normalize KD [list [lindex $test($i) 3]]
+} {[lindex $test($i) 4]}
+
+test unicode-1.[incr j] {normalize KD: [lindex $test($i) 5]} {
+ unicode::normalize KD [list [lindex $test($i) 4]]
+} {[lindex $test($i) 4]}
+"
+}
+
+set j 0
+foreach i $all_tests {
+ puts $f \
+"
+test unicode-4.[incr j] {normalize KC: [lindex $test($i) 5]} {
+ unicode::normalize KC [list [lindex $test($i) 0]]
+} {[lindex $test($i) 3]}
+
+test unicode-4.[incr j] {normalize KC: [lindex $test($i) 5]} {
+ unicode::normalize KC [list [lindex $test($i) 1]]
+} {[lindex $test($i) 3]}
+
+test unicode-4.[incr j] {normalize KC: [lindex $test($i) 5]} {
+ unicode::normalize KC [list [lindex $test($i) 2]]
+} {[lindex $test($i) 3]}
+
+test unicode-4.[incr j] {normalizeS KC: [lindex $test1($i) 5]} {
+ unicode::normalizeS KC \"[lindex $test1($i) 3]\"
+} \"[lindex $test1($i) 3]\"
+
+test unicode-4.[incr j] {normalize KC: [lindex $test($i) 5]} {
+ unicode::normalize KC [list [lindex $test($i) 4]]
+} {[lindex $test($i) 3]}
+"
+}
+
+puts $f \
+"
+test unicode-5.1 {fromstring} {
+ unicode::fromstring \"\\u0403\\u0405\\u0406\\u041f\\u0034\"
+} {1027 1029 1030 1055 52}
+
+test unicode-5.2 {fromstring} {
+ unicode::fromstring \"\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007\\u0008\\u0009\\u000a\\u000b\\u000c\\u000d\"
+} {1 2 3 4 5 6 7 8 9 10 11 12 13}
+
+test unicode-6.1 {tostring} {
+ unicode::tostring {16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1}
+} \"\\u0010\\u000f\\u000e\\u000d\\u000c\\u000b\\u000a\\u0009\\u0008\\u0007\\u0006\\u0005\\u0004\\u0003\\u0002\\u0001\"
+
+test unicode-6.2 {tostring} {
+ unicode::tostring {12345 12346 12347 12348 12349 12350 12351}
+} \"\\u3039\\u303a\\u303b\\u303c\\u303d\\u303e\\u303f\"
+
+test unicode-7.1 {normalize bad form} {
+ catch {unicode::normalize S \"\"} result
+ set result
+} \"::unicode::normalize: Only D, C, KD and KC forms are allowed\"
+
+test unicode-8.1 {normalizeS bad form} {
+ catch {unicode::normalizeS S \"\"} result
+ set result
+} \"::unicode::normalizeS: Only D, C, KD and KC forms are allowed\"
+
+::tcltest::cleanupTests
+"
+
+close $f
+
diff --git a/tcllib/modules/stringprep/unicode.man b/tcllib/modules/stringprep/unicode.man
new file mode 100644
index 0000000..639eeda
--- /dev/null
+++ b/tcllib/modules/stringprep/unicode.man
@@ -0,0 +1,83 @@
+[comment {-*- tcl -*- doctools manpage}]
+[manpage_begin unicode n 1.0.0]
+[see_also stringprep(n)]
+[keywords normalization]
+[keywords unicode]
+[copyright {2007, Sergei Golovan <sgolovan@nes.ru>}]
+[moddesc {Unicode normalization}]
+[titledesc {Implementation of Unicode normalization}]
+[require Tcl 8.3]
+[require unicode 1.0]
+[description]
+[para]
+
+This is an implementation in Tcl of the Unicode normalization forms.
+
+[section "COMMANDS"]
+
+[list_begin definitions]
+[call [cmd "::unicode::fromstring"] \
+ [arg string]]
+
+Converts [arg string] to list of integer Unicode character codes which
+is used in [package unicode] for internal string representation.
+
+[call [cmd "::unicode::tostring"] \
+ [arg uclist]]
+
+Converts list of integers [arg uclist] back to Tcl string.
+
+[call [cmd "::unicode::normalize"] \
+ [arg form] \
+ [arg uclist]]
+
+Normalizes Unicode characters list [arg ulist] according to [arg form]
+and returns the normalized list. Form [arg form] takes one of the following
+values: [arg D] (canonical decomposition), [arg C] (canonical decomposition, followed
+by canonical composition), [arg KD] (compatibility decomposition), or [arg KC]
+(compatibility decomposition, followed by canonical composition).
+
+[call [cmd "::unicode::normalizeS"] \
+ [arg form] \
+ [arg string]]
+
+A shortcut to
+::unicode::tostring [lb]unicode::normalize \$form [lb]::unicode::fromstring \$string[rb][rb].
+Normalizes Tcl string and returns normalized string.
+
+[list_end]
+
+[section EXAMPLES]
+
+[example {
+% ::unicode::fromstring "\u0410\u0411\u0412\u0413"
+1040 1041 1042 1043
+% ::unicode::tostring {49 50 51 52 53}
+12345
+%
+}]
+
+[example {
+% ::unicode::normalize D {7692 775}
+68 803 775
+% ::unicode::normalizeS KD "\u1d2c"
+A
+%
+}]
+
+[section "REFERENCES"]
+
+[list_begin enum]
+
+[enum]
+ "Unicode Standard Annex #15: Unicode Normalization Forms",
+ ([uri http://unicode.org/reports/tr15/])
+
+[list_end]
+
+[section "AUTHORS"]
+Sergei Golovan
+
+[vset CATEGORY stringprep]
+[include ../doctools2base/include/feedback.inc]
+[manpage_end]
diff --git a/tcllib/modules/stringprep/unicode.tcl b/tcllib/modules/stringprep/unicode.tcl
new file mode 100644
index 0000000..428f735
--- /dev/null
+++ b/tcllib/modules/stringprep/unicode.tcl
@@ -0,0 +1,292 @@
+# unicode.tcl -*- tcl -*-
+#
+# Implementation of RFC 3454 "Preparation of Internationalized Strings"
+#
+# Copyright (c) 2007 Sergei Golovan
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# RCS: @(#) $Id: unicode.tcl,v 1.1 2008/01/29 02:18:10 patthoyts Exp $
+
+package require unicode::data 1.0
+
+namespace eval ::unicode {
+ # Hangul constants
+ set SBase 0xac00
+ set LBase 0x1100
+ set VBase 0x1161
+ set TBase 0x11a7
+ set LCount 19
+ set VCount 21
+ set TCount 28
+ set NCount [expr {$VCount * $TCount}]
+ set SCount [expr {$LCount * $NCount}]
+}
+
+########################################################################
+# ::unicode::fromstring converts string to list of integers
+
+proc ::unicode::fromstring {str} {
+ set uclist {}
+ foreach char [split $str ""] {
+ lappend uclist [scan $char %c]
+ }
+ return $uclist
+}
+
+########################################################################
+# ::unicode::tostring converts list of integers to string
+
+proc ::unicode::tostring {uclist} {
+ set res ""
+ foreach num $uclist {
+ append res [format %c $num]
+ }
+ return $res
+}
+
+########################################################################
+# ::unicode::normalize normalizes list of integers according to
+# http://unicode.org/reports/tr15/
+# form is to be D, C, KD, or KC
+
+proc ::unicode::normalize {form uclist} {
+ switch -- $form {
+ D { return [normalizeD $uclist] }
+ C { return [normalizeC $uclist] }
+ KD { return [normalizeKD $uclist] }
+ KC { return [normalizeKC $uclist] }
+ default {
+ return -code error \
+ "::unicode::normalize: Only D, C, KD and KC forms are\
+ allowed"
+ }
+ }
+}
+
+########################################################################
+# ::unicode::normalizeS normalizes string according to
+# http://unicode.org/reports/tr15/
+# form is to be D, C, KD, or KC
+
+proc ::unicode::normalizeS {form str} {
+ switch -- $form {
+ D { return [tostring [normalizeD [fromstring $str]]] }
+ C { return [tostring [normalizeC [fromstring $str]]] }
+ KD { return [tostring [normalizeKD [fromstring $str]]] }
+ KC { return [tostring [normalizeKC [fromstring $str]]] }
+ default {
+ return -code error \
+ "::unicode::normalizeS: Only D, C, KD and KC forms are\
+ allowed"
+ }
+ }
+}
+
+########################################################################
+
+proc ::unicode::normalizeD {uclist} {
+ set res {}
+ foreach uc $uclist {
+ set res [concat $res [decomposeCanonical $uc]]
+ }
+
+ canonicalOrdering $res
+}
+
+proc ::unicode::normalizeC {uclist} {
+ composeCanonical [normalizeD $uclist]
+}
+
+proc ::unicode::normalizeKD {uclist} {
+ set res {}
+ foreach uc $uclist {
+ set res [concat $res [decomposeCompat $uc]]
+ }
+
+ canonicalOrdering $res
+}
+
+proc ::unicode::normalizeKC {uclist} {
+ composeCanonical [normalizeKD $uclist]
+}
+
+########################################################################
+# Adjacent characters with nonzero character class should go in
+# order of increasing character class
+
+proc ::unicode::canonicalOrdering {uclist} {
+ set res {}
+ set slist {}
+ foreach uc $uclist {
+ set cclass [data::GetUniCharCClass $uc]
+ if {$cclass != 0} {
+ lappend slist [list $uc $cclass]
+ } else {
+ foreach s [lsort -integer -index 1 $slist] {
+ lappend res [lindex $s 0]
+ }
+ set slist {}
+ lappend res $uc
+ }
+ }
+ foreach s [lsort -integer -index 1 $slist] {
+ lappend res [lindex $s 0]
+ }
+
+ return $res
+}
+
+########################################################################
+
+proc ::unicode::decomposeHangul {uc} {
+ variable SBase
+ variable LBase
+ variable VBase
+ variable TBase
+ variable LCount
+ variable VCount
+ variable TCount
+ variable NCount
+ variable SCount
+
+ # Hangul decomposition is algorithmic
+ set SIndex [expr {$uc - $SBase}]
+ if {$SIndex >= 0 && $SIndex < $SCount} {
+ set res {}
+ set L [expr {$LBase + $SIndex / $NCount}]
+ set V [expr {$VBase + ($SIndex % $NCount) / $TCount}]
+ set T [expr {$TBase + $SIndex % $TCount}]
+ set res [list $L $V]
+ if {$T != $TBase} {
+ lappend res $T
+ }
+ return $res
+ }
+ return -1
+}
+
+########################################################################
+
+proc ::unicode::decomposeCanonical {uc} {
+ # Try to decompose Hangul first
+ set res [decomposeHangul $uc]
+ if {$res >= 0} {
+ return $res
+ }
+
+ # For others do a lookup in data tables
+ set info [data::GetUniCharDecompInfo $uc]
+ if {$info >= 0} {
+ set res {}
+ foreach c [data::GetDecompList $info] {
+ set res [concat $res [decomposeCanonical $c]]
+ }
+ return $res
+ } else {
+ return [list $uc]
+ }
+}
+
+########################################################################
+
+proc ::unicode::decomposeCompat {uc} {
+ # Try to decompose Hangul first
+ set res [decomposeHangul $uc]
+ if {$res >= 0} {
+ return $res
+ }
+
+ # For others do a lookup in data tables
+ set info [data::GetUniCharDecompCompatInfo $uc]
+ if {$info >= 0} {
+ set res {}
+ foreach c [data::GetDecompList $info] {
+ set res [concat $res [decomposeCompat $c]]
+ }
+ return $res
+ } else {
+ return [list $uc]
+ }
+}
+
+########################################################################
+
+proc ::unicode::composeTwo {uc1 uc2} {
+ variable SBase
+ variable LBase
+ variable VBase
+ variable TBase
+ variable LCount
+ variable VCount
+ variable TCount
+ variable NCount
+ variable SCount
+
+ # Hangul composition is algorithmic
+ if {$uc1 >= $LBase && $uc1 < $LBase + $LCount && \
+ $uc2 >= $VBase && $uc2 < $VBase + $VCount} {
+ return [expr {$SBase + (($uc1 - $LBase) * $VCount + \
+ ($uc2 - $VBase)) * $TCount}]
+ }
+
+ if {$uc1 >= $SBase && $uc1 < $SBase + $SCount && \
+ (($uc1 - $SBase) % $TCount) == 0 && \
+ $uc2 >= $TBase && $uc2 < $TBase + $TCount} {
+ return [expr {$uc1 + $uc2 - $TBase}]
+ }
+
+ # For others do a lookup in data tables
+ set info1 [data::GetUniCharCompInfo $uc1]
+ set res [data::GetCompFirst $uc2 $info1]
+ if {$res != -1} {
+ return $res
+ }
+
+ set info2 [data::GetUniCharCompInfo $uc2]
+ set res [data::GetCompSecond $uc1 $info2]
+ if {$res != -1} {
+ return $res
+ }
+
+ data::GetCompBoth $info1 $info2
+}
+
+########################################################################
+
+proc ::unicode::composeCanonical {uclist} {
+ if {[llength $uclist] == 0} {
+ return {}
+ }
+
+ set res {}
+ set comps {}
+ set ch1 [lindex $uclist 0]
+ set cclass_prev [data::GetUniCharCClass $ch1]
+ foreach ch2 [lrange $uclist 1 end] {
+ set cclass [data::GetUniCharCClass $ch2]
+ if {($cclass_prev == 0 || $cclass > $cclass_prev) && \
+ [set ruc [composeTwo $ch1 $ch2]]} {
+ set ch1 $ruc
+ } else {
+ if {$cclass == 0} {
+ lappend res $ch1
+ set res [concat $res $comps]
+ set comps {}
+ set ch1 $ch2
+ set cclass_prev 0
+ } else {
+ lappend comps $ch2
+ set cclass_prev $cclass
+ }
+ }
+ }
+ lappend res $ch1
+ concat $res $comps
+}
+
+########################################################################
+
+package provide unicode 1.0.0
+
diff --git a/tcllib/modules/stringprep/unicode.test b/tcllib/modules/stringprep/unicode.test
new file mode 100644
index 0000000..0325bae
--- /dev/null
+++ b/tcllib/modules/stringprep/unicode.test
@@ -0,0 +1,1732 @@
+# unicode.test -*- tcl -*-
+#
+# Tests for the unicode package. This file is automatically generated by
+# the gen_unicode_test.tcl script. Do not modify this file by hands.
+#
+# RCS: @(#) $Id: unicode.test,v 1.1 2008/01/29 02:18:10 patthoyts Exp $
+
+# -------------------------------------------------------------------------
+
+source [file join \
+ [file dirname [file dirname [file join [pwd] [info script]]]] \
+ devtools testutilities.tcl]
+
+testsNeedTcl 8.3
+testsNeedTcltest 1.0
+
+testing {
+ useLocalFile unicode_data.tcl
+ useLocalFile unicode.tcl
+}
+
+# -------------------------------------------------------------------------
+
+
+test unicode-1.1 {normalizeS D: LATIN CAPITAL LETTER D, COMBINING DOT ABOVE, COMBINING DOT BELOW} {
+ unicode::normalizeS D "\u0044\u0307\u0323"
+} "\u0044\u0323\u0307"
+
+test unicode-1.2 {normalize D: LATIN CAPITAL LETTER D, COMBINING DOT ABOVE, COMBINING DOT BELOW} {
+ unicode::normalize D {7692 775}
+} {68 803 775}
+
+test unicode-1.3 {normalize D: LATIN CAPITAL LETTER D, COMBINING DOT ABOVE, COMBINING DOT BELOW} {
+ unicode::normalize D {68 803 775}
+} {68 803 775}
+
+test unicode-1.4 {normalize D: LATIN CAPITAL LETTER D, COMBINING DOT ABOVE, COMBINING DOT BELOW} {
+ unicode::normalize D {7692 775}
+} {68 803 775}
+
+test unicode-1.5 {normalize D: LATIN CAPITAL LETTER D, COMBINING DOT ABOVE, COMBINING DOT BELOW} {
+ unicode::normalize D {68 803 775}
+} {68 803 775}
+
+
+test unicode-1.6 {normalizeS D: NO-BREAK SPACE} {
+ unicode::normalizeS D "\u00A0"
+} "\u00A0"
+
+test unicode-1.7 {normalize D: NO-BREAK SPACE} {
+ unicode::normalize D 160
+} {160}
+
+test unicode-1.8 {normalize D: NO-BREAK SPACE} {
+ unicode::normalize D 160
+} {160}
+
+test unicode-1.9 {normalize D: NO-BREAK SPACE} {
+ unicode::normalize D 32
+} {32}
+
+test unicode-1.10 {normalize D: NO-BREAK SPACE} {
+ unicode::normalize D 32
+} {32}
+
+
+test unicode-1.11 {normalizeS D: VULGAR FRACTION ONE HALF} {
+ unicode::normalizeS D "\u00BD"
+} "\u00BD"
+
+test unicode-1.12 {normalize D: VULGAR FRACTION ONE HALF} {
+ unicode::normalize D 189
+} {189}
+
+test unicode-1.13 {normalize D: VULGAR FRACTION ONE HALF} {
+ unicode::normalize D 189
+} {189}
+
+test unicode-1.14 {normalize D: VULGAR FRACTION ONE HALF} {
+ unicode::normalize D {49 8260 50}
+} {49 8260 50}
+
+test unicode-1.15 {normalize D: VULGAR FRACTION ONE HALF} {
+ unicode::normalize D {49 8260 50}
+} {49 8260 50}
+
+
+test unicode-1.16 {normalizeS D: ORIYA LETTER RRA} {
+ unicode::normalizeS D "\u0B5C"
+} "\u0B21\u0B3C"
+
+test unicode-1.17 {normalize D: ORIYA LETTER RRA} {
+ unicode::normalize D {2849 2876}
+} {2849 2876}
+
+test unicode-1.18 {normalize D: ORIYA LETTER RRA} {
+ unicode::normalize D {2849 2876}
+} {2849 2876}
+
+test unicode-1.19 {normalize D: ORIYA LETTER RRA} {
+ unicode::normalize D {2849 2876}
+} {2849 2876}
+
+test unicode-1.20 {normalize D: ORIYA LETTER RRA} {
+ unicode::normalize D {2849 2876}
+} {2849 2876}
+
+
+test unicode-1.21 {normalizeS D: KANNADA VOWEL SIGN EE} {
+ unicode::normalizeS D "\u0CC7"
+} "\u0CC6\u0CD5"
+
+test unicode-1.22 {normalize D: KANNADA VOWEL SIGN EE} {
+ unicode::normalize D 3271
+} {3270 3285}
+
+test unicode-1.23 {normalize D: KANNADA VOWEL SIGN EE} {
+ unicode::normalize D {3270 3285}
+} {3270 3285}
+
+test unicode-1.24 {normalize D: KANNADA VOWEL SIGN EE} {
+ unicode::normalize D 3271
+} {3270 3285}
+
+test unicode-1.25 {normalize D: KANNADA VOWEL SIGN EE} {
+ unicode::normalize D {3270 3285}
+} {3270 3285}
+
+
+test unicode-1.26 {normalizeS D: TIBETAN LETTER GHA} {
+ unicode::normalizeS D "\u0F43"
+} "\u0F42\u0FB7"
+
+test unicode-1.27 {normalize D: TIBETAN LETTER GHA} {
+ unicode::normalize D {3906 4023}
+} {3906 4023}
+
+test unicode-1.28 {normalize D: TIBETAN LETTER GHA} {
+ unicode::normalize D {3906 4023}
+} {3906 4023}
+
+test unicode-1.29 {normalize D: TIBETAN LETTER GHA} {
+ unicode::normalize D {3906 4023}
+} {3906 4023}
+
+test unicode-1.30 {normalize D: TIBETAN LETTER GHA} {
+ unicode::normalize D {3906 4023}
+} {3906 4023}
+
+
+test unicode-1.31 {normalizeS D: MODIFIER LETTER CAPITAL A} {
+ unicode::normalizeS D "\u1D2C"
+} "\u1D2C"
+
+test unicode-1.32 {normalize D: MODIFIER LETTER CAPITAL A} {
+ unicode::normalize D 7468
+} {7468}
+
+test unicode-1.33 {normalize D: MODIFIER LETTER CAPITAL A} {
+ unicode::normalize D 7468
+} {7468}
+
+test unicode-1.34 {normalize D: MODIFIER LETTER CAPITAL A} {
+ unicode::normalize D 65
+} {65}
+
+test unicode-1.35 {normalize D: MODIFIER LETTER CAPITAL A} {
+ unicode::normalize D 65
+} {65}
+
+
+test unicode-1.36 {normalizeS D: GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA} {
+ unicode::normalizeS D "\u1F14"
+} "\u03B5\u0313\u0301"
+
+test unicode-1.37 {normalize D: GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA} {
+ unicode::normalize D 7956
+} {949 787 769}
+
+test unicode-1.38 {normalize D: GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA} {
+ unicode::normalize D {949 787 769}
+} {949 787 769}
+
+test unicode-1.39 {normalize D: GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA} {
+ unicode::normalize D 7956
+} {949 787 769}
+
+test unicode-1.40 {normalize D: GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA} {
+ unicode::normalize D {949 787 769}
+} {949 787 769}
+
+
+test unicode-1.41 {normalizeS D: KANGXI RADICAL SPROUT} {
+ unicode::normalizeS D "\u2F2C"
+} "\u2F2C"
+
+test unicode-1.42 {normalize D: KANGXI RADICAL SPROUT} {
+ unicode::normalize D 12076
+} {12076}
+
+test unicode-1.43 {normalize D: KANGXI RADICAL SPROUT} {
+ unicode::normalize D 12076
+} {12076}
+
+test unicode-1.44 {normalize D: KANGXI RADICAL SPROUT} {
+ unicode::normalize D 23662
+} {23662}
+
+test unicode-1.45 {normalize D: KANGXI RADICAL SPROUT} {
+ unicode::normalize D 23662
+} {23662}
+
+
+test unicode-1.46 {normalizeS D: HIRAGANA LETTER DE} {
+ unicode::normalizeS D "\u3067"
+} "\u3066\u3099"
+
+test unicode-1.47 {normalize D: HIRAGANA LETTER DE} {
+ unicode::normalize D 12391
+} {12390 12441}
+
+test unicode-1.48 {normalize D: HIRAGANA LETTER DE} {
+ unicode::normalize D {12390 12441}
+} {12390 12441}
+
+test unicode-1.49 {normalize D: HIRAGANA LETTER DE} {
+ unicode::normalize D 12391
+} {12390 12441}
+
+test unicode-1.50 {normalize D: HIRAGANA LETTER DE} {
+ unicode::normalize D {12390 12441}
+} {12390 12441}
+
+
+test unicode-1.51 {normalizeS D: KATAKANA LETTER PA} {
+ unicode::normalizeS D "\u30D1"
+} "\u30CF\u309A"
+
+test unicode-1.52 {normalize D: KATAKANA LETTER PA} {
+ unicode::normalize D 12497
+} {12495 12442}
+
+test unicode-1.53 {normalize D: KATAKANA LETTER PA} {
+ unicode::normalize D {12495 12442}
+} {12495 12442}
+
+test unicode-1.54 {normalize D: KATAKANA LETTER PA} {
+ unicode::normalize D 12497
+} {12495 12442}
+
+test unicode-1.55 {normalize D: KATAKANA LETTER PA} {
+ unicode::normalize D {12495 12442}
+} {12495 12442}
+
+
+test unicode-1.56 {normalizeS D: HANGUL LETTER SIOS-PIEUP} {
+ unicode::normalizeS D "\u317D"
+} "\u317D"
+
+test unicode-1.57 {normalize D: HANGUL LETTER SIOS-PIEUP} {
+ unicode::normalize D 12669
+} {12669}
+
+test unicode-1.58 {normalize D: HANGUL LETTER SIOS-PIEUP} {
+ unicode::normalize D 12669
+} {12669}
+
+test unicode-1.59 {normalize D: HANGUL LETTER SIOS-PIEUP} {
+ unicode::normalize D 4402
+} {4402}
+
+test unicode-1.60 {normalize D: HANGUL LETTER SIOS-PIEUP} {
+ unicode::normalize D 4402
+} {4402}
+
+
+test unicode-1.61 {normalizeS D: HANGUL SYLLABLE GYANG} {
+ unicode::normalizeS D "\uAC4D"
+} "\u1100\u1163\u11BC"
+
+test unicode-1.62 {normalize D: HANGUL SYLLABLE GYANG} {
+ unicode::normalize D 44109
+} {4352 4451 4540}
+
+test unicode-1.63 {normalize D: HANGUL SYLLABLE GYANG} {
+ unicode::normalize D {4352 4451 4540}
+} {4352 4451 4540}
+
+test unicode-1.64 {normalize D: HANGUL SYLLABLE GYANG} {
+ unicode::normalize D 44109
+} {4352 4451 4540}
+
+test unicode-1.65 {normalize D: HANGUL SYLLABLE GYANG} {
+ unicode::normalize D {4352 4451 4540}
+} {4352 4451 4540}
+
+
+test unicode-1.66 {normalizeS D: CJK COMPATIBILITY IDEOGRAPH-F98E} {
+ unicode::normalizeS D "\uF98E"
+} "\u5E74"
+
+test unicode-1.67 {normalize D: CJK COMPATIBILITY IDEOGRAPH-F98E} {
+ unicode::normalize D 24180
+} {24180}
+
+test unicode-1.68 {normalize D: CJK COMPATIBILITY IDEOGRAPH-F98E} {
+ unicode::normalize D 24180
+} {24180}
+
+test unicode-1.69 {normalize D: CJK COMPATIBILITY IDEOGRAPH-F98E} {
+ unicode::normalize D 24180
+} {24180}
+
+test unicode-1.70 {normalize D: CJK COMPATIBILITY IDEOGRAPH-F98E} {
+ unicode::normalize D 24180
+} {24180}
+
+
+test unicode-1.71 {normalizeS D: ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM} {
+ unicode::normalizeS D "\uFBAA"
+} "\uFBAA"
+
+test unicode-1.72 {normalize D: ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM} {
+ unicode::normalize D 64426
+} {64426}
+
+test unicode-1.73 {normalize D: ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM} {
+ unicode::normalize D 64426
+} {64426}
+
+test unicode-1.74 {normalize D: ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM} {
+ unicode::normalize D 1726
+} {1726}
+
+test unicode-1.75 {normalize D: ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM} {
+ unicode::normalize D 1726
+} {1726}
+
+
+test unicode-1.76 {normalizeS D: ARABIC LIGATURE AIN WITH JEEM ISOLATED FORM} {
+ unicode::normalizeS D "\uFC29"
+} "\uFC29"
+
+test unicode-1.77 {normalize D: ARABIC LIGATURE AIN WITH JEEM ISOLATED FORM} {
+ unicode::normalize D 64553
+} {64553}
+
+test unicode-1.78 {normalize D: ARABIC LIGATURE AIN WITH JEEM ISOLATED FORM} {
+ unicode::normalize D 64553
+} {64553}
+
+test unicode-1.79 {normalize D: ARABIC LIGATURE AIN WITH JEEM ISOLATED FORM} {
+ unicode::normalize D {1593 1580}
+} {1593 1580}
+
+test unicode-1.80 {normalize D: ARABIC LIGATURE AIN WITH JEEM ISOLATED FORM} {
+ unicode::normalize D {1593 1580}
+} {1593 1580}
+
+
+test unicode-1.81 {normalizeS D: FULLWIDTH DIGIT THREE} {
+ unicode::normalizeS D "\uFF13"
+} "\uFF13"
+
+test unicode-1.82 {normalize D: FULLWIDTH DIGIT THREE} {
+ unicode::normalize D 65299
+} {65299}
+
+test unicode-1.83 {normalize D: FULLWIDTH DIGIT THREE} {
+ unicode::normalize D 65299
+} {65299}
+
+test unicode-1.84 {normalize D: FULLWIDTH DIGIT THREE} {
+ unicode::normalize D 51
+} {51}
+
+test unicode-1.85 {normalize D: FULLWIDTH DIGIT THREE} {
+ unicode::normalize D 51
+} {51}
+
+
+test unicode-1.86 {normalizeS D: LATIN SMALL LETTER A, COMBINING CYRILLIC TITLO, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B} {
+ unicode::normalizeS D "\u0061\u0483\u0315\u0300\u05AE\u0062"
+} "\u0061\u05AE\u0483\u0300\u0315\u0062"
+
+test unicode-1.87 {normalize D: LATIN SMALL LETTER A, COMBINING CYRILLIC TITLO, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B} {
+ unicode::normalize D {97 1454 1155 768 789 98}
+} {97 1454 1155 768 789 98}
+
+test unicode-1.88 {normalize D: LATIN SMALL LETTER A, COMBINING CYRILLIC TITLO, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B} {
+ unicode::normalize D {97 1454 1155 768 789 98}
+} {97 1454 1155 768 789 98}
+
+test unicode-1.89 {normalize D: LATIN SMALL LETTER A, COMBINING CYRILLIC TITLO, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B} {
+ unicode::normalize D {97 1454 1155 768 789 98}
+} {97 1454 1155 768 789 98}
+
+test unicode-1.90 {normalize D: LATIN SMALL LETTER A, COMBINING CYRILLIC TITLO, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B} {
+ unicode::normalize D {97 1454 1155 768 789 98}
+} {97 1454 1155 768 789 98}
+
+
+test unicode-1.91 {normalizeS D: LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, COMBINING RING OVERLAY, LATIN SMALL LETTER B} {
+ unicode::normalizeS D "\u0061\u093C\u0334\u20D8\u0062"
+} "\u0061\u0334\u20D8\u093C\u0062"
+
+test unicode-1.92 {normalize D: LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, COMBINING RING OVERLAY, LATIN SMALL LETTER B} {
+ unicode::normalize D {97 820 8408 2364 98}
+} {97 820 8408 2364 98}
+
+test unicode-1.93 {normalize D: LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, COMBINING RING OVERLAY, LATIN SMALL LETTER B} {
+ unicode::normalize D {97 820 8408 2364 98}
+} {97 820 8408 2364 98}
+
+test unicode-1.94 {normalize D: LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, COMBINING RING OVERLAY, LATIN SMALL LETTER B} {
+ unicode::normalize D {97 820 8408 2364 98}
+} {97 820 8408 2364 98}
+
+test unicode-1.95 {normalize D: LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, COMBINING RING OVERLAY, LATIN SMALL LETTER B} {
+ unicode::normalize D {97 820 8408 2364 98}
+} {97 820 8408 2364 98}
+
+
+test unicode-1.96 {normalizeS D: HANGUL SYLLABLE BYO, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT} {
+ unicode::normalizeS D "\uBD64\u0334\u11AE"
+} "\u1107\u116D\u0334\u11AE"
+
+test unicode-1.97 {normalize D: HANGUL SYLLABLE BYO, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT} {
+ unicode::normalize D {48484 820 4526}
+} {4359 4461 820 4526}
+
+test unicode-1.98 {normalize D: HANGUL SYLLABLE BYO, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT} {
+ unicode::normalize D {4359 4461 820 4526}
+} {4359 4461 820 4526}
+
+test unicode-1.99 {normalize D: HANGUL SYLLABLE BYO, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT} {
+ unicode::normalize D {48484 820 4526}
+} {4359 4461 820 4526}
+
+test unicode-1.100 {normalize D: HANGUL SYLLABLE BYO, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT} {
+ unicode::normalize D {4359 4461 820 4526}
+} {4359 4461 820 4526}
+
+
+test unicode-2.1 {normalize C: LATIN CAPITAL LETTER D, COMBINING DOT ABOVE, COMBINING DOT BELOW} {
+ unicode::normalize C {68 775 803}
+} {7692 775}
+
+test unicode-2.2 {normalizeS C: LATIN CAPITAL LETTER D, COMBINING DOT ABOVE, COMBINING DOT BELOW} {
+ unicode::normalizeS C "\u1E0C\u0307"
+} "\u1E0C\u0307"
+
+test unicode-2.3 {normalize C: LATIN CAPITAL LETTER D, COMBINING DOT ABOVE, COMBINING DOT BELOW} {
+ unicode::normalize C {68 803 775}
+} {7692 775}
+
+test unicode-2.4 {normalize C: LATIN CAPITAL LETTER D, COMBINING DOT ABOVE, COMBINING DOT BELOW} {
+ unicode::normalize C {7692 775}
+} {7692 775}
+
+test unicode-2.5 {normalize C: LATIN CAPITAL LETTER D, COMBINING DOT ABOVE, COMBINING DOT BELOW} {
+ unicode::normalize C {68 803 775}
+} {7692 775}
+
+
+test unicode-2.6 {normalize C: NO-BREAK SPACE} {
+ unicode::normalize C 160
+} {160}
+
+test unicode-2.7 {normalizeS C: NO-BREAK SPACE} {
+ unicode::normalizeS C "\u00A0"
+} "\u00A0"
+
+test unicode-2.8 {normalize C: NO-BREAK SPACE} {
+ unicode::normalize C 160
+} {160}
+
+test unicode-2.9 {normalize C: NO-BREAK SPACE} {
+ unicode::normalize C 32
+} {32}
+
+test unicode-2.10 {normalize C: NO-BREAK SPACE} {
+ unicode::normalize C 32
+} {32}
+
+
+test unicode-2.11 {normalize C: VULGAR FRACTION ONE HALF} {
+ unicode::normalize C 189
+} {189}
+
+test unicode-2.12 {normalizeS C: VULGAR FRACTION ONE HALF} {
+ unicode::normalizeS C "\u00BD"
+} "\u00BD"
+
+test unicode-2.13 {normalize C: VULGAR FRACTION ONE HALF} {
+ unicode::normalize C 189
+} {189}
+
+test unicode-2.14 {normalize C: VULGAR FRACTION ONE HALF} {
+ unicode::normalize C {49 8260 50}
+} {49 8260 50}
+
+test unicode-2.15 {normalize C: VULGAR FRACTION ONE HALF} {
+ unicode::normalize C {49 8260 50}
+} {49 8260 50}
+
+
+test unicode-2.16 {normalize C: ORIYA LETTER RRA} {
+ unicode::normalize C 2908
+} {2849 2876}
+
+test unicode-2.17 {normalizeS C: ORIYA LETTER RRA} {
+ unicode::normalizeS C "\u0B21\u0B3C"
+} "\u0B21\u0B3C"
+
+test unicode-2.18 {normalize C: ORIYA LETTER RRA} {
+ unicode::normalize C {2849 2876}
+} {2849 2876}
+
+test unicode-2.19 {normalize C: ORIYA LETTER RRA} {
+ unicode::normalize C {2849 2876}
+} {2849 2876}
+
+test unicode-2.20 {normalize C: ORIYA LETTER RRA} {
+ unicode::normalize C {2849 2876}
+} {2849 2876}
+
+
+test unicode-2.21 {normalize C: KANNADA VOWEL SIGN EE} {
+ unicode::normalize C 3271
+} {3271}
+
+test unicode-2.22 {normalizeS C: KANNADA VOWEL SIGN EE} {
+ unicode::normalizeS C "\u0CC7"
+} "\u0CC7"
+
+test unicode-2.23 {normalize C: KANNADA VOWEL SIGN EE} {
+ unicode::normalize C {3270 3285}
+} {3271}
+
+test unicode-2.24 {normalize C: KANNADA VOWEL SIGN EE} {
+ unicode::normalize C 3271
+} {3271}
+
+test unicode-2.25 {normalize C: KANNADA VOWEL SIGN EE} {
+ unicode::normalize C {3270 3285}
+} {3271}
+
+
+test unicode-2.26 {normalize C: TIBETAN LETTER GHA} {
+ unicode::normalize C 3907
+} {3906 4023}
+
+test unicode-2.27 {normalizeS C: TIBETAN LETTER GHA} {
+ unicode::normalizeS C "\u0F42\u0FB7"
+} "\u0F42\u0FB7"
+
+test unicode-2.28 {normalize C: TIBETAN LETTER GHA} {
+ unicode::normalize C {3906 4023}
+} {3906 4023}
+
+test unicode-2.29 {normalize C: TIBETAN LETTER GHA} {
+ unicode::normalize C {3906 4023}
+} {3906 4023}
+
+test unicode-2.30 {normalize C: TIBETAN LETTER GHA} {
+ unicode::normalize C {3906 4023}
+} {3906 4023}
+
+
+test unicode-2.31 {normalize C: MODIFIER LETTER CAPITAL A} {
+ unicode::normalize C 7468
+} {7468}
+
+test unicode-2.32 {normalizeS C: MODIFIER LETTER CAPITAL A} {
+ unicode::normalizeS C "\u1D2C"
+} "\u1D2C"
+
+test unicode-2.33 {normalize C: MODIFIER LETTER CAPITAL A} {
+ unicode::normalize C 7468
+} {7468}
+
+test unicode-2.34 {normalize C: MODIFIER LETTER CAPITAL A} {
+ unicode::normalize C 65
+} {65}
+
+test unicode-2.35 {normalize C: MODIFIER LETTER CAPITAL A} {
+ unicode::normalize C 65
+} {65}
+
+
+test unicode-2.36 {normalize C: GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA} {
+ unicode::normalize C 7956
+} {7956}
+
+test unicode-2.37 {normalizeS C: GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA} {
+ unicode::normalizeS C "\u1F14"
+} "\u1F14"
+
+test unicode-2.38 {normalize C: GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA} {
+ unicode::normalize C {949 787 769}
+} {7956}
+
+test unicode-2.39 {normalize C: GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA} {
+ unicode::normalize C 7956
+} {7956}
+
+test unicode-2.40 {normalize C: GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA} {
+ unicode::normalize C {949 787 769}
+} {7956}
+
+
+test unicode-2.41 {normalize C: KANGXI RADICAL SPROUT} {
+ unicode::normalize C 12076
+} {12076}
+
+test unicode-2.42 {normalizeS C: KANGXI RADICAL SPROUT} {
+ unicode::normalizeS C "\u2F2C"
+} "\u2F2C"
+
+test unicode-2.43 {normalize C: KANGXI RADICAL SPROUT} {
+ unicode::normalize C 12076
+} {12076}
+
+test unicode-2.44 {normalize C: KANGXI RADICAL SPROUT} {
+ unicode::normalize C 23662
+} {23662}
+
+test unicode-2.45 {normalize C: KANGXI RADICAL SPROUT} {
+ unicode::normalize C 23662
+} {23662}
+
+
+test unicode-2.46 {normalize C: HIRAGANA LETTER DE} {
+ unicode::normalize C 12391
+} {12391}
+
+test unicode-2.47 {normalizeS C: HIRAGANA LETTER DE} {
+ unicode::normalizeS C "\u3067"
+} "\u3067"
+
+test unicode-2.48 {normalize C: HIRAGANA LETTER DE} {
+ unicode::normalize C {12390 12441}
+} {12391}
+
+test unicode-2.49 {normalize C: HIRAGANA LETTER DE} {
+ unicode::normalize C 12391
+} {12391}
+
+test unicode-2.50 {normalize C: HIRAGANA LETTER DE} {
+ unicode::normalize C {12390 12441}
+} {12391}
+
+
+test unicode-2.51 {normalize C: KATAKANA LETTER PA} {
+ unicode::normalize C 12497
+} {12497}
+
+test unicode-2.52 {normalizeS C: KATAKANA LETTER PA} {
+ unicode::normalizeS C "\u30D1"
+} "\u30D1"
+
+test unicode-2.53 {normalize C: KATAKANA LETTER PA} {
+ unicode::normalize C {12495 12442}
+} {12497}
+
+test unicode-2.54 {normalize C: KATAKANA LETTER PA} {
+ unicode::normalize C 12497
+} {12497}
+
+test unicode-2.55 {normalize C: KATAKANA LETTER PA} {
+ unicode::normalize C {12495 12442}
+} {12497}
+
+
+test unicode-2.56 {normalize C: HANGUL LETTER SIOS-PIEUP} {
+ unicode::normalize C 12669
+} {12669}
+
+test unicode-2.57 {normalizeS C: HANGUL LETTER SIOS-PIEUP} {
+ unicode::normalizeS C "\u317D"
+} "\u317D"
+
+test unicode-2.58 {normalize C: HANGUL LETTER SIOS-PIEUP} {
+ unicode::normalize C 12669
+} {12669}
+
+test unicode-2.59 {normalize C: HANGUL LETTER SIOS-PIEUP} {
+ unicode::normalize C 4402
+} {4402}
+
+test unicode-2.60 {normalize C: HANGUL LETTER SIOS-PIEUP} {
+ unicode::normalize C 4402
+} {4402}
+
+
+test unicode-2.61 {normalize C: HANGUL SYLLABLE GYANG} {
+ unicode::normalize C 44109
+} {44109}
+
+test unicode-2.62 {normalizeS C: HANGUL SYLLABLE GYANG} {
+ unicode::normalizeS C "\uAC4D"
+} "\uAC4D"
+
+test unicode-2.63 {normalize C: HANGUL SYLLABLE GYANG} {
+ unicode::normalize C {4352 4451 4540}
+} {44109}
+
+test unicode-2.64 {normalize C: HANGUL SYLLABLE GYANG} {
+ unicode::normalize C 44109
+} {44109}
+
+test unicode-2.65 {normalize C: HANGUL SYLLABLE GYANG} {
+ unicode::normalize C {4352 4451 4540}
+} {44109}
+
+
+test unicode-2.66 {normalize C: CJK COMPATIBILITY IDEOGRAPH-F98E} {
+ unicode::normalize C 63886
+} {24180}
+
+test unicode-2.67 {normalizeS C: CJK COMPATIBILITY IDEOGRAPH-F98E} {
+ unicode::normalizeS C "\u5E74"
+} "\u5E74"
+
+test unicode-2.68 {normalize C: CJK COMPATIBILITY IDEOGRAPH-F98E} {
+ unicode::normalize C 24180
+} {24180}
+
+test unicode-2.69 {normalize C: CJK COMPATIBILITY IDEOGRAPH-F98E} {
+ unicode::normalize C 24180
+} {24180}
+
+test unicode-2.70 {normalize C: CJK COMPATIBILITY IDEOGRAPH-F98E} {
+ unicode::normalize C 24180
+} {24180}
+
+
+test unicode-2.71 {normalize C: ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM} {
+ unicode::normalize C 64426
+} {64426}
+
+test unicode-2.72 {normalizeS C: ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM} {
+ unicode::normalizeS C "\uFBAA"
+} "\uFBAA"
+
+test unicode-2.73 {normalize C: ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM} {
+ unicode::normalize C 64426
+} {64426}
+
+test unicode-2.74 {normalize C: ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM} {
+ unicode::normalize C 1726
+} {1726}
+
+test unicode-2.75 {normalize C: ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM} {
+ unicode::normalize C 1726
+} {1726}
+
+
+test unicode-2.76 {normalize C: ARABIC LIGATURE AIN WITH JEEM ISOLATED FORM} {
+ unicode::normalize C 64553
+} {64553}
+
+test unicode-2.77 {normalizeS C: ARABIC LIGATURE AIN WITH JEEM ISOLATED FORM} {
+ unicode::normalizeS C "\uFC29"
+} "\uFC29"
+
+test unicode-2.78 {normalize C: ARABIC LIGATURE AIN WITH JEEM ISOLATED FORM} {
+ unicode::normalize C 64553
+} {64553}
+
+test unicode-2.79 {normalize C: ARABIC LIGATURE AIN WITH JEEM ISOLATED FORM} {
+ unicode::normalize C {1593 1580}
+} {1593 1580}
+
+test unicode-2.80 {normalize C: ARABIC LIGATURE AIN WITH JEEM ISOLATED FORM} {
+ unicode::normalize C {1593 1580}
+} {1593 1580}
+
+
+test unicode-2.81 {normalize C: FULLWIDTH DIGIT THREE} {
+ unicode::normalize C 65299
+} {65299}
+
+test unicode-2.82 {normalizeS C: FULLWIDTH DIGIT THREE} {
+ unicode::normalizeS C "\uFF13"
+} "\uFF13"
+
+test unicode-2.83 {normalize C: FULLWIDTH DIGIT THREE} {
+ unicode::normalize C 65299
+} {65299}
+
+test unicode-2.84 {normalize C: FULLWIDTH DIGIT THREE} {
+ unicode::normalize C 51
+} {51}
+
+test unicode-2.85 {normalize C: FULLWIDTH DIGIT THREE} {
+ unicode::normalize C 51
+} {51}
+
+
+test unicode-2.86 {normalize C: LATIN SMALL LETTER A, COMBINING CYRILLIC TITLO, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B} {
+ unicode::normalize C {97 1155 789 768 1454 98}
+} {97 1454 1155 768 789 98}
+
+test unicode-2.87 {normalizeS C: LATIN SMALL LETTER A, COMBINING CYRILLIC TITLO, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B} {
+ unicode::normalizeS C "\u0061\u05AE\u0483\u0300\u0315\u0062"
+} "\u0061\u05AE\u0483\u0300\u0315\u0062"
+
+test unicode-2.88 {normalize C: LATIN SMALL LETTER A, COMBINING CYRILLIC TITLO, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B} {
+ unicode::normalize C {97 1454 1155 768 789 98}
+} {97 1454 1155 768 789 98}
+
+test unicode-2.89 {normalize C: LATIN SMALL LETTER A, COMBINING CYRILLIC TITLO, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B} {
+ unicode::normalize C {97 1454 1155 768 789 98}
+} {97 1454 1155 768 789 98}
+
+test unicode-2.90 {normalize C: LATIN SMALL LETTER A, COMBINING CYRILLIC TITLO, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B} {
+ unicode::normalize C {97 1454 1155 768 789 98}
+} {97 1454 1155 768 789 98}
+
+
+test unicode-2.91 {normalize C: LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, COMBINING RING OVERLAY, LATIN SMALL LETTER B} {
+ unicode::normalize C {97 2364 820 8408 98}
+} {97 820 8408 2364 98}
+
+test unicode-2.92 {normalizeS C: LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, COMBINING RING OVERLAY, LATIN SMALL LETTER B} {
+ unicode::normalizeS C "\u0061\u0334\u20D8\u093C\u0062"
+} "\u0061\u0334\u20D8\u093C\u0062"
+
+test unicode-2.93 {normalize C: LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, COMBINING RING OVERLAY, LATIN SMALL LETTER B} {
+ unicode::normalize C {97 820 8408 2364 98}
+} {97 820 8408 2364 98}
+
+test unicode-2.94 {normalize C: LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, COMBINING RING OVERLAY, LATIN SMALL LETTER B} {
+ unicode::normalize C {97 820 8408 2364 98}
+} {97 820 8408 2364 98}
+
+test unicode-2.95 {normalize C: LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, COMBINING RING OVERLAY, LATIN SMALL LETTER B} {
+ unicode::normalize C {97 820 8408 2364 98}
+} {97 820 8408 2364 98}
+
+
+test unicode-2.96 {normalize C: HANGUL SYLLABLE BYO, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT} {
+ unicode::normalize C {48484 820 4526}
+} {48484 820 4526}
+
+test unicode-2.97 {normalizeS C: HANGUL SYLLABLE BYO, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT} {
+ unicode::normalizeS C "\uBD64\u0334\u11AE"
+} "\uBD64\u0334\u11AE"
+
+test unicode-2.98 {normalize C: HANGUL SYLLABLE BYO, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT} {
+ unicode::normalize C {4359 4461 820 4526}
+} {48484 820 4526}
+
+test unicode-2.99 {normalize C: HANGUL SYLLABLE BYO, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT} {
+ unicode::normalize C {48484 820 4526}
+} {48484 820 4526}
+
+test unicode-2.100 {normalize C: HANGUL SYLLABLE BYO, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT} {
+ unicode::normalize C {4359 4461 820 4526}
+} {48484 820 4526}
+
+
+test unicode-3.1 {normalize KD: LATIN CAPITAL LETTER D, COMBINING DOT ABOVE, COMBINING DOT BELOW} {
+ unicode::normalize KD {68 775 803}
+} {68 803 775}
+
+test unicode-3.2 {normalize KD: LATIN CAPITAL LETTER D, COMBINING DOT ABOVE, COMBINING DOT BELOW} {
+ unicode::normalize KD {7692 775}
+} {68 803 775}
+
+test unicode-3.3 {normalizeS KD: LATIN CAPITAL LETTER D, COMBINING DOT ABOVE, COMBINING DOT BELOW} {
+ unicode::normalizeS KD "\u0044\u0323\u0307"
+} "\u0044\u0323\u0307"
+
+test unicode-3.4 {normalize KD: LATIN CAPITAL LETTER D, COMBINING DOT ABOVE, COMBINING DOT BELOW} {
+ unicode::normalize KD {7692 775}
+} {68 803 775}
+
+test unicode-1.5 {normalize KD: LATIN CAPITAL LETTER D, COMBINING DOT ABOVE, COMBINING DOT BELOW} {
+ unicode::normalize KD {68 803 775}
+} {68 803 775}
+
+
+test unicode-3.6 {normalize KD: NO-BREAK SPACE} {
+ unicode::normalize KD 160
+} {32}
+
+test unicode-3.7 {normalize KD: NO-BREAK SPACE} {
+ unicode::normalize KD 160
+} {32}
+
+test unicode-3.8 {normalizeS KD: NO-BREAK SPACE} {
+ unicode::normalizeS KD "\u00A0"
+} "\u0020"
+
+test unicode-3.9 {normalize KD: NO-BREAK SPACE} {
+ unicode::normalize KD 32
+} {32}
+
+test unicode-1.10 {normalize KD: NO-BREAK SPACE} {
+ unicode::normalize KD 32
+} {32}
+
+
+test unicode-3.11 {normalize KD: VULGAR FRACTION ONE HALF} {
+ unicode::normalize KD 189
+} {49 8260 50}
+
+test unicode-3.12 {normalize KD: VULGAR FRACTION ONE HALF} {
+ unicode::normalize KD 189
+} {49 8260 50}
+
+test unicode-3.13 {normalizeS KD: VULGAR FRACTION ONE HALF} {
+ unicode::normalizeS KD "\u00BD"
+} "\u0031\u2044\u0032"
+
+test unicode-3.14 {normalize KD: VULGAR FRACTION ONE HALF} {
+ unicode::normalize KD {49 8260 50}
+} {49 8260 50}
+
+test unicode-1.15 {normalize KD: VULGAR FRACTION ONE HALF} {
+ unicode::normalize KD {49 8260 50}
+} {49 8260 50}
+
+
+test unicode-3.16 {normalize KD: ORIYA LETTER RRA} {
+ unicode::normalize KD 2908
+} {2849 2876}
+
+test unicode-3.17 {normalize KD: ORIYA LETTER RRA} {
+ unicode::normalize KD {2849 2876}
+} {2849 2876}
+
+test unicode-3.18 {normalizeS KD: ORIYA LETTER RRA} {
+ unicode::normalizeS KD "\u0B21\u0B3C"
+} "\u0B21\u0B3C"
+
+test unicode-3.19 {normalize KD: ORIYA LETTER RRA} {
+ unicode::normalize KD {2849 2876}
+} {2849 2876}
+
+test unicode-1.20 {normalize KD: ORIYA LETTER RRA} {
+ unicode::normalize KD {2849 2876}
+} {2849 2876}
+
+
+test unicode-3.21 {normalize KD: KANNADA VOWEL SIGN EE} {
+ unicode::normalize KD 3271
+} {3270 3285}
+
+test unicode-3.22 {normalize KD: KANNADA VOWEL SIGN EE} {
+ unicode::normalize KD 3271
+} {3270 3285}
+
+test unicode-3.23 {normalizeS KD: KANNADA VOWEL SIGN EE} {
+ unicode::normalizeS KD "\u0CC6\u0CD5"
+} "\u0CC6\u0CD5"
+
+test unicode-3.24 {normalize KD: KANNADA VOWEL SIGN EE} {
+ unicode::normalize KD 3271
+} {3270 3285}
+
+test unicode-1.25 {normalize KD: KANNADA VOWEL SIGN EE} {
+ unicode::normalize KD {3270 3285}
+} {3270 3285}
+
+
+test unicode-3.26 {normalize KD: TIBETAN LETTER GHA} {
+ unicode::normalize KD 3907
+} {3906 4023}
+
+test unicode-3.27 {normalize KD: TIBETAN LETTER GHA} {
+ unicode::normalize KD {3906 4023}
+} {3906 4023}
+
+test unicode-3.28 {normalizeS KD: TIBETAN LETTER GHA} {
+ unicode::normalizeS KD "\u0F42\u0FB7"
+} "\u0F42\u0FB7"
+
+test unicode-3.29 {normalize KD: TIBETAN LETTER GHA} {
+ unicode::normalize KD {3906 4023}
+} {3906 4023}
+
+test unicode-1.30 {normalize KD: TIBETAN LETTER GHA} {
+ unicode::normalize KD {3906 4023}
+} {3906 4023}
+
+
+test unicode-3.31 {normalize KD: MODIFIER LETTER CAPITAL A} {
+ unicode::normalize KD 7468
+} {65}
+
+test unicode-3.32 {normalize KD: MODIFIER LETTER CAPITAL A} {
+ unicode::normalize KD 7468
+} {65}
+
+test unicode-3.33 {normalizeS KD: MODIFIER LETTER CAPITAL A} {
+ unicode::normalizeS KD "\u1D2C"
+} "\u0041"
+
+test unicode-3.34 {normalize KD: MODIFIER LETTER CAPITAL A} {
+ unicode::normalize KD 65
+} {65}
+
+test unicode-1.35 {normalize KD: MODIFIER LETTER CAPITAL A} {
+ unicode::normalize KD 65
+} {65}
+
+
+test unicode-3.36 {normalize KD: GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA} {
+ unicode::normalize KD 7956
+} {949 787 769}
+
+test unicode-3.37 {normalize KD: GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA} {
+ unicode::normalize KD 7956
+} {949 787 769}
+
+test unicode-3.38 {normalizeS KD: GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA} {
+ unicode::normalizeS KD "\u03B5\u0313\u0301"
+} "\u03B5\u0313\u0301"
+
+test unicode-3.39 {normalize KD: GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA} {
+ unicode::normalize KD 7956
+} {949 787 769}
+
+test unicode-1.40 {normalize KD: GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA} {
+ unicode::normalize KD {949 787 769}
+} {949 787 769}
+
+
+test unicode-3.41 {normalize KD: KANGXI RADICAL SPROUT} {
+ unicode::normalize KD 12076
+} {23662}
+
+test unicode-3.42 {normalize KD: KANGXI RADICAL SPROUT} {
+ unicode::normalize KD 12076
+} {23662}
+
+test unicode-3.43 {normalizeS KD: KANGXI RADICAL SPROUT} {
+ unicode::normalizeS KD "\u2F2C"
+} "\u5C6E"
+
+test unicode-3.44 {normalize KD: KANGXI RADICAL SPROUT} {
+ unicode::normalize KD 23662
+} {23662}
+
+test unicode-1.45 {normalize KD: KANGXI RADICAL SPROUT} {
+ unicode::normalize KD 23662
+} {23662}
+
+
+test unicode-3.46 {normalize KD: HIRAGANA LETTER DE} {
+ unicode::normalize KD 12391
+} {12390 12441}
+
+test unicode-3.47 {normalize KD: HIRAGANA LETTER DE} {
+ unicode::normalize KD 12391
+} {12390 12441}
+
+test unicode-3.48 {normalizeS KD: HIRAGANA LETTER DE} {
+ unicode::normalizeS KD "\u3066\u3099"
+} "\u3066\u3099"
+
+test unicode-3.49 {normalize KD: HIRAGANA LETTER DE} {
+ unicode::normalize KD 12391
+} {12390 12441}
+
+test unicode-1.50 {normalize KD: HIRAGANA LETTER DE} {
+ unicode::normalize KD {12390 12441}
+} {12390 12441}
+
+
+test unicode-3.51 {normalize KD: KATAKANA LETTER PA} {
+ unicode::normalize KD 12497
+} {12495 12442}
+
+test unicode-3.52 {normalize KD: KATAKANA LETTER PA} {
+ unicode::normalize KD 12497
+} {12495 12442}
+
+test unicode-3.53 {normalizeS KD: KATAKANA LETTER PA} {
+ unicode::normalizeS KD "\u30CF\u309A"
+} "\u30CF\u309A"
+
+test unicode-3.54 {normalize KD: KATAKANA LETTER PA} {
+ unicode::normalize KD 12497
+} {12495 12442}
+
+test unicode-1.55 {normalize KD: KATAKANA LETTER PA} {
+ unicode::normalize KD {12495 12442}
+} {12495 12442}
+
+
+test unicode-3.56 {normalize KD: HANGUL LETTER SIOS-PIEUP} {
+ unicode::normalize KD 12669
+} {4402}
+
+test unicode-3.57 {normalize KD: HANGUL LETTER SIOS-PIEUP} {
+ unicode::normalize KD 12669
+} {4402}
+
+test unicode-3.58 {normalizeS KD: HANGUL LETTER SIOS-PIEUP} {
+ unicode::normalizeS KD "\u317D"
+} "\u1132"
+
+test unicode-3.59 {normalize KD: HANGUL LETTER SIOS-PIEUP} {
+ unicode::normalize KD 4402
+} {4402}
+
+test unicode-1.60 {normalize KD: HANGUL LETTER SIOS-PIEUP} {
+ unicode::normalize KD 4402
+} {4402}
+
+
+test unicode-3.61 {normalize KD: HANGUL SYLLABLE GYANG} {
+ unicode::normalize KD 44109
+} {4352 4451 4540}
+
+test unicode-3.62 {normalize KD: HANGUL SYLLABLE GYANG} {
+ unicode::normalize KD 44109
+} {4352 4451 4540}
+
+test unicode-3.63 {normalizeS KD: HANGUL SYLLABLE GYANG} {
+ unicode::normalizeS KD "\u1100\u1163\u11BC"
+} "\u1100\u1163\u11BC"
+
+test unicode-3.64 {normalize KD: HANGUL SYLLABLE GYANG} {
+ unicode::normalize KD 44109
+} {4352 4451 4540}
+
+test unicode-1.65 {normalize KD: HANGUL SYLLABLE GYANG} {
+ unicode::normalize KD {4352 4451 4540}
+} {4352 4451 4540}
+
+
+test unicode-3.66 {normalize KD: CJK COMPATIBILITY IDEOGRAPH-F98E} {
+ unicode::normalize KD 63886
+} {24180}
+
+test unicode-3.67 {normalize KD: CJK COMPATIBILITY IDEOGRAPH-F98E} {
+ unicode::normalize KD 24180
+} {24180}
+
+test unicode-3.68 {normalizeS KD: CJK COMPATIBILITY IDEOGRAPH-F98E} {
+ unicode::normalizeS KD "\u5E74"
+} "\u5E74"
+
+test unicode-3.69 {normalize KD: CJK COMPATIBILITY IDEOGRAPH-F98E} {
+ unicode::normalize KD 24180
+} {24180}
+
+test unicode-1.70 {normalize KD: CJK COMPATIBILITY IDEOGRAPH-F98E} {
+ unicode::normalize KD 24180
+} {24180}
+
+
+test unicode-3.71 {normalize KD: ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM} {
+ unicode::normalize KD 64426
+} {1726}
+
+test unicode-3.72 {normalize KD: ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM} {
+ unicode::normalize KD 64426
+} {1726}
+
+test unicode-3.73 {normalizeS KD: ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM} {
+ unicode::normalizeS KD "\uFBAA"
+} "\u06BE"
+
+test unicode-3.74 {normalize KD: ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM} {
+ unicode::normalize KD 1726
+} {1726}
+
+test unicode-1.75 {normalize KD: ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM} {
+ unicode::normalize KD 1726
+} {1726}
+
+
+test unicode-3.76 {normalize KD: ARABIC LIGATURE AIN WITH JEEM ISOLATED FORM} {
+ unicode::normalize KD 64553
+} {1593 1580}
+
+test unicode-3.77 {normalize KD: ARABIC LIGATURE AIN WITH JEEM ISOLATED FORM} {
+ unicode::normalize KD 64553
+} {1593 1580}
+
+test unicode-3.78 {normalizeS KD: ARABIC LIGATURE AIN WITH JEEM ISOLATED FORM} {
+ unicode::normalizeS KD "\uFC29"
+} "\u0639\u062C"
+
+test unicode-3.79 {normalize KD: ARABIC LIGATURE AIN WITH JEEM ISOLATED FORM} {
+ unicode::normalize KD {1593 1580}
+} {1593 1580}
+
+test unicode-1.80 {normalize KD: ARABIC LIGATURE AIN WITH JEEM ISOLATED FORM} {
+ unicode::normalize KD {1593 1580}
+} {1593 1580}
+
+
+test unicode-3.81 {normalize KD: FULLWIDTH DIGIT THREE} {
+ unicode::normalize KD 65299
+} {51}
+
+test unicode-3.82 {normalize KD: FULLWIDTH DIGIT THREE} {
+ unicode::normalize KD 65299
+} {51}
+
+test unicode-3.83 {normalizeS KD: FULLWIDTH DIGIT THREE} {
+ unicode::normalizeS KD "\uFF13"
+} "\u0033"
+
+test unicode-3.84 {normalize KD: FULLWIDTH DIGIT THREE} {
+ unicode::normalize KD 51
+} {51}
+
+test unicode-1.85 {normalize KD: FULLWIDTH DIGIT THREE} {
+ unicode::normalize KD 51
+} {51}
+
+
+test unicode-3.86 {normalize KD: LATIN SMALL LETTER A, COMBINING CYRILLIC TITLO, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B} {
+ unicode::normalize KD {97 1155 789 768 1454 98}
+} {97 1454 1155 768 789 98}
+
+test unicode-3.87 {normalize KD: LATIN SMALL LETTER A, COMBINING CYRILLIC TITLO, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B} {
+ unicode::normalize KD {97 1454 1155 768 789 98}
+} {97 1454 1155 768 789 98}
+
+test unicode-3.88 {normalizeS KD: LATIN SMALL LETTER A, COMBINING CYRILLIC TITLO, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B} {
+ unicode::normalizeS KD "\u0061\u05AE\u0483\u0300\u0315\u0062"
+} "\u0061\u05AE\u0483\u0300\u0315\u0062"
+
+test unicode-3.89 {normalize KD: LATIN SMALL LETTER A, COMBINING CYRILLIC TITLO, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B} {
+ unicode::normalize KD {97 1454 1155 768 789 98}
+} {97 1454 1155 768 789 98}
+
+test unicode-1.90 {normalize KD: LATIN SMALL LETTER A, COMBINING CYRILLIC TITLO, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B} {
+ unicode::normalize KD {97 1454 1155 768 789 98}
+} {97 1454 1155 768 789 98}
+
+
+test unicode-3.91 {normalize KD: LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, COMBINING RING OVERLAY, LATIN SMALL LETTER B} {
+ unicode::normalize KD {97 2364 820 8408 98}
+} {97 820 8408 2364 98}
+
+test unicode-3.92 {normalize KD: LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, COMBINING RING OVERLAY, LATIN SMALL LETTER B} {
+ unicode::normalize KD {97 820 8408 2364 98}
+} {97 820 8408 2364 98}
+
+test unicode-3.93 {normalizeS KD: LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, COMBINING RING OVERLAY, LATIN SMALL LETTER B} {
+ unicode::normalizeS KD "\u0061\u0334\u20D8\u093C\u0062"
+} "\u0061\u0334\u20D8\u093C\u0062"
+
+test unicode-3.94 {normalize KD: LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, COMBINING RING OVERLAY, LATIN SMALL LETTER B} {
+ unicode::normalize KD {97 820 8408 2364 98}
+} {97 820 8408 2364 98}
+
+test unicode-1.95 {normalize KD: LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, COMBINING RING OVERLAY, LATIN SMALL LETTER B} {
+ unicode::normalize KD {97 820 8408 2364 98}
+} {97 820 8408 2364 98}
+
+
+test unicode-3.96 {normalize KD: HANGUL SYLLABLE BYO, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT} {
+ unicode::normalize KD {48484 820 4526}
+} {4359 4461 820 4526}
+
+test unicode-3.97 {normalize KD: HANGUL SYLLABLE BYO, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT} {
+ unicode::normalize KD {48484 820 4526}
+} {4359 4461 820 4526}
+
+test unicode-3.98 {normalizeS KD: HANGUL SYLLABLE BYO, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT} {
+ unicode::normalizeS KD "\u1107\u116D\u0334\u11AE"
+} "\u1107\u116D\u0334\u11AE"
+
+test unicode-3.99 {normalize KD: HANGUL SYLLABLE BYO, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT} {
+ unicode::normalize KD {48484 820 4526}
+} {4359 4461 820 4526}
+
+test unicode-1.100 {normalize KD: HANGUL SYLLABLE BYO, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT} {
+ unicode::normalize KD {4359 4461 820 4526}
+} {4359 4461 820 4526}
+
+
+test unicode-4.1 {normalize KC: LATIN CAPITAL LETTER D, COMBINING DOT ABOVE, COMBINING DOT BELOW} {
+ unicode::normalize KC {68 775 803}
+} {7692 775}
+
+test unicode-4.2 {normalize KC: LATIN CAPITAL LETTER D, COMBINING DOT ABOVE, COMBINING DOT BELOW} {
+ unicode::normalize KC {7692 775}
+} {7692 775}
+
+test unicode-4.3 {normalize KC: LATIN CAPITAL LETTER D, COMBINING DOT ABOVE, COMBINING DOT BELOW} {
+ unicode::normalize KC {68 803 775}
+} {7692 775}
+
+test unicode-4.4 {normalizeS KC: LATIN CAPITAL LETTER D, COMBINING DOT ABOVE, COMBINING DOT BELOW} {
+ unicode::normalizeS KC "\u1E0C\u0307"
+} "\u1E0C\u0307"
+
+test unicode-4.5 {normalize KC: LATIN CAPITAL LETTER D, COMBINING DOT ABOVE, COMBINING DOT BELOW} {
+ unicode::normalize KC {68 803 775}
+} {7692 775}
+
+
+test unicode-4.6 {normalize KC: NO-BREAK SPACE} {
+ unicode::normalize KC 160
+} {32}
+
+test unicode-4.7 {normalize KC: NO-BREAK SPACE} {
+ unicode::normalize KC 160
+} {32}
+
+test unicode-4.8 {normalize KC: NO-BREAK SPACE} {
+ unicode::normalize KC 160
+} {32}
+
+test unicode-4.9 {normalizeS KC: NO-BREAK SPACE} {
+ unicode::normalizeS KC "\u0020"
+} "\u0020"
+
+test unicode-4.10 {normalize KC: NO-BREAK SPACE} {
+ unicode::normalize KC 32
+} {32}
+
+
+test unicode-4.11 {normalize KC: VULGAR FRACTION ONE HALF} {
+ unicode::normalize KC 189
+} {49 8260 50}
+
+test unicode-4.12 {normalize KC: VULGAR FRACTION ONE HALF} {
+ unicode::normalize KC 189
+} {49 8260 50}
+
+test unicode-4.13 {normalize KC: VULGAR FRACTION ONE HALF} {
+ unicode::normalize KC 189
+} {49 8260 50}
+
+test unicode-4.14 {normalizeS KC: VULGAR FRACTION ONE HALF} {
+ unicode::normalizeS KC "\u0031\u2044\u0032"
+} "\u0031\u2044\u0032"
+
+test unicode-4.15 {normalize KC: VULGAR FRACTION ONE HALF} {
+ unicode::normalize KC {49 8260 50}
+} {49 8260 50}
+
+
+test unicode-4.16 {normalize KC: ORIYA LETTER RRA} {
+ unicode::normalize KC 2908
+} {2849 2876}
+
+test unicode-4.17 {normalize KC: ORIYA LETTER RRA} {
+ unicode::normalize KC {2849 2876}
+} {2849 2876}
+
+test unicode-4.18 {normalize KC: ORIYA LETTER RRA} {
+ unicode::normalize KC {2849 2876}
+} {2849 2876}
+
+test unicode-4.19 {normalizeS KC: ORIYA LETTER RRA} {
+ unicode::normalizeS KC "\u0B21\u0B3C"
+} "\u0B21\u0B3C"
+
+test unicode-4.20 {normalize KC: ORIYA LETTER RRA} {
+ unicode::normalize KC {2849 2876}
+} {2849 2876}
+
+
+test unicode-4.21 {normalize KC: KANNADA VOWEL SIGN EE} {
+ unicode::normalize KC 3271
+} {3271}
+
+test unicode-4.22 {normalize KC: KANNADA VOWEL SIGN EE} {
+ unicode::normalize KC 3271
+} {3271}
+
+test unicode-4.23 {normalize KC: KANNADA VOWEL SIGN EE} {
+ unicode::normalize KC {3270 3285}
+} {3271}
+
+test unicode-4.24 {normalizeS KC: KANNADA VOWEL SIGN EE} {
+ unicode::normalizeS KC "\u0CC7"
+} "\u0CC7"
+
+test unicode-4.25 {normalize KC: KANNADA VOWEL SIGN EE} {
+ unicode::normalize KC {3270 3285}
+} {3271}
+
+
+test unicode-4.26 {normalize KC: TIBETAN LETTER GHA} {
+ unicode::normalize KC 3907
+} {3906 4023}
+
+test unicode-4.27 {normalize KC: TIBETAN LETTER GHA} {
+ unicode::normalize KC {3906 4023}
+} {3906 4023}
+
+test unicode-4.28 {normalize KC: TIBETAN LETTER GHA} {
+ unicode::normalize KC {3906 4023}
+} {3906 4023}
+
+test unicode-4.29 {normalizeS KC: TIBETAN LETTER GHA} {
+ unicode::normalizeS KC "\u0F42\u0FB7"
+} "\u0F42\u0FB7"
+
+test unicode-4.30 {normalize KC: TIBETAN LETTER GHA} {
+ unicode::normalize KC {3906 4023}
+} {3906 4023}
+
+
+test unicode-4.31 {normalize KC: MODIFIER LETTER CAPITAL A} {
+ unicode::normalize KC 7468
+} {65}
+
+test unicode-4.32 {normalize KC: MODIFIER LETTER CAPITAL A} {
+ unicode::normalize KC 7468
+} {65}
+
+test unicode-4.33 {normalize KC: MODIFIER LETTER CAPITAL A} {
+ unicode::normalize KC 7468
+} {65}
+
+test unicode-4.34 {normalizeS KC: MODIFIER LETTER CAPITAL A} {
+ unicode::normalizeS KC "\u0041"
+} "\u0041"
+
+test unicode-4.35 {normalize KC: MODIFIER LETTER CAPITAL A} {
+ unicode::normalize KC 65
+} {65}
+
+
+test unicode-4.36 {normalize KC: GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA} {
+ unicode::normalize KC 7956
+} {7956}
+
+test unicode-4.37 {normalize KC: GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA} {
+ unicode::normalize KC 7956
+} {7956}
+
+test unicode-4.38 {normalize KC: GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA} {
+ unicode::normalize KC {949 787 769}
+} {7956}
+
+test unicode-4.39 {normalizeS KC: GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA} {
+ unicode::normalizeS KC "\u1F14"
+} "\u1F14"
+
+test unicode-4.40 {normalize KC: GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA} {
+ unicode::normalize KC {949 787 769}
+} {7956}
+
+
+test unicode-4.41 {normalize KC: KANGXI RADICAL SPROUT} {
+ unicode::normalize KC 12076
+} {23662}
+
+test unicode-4.42 {normalize KC: KANGXI RADICAL SPROUT} {
+ unicode::normalize KC 12076
+} {23662}
+
+test unicode-4.43 {normalize KC: KANGXI RADICAL SPROUT} {
+ unicode::normalize KC 12076
+} {23662}
+
+test unicode-4.44 {normalizeS KC: KANGXI RADICAL SPROUT} {
+ unicode::normalizeS KC "\u5C6E"
+} "\u5C6E"
+
+test unicode-4.45 {normalize KC: KANGXI RADICAL SPROUT} {
+ unicode::normalize KC 23662
+} {23662}
+
+
+test unicode-4.46 {normalize KC: HIRAGANA LETTER DE} {
+ unicode::normalize KC 12391
+} {12391}
+
+test unicode-4.47 {normalize KC: HIRAGANA LETTER DE} {
+ unicode::normalize KC 12391
+} {12391}
+
+test unicode-4.48 {normalize KC: HIRAGANA LETTER DE} {
+ unicode::normalize KC {12390 12441}
+} {12391}
+
+test unicode-4.49 {normalizeS KC: HIRAGANA LETTER DE} {
+ unicode::normalizeS KC "\u3067"
+} "\u3067"
+
+test unicode-4.50 {normalize KC: HIRAGANA LETTER DE} {
+ unicode::normalize KC {12390 12441}
+} {12391}
+
+
+test unicode-4.51 {normalize KC: KATAKANA LETTER PA} {
+ unicode::normalize KC 12497
+} {12497}
+
+test unicode-4.52 {normalize KC: KATAKANA LETTER PA} {
+ unicode::normalize KC 12497
+} {12497}
+
+test unicode-4.53 {normalize KC: KATAKANA LETTER PA} {
+ unicode::normalize KC {12495 12442}
+} {12497}
+
+test unicode-4.54 {normalizeS KC: KATAKANA LETTER PA} {
+ unicode::normalizeS KC "\u30D1"
+} "\u30D1"
+
+test unicode-4.55 {normalize KC: KATAKANA LETTER PA} {
+ unicode::normalize KC {12495 12442}
+} {12497}
+
+
+test unicode-4.56 {normalize KC: HANGUL LETTER SIOS-PIEUP} {
+ unicode::normalize KC 12669
+} {4402}
+
+test unicode-4.57 {normalize KC: HANGUL LETTER SIOS-PIEUP} {
+ unicode::normalize KC 12669
+} {4402}
+
+test unicode-4.58 {normalize KC: HANGUL LETTER SIOS-PIEUP} {
+ unicode::normalize KC 12669
+} {4402}
+
+test unicode-4.59 {normalizeS KC: HANGUL LETTER SIOS-PIEUP} {
+ unicode::normalizeS KC "\u1132"
+} "\u1132"
+
+test unicode-4.60 {normalize KC: HANGUL LETTER SIOS-PIEUP} {
+ unicode::normalize KC 4402
+} {4402}
+
+
+test unicode-4.61 {normalize KC: HANGUL SYLLABLE GYANG} {
+ unicode::normalize KC 44109
+} {44109}
+
+test unicode-4.62 {normalize KC: HANGUL SYLLABLE GYANG} {
+ unicode::normalize KC 44109
+} {44109}
+
+test unicode-4.63 {normalize KC: HANGUL SYLLABLE GYANG} {
+ unicode::normalize KC {4352 4451 4540}
+} {44109}
+
+test unicode-4.64 {normalizeS KC: HANGUL SYLLABLE GYANG} {
+ unicode::normalizeS KC "\uAC4D"
+} "\uAC4D"
+
+test unicode-4.65 {normalize KC: HANGUL SYLLABLE GYANG} {
+ unicode::normalize KC {4352 4451 4540}
+} {44109}
+
+
+test unicode-4.66 {normalize KC: CJK COMPATIBILITY IDEOGRAPH-F98E} {
+ unicode::normalize KC 63886
+} {24180}
+
+test unicode-4.67 {normalize KC: CJK COMPATIBILITY IDEOGRAPH-F98E} {
+ unicode::normalize KC 24180
+} {24180}
+
+test unicode-4.68 {normalize KC: CJK COMPATIBILITY IDEOGRAPH-F98E} {
+ unicode::normalize KC 24180
+} {24180}
+
+test unicode-4.69 {normalizeS KC: CJK COMPATIBILITY IDEOGRAPH-F98E} {
+ unicode::normalizeS KC "\u5E74"
+} "\u5E74"
+
+test unicode-4.70 {normalize KC: CJK COMPATIBILITY IDEOGRAPH-F98E} {
+ unicode::normalize KC 24180
+} {24180}
+
+
+test unicode-4.71 {normalize KC: ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM} {
+ unicode::normalize KC 64426
+} {1726}
+
+test unicode-4.72 {normalize KC: ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM} {
+ unicode::normalize KC 64426
+} {1726}
+
+test unicode-4.73 {normalize KC: ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM} {
+ unicode::normalize KC 64426
+} {1726}
+
+test unicode-4.74 {normalizeS KC: ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM} {
+ unicode::normalizeS KC "\u06BE"
+} "\u06BE"
+
+test unicode-4.75 {normalize KC: ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM} {
+ unicode::normalize KC 1726
+} {1726}
+
+
+test unicode-4.76 {normalize KC: ARABIC LIGATURE AIN WITH JEEM ISOLATED FORM} {
+ unicode::normalize KC 64553
+} {1593 1580}
+
+test unicode-4.77 {normalize KC: ARABIC LIGATURE AIN WITH JEEM ISOLATED FORM} {
+ unicode::normalize KC 64553
+} {1593 1580}
+
+test unicode-4.78 {normalize KC: ARABIC LIGATURE AIN WITH JEEM ISOLATED FORM} {
+ unicode::normalize KC 64553
+} {1593 1580}
+
+test unicode-4.79 {normalizeS KC: ARABIC LIGATURE AIN WITH JEEM ISOLATED FORM} {
+ unicode::normalizeS KC "\u0639\u062C"
+} "\u0639\u062C"
+
+test unicode-4.80 {normalize KC: ARABIC LIGATURE AIN WITH JEEM ISOLATED FORM} {
+ unicode::normalize KC {1593 1580}
+} {1593 1580}
+
+
+test unicode-4.81 {normalize KC: FULLWIDTH DIGIT THREE} {
+ unicode::normalize KC 65299
+} {51}
+
+test unicode-4.82 {normalize KC: FULLWIDTH DIGIT THREE} {
+ unicode::normalize KC 65299
+} {51}
+
+test unicode-4.83 {normalize KC: FULLWIDTH DIGIT THREE} {
+ unicode::normalize KC 65299
+} {51}
+
+test unicode-4.84 {normalizeS KC: FULLWIDTH DIGIT THREE} {
+ unicode::normalizeS KC "\u0033"
+} "\u0033"
+
+test unicode-4.85 {normalize KC: FULLWIDTH DIGIT THREE} {
+ unicode::normalize KC 51
+} {51}
+
+
+test unicode-4.86 {normalize KC: LATIN SMALL LETTER A, COMBINING CYRILLIC TITLO, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B} {
+ unicode::normalize KC {97 1155 789 768 1454 98}
+} {97 1454 1155 768 789 98}
+
+test unicode-4.87 {normalize KC: LATIN SMALL LETTER A, COMBINING CYRILLIC TITLO, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B} {
+ unicode::normalize KC {97 1454 1155 768 789 98}
+} {97 1454 1155 768 789 98}
+
+test unicode-4.88 {normalize KC: LATIN SMALL LETTER A, COMBINING CYRILLIC TITLO, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B} {
+ unicode::normalize KC {97 1454 1155 768 789 98}
+} {97 1454 1155 768 789 98}
+
+test unicode-4.89 {normalizeS KC: LATIN SMALL LETTER A, COMBINING CYRILLIC TITLO, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B} {
+ unicode::normalizeS KC "\u0061\u05AE\u0483\u0300\u0315\u0062"
+} "\u0061\u05AE\u0483\u0300\u0315\u0062"
+
+test unicode-4.90 {normalize KC: LATIN SMALL LETTER A, COMBINING CYRILLIC TITLO, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B} {
+ unicode::normalize KC {97 1454 1155 768 789 98}
+} {97 1454 1155 768 789 98}
+
+
+test unicode-4.91 {normalize KC: LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, COMBINING RING OVERLAY, LATIN SMALL LETTER B} {
+ unicode::normalize KC {97 2364 820 8408 98}
+} {97 820 8408 2364 98}
+
+test unicode-4.92 {normalize KC: LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, COMBINING RING OVERLAY, LATIN SMALL LETTER B} {
+ unicode::normalize KC {97 820 8408 2364 98}
+} {97 820 8408 2364 98}
+
+test unicode-4.93 {normalize KC: LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, COMBINING RING OVERLAY, LATIN SMALL LETTER B} {
+ unicode::normalize KC {97 820 8408 2364 98}
+} {97 820 8408 2364 98}
+
+test unicode-4.94 {normalizeS KC: LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, COMBINING RING OVERLAY, LATIN SMALL LETTER B} {
+ unicode::normalizeS KC "\u0061\u0334\u20D8\u093C\u0062"
+} "\u0061\u0334\u20D8\u093C\u0062"
+
+test unicode-4.95 {normalize KC: LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, COMBINING RING OVERLAY, LATIN SMALL LETTER B} {
+ unicode::normalize KC {97 820 8408 2364 98}
+} {97 820 8408 2364 98}
+
+
+test unicode-4.96 {normalize KC: HANGUL SYLLABLE BYO, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT} {
+ unicode::normalize KC {48484 820 4526}
+} {48484 820 4526}
+
+test unicode-4.97 {normalize KC: HANGUL SYLLABLE BYO, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT} {
+ unicode::normalize KC {48484 820 4526}
+} {48484 820 4526}
+
+test unicode-4.98 {normalize KC: HANGUL SYLLABLE BYO, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT} {
+ unicode::normalize KC {4359 4461 820 4526}
+} {48484 820 4526}
+
+test unicode-4.99 {normalizeS KC: HANGUL SYLLABLE BYO, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT} {
+ unicode::normalizeS KC "\uBD64\u0334\u11AE"
+} "\uBD64\u0334\u11AE"
+
+test unicode-4.100 {normalize KC: HANGUL SYLLABLE BYO, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT} {
+ unicode::normalize KC {4359 4461 820 4526}
+} {48484 820 4526}
+
+
+test unicode-5.1 {fromstring} {
+ unicode::fromstring "\u0403\u0405\u0406\u041f\u0034"
+} {1027 1029 1030 1055 52}
+
+test unicode-5.2 {fromstring} {
+ unicode::fromstring "\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u0009\u000a\u000b\u000c\u000d"
+} {1 2 3 4 5 6 7 8 9 10 11 12 13}
+
+test unicode-6.1 {tostring} {
+ unicode::tostring {16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1}
+} "\u0010\u000f\u000e\u000d\u000c\u000b\u000a\u0009\u0008\u0007\u0006\u0005\u0004\u0003\u0002\u0001"
+
+test unicode-6.2 {tostring} {
+ unicode::tostring {12345 12346 12347 12348 12349 12350 12351}
+} "\u3039\u303a\u303b\u303c\u303d\u303e\u303f"
+
+test unicode-7.1 {normalize bad form} {
+ catch {unicode::normalize S ""} result
+ set result
+} "::unicode::normalize: Only D, C, KD and KC forms are allowed"
+
+test unicode-8.1 {normalizeS bad form} {
+ catch {unicode::normalizeS S ""} result
+ set result
+} "::unicode::normalizeS: Only D, C, KD and KC forms are allowed"
+
+::tcltest::cleanupTests
+
diff --git a/tcllib/modules/stringprep/unicode_data.man b/tcllib/modules/stringprep/unicode_data.man
new file mode 100644
index 0000000..25d0efb
--- /dev/null
+++ b/tcllib/modules/stringprep/unicode_data.man
@@ -0,0 +1,21 @@
+[comment {-*- tcl -*- doctools manpage}]
+[manpage_begin unicode::data n 1.0.0]
+[keywords stringprep]
+[keywords unicode]
+[copyright {2007, Sergei Golovan <sgolovan@nes.ru>}]
+[moddesc {Preparation of Internationalized Strings}]
+[titledesc {unicode data tables, generated, internal}]
+[require Tcl 8.3]
+[require unicode::data 1.0.0]
+[description]
+[para]
+
+The [package unicode::data] package is a helper for
+[package unicode], providing it with the data tables needed to
+perform its functions. It is an [emph internal] package which should
+not be accessed on its own. Because of that it has no publicly
+documented API either. Its implementation is generated by a script.
+
+[vset CATEGORY stringprep]
+[include ../doctools2base/include/feedback.inc]
+[manpage_end]
diff --git a/tcllib/modules/stringprep/unicode_data.tcl b/tcllib/modules/stringprep/unicode_data.tcl
new file mode 100644
index 0000000..8121392
--- /dev/null
+++ b/tcllib/modules/stringprep/unicode_data.tcl
@@ -0,0 +1,1547 @@
+# unicode_data.tcl --
+#
+# Declarations of Unicode character information tables. This file is
+# automatically generated by the gen_unicode_data.tcl script. Do not
+# modify this file by hand.
+#
+# Copyright (c) 1998 Scriptics Corporation.
+# Copyright (c) 2007 Alexey Shchepin
+# Copyright (c) 2007 Sergei Golovan
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# RCS: @(#) $Id: unicode_data.tcl,v 1.1 2008/01/29 02:18:10 patthoyts Exp $
+
+#
+# A 16-bit Unicode character is split into two parts in order to index
+# into the following tables. The lower CCLASS_OFFSET_BITS comprise an offset
+# into a page of characters. The upper bits comprise the page number.
+#
+
+package provide unicode::data 1.0.0
+
+namespace eval ::unicode::data {
+
+set CCLASS_OFFSET_BITS 2
+
+#
+# The cclassPageMap is indexed by page number and returns an alternate page number
+# that identifies a unique page of characters. Many Unicode characters map
+# to the same alternate page number.
+#
+
+array unset cclassPageMap
+array set cclassPageMap [list \
+ 192 1 193 1 194 1 195 1 196 1 197 2 198 3 199 4 200 5 201 6 202 7 203 4 \
+ 204 4 205 8 206 9 207 10 208 1 209 11 210 12 211 13 212 14 213 15 214 16 \
+ 215 17 216 18 217 1 218 1 219 1 288 19 289 20 356 21 357 22 358 23 359 1 \
+ 360 24 361 4 362 22 363 25 364 26 365 27 366 28 367 29 368 30 369 31 \
+ 388 1 389 32 402 33 403 34 404 35 405 36 406 1 407 37 412 38 437 39 \
+ 438 1 439 40 440 14 441 40 442 41 443 42 452 43 460 44 461 45 462 46 \
+ 463 47 464 22 465 47 466 37 506 19 507 1 508 22 591 48 595 49 596 50 \
+ 597 51 623 48 627 49 655 48 659 49 687 48 691 49 719 48 723 49 755 49 \
+ 787 49 789 52 815 48 819 49 851 49 882 53 910 54 914 55 942 56 946 57 \
+ 966 58 973 59 974 60 988 61 989 62 990 63 991 64 992 65 993 66 1009 67 \
+ 1037 68 1038 49 1239 19 1477 69 1485 69 1524 53 1527 70 1578 71 1614 72 \
+ 1669 19 1670 73 1741 48 1745 69 1754 19 1755 10 1756 1 1904 22 1905 1 \
+ 1906 74 1919 75 2100 76 2101 1 2102 77 2103 51 2104 70 2105 78 2106 79 \
+ 2107 4 3082 80 3083 81 3110 82 10753 53 16071 83 16264 1 17027 84 17038 85 \
+ 17039 86 29785 87 29786 88 29787 89 29788 90 29790 91 29791 4 29792 92 \
+ 29793 93 29794 24 29802 39 29803 32 29840 39 29841 51]
+
+set CCLASS_COMMON_PAGE_MAP 0
+
+#
+# The cclassGroupMap is indexed by combining the alternate page number with
+# the page offset and returns a combining class number.
+#
+
+set cclassGroupMap [list \
+ 0 0 0 0 230 230 230 230 230 232 220 220 220 220 232 216 220 220 220 \
+ 220 220 202 202 220 220 220 220 202 202 220 220 220 1 1 1 1 1 220 220 \
+ 220 220 230 230 230 230 240 230 220 220 220 230 230 230 220 220 0 230 \
+ 230 230 220 220 220 220 230 232 220 220 230 233 234 234 233 234 234 \
+ 233 230 0 0 0 230 230 230 230 0 0 220 230 230 230 230 220 230 230 230 \
+ 222 220 230 230 220 220 230 222 228 230 10 11 12 13 14 15 16 17 18 \
+ 19 19 20 21 22 0 23 0 24 25 0 230 220 0 18 230 230 0 0 0 0 0 27 28 \
+ 29 30 31 32 33 34 230 230 220 220 230 220 230 230 0 35 0 0 0 0 0 230 \
+ 230 230 0 0 230 230 0 220 230 230 220 0 0 0 36 0 0 230 220 230 230 \
+ 220 230 230 220 220 220 230 220 220 230 220 230 7 0 0 0 0 9 0 0 0 230 \
+ 220 230 230 0 0 0 0 84 91 0 0 0 9 0 103 103 9 0 107 107 107 107 118 \
+ 118 0 0 122 122 122 122 220 220 0 0 0 220 0 220 0 216 0 0 0 129 130 \
+ 0 132 0 0 0 0 0 130 130 130 130 0 0 130 0 230 230 9 0 230 230 0 0 220 \
+ 0 0 0 0 7 9 0 0 0 0 230 0 0 0 228 0 0 0 222 230 220 220 0 0 0 230 230 \
+ 220 0 0 0 230 220 230 230 1 1 1 1 1 230 0 1 1 230 220 230 1 1 0 0 218 \
+ 228 232 222 224 224 0 8 8 0 0 0 26 0 0 220 0 230 230 1 220 0 0 0 0 \
+ 9 0 216 216 1 1 1 0 0 0 226 216 216 216 216 216 0 0 0 0 220 220 220 \
+ 220 0 0 230 230 230]
+
+proc GetUniCharCClass {uc} {
+ variable CCLASS_OFFSET_BITS
+ variable CCLASS_COMMON_PAGE_MAP
+ variable cclassPageMap
+ variable cclassGroupMap
+
+ set page [expr {($uc & 0x1fffff) >> $CCLASS_OFFSET_BITS}]
+ if {[info exists cclassPageMap($page)]} {
+ set apage $cclassPageMap($page)
+ } else {
+ set apage $CCLASS_COMMON_PAGE_MAP
+ }
+
+ lindex $cclassGroupMap \
+ [expr {($apage << $CCLASS_OFFSET_BITS) | \
+ ($uc & ((1 << $CCLASS_OFFSET_BITS) - 1))}]
+}
+
+
+set DECOMP_OFFSET_BITS 3
+
+#
+# The pageMap is indexed by page number and returns an alternate page number
+# that identifies a unique page of characters. Many Unicode characters map
+# to the same alternate page number.
+#
+
+array unset decompPageMap
+array set decompPageMap [list \
+ 20 1 21 2 22 3 23 4 24 5 25 6 26 7 27 8 28 9 29 10 30 11 31 12 32 13 \
+ 33 14 34 15 35 16 36 17 37 18 38 19 39 20 40 21 41 22 42 23 43 24 44 25 \
+ 45 26 46 27 47 28 52 29 53 30 54 31 56 32 57 33 58 34 59 35 60 36 61 37 \
+ 62 38 63 39 64 40 65 41 66 42 67 43 68 44 69 45 70 46 86 47 87 48 91 49 \
+ 92 50 104 51 110 52 111 53 112 54 113 55 114 56 117 57 118 58 121 59 \
+ 122 60 126 61 127 62 128 63 129 64 131 65 135 66 138 67 139 68 142 69 \
+ 152 70 154 71 155 72 156 73 157 74 158 75 159 76 176 77 196 78 206 79 \
+ 207 80 216 81 218 82 293 83 294 84 299 85 313 86 315 87 326 88 331 89 \
+ 361 90 363 91 370 92 377 93 393 94 408 95 409 96 425 97 443 98 454 99 \
+ 470 100 475 101 481 102 488 103 489 104 490 105 491 106 493 107 494 108 \
+ 495 109 496 110 498 111 499 112 500 113 501 114 503 115 516 116 543 117 \
+ 864 118 865 119 866 120 871 121 872 122 933 123 934 124 935 125 936 126 \
+ 937 127 938 128 939 129 940 130 941 131 943 132 947 133 948 134 949 135 \
+ 950 136 951 137 960 138 961 139 962 140 963 141 964 142 965 143 966 144 \
+ 967 145 968 146 969 147 970 148 971 149 972 150 973 151 974 152 975 153 \
+ 976 154 977 155 978 156 979 157 980 158 981 159 982 160 983 161 984 162 \
+ 985 163 986 164 987 165 988 166 989 167 990 168 991 169 992 170 993 171 \
+ 994 172 995 173 996 174 997 175 998 176 999 177 1000 178 1001 179 1002 180 \
+ 1003 181 1004 182 1005 183 1006 184 1007 185 1008 186 1009 187 1010 188 \
+ 1011 189 1012 190 1013 191 1014 192 1015 193 1016 194 1017 195 1018 196 \
+ 1019 197 1020 198 1021 199 1022 200 1023 201 1024 202 1025 203 1026 204 \
+ 1028 205 1029 206 1030 207 1031 208 1032 209 1033 210 1034 211 1035 206 \
+ 1038 212 1039 213 1040 214 1041 215 1042 216 1045 217 1056 218 1057 219 \
+ 1058 220 1059 221 1060 222 1061 223 1062 224 1063 225 1064 226 1065 227 \
+ 1066 228 1067 229 1068 230 1069 231 1070 232 1071 233 1075 234 1077 235 \
+ 1081 236 1088 237 1089 238 1092 239 1093 240 1094 241 1096 242 1097 243 \
+ 1100 244 1101 245 1102 246 1103 247 1104 248 1105 249 1109 250 1116 251 \
+ 1117 252 1125 253 1164 254 1165 255 1166 256 1167 257 1168 258 1169 259 \
+ 1170 260 1171 261 1172 262 1173 263 1174 264 1175 265 1176 266 1177 267 \
+ 1178 268 1179 269 1180 270 1181 271 1345 272 1358 273 1371 274 1453 275 \
+ 1491 276 1502 277 1504 278 1505 279 1506 280 1507 281 1508 282 1509 283 \
+ 1510 284 1511 285 1512 286 1513 287 1514 288 1515 289 1516 290 1517 291 \
+ 1518 292 1519 293 1520 294 1521 295 1522 296 1523 297 1524 298 1525 299 \
+ 1526 300 1527 301 1528 302 1529 303 1530 304 1536 1 1542 305 1543 306 \
+ 1545 307 1546 308 1547 309 1548 310 1549 311 1550 312 1551 313 1554 314 \
+ 1555 315 1557 316 1558 317 1559 318 1560 319 1561 320 1562 321 1563 322 \
+ 1566 323 1567 324 1574 325 1575 326 1576 327 1577 328 1578 329 1579 330 \
+ 1580 331 1581 332 1582 333 1583 334 1584 335 1585 336 1586 337 1587 338 \
+ 1600 339 1601 340 1602 341 1603 342 1604 343 1605 344 1606 345 1607 346 \
+ 1608 347 1610 348 1611 349 1612 350 1613 351 1614 352 1615 353 1616 354 \
+ 1617 355 1618 356 1619 357 1620 358 1621 359 1622 360 1623 361 1624 362 \
+ 1625 363 1626 364 1627 365 1628 366 1629 367 1630 368 1631 369 1632 370 \
+ 1633 371 1634 372 1635 373 1636 374 1637 375 1638 376 1639 377 1640 378 \
+ 1641 379 1642 380 1643 381 1644 382 1645 383 1646 384 1647 385 1648 386 \
+ 1649 387 1650 388 1651 389 1652 390 1653 391 1654 392 1655 393 1656 394 \
+ 1657 395 1658 396 1659 397 1660 398 1661 399 1662 400 1663 401 7968 402 \
+ 7969 403 7970 404 7971 405 7972 406 7973 407 7974 408 7975 409 7976 410 \
+ 7977 411 7978 412 7979 413 7980 414 7981 415 7982 416 7983 417 7984 418 \
+ 7985 419 7986 420 7987 421 7988 422 7989 423 7990 424 7991 425 7992 426 \
+ 7993 427 7994 428 7995 429 7996 430 7997 431 7998 432 7999 433 8000 434 \
+ 8001 435 8002 436 8003 437 8004 438 8005 439 8006 440 8007 441 8008 442 \
+ 8009 443 8010 444 8011 445 8012 446 8013 447 8014 448 8015 449 8016 450 \
+ 8017 451 8018 452 8019 453 8020 454 8021 455 8022 456 8023 457 8024 458 \
+ 8025 459 8026 460 8027 461 8032 462 8034 463 8035 464 8036 465 8037 466 \
+ 8038 467 8039 468 8040 469 8041 470 8042 471 8043 472 8044 473 8045 474 \
+ 8046 475 8047 476 8048 477 8049 478 8050 479 8051 480 8052 481 8053 482 \
+ 8054 483 8058 484 8059 485 8060 486 8061 487 8062 488 8063 489 8064 490 \
+ 8065 491 8066 492 8067 493 8068 494 8069 495 8070 496 8071 497 8072 498 \
+ 8073 499 8074 500 8075 501 8076 502 8077 503 8078 504 8079 505 8080 506 \
+ 8081 507 8082 508 8083 509 8084 510 8085 511 8086 512 8087 513 8088 514 \
+ 8089 515 8090 516 8091 517 8092 518 8093 519 8094 520 8095 521 8096 522 \
+ 8097 523 8098 524 8099 525 8100 526 8101 527 8102 528 8103 529 8106 530 \
+ 8107 531 8108 532 8109 533 8110 534 8111 535 8112 536 8113 537 8114 538 \
+ 8115 539 8116 540 8117 541 8118 542 8119 543 8120 544 8126 545 8127 546 \
+ 8130 547 8131 548 8134 549 8135 550 8136 551 8137 552 8138 553 8139 554 \
+ 8140 555 8141 556 8142 557 8143 558 8144 559 8145 560 8146 561 8147 562 \
+ 8148 563 8149 564 8150 565 8151 566 8152 567 8153 568 8154 569 8155 570 \
+ 8156 571 8157 572 8158 573 8159 574 8160 575 8161 576 8162 214 8163 577 \
+ 8164 578 8165 579 8166 580 8167 581 8168 582 8169 583 8170 584 8171 585 \
+ 8172 586 8173 587 8174 588 8175 589 8176 590 8177 591 8178 592 8179 593 \
+ 8180 594 8181 595 8182 596 8183 597 8184 598 8185 599 8186 600 8187 601 \
+ 8188 602 8189 603 14891 604 14892 605 14903 606 14904 607 14976 608 \
+ 14977 609 14978 610 14979 611 14980 612 14981 613 14982 614 14983 615 \
+ 14984 616 14985 617 14986 618 14987 619 14988 620 14989 608 14990 609 \
+ 14991 610 14992 611 14993 612 14994 613 14995 621 14996 622 14997 623 \
+ 14998 617 14999 624 15000 625 15001 620 15002 608 15003 609 15004 610 \
+ 15005 611 15006 612 15007 613 15008 626 15009 627 15010 628 15011 629 \
+ 15012 630 15013 619 15014 620 15015 631 15016 632 15017 633 15018 634 \
+ 15019 612 15020 613 15021 614 15022 615 15023 616 15024 617 15025 630 \
+ 15026 619 15027 620 15028 608 15029 609 15030 610 15031 611 15032 612 \
+ 15033 613 15034 614 15035 615 15036 616 15037 617 15038 630 15039 619 \
+ 15040 620 15041 608 15042 609 15043 610 15044 611 15045 612 15046 613 \
+ 15047 614 15048 615 15049 616 15050 617 15051 630 15052 619 15053 620 \
+ 15054 608 15055 609 15056 610 15057 611 15058 612 15059 613 15060 635 \
+ 15061 636 15062 637 15063 638 15064 639 15065 640 15066 641 15067 642 \
+ 15068 643 15069 644 15070 645 15071 646 15072 647 15073 648 15074 649 \
+ 15075 650 15076 651 15077 652 15078 653 15079 654 15080 655 15081 656 \
+ 15082 657 15083 658 15084 659 15085 660 15086 661 15087 662 15088 663 \
+ 15089 664 15090 636 15091 637 15092 638 15093 639 15094 640 15095 641 \
+ 15096 642 15097 665 15098 666 15099 214 15100 667 15101 668 15102 669 \
+ 15103 666 24320 670 24321 671 24322 672 24323 673 24324 674 24325 675 \
+ 24326 676 24327 677 24328 678 24329 679 24330 680 24331 681 24332 682 \
+ 24333 683 24334 684 24335 685 24336 686 24337 687 24338 688 24339 689 \
+ 24340 690 24341 691 24342 692 24343 693 24344 694 24345 695 24346 696 \
+ 24347 697 24348 698 24349 699 24350 700 24351 701 24352 702 24353 703 \
+ 24354 704 24355 705 24356 706 24357 707 24358 708 24359 709 24360 710 \
+ 24361 711 24362 712 24363 713 24364 714 24365 715 24366 716 24367 717 \
+ 24368 718 24369 719 24370 720 24371 721 24372 722 24373 723 24374 724 \
+ 24375 725 24376 726 24377 727 24378 728 24379 729 24380 730 24381 731 \
+ 24382 732 24383 733 24384 734 24385 735 24386 736 24387 737]
+
+set DECOMP_COMMON_PAGE_MAP 0
+
+#
+# The decompGroupMap is indexed by combining the alternate page number with
+# the page offset and returns a group number that identifies a length and
+# shift of decomposition sequence in decompList
+#
+
+set decompGroupMap [list \
+ -1 -1 -1 -1 -1 -1 -1 -1 196608 -1 -1 -1 -1 -1 -1 -1 327681 -1 196611 \
+ -1 -1 -1 -1 327684 -1 -1 196614 196615 327688 196618 -1 -1 327691 196621 \
+ 196622 -1 458767 458770 458773 -1 262168 262170 262172 262174 262176 \
+ 262178 -1 262180 262182 262184 262186 262188 262190 262192 262194 262196 \
+ -1 262198 262200 262202 262204 262206 262208 -1 -1 262210 262212 262214 \
+ 262216 262218 -1 -1 262220 262222 262224 262226 262228 262230 -1 262232 \
+ 262234 262236 262238 262240 262242 262244 262246 262248 -1 262250 262252 \
+ 262254 262256 262258 262260 -1 -1 262262 262264 262266 262268 262270 \
+ -1 262272 262274 262276 262278 262280 262282 262284 262286 262288 262290 \
+ 262292 262294 262296 262298 262300 262302 262304 -1 -1 262306 262308 \
+ 262310 262312 262314 262316 262318 262320 262322 262324 262326 262328 \
+ 262330 262332 262334 262336 262338 262340 262342 262344 -1 -1 262346 \
+ 262348 262350 262352 262354 262356 262358 262360 262362 -1 327900 327902 \
+ 262368 262370 262372 262374 -1 262376 262378 262380 262382 262384 262386 \
+ 327924 327926 -1 -1 262392 262394 262396 262398 262400 262402 327940 \
+ -1 -1 262406 262408 262410 262412 262414 262416 -1 -1 262418 262420 \
+ 262422 262424 262426 262428 262430 262432 262434 262436 262438 262440 \
+ 262442 262444 262446 262448 262450 262452 -1 -1 262454 262456 262458 \
+ 262460 262462 262464 262466 262468 262470 262472 262474 262476 262478 \
+ 262480 262482 262484 262486 262488 262490 262492 262494 262496 262498 \
+ 196964 262501 262503 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 262505 \
+ 262507 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 328045 328047 328049 328051 \
+ 328053 328055 328057 328059 328061 262527 262529 262531 262533 262535 \
+ 262537 262539 262541 262543 262545 262547 262549 262551 262553 262555 \
+ 262557 -1 262559 262561 262563 262565 262567 262569 -1 -1 262571 262573 \
+ 262575 262577 262579 262581 262583 262585 262587 262589 262591 328129 \
+ 328131 328133 262599 262601 -1 -1 262603 262605 262607 262609 262611 \
+ 262613 262615 262617 262619 262621 262623 262625 262627 262629 262631 \
+ 262633 262635 262637 262639 262641 262643 262645 262647 262649 262651 \
+ 262653 262655 262657 262659 262661 262663 262665 262667 262669 262671 \
+ 262673 -1 -1 262675 262677 -1 -1 -1 -1 -1 -1 262679 262681 262683 262685 \
+ 262687 262689 262691 262693 262695 262697 262699 262701 262703 262705 \
+ -1 -1 -1 -1 197171 197172 197173 197174 197175 197176 197177 197178 \
+ 197179 -1 -1 -1 -1 -1 -1 -1 328252 328254 328256 328258 328260 328262 \
+ -1 -1 197192 197193 196964 197194 197195 -1 -1 -1 131660 131661 -1 \
+ 131662 262735 -1 -1 -1 -1 -1 -1 -1 131665 -1 -1 -1 -1 -1 328274 -1 \
+ -1 -1 131668 -1 -1 -1 -1 -1 327688 262741 262743 131673 262746 262748 \
+ 262750 -1 262752 -1 262754 262756 262758 -1 -1 -1 -1 -1 -1 -1 -1 -1 \
+ 262760 262762 262764 262766 262768 262770 262772 -1 -1 -1 -1 -1 -1 \
+ -1 -1 -1 262774 262776 262778 262780 262782 -1 197248 197249 197250 \
+ 262787 262789 197255 197256 -1 197257 197258 197259 -1 197260 197261 \
+ -1 -1 -1 197262 -1 -1 -1 -1 -1 -1 262799 262801 -1 262803 -1 -1 -1 \
+ 262805 -1 -1 -1 -1 262807 262809 262811 -1 -1 262813 -1 -1 -1 -1 -1 \
+ -1 -1 262815 -1 -1 -1 -1 -1 -1 262817 262819 -1 262821 -1 -1 -1 262823 \
+ -1 -1 -1 -1 262825 262827 262829 -1 -1 -1 -1 -1 -1 -1 262831 262833 \
+ -1 262835 262837 -1 -1 -1 -1 -1 262839 262841 262843 262845 -1 -1 262847 \
+ 262849 -1 -1 262851 262853 262855 262857 262859 262861 -1 -1 262863 \
+ 262865 262867 262869 262871 262873 -1 -1 262875 262877 262879 262881 \
+ 262883 262885 262887 262889 262891 262893 262895 262897 -1 -1 262899 \
+ 262901 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 328439 -1 -1 262905 262907 \
+ 262909 262911 262913 -1 -1 -1 -1 -1 -1 328451 328453 328455 328457 \
+ -1 -1 -1 -1 -1 -1 -1 262923 -1 262925 -1 -1 -1 -1 -1 -1 -1 -1 262927 \
+ -1 -1 -1 -1 -1 262929 -1 -1 -1 -1 -1 -1 -1 262931 -1 -1 262933 -1 -1 \
+ -1 262935 262937 262939 262941 262943 262945 262947 262949 -1 -1 -1 \
+ 262951 262953 -1 -1 -1 -1 -1 -1 -1 262955 262957 -1 262959 -1 -1 -1 \
+ 262961 -1 -1 262963 -1 -1 262965 262967 262969 -1 -1 262971 -1 262973 \
+ -1 -1 262975 262977 -1 -1 -1 -1 -1 -1 -1 262979 262981 -1 -1 -1 -1 \
+ -1 -1 262983 -1 -1 -1 -1 -1 262985 262987 262989 -1 -1 -1 262991 -1 \
+ -1 -1 -1 -1 -1 -1 262993 -1 -1 -1 -1 -1 -1 262995 262997 -1 262999 \
+ 263001 -1 -1 -1 -1 -1 -1 263003 263005 263007 -1 -1 -1 -1 -1 263009 \
+ -1 263011 263013 263015 -1 -1 -1 -1 328553 -1 -1 -1 -1 -1 -1 -1 328555 \
+ -1 -1 -1 -1 -1 -1 -1 -1 328557 328559 -1 -1 -1 -1 -1 -1 197489 -1 -1 \
+ -1 -1 -1 -1 263026 -1 -1 -1 -1 -1 -1 -1 -1 -1 263028 -1 -1 -1 -1 263030 \
+ -1 -1 -1 -1 263032 -1 -1 -1 -1 263034 -1 -1 -1 -1 263036 -1 -1 -1 -1 \
+ -1 -1 -1 -1 -1 263038 -1 263040 263042 328580 263046 328584 -1 -1 -1 \
+ -1 -1 -1 -1 263050 -1 -1 -1 -1 -1 -1 -1 -1 -1 263052 -1 -1 -1 -1 -1 \
+ -1 -1 -1 -1 263054 -1 -1 -1 -1 263056 -1 -1 -1 -1 263058 -1 -1 -1 -1 \
+ 263060 -1 -1 -1 -1 263062 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 263064 \
+ -1 -1 -1 -1 -1 197530 -1 -1 -1 -1 -1 -1 -1 -1 -1 263067 -1 263069 -1 \
+ 263071 -1 263073 -1 263075 -1 -1 -1 263077 -1 -1 -1 -1 -1 -1 -1 -1 \
+ 263079 -1 263081 -1 -1 263083 263085 -1 263087 -1 -1 -1 -1 -1 -1 -1 \
+ -1 197553 197554 197555 -1 197556 197557 197558 197559 197560 197561 \
+ 197562 197563 197564 197565 197566 -1 197567 197568 197569 197570 197571 \
+ 197572 197573 196611 197574 197575 197576 197577 197578 197579 197580 \
+ 197581 197582 197583 -1 197584 197585 197586 196622 197587 197588 197589 \
+ 197590 197591 197592 197593 197594 197595 197596 197248 197597 197598 \
+ 197255 197599 197600 197174 197592 197595 197248 197597 197258 197255 \
+ 197599 -1 -1 -1 -1 -1 197601 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 197602 197603 \
+ 197604 197605 197582 197606 197607 197608 197609 197610 197611 197612 \
+ 197613 197614 197615 197616 197617 197618 197619 197620 197621 197622 \
+ 197623 197624 197625 197626 197627 197628 197629 197630 197631 197632 \
+ 197633 197634 197635 197636 197249 263173 263175 263177 263179 263181 \
+ 263183 263185 263187 263189 263191 263193 263195 263197 263199 263201 \
+ 263203 263205 263207 263209 263211 263213 263215 263217 263219 263221 \
+ 263223 263225 263227 263229 263231 263233 263235 263237 263239 263241 \
+ 263243 263245 263247 263249 263251 263253 263255 263257 263259 263261 \
+ 263263 263265 263267 263269 263271 263273 263275 263277 263279 263281 \
+ 263283 263285 263287 263289 263291 263293 263295 263297 263299 263301 \
+ 263303 263305 263307 263309 263311 263313 263315 263317 263319 263321 \
+ 263323 263325 263327 263329 263331 263333 263335 263337 263339 263341 \
+ 263343 263345 263347 263349 263351 263353 263355 263357 263359 263361 \
+ 263363 263365 263367 263369 263371 263373 263375 263377 263379 263381 \
+ 263383 263385 263387 263389 263391 263393 263395 263397 263399 263401 \
+ 263403 263405 263407 263409 263411 263413 263415 263417 263419 263421 \
+ 263423 263425 263427 263429 263431 263433 263435 263437 263439 263441 \
+ 263443 263445 263447 263449 263451 263453 263455 263457 263459 263461 \
+ 263463 263465 263467 263469 263471 263473 263475 263477 263479 329017 \
+ 263483 -1 -1 -1 -1 263485 263487 263489 263491 263493 263495 263497 \
+ 263499 263501 263503 263505 263507 263509 263511 263513 263515 263517 \
+ 263519 263521 263523 263525 263527 263529 263531 263533 263535 263537 \
+ 263539 263541 263543 263545 263547 263549 263551 263553 263555 263557 \
+ 263559 263561 263563 263565 263567 263569 263571 263573 263575 263577 \
+ 263579 263581 263583 263585 263587 263589 263591 263593 263595 263597 \
+ 263599 263601 263603 263605 263607 263609 263611 263613 263615 263617 \
+ 263619 263621 263623 263625 263627 263629 263631 263633 263635 263637 \
+ 263639 263641 263643 263645 263647 263649 263651 263653 263655 263657 \
+ 263659 263661 263663 -1 -1 -1 -1 -1 -1 263665 263667 263669 263671 \
+ 263673 263675 263677 263679 263681 263683 263685 263687 263689 263691 \
+ 263693 263695 263697 263699 263701 263703 263705 263707 -1 -1 263709 \
+ 263711 263713 263715 263717 263719 -1 -1 263721 263723 263725 263727 \
+ 263729 263731 263733 263735 263737 263739 263741 263743 263745 263747 \
+ 263749 263751 263753 263755 263757 263759 263761 263763 263765 263767 \
+ 263769 263771 263773 263775 263777 263779 263781 263783 263785 263787 \
+ 263789 263791 263793 263795 -1 -1 263797 263799 263801 263803 263805 \
+ 263807 -1 -1 263809 263811 263813 263815 263817 263819 263821 263823 \
+ -1 263825 -1 263827 -1 263829 -1 263831 263833 263835 263837 263839 \
+ 263841 263843 263845 263847 263849 263851 263853 263855 263857 263859 \
+ 263861 263863 263865 132795 263868 132798 263871 132801 263874 132804 \
+ 263877 132807 263880 132810 263883 132813 -1 -1 263886 263888 263890 \
+ 263892 263894 263896 263898 263900 263902 263904 263906 263908 263910 \
+ 263912 263914 263916 263918 263920 263922 263924 263926 263928 263930 \
+ 263932 263934 263936 263938 263940 263942 263944 263946 263948 263950 \
+ 263952 263954 263956 263958 263960 263962 263964 263966 263968 263970 \
+ 263972 263974 263976 263978 263980 263982 263984 263986 263988 263990 \
+ -1 263992 263994 263996 263998 264000 132930 264003 329541 132935 329541 \
+ 329544 264010 264012 264014 264016 -1 264018 264020 264022 132952 264025 \
+ 132955 264028 264030 264032 264034 264036 264038 264040 132970 -1 -1 \
+ 264043 264045 264047 264049 264051 132981 -1 264054 264056 264058 264060 \
+ 264062 264064 132994 264067 264069 264071 264073 264075 264077 264079 \
+ 133009 264082 264084 133014 133015 -1 -1 264088 264090 264092 -1 264094 \
+ 264096 264098 133028 264101 133031 264104 133034 329643 -1 133037 133038 \
+ 196608 196608 196608 196608 196608 196608 196608 196608 196608 -1 -1 \
+ -1 -1 -1 -1 198575 -1 -1 -1 -1 -1 329648 -1 -1 -1 -1 198578 329651 \
+ 460725 -1 -1 -1 -1 -1 -1 -1 -1 196608 -1 -1 -1 329656 460730 -1 329661 \
+ 460735 -1 -1 -1 -1 329666 -1 329668 -1 -1 -1 -1 -1 -1 -1 -1 329670 \
+ 329672 329674 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 591820 198608 \
+ 197600 -1 -1 198609 198610 198611 198612 198613 198614 198615 198616 \
+ 198617 198618 198619 198620 198608 196621 196614 196615 198609 198610 \
+ 198611 198612 198613 198614 198615 198616 198617 198618 198619 -1 196611 \
+ 197579 196622 197194 197580 -1 -1 -1 329693 -1 -1 -1 -1 -1 -1 -1 460767 \
+ 460770 198629 329702 -1 460776 460779 198638 -1 329711 197583 197560 \
+ 197560 197560 197171 198641 197561 197561 197564 197193 -1 197566 329714 \
+ -1 -1 197569 198644 197570 197570 197570 -1 -1 329717 460791 329722 \
+ -1 198652 -1 133117 -1 198652 -1 132027 133118 197555 198629 -1 197579 \
+ 197557 198655 -1 197565 196622 198656 198657 198658 198659 197600 -1 \
+ 460804 197256 197597 198663 198664 198665 -1 -1 -1 -1 197556 197578 \
+ 197579 197600 197173 -1 -1 -1 -1 -1 -1 -1 -1 -1 460810 460813 460816 \
+ 460819 460822 460825 460828 460831 460834 460837 460840 460843 329774 \
+ 197561 329776 460850 329781 198711 329784 460858 591933 329793 198723 \
+ 329796 460870 197564 198629 197556 197565 197600 329801 460875 329806 \
+ 197595 329808 460882 591957 329817 197194 329819 460893 197193 197603 \
+ 197578 197585 -1 -1 264288 264290 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 264292 \
+ -1 -1 -1 -1 -1 -1 264294 264296 264298 -1 -1 -1 -1 264300 -1 -1 -1 \
+ -1 264302 -1 -1 264304 -1 -1 -1 -1 -1 -1 -1 264306 -1 264308 -1 -1 \
+ -1 -1 -1 329846 460920 -1 329851 460925 -1 -1 -1 -1 -1 -1 -1 -1 264320 \
+ -1 -1 264322 -1 -1 264324 -1 264326 -1 -1 -1 -1 -1 -1 264328 -1 264330 \
+ -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 264332 264334 264336 264338 264340 -1 \
+ -1 264342 264344 -1 -1 264346 264348 -1 -1 -1 -1 -1 -1 264350 264352 \
+ -1 -1 264354 264356 -1 -1 264358 264360 -1 -1 -1 -1 -1 -1 -1 -1 -1 \
+ -1 264362 264364 264366 264368 264370 264372 264374 264376 -1 -1 -1 \
+ -1 -1 -1 264378 264380 264382 264384 -1 -1 -1 133314 133315 -1 -1 -1 \
+ -1 -1 196621 196614 196615 198609 198610 198611 198612 198613 198614 \
+ 329924 329926 329928 329930 329932 329934 329936 329938 329940 329942 \
+ 329944 461018 461021 461024 461027 461030 461033 461036 461039 461042 \
+ 592117 592121 592125 592129 592133 592137 592141 592145 592149 592153 \
+ 592157 330017 330019 330021 330023 330025 330027 330029 330031 330033 \
+ 461107 461110 461113 461116 461119 461122 461125 461128 461131 461134 \
+ 461137 461140 461143 461146 461149 461152 461155 461158 461161 461164 \
+ 461167 461170 461173 461176 461179 461182 461185 461188 461191 461194 \
+ 461197 461200 461203 461206 461209 461212 461215 197553 197555 198629 \
+ 197556 197557 198655 197559 197560 197561 197562 197563 197564 197565 \
+ 197566 197567 197569 198644 197570 199074 197571 197572 198711 197573 \
+ 198723 199075 198652 196611 197577 197603 197578 197579 197606 197583 \
+ 197171 197600 197173 197584 197193 197585 198620 196622 197590 199076 \
+ 197174 196964 197591 197592 197595 197178 197194 197179 197633 198608 \
+ -1 -1 -1 -1 -1 -1 -1 -1 -1 592293 -1 -1 -1 -1 -1 -1 -1 461225 330156 \
+ 461230 -1 -1 -1 -1 -1 264625 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 199091 -1 \
+ -1 -1 -1 -1 -1 -1 199092 -1 -1 -1 199093 -1 -1 -1 -1 199094 199095 \
+ 199096 199097 199098 199099 199100 199101 199102 199103 199104 199105 \
+ 199106 199107 199108 199109 199110 199111 199112 199113 199114 199115 \
+ 199116 199117 199118 199119 199120 199121 199122 199123 199124 199125 \
+ 199126 199127 199128 199129 199130 199131 199132 199133 199134 199135 \
+ 199136 199137 199138 199139 199140 199141 199142 199143 199144 199145 \
+ 199146 199147 199148 199149 199150 199151 199152 199153 199154 199155 \
+ 199156 199157 199158 199159 199160 199161 199162 199163 199164 199165 \
+ 199166 199167 199168 199169 199170 199171 199172 199173 199174 199175 \
+ 199176 199177 199178 199179 199180 199181 199182 199183 199184 199185 \
+ 199186 199187 199188 199189 199190 199191 199192 199193 199194 199195 \
+ 199196 199197 199198 199199 199200 199201 199202 199203 199204 199205 \
+ 199206 199207 199208 199209 199210 199211 199212 199213 199214 199215 \
+ 199216 199217 199218 199219 199220 199221 199222 199223 199224 199225 \
+ 199226 199227 199228 199229 199230 199231 199232 199233 199234 199235 \
+ 199236 199237 199238 199239 199240 199241 199242 199243 199244 199245 \
+ 199246 199247 199248 199249 199250 199251 199252 199253 199254 199255 \
+ 199256 199257 199258 199259 199260 199261 199262 199263 199264 199265 \
+ 199266 199267 199268 199269 199270 199271 199272 199273 199274 199275 \
+ 199276 199277 199278 199279 199280 199281 199282 199283 199284 199285 \
+ 199286 199287 199288 199289 199290 199291 199292 199293 199294 199295 \
+ 199296 199297 199298 199299 199300 199301 199302 199303 199304 199305 \
+ 199306 199307 -1 -1 -1 -1 -1 -1 -1 -1 199308 -1 199117 199309 199310 \
+ -1 -1 -1 -1 -1 -1 -1 -1 -1 264847 -1 264849 -1 264851 -1 264853 -1 \
+ 264855 -1 264857 -1 264859 -1 264861 -1 264863 -1 264865 -1 264867 \
+ -1 264869 -1 -1 264871 -1 264873 -1 264875 -1 -1 -1 -1 -1 -1 264877 \
+ 264879 -1 264881 264883 -1 264885 264887 -1 264889 264891 -1 264893 \
+ 264895 -1 -1 -1 -1 -1 -1 264897 -1 -1 -1 -1 -1 -1 330435 330437 -1 \
+ 264903 330441 -1 -1 -1 -1 264907 -1 264909 -1 264911 -1 264913 -1 264915 \
+ -1 264917 -1 264919 -1 264921 -1 264923 -1 264925 -1 264927 -1 264929 \
+ -1 -1 264931 -1 264933 -1 264935 -1 -1 -1 -1 -1 -1 264937 264939 -1 \
+ 264941 264943 -1 264945 264947 -1 264949 264951 -1 264953 264955 -1 \
+ -1 -1 -1 -1 -1 264957 -1 -1 264959 264961 264963 264965 -1 -1 -1 264967 \
+ 330505 -1 199435 199436 199437 199438 199439 199440 199441 199442 199443 \
+ 199444 199445 199446 199447 199448 199449 199450 199451 199452 199453 \
+ 199454 199455 199456 199457 199458 199459 199460 199461 199462 199463 \
+ 199464 199465 199466 199467 199468 199469 199470 199471 199472 199473 \
+ 199474 199475 199476 199477 199478 199479 199480 199481 199482 199483 \
+ 199484 199485 199486 199487 199488 199489 199490 199491 199492 199493 \
+ 199494 199495 199496 199497 199498 199499 199500 199501 199502 199503 \
+ 199504 199505 199506 199507 199508 199509 199510 199511 199512 199513 \
+ 199514 199515 199516 199517 199518 199519 199520 199521 199522 199523 \
+ 199524 199525 199526 199527 199528 -1 -1 -1 199094 199100 199529 199530 \
+ 199531 199532 199533 199534 199098 199535 199536 199537 199538 199102 \
+ 461683 461686 461689 461692 461695 461698 461701 461704 461707 461710 \
+ 461713 461716 461719 461722 592797 592801 592805 592809 592813 592817 \
+ 592821 592825 592829 592833 592837 592841 592845 592849 592853 986073 \
+ 855008 -1 461798 461801 461804 461807 461810 461813 461816 461819 461822 \
+ 461825 461828 461831 461834 461837 461840 461843 461846 461849 461852 \
+ 461855 461858 461861 461864 461867 461870 461873 461876 461879 461882 \
+ 461885 461888 461891 461894 461897 461900 461903 -1 -1 -1 -1 461906 \
+ 330837 330839 330841 330843 330845 330847 330849 330851 330853 330855 \
+ 330857 330859 330861 330863 330865 199435 199438 199441 199443 199451 \
+ 199452 199455 199457 199458 199460 199461 199462 199463 199464 330867 \
+ 330869 330871 330873 330875 330877 330879 330881 330883 330885 330887 \
+ 330889 330891 330893 724111 593044 330904 -1 199094 199100 199529 199530 \
+ 199834 199835 199836 199105 199837 199117 199167 199179 199178 199168 \
+ 199260 199125 199165 199838 199839 199840 199841 199842 199843 199844 \
+ 199845 199846 199847 199131 199848 199849 199850 199851 199852 199853 \
+ 199854 199855 199531 199532 199533 199856 199857 199858 199859 199860 \
+ 199861 199862 199863 199864 199865 330938 330940 330942 330944 330946 \
+ 330948 330950 330952 330954 330956 330958 330960 330962 330964 330966 \
+ 330968 330970 330972 330974 330976 330978 330980 330982 330984 462058 \
+ 462061 462064 330995 462069 331000 462074 199933 199934 199935 199936 \
+ 199937 199938 199939 199940 199941 199942 199943 199944 199945 199946 \
+ 199947 199948 199949 199950 199951 199952 199953 199954 199955 199956 \
+ 199957 199958 199959 199960 199961 199962 199963 199964 199965 199966 \
+ 199967 199968 199969 199970 199971 199972 199973 199974 199975 199976 \
+ 199977 199978 199979 -1 593196 593200 593204 462136 593211 462143 462146 \
+ 724293 593226 462158 462161 462164 593239 593243 462175 462178 331109 \
+ 462183 593258 593262 331122 724340 855417 724351 462212 724359 724364 \
+ 593297 462229 462232 462235 593310 724386 593319 462251 462254 462257 \
+ 331188 331190 331192 331194 462268 462271 724418 462279 593354 724430 \
+ 462291 331222 331224 724442 593375 724451 462312 724459 331248 462322 \
+ 462325 462328 462331 462334 593409 462341 331272 462346 462349 462352 \
+ 593427 462359 462362 462365 724512 593445 331305 724523 331312 593458 \
+ 593462 462394 462397 462400 593475 331335 462409 593484 331344 724562 \
+ 462423 331354 331356 331358 331360 331362 331364 331366 331368 331370 \
+ 331372 462446 462449 462452 462455 462458 462461 462464 462467 462470 \
+ 462473 462476 462479 462482 462485 462488 462491 331422 331424 462498 \
+ 331429 331431 331433 462507 462510 331441 331443 331445 331447 331449 \
+ 593595 331455 331457 331459 331461 331463 331465 331467 331469 462543 \
+ 593618 331478 331480 331482 331484 331486 331488 331490 462564 462567 \
+ 462570 462573 331504 331506 331508 331510 331512 331514 331516 331518 \
+ 331520 331522 462596 462599 331530 462604 462607 462610 331541 462615 \
+ 462618 593693 331553 462627 462630 462633 462636 724783 855860 331578 \
+ 331580 331582 331584 331586 331588 331590 331592 331594 331596 331598 \
+ 331600 331602 331604 331606 331608 331610 331612 593758 331618 331620 \
+ 331622 593768 462700 331631 331633 331635 331637 331639 331641 331643 \
+ 331645 331647 331649 462723 331654 331656 462730 462733 331664 593810 \
+ 462742 331673 331675 331677 331679 462753 462756 331687 331689 331691 \
+ 331693 331695 331697 331699 331701 331703 462777 462780 462783 462786 \
+ 462789 462792 462795 462798 462801 462804 462807 462810 462813 462816 \
+ 462819 462822 462825 462828 462831 462834 462837 462840 462843 135166 \
+ 135167 133716 135168 135169 135170 135171 133770 133770 135172 133724 \
+ 135173 135174 135175 135176 135177 135178 135179 135180 135181 135182 \
+ 135183 135184 135185 135186 135187 135188 135189 135190 135191 135192 \
+ 135193 135194 135195 135196 135197 135198 135199 135200 135201 135202 \
+ 135203 135204 135205 135206 135207 135208 135209 135210 135211 135212 \
+ 135213 133682 135214 135215 135216 135217 135218 135219 135220 135221 \
+ 135222 135223 135224 133755 135225 135226 135227 135228 135229 135230 \
+ 135231 135232 135233 135234 135235 135236 135237 135238 135239 135240 \
+ 135241 135242 135243 135244 135245 135246 135247 135248 135249 135250 \
+ 135251 135182 135252 135253 135254 135255 135256 135257 135258 135259 \
+ 135260 135261 135262 135263 135264 135265 135266 135267 135268 135269 \
+ 135270 135271 133718 135272 135273 135274 135275 135276 135277 135278 \
+ 135279 135280 135281 135282 135283 135284 135285 135286 133595 135287 \
+ 135288 135289 135290 135291 135292 135293 135294 133576 135295 135296 \
+ 135297 135298 135299 135300 135301 135302 135303 135304 135305 135306 \
+ 135307 135308 135309 135310 135311 135312 135313 135314 135315 135316 \
+ 135270 135317 135318 135319 135320 135321 135322 135323 135324 135254 \
+ 135325 135326 135327 135328 135329 135330 135331 135332 135333 135334 \
+ 135335 135336 135337 135338 135339 135340 135341 135342 135343 135344 \
+ 135182 135345 135346 135347 135348 133769 135349 135350 135351 135352 \
+ 135353 135354 135355 135356 135357 135358 135359 135360 134299 135361 \
+ 135362 135363 135364 135365 135366 135367 135368 135369 135256 135370 \
+ 135371 135372 135373 135374 135375 135376 135377 135378 135379 135380 \
+ 135381 135382 133723 135383 135384 135385 135386 135387 135388 135389 \
+ 135390 135391 135392 135393 135394 135395 133674 135396 135397 135398 \
+ 135399 135400 135401 135402 135403 135404 135405 135406 135407 135408 \
+ 135409 135410 135411 133701 135412 133704 135413 135414 135415 -1 -1 \
+ 135416 -1 135417 -1 -1 135418 135419 135420 135421 135422 135423 135424 \
+ 135425 135426 133681 -1 135427 -1 135428 -1 -1 135429 135430 -1 -1 \
+ -1 135431 135432 135433 135434 -1 -1 135435 135436 135437 135438 135439 \
+ 135440 135441 135442 135443 135444 135445 135446 133602 135447 135448 \
+ 135449 135450 135451 135452 135453 135454 135455 135456 135457 135458 \
+ 135459 135460 135461 134304 135462 135463 135464 135465 134308 135466 \
+ 135467 135468 135469 135470 135306 135471 135472 135473 135474 135475 \
+ 135476 135476 135477 135478 135479 135480 135481 135482 135483 135484 \
+ 135429 135485 135486 135487 -1 -1 -1 -1 -1 135488 135489 135490 135491 \
+ 135492 135493 135494 135495 135441 135496 135497 135498 135416 135499 \
+ 135500 135501 135502 135503 135504 135505 135506 135507 135508 135509 \
+ 135510 135449 135511 135450 135512 135513 135514 135515 135516 135417 \
+ 135203 135517 135518 133635 135271 135354 135519 135520 135457 135521 \
+ 135458 135522 135523 135524 135419 135525 135526 135527 135528 135529 \
+ 135420 135530 135531 135532 135533 135534 135535 135470 135536 135537 \
+ 135306 135538 135474 135539 135540 135541 135542 135543 135479 135544 \
+ 135428 135545 135480 135252 135546 135481 135547 135483 135548 135549 \
+ 135550 135551 135552 135485 135425 135553 135486 135554 135487 135555 \
+ 133770 135556 135557 135558 135559 135560 135561 135562 135563 135564 \
+ 135565 135566 -1 -1 -1 -1 -1 -1 332175 332177 332179 463253 463256 \
+ 332187 332189 -1 -1 -1 -1 332191 332193 332195 332197 332199 -1 -1 \
+ -1 -1 -1 266665 -1 266667 201133 198656 198659 201134 201135 201136 \
+ 201137 201138 201139 198615 266676 266678 266680 266682 266684 266686 \
+ 266688 266690 266692 266694 266696 266698 266700 -1 266702 266704 266706 \
+ 266708 266710 -1 266712 -1 266714 266716 -1 266718 266720 -1 266722 \
+ 266724 266726 266728 266730 266732 266734 266736 266738 332276 201206 \
+ 201206 201207 201207 201207 201207 201208 201208 201208 201208 201209 \
+ 201209 201209 201209 201210 201210 201210 201210 201211 201211 201211 \
+ 201211 201212 201212 201212 201212 201213 201213 201213 201213 201214 \
+ 201214 201214 201214 201215 201215 201215 201215 201216 201216 201216 \
+ 201216 201217 201217 201217 201217 201218 201218 201218 201218 201219 \
+ 201219 201220 201220 201221 201221 201222 201222 201223 201223 201224 \
+ 201224 201225 201225 201225 201225 201226 201226 201226 201226 201227 \
+ 201227 201227 201227 201228 201228 201228 201228 201229 201229 201230 \
+ 201230 201230 201230 201231 201231 201232 201232 201232 201232 201233 \
+ 201233 201233 201233 201234 201234 201235 201235 -1 -1 -1 -1 -1 -1 \
+ -1 -1 -1 201236 201236 201236 201236 201237 201237 201238 201238 201239 \
+ 201239 201240 201241 201241 201242 201242 201243 201243 201244 201244 \
+ 201244 201244 201245 201245 332318 332318 332320 332320 332322 332322 \
+ 332324 332324 332326 332326 332328 332328 332330 332330 332330 332332 \
+ 332332 332332 201262 201262 201262 201262 332335 332337 332339 332332 \
+ 332341 332343 332345 332347 332349 332351 332353 332355 332357 332359 \
+ 332361 332363 332365 332367 332369 332371 332373 332375 332377 332379 \
+ 332381 332383 332385 332387 332389 332391 332393 332395 332397 332399 \
+ 332401 332403 332405 332407 332409 332411 332413 332415 332417 332419 \
+ 332421 332423 332425 332427 332429 332431 332433 332435 332437 332439 \
+ 332441 332443 332445 332447 332449 332451 332453 332455 332457 332459 \
+ 332461 332463 332465 332467 332469 332471 332473 332475 332477 332479 \
+ 332481 332483 332485 332487 332489 332491 332493 332495 332497 332499 \
+ 332501 332503 332505 332507 332509 332511 332513 332515 332517 332519 \
+ 463593 463596 463599 463602 463605 463608 332539 332541 332339 332543 \
+ 332332 332341 332545 332547 332349 332549 332351 332353 332551 332553 \
+ 332361 332555 332363 332365 332557 332559 332369 332561 332371 332373 \
+ 332431 332433 332439 332441 332443 332451 332453 332455 332457 332465 \
+ 332467 332469 332563 332477 332565 332567 332489 332569 332491 332493 \
+ 332519 332571 332573 332509 332575 332511 332513 332335 332337 332577 \
+ 332339 332579 332343 332345 332347 332349 332581 332355 332357 332359 \
+ 332361 332583 332369 332375 332377 332379 332381 332383 332387 332389 \
+ 332391 332393 332395 332397 332585 332399 332401 332403 332405 332407 \
+ 332409 332413 332415 332417 332419 332421 332423 332425 332427 332429 \
+ 332435 332437 332445 332447 332449 332451 332453 332459 332461 332463 \
+ 332465 332587 332471 332473 332475 332477 332483 332485 332487 332489 \
+ 332589 332495 332497 332591 332503 332505 332507 332509 332593 332339 \
+ 332579 332349 332581 332361 332583 332369 332595 332395 332597 332599 \
+ 332601 332451 332453 332465 332489 332589 332509 332593 463675 463678 \
+ 463681 332612 332614 332616 332618 332620 332622 332624 332626 332628 \
+ 332630 332632 332634 332636 332638 332640 332642 332644 332646 332648 \
+ 332650 332652 332654 332656 332599 332658 332660 332662 332664 332612 \
+ 332614 332616 332618 332620 332622 332624 332626 332628 332630 332632 \
+ 332634 332636 332638 332640 332642 332644 332646 332648 332650 332652 \
+ 332654 332656 332599 332658 332660 332662 332664 332652 332654 332656 \
+ 332599 332597 332601 332411 332389 332391 332393 332652 332654 332656 \
+ 332411 332413 332666 332666 -1 -1 463740 463743 463743 463746 463749 \
+ 463752 463755 463758 463761 463761 463764 463767 463770 463773 463776 \
+ 463779 463779 463782 463785 463785 463788 463788 463791 463794 463794 \
+ 463797 463800 463800 463803 463803 463806 463809 463809 463812 463812 \
+ 463815 463818 463821 463824 463824 463827 463830 463833 463836 463839 \
+ 463839 463842 463845 463848 463851 463854 463857 463857 463860 463860 \
+ 463863 463863 463866 463869 463872 463875 463878 463881 463884 -1 -1 \
+ 463887 463890 463893 463896 463899 463902 463902 463905 463908 463911 \
+ 463914 463914 463917 463920 463923 463926 463929 463932 463935 463938 \
+ 463941 463944 463947 463950 463953 463956 463959 463962 463965 463968 \
+ 463971 463974 463977 463980 463842 463848 463983 463986 463989 463992 \
+ 463995 463998 463995 463989 464001 464004 464007 464010 464013 463998 \
+ 463821 463791 464016 464019 464022 464025 595100 595104 595108 595112 \
+ 595116 595120 595124 464056 2430139 1119437 595157 -1 -1 -1 201945 \
+ 201946 201947 201948 197204 201949 201950 201951 201952 201953 -1 -1 \
+ -1 -1 -1 -1 201954 201955 201956 201957 201957 198618 198619 201958 \
+ 201959 201960 201961 201962 201963 201964 201965 198850 198851 201966 \
+ 201967 201968 201969 -1 -1 201970 201971 201972 201972 201972 201972 \
+ 201957 201957 201957 201945 201946 198578 -1 197204 201948 201950 201949 \
+ 201955 198618 198619 201958 201959 201960 201961 201973 201974 201975 \
+ 198615 201976 201977 201978 198617 -1 201979 201980 201981 201982 -1 \
+ -1 -1 -1 333055 333057 333059 -1 333061 -1 333063 333065 333067 333069 \
+ 333071 333073 333075 333077 333079 333081 202011 202012 202012 202013 \
+ 202013 202014 202014 202015 202015 202016 202016 202016 202016 202017 \
+ 202017 202018 202018 202018 202018 202019 202019 202020 202020 202020 \
+ 202020 202021 202021 202021 202021 202022 202022 202022 202022 202023 \
+ 202023 202023 202023 202024 202024 202024 202024 202025 202025 202026 \
+ 202026 202027 202027 202028 202028 202029 202029 202029 202029 202030 \
+ 202030 202030 202030 202031 202031 202031 202031 202032 202032 202032 \
+ 202032 202033 202033 202033 202033 202034 202034 202034 202034 202035 \
+ 202035 202035 202035 202036 202036 202036 202036 202037 202037 202037 \
+ 202037 202038 202038 202038 202038 202039 202039 202039 202039 202040 \
+ 202040 202040 202040 202041 202041 202041 202041 202042 202042 202042 \
+ 202042 202043 202043 202043 202043 202044 202044 201245 201245 202045 \
+ 202045 202045 202045 333118 333118 333120 333120 333122 333122 333124 \
+ 333124 -1 -1 -1 -1 201949 202054 201973 201980 201981 201974 202055 \
+ 198618 198619 201975 198615 201945 201976 198578 202056 198613 198614 \
+ 201948 197204 201977 198617 201978 201950 201982 197553 197555 198629 \
+ 197556 197557 198655 197559 197560 197561 197562 197563 197564 197565 \
+ 197566 197567 197569 198644 197570 199074 197571 197572 198711 197573 \
+ 198723 199075 198652 201970 201979 201971 202057 201957 198551 196611 \
+ 197577 197603 197578 197579 197606 197583 197171 197600 197173 197584 \
+ 197193 197585 198620 196622 197590 199076 197174 196964 197591 197592 \
+ 197595 197178 197194 197179 197633 201958 202058 201959 202059 202060 \
+ 202061 201947 201966 201967 201946 202062 199979 202063 202064 202065 \
+ 202066 202067 202068 202069 202070 202071 202072 199933 199934 199935 \
+ 199936 199937 199938 199939 199940 199941 199942 199943 199944 199945 \
+ 199946 199947 199948 199949 199950 199951 199952 199953 199954 199955 \
+ 199956 199957 199958 199959 199960 199961 199962 199963 199964 199965 \
+ 199966 199967 199968 199969 199970 199971 199972 199973 199974 199975 \
+ 199976 202073 202074 202075 202076 202077 202078 202079 202080 202081 \
+ 202082 202083 202084 202085 202086 202087 202088 202089 202090 202091 \
+ 202092 202093 202094 202095 202096 202097 202098 202099 202100 202101 \
+ 202102 202103 202104 202105 202106 -1 -1 -1 202107 202108 202109 202110 \
+ 202111 202112 -1 -1 202113 202114 202115 202116 202117 202118 -1 -1 \
+ 202119 202120 202121 202122 202123 202124 -1 -1 202125 202126 202127 \
+ -1 -1 -1 202128 202129 202130 202131 202132 202133 202134 -1 202135 \
+ 202136 202137 202138 202139 202140 202141 -1 -1 -1 -1 -1 -1 -1 267678 \
+ 267680 267682 267684 267686 267688 267690 -1 -1 -1 -1 -1 -1 267692 \
+ 267694 267696 267698 267700 267702 -1 -1 -1 -1 -1 -1 -1 197553 197555 \
+ 198629 197556 197557 198655 197559 197560 197561 197562 197563 197564 \
+ 197565 197566 197567 197569 198644 197570 199074 197571 197572 198711 \
+ 197573 198723 199075 198652 196611 197577 197603 197578 197579 197606 \
+ 197583 197171 197600 197173 197584 197193 197585 198620 196622 197590 \
+ 199076 197174 196964 197591 197592 197595 197178 197194 197179 197633 \
+ 197553 197555 198629 197556 197557 198655 197559 197560 197561 197562 \
+ 197563 197564 197565 197566 197567 197569 198644 197570 199074 197571 \
+ 197572 198711 197573 198723 199075 198652 196611 197577 197603 197578 \
+ 197579 197606 197583 -1 197600 197173 197584 197193 197585 198620 196622 \
+ 197590 199076 197174 196964 197591 197592 197595 197178 197194 197179 \
+ 197633 197178 197194 197179 197633 197553 -1 198629 197556 -1 -1 197559 \
+ -1 -1 197562 197563 -1 -1 197566 197567 197569 198644 -1 199074 197571 \
+ 197603 197578 -1 197606 -1 197171 197600 197173 197584 197193 197585 \
+ 198620 -1 197590 199076 197174 197178 197194 197179 197633 197553 197555 \
+ -1 197556 197557 198655 197559 -1 -1 197562 197563 197564 197565 197566 \
+ 197567 197569 198644 -1 199074 197571 197572 198711 197573 198723 199075 \
+ -1 196611 197577 197603 197578 197579 197606 197583 197171 197600 197173 \
+ 197553 197555 -1 197556 197557 198655 197559 -1 197561 197562 197563 \
+ 197564 197565 -1 197567 -1 -1 -1 199074 197571 197572 198711 197573 \
+ 198723 199075 -1 196611 197577 197603 197578 197579 197606 197178 197194 \
+ 197179 197633 202168 202169 -1 -1 202170 202171 198663 202172 202173 \
+ 202174 202175 197260 202176 202177 202178 202179 202180 202181 202182 \
+ 198664 202183 202184 197262 202185 197250 202186 202187 202188 198653 \
+ 202189 202190 197248 197597 197598 197261 202191 202192 197249 198471 \
+ 197257 202193 196618 202194 202195 202196 197256 197258 197259 202197 \
+ 202198 202199 197255 197599 202200 202201 202202 202203 202204 202205 \
+ 202206 202207 202208 202170 202171 198663 202172 202173 202174 202175 \
+ 197260 202176 202177 202178 202179 202180 202181 202182 198664 202183 \
+ 202184 197262 202185 197250 202186 202187 202188 198653 202189 202190 \
+ 197248 197597 197598 197261 202191 202192 197249 198471 197257 202193 \
+ 196618 202194 202195 202196 197256 197258 197259 202197 202198 202199 \
+ 197255 197599 202200 202201 202202 202203 202204 202205 202206 202207 \
+ 202208 202170 202171 198663 202172 202173 202174 202175 197260 202176 \
+ 202177 202178 202179 202180 202181 202182 198664 202183 202184 197262 \
+ 202185 197250 202186 202187 202188 198653 202189 202190 197248 197597 \
+ 197598 197261 202191 202192 197249 198471 197257 202193 196618 202194 \
+ 202195 202196 197256 197258 197259 202197 202198 202199 197255 197599 \
+ 202200 202201 202202 202203 202204 202205 202206 202207 202208 202170 \
+ 202171 198663 202172 202173 202174 202175 197260 202176 202177 202178 \
+ 202179 202180 202181 202182 198664 202183 202184 197262 202185 197250 \
+ 202186 202187 202188 198653 202189 202190 197248 197597 197598 197261 \
+ 202191 202192 197249 198471 197257 202193 196618 202194 202195 202196 \
+ 197256 197258 197259 202197 202198 202199 197255 197599 202200 202201 \
+ 202202 202203 202204 202205 202206 202207 202208 202207 202208 202209 \
+ 202210 -1 -1 198608 196621 196614 196615 198609 198610 198611 198612 \
+ 198613 198614 198613 198614 198608 196621 196614 196615 198609 198610 \
+ 198611 198612 198613 198614 198608 196621 196614 196615 198609 198610 \
+ 198611 198612 198613 198614 198608 196621 136675 136676 136677 136678 \
+ 136679 135435 136680 136681 136682 136683 135436 136684 136685 136686 \
+ 135437 136687 136688 136689 136690 136691 136692 136693 136694 136695 \
+ 136696 136697 136698 135489 136699 133574 136700 136701 136702 136703 \
+ 136704 136705 136706 135494 135438 135439 135495 136707 136708 135258 \
+ 136709 135440 136710 136711 136712 136713 136713 136713 136714 136715 \
+ 136716 136717 136718 136719 136720 136721 136722 136723 136724 136725 \
+ 136726 136727 136728 136729 136730 136731 136731 135497 136732 136733 \
+ 136734 136735 135442 136736 136737 136738 135404 136739 136740 136741 \
+ 136742 136743 136744 136745 136746 136747 136748 136749 136750 136751 \
+ 136752 136753 136754 136755 136756 136757 136758 136759 136760 136761 \
+ 136762 136763 136764 136764 136765 136766 136767 135254 136768 136769 \
+ 136770 136771 136772 133600 136773 136774 133602 136775 136776 136777 \
+ 136778 136779 136780 136781 136782 136783 136784 136785 136786 136787 \
+ 136788 136789 136790 136791 136792 136793 136794 136795 135202 136796 \
+ 133612 136797 136797 136798 136799 136799 136800 136801 136802 136803 \
+ 136804 136805 136806 136807 136808 136809 136810 136811 136812 135447 \
+ 136813 136814 136815 136816 135509 136816 136817 135449 136818 136819 \
+ 136820 136821 135450 135175 136822 136823 136824 136825 136826 136827 \
+ 136828 136829 136830 136831 136832 136833 136834 136835 136836 136837 \
+ 136838 136839 136840 136841 136842 136843 135451 136844 136845 136846 \
+ 136847 136848 136849 135453 136850 136851 136852 136853 136854 136855 \
+ 136856 136857 135203 135517 136858 136859 136860 136861 136862 136863 \
+ 136864 136865 135454 136866 136867 136868 136869 135559 136870 136871 \
+ 136872 136873 136874 136875 136876 136877 136878 136879 136880 136881 \
+ 136882 135271 136883 136884 136885 136886 136887 136888 136889 136890 \
+ 136891 136892 136893 135455 135354 136894 136895 136896 136897 136898 \
+ 136899 136900 136901 135520 136902 136903 136904 136905 136906 136907 \
+ 136908 136909 135521 136910 136911 136912 136913 136914 136915 136916 \
+ 136917 136918 136919 136920 136921 135523 136922 136923 136924 136925 \
+ 136926 136927 136928 136929 136930 136931 136932 136932 136933 136934 \
+ 135525 136935 136936 136937 136938 136939 136940 136941 135257 136942 \
+ 136943 136944 136945 136946 136947 136948 135531 136949 136950 136951 \
+ 136952 136953 136954 136954 135532 135561 136955 136956 136957 136958 \
+ 136959 135220 135534 136960 136961 135465 136962 136963 135424 136964 \
+ 136965 135468 136966 136967 136968 136969 136969 136970 136971 136972 \
+ 136973 136974 136975 136976 136977 136978 136979 136980 136981 136982 \
+ 136983 136984 136985 136986 136987 136988 136989 136990 136991 136992 \
+ 136993 136994 136995 136996 135474 136997 136998 136999 137000 137001 \
+ 137002 137003 137004 137005 137006 137007 137008 137009 137010 137011 \
+ 137012 136798 137013 137014 137015 137016 137017 137018 137019 137020 \
+ 137021 137022 137023 137024 135274 137025 137026 137027 137028 137029 \
+ 137030 135477 137031 137032 137033 137034 137035 137036 137037 137038 \
+ 137039 137040 137041 137042 137043 137044 137045 137046 137047 137048 \
+ 137049 137050 135215 137051 137052 137053 137054 137055 137056 135541 \
+ 137057 137058 137059 137060 137061 137062 137063 137064 133702 137065 \
+ 137066 137067 137068 137069 137070 137071 137072 137073 137074 137075 \
+ 135546 135547 133709 137076 137077 137078 137079 137080 137081 137082 \
+ 137083 137084 137085 137086 137087 135548 137088 137089 137090 137091 \
+ 137092 137093 137094 137095 137096 137097 137098 137099 137100 137101 \
+ 137102 137103 137104 137105 137106 137107 137108 137109 137110 137111 \
+ 137112 137113 137114 137115 137116 137117 135554 135554 137118 137119 \
+ 137120 137121 137122 137123 137124 137125 137126 137127 135555 137128 \
+ 137129 137130 137131 137132 137133 137134 137135 137136 137137 133757 \
+ 137138 133761 137139 137140 137141 137142 133766 137143 -1 -1]
+
+#
+# List of decomposition sequences
+#
+
+set decompList [list \
+ 32 32 776 97 32 772 50 51 32 769 956 32 807 49 111 49 8260 52 49 8260 \
+ 50 51 8260 52 65 768 65 769 65 770 65 771 65 776 65 778 67 807 69 768 \
+ 69 769 69 770 69 776 73 768 73 769 73 770 73 776 78 771 79 768 79 769 \
+ 79 770 79 771 79 776 85 768 85 769 85 770 85 776 89 769 97 768 97 769 \
+ 97 770 97 771 97 776 97 778 99 807 101 768 101 769 101 770 101 776 \
+ 105 768 105 769 105 770 105 776 110 771 111 768 111 769 111 770 111 \
+ 771 111 776 117 768 117 769 117 770 117 776 121 769 121 776 65 772 \
+ 97 772 65 774 97 774 65 808 97 808 67 769 99 769 67 770 99 770 67 775 \
+ 99 775 67 780 99 780 68 780 100 780 69 772 101 772 69 774 101 774 69 \
+ 775 101 775 69 808 101 808 69 780 101 780 71 770 103 770 71 774 103 \
+ 774 71 775 103 775 71 807 103 807 72 770 104 770 73 771 105 771 73 \
+ 772 105 772 73 774 105 774 73 808 105 808 73 775 73 74 105 106 74 770 \
+ 106 770 75 807 107 807 76 769 108 769 76 807 108 807 76 780 108 780 \
+ 76 183 108 183 78 769 110 769 78 807 110 807 78 780 110 780 700 110 \
+ 79 772 111 772 79 774 111 774 79 779 111 779 82 769 114 769 82 807 \
+ 114 807 82 780 114 780 83 769 115 769 83 770 115 770 83 807 115 807 \
+ 83 780 115 780 84 807 116 807 84 780 116 780 85 771 117 771 85 772 \
+ 117 772 85 774 117 774 85 778 117 778 85 779 117 779 85 808 117 808 \
+ 87 770 119 770 89 770 121 770 89 776 90 769 122 769 90 775 122 775 \
+ 90 780 122 780 115 79 795 111 795 85 795 117 795 68 381 68 382 100 \
+ 382 76 74 76 106 108 106 78 74 78 106 110 106 65 780 97 780 73 780 \
+ 105 780 79 780 111 780 85 780 117 780 220 772 252 772 220 769 252 769 \
+ 220 780 252 780 220 768 252 768 196 772 228 772 550 772 551 772 198 \
+ 772 230 772 71 780 103 780 75 780 107 780 79 808 111 808 490 772 491 \
+ 772 439 780 658 780 106 780 68 90 68 122 100 122 71 769 103 769 78 \
+ 768 110 768 197 769 229 769 198 769 230 769 216 769 248 769 65 783 \
+ 97 783 65 785 97 785 69 783 101 783 69 785 101 785 73 783 105 783 73 \
+ 785 105 785 79 783 111 783 79 785 111 785 82 783 114 783 82 785 114 \
+ 785 85 783 117 783 85 785 117 785 83 806 115 806 84 806 116 806 72 \
+ 780 104 780 65 775 97 775 69 807 101 807 214 772 246 772 213 772 245 \
+ 772 79 775 111 775 558 772 559 772 89 772 121 772 104 614 106 114 633 \
+ 635 641 119 121 32 774 32 775 32 778 32 808 32 771 32 779 611 108 120 \
+ 661 768 769 787 776 769 697 32 837 59 168 769 913 769 183 917 769 919 \
+ 769 921 769 927 769 933 769 937 769 970 769 921 776 933 776 945 769 \
+ 949 769 951 769 953 769 971 769 953 776 965 776 959 769 965 769 969 \
+ 769 946 952 933 978 769 978 776 966 960 954 961 962 920 949 931 1045 \
+ 768 1045 776 1043 769 1030 776 1050 769 1048 768 1059 774 1048 774 \
+ 1080 774 1077 768 1077 776 1075 769 1110 776 1082 769 1080 768 1091 \
+ 774 1140 783 1141 783 1046 774 1078 774 1040 774 1072 774 1040 776 \
+ 1072 776 1045 774 1077 774 1240 776 1241 776 1046 776 1078 776 1047 \
+ 776 1079 776 1048 772 1080 772 1048 776 1080 776 1054 776 1086 776 \
+ 1256 776 1257 776 1069 776 1101 776 1059 772 1091 772 1059 776 1091 \
+ 776 1059 779 1091 779 1063 776 1095 776 1067 776 1099 776 1381 1410 \
+ 1575 1619 1575 1620 1608 1620 1575 1621 1610 1620 1575 1652 1608 1652 \
+ 1735 1652 1610 1652 1749 1620 1729 1620 1746 1620 2344 2364 2352 2364 \
+ 2355 2364 2325 2364 2326 2364 2327 2364 2332 2364 2337 2364 2338 2364 \
+ 2347 2364 2351 2364 2503 2494 2503 2519 2465 2492 2466 2492 2479 2492 \
+ 2610 2620 2616 2620 2582 2620 2583 2620 2588 2620 2603 2620 2887 2902 \
+ 2887 2878 2887 2903 2849 2876 2850 2876 2962 3031 3014 3006 3015 3006 \
+ 3014 3031 3142 3158 3263 3285 3270 3285 3270 3286 3270 3266 3274 3285 \
+ 3398 3390 3399 3390 3398 3415 3545 3530 3545 3535 3548 3530 3545 3551 \
+ 3661 3634 3789 3762 3755 3737 3755 3745 3851 3906 4023 3916 4023 3921 \
+ 4023 3926 4023 3931 4023 3904 4021 3953 3954 3953 3956 4018 3968 4018 \
+ 3969 4019 3968 4019 3969 3953 3968 3986 4023 3996 4023 4001 4023 4006 \
+ 4023 4011 4023 3984 4021 4133 4142 4316 6917 6965 6919 6965 6921 6965 \
+ 6923 6965 6925 6965 6929 6965 6970 6965 6972 6965 6974 6965 6975 6965 \
+ 6978 6965 65 198 66 68 69 398 71 72 73 74 75 76 77 78 79 546 80 82 \
+ 84 85 87 592 593 7426 98 100 101 601 603 604 103 107 109 331 596 7446 \
+ 7447 112 116 117 7453 623 118 7461 947 948 967 105 1085 594 99 597 \
+ 240 102 607 609 613 616 617 618 7547 669 621 7557 671 625 624 626 627 \
+ 628 629 632 642 643 427 649 650 7452 651 652 122 656 657 658 65 805 \
+ 97 805 66 775 98 775 66 803 98 803 66 817 98 817 199 769 231 769 68 \
+ 775 100 775 68 803 100 803 68 817 100 817 68 807 100 807 68 813 100 \
+ 813 274 768 275 768 274 769 275 769 69 813 101 813 69 816 101 816 552 \
+ 774 553 774 70 775 102 775 71 772 103 772 72 775 104 775 72 803 104 \
+ 803 72 776 104 776 72 807 104 807 72 814 104 814 73 816 105 816 207 \
+ 769 239 769 75 769 107 769 75 803 107 803 75 817 107 817 76 803 108 \
+ 803 7734 772 7735 772 76 817 108 817 76 813 108 813 77 769 109 769 \
+ 77 775 109 775 77 803 109 803 78 775 110 775 78 803 110 803 78 817 \
+ 110 817 78 813 110 813 213 769 245 769 213 776 245 776 332 768 333 \
+ 768 332 769 333 769 80 769 112 769 80 775 112 775 82 775 114 775 82 \
+ 803 114 803 7770 772 7771 772 82 817 114 817 83 775 115 775 83 803 \
+ 115 803 346 775 347 775 352 775 353 775 7778 775 7779 775 84 775 116 \
+ 775 84 803 116 803 84 817 116 817 84 813 116 813 85 804 117 804 85 \
+ 816 117 816 85 813 117 813 360 769 361 769 362 776 363 776 86 771 118 \
+ 771 86 803 118 803 87 768 119 768 87 769 119 769 87 776 119 776 87 \
+ 775 119 775 87 803 119 803 88 775 120 775 88 776 120 776 89 775 121 \
+ 775 90 770 122 770 90 803 122 803 90 817 122 817 104 817 116 776 119 \
+ 778 121 778 97 702 383 775 65 803 97 803 65 777 97 777 194 769 226 \
+ 769 194 768 226 768 194 777 226 777 194 771 226 771 7840 770 7841 770 \
+ 258 769 259 769 258 768 259 768 258 777 259 777 258 771 259 771 7840 \
+ 774 7841 774 69 803 101 803 69 777 101 777 69 771 101 771 202 769 234 \
+ 769 202 768 234 768 202 777 234 777 202 771 234 771 7864 770 7865 770 \
+ 73 777 105 777 73 803 105 803 79 803 111 803 79 777 111 777 212 769 \
+ 244 769 212 768 244 768 212 777 244 777 212 771 244 771 7884 770 7885 \
+ 770 416 769 417 769 416 768 417 768 416 777 417 777 416 771 417 771 \
+ 416 803 417 803 85 803 117 803 85 777 117 777 431 769 432 769 431 768 \
+ 432 768 431 777 432 777 431 771 432 771 431 803 432 803 89 768 121 \
+ 768 89 803 121 803 89 777 121 777 89 771 121 771 945 787 945 788 7936 \
+ 768 7937 768 7936 769 7937 769 7936 834 7937 834 913 787 913 788 7944 \
+ 768 7945 768 7944 769 7945 769 7944 834 7945 834 949 787 949 788 7952 \
+ 768 7953 768 7952 769 7953 769 917 787 917 788 7960 768 7961 768 7960 \
+ 769 7961 769 951 787 951 788 7968 768 7969 768 7968 769 7969 769 7968 \
+ 834 7969 834 919 787 919 788 7976 768 7977 768 7976 769 7977 769 7976 \
+ 834 7977 834 953 787 953 788 7984 768 7985 768 7984 769 7985 769 7984 \
+ 834 7985 834 921 787 921 788 7992 768 7993 768 7992 769 7993 769 7992 \
+ 834 7993 834 959 787 959 788 8000 768 8001 768 8000 769 8001 769 927 \
+ 787 927 788 8008 768 8009 768 8008 769 8009 769 965 787 965 788 8016 \
+ 768 8017 768 8016 769 8017 769 8016 834 8017 834 933 788 8025 768 8025 \
+ 769 8025 834 969 787 969 788 8032 768 8033 768 8032 769 8033 769 8032 \
+ 834 8033 834 937 787 937 788 8040 768 8041 768 8040 769 8041 769 8040 \
+ 834 8041 834 945 768 940 949 768 941 951 768 942 953 768 943 959 768 \
+ 972 965 768 973 969 768 974 7936 837 7937 837 7938 837 7939 837 7940 \
+ 837 7941 837 7942 837 7943 837 7944 837 7945 837 7946 837 7947 837 \
+ 7948 837 7949 837 7950 837 7951 837 7968 837 7969 837 7970 837 7971 \
+ 837 7972 837 7973 837 7974 837 7975 837 7976 837 7977 837 7978 837 \
+ 7979 837 7980 837 7981 837 7982 837 7983 837 8032 837 8033 837 8034 \
+ 837 8035 837 8036 837 8037 837 8038 837 8039 837 8040 837 8041 837 \
+ 8042 837 8043 837 8044 837 8045 837 8046 837 8047 837 945 774 945 772 \
+ 8048 837 945 837 940 837 945 834 8118 837 913 774 913 772 913 768 902 \
+ 913 837 32 787 953 32 834 168 834 8052 837 951 837 942 837 951 834 \
+ 8134 837 917 768 904 919 768 905 919 837 8127 768 8127 769 8127 834 \
+ 953 774 953 772 970 768 912 953 834 970 834 921 774 921 772 921 768 \
+ 906 8190 768 8190 769 8190 834 965 774 965 772 971 768 944 961 787 \
+ 961 788 965 834 971 834 933 774 933 772 933 768 910 929 788 168 768 \
+ 901 96 8060 837 969 837 974 837 969 834 8182 837 927 768 908 937 768 \
+ 911 937 837 180 32 788 8194 8195 8208 32 819 46 46 46 46 46 46 8242 \
+ 8242 8242 8242 8242 8245 8245 8245 8245 8245 33 33 32 773 63 63 63 \
+ 33 33 63 8242 8242 8242 8242 48 52 53 54 55 56 57 43 8722 61 40 41 \
+ 110 82 115 97 47 99 97 47 115 67 176 67 99 47 111 99 47 117 400 176 \
+ 70 295 78 111 81 83 77 84 69 76 84 77 90 937 197 70 1488 1489 1490 \
+ 1491 70 65 88 915 928 8721 49 8260 51 50 8260 51 49 8260 53 50 8260 \
+ 53 51 8260 53 52 8260 53 49 8260 54 53 8260 54 49 8260 56 51 8260 56 \
+ 53 8260 56 55 8260 56 49 8260 73 73 73 73 73 73 86 86 86 73 86 73 73 \
+ 86 73 73 73 73 88 88 88 73 88 73 73 105 105 105 105 105 105 118 118 \
+ 105 118 105 105 118 105 105 105 105 120 120 105 120 105 105 8592 824 \
+ 8594 824 8596 824 8656 824 8660 824 8658 824 8707 824 8712 824 8715 \
+ 824 8739 824 8741 824 8747 8747 8747 8747 8747 8750 8750 8750 8750 \
+ 8750 8764 824 8771 824 8773 824 8776 824 61 824 8801 824 8781 824 60 \
+ 824 62 824 8804 824 8805 824 8818 824 8819 824 8822 824 8823 824 8826 \
+ 824 8827 824 8834 824 8835 824 8838 824 8839 824 8866 824 8872 824 \
+ 8873 824 8875 824 8828 824 8829 824 8849 824 8850 824 8882 824 8883 \
+ 824 8884 824 8885 824 12296 12297 49 48 49 49 49 50 49 51 49 52 49 \
+ 53 49 54 49 55 49 56 49 57 50 48 40 49 41 40 50 41 40 51 41 40 52 41 \
+ 40 53 41 40 54 41 40 55 41 40 56 41 40 57 41 40 49 48 41 40 49 49 41 \
+ 40 49 50 41 40 49 51 41 40 49 52 41 40 49 53 41 40 49 54 41 40 49 55 \
+ 41 40 49 56 41 40 49 57 41 40 50 48 41 49 46 50 46 51 46 52 46 53 46 \
+ 54 46 55 46 56 46 57 46 49 48 46 49 49 46 49 50 46 49 51 46 49 52 46 \
+ 49 53 46 49 54 46 49 55 46 49 56 46 49 57 46 50 48 46 40 97 41 40 98 \
+ 41 40 99 41 40 100 41 40 101 41 40 102 41 40 103 41 40 104 41 40 105 \
+ 41 40 106 41 40 107 41 40 108 41 40 109 41 40 110 41 40 111 41 40 112 \
+ 41 40 113 41 40 114 41 40 115 41 40 116 41 40 117 41 40 118 41 40 119 \
+ 41 40 120 41 40 121 41 40 122 41 83 89 113 8747 8747 8747 8747 58 58 \
+ 61 61 61 61 61 61 10973 824 11617 27597 40863 19968 20008 20022 20031 \
+ 20057 20101 20108 20128 20154 20799 20837 20843 20866 20886 20907 20960 \
+ 20981 20992 21147 21241 21269 21274 21304 21313 21340 21353 21378 21430 \
+ 21448 21475 22231 22303 22763 22786 22794 22805 22823 22899 23376 23424 \
+ 23544 23567 23586 23608 23662 23665 24027 24037 24049 24062 24178 24186 \
+ 24191 24308 24318 24331 24339 24400 24417 24435 24515 25096 25142 25163 \
+ 25903 25908 25991 26007 26020 26041 26080 26085 26352 26376 26408 27424 \
+ 27490 27513 27571 27595 27604 27611 27663 27668 27700 28779 29226 29238 \
+ 29243 29247 29255 29273 29275 29356 29572 29577 29916 29926 29976 29983 \
+ 29992 30000 30091 30098 30326 30333 30382 30399 30446 30683 30690 30707 \
+ 31034 31160 31166 31348 31435 31481 31859 31992 32566 32593 32650 32701 \
+ 32769 32780 32786 32819 32895 32905 33251 33258 33267 33276 33292 33307 \
+ 33311 33390 33394 33400 34381 34411 34880 34892 34915 35198 35211 35282 \
+ 35328 35895 35910 35925 35960 35997 36196 36208 36275 36523 36554 36763 \
+ 36784 36789 37009 37193 37318 37324 37329 38263 38272 38428 38582 38585 \
+ 38632 38737 38750 38754 38761 38859 38893 38899 38913 39080 39131 39135 \
+ 39318 39321 39340 39592 39640 39647 39717 39727 39730 39740 39770 40165 \
+ 40565 40575 40613 40635 40643 40653 40657 40697 40701 40718 40723 40736 \
+ 40763 40778 40786 40845 40860 40864 12306 21316 21317 12363 12441 12365 \
+ 12441 12367 12441 12369 12441 12371 12441 12373 12441 12375 12441 12377 \
+ 12441 12379 12441 12381 12441 12383 12441 12385 12441 12388 12441 12390 \
+ 12441 12392 12441 12399 12441 12399 12442 12402 12441 12402 12442 12405 \
+ 12441 12405 12442 12408 12441 12408 12442 12411 12441 12411 12442 12358 \
+ 12441 32 12441 32 12442 12445 12441 12424 12426 12459 12441 12461 12441 \
+ 12463 12441 12465 12441 12467 12441 12469 12441 12471 12441 12473 12441 \
+ 12475 12441 12477 12441 12479 12441 12481 12441 12484 12441 12486 12441 \
+ 12488 12441 12495 12441 12495 12442 12498 12441 12498 12442 12501 12441 \
+ 12501 12442 12504 12441 12504 12442 12507 12441 12507 12442 12454 12441 \
+ 12527 12441 12528 12441 12529 12441 12530 12441 12541 12441 12467 12488 \
+ 4352 4353 4522 4354 4524 4525 4355 4356 4357 4528 4529 4530 4531 4532 \
+ 4533 4378 4358 4359 4360 4385 4361 4362 4363 4364 4365 4366 4367 4368 \
+ 4369 4370 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 \
+ 4461 4462 4463 4464 4465 4466 4467 4468 4469 4448 4372 4373 4551 4552 \
+ 4556 4558 4563 4567 4569 4380 4573 4575 4381 4382 4384 4386 4387 4391 \
+ 4393 4395 4396 4397 4398 4399 4402 4406 4416 4423 4428 4593 4594 4439 \
+ 4440 4441 4484 4485 4488 4497 4498 4500 4510 4513 19977 22235 19978 \
+ 20013 19979 30002 19993 19969 22825 22320 40 4352 41 40 4354 41 40 \
+ 4355 41 40 4357 41 40 4358 41 40 4359 41 40 4361 41 40 4363 41 40 4364 \
+ 41 40 4366 41 40 4367 41 40 4368 41 40 4369 41 40 4370 41 40 4352 4449 \
+ 41 40 4354 4449 41 40 4355 4449 41 40 4357 4449 41 40 4358 4449 41 \
+ 40 4359 4449 41 40 4361 4449 41 40 4363 4449 41 40 4364 4449 41 40 \
+ 4366 4449 41 40 4367 4449 41 40 4368 4449 41 40 4369 4449 41 40 4370 \
+ 4449 41 40 4364 4462 41 40 4363 4457 4364 4453 4523 41 40 4363 4457 \
+ 4370 4462 41 40 19968 41 40 20108 41 40 19977 41 40 22235 41 40 20116 \
+ 41 40 20845 41 40 19971 41 40 20843 41 40 20061 41 40 21313 41 40 26376 \
+ 41 40 28779 41 40 27700 41 40 26408 41 40 37329 41 40 22303 41 40 26085 \
+ 41 40 26666 41 40 26377 41 40 31038 41 40 21517 41 40 29305 41 40 36001 \
+ 41 40 31069 41 40 21172 41 40 20195 41 40 21628 41 40 23398 41 40 30435 \
+ 41 40 20225 41 40 36039 41 40 21332 41 40 31085 41 40 20241 41 40 33258 \
+ 41 40 33267 41 80 84 69 50 49 50 50 50 51 50 52 50 53 50 54 50 55 50 \
+ 56 50 57 51 48 51 49 51 50 51 51 51 52 51 53 4352 4449 4354 4449 4355 \
+ 4449 4357 4449 4358 4449 4359 4449 4361 4449 4363 4449 4364 4449 4366 \
+ 4449 4367 4449 4368 4449 4369 4449 4370 4449 4366 4449 4535 4352 4457 \
+ 4364 4462 4363 4468 4363 4462 20116 20845 19971 20061 26666 26377 31038 \
+ 21517 29305 36001 31069 21172 31192 30007 36969 20778 21360 27880 38917 \
+ 20241 20889 27491 24038 21491 21307 23447 23398 30435 20225 36039 21332 \
+ 22812 51 54 51 55 51 56 51 57 52 48 52 49 52 50 52 51 52 52 52 53 52 \
+ 54 52 55 52 56 52 57 53 48 49 26376 50 26376 51 26376 52 26376 53 26376 \
+ 54 26376 55 26376 56 26376 57 26376 49 48 26376 49 49 26376 49 50 26376 \
+ 72 103 101 114 103 101 86 76 84 68 12450 12452 12454 12456 12458 12459 \
+ 12461 12463 12465 12467 12469 12471 12473 12475 12477 12479 12481 12484 \
+ 12486 12488 12490 12491 12492 12493 12494 12495 12498 12501 12504 12507 \
+ 12510 12511 12512 12513 12514 12516 12518 12520 12521 12522 12523 12524 \
+ 12525 12527 12528 12529 12530 12450 12497 12540 12488 12450 12523 12501 \
+ 12449 12450 12531 12506 12450 12450 12540 12523 12452 12491 12531 12464 \
+ 12452 12531 12481 12454 12457 12531 12456 12473 12463 12540 12489 12456 \
+ 12540 12459 12540 12458 12531 12473 12458 12540 12512 12459 12452 12522 \
+ 12459 12521 12483 12488 12459 12525 12522 12540 12460 12525 12531 12460 \
+ 12531 12510 12462 12460 12462 12491 12540 12461 12517 12522 12540 12462 \
+ 12523 12480 12540 12461 12525 12461 12525 12464 12521 12512 12461 12525 \
+ 12513 12540 12488 12523 12461 12525 12527 12483 12488 12464 12521 12512 \
+ 12464 12521 12512 12488 12531 12463 12523 12476 12452 12525 12463 12525 \
+ 12540 12493 12465 12540 12473 12467 12523 12490 12467 12540 12509 12469 \
+ 12452 12463 12523 12469 12531 12481 12540 12512 12471 12522 12531 12464 \
+ 12475 12531 12481 12475 12531 12488 12480 12540 12473 12487 12471 12489 \
+ 12523 12488 12531 12490 12494 12494 12483 12488 12495 12452 12484 12497 \
+ 12540 12475 12531 12488 12497 12540 12484 12496 12540 12524 12523 12500 \
+ 12450 12473 12488 12523 12500 12463 12523 12500 12467 12499 12523 12501 \
+ 12449 12521 12483 12489 12501 12451 12540 12488 12502 12483 12471 12455 \
+ 12523 12501 12521 12531 12504 12463 12479 12540 12523 12506 12477 12506 \
+ 12491 12498 12504 12523 12484 12506 12531 12473 12506 12540 12472 12505 \
+ 12540 12479 12509 12452 12531 12488 12508 12523 12488 12507 12531 12509 \
+ 12531 12489 12507 12540 12523 12507 12540 12531 12510 12452 12463 12525 \
+ 12510 12452 12523 12510 12483 12495 12510 12523 12463 12510 12531 12471 \
+ 12519 12531 12511 12463 12525 12531 12511 12522 12511 12522 12496 12540 \
+ 12523 12513 12460 12513 12460 12488 12531 12513 12540 12488 12523 12516 \
+ 12540 12489 12516 12540 12523 12518 12450 12531 12522 12483 12488 12523 \
+ 12522 12521 12523 12500 12540 12523 12540 12502 12523 12524 12512 12524 \
+ 12531 12488 12466 12531 12527 12483 12488 48 28857 49 28857 50 28857 \
+ 51 28857 52 28857 53 28857 54 28857 55 28857 56 28857 57 28857 49 48 \
+ 28857 49 49 28857 49 50 28857 49 51 28857 49 52 28857 49 53 28857 49 \
+ 54 28857 49 55 28857 49 56 28857 49 57 28857 50 48 28857 50 49 28857 \
+ 50 50 28857 50 51 28857 50 52 28857 104 80 97 100 97 65 85 98 97 114 \
+ 111 86 112 99 100 109 100 109 178 100 109 179 73 85 24179 25104 26157 \
+ 21644 22823 27491 26126 27835 26666 24335 20250 31038 112 65 110 65 \
+ 956 65 109 65 107 65 75 66 77 66 71 66 99 97 108 107 99 97 108 112 \
+ 70 110 70 956 70 956 103 109 103 107 103 72 122 107 72 122 77 72 122 \
+ 71 72 122 84 72 122 956 8467 109 8467 100 8467 107 8467 102 109 110 \
+ 109 956 109 109 109 99 109 107 109 109 109 178 99 109 178 109 178 107 \
+ 109 178 109 109 179 99 109 179 109 179 107 109 179 109 8725 115 109 \
+ 8725 115 178 80 97 107 80 97 77 80 97 71 80 97 114 97 100 114 97 100 \
+ 8725 115 114 97 100 8725 115 178 112 115 110 115 956 115 109 115 112 \
+ 86 110 86 956 86 109 86 107 86 77 86 112 87 110 87 956 87 109 87 107 \
+ 87 77 87 107 937 77 937 97 46 109 46 66 113 99 99 99 100 67 8725 107 \
+ 103 67 111 46 100 66 71 121 104 97 72 80 105 110 75 75 75 77 107 116 \
+ 108 109 108 110 108 111 103 108 120 109 98 109 105 108 109 111 108 \
+ 80 72 112 46 109 46 80 80 77 80 82 115 114 83 118 87 98 86 8725 109 \
+ 65 8725 109 49 26085 50 26085 51 26085 52 26085 53 26085 54 26085 55 \
+ 26085 56 26085 57 26085 49 48 26085 49 49 26085 49 50 26085 49 51 26085 \
+ 49 52 26085 49 53 26085 49 54 26085 49 55 26085 49 56 26085 49 57 26085 \
+ 50 48 26085 50 49 26085 50 50 26085 50 51 26085 50 52 26085 50 53 26085 \
+ 50 54 26085 50 55 26085 50 56 26085 50 57 26085 51 48 26085 51 49 26085 \
+ 103 97 108 35912 26356 36040 28369 20018 21477 22865 21895 22856 25078 \
+ 30313 32645 34367 34746 35064 37007 27138 27931 28889 29662 33853 37226 \
+ 39409 20098 21365 27396 29211 34349 40478 23888 28651 34253 35172 25289 \
+ 33240 34847 24266 26391 28010 29436 37070 20358 20919 21214 25796 27347 \
+ 29200 30439 34310 34396 36335 38706 39791 40442 30860 31103 32160 33737 \
+ 37636 35542 22751 24324 31840 32894 29282 30922 36034 38647 22744 23650 \
+ 27155 28122 28431 32047 32311 38475 21202 32907 20956 20940 31260 32190 \
+ 33777 38517 35712 25295 35582 20025 23527 24594 29575 30064 21271 30971 \
+ 20415 24489 19981 27852 25976 32034 21443 22622 30465 33865 35498 27578 \
+ 27784 25342 33509 25504 30053 20142 20841 20937 26753 31975 33391 35538 \
+ 37327 21237 21570 24300 26053 28670 31018 38317 39530 40599 40654 26310 \
+ 27511 36706 24180 24976 25088 25754 28451 29001 29833 31178 32244 32879 \
+ 36646 34030 36899 37706 21015 21155 21693 28872 35010 24265 24565 25467 \
+ 27566 31806 29557 20196 22265 23994 24604 29618 29801 32666 32838 37428 \
+ 38646 38728 38936 20363 31150 37300 38584 24801 20102 20698 23534 23615 \
+ 26009 29134 30274 34044 36988 26248 38446 21129 26491 26611 27969 28316 \
+ 29705 30041 30827 32016 39006 25134 38520 20523 23833 28138 36650 24459 \
+ 24900 26647 38534 21033 21519 23653 26131 26446 26792 27877 29702 30178 \
+ 32633 35023 35041 38626 21311 28346 21533 29136 29848 34298 38563 40023 \
+ 40607 26519 28107 33256 31520 31890 29376 28825 35672 20160 33590 21050 \
+ 20999 24230 25299 31958 23429 27934 26292 36667 38477 24275 20800 21952 \
+ 22618 26228 20958 29482 30410 31036 31070 31077 31119 38742 31934 34322 \
+ 35576 36920 37117 39151 39164 39208 40372 20398 20711 20813 21193 21220 \
+ 21329 21917 22022 22120 22592 22696 23652 24724 24936 24974 25074 25935 \
+ 26082 26257 26757 28023 28186 28450 29038 29227 29730 30865 31049 31048 \
+ 31056 31062 31117 31118 31296 31361 31680 32265 32321 32626 32773 33261 \
+ 33401 33879 35088 35222 35585 35641 36051 36104 36790 38627 38911 38971 \
+ 20006 20917 20840 20352 20805 20864 21191 21242 21845 21913 21986 22707 \
+ 22852 22868 23138 23336 24274 24281 24425 24493 24792 24910 24840 24928 \
+ 25140 25540 25628 25682 25942 26395 26454 28379 28363 28702 30631 29237 \
+ 29359 29809 29958 30011 30237 30239 30427 30452 30538 30528 30924 31409 \
+ 31867 32091 32574 33618 33775 34681 35137 35206 35519 35531 35565 35722 \
+ 36664 36978 37273 37494 38524 38875 38923 39698 141386 141380 144341 \
+ 15261 16408 16441 152137 154832 163539 40771 40846 102 102 102 105 \
+ 102 108 102 102 105 102 102 108 383 116 115 116 1396 1398 1396 1381 \
+ 1396 1387 1406 1398 1396 1389 1497 1460 1522 1463 1506 1492 1499 1500 \
+ 1501 1512 1514 1513 1473 1513 1474 64329 1473 64329 1474 1488 1463 \
+ 1488 1464 1488 1468 1489 1468 1490 1468 1491 1468 1492 1468 1493 1468 \
+ 1494 1468 1496 1468 1497 1468 1498 1468 1499 1468 1500 1468 1502 1468 \
+ 1504 1468 1505 1468 1507 1468 1508 1468 1510 1468 1511 1468 1512 1468 \
+ 1513 1468 1514 1468 1493 1465 1489 1471 1499 1471 1508 1471 1488 1500 \
+ 1649 1659 1662 1664 1658 1663 1657 1700 1702 1668 1667 1670 1671 1677 \
+ 1676 1678 1672 1688 1681 1705 1711 1715 1713 1722 1723 1728 1729 1726 \
+ 1746 1747 1709 1735 1734 1736 1655 1739 1733 1737 1744 1609 1574 1575 \
+ 1574 1749 1574 1608 1574 1735 1574 1734 1574 1736 1574 1744 1574 1609 \
+ 1740 1574 1580 1574 1581 1574 1605 1574 1610 1576 1580 1576 1581 1576 \
+ 1582 1576 1605 1576 1609 1576 1610 1578 1580 1578 1581 1578 1582 1578 \
+ 1605 1578 1609 1578 1610 1579 1580 1579 1605 1579 1609 1579 1610 1580 \
+ 1581 1580 1605 1581 1580 1581 1605 1582 1580 1582 1581 1582 1605 1587 \
+ 1580 1587 1581 1587 1582 1587 1605 1589 1581 1589 1605 1590 1580 1590 \
+ 1581 1590 1582 1590 1605 1591 1581 1591 1605 1592 1605 1593 1580 1593 \
+ 1605 1594 1580 1594 1605 1601 1580 1601 1581 1601 1582 1601 1605 1601 \
+ 1609 1601 1610 1602 1581 1602 1605 1602 1609 1602 1610 1603 1575 1603 \
+ 1580 1603 1581 1603 1582 1603 1604 1603 1605 1603 1609 1603 1610 1604 \
+ 1580 1604 1581 1604 1582 1604 1605 1604 1609 1604 1610 1605 1580 1605 \
+ 1581 1605 1582 1605 1605 1605 1609 1605 1610 1606 1580 1606 1581 1606 \
+ 1582 1606 1605 1606 1609 1606 1610 1607 1580 1607 1605 1607 1609 1607 \
+ 1610 1610 1580 1610 1581 1610 1582 1610 1605 1610 1609 1610 1610 1584 \
+ 1648 1585 1648 1609 1648 32 1612 1617 32 1613 1617 32 1614 1617 32 \
+ 1615 1617 32 1616 1617 32 1617 1648 1574 1585 1574 1586 1574 1606 1576 \
+ 1585 1576 1586 1576 1606 1578 1585 1578 1586 1578 1606 1579 1585 1579 \
+ 1586 1579 1606 1605 1575 1606 1585 1606 1586 1606 1606 1610 1585 1610 \
+ 1586 1610 1606 1574 1582 1574 1607 1576 1607 1578 1607 1589 1582 1604 \
+ 1607 1606 1607 1607 1648 1610 1607 1579 1607 1587 1607 1588 1605 1588 \
+ 1607 1600 1614 1617 1600 1615 1617 1600 1616 1617 1591 1609 1591 1610 \
+ 1593 1609 1593 1610 1594 1609 1594 1610 1587 1609 1587 1610 1588 1609 \
+ 1588 1610 1581 1609 1581 1610 1580 1609 1580 1610 1582 1609 1582 1610 \
+ 1589 1609 1589 1610 1590 1609 1590 1610 1588 1580 1588 1581 1588 1582 \
+ 1588 1585 1587 1585 1589 1585 1590 1585 1575 1611 1578 1580 1605 1578 \
+ 1581 1580 1578 1581 1605 1578 1582 1605 1578 1605 1580 1578 1605 1581 \
+ 1578 1605 1582 1580 1605 1581 1581 1605 1610 1581 1605 1609 1587 1581 \
+ 1580 1587 1580 1581 1587 1580 1609 1587 1605 1581 1587 1605 1580 1587 \
+ 1605 1605 1589 1581 1581 1589 1605 1605 1588 1581 1605 1588 1580 1610 \
+ 1588 1605 1582 1588 1605 1605 1590 1581 1609 1590 1582 1605 1591 1605 \
+ 1581 1591 1605 1605 1591 1605 1610 1593 1580 1605 1593 1605 1605 1593 \
+ 1605 1609 1594 1605 1605 1594 1605 1610 1594 1605 1609 1601 1582 1605 \
+ 1602 1605 1581 1602 1605 1605 1604 1581 1605 1604 1581 1610 1604 1581 \
+ 1609 1604 1580 1580 1604 1582 1605 1604 1605 1581 1605 1581 1580 1605 \
+ 1581 1605 1605 1581 1610 1605 1580 1581 1605 1580 1605 1605 1582 1580 \
+ 1605 1582 1605 1605 1580 1582 1607 1605 1580 1607 1605 1605 1606 1581 \
+ 1605 1606 1581 1609 1606 1580 1605 1606 1580 1609 1606 1605 1610 1606 \
+ 1605 1609 1610 1605 1605 1576 1582 1610 1578 1580 1610 1578 1580 1609 \
+ 1578 1582 1610 1578 1582 1609 1578 1605 1610 1578 1605 1609 1580 1605 \
+ 1610 1580 1581 1609 1580 1605 1609 1587 1582 1609 1589 1581 1610 1588 \
+ 1581 1610 1590 1581 1610 1604 1580 1610 1604 1605 1610 1610 1581 1610 \
+ 1610 1580 1610 1610 1605 1610 1605 1605 1610 1602 1605 1610 1606 1581 \
+ 1610 1593 1605 1610 1603 1605 1610 1606 1580 1581 1605 1582 1610 1604 \
+ 1580 1605 1603 1605 1605 1580 1581 1610 1581 1580 1610 1605 1580 1610 \
+ 1601 1605 1610 1576 1581 1610 1587 1582 1610 1606 1580 1610 1589 1604 \
+ 1746 1602 1604 1746 1575 1604 1604 1607 1575 1603 1576 1585 1605 1581 \
+ 1605 1583 1589 1604 1593 1605 1585 1587 1608 1604 1593 1604 1610 1607 \
+ 1608 1587 1604 1605 1589 1604 1609 1589 1604 1609 32 1575 1604 1604 \
+ 1607 32 1593 1604 1610 1607 32 1608 1587 1604 1605 1580 1604 32 1580 \
+ 1604 1575 1604 1607 1585 1740 1575 1604 44 12289 12290 58 33 63 12310 \
+ 12311 8230 8229 8212 8211 95 123 125 12308 12309 12304 12305 12298 \
+ 12299 12300 12301 12302 12303 91 93 8254 35 38 42 45 60 62 92 36 37 \
+ 64 32 1611 1600 1611 32 1612 32 1613 32 1614 1600 1614 32 1615 1600 \
+ 1615 32 1616 1600 1616 32 1617 1600 1617 32 1618 1600 1618 1569 1570 \
+ 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 \
+ 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1601 1602 1603 1604 \
+ 1605 1606 1607 1608 1610 1604 1570 1604 1571 1604 1573 1604 1575 34 \
+ 39 47 94 124 126 10629 10630 12539 12449 12451 12453 12455 12457 12515 \
+ 12517 12519 12483 12540 12531 12441 12442 12644 12593 12594 12595 12596 \
+ 12597 12598 12599 12600 12601 12602 12603 12604 12605 12606 12607 12608 \
+ 12609 12610 12611 12612 12613 12614 12615 12616 12617 12618 12619 12620 \
+ 12621 12622 12623 12624 12625 12626 12627 12628 12629 12630 12631 12632 \
+ 12633 12634 12635 12636 12637 12638 12639 12640 12641 12642 12643 162 \
+ 163 172 175 166 165 8361 9474 8592 8593 8594 8595 9632 9675 119127 \
+ 119141 119128 119141 119135 119150 119135 119151 119135 119152 119135 \
+ 119153 119135 119154 119225 119141 119226 119141 119227 119150 119228 \
+ 119150 119227 119151 119228 119151 305 567 913 914 916 917 918 919 \
+ 921 922 923 924 925 926 927 929 1012 932 934 935 936 8711 945 950 951 \
+ 955 957 958 959 963 964 965 968 969 8706 1013 977 1008 981 1009 982 \
+ 988 989 20029 20024 20033 131362 20320 20411 20482 20602 20633 20687 \
+ 13470 132666 20820 20836 20855 132380 13497 20839 20877 132427 20887 \
+ 20900 20172 20908 168415 20995 13535 21051 21062 21106 21111 13589 \
+ 21253 21254 21321 21338 21363 21373 21375 133676 28784 21450 21471 \
+ 133987 21483 21489 21510 21662 21560 21576 21608 21666 21750 21776 \
+ 21843 21859 21892 21931 21939 21954 22294 22295 22097 22132 22766 22478 \
+ 22516 22541 22411 22578 22577 22700 136420 22770 22775 22790 22810 \
+ 22818 22882 136872 136938 23020 23067 23079 23000 23142 14062 14076 \
+ 23304 23358 137672 23491 23512 23539 138008 23551 23558 24403 14209 \
+ 23648 23744 23693 138724 23875 138726 23918 23915 23932 24033 24034 \
+ 14383 24061 24104 24125 24169 14434 139651 14460 24240 24243 24246 \
+ 172946 140081 33281 24354 14535 144056 156122 24418 24427 14563 24474 \
+ 24525 24535 24569 24705 14650 14620 141012 24775 24904 24908 24954 \
+ 25010 24996 25007 25054 25104 25115 25181 25265 25300 25424 142092 \
+ 25405 25340 25448 25475 25572 142321 25634 25541 25513 14894 25705 \
+ 25726 25757 25719 14956 25964 143370 26083 26360 26185 15129 15112 \
+ 15076 20882 20885 26368 26268 32941 17369 26401 26462 26451 144323 \
+ 15177 26618 26501 26706 144493 26766 26655 26900 26946 27043 27114 \
+ 27304 145059 27355 15384 27425 145575 27476 15438 27506 27551 27579 \
+ 146061 138507 146170 27726 146620 27839 27853 27751 27926 27966 28009 \
+ 28024 28037 146718 27956 28207 28270 15667 28359 147153 28153 28526 \
+ 147294 147342 28614 28729 28699 15766 28746 28797 28791 28845 132389 \
+ 28997 148067 29084 148395 29224 29264 149000 29312 29333 149301 149524 \
+ 29562 29579 16044 29605 16056 29767 29788 29829 29898 16155 29988 150582 \
+ 30014 150674 139679 30224 151457 151480 151620 16380 16392 151795 151794 \
+ 151833 151859 30494 30495 30603 16454 16534 152605 30798 16611 153126 \
+ 153242 153285 31211 16687 31306 31311 153980 154279 31470 16898 154539 \
+ 31686 31689 16935 154752 31954 17056 31976 31971 32000 155526 32099 \
+ 17153 32199 32258 32325 17204 156200 156231 17241 156377 32634 156478 \
+ 32661 32762 156890 156963 32864 157096 32880 144223 17365 32946 33027 \
+ 17419 33086 23221 157607 157621 144275 144284 33284 36766 17515 33425 \
+ 33419 33437 21171 33457 33459 33469 33510 158524 33565 33635 33709 \
+ 33571 33725 33767 33619 33738 33740 33756 158774 159083 158933 17707 \
+ 34033 34035 34070 160714 34148 159532 17757 17761 159665 159954 17771 \
+ 34384 34407 34409 34473 34440 34574 34530 34600 34667 34694 17879 34785 \
+ 34817 17913 34912 161383 35031 35038 17973 35066 13499 161966 162150 \
+ 18110 18119 35488 162984 36011 36033 36123 36215 163631 133124 36299 \
+ 36284 36336 133342 36564 165330 165357 37012 37105 37137 165678 37147 \
+ 37432 37591 37592 37500 37881 37909 166906 38283 18837 38327 167287 \
+ 18918 38595 23986 38691 168261 168474 19054 19062 38880 168970 19122 \
+ 169110 38953 169398 39138 19251 39209 39335 39362 39422 19406 170800 \
+ 40000 40189 19662 19693 40295 172238 19704 172293 172558 172689 19798 \
+ 40702 40709 40719 40726 173568]
+
+set DECOMP_COMPAT_MASK 65536
+set DECOMP_INFO_BITS 17
+
+#
+# This macro extracts the information about a character from the
+# Unicode character tables.
+#
+
+proc GetUniCharDecompCompatInfo {uc} {
+ variable DECOMP_OFFSET_BITS
+ variable DECOMP_COMMON_PAGE_MAP
+ variable decompPageMap
+ variable decompGroupMap
+
+ set page [expr {($uc & 0x1fffff) >> $DECOMP_OFFSET_BITS}]
+ if {[info exists decompPageMap($page)]} {
+ set apage $decompPageMap($page)
+ } else {
+ set apage $DECOMP_COMMON_PAGE_MAP
+ }
+
+ lindex $decompGroupMap \
+ [expr {($apage << $DECOMP_OFFSET_BITS) | \
+ ($uc & ((1 << $DECOMP_OFFSET_BITS) - 1))}]
+}
+
+proc GetUniCharDecompInfo {uc} {
+ variable DECOMP_COMPAT_MASK
+
+ set info [GetUniCharDecompCompatInfo $uc]
+ if {$info & $DECOMP_COMPAT_MASK} {
+ return -1
+ } else {
+ return $info
+ }
+}
+
+proc GetDecompList {info} {
+ variable DECOMP_INFO_BITS
+ variable decompList
+
+ set decomp_len [expr {$info >> $DECOMP_INFO_BITS}]
+ set decomp_shift [expr {$info & ((1 << ($DECOMP_INFO_BITS - 1)) - 1)}]
+
+ lrange $decompList $decomp_shift [expr {$decomp_shift + $decomp_len - 1}]
+}
+
+set COMP_OFFSET_BITS 1
+
+#
+# The pageMap is indexed by page number and returns an alternate page number
+# that identifies a unique page of characters. Many Unicode characters map
+# to the same alternate page number.
+#
+
+array unset compPageMap
+array set compPageMap [list \
+ 30 1 31 2 32 3 33 4 34 5 35 6 36 7 37 8 38 9 39 10 40 11 41 12 42 13 \
+ 43 14 44 15 45 16 48 17 49 18 50 19 51 20 52 21 53 22 54 23 55 24 56 25 \
+ 57 26 58 27 59 28 60 29 61 30 84 31 97 32 98 33 99 34 101 35 103 36 \
+ 106 37 107 38 108 39 110 40 113 41 114 42 115 43 117 44 119 45 122 46 \
+ 123 47 124 48 126 49 129 50 137 51 166 52 173 53 176 54 180 55 181 56 \
+ 191 57 208 58 215 59 216 60 219 61 245 62 275 63 276 64 279 65 329 66 \
+ 384 67 385 68 386 69 387 70 388 71 389 72 390 73 391 74 392 75 393 76 \
+ 394 77 397 78 401 79 402 80 403 81 404 82 406 83 407 84 408 85 417 86 \
+ 418 87 456 88 458 89 459 90 460 91 463 92 464 93 466 94 468 95 470 96 \
+ 471 97 472 98 474 99 475 100 476 101 479 102 480 103 482 104 484 105 \
+ 485 106 487 107 489 108 515 109 520 110 521 111 522 112 523 113 524 114 \
+ 525 115 527 116 529 117 531 118 533 119 534 120 536 121 537 122 538 123 \
+ 539 124 540 125 541 126 543 127 545 128 547 129 549 130 550 131 555 132 \
+ 570 133 620 134 628 135 787 136 804 137 805 138 809 139 810 140 864 141 \
+ 873 142 874 143 1172 144 1176 145 1177 146 1247 147 1259 148 1439 149 \
+ 1451 150 1481 151 1503 152 1507 153 1515 154 1571 155 1631 156 1633 157 \
+ 1635 158 1637 159 1642 160 1643 161 1695 162 1699 163 1707 164 1765 165 \
+ 1767 166 1772 167 1774 168 1775 169 2066 170 3458 171 3459 172 3460 173 \
+ 3461 174 3462 175 3464 176 3485 177 3486 178 3487 179 3489 180 3867 181 \
+ 3885 182 3889 183 3920 184 3932 185 3942 186 3968 187 3969 188 3970 189 \
+ 3971 190 3972 191 3973 192 3974 193 3975 194 3976 195 3980 196 3984 197 \
+ 3985 198 3986 199 3987 200 3988 201 3989 202 3990 203 3991 204 3992 205 \
+ 3996 206 4000 207 4004 208 4008 209 4012 210 4016 211 4017 212 4018 213 \
+ 4019 214 4020 215 4021 216 4022 217 4023 218 4024 219 4026 220 4030 221 \
+ 4059 222 4063 223 4067 224 4091 225 4095 226 4296 227 4297 228 4298 229 \
+ 4328 230 4329 231 4330 232 4353 233 4356 234 4357 235 4369 236 4370 237 \
+ 4382 238 4385 239 4386 240 4388 241 4390 242 4400 243 4402 244 4409 245 \
+ 4411 246 4413 247 4414 248 4417 249 4419 250 4424 251 4425 252 4433 253 \
+ 4436 254 4437 255 4441 256 4442 257 6179 258 6181 259 6182 260 6183 261 \
+ 6184 262 6185 263 6186 264 6187 265 6188 266 6189 267 6190 268 6191 269 \
+ 6192 270 6194 271 6195 272 6196 273 6199 274 6201 275 6202 276 6204 277 \
+ 6205 278 6220 279 6221 280 6222 281 6227 282 6229 283 6230 284 6231 285 \
+ 6232 286 6233 287 6234 288 6235 289 6236 290 6237 291 6238 292 6239 293 \
+ 6240 294 6242 295 6243 296 6244 297 6247 298 6249 299 6250 300 6252 301 \
+ 6253 302 6263 303 6264 304 6265 305 6270 306]
+
+set COMP_COMMON_PAGE_MAP 0
+
+#
+# The groupMap is indexed by combining the alternate page number with
+# the page offset and returns a group number that identifies a unique
+# set of character attributes.
+#
+
+set compGroupMap [list \
+ -1 -1 65568 65648 65749 -1 -1 30 91 141 65 121 65712 38 94 1 65611 \
+ 124 44 100 12 76 77 -1 48 105 17 84 136 54 113 23 24 -1 -1 140 64 120 \
+ 71 123 65577 99 10 75 129 47 104 16 15 83 135 -1 110 22 86 137 59 117 \
+ 118 28 89 -1 102 -1 6 -1 65724 65579 101 65551 42 -1 -1 65580 130 50 \
+ 65686 -1 65636 -1 115 -1 32 -1 65753 65607 67 65715 5 -1 -1 65550 107 \
+ 20 65634 -1 65591 -1 87 -1 142 66 106 18 37 93 65632 65733 65640 65741 \
+ 65604 65709 65571 65657 -1 65739 81 131 -1 119 33 -1 -1 65546 65597 \
+ 65705 65683 65555 65633 65735 65742 65594 65740 -1 131073 131074 131075 \
+ 131077 131079 -1 131080 131082 131083 131084 131098 131102 131085 -1 \
+ -1 131086 -1 131087 -1 131076 131078 -1 -1 131103 -1 131088 131104 \
+ 131101 131097 131092 131089 -1 -1 131094 131093 -1 131091 131095 131090 \
+ -1 -1 131072 -1 34 -1 122 -1 96 -1 8 -1 80 -1 65590 -1 85 -1 26 65538 \
+ -1 65718 -1 -1 2 -1 95 -1 7 -1 125 -1 51 -1 111 -1 56 -1 0 138 62 65672 \
+ -1 39 -1 65747 -1 97 -1 -1 65725 -1 103 14 65630 132 -1 65585 -1 65738 \
+ -1 -1 139 -1 65570 -1 65717 -1 65671 72 -1 -1 65678 -1 79 133 65586 \
+ 52 -1 65558 -1 65696 -1 -1 63 -1 65755 -1 65667 -1 65601 65666 -1 65669 \
+ 65545 65659 65542 65691 65563 -1 143 65744 -1 65665 -1 -1 196618 131108 \
+ 196619 -1 65626 65619 -1 -1 65618 65745 -1 65664 -1 -1 65663 196611 \
+ -1 -1 196612 196613 -1 196614 196615 65581 -1 131105 -1 98 65588 -1 \
+ 131106 65582 -1 -1 65727 196616 -1 127 -1 65638 -1 -1 131107 196617 \
+ -1 131096 -1 19 65704 -1 196610 131081 -1 -1 196608 -1 3 65539 -1 -1 \
+ 196609 -1 65624 -1 65710 -1 65562 -1 65708 -1 65559 -1 65621 -1 65556 \
+ 65547 -1 65602 -1 65687 65600 65599 -1 65688 65560 65694 65565 65754 \
+ 65608 114 25 65681 65554 65540 65612 82 134 65595 65701 65702 65569 \
+ 65649 65750 58 116 65573 65661 65544 65616 65617 65721 36 92 9 73 53 \
+ 108 65699 65567 65647 65748 65605 65711 27 88 65541 65613 65614 65720 \
+ 65576 65675 11 69 126 45 13 78 55 112 29 90 -1 70 128 46 65692 65564 \
+ 65643 65743 65596 65703 109 21 65650 65751 65606 65713 65572 65660 \
+ 65543 -1 65578 -1 65553 -1 65537 -1 -1 40 65689 -1 65574 -1 4 -1 65716 \
+ -1 65668 -1 65622 -1 65707 -1 65652 -1 65752 -1 -1 65722 65627 -1 -1 \
+ 65684 -1 65676 -1 65549 65656 -1 -1 65548 -1 65726 65552 -1 -1 65690 \
+ -1 65603 65655 65536 65732 65587 65561 65639 65697 65566 65645 65746 \
+ 65654 65756 65575 65670 -1 65584 65583 -1 65609 -1 65620 65723 -1 65677 \
+ 65557 65637 65736 65592 65729 -1 -1 65719 -1 65714 -1 65706 -1 65695 \
+ -1 65693 -1 65685 -1 65679 -1 65673 -1 65658 -1 65653 -1 65646 -1 65641 \
+ 65631 -1 65628 -1 65623 -1 -1 60 74 -1 -1 68 61 -1 -1 57 -1 131099 \
+ 131100 -1 -1 65728 65700 -1 -1 65682 -1 65680 -1 65674 -1 65662 -1 \
+ 65651 -1 65644 -1 65642 -1 65635 -1 65629 -1 65625 -1 65615 -1 65610 \
+ 65598 -1 65593 -1 65589 -1 -1 41 31 -1 -1 49 43 -1 -1 35 -1 65737 65734 \
+ 65731 65730 -1 -1 65698]
+
+#
+# Lists of compositions for characters that appears only in one composition
+#
+
+set compFirstList [list \
+ {824 8817} {837 8119} {837 8116} {3530 3549} {770 7896} {837 8090} \
+ {776 1243} {837 8114} {837 8076} {783 1143} {780 494} {6965 6971} \
+ {824 8772} {824 8742} {769 7727} {769 7688} {824 8777} {837 8178} \
+ {770 7879} {772 481} {6965 6930} {824 8938} {769 1116} {6965 6924} \
+ {772 7737} {824 8824} {6965 6920} {776 1259} {837 8099} {772 7773} \
+ {824 8833} {837 8083} {824 8814} {837 8069} {776 1268} {776 7802} \
+ {837 8110} {837 8074} {837 8183} {824 8840} {837 8094} {775 7711} \
+ {837 8130} {769 506} {769 7726} {3031 2964} {3158 3144} {824 8931} \
+ {824 8930} {769 1036} {776 1247} {824 8821} {3006 3019} {12441 12489} \
+ {788 8172} {769 511} {824 8941} {12441 12487} {772 561} {837 8066} \
+ {837 8102} {772 492} {12441 12485} {6965 6979} {6965 6977} \
+ {776 1261} {6965 6973} {824 8802} {769 7800} {837 8086} {837 8108} \
+ {769 507} {775 7785} {824 8876} {12441 12482} {770 308} {770 7897} \
+ {837 8091} {837 8092} {12441 12480} {837 8077} {837 8078} \
+ {1620 1728} {1620 1747} {824 8877} {6965 6926} {824 8622} \
+ {12441 12393} {4142 4134} {12441 12478} {1620 1730} {824 8713} \
+ {12441 12391} {12441 12476} {776 1246} {12441 12389} {775 7780} \
+ {774 7708} {772 555} {12441 12474} {769 510} {824 8939} {3285 3275} \
+ {824 8825} {775 7782} {12441 12386} {12441 12472} {837 8100} \
+ {12441 12470} {824 8928} {12441 12384} {837 8084} {824 8800} \
+ {837 8070} {837 8106} {12441 12468} {824 8655} {12441 12382} \
+ {824 8836} {824 8816} {824 8769} {776 7803} {12441 12380} \
+ {776 1242} {837 8111} {837 8075} {12441 12466} {2364 2356} \
+ {2364 2353} {1620 1574} {776 1111} {776 1273} {824 8603} \
+ {783 1142} {824 8841} {776 1260} {837 8180} {12441 12378} \
+ {12441 12464} {837 8095} {824 8740} {824 8879} {769 1107} \
+ {12441 12376} {12441 12462} {770 7878} {12441 12460} {772 480} \
+ {824 8716} {12441 12374} {772 554} {6965 6976} {772 7736} \
+ {837 8135} {824 8813} {776 1258} {837 8098} {12441 12372} \
+ {772 7772} {12441 12370} {776 1255} {824 8832} {12441 12542} \
+ {837 8082} {12441 12532} {837 8067} {837 8068} {837 8103} \
+ {3390 3403} {772 493} {12441 12368} {824 8653} {6965 6922} \
+ {769 7801} {6965 6918} {837 8087} {775 7710} {837 8109} {12441 12366} \
+ {769 7689} {824 8602} {776 1272} {837 8132} {12441 12364} \
+ {837 8093} {837 8079} {824 8708} {824 8878} {772 478} {769 1027} \
+ {824 8775} {3285 3264} {12441 12446} {12441 12436} {12441 12538} \
+ {12441 12537} {824 8820} {775 7781} {12441 12536} {774 7709} \
+ {824 8940} {12441 12535} {776 1254} {775 7835} {780 495} \
+ {775 7783} {772 560} {837 8101} {1620 1572} {2364 2345} {824 8929} \
+ {776 1031} {837 8085} {824 8815} {837 8071} {837 8107} {824 8654} \
+ {772 479} {775 7784} {776 1269} {824 8837}]
+
+set compSecondList [list \
+ {3545 3548} {3545 3550} {3398 3404} {2503 2507} {2503 2508} \
+ {2887 2891} {2887 2888} {2887 2892} {3270 3274} {3270 3272} \
+ {1575 1570} {1575 1573}]
+
+#
+# Compositions matrix
+#
+
+array unset compBothMap
+array set compBothMap [list \
+ 0 8179 1 8060 2 974 4 8032 6 8033 18 8182 145 204 146 205 147 206 149 296 \
+ 151 298 152 300 154 304 155 207 156 7880 157 463 158 520 159 522 160 7882 \
+ 161 302 163 7724 288 8115 289 8048 290 940 292 7936 294 7937 295 8113 \
+ 296 8112 306 8118 441 3546 577 8157 578 8158 594 8159 721 7873 722 7871 \
+ 725 7877 732 7875 865 7846 866 7844 869 7850 876 7848 1008 8131 1009 8052 \
+ 1010 942 1012 7968 1014 7969 1026 8134 1153 8154 1154 906 1156 7992 \
+ 1158 7993 1159 8153 1160 8152 1163 938 1297 7962 1298 7964 1443 293 \
+ 1450 7715 1451 7719 1453 543 1456 7717 1460 7721 1461 7723 1463 7830 \
+ 1585 7986 1586 7988 1602 7990 1729 504 1730 323 1733 209 1738 7748 1741 327 \
+ 1744 7750 1748 325 1750 7754 1751 7752 1873 8002 1874 8004 2024 1217 \
+ 2027 1244 2161 505 2162 324 2165 241 2170 7749 2173 328 2176 7751 2180 326 \
+ 2182 7755 2183 7753 2306 7743 2314 7745 2320 7747 2458 7786 2461 356 \
+ 2464 7788 2468 354 2470 7792 2471 7790 2473 538 2593 7701 2594 7703 \
+ 2760 3402 2882 7757 2887 557 2891 7759 3024 8105 3025 8043 3026 8045 \
+ 3042 8047 3170 347 3171 349 3178 7777 3181 353 3184 7779 3188 351 3193 537 \
+ 3313 7922 3314 221 3315 374 3317 7928 3319 562 3322 7822 3323 376 3324 7926 \
+ 3328 7924 3458 377 3459 7824 3466 379 3469 381 3472 7826 3479 7828 3603 7853 \
+ 3608 7863 3744 8188 3745 8186 3746 911 3748 8040 3750 8041 3888 8088 \
+ 3889 7978 3890 7980 3906 7982 4033 7923 4034 253 4035 375 4037 7929 \
+ 4039 563 4042 7823 4043 255 4044 7927 4048 7925 4058 7833 4177 8018 \
+ 4178 8020 4194 8022 4321 192 4322 193 4323 194 4325 195 4327 256 4328 258 \
+ 4330 550 4331 196 4332 7842 4333 461 4334 512 4335 514 4336 7840 4337 260 \
+ 4346 197 4349 7680 4491 12499 4492 12500 4609 7847 4610 7845 4613 7851 \
+ 4620 7849 4753 7915 4754 7913 4757 7919 4764 7917 4768 7921 4896 8124 \
+ 4897 8122 4898 902 4900 7944 4902 7945 4903 8121 4904 8120 5067 12508 \
+ 5068 12509 5185 7954 5186 7956 5329 7760 5330 7762 5474 500 5475 284 \
+ 5479 7712 5480 286 5482 288 5485 486 5492 290 5618 979 5627 980 5761 8141 \
+ 5762 8142 5778 8143 5931 12496 5932 12497 6049 7872 6050 7870 6053 7876 \
+ 6060 7874 6219 12505 6220 12506 6338 313 6349 317 6352 7734 6356 315 \
+ 6358 7740 6359 7738 6481 7995 6482 7997 6498 7999 6624 8097 6625 8035 \
+ 6626 8037 6642 8039 6770 7729 6781 489 6784 7731 6788 311 6791 7733 \
+ 6914 340 6922 7768 6925 344 6926 528 6927 530 6928 7770 6932 342 6935 7774 \
+ 7083 12502 7084 12503 7202 7756 7207 556 7211 7758 7345 8056 7346 972 \
+ 7348 8000 7350 8001 7489 1117 7495 1251 7496 1081 7499 1253 7632 8080 \
+ 7633 7970 7634 7972 7650 7974 7777 7808 7778 7810 7779 372 7786 7814 \
+ 7787 7812 7792 7816 7921 8010 7922 8012 8065 8058 8066 973 8068 8016 \
+ 8070 8017 8071 8161 8072 8160 8075 971 8082 8166 8235 12412 8236 12413 \
+ 8352 8072 8353 7946 8354 7948 8370 7950 8501 7805 8512 7807 8667 12400 \
+ 8668 12401 8811 12409 8812 12410 8929 8162 8930 944 8946 8167 9079 1263 \
+ 9080 1118 9083 1265 9102 1267 9226 7683 9232 7685 9239 7687 9370 7690 \
+ 9373 270 9376 7692 9380 7696 9382 7698 9383 7694 9505 7857 9506 7855 \
+ 9509 7861 9516 7859 9650 509 9655 483 9819 12406 9820 12407 9937 7987 \
+ 9938 7989 9954 7991 10081 8027 10082 8029 10098 8031 10234 7691 10237 271 \
+ 10240 7693 10244 7697 10246 7699 10247 7695 10376 1233 10379 1235 10513 7963 \
+ 10514 7965 10683 12403 10684 12404 10801 236 10802 237 10803 238 10805 297 \
+ 10807 299 10808 301 10811 239 10812 7881 10813 464 10814 521 10815 523 \
+ 10816 7883 10817 303 10819 7725 10945 210 10946 211 10947 212 10949 213 \
+ 10951 332 10952 334 10954 558 10955 214 10956 7886 10957 465 10958 524 \
+ 10959 526 10960 7884 10961 490 10974 336 10975 416 11090 7764 11098 7766 \
+ 11233 8003 11234 8005 11377 1104 11384 1239 11387 1105 11521 8184 11522 908 \
+ 11524 8008 11526 8009 11665 7900 11666 7898 11669 7904 11676 7902 11680 7906 \
+ 11808 8064 11809 7938 11810 7940 11826 7942 11953 242 11954 243 11955 244 \
+ 11957 245 11959 333 11960 335 11962 559 11963 246 11964 7887 11965 466 \
+ 11966 525 11967 527 11968 7885 11969 491 11982 337 11983 417 12097 217 \
+ 12098 218 12099 219 12101 360 12103 362 12104 364 12107 220 12108 7910 \
+ 12109 467 12110 532 12111 534 12112 7908 12113 370 12115 7796 12118 7798 \
+ 12122 366 12126 368 12127 431 12128 7794 12241 8170 12242 910 12246 8025 \
+ 12247 8169 12248 8168 12251 939 12394 7787 12395 7831 12397 357 12400 7789 \
+ 12404 355 12406 7793 12407 7791 12409 539 12529 476 12530 472 12535 470 \
+ 12541 474 12672 8089 12673 7979 12674 7981 12690 7983 12818 378 12819 7825 \
+ 12826 380 12829 382 12832 7827 12839 7829 12961 8019 12962 8021 12978 8023 \
+ 13114 7682 13120 7684 13127 7686 13249 7955 13250 7957 13393 7761 13394 7763 \
+ 13539 292 13546 7714 13547 7718 13549 542 13552 7716 13556 7720 13557 7722 \
+ 13681 8050 13682 941 13684 7952 13686 7953 13824 8140 13825 8138 13826 905 \
+ 13828 7976 13830 7977 13976 1232 13979 1234 14145 3018 14146 3020 14258 501 \
+ 14259 285 14263 7713 14264 287 14266 289 14269 487 14276 291 14402 7742 \
+ 14410 7744 14416 7746 14546 508 14551 482 14689 8173 14690 901 14706 8129 \
+ 14833 1024 14840 1238 14843 1025 14978 314 14989 318 14992 7735 14996 316 \
+ 14998 7741 14999 7739 15122 346 15123 348 15130 7776 15133 352 15136 7778 \
+ 15140 350 15145 536 15265 7700 15266 7702 15409 7891 15410 7889 15413 7895 \
+ 15420 7893 15552 8081 15553 7971 15554 7973 15570 7975 15696 8104 15697 8042 \
+ 15698 8044 15714 8046 15842 341 15850 7769 15853 345 15854 529 15855 531 \
+ 15856 7771 15860 343 15863 7775 15988 8164 15990 8165 16129 8011 16130 8013 \
+ 16282 7818 16283 7820 16419 7852 16424 7862 16561 475 16562 471 16567 469 \
+ 16573 473 16704 8073 16705 7947 16706 7949 16722 7951 16849 7809 16850 7811 \
+ 16851 373 16858 7815 16859 7813 16864 7817 16874 7832 17002 7819 17003 7821 \
+ 17137 7914 17138 7912 17141 7918 17148 7916 17152 7920 17282 263 17283 265 \
+ 17290 267 17293 269 17300 231 17425 200 17426 201 17427 202 17429 7868 \
+ 17431 274 17432 276 17434 278 17435 203 17436 7866 17437 282 17438 516 \
+ 17439 518 17440 7864 17441 280 17443 7706 17444 552 17446 7704 17569 8136 \
+ 17570 904 17572 7960 17574 7961 17713 232 17714 233 17715 234 17717 7869 \
+ 17719 275 17720 277 17722 279 17723 235 17724 7867 17725 283 17726 517 \
+ 17727 519 17728 7865 17729 281 17731 7707 17732 553 17734 7705 17858 7728 \
+ 17869 488 17872 7730 17876 310 17879 7732 18001 8054 18002 943 18004 7984 \
+ 18006 7985 18007 8145 18008 8144 18011 970 18018 8150 18145 7994 18146 7996 \
+ 18162 7998 18323 3271 18432 8096 18433 8034 18434 8036 18450 8038 18579 309 \
+ 18589 496 18721 7890 18722 7888 18725 7894 18732 7892 18865 7901 18866 7899 \
+ 18869 7905 18876 7903 18880 7907 19009 1037 19015 1250 19016 1049 19019 1252 \
+ 19160 1218 19163 1245 19296 8065 19297 7939 19298 7941 19314 7943 19442 7765 \
+ 19450 7767 19589 7804 19600 7806 19729 249 19730 250 19731 251 19733 361 \
+ 19735 363 19736 365 19739 252 19740 7911 19741 468 19742 533 19743 535 \
+ 19744 7909 19745 371 19747 7797 19750 7799 19754 367 19758 369 19759 432 \
+ 19760 7795 19873 8146 19874 912 19890 8151 20023 1262 20024 1038 20027 1264 \
+ 20046 1266 20161 224 20162 225 20163 226 20165 227 20167 257 20168 259 \
+ 20170 551 20171 228 20172 7843 20173 462 20174 513 20175 515 20176 7841 \
+ 20177 261 20186 229 20189 7681 20306 262 20307 264 20314 266 20317 268 \
+ 20324 199 20449 7856 20450 7854 20453 7860 20460 7858 20628 1571]
+
+
+proc GetUniCharCompInfo {uc} {
+ variable COMP_OFFSET_BITS
+ variable COMP_COMMON_PAGE_MAP
+ variable compPageMap
+ variable compGroupMap
+
+ set page [expr {($uc & 0x1fffff) >> $COMP_OFFSET_BITS}]
+ if {[info exists compPageMap($page)]} {
+ set apage $compPageMap($page)
+ } else {
+ set apage $COMP_COMMON_PAGE_MAP
+ }
+
+ lindex $compGroupMap \
+ [expr {($apage << $COMP_OFFSET_BITS) | \
+ ($uc & ((1 << $COMP_OFFSET_BITS) - 1))}]
+}
+
+set COMP_SINGLE_MASK 65536
+set COMP_SECOND_MASK 131072
+set COMP_MASK 65535
+set COMP_LENGTH1 144
+
+proc GetCompFirst {uc info} {
+ variable COMP_SINGLE_MASK
+ variable COMP_SECOND_MASK
+ variable COMP_MASK
+ variable compFirstList
+
+ if {$info == -1 || !($info & $COMP_SINGLE_MASK)} {
+ return -1
+ }
+ if {!($info & $COMP_SECOND_MASK)} {
+ set comp [lindex $compFirstList [expr {$info & $COMP_MASK}]]
+ if {$uc == [lindex $comp 0]} {
+ return [lindex $comp 1]
+ }
+ }
+ return 0
+}
+
+proc GetCompSecond {uc info} {
+ variable COMP_SINGLE_MASK
+ variable COMP_SECOND_MASK
+ variable COMP_MASK
+ variable compSecondList
+
+ if {$info == -1 || !($info & $COMP_SINGLE_MASK)} {
+ return -1
+ }
+ if {$info & $COMP_SECOND_MASK} {
+ set comp [lindex $compSecondList [expr {$info & $COMP_MASK}]]
+ if {$uc == [lindex $comp 0]} {
+ return [lindex $comp 1]
+ }
+ }
+ return 0
+}
+
+proc GetCompBoth {info1 info2} {
+ variable COMP_SECOND_MASK
+ variable COMP_MASK
+ variable COMP_LENGTH1
+ variable compBothMap
+
+ if {$info1 != -1 && $info2 != -1 && !($info1 & $COMP_SECOND_MASK) && ($info2 & $COMP_SECOND_MASK)} {
+ set idx [expr {$COMP_LENGTH1 * $info1 + ($info2 & $COMP_MASK)}]
+ if {[info exists compBothMap($idx)]} {
+ return $compBothMap($idx)
+ } else {
+ return 0
+ }
+ } else {
+ return 0
+ }
+}
+
+} ; # namespace eval ::unicode::data
+