From 9929c0aaf53562e2b5aaad1f7dacdcde351accf2 Mon Sep 17 00:00:00 2001 From: nick evans Date: Fri, 15 Dec 2023 12:13:59 -0500 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Refactor=20stringprep=20ta?= =?UTF-8?q?ble=20generation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tables are now generated into one table per file. By using autoload, this avoids needing to load *all* of the tables to access only one. Also, PROHIBIT regexps combining all of the prohibited tables have been compiled for the "SASLprep", "nameprep", and "trace" profiles (previously, only "SASLprep" had its own combined PROHIBIT regexp). --- lib/net/imap/sasl/anonymous_authenticator.rb | 2 +- lib/net/imap/stringprep.rb | 29 +- lib/net/imap/stringprep/saslprep.rb | 124 ++++- .../imap/stringprep/saslprep/prohibited.rb | 22 + lib/net/imap/stringprep/tables.rb | 171 ++---- .../imap/stringprep/tables/bidi_desc_req2.rb | 13 + .../imap/stringprep/tables/bidi_desc_req3.rb | 13 + .../imap/stringprep/tables/bidi_fails_req2.rb | 17 + .../imap/stringprep/tables/bidi_fails_req3.rb | 18 + .../bidi_failure.rb} | 86 +-- lib/net/imap/stringprep/tables/in_a_1.rb | 14 + lib/net/imap/stringprep/tables/in_b_1.rb | 14 + lib/net/imap/stringprep/tables/in_b_2.rb | 14 + lib/net/imap/stringprep/tables/in_b_3.rb | 14 + lib/net/imap/stringprep/tables/in_c_1_1.rb | 14 + lib/net/imap/stringprep/tables/in_c_1_2.rb | 14 + lib/net/imap/stringprep/tables/in_c_2_1.rb | 14 + lib/net/imap/stringprep/tables/in_c_2_2.rb | 14 + lib/net/imap/stringprep/tables/in_c_3.rb | 14 + lib/net/imap/stringprep/tables/in_c_4.rb | 14 + lib/net/imap/stringprep/tables/in_c_5.rb | 14 + lib/net/imap/stringprep/tables/in_c_6.rb | 14 + lib/net/imap/stringprep/tables/in_c_7.rb | 14 + lib/net/imap/stringprep/tables/in_c_8.rb | 14 + lib/net/imap/stringprep/tables/in_c_9.rb | 14 + lib/net/imap/stringprep/tables/in_d_1.rb | 14 + .../imap/stringprep/tables/in_d_1_negated.rb | 14 + lib/net/imap/stringprep/tables/in_d_2.rb | 14 + lib/net/imap/stringprep/tables/map_b_1.rb | 14 + lib/net/imap/stringprep/tables/map_b_2.rb | 14 + lib/net/imap/stringprep/tables/map_b_3.rb | 14 + lib/net/imap/stringprep/tables/mappings.rb | 18 + .../stringprep/tables/nameprep_prohibit.rb | 15 + .../tables/nameprep_prohibit_stored.rb | 16 + lib/net/imap/stringprep/tables/regexps.rb | 32 ++ .../stringprep/tables/saslprep_prohibit.rb | 15 + .../tables/saslprep_prohibit_stored.rb | 16 + lib/net/imap/stringprep/tables/titles.rb | 34 ++ .../imap/stringprep/tables/trace_prohibit.rb | 15 + .../tables/trace_prohibit_stored.rb | 16 + rakelib/rfc3454_table_parser.rb | 89 ++++ rakelib/saslprep.rake | 30 -- rakelib/string_prep_tables_generator.rb | 503 +++++++----------- rakelib/stringprep.rake | 37 ++ rakelib/stringprep_table_transformer.rb | 59 ++ test/net/imap/test_imap_authenticators.rb | 4 +- test/net/imap/test_regexps.rb | 9 + test/net/imap/test_saslprep.rb | 1 + test/net/imap/test_stringprep_tables.rb | 6 +- 49 files changed, 1101 insertions(+), 603 deletions(-) create mode 100644 lib/net/imap/stringprep/saslprep/prohibited.rb create mode 100644 lib/net/imap/stringprep/tables/bidi_desc_req2.rb create mode 100644 lib/net/imap/stringprep/tables/bidi_desc_req3.rb create mode 100644 lib/net/imap/stringprep/tables/bidi_fails_req2.rb create mode 100644 lib/net/imap/stringprep/tables/bidi_fails_req3.rb rename lib/net/imap/stringprep/{saslprep_tables.rb => tables/bidi_failure.rb} (78%) create mode 100644 lib/net/imap/stringprep/tables/in_a_1.rb create mode 100644 lib/net/imap/stringprep/tables/in_b_1.rb create mode 100644 lib/net/imap/stringprep/tables/in_b_2.rb create mode 100644 lib/net/imap/stringprep/tables/in_b_3.rb create mode 100644 lib/net/imap/stringprep/tables/in_c_1_1.rb create mode 100644 lib/net/imap/stringprep/tables/in_c_1_2.rb create mode 100644 lib/net/imap/stringprep/tables/in_c_2_1.rb create mode 100644 lib/net/imap/stringprep/tables/in_c_2_2.rb create mode 100644 lib/net/imap/stringprep/tables/in_c_3.rb create mode 100644 lib/net/imap/stringprep/tables/in_c_4.rb create mode 100644 lib/net/imap/stringprep/tables/in_c_5.rb create mode 100644 lib/net/imap/stringprep/tables/in_c_6.rb create mode 100644 lib/net/imap/stringprep/tables/in_c_7.rb create mode 100644 lib/net/imap/stringprep/tables/in_c_8.rb create mode 100644 lib/net/imap/stringprep/tables/in_c_9.rb create mode 100644 lib/net/imap/stringprep/tables/in_d_1.rb create mode 100644 lib/net/imap/stringprep/tables/in_d_1_negated.rb create mode 100644 lib/net/imap/stringprep/tables/in_d_2.rb create mode 100644 lib/net/imap/stringprep/tables/map_b_1.rb create mode 100644 lib/net/imap/stringprep/tables/map_b_2.rb create mode 100644 lib/net/imap/stringprep/tables/map_b_3.rb create mode 100644 lib/net/imap/stringprep/tables/mappings.rb create mode 100644 lib/net/imap/stringprep/tables/nameprep_prohibit.rb create mode 100644 lib/net/imap/stringprep/tables/nameprep_prohibit_stored.rb create mode 100644 lib/net/imap/stringprep/tables/regexps.rb create mode 100644 lib/net/imap/stringprep/tables/saslprep_prohibit.rb create mode 100644 lib/net/imap/stringprep/tables/saslprep_prohibit_stored.rb create mode 100644 lib/net/imap/stringprep/tables/titles.rb create mode 100644 lib/net/imap/stringprep/tables/trace_prohibit.rb create mode 100644 lib/net/imap/stringprep/tables/trace_prohibit_stored.rb create mode 100644 rakelib/rfc3454_table_parser.rb delete mode 100644 rakelib/saslprep.rake create mode 100644 rakelib/stringprep.rake create mode 100644 rakelib/stringprep_table_transformer.rb diff --git a/lib/net/imap/sasl/anonymous_authenticator.rb b/lib/net/imap/sasl/anonymous_authenticator.rb index aa4ecae4..ba0cbed0 100644 --- a/lib/net/imap/sasl/anonymous_authenticator.rb +++ b/lib/net/imap/sasl/anonymous_authenticator.rb @@ -36,7 +36,7 @@ class AnonymousAuthenticator # Any other keyword arguments are silently ignored. def initialize(anon_msg = nil, anonymous_message: nil, **) message = (anonymous_message || anon_msg || "").to_str - @anonymous_message = StringPrep::Trace.stringprep_trace message + @anonymous_message = IMAP::StringPrep::Trace.stringprep_trace message if (size = @anonymous_message&.length)&.> 255 raise ArgumentError, "anonymous_message is too long. (%d codepoints)" % [size] diff --git a/lib/net/imap/stringprep.rb b/lib/net/imap/stringprep.rb index c18e1dd7..1324cbbb 100644 --- a/lib/net/imap/stringprep.rb +++ b/lib/net/imap/stringprep.rb @@ -73,34 +73,35 @@ def self.[](table) # The above steps MUST be performed in the order given to comply with # this specification. # - def stringprep(string, - maps:, - normalization:, - prohibited:, - **opts) + def stringprep(string, maps:, normalization:, prohibited:, **opts) string = string.encode("UTF-8") # also dups (and raises invalid encoding) - map_tables!(string, *maps) if maps + map!(string, maps) if maps&.any? string.unicode_normalize!(normalization) if normalization check_prohibited!(string, *prohibited, **opts) if prohibited string end - def map_tables!(string, *tables) - tables.each do |table| - regexp, replacements = Tables::MAPPINGS.fetch(table) - string.gsub!(regexp, replacements) + def map!(string, mappings) + mappings.each do |mapping| + mapping = Tables::MAPPINGS.fetch(mapping) if mapping.is_a?(String) + string.gsub!(*mapping) end string end + def map_tables!(string, *tables) + warn "map_tables! is deprecated. Use map! instead." + map!(string, tables.map { Tables::MAPPINGS.fetch(table) }) + end + # Checks +string+ for any codepoint in +tables+. Raises a # ProhibitedCodepoint describing the first matching table. # - # Also checks bidirectional characters, when bidi: true, which may - # raise a BidiStringError. + # Also checks bidirectional characters, when bidi: true, which + # may raise a BidiStringError. # - # +profile+ is an optional string which will be added to any exception that - # is raised (it does not affect behavior). + # +profile+ is an optional string which will be added to any exception + # that is raised (it does not affect behavior). def check_prohibited!(string, *tables, bidi: false, diff --git a/lib/net/imap/stringprep/saslprep.rb b/lib/net/imap/stringprep/saslprep.rb index ae95fb81..886ab27e 100644 --- a/lib/net/imap/stringprep/saslprep.rb +++ b/lib/net/imap/stringprep/saslprep.rb @@ -4,60 +4,126 @@ module Net class IMAP module StringPrep - # SASLprep#saslprep can be used to prepare a string according to [RFC4013]. + # SASLprep#saslprep can be used to prepare a string according to + # RFC4013[https://tools.ietf.org/html/rfc4013]. # # \SASLprep maps characters three ways: to nothing, to space, and Unicode # normalization form KC. \SASLprep prohibits codepoints from nearly all - # standard StringPrep tables (RFC3454, Appendix "C"), and uses + # standard StringPrep tables + # (RFC3454[https://tools.ietf.org/html/rfc3454], Appendix "C"), and uses # \StringPrep's standard bidirectional characters requirements (Appendix # "D"). \SASLprep also uses \StringPrep's definition of "Unassigned" # codepoints (Appendix "A"). module SASLprep + # Avoid loading these tables unless they are needed (for non-ASCII). + autoload :PROHIBITED_OUTPUT, "#{__dir__}/saslprep/prohibited.rb" + autoload :PROHIBITED_OUTPUT_STORED, "#{__dir__}/saslprep/prohibited.rb" + autoload :PROHIBITED, "#{__dir__}/saslprep/prohibited.rb" + autoload :PROHIBITED_STORED, "#{__dir__}/saslprep/prohibited.rb" + + # Defined in RFC4013[https://tools.ietf.org/html/rfc4013]. + STRINGPREP_PROFILE = "SASLprep" # Used to short-circuit strings that don't need preparation. ASCII_NO_CTRLS = /\A[\x20-\x7e]*\z/u.freeze - # Avoid loading these tables unless they are needed (they are only - # needed for non-ASCII). - saslprep_tables = File.expand_path("saslprep_tables", __dir__) - autoload :MAP_TO_NOTHING, saslprep_tables - autoload :MAP_TO_SPACE, saslprep_tables - autoload :PROHIBITED, saslprep_tables - autoload :PROHIBITED_STORED, saslprep_tables - autoload :TABLES_PROHIBITED, saslprep_tables - autoload :TABLES_PROHIBITED_STORED, saslprep_tables + # Regexp for RFC4013[https://tools.ietf.org/html/rfc4013] §2.1 Mapping - + # mapped to space + MAP_TO_SPACE = Tables::IN_C_1_2 + + # Regexp for RFC4013[https://tools.ietf.org/html/rfc4013] §2.1 Mapping - + # mapped to nothing + MAP_TO_NOTHING = Tables::IN_B_1 + + # RFC4013[https://tools.ietf.org/html/rfc4013] §2.1 Mapping + # >>> + # This profile specifies: + # - non-ASCII space characters (\StringPrep\[\"C.1.2\"]) that can + # be mapped to SPACE (U+0020) + # - the "commonly mapped to nothing" characters + # (\StringPrep\[\"B.1\"]) that can be mapped to nothing. + MAPPINGS = { + MAP_TO_SPACE => " ", + MAP_TO_NOTHING => "", + }.freeze + + # RFC4013[https://tools.ietf.org/html/rfc4013] §2.2 Normalization + # >>> + # This profile specifies using Unicode normalization form KC, as + # described in Section 4 of [StringPrep]. + NORMALIZATION = :nfkc + + # RFC4013[https://tools.ietf.org/html/rfc4013] §2.3 Prohibited Output + # >>> + # * Non-ASCII space characters — \StringPrep\[\"C.1.2\"] + # * ASCII control characters — \StringPrep\[\"C.2.1\"] + # * Non-ASCII control characters — \StringPrep\[\"C.2.2\"] + # * Private Use characters — \StringPrep\[\"C.3\"] + # * Non-character code points — \StringPrep\[\"C.4\"] + # * Surrogate code points — \StringPrep\[\"C.5\"] + # * Inappropriate for plain text characters — \StringPrep\[\"C.6\"] + # * Inappropriate for canonical representation characters — \StringPrep\[\"C.7\"] + # * Change display properties or deprecated characters — \StringPrep\[\"C.8\"] + # * Tagging characters — \StringPrep\[\"C.9\"] + PROHIBITED_TABLES = %w[C.1.2 C.2.1 C.2.2 C.3 C.4 C.5 C.6 C.7 C.8 C.9] + .freeze + + # RFC4013[https://tools.ietf.org/html/rfc4013] §2.4 Bidirectional + # Characters + # >>> + # This profile specifies checking bidirectional strings as described + # in [StringPrep, Section 6]. + CHECK_BIDI = true + + # RFC4013[https://tools.ietf.org/html/rfc4013] §2.5 Unassigned Code + # Points + # >>> + # This profile specifies the \StringPrep\[\"A.1\"] table as its + # list of unassigned code points. + UNASSIGNED_TABLE = "A.1" + + # :nodoc: + UNASSIGNED = Tables::IN_A_1 + deprecate_constant :UNASSIGNED module_function # Prepares a UTF-8 +string+ for comparison, using the \SASLprep profile - # RFC4013 of the StringPrep algorithm RFC3454. + # {[RFC4013]}[https://tools.ietf.org/html/rfc4013] of the StringPrep + # algorithm {[RFC3454]}[https://tools.ietf.org/html/rfc3454]. # # By default, prohibited strings will return +nil+. When +exception+ is # +true+, a StringPrepError describing the violation will be raised. # # When +stored+ is +true+, "unassigned" codepoints will be prohibited. # For \StringPrep and the \SASLprep profile, "unassigned" refers to - # Unicode 3.2, and not later versions. See RFC3454 §7 for more + # Unicode 3.2, and not later versions. See RFC3454[https://tools.ietf.org/html/rfc3454] §7 for more # information. - def saslprep(str, stored: false, exception: false) - return str if ASCII_NO_CTRLS.match?(str) # incompatible encoding raises - str = str.encode("UTF-8") # also dups (and raises for invalid encoding) - str.gsub!(MAP_TO_SPACE, " ") - str.gsub!(MAP_TO_NOTHING, "") - str.unicode_normalize!(:nfkc) - # These regexps combine the prohibited and bidirectional checks - return str unless str.match?(stored ? PROHIBITED_STORED : PROHIBITED) - return nil unless exception - # raise helpful errors to indicate *why* it failed: - tables = stored ? TABLES_PROHIBITED_STORED : TABLES_PROHIBITED - StringPrep.check_prohibited! str, *tables, bidi: true, profile: "SASLprep" - raise InvalidStringError.new( - "unknown error", string: string, profile: "SASLprep" - ) + def saslprep(original, stored: false, exception: false) + return original if ASCII_NO_CTRLS.match?(original) # incompatible encoding raises + if exception + StringPrep.stringprep( + original, + unassigned: UNASSIGNED_TABLE, + maps: MAPPINGS, + prohibited: PROHIBITED_TABLES, + normalization: NORMALIZATION, + bidi: CHECK_BIDI, + stored: stored, + profile: STRINGPREP_PROFILE, + ) + else + str = original.encode("UTF-8") # also dups (and raises for invalid encoding) + str.gsub!(MAP_TO_SPACE, " ") + str.gsub!(MAP_TO_NOTHING, "") + str.unicode_normalize!(:nfkc) + str unless str.match?(stored ? PROHIBITED_STORED : PROHIBITED) + end rescue ArgumentError, Encoding::CompatibilityError => ex if /invalid byte sequence|incompatible encoding/.match? ex.message return nil unless exception - raise StringPrepError.new(ex.message, string: str, profile: "saslprep") + raise StringPrepError.new(ex.message, string: str, + profile: STRINGPREP_PROFILE) end raise ex end diff --git a/lib/net/imap/stringprep/saslprep/prohibited.rb b/lib/net/imap/stringprep/saslprep/prohibited.rb new file mode 100644 index 00000000..f8e86fc4 --- /dev/null +++ b/lib/net/imap/stringprep/saslprep/prohibited.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module Net::IMAP::StringPrep + + module SASLprep + + # :nodoc: + PROHIBITED_OUTPUT = Tables::SASLPREP_PROHIBIT + + # :nodoc: + PROHIBITED_OUTPUT_STORED = Tables::SASLPREP_PROHIBIT_STORED + + # :nodoc: + PROHIBITED = Regexp.union(PROHIBITED_OUTPUT, Tables::BIDI_FAILURE) + + # :nodoc: + PROHIBITED_STORED = Regexp.union( + PROHIBITED_OUTPUT_STORED, Tables::BIDI_FAILURE, + ) + + end +end diff --git a/lib/net/imap/stringprep/tables.rb b/lib/net/imap/stringprep/tables.rb index 0edeabdd..57a61e76 100644 --- a/lib/net/imap/stringprep/tables.rb +++ b/lib/net/imap/stringprep/tables.rb @@ -1,146 +1,47 @@ # frozen_string_literal: true #-- -# This file is generated from RFC3454, by rake. Don't edit directly. +# This file is generated by `rake stringprep:tables`. Don't edit directly. #++ module Net::IMAP::StringPrep - module Tables - # Unassigned code points in Unicode 3.2 \StringPrep\[\"A.1\"] - IN_A_1 = /\p{^AGE=3.2}/.freeze - - # Commonly mapped to nothing \StringPrep\[\"B.1\"] - IN_B_1 = /[\u{00ad 034f 1806 2060 feff}\u{180b}-\u{180d}\u{200b}-\u{200d}\u{fe00}-\u{fe0f}]/.freeze - - # Mapping for case-folding used with NFKC \StringPrep\[\"B.2\"] - IN_B_2 = /[\u{00b5 0100 0102 0104 0106 0108 010a 010c 010e 0110 0112 0114 0116 0118 011a 011c 011e 0120 0122 0124 0126 0128 012a 012c 012e 0130 0132 0134 0136 0139 013b 013d 013f 0141 0143 0145 0147 014c 014e 0150 0152 0154 0156 0158 015a 015c 015e 0160 0162 0164 0166 0168 016a 016c 016e 0170 0172 0174 0176 017b 017d 017f 0184 01a2 01a4 01a9 01ac 01b5 01bc 01cd 01cf 01d1 01d3 01d5 01d7 01d9 01db 01de 01e0 01e2 01e4 01e6 01e8 01ea 01ec 01ee 01f4 01fa 01fc 01fe 0200 0202 0204 0206 0208 020a 020c 020e 0210 0212 0214 0216 0218 021a 021c 021e 0220 0222 0224 0226 0228 022a 022c 022e 0230 0232 0345 037a 0386 038c 03b0 03c2 03d8 03da 03dc 03de 03e0 03e2 03e4 03e6 03e8 03ea 03ec 03ee 0460 0462 0464 0466 0468 046a 046c 046e 0470 0472 0474 0476 0478 047a 047c 047e 0480 048a 048c 048e 0490 0492 0494 0496 0498 049a 049c 049e 04a0 04a2 04a4 04a6 04a8 04aa 04ac 04ae 04b0 04b2 04b4 04b6 04b8 04ba 04bc 04be 04c1 04c3 04c5 04c7 04c9 04cb 04cd 04d0 04d2 04d4 04d6 04d8 04da 04dc 04de 04e0 04e2 04e4 04e6 04e8 04ea 04ec 04ee 04f0 04f2 04f4 04f8 0500 0502 0504 0506 0508 050a 050c 050e 0587 1e00 1e02 1e04 1e06 1e08 1e0a 1e0c 1e0e 1e10 1e12 1e14 1e16 1e18 1e1a 1e1c 1e1e 1e20 1e22 1e24 1e26 1e28 1e2a 1e2c 1e2e 1e30 1e32 1e34 1e36 1e38 1e3a 1e3c 1e3e 1e40 1e42 1e44 1e46 1e48 1e4a 1e4c 1e4e 1e50 1e52 1e54 1e56 1e58 1e5a 1e5c 1e5e 1e60 1e62 1e64 1e66 1e68 1e6a 1e6c 1e6e 1e70 1e72 1e74 1e76 1e78 1e7a 1e7c 1e7e 1e80 1e82 1e84 1e86 1e88 1e8a 1e8c 1e8e 1e90 1e92 1e94 1ea0 1ea2 1ea4 1ea6 1ea8 1eaa 1eac 1eae 1eb0 1eb2 1eb4 1eb6 1eb8 1eba 1ebc 1ebe 1ec0 1ec2 1ec4 1ec6 1ec8 1eca 1ecc 1ece 1ed0 1ed2 1ed4 1ed6 1ed8 1eda 1edc 1ede 1ee0 1ee2 1ee4 1ee6 1ee8 1eea 1eec 1eee 1ef0 1ef2 1ef4 1ef6 1ef8 1f50 1f52 1f54 1f56 1f59 1f5b 1f5d 1f5f 1fbe 20a8 2107 2109 2124 2126 2128 2133 2145 3371 3373 3375 33c3 33cb 33d7 1d49c 1d4a2 1d546 1d6d3 1d70d 1d747 1d781 1d7bb}\u{0041}-\u{005a}\u{00c0}-\u{00d6}\u{00d8}-\u{00df}\u{0149}-\u{014a}\u{0178}-\u{0179}\u{0181}-\u{0182}\u{0186}-\u{0187}\u{0189}-\u{018b}\u{018e}-\u{0191}\u{0193}-\u{0194}\u{0196}-\u{0198}\u{019c}-\u{019d}\u{019f}-\u{01a0}\u{01a6}-\u{01a7}\u{01ae}-\u{01af}\u{01b1}-\u{01b3}\u{01b7}-\u{01b8}\u{01c4}-\u{01c5}\u{01c7}-\u{01c8}\u{01ca}-\u{01cb}\u{01f0}-\u{01f2}\u{01f6}-\u{01f8}\u{0388}-\u{038a}\u{038e}-\u{03a1}\u{03a3}-\u{03ab}\u{03d0}-\u{03d6}\u{03f0}-\u{03f2}\u{03f4}-\u{03f5}\u{0400}-\u{042f}\u{0531}-\u{0556}\u{1e96}-\u{1e9b}\u{1f08}-\u{1f0f}\u{1f18}-\u{1f1d}\u{1f28}-\u{1f2f}\u{1f38}-\u{1f3f}\u{1f48}-\u{1f4d}\u{1f68}-\u{1f6f}\u{1f80}-\u{1faf}\u{1fb2}-\u{1fb4}\u{1fb6}-\u{1fbc}\u{1fc2}-\u{1fc4}\u{1fc6}-\u{1fcc}\u{1fd2}-\u{1fd3}\u{1fd6}-\u{1fdb}\u{1fe2}-\u{1fe4}\u{1fe6}-\u{1fec}\u{1ff2}-\u{1ff4}\u{1ff6}-\u{1ffc}\u{2102}-\u{2103}\u{210b}-\u{210d}\u{2110}-\u{2112}\u{2115}-\u{2116}\u{2119}-\u{211d}\u{2120}-\u{2122}\u{212a}-\u{212d}\u{2130}-\u{2131}\u{213e}-\u{213f}\u{2160}-\u{216f}\u{24b6}-\u{24cf}\u{3380}-\u{3387}\u{338a}-\u{338c}\u{3390}-\u{3394}\u{33a9}-\u{33ac}\u{33b4}-\u{33c1}\u{33c6}-\u{33c9}\u{33cd}-\u{33ce}\u{33d9}-\u{33da}\u{33dc}-\u{33dd}\u{fb00}-\u{fb06}\u{fb13}-\u{fb17}\u{ff21}-\u{ff3a}\u{10400}-\u{10425}\u{1d400}-\u{1d419}\u{1d434}-\u{1d44d}\u{1d468}-\u{1d481}\u{1d49e}-\u{1d49f}\u{1d4a5}-\u{1d4a6}\u{1d4a9}-\u{1d4ac}\u{1d4ae}-\u{1d4b5}\u{1d4d0}-\u{1d4e9}\u{1d504}-\u{1d505}\u{1d507}-\u{1d50a}\u{1d50d}-\u{1d514}\u{1d516}-\u{1d51c}\u{1d538}-\u{1d539}\u{1d53b}-\u{1d53e}\u{1d540}-\u{1d544}\u{1d54a}-\u{1d550}\u{1d56c}-\u{1d585}\u{1d5a0}-\u{1d5b9}\u{1d5d4}-\u{1d5ed}\u{1d608}-\u{1d621}\u{1d63c}-\u{1d655}\u{1d670}-\u{1d689}\u{1d6a8}-\u{1d6c0}\u{1d6e2}-\u{1d6fa}\u{1d71c}-\u{1d734}\u{1d756}-\u{1d76e}\u{1d790}-\u{1d7a8}]/.freeze - - # Mapping for case-folding used with no normalization \StringPrep\[\"B.3\"] - IN_B_3 = /[\u{00b5 0100 0102 0104 0106 0108 010a 010c 010e 0110 0112 0114 0116 0118 011a 011c 011e 0120 0122 0124 0126 0128 012a 012c 012e 0130 0132 0134 0136 0139 013b 013d 013f 0141 0143 0145 0147 014c 014e 0150 0152 0154 0156 0158 015a 015c 015e 0160 0162 0164 0166 0168 016a 016c 016e 0170 0172 0174 0176 017b 017d 017f 0184 01a2 01a4 01a9 01ac 01b5 01bc 01cd 01cf 01d1 01d3 01d5 01d7 01d9 01db 01de 01e0 01e2 01e4 01e6 01e8 01ea 01ec 01ee 01f4 01fa 01fc 01fe 0200 0202 0204 0206 0208 020a 020c 020e 0210 0212 0214 0216 0218 021a 021c 021e 0220 0222 0224 0226 0228 022a 022c 022e 0230 0232 0345 0386 038c 03b0 03c2 03d8 03da 03dc 03de 03e0 03e2 03e4 03e6 03e8 03ea 03ec 03ee 0460 0462 0464 0466 0468 046a 046c 046e 0470 0472 0474 0476 0478 047a 047c 047e 0480 048a 048c 048e 0490 0492 0494 0496 0498 049a 049c 049e 04a0 04a2 04a4 04a6 04a8 04aa 04ac 04ae 04b0 04b2 04b4 04b6 04b8 04ba 04bc 04be 04c1 04c3 04c5 04c7 04c9 04cb 04cd 04d0 04d2 04d4 04d6 04d8 04da 04dc 04de 04e0 04e2 04e4 04e6 04e8 04ea 04ec 04ee 04f0 04f2 04f4 04f8 0500 0502 0504 0506 0508 050a 050c 050e 0587 1e00 1e02 1e04 1e06 1e08 1e0a 1e0c 1e0e 1e10 1e12 1e14 1e16 1e18 1e1a 1e1c 1e1e 1e20 1e22 1e24 1e26 1e28 1e2a 1e2c 1e2e 1e30 1e32 1e34 1e36 1e38 1e3a 1e3c 1e3e 1e40 1e42 1e44 1e46 1e48 1e4a 1e4c 1e4e 1e50 1e52 1e54 1e56 1e58 1e5a 1e5c 1e5e 1e60 1e62 1e64 1e66 1e68 1e6a 1e6c 1e6e 1e70 1e72 1e74 1e76 1e78 1e7a 1e7c 1e7e 1e80 1e82 1e84 1e86 1e88 1e8a 1e8c 1e8e 1e90 1e92 1e94 1ea0 1ea2 1ea4 1ea6 1ea8 1eaa 1eac 1eae 1eb0 1eb2 1eb4 1eb6 1eb8 1eba 1ebc 1ebe 1ec0 1ec2 1ec4 1ec6 1ec8 1eca 1ecc 1ece 1ed0 1ed2 1ed4 1ed6 1ed8 1eda 1edc 1ede 1ee0 1ee2 1ee4 1ee6 1ee8 1eea 1eec 1eee 1ef0 1ef2 1ef4 1ef6 1ef8 1f50 1f52 1f54 1f56 1f59 1f5b 1f5d 1f5f 1fbe 2126}\u{0041}-\u{005a}\u{00c0}-\u{00d6}\u{00d8}-\u{00df}\u{0149}-\u{014a}\u{0178}-\u{0179}\u{0181}-\u{0182}\u{0186}-\u{0187}\u{0189}-\u{018b}\u{018e}-\u{0191}\u{0193}-\u{0194}\u{0196}-\u{0198}\u{019c}-\u{019d}\u{019f}-\u{01a0}\u{01a6}-\u{01a7}\u{01ae}-\u{01af}\u{01b1}-\u{01b3}\u{01b7}-\u{01b8}\u{01c4}-\u{01c5}\u{01c7}-\u{01c8}\u{01ca}-\u{01cb}\u{01f0}-\u{01f2}\u{01f6}-\u{01f8}\u{0388}-\u{038a}\u{038e}-\u{03a1}\u{03a3}-\u{03ab}\u{03d0}-\u{03d1}\u{03d5}-\u{03d6}\u{03f0}-\u{03f2}\u{03f4}-\u{03f5}\u{0400}-\u{042f}\u{0531}-\u{0556}\u{1e96}-\u{1e9b}\u{1f08}-\u{1f0f}\u{1f18}-\u{1f1d}\u{1f28}-\u{1f2f}\u{1f38}-\u{1f3f}\u{1f48}-\u{1f4d}\u{1f68}-\u{1f6f}\u{1f80}-\u{1faf}\u{1fb2}-\u{1fb4}\u{1fb6}-\u{1fbc}\u{1fc2}-\u{1fc4}\u{1fc6}-\u{1fcc}\u{1fd2}-\u{1fd3}\u{1fd6}-\u{1fdb}\u{1fe2}-\u{1fe4}\u{1fe6}-\u{1fec}\u{1ff2}-\u{1ff4}\u{1ff6}-\u{1ffc}\u{212a}-\u{212b}\u{2160}-\u{216f}\u{24b6}-\u{24cf}\u{fb00}-\u{fb06}\u{fb13}-\u{fb17}\u{ff21}-\u{ff3a}\u{10400}-\u{10425}]/.freeze - - # Replacements for IN_B.1 - MAP_B_1 = "".freeze - - # Replacements for IN_B.2 - MAP_B_2 = {"A"=>"a", "B"=>"b", "C"=>"c", "D"=>"d", "E"=>"e", "F"=>"f", "G"=>"g", "H"=>"h", "I"=>"i", "J"=>"j", "K"=>"k", "L"=>"l", "M"=>"m", "N"=>"n", "O"=>"o", "P"=>"p", "Q"=>"q", "R"=>"r", "S"=>"s", "T"=>"t", "U"=>"u", "V"=>"v", "W"=>"w", "X"=>"x", "Y"=>"y", "Z"=>"z", "µ"=>"μ", "À"=>"à", "Á"=>"á", "Â"=>"â", "Ã"=>"ã", "Ä"=>"ä", "Å"=>"å", "Æ"=>"æ", "Ç"=>"ç", "È"=>"è", "É"=>"é", "Ê"=>"ê", "Ë"=>"ë", "Ì"=>"ì", "Í"=>"í", "Î"=>"î", "Ï"=>"ï", "Ð"=>"ð", "Ñ"=>"ñ", "Ò"=>"ò", "Ó"=>"ó", "Ô"=>"ô", "Õ"=>"õ", "Ö"=>"ö", "Ø"=>"ø", "Ù"=>"ù", "Ú"=>"ú", "Û"=>"û", "Ü"=>"ü", "Ý"=>"ý", "Þ"=>"þ", "ß"=>"ss", "Ā"=>"ā", "Ă"=>"ă", "Ą"=>"ą", "Ć"=>"ć", "Ĉ"=>"ĉ", "Ċ"=>"ċ", "Č"=>"č", "Ď"=>"ď", "Đ"=>"đ", "Ē"=>"ē", "Ĕ"=>"ĕ", "Ė"=>"ė", "Ę"=>"ę", "Ě"=>"ě", "Ĝ"=>"ĝ", "Ğ"=>"ğ", "Ġ"=>"ġ", "Ģ"=>"ģ", "Ĥ"=>"ĥ", "Ħ"=>"ħ", "Ĩ"=>"ĩ", "Ī"=>"ī", "Ĭ"=>"ĭ", "Į"=>"į", "İ"=>"i̇", "IJ"=>"ij", "Ĵ"=>"ĵ", "Ķ"=>"ķ", "Ĺ"=>"ĺ", "Ļ"=>"ļ", "Ľ"=>"ľ", "Ŀ"=>"ŀ", "Ł"=>"ł", "Ń"=>"ń", "Ņ"=>"ņ", "Ň"=>"ň", "ʼn"=>"ʼn", "Ŋ"=>"ŋ", "Ō"=>"ō", "Ŏ"=>"ŏ", "Ő"=>"ő", "Œ"=>"œ", "Ŕ"=>"ŕ", "Ŗ"=>"ŗ", "Ř"=>"ř", "Ś"=>"ś", "Ŝ"=>"ŝ", "Ş"=>"ş", "Š"=>"š", "Ţ"=>"ţ", "Ť"=>"ť", "Ŧ"=>"ŧ", "Ũ"=>"ũ", "Ū"=>"ū", "Ŭ"=>"ŭ", "Ů"=>"ů", "Ű"=>"ű", "Ų"=>"ų", "Ŵ"=>"ŵ", "Ŷ"=>"ŷ", "Ÿ"=>"ÿ", "Ź"=>"ź", "Ż"=>"ż", "Ž"=>"ž", "ſ"=>"s", "Ɓ"=>"ɓ", "Ƃ"=>"ƃ", "Ƅ"=>"ƅ", "Ɔ"=>"ɔ", "Ƈ"=>"ƈ", "Ɖ"=>"ɖ", "Ɗ"=>"ɗ", "Ƌ"=>"ƌ", "Ǝ"=>"ǝ", "Ə"=>"ə", "Ɛ"=>"ɛ", "Ƒ"=>"ƒ", "Ɠ"=>"ɠ", "Ɣ"=>"ɣ", "Ɩ"=>"ɩ", "Ɨ"=>"ɨ", "Ƙ"=>"ƙ", "Ɯ"=>"ɯ", "Ɲ"=>"ɲ", "Ɵ"=>"ɵ", "Ơ"=>"ơ", "Ƣ"=>"ƣ", "Ƥ"=>"ƥ", "Ʀ"=>"ʀ", "Ƨ"=>"ƨ", "Ʃ"=>"ʃ", "Ƭ"=>"ƭ", "Ʈ"=>"ʈ", "Ư"=>"ư", "Ʊ"=>"ʊ", "Ʋ"=>"ʋ", "Ƴ"=>"ƴ", "Ƶ"=>"ƶ", "Ʒ"=>"ʒ", "Ƹ"=>"ƹ", "Ƽ"=>"ƽ", "DŽ"=>"dž", "Dž"=>"dž", "LJ"=>"lj", "Lj"=>"lj", "NJ"=>"nj", "Nj"=>"nj", "Ǎ"=>"ǎ", "Ǐ"=>"ǐ", "Ǒ"=>"ǒ", "Ǔ"=>"ǔ", "Ǖ"=>"ǖ", "Ǘ"=>"ǘ", "Ǚ"=>"ǚ", "Ǜ"=>"ǜ", "Ǟ"=>"ǟ", "Ǡ"=>"ǡ", "Ǣ"=>"ǣ", "Ǥ"=>"ǥ", "Ǧ"=>"ǧ", "Ǩ"=>"ǩ", "Ǫ"=>"ǫ", "Ǭ"=>"ǭ", "Ǯ"=>"ǯ", "ǰ"=>"ǰ", "DZ"=>"dz", "Dz"=>"dz", "Ǵ"=>"ǵ", "Ƕ"=>"ƕ", "Ƿ"=>"ƿ", "Ǹ"=>"ǹ", "Ǻ"=>"ǻ", "Ǽ"=>"ǽ", "Ǿ"=>"ǿ", "Ȁ"=>"ȁ", "Ȃ"=>"ȃ", "Ȅ"=>"ȅ", "Ȇ"=>"ȇ", "Ȉ"=>"ȉ", "Ȋ"=>"ȋ", "Ȍ"=>"ȍ", "Ȏ"=>"ȏ", "Ȑ"=>"ȑ", "Ȓ"=>"ȓ", "Ȕ"=>"ȕ", "Ȗ"=>"ȗ", "Ș"=>"ș", "Ț"=>"ț", "Ȝ"=>"ȝ", "Ȟ"=>"ȟ", "Ƞ"=>"ƞ", "Ȣ"=>"ȣ", "Ȥ"=>"ȥ", "Ȧ"=>"ȧ", "Ȩ"=>"ȩ", "Ȫ"=>"ȫ", "Ȭ"=>"ȭ", "Ȯ"=>"ȯ", "Ȱ"=>"ȱ", "Ȳ"=>"ȳ", "ͅ"=>"ι", "ͺ"=>" ι", "Ά"=>"ά", "Έ"=>"έ", "Ή"=>"ή", "Ί"=>"ί", "Ό"=>"ό", "Ύ"=>"ύ", "Ώ"=>"ώ", "ΐ"=>"ΐ", "Α"=>"α", "Β"=>"β", "Γ"=>"γ", "Δ"=>"δ", "Ε"=>"ε", "Ζ"=>"ζ", "Η"=>"η", "Θ"=>"θ", "Ι"=>"ι", "Κ"=>"κ", "Λ"=>"λ", "Μ"=>"μ", "Ν"=>"ν", "Ξ"=>"ξ", "Ο"=>"ο", "Π"=>"π", "Ρ"=>"ρ", "Σ"=>"σ", "Τ"=>"τ", "Υ"=>"υ", "Φ"=>"φ", "Χ"=>"χ", "Ψ"=>"ψ", "Ω"=>"ω", "Ϊ"=>"ϊ", "Ϋ"=>"ϋ", "ΰ"=>"ΰ", "ς"=>"σ", "ϐ"=>"β", "ϑ"=>"θ", "ϒ"=>"υ", "ϓ"=>"ύ", "ϔ"=>"ϋ", "ϕ"=>"φ", "ϖ"=>"π", "Ϙ"=>"ϙ", "Ϛ"=>"ϛ", "Ϝ"=>"ϝ", "Ϟ"=>"ϟ", "Ϡ"=>"ϡ", "Ϣ"=>"ϣ", "Ϥ"=>"ϥ", "Ϧ"=>"ϧ", "Ϩ"=>"ϩ", "Ϫ"=>"ϫ", "Ϭ"=>"ϭ", "Ϯ"=>"ϯ", "ϰ"=>"κ", "ϱ"=>"ρ", "ϲ"=>"σ", "ϴ"=>"θ", "ϵ"=>"ε", "Ѐ"=>"ѐ", "Ё"=>"ё", "Ђ"=>"ђ", "Ѓ"=>"ѓ", "Є"=>"є", "Ѕ"=>"ѕ", "І"=>"і", "Ї"=>"ї", "Ј"=>"ј", "Љ"=>"љ", "Њ"=>"њ", "Ћ"=>"ћ", "Ќ"=>"ќ", "Ѝ"=>"ѝ", "Ў"=>"ў", "Џ"=>"џ", "А"=>"а", "Б"=>"б", "В"=>"в", "Г"=>"г", "Д"=>"д", "Е"=>"е", "Ж"=>"ж", "З"=>"з", "И"=>"и", "Й"=>"й", "К"=>"к", "Л"=>"л", "М"=>"м", "Н"=>"н", "О"=>"о", "П"=>"п", "Р"=>"р", "С"=>"с", "Т"=>"т", "У"=>"у", "Ф"=>"ф", "Х"=>"х", "Ц"=>"ц", "Ч"=>"ч", "Ш"=>"ш", "Щ"=>"щ", "Ъ"=>"ъ", "Ы"=>"ы", "Ь"=>"ь", "Э"=>"э", "Ю"=>"ю", "Я"=>"я", "Ѡ"=>"ѡ", "Ѣ"=>"ѣ", "Ѥ"=>"ѥ", "Ѧ"=>"ѧ", "Ѩ"=>"ѩ", "Ѫ"=>"ѫ", "Ѭ"=>"ѭ", "Ѯ"=>"ѯ", "Ѱ"=>"ѱ", "Ѳ"=>"ѳ", "Ѵ"=>"ѵ", "Ѷ"=>"ѷ", "Ѹ"=>"ѹ", "Ѻ"=>"ѻ", "Ѽ"=>"ѽ", "Ѿ"=>"ѿ", "Ҁ"=>"ҁ", "Ҋ"=>"ҋ", "Ҍ"=>"ҍ", "Ҏ"=>"ҏ", "Ґ"=>"ґ", "Ғ"=>"ғ", "Ҕ"=>"ҕ", "Җ"=>"җ", "Ҙ"=>"ҙ", "Қ"=>"қ", "Ҝ"=>"ҝ", "Ҟ"=>"ҟ", "Ҡ"=>"ҡ", "Ң"=>"ң", "Ҥ"=>"ҥ", "Ҧ"=>"ҧ", "Ҩ"=>"ҩ", "Ҫ"=>"ҫ", "Ҭ"=>"ҭ", "Ү"=>"ү", "Ұ"=>"ұ", "Ҳ"=>"ҳ", "Ҵ"=>"ҵ", "Ҷ"=>"ҷ", "Ҹ"=>"ҹ", "Һ"=>"һ", "Ҽ"=>"ҽ", "Ҿ"=>"ҿ", "Ӂ"=>"ӂ", "Ӄ"=>"ӄ", "Ӆ"=>"ӆ", "Ӈ"=>"ӈ", "Ӊ"=>"ӊ", "Ӌ"=>"ӌ", "Ӎ"=>"ӎ", "Ӑ"=>"ӑ", "Ӓ"=>"ӓ", "Ӕ"=>"ӕ", "Ӗ"=>"ӗ", "Ә"=>"ә", "Ӛ"=>"ӛ", "Ӝ"=>"ӝ", "Ӟ"=>"ӟ", "Ӡ"=>"ӡ", "Ӣ"=>"ӣ", "Ӥ"=>"ӥ", "Ӧ"=>"ӧ", "Ө"=>"ө", "Ӫ"=>"ӫ", "Ӭ"=>"ӭ", "Ӯ"=>"ӯ", "Ӱ"=>"ӱ", "Ӳ"=>"ӳ", "Ӵ"=>"ӵ", "Ӹ"=>"ӹ", "Ԁ"=>"ԁ", "Ԃ"=>"ԃ", "Ԅ"=>"ԅ", "Ԇ"=>"ԇ", "Ԉ"=>"ԉ", "Ԋ"=>"ԋ", "Ԍ"=>"ԍ", "Ԏ"=>"ԏ", "Ա"=>"ա", "Բ"=>"բ", "Գ"=>"գ", "Դ"=>"դ", "Ե"=>"ե", "Զ"=>"զ", "Է"=>"է", "Ը"=>"ը", "Թ"=>"թ", "Ժ"=>"ժ", "Ի"=>"ի", "Լ"=>"լ", "Խ"=>"խ", "Ծ"=>"ծ", "Կ"=>"կ", "Հ"=>"հ", "Ձ"=>"ձ", "Ղ"=>"ղ", "Ճ"=>"ճ", "Մ"=>"մ", "Յ"=>"յ", "Ն"=>"ն", "Շ"=>"շ", "Ո"=>"ո", "Չ"=>"չ", "Պ"=>"պ", "Ջ"=>"ջ", "Ռ"=>"ռ", "Ս"=>"ս", "Վ"=>"վ", "Տ"=>"տ", "Ր"=>"ր", "Ց"=>"ց", "Ւ"=>"ւ", "Փ"=>"փ", "Ք"=>"ք", "Օ"=>"օ", "Ֆ"=>"ֆ", "և"=>"եւ", "Ḁ"=>"ḁ", "Ḃ"=>"ḃ", "Ḅ"=>"ḅ", "Ḇ"=>"ḇ", "Ḉ"=>"ḉ", "Ḋ"=>"ḋ", "Ḍ"=>"ḍ", "Ḏ"=>"ḏ", "Ḑ"=>"ḑ", "Ḓ"=>"ḓ", "Ḕ"=>"ḕ", "Ḗ"=>"ḗ", "Ḙ"=>"ḙ", "Ḛ"=>"ḛ", "Ḝ"=>"ḝ", "Ḟ"=>"ḟ", "Ḡ"=>"ḡ", "Ḣ"=>"ḣ", "Ḥ"=>"ḥ", "Ḧ"=>"ḧ", "Ḩ"=>"ḩ", "Ḫ"=>"ḫ", "Ḭ"=>"ḭ", "Ḯ"=>"ḯ", "Ḱ"=>"ḱ", "Ḳ"=>"ḳ", "Ḵ"=>"ḵ", "Ḷ"=>"ḷ", "Ḹ"=>"ḹ", "Ḻ"=>"ḻ", "Ḽ"=>"ḽ", "Ḿ"=>"ḿ", "Ṁ"=>"ṁ", "Ṃ"=>"ṃ", "Ṅ"=>"ṅ", "Ṇ"=>"ṇ", "Ṉ"=>"ṉ", "Ṋ"=>"ṋ", "Ṍ"=>"ṍ", "Ṏ"=>"ṏ", "Ṑ"=>"ṑ", "Ṓ"=>"ṓ", "Ṕ"=>"ṕ", "Ṗ"=>"ṗ", "Ṙ"=>"ṙ", "Ṛ"=>"ṛ", "Ṝ"=>"ṝ", "Ṟ"=>"ṟ", "Ṡ"=>"ṡ", "Ṣ"=>"ṣ", "Ṥ"=>"ṥ", "Ṧ"=>"ṧ", "Ṩ"=>"ṩ", "Ṫ"=>"ṫ", "Ṭ"=>"ṭ", "Ṯ"=>"ṯ", "Ṱ"=>"ṱ", "Ṳ"=>"ṳ", "Ṵ"=>"ṵ", "Ṷ"=>"ṷ", "Ṹ"=>"ṹ", "Ṻ"=>"ṻ", "Ṽ"=>"ṽ", "Ṿ"=>"ṿ", "Ẁ"=>"ẁ", "Ẃ"=>"ẃ", "Ẅ"=>"ẅ", "Ẇ"=>"ẇ", "Ẉ"=>"ẉ", "Ẋ"=>"ẋ", "Ẍ"=>"ẍ", "Ẏ"=>"ẏ", "Ẑ"=>"ẑ", "Ẓ"=>"ẓ", "Ẕ"=>"ẕ", "ẖ"=>"ẖ", "ẗ"=>"ẗ", "ẘ"=>"ẘ", "ẙ"=>"ẙ", "ẚ"=>"aʾ", "ẛ"=>"ṡ", "Ạ"=>"ạ", "Ả"=>"ả", "Ấ"=>"ấ", "Ầ"=>"ầ", "Ẩ"=>"ẩ", "Ẫ"=>"ẫ", "Ậ"=>"ậ", "Ắ"=>"ắ", "Ằ"=>"ằ", "Ẳ"=>"ẳ", "Ẵ"=>"ẵ", "Ặ"=>"ặ", "Ẹ"=>"ẹ", "Ẻ"=>"ẻ", "Ẽ"=>"ẽ", "Ế"=>"ế", "Ề"=>"ề", "Ể"=>"ể", "Ễ"=>"ễ", "Ệ"=>"ệ", "Ỉ"=>"ỉ", "Ị"=>"ị", "Ọ"=>"ọ", "Ỏ"=>"ỏ", "Ố"=>"ố", "Ồ"=>"ồ", "Ổ"=>"ổ", "Ỗ"=>"ỗ", "Ộ"=>"ộ", "Ớ"=>"ớ", "Ờ"=>"ờ", "Ở"=>"ở", "Ỡ"=>"ỡ", "Ợ"=>"ợ", "Ụ"=>"ụ", "Ủ"=>"ủ", "Ứ"=>"ứ", "Ừ"=>"ừ", "Ử"=>"ử", "Ữ"=>"ữ", "Ự"=>"ự", "Ỳ"=>"ỳ", "Ỵ"=>"ỵ", "Ỷ"=>"ỷ", "Ỹ"=>"ỹ", "Ἀ"=>"ἀ", "Ἁ"=>"ἁ", "Ἂ"=>"ἂ", "Ἃ"=>"ἃ", "Ἄ"=>"ἄ", "Ἅ"=>"ἅ", "Ἆ"=>"ἆ", "Ἇ"=>"ἇ", "Ἐ"=>"ἐ", "Ἑ"=>"ἑ", "Ἒ"=>"ἒ", "Ἓ"=>"ἓ", "Ἔ"=>"ἔ", "Ἕ"=>"ἕ", "Ἠ"=>"ἠ", "Ἡ"=>"ἡ", "Ἢ"=>"ἢ", "Ἣ"=>"ἣ", "Ἤ"=>"ἤ", "Ἥ"=>"ἥ", "Ἦ"=>"ἦ", "Ἧ"=>"ἧ", "Ἰ"=>"ἰ", "Ἱ"=>"ἱ", "Ἲ"=>"ἲ", "Ἳ"=>"ἳ", "Ἴ"=>"ἴ", "Ἵ"=>"ἵ", "Ἶ"=>"ἶ", "Ἷ"=>"ἷ", "Ὀ"=>"ὀ", "Ὁ"=>"ὁ", "Ὂ"=>"ὂ", "Ὃ"=>"ὃ", "Ὄ"=>"ὄ", "Ὅ"=>"ὅ", "ὐ"=>"ὐ", "ὒ"=>"ὒ", "ὔ"=>"ὔ", "ὖ"=>"ὖ", "Ὑ"=>"ὑ", "Ὓ"=>"ὓ", "Ὕ"=>"ὕ", "Ὗ"=>"ὗ", "Ὠ"=>"ὠ", "Ὡ"=>"ὡ", "Ὢ"=>"ὢ", "Ὣ"=>"ὣ", "Ὤ"=>"ὤ", "Ὥ"=>"ὥ", "Ὦ"=>"ὦ", "Ὧ"=>"ὧ", "ᾀ"=>"ἀι", "ᾁ"=>"ἁι", "ᾂ"=>"ἂι", "ᾃ"=>"ἃι", "ᾄ"=>"ἄι", "ᾅ"=>"ἅι", "ᾆ"=>"ἆι", "ᾇ"=>"ἇι", "ᾈ"=>"ἀι", "ᾉ"=>"ἁι", "ᾊ"=>"ἂι", "ᾋ"=>"ἃι", "ᾌ"=>"ἄι", "ᾍ"=>"ἅι", "ᾎ"=>"ἆι", "ᾏ"=>"ἇι", "ᾐ"=>"ἠι", "ᾑ"=>"ἡι", "ᾒ"=>"ἢι", "ᾓ"=>"ἣι", "ᾔ"=>"ἤι", "ᾕ"=>"ἥι", "ᾖ"=>"ἦι", "ᾗ"=>"ἧι", "ᾘ"=>"ἠι", "ᾙ"=>"ἡι", "ᾚ"=>"ἢι", "ᾛ"=>"ἣι", "ᾜ"=>"ἤι", "ᾝ"=>"ἥι", "ᾞ"=>"ἦι", "ᾟ"=>"ἧι", "ᾠ"=>"ὠι", "ᾡ"=>"ὡι", "ᾢ"=>"ὢι", "ᾣ"=>"ὣι", "ᾤ"=>"ὤι", "ᾥ"=>"ὥι", "ᾦ"=>"ὦι", "ᾧ"=>"ὧι", "ᾨ"=>"ὠι", "ᾩ"=>"ὡι", "ᾪ"=>"ὢι", "ᾫ"=>"ὣι", "ᾬ"=>"ὤι", "ᾭ"=>"ὥι", "ᾮ"=>"ὦι", "ᾯ"=>"ὧι", "ᾲ"=>"ὰι", "ᾳ"=>"αι", "ᾴ"=>"άι", "ᾶ"=>"ᾶ", "ᾷ"=>"ᾶι", "Ᾰ"=>"ᾰ", "Ᾱ"=>"ᾱ", "Ὰ"=>"ὰ", "Ά"=>"ά", "ᾼ"=>"αι", "ι"=>"ι", "ῂ"=>"ὴι", "ῃ"=>"ηι", "ῄ"=>"ήι", "ῆ"=>"ῆ", "ῇ"=>"ῆι", "Ὲ"=>"ὲ", "Έ"=>"έ", "Ὴ"=>"ὴ", "Ή"=>"ή", "ῌ"=>"ηι", "ῒ"=>"ῒ", "ΐ"=>"ΐ", "ῖ"=>"ῖ", "ῗ"=>"ῗ", "Ῐ"=>"ῐ", "Ῑ"=>"ῑ", "Ὶ"=>"ὶ", "Ί"=>"ί", "ῢ"=>"ῢ", "ΰ"=>"ΰ", "ῤ"=>"ῤ", "ῦ"=>"ῦ", "ῧ"=>"ῧ", "Ῠ"=>"ῠ", "Ῡ"=>"ῡ", "Ὺ"=>"ὺ", "Ύ"=>"ύ", "Ῥ"=>"ῥ", "ῲ"=>"ὼι", "ῳ"=>"ωι", "ῴ"=>"ώι", "ῶ"=>"ῶ", "ῷ"=>"ῶι", "Ὸ"=>"ὸ", "Ό"=>"ό", "Ὼ"=>"ὼ", "Ώ"=>"ώ", "ῼ"=>"ωι", "₨"=>"rs", "ℂ"=>"c", "℃"=>"°c", "ℇ"=>"ɛ", "℉"=>"°f", "ℋ"=>"h", "ℌ"=>"h", "ℍ"=>"h", "ℐ"=>"i", "ℑ"=>"i", "ℒ"=>"l", "ℕ"=>"n", "№"=>"no", "ℙ"=>"p", "ℚ"=>"q", "ℛ"=>"r", "ℜ"=>"r", "ℝ"=>"r", "℠"=>"sm", "℡"=>"tel", "™"=>"tm", "ℤ"=>"z", "Ω"=>"ω", "ℨ"=>"z", "K"=>"k", "Å"=>"å", "ℬ"=>"b", "ℭ"=>"c", "ℰ"=>"e", "ℱ"=>"f", "ℳ"=>"m", "ℾ"=>"γ", "ℿ"=>"π", "ⅅ"=>"d", "Ⅰ"=>"ⅰ", "Ⅱ"=>"ⅱ", "Ⅲ"=>"ⅲ", "Ⅳ"=>"ⅳ", "Ⅴ"=>"ⅴ", "Ⅵ"=>"ⅵ", "Ⅶ"=>"ⅶ", "Ⅷ"=>"ⅷ", "Ⅸ"=>"ⅸ", "Ⅹ"=>"ⅹ", "Ⅺ"=>"ⅺ", "Ⅻ"=>"ⅻ", "Ⅼ"=>"ⅼ", "Ⅽ"=>"ⅽ", "Ⅾ"=>"ⅾ", "Ⅿ"=>"ⅿ", "Ⓐ"=>"ⓐ", "Ⓑ"=>"ⓑ", "Ⓒ"=>"ⓒ", "Ⓓ"=>"ⓓ", "Ⓔ"=>"ⓔ", "Ⓕ"=>"ⓕ", "Ⓖ"=>"ⓖ", "Ⓗ"=>"ⓗ", "Ⓘ"=>"ⓘ", "Ⓙ"=>"ⓙ", "Ⓚ"=>"ⓚ", "Ⓛ"=>"ⓛ", "Ⓜ"=>"ⓜ", "Ⓝ"=>"ⓝ", "Ⓞ"=>"ⓞ", "Ⓟ"=>"ⓟ", "Ⓠ"=>"ⓠ", "Ⓡ"=>"ⓡ", "Ⓢ"=>"ⓢ", "Ⓣ"=>"ⓣ", "Ⓤ"=>"ⓤ", "Ⓥ"=>"ⓥ", "Ⓦ"=>"ⓦ", "Ⓧ"=>"ⓧ", "Ⓨ"=>"ⓨ", "Ⓩ"=>"ⓩ", "㍱"=>"hpa", "㍳"=>"au", "㍵"=>"ov", "㎀"=>"pa", "㎁"=>"na", "㎂"=>"μa", "㎃"=>"ma", "㎄"=>"ka", "㎅"=>"kb", "㎆"=>"mb", "㎇"=>"gb", "㎊"=>"pf", "㎋"=>"nf", "㎌"=>"μf", "㎐"=>"hz", "㎑"=>"khz", "㎒"=>"mhz", "㎓"=>"ghz", "㎔"=>"thz", "㎩"=>"pa", "㎪"=>"kpa", "㎫"=>"mpa", "㎬"=>"gpa", "㎴"=>"pv", "㎵"=>"nv", "㎶"=>"μv", "㎷"=>"mv", "㎸"=>"kv", "㎹"=>"mv", "㎺"=>"pw", "㎻"=>"nw", "㎼"=>"μw", "㎽"=>"mw", "㎾"=>"kw", "㎿"=>"mw", "㏀"=>"kω", "㏁"=>"mω", "㏃"=>"bq", "㏆"=>"c∕kg", "㏇"=>"co.", "㏈"=>"db", "㏉"=>"gy", "㏋"=>"hp", "㏍"=>"kk", "㏎"=>"km", "㏗"=>"ph", "㏙"=>"ppm", "㏚"=>"pr", "㏜"=>"sv", "㏝"=>"wb", "ff"=>"ff", "fi"=>"fi", "fl"=>"fl", "ffi"=>"ffi", "ffl"=>"ffl", "ſt"=>"st", "st"=>"st", "ﬓ"=>"մն", "ﬔ"=>"մե", "ﬕ"=>"մի", "ﬖ"=>"վն", "ﬗ"=>"մխ", "A"=>"a", "B"=>"b", "C"=>"c", "D"=>"d", "E"=>"e", "F"=>"f", "G"=>"g", "H"=>"h", "I"=>"i", "J"=>"j", "K"=>"k", "L"=>"l", "M"=>"m", "N"=>"n", "O"=>"o", "P"=>"p", "Q"=>"q", "R"=>"r", "S"=>"s", "T"=>"t", "U"=>"u", "V"=>"v", "W"=>"w", "X"=>"x", "Y"=>"y", "Z"=>"z", "𐐀"=>"𐐨", "𐐁"=>"𐐩", "𐐂"=>"𐐪", "𐐃"=>"𐐫", "𐐄"=>"𐐬", "𐐅"=>"𐐭", "𐐆"=>"𐐮", "𐐇"=>"𐐯", "𐐈"=>"𐐰", "𐐉"=>"𐐱", "𐐊"=>"𐐲", "𐐋"=>"𐐳", "𐐌"=>"𐐴", "𐐍"=>"𐐵", "𐐎"=>"𐐶", "𐐏"=>"𐐷", "𐐐"=>"𐐸", "𐐑"=>"𐐹", "𐐒"=>"𐐺", "𐐓"=>"𐐻", "𐐔"=>"𐐼", "𐐕"=>"𐐽", "𐐖"=>"𐐾", "𐐗"=>"𐐿", "𐐘"=>"𐑀", "𐐙"=>"𐑁", "𐐚"=>"𐑂", "𐐛"=>"𐑃", "𐐜"=>"𐑄", "𐐝"=>"𐑅", "𐐞"=>"𐑆", "𐐟"=>"𐑇", "𐐠"=>"𐑈", "𐐡"=>"𐑉", "𐐢"=>"𐑊", "𐐣"=>"𐑋", "𐐤"=>"𐑌", "𐐥"=>"𐑍", "𝐀"=>"a", "𝐁"=>"b", "𝐂"=>"c", "𝐃"=>"d", "𝐄"=>"e", "𝐅"=>"f", "𝐆"=>"g", "𝐇"=>"h", "𝐈"=>"i", "𝐉"=>"j", "𝐊"=>"k", "𝐋"=>"l", "𝐌"=>"m", "𝐍"=>"n", "𝐎"=>"o", "𝐏"=>"p", "𝐐"=>"q", "𝐑"=>"r", "𝐒"=>"s", "𝐓"=>"t", "𝐔"=>"u", "𝐕"=>"v", "𝐖"=>"w", "𝐗"=>"x", "𝐘"=>"y", "𝐙"=>"z", "𝐴"=>"a", "𝐵"=>"b", "𝐶"=>"c", "𝐷"=>"d", "𝐸"=>"e", "𝐹"=>"f", "𝐺"=>"g", "𝐻"=>"h", "𝐼"=>"i", "𝐽"=>"j", "𝐾"=>"k", "𝐿"=>"l", "𝑀"=>"m", "𝑁"=>"n", "𝑂"=>"o", "𝑃"=>"p", "𝑄"=>"q", "𝑅"=>"r", "𝑆"=>"s", "𝑇"=>"t", "𝑈"=>"u", "𝑉"=>"v", "𝑊"=>"w", "𝑋"=>"x", "𝑌"=>"y", "𝑍"=>"z", "𝑨"=>"a", "𝑩"=>"b", "𝑪"=>"c", "𝑫"=>"d", "𝑬"=>"e", "𝑭"=>"f", "𝑮"=>"g", "𝑯"=>"h", "𝑰"=>"i", "𝑱"=>"j", "𝑲"=>"k", "𝑳"=>"l", "𝑴"=>"m", "𝑵"=>"n", "𝑶"=>"o", "𝑷"=>"p", "𝑸"=>"q", "𝑹"=>"r", "𝑺"=>"s", "𝑻"=>"t", "𝑼"=>"u", "𝑽"=>"v", "𝑾"=>"w", "𝑿"=>"x", "𝒀"=>"y", "𝒁"=>"z", "𝒜"=>"a", "𝒞"=>"c", "𝒟"=>"d", "𝒢"=>"g", "𝒥"=>"j", "𝒦"=>"k", "𝒩"=>"n", "𝒪"=>"o", "𝒫"=>"p", "𝒬"=>"q", "𝒮"=>"s", "𝒯"=>"t", "𝒰"=>"u", "𝒱"=>"v", "𝒲"=>"w", "𝒳"=>"x", "𝒴"=>"y", "𝒵"=>"z", "𝓐"=>"a", "𝓑"=>"b", "𝓒"=>"c", "𝓓"=>"d", "𝓔"=>"e", "𝓕"=>"f", "𝓖"=>"g", "𝓗"=>"h", "𝓘"=>"i", "𝓙"=>"j", "𝓚"=>"k", "𝓛"=>"l", "𝓜"=>"m", "𝓝"=>"n", "𝓞"=>"o", "𝓟"=>"p", "𝓠"=>"q", "𝓡"=>"r", "𝓢"=>"s", "𝓣"=>"t", "𝓤"=>"u", "𝓥"=>"v", "𝓦"=>"w", "𝓧"=>"x", "𝓨"=>"y", "𝓩"=>"z", "𝔄"=>"a", "𝔅"=>"b", "𝔇"=>"d", "𝔈"=>"e", "𝔉"=>"f", "𝔊"=>"g", "𝔍"=>"j", "𝔎"=>"k", "𝔏"=>"l", "𝔐"=>"m", "𝔑"=>"n", "𝔒"=>"o", "𝔓"=>"p", "𝔔"=>"q", "𝔖"=>"s", "𝔗"=>"t", "𝔘"=>"u", "𝔙"=>"v", "𝔚"=>"w", "𝔛"=>"x", "𝔜"=>"y", "𝔸"=>"a", "𝔹"=>"b", "𝔻"=>"d", "𝔼"=>"e", "𝔽"=>"f", "𝔾"=>"g", "𝕀"=>"i", "𝕁"=>"j", "𝕂"=>"k", "𝕃"=>"l", "𝕄"=>"m", "𝕆"=>"o", "𝕊"=>"s", "𝕋"=>"t", "𝕌"=>"u", "𝕍"=>"v", "𝕎"=>"w", "𝕏"=>"x", "𝕐"=>"y", "𝕬"=>"a", "𝕭"=>"b", "𝕮"=>"c", "𝕯"=>"d", "𝕰"=>"e", "𝕱"=>"f", "𝕲"=>"g", "𝕳"=>"h", "𝕴"=>"i", "𝕵"=>"j", "𝕶"=>"k", "𝕷"=>"l", "𝕸"=>"m", "𝕹"=>"n", "𝕺"=>"o", "𝕻"=>"p", "𝕼"=>"q", "𝕽"=>"r", "𝕾"=>"s", "𝕿"=>"t", "𝖀"=>"u", "𝖁"=>"v", "𝖂"=>"w", "𝖃"=>"x", "𝖄"=>"y", "𝖅"=>"z", "𝖠"=>"a", "𝖡"=>"b", "𝖢"=>"c", "𝖣"=>"d", "𝖤"=>"e", "𝖥"=>"f", "𝖦"=>"g", "𝖧"=>"h", "𝖨"=>"i", "𝖩"=>"j", "𝖪"=>"k", "𝖫"=>"l", "𝖬"=>"m", "𝖭"=>"n", "𝖮"=>"o", "𝖯"=>"p", "𝖰"=>"q", "𝖱"=>"r", "𝖲"=>"s", "𝖳"=>"t", "𝖴"=>"u", "𝖵"=>"v", "𝖶"=>"w", "𝖷"=>"x", "𝖸"=>"y", "𝖹"=>"z", "𝗔"=>"a", "𝗕"=>"b", "𝗖"=>"c", "𝗗"=>"d", "𝗘"=>"e", "𝗙"=>"f", "𝗚"=>"g", "𝗛"=>"h", "𝗜"=>"i", "𝗝"=>"j", "𝗞"=>"k", "𝗟"=>"l", "𝗠"=>"m", "𝗡"=>"n", "𝗢"=>"o", "𝗣"=>"p", "𝗤"=>"q", "𝗥"=>"r", "𝗦"=>"s", "𝗧"=>"t", "𝗨"=>"u", "𝗩"=>"v", "𝗪"=>"w", "𝗫"=>"x", "𝗬"=>"y", "𝗭"=>"z", "𝘈"=>"a", "𝘉"=>"b", "𝘊"=>"c", "𝘋"=>"d", "𝘌"=>"e", "𝘍"=>"f", "𝘎"=>"g", "𝘏"=>"h", "𝘐"=>"i", "𝘑"=>"j", "𝘒"=>"k", "𝘓"=>"l", "𝘔"=>"m", "𝘕"=>"n", "𝘖"=>"o", "𝘗"=>"p", "𝘘"=>"q", "𝘙"=>"r", "𝘚"=>"s", "𝘛"=>"t", "𝘜"=>"u", "𝘝"=>"v", "𝘞"=>"w", "𝘟"=>"x", "𝘠"=>"y", "𝘡"=>"z", "𝘼"=>"a", "𝘽"=>"b", "𝘾"=>"c", "𝘿"=>"d", "𝙀"=>"e", "𝙁"=>"f", "𝙂"=>"g", "𝙃"=>"h", "𝙄"=>"i", "𝙅"=>"j", "𝙆"=>"k", "𝙇"=>"l", "𝙈"=>"m", "𝙉"=>"n", "𝙊"=>"o", "𝙋"=>"p", "𝙌"=>"q", "𝙍"=>"r", "𝙎"=>"s", "𝙏"=>"t", "𝙐"=>"u", "𝙑"=>"v", "𝙒"=>"w", "𝙓"=>"x", "𝙔"=>"y", "𝙕"=>"z", "𝙰"=>"a", "𝙱"=>"b", "𝙲"=>"c", "𝙳"=>"d", "𝙴"=>"e", "𝙵"=>"f", "𝙶"=>"g", "𝙷"=>"h", "𝙸"=>"i", "𝙹"=>"j", "𝙺"=>"k", "𝙻"=>"l", "𝙼"=>"m", "𝙽"=>"n", "𝙾"=>"o", "𝙿"=>"p", "𝚀"=>"q", "𝚁"=>"r", "𝚂"=>"s", "𝚃"=>"t", "𝚄"=>"u", "𝚅"=>"v", "𝚆"=>"w", "𝚇"=>"x", "𝚈"=>"y", "𝚉"=>"z", "𝚨"=>"α", "𝚩"=>"β", "𝚪"=>"γ", "𝚫"=>"δ", "𝚬"=>"ε", "𝚭"=>"ζ", "𝚮"=>"η", "𝚯"=>"θ", "𝚰"=>"ι", "𝚱"=>"κ", "𝚲"=>"λ", "𝚳"=>"μ", "𝚴"=>"ν", "𝚵"=>"ξ", "𝚶"=>"ο", "𝚷"=>"π", "𝚸"=>"ρ", "𝚹"=>"θ", "𝚺"=>"σ", "𝚻"=>"τ", "𝚼"=>"υ", "𝚽"=>"φ", "𝚾"=>"χ", "𝚿"=>"ψ", "𝛀"=>"ω", "𝛓"=>"σ", "𝛢"=>"α", "𝛣"=>"β", "𝛤"=>"γ", "𝛥"=>"δ", "𝛦"=>"ε", "𝛧"=>"ζ", "𝛨"=>"η", "𝛩"=>"θ", "𝛪"=>"ι", "𝛫"=>"κ", "𝛬"=>"λ", "𝛭"=>"μ", "𝛮"=>"ν", "𝛯"=>"ξ", "𝛰"=>"ο", "𝛱"=>"π", "𝛲"=>"ρ", "𝛳"=>"θ", "𝛴"=>"σ", "𝛵"=>"τ", "𝛶"=>"υ", "𝛷"=>"φ", "𝛸"=>"χ", "𝛹"=>"ψ", "𝛺"=>"ω", "𝜍"=>"σ", "𝜜"=>"α", "𝜝"=>"β", "𝜞"=>"γ", "𝜟"=>"δ", "𝜠"=>"ε", "𝜡"=>"ζ", "𝜢"=>"η", "𝜣"=>"θ", "𝜤"=>"ι", "𝜥"=>"κ", "𝜦"=>"λ", "𝜧"=>"μ", "𝜨"=>"ν", "𝜩"=>"ξ", "𝜪"=>"ο", "𝜫"=>"π", "𝜬"=>"ρ", "𝜭"=>"θ", "𝜮"=>"σ", "𝜯"=>"τ", "𝜰"=>"υ", "𝜱"=>"φ", "𝜲"=>"χ", "𝜳"=>"ψ", "𝜴"=>"ω", "𝝇"=>"σ", "𝝖"=>"α", "𝝗"=>"β", "𝝘"=>"γ", "𝝙"=>"δ", "𝝚"=>"ε", "𝝛"=>"ζ", "𝝜"=>"η", "𝝝"=>"θ", "𝝞"=>"ι", "𝝟"=>"κ", "𝝠"=>"λ", "𝝡"=>"μ", "𝝢"=>"ν", "𝝣"=>"ξ", "𝝤"=>"ο", "𝝥"=>"π", "𝝦"=>"ρ", "𝝧"=>"θ", "𝝨"=>"σ", "𝝩"=>"τ", "𝝪"=>"υ", "𝝫"=>"φ", "𝝬"=>"χ", "𝝭"=>"ψ", "𝝮"=>"ω", "𝞁"=>"σ", "𝞐"=>"α", "𝞑"=>"β", "𝞒"=>"γ", "𝞓"=>"δ", "𝞔"=>"ε", "𝞕"=>"ζ", "𝞖"=>"η", "𝞗"=>"θ", "𝞘"=>"ι", "𝞙"=>"κ", "𝞚"=>"λ", "𝞛"=>"μ", "𝞜"=>"ν", "𝞝"=>"ξ", "𝞞"=>"ο", "𝞟"=>"π", "𝞠"=>"ρ", "𝞡"=>"θ", "𝞢"=>"σ", "𝞣"=>"τ", "𝞤"=>"υ", "𝞥"=>"φ", "𝞦"=>"χ", "𝞧"=>"ψ", "𝞨"=>"ω", "𝞻"=>"σ"}.freeze - - # Replacements for IN_B.3 - MAP_B_3 = {"A"=>"a", "B"=>"b", "C"=>"c", "D"=>"d", "E"=>"e", "F"=>"f", "G"=>"g", "H"=>"h", "I"=>"i", "J"=>"j", "K"=>"k", "L"=>"l", "M"=>"m", "N"=>"n", "O"=>"o", "P"=>"p", "Q"=>"q", "R"=>"r", "S"=>"s", "T"=>"t", "U"=>"u", "V"=>"v", "W"=>"w", "X"=>"x", "Y"=>"y", "Z"=>"z", "µ"=>"μ", "À"=>"à", "Á"=>"á", "Â"=>"â", "Ã"=>"ã", "Ä"=>"ä", "Å"=>"å", "Æ"=>"æ", "Ç"=>"ç", "È"=>"è", "É"=>"é", "Ê"=>"ê", "Ë"=>"ë", "Ì"=>"ì", "Í"=>"í", "Î"=>"î", "Ï"=>"ï", "Ð"=>"ð", "Ñ"=>"ñ", "Ò"=>"ò", "Ó"=>"ó", "Ô"=>"ô", "Õ"=>"õ", "Ö"=>"ö", "Ø"=>"ø", "Ù"=>"ù", "Ú"=>"ú", "Û"=>"û", "Ü"=>"ü", "Ý"=>"ý", "Þ"=>"þ", "ß"=>"ss", "Ā"=>"ā", "Ă"=>"ă", "Ą"=>"ą", "Ć"=>"ć", "Ĉ"=>"ĉ", "Ċ"=>"ċ", "Č"=>"č", "Ď"=>"ď", "Đ"=>"đ", "Ē"=>"ē", "Ĕ"=>"ĕ", "Ė"=>"ė", "Ę"=>"ę", "Ě"=>"ě", "Ĝ"=>"ĝ", "Ğ"=>"ğ", "Ġ"=>"ġ", "Ģ"=>"ģ", "Ĥ"=>"ĥ", "Ħ"=>"ħ", "Ĩ"=>"ĩ", "Ī"=>"ī", "Ĭ"=>"ĭ", "Į"=>"į", "İ"=>"i̇", "IJ"=>"ij", "Ĵ"=>"ĵ", "Ķ"=>"ķ", "Ĺ"=>"ĺ", "Ļ"=>"ļ", "Ľ"=>"ľ", "Ŀ"=>"ŀ", "Ł"=>"ł", "Ń"=>"ń", "Ņ"=>"ņ", "Ň"=>"ň", "ʼn"=>"ʼn", "Ŋ"=>"ŋ", "Ō"=>"ō", "Ŏ"=>"ŏ", "Ő"=>"ő", "Œ"=>"œ", "Ŕ"=>"ŕ", "Ŗ"=>"ŗ", "Ř"=>"ř", "Ś"=>"ś", "Ŝ"=>"ŝ", "Ş"=>"ş", "Š"=>"š", "Ţ"=>"ţ", "Ť"=>"ť", "Ŧ"=>"ŧ", "Ũ"=>"ũ", "Ū"=>"ū", "Ŭ"=>"ŭ", "Ů"=>"ů", "Ű"=>"ű", "Ų"=>"ų", "Ŵ"=>"ŵ", "Ŷ"=>"ŷ", "Ÿ"=>"ÿ", "Ź"=>"ź", "Ż"=>"ż", "Ž"=>"ž", "ſ"=>"s", "Ɓ"=>"ɓ", "Ƃ"=>"ƃ", "Ƅ"=>"ƅ", "Ɔ"=>"ɔ", "Ƈ"=>"ƈ", "Ɖ"=>"ɖ", "Ɗ"=>"ɗ", "Ƌ"=>"ƌ", "Ǝ"=>"ǝ", "Ə"=>"ə", "Ɛ"=>"ɛ", "Ƒ"=>"ƒ", "Ɠ"=>"ɠ", "Ɣ"=>"ɣ", "Ɩ"=>"ɩ", "Ɨ"=>"ɨ", "Ƙ"=>"ƙ", "Ɯ"=>"ɯ", "Ɲ"=>"ɲ", "Ɵ"=>"ɵ", "Ơ"=>"ơ", "Ƣ"=>"ƣ", "Ƥ"=>"ƥ", "Ʀ"=>"ʀ", "Ƨ"=>"ƨ", "Ʃ"=>"ʃ", "Ƭ"=>"ƭ", "Ʈ"=>"ʈ", "Ư"=>"ư", "Ʊ"=>"ʊ", "Ʋ"=>"ʋ", "Ƴ"=>"ƴ", "Ƶ"=>"ƶ", "Ʒ"=>"ʒ", "Ƹ"=>"ƹ", "Ƽ"=>"ƽ", "DŽ"=>"dž", "Dž"=>"dž", "LJ"=>"lj", "Lj"=>"lj", "NJ"=>"nj", "Nj"=>"nj", "Ǎ"=>"ǎ", "Ǐ"=>"ǐ", "Ǒ"=>"ǒ", "Ǔ"=>"ǔ", "Ǖ"=>"ǖ", "Ǘ"=>"ǘ", "Ǚ"=>"ǚ", "Ǜ"=>"ǜ", "Ǟ"=>"ǟ", "Ǡ"=>"ǡ", "Ǣ"=>"ǣ", "Ǥ"=>"ǥ", "Ǧ"=>"ǧ", "Ǩ"=>"ǩ", "Ǫ"=>"ǫ", "Ǭ"=>"ǭ", "Ǯ"=>"ǯ", "ǰ"=>"ǰ", "DZ"=>"dz", "Dz"=>"dz", "Ǵ"=>"ǵ", "Ƕ"=>"ƕ", "Ƿ"=>"ƿ", "Ǹ"=>"ǹ", "Ǻ"=>"ǻ", "Ǽ"=>"ǽ", "Ǿ"=>"ǿ", "Ȁ"=>"ȁ", "Ȃ"=>"ȃ", "Ȅ"=>"ȅ", "Ȇ"=>"ȇ", "Ȉ"=>"ȉ", "Ȋ"=>"ȋ", "Ȍ"=>"ȍ", "Ȏ"=>"ȏ", "Ȑ"=>"ȑ", "Ȓ"=>"ȓ", "Ȕ"=>"ȕ", "Ȗ"=>"ȗ", "Ș"=>"ș", "Ț"=>"ț", "Ȝ"=>"ȝ", "Ȟ"=>"ȟ", "Ƞ"=>"ƞ", "Ȣ"=>"ȣ", "Ȥ"=>"ȥ", "Ȧ"=>"ȧ", "Ȩ"=>"ȩ", "Ȫ"=>"ȫ", "Ȭ"=>"ȭ", "Ȯ"=>"ȯ", "Ȱ"=>"ȱ", "Ȳ"=>"ȳ", "ͅ"=>"ι", "Ά"=>"ά", "Έ"=>"έ", "Ή"=>"ή", "Ί"=>"ί", "Ό"=>"ό", "Ύ"=>"ύ", "Ώ"=>"ώ", "ΐ"=>"ΐ", "Α"=>"α", "Β"=>"β", "Γ"=>"γ", "Δ"=>"δ", "Ε"=>"ε", "Ζ"=>"ζ", "Η"=>"η", "Θ"=>"θ", "Ι"=>"ι", "Κ"=>"κ", "Λ"=>"λ", "Μ"=>"μ", "Ν"=>"ν", "Ξ"=>"ξ", "Ο"=>"ο", "Π"=>"π", "Ρ"=>"ρ", "Σ"=>"σ", "Τ"=>"τ", "Υ"=>"υ", "Φ"=>"φ", "Χ"=>"χ", "Ψ"=>"ψ", "Ω"=>"ω", "Ϊ"=>"ϊ", "Ϋ"=>"ϋ", "ΰ"=>"ΰ", "ς"=>"σ", "ϐ"=>"β", "ϑ"=>"θ", "ϕ"=>"φ", "ϖ"=>"π", "Ϙ"=>"ϙ", "Ϛ"=>"ϛ", "Ϝ"=>"ϝ", "Ϟ"=>"ϟ", "Ϡ"=>"ϡ", "Ϣ"=>"ϣ", "Ϥ"=>"ϥ", "Ϧ"=>"ϧ", "Ϩ"=>"ϩ", "Ϫ"=>"ϫ", "Ϭ"=>"ϭ", "Ϯ"=>"ϯ", "ϰ"=>"κ", "ϱ"=>"ρ", "ϲ"=>"σ", "ϴ"=>"θ", "ϵ"=>"ε", "Ѐ"=>"ѐ", "Ё"=>"ё", "Ђ"=>"ђ", "Ѓ"=>"ѓ", "Є"=>"є", "Ѕ"=>"ѕ", "І"=>"і", "Ї"=>"ї", "Ј"=>"ј", "Љ"=>"љ", "Њ"=>"њ", "Ћ"=>"ћ", "Ќ"=>"ќ", "Ѝ"=>"ѝ", "Ў"=>"ў", "Џ"=>"џ", "А"=>"а", "Б"=>"б", "В"=>"в", "Г"=>"г", "Д"=>"д", "Е"=>"е", "Ж"=>"ж", "З"=>"з", "И"=>"и", "Й"=>"й", "К"=>"к", "Л"=>"л", "М"=>"м", "Н"=>"н", "О"=>"о", "П"=>"п", "Р"=>"р", "С"=>"с", "Т"=>"т", "У"=>"у", "Ф"=>"ф", "Х"=>"х", "Ц"=>"ц", "Ч"=>"ч", "Ш"=>"ш", "Щ"=>"щ", "Ъ"=>"ъ", "Ы"=>"ы", "Ь"=>"ь", "Э"=>"э", "Ю"=>"ю", "Я"=>"я", "Ѡ"=>"ѡ", "Ѣ"=>"ѣ", "Ѥ"=>"ѥ", "Ѧ"=>"ѧ", "Ѩ"=>"ѩ", "Ѫ"=>"ѫ", "Ѭ"=>"ѭ", "Ѯ"=>"ѯ", "Ѱ"=>"ѱ", "Ѳ"=>"ѳ", "Ѵ"=>"ѵ", "Ѷ"=>"ѷ", "Ѹ"=>"ѹ", "Ѻ"=>"ѻ", "Ѽ"=>"ѽ", "Ѿ"=>"ѿ", "Ҁ"=>"ҁ", "Ҋ"=>"ҋ", "Ҍ"=>"ҍ", "Ҏ"=>"ҏ", "Ґ"=>"ґ", "Ғ"=>"ғ", "Ҕ"=>"ҕ", "Җ"=>"җ", "Ҙ"=>"ҙ", "Қ"=>"қ", "Ҝ"=>"ҝ", "Ҟ"=>"ҟ", "Ҡ"=>"ҡ", "Ң"=>"ң", "Ҥ"=>"ҥ", "Ҧ"=>"ҧ", "Ҩ"=>"ҩ", "Ҫ"=>"ҫ", "Ҭ"=>"ҭ", "Ү"=>"ү", "Ұ"=>"ұ", "Ҳ"=>"ҳ", "Ҵ"=>"ҵ", "Ҷ"=>"ҷ", "Ҹ"=>"ҹ", "Һ"=>"һ", "Ҽ"=>"ҽ", "Ҿ"=>"ҿ", "Ӂ"=>"ӂ", "Ӄ"=>"ӄ", "Ӆ"=>"ӆ", "Ӈ"=>"ӈ", "Ӊ"=>"ӊ", "Ӌ"=>"ӌ", "Ӎ"=>"ӎ", "Ӑ"=>"ӑ", "Ӓ"=>"ӓ", "Ӕ"=>"ӕ", "Ӗ"=>"ӗ", "Ә"=>"ә", "Ӛ"=>"ӛ", "Ӝ"=>"ӝ", "Ӟ"=>"ӟ", "Ӡ"=>"ӡ", "Ӣ"=>"ӣ", "Ӥ"=>"ӥ", "Ӧ"=>"ӧ", "Ө"=>"ө", "Ӫ"=>"ӫ", "Ӭ"=>"ӭ", "Ӯ"=>"ӯ", "Ӱ"=>"ӱ", "Ӳ"=>"ӳ", "Ӵ"=>"ӵ", "Ӹ"=>"ӹ", "Ԁ"=>"ԁ", "Ԃ"=>"ԃ", "Ԅ"=>"ԅ", "Ԇ"=>"ԇ", "Ԉ"=>"ԉ", "Ԋ"=>"ԋ", "Ԍ"=>"ԍ", "Ԏ"=>"ԏ", "Ա"=>"ա", "Բ"=>"բ", "Գ"=>"գ", "Դ"=>"դ", "Ե"=>"ե", "Զ"=>"զ", "Է"=>"է", "Ը"=>"ը", "Թ"=>"թ", "Ժ"=>"ժ", "Ի"=>"ի", "Լ"=>"լ", "Խ"=>"խ", "Ծ"=>"ծ", "Կ"=>"կ", "Հ"=>"հ", "Ձ"=>"ձ", "Ղ"=>"ղ", "Ճ"=>"ճ", "Մ"=>"մ", "Յ"=>"յ", "Ն"=>"ն", "Շ"=>"շ", "Ո"=>"ո", "Չ"=>"չ", "Պ"=>"պ", "Ջ"=>"ջ", "Ռ"=>"ռ", "Ս"=>"ս", "Վ"=>"վ", "Տ"=>"տ", "Ր"=>"ր", "Ց"=>"ց", "Ւ"=>"ւ", "Փ"=>"փ", "Ք"=>"ք", "Օ"=>"օ", "Ֆ"=>"ֆ", "և"=>"եւ", "Ḁ"=>"ḁ", "Ḃ"=>"ḃ", "Ḅ"=>"ḅ", "Ḇ"=>"ḇ", "Ḉ"=>"ḉ", "Ḋ"=>"ḋ", "Ḍ"=>"ḍ", "Ḏ"=>"ḏ", "Ḑ"=>"ḑ", "Ḓ"=>"ḓ", "Ḕ"=>"ḕ", "Ḗ"=>"ḗ", "Ḙ"=>"ḙ", "Ḛ"=>"ḛ", "Ḝ"=>"ḝ", "Ḟ"=>"ḟ", "Ḡ"=>"ḡ", "Ḣ"=>"ḣ", "Ḥ"=>"ḥ", "Ḧ"=>"ḧ", "Ḩ"=>"ḩ", "Ḫ"=>"ḫ", "Ḭ"=>"ḭ", "Ḯ"=>"ḯ", "Ḱ"=>"ḱ", "Ḳ"=>"ḳ", "Ḵ"=>"ḵ", "Ḷ"=>"ḷ", "Ḹ"=>"ḹ", "Ḻ"=>"ḻ", "Ḽ"=>"ḽ", "Ḿ"=>"ḿ", "Ṁ"=>"ṁ", "Ṃ"=>"ṃ", "Ṅ"=>"ṅ", "Ṇ"=>"ṇ", "Ṉ"=>"ṉ", "Ṋ"=>"ṋ", "Ṍ"=>"ṍ", "Ṏ"=>"ṏ", "Ṑ"=>"ṑ", "Ṓ"=>"ṓ", "Ṕ"=>"ṕ", "Ṗ"=>"ṗ", "Ṙ"=>"ṙ", "Ṛ"=>"ṛ", "Ṝ"=>"ṝ", "Ṟ"=>"ṟ", "Ṡ"=>"ṡ", "Ṣ"=>"ṣ", "Ṥ"=>"ṥ", "Ṧ"=>"ṧ", "Ṩ"=>"ṩ", "Ṫ"=>"ṫ", "Ṭ"=>"ṭ", "Ṯ"=>"ṯ", "Ṱ"=>"ṱ", "Ṳ"=>"ṳ", "Ṵ"=>"ṵ", "Ṷ"=>"ṷ", "Ṹ"=>"ṹ", "Ṻ"=>"ṻ", "Ṽ"=>"ṽ", "Ṿ"=>"ṿ", "Ẁ"=>"ẁ", "Ẃ"=>"ẃ", "Ẅ"=>"ẅ", "Ẇ"=>"ẇ", "Ẉ"=>"ẉ", "Ẋ"=>"ẋ", "Ẍ"=>"ẍ", "Ẏ"=>"ẏ", "Ẑ"=>"ẑ", "Ẓ"=>"ẓ", "Ẕ"=>"ẕ", "ẖ"=>"ẖ", "ẗ"=>"ẗ", "ẘ"=>"ẘ", "ẙ"=>"ẙ", "ẚ"=>"aʾ", "ẛ"=>"ṡ", "Ạ"=>"ạ", "Ả"=>"ả", "Ấ"=>"ấ", "Ầ"=>"ầ", "Ẩ"=>"ẩ", "Ẫ"=>"ẫ", "Ậ"=>"ậ", "Ắ"=>"ắ", "Ằ"=>"ằ", "Ẳ"=>"ẳ", "Ẵ"=>"ẵ", "Ặ"=>"ặ", "Ẹ"=>"ẹ", "Ẻ"=>"ẻ", "Ẽ"=>"ẽ", "Ế"=>"ế", "Ề"=>"ề", "Ể"=>"ể", "Ễ"=>"ễ", "Ệ"=>"ệ", "Ỉ"=>"ỉ", "Ị"=>"ị", "Ọ"=>"ọ", "Ỏ"=>"ỏ", "Ố"=>"ố", "Ồ"=>"ồ", "Ổ"=>"ổ", "Ỗ"=>"ỗ", "Ộ"=>"ộ", "Ớ"=>"ớ", "Ờ"=>"ờ", "Ở"=>"ở", "Ỡ"=>"ỡ", "Ợ"=>"ợ", "Ụ"=>"ụ", "Ủ"=>"ủ", "Ứ"=>"ứ", "Ừ"=>"ừ", "Ử"=>"ử", "Ữ"=>"ữ", "Ự"=>"ự", "Ỳ"=>"ỳ", "Ỵ"=>"ỵ", "Ỷ"=>"ỷ", "Ỹ"=>"ỹ", "Ἀ"=>"ἀ", "Ἁ"=>"ἁ", "Ἂ"=>"ἂ", "Ἃ"=>"ἃ", "Ἄ"=>"ἄ", "Ἅ"=>"ἅ", "Ἆ"=>"ἆ", "Ἇ"=>"ἇ", "Ἐ"=>"ἐ", "Ἑ"=>"ἑ", "Ἒ"=>"ἒ", "Ἓ"=>"ἓ", "Ἔ"=>"ἔ", "Ἕ"=>"ἕ", "Ἠ"=>"ἠ", "Ἡ"=>"ἡ", "Ἢ"=>"ἢ", "Ἣ"=>"ἣ", "Ἤ"=>"ἤ", "Ἥ"=>"ἥ", "Ἦ"=>"ἦ", "Ἧ"=>"ἧ", "Ἰ"=>"ἰ", "Ἱ"=>"ἱ", "Ἲ"=>"ἲ", "Ἳ"=>"ἳ", "Ἴ"=>"ἴ", "Ἵ"=>"ἵ", "Ἶ"=>"ἶ", "Ἷ"=>"ἷ", "Ὀ"=>"ὀ", "Ὁ"=>"ὁ", "Ὂ"=>"ὂ", "Ὃ"=>"ὃ", "Ὄ"=>"ὄ", "Ὅ"=>"ὅ", "ὐ"=>"ὐ", "ὒ"=>"ὒ", "ὔ"=>"ὔ", "ὖ"=>"ὖ", "Ὑ"=>"ὑ", "Ὓ"=>"ὓ", "Ὕ"=>"ὕ", "Ὗ"=>"ὗ", "Ὠ"=>"ὠ", "Ὡ"=>"ὡ", "Ὢ"=>"ὢ", "Ὣ"=>"ὣ", "Ὤ"=>"ὤ", "Ὥ"=>"ὥ", "Ὦ"=>"ὦ", "Ὧ"=>"ὧ", "ᾀ"=>"ἀι", "ᾁ"=>"ἁι", "ᾂ"=>"ἂι", "ᾃ"=>"ἃι", "ᾄ"=>"ἄι", "ᾅ"=>"ἅι", "ᾆ"=>"ἆι", "ᾇ"=>"ἇι", "ᾈ"=>"ἀι", "ᾉ"=>"ἁι", "ᾊ"=>"ἂι", "ᾋ"=>"ἃι", "ᾌ"=>"ἄι", "ᾍ"=>"ἅι", "ᾎ"=>"ἆι", "ᾏ"=>"ἇι", "ᾐ"=>"ἠι", "ᾑ"=>"ἡι", "ᾒ"=>"ἢι", "ᾓ"=>"ἣι", "ᾔ"=>"ἤι", "ᾕ"=>"ἥι", "ᾖ"=>"ἦι", "ᾗ"=>"ἧι", "ᾘ"=>"ἠι", "ᾙ"=>"ἡι", "ᾚ"=>"ἢι", "ᾛ"=>"ἣι", "ᾜ"=>"ἤι", "ᾝ"=>"ἥι", "ᾞ"=>"ἦι", "ᾟ"=>"ἧι", "ᾠ"=>"ὠι", "ᾡ"=>"ὡι", "ᾢ"=>"ὢι", "ᾣ"=>"ὣι", "ᾤ"=>"ὤι", "ᾥ"=>"ὥι", "ᾦ"=>"ὦι", "ᾧ"=>"ὧι", "ᾨ"=>"ὠι", "ᾩ"=>"ὡι", "ᾪ"=>"ὢι", "ᾫ"=>"ὣι", "ᾬ"=>"ὤι", "ᾭ"=>"ὥι", "ᾮ"=>"ὦι", "ᾯ"=>"ὧι", "ᾲ"=>"ὰι", "ᾳ"=>"αι", "ᾴ"=>"άι", "ᾶ"=>"ᾶ", "ᾷ"=>"ᾶι", "Ᾰ"=>"ᾰ", "Ᾱ"=>"ᾱ", "Ὰ"=>"ὰ", "Ά"=>"ά", "ᾼ"=>"αι", "ι"=>"ι", "ῂ"=>"ὴι", "ῃ"=>"ηι", "ῄ"=>"ήι", "ῆ"=>"ῆ", "ῇ"=>"ῆι", "Ὲ"=>"ὲ", "Έ"=>"έ", "Ὴ"=>"ὴ", "Ή"=>"ή", "ῌ"=>"ηι", "ῒ"=>"ῒ", "ΐ"=>"ΐ", "ῖ"=>"ῖ", "ῗ"=>"ῗ", "Ῐ"=>"ῐ", "Ῑ"=>"ῑ", "Ὶ"=>"ὶ", "Ί"=>"ί", "ῢ"=>"ῢ", "ΰ"=>"ΰ", "ῤ"=>"ῤ", "ῦ"=>"ῦ", "ῧ"=>"ῧ", "Ῠ"=>"ῠ", "Ῡ"=>"ῡ", "Ὺ"=>"ὺ", "Ύ"=>"ύ", "Ῥ"=>"ῥ", "ῲ"=>"ὼι", "ῳ"=>"ωι", "ῴ"=>"ώι", "ῶ"=>"ῶ", "ῷ"=>"ῶι", "Ὸ"=>"ὸ", "Ό"=>"ό", "Ὼ"=>"ὼ", "Ώ"=>"ώ", "ῼ"=>"ωι", "Ω"=>"ω", "K"=>"k", "Å"=>"å", "Ⅰ"=>"ⅰ", "Ⅱ"=>"ⅱ", "Ⅲ"=>"ⅲ", "Ⅳ"=>"ⅳ", "Ⅴ"=>"ⅴ", "Ⅵ"=>"ⅵ", "Ⅶ"=>"ⅶ", "Ⅷ"=>"ⅷ", "Ⅸ"=>"ⅸ", "Ⅹ"=>"ⅹ", "Ⅺ"=>"ⅺ", "Ⅻ"=>"ⅻ", "Ⅼ"=>"ⅼ", "Ⅽ"=>"ⅽ", "Ⅾ"=>"ⅾ", "Ⅿ"=>"ⅿ", "Ⓐ"=>"ⓐ", "Ⓑ"=>"ⓑ", "Ⓒ"=>"ⓒ", "Ⓓ"=>"ⓓ", "Ⓔ"=>"ⓔ", "Ⓕ"=>"ⓕ", "Ⓖ"=>"ⓖ", "Ⓗ"=>"ⓗ", "Ⓘ"=>"ⓘ", "Ⓙ"=>"ⓙ", "Ⓚ"=>"ⓚ", "Ⓛ"=>"ⓛ", "Ⓜ"=>"ⓜ", "Ⓝ"=>"ⓝ", "Ⓞ"=>"ⓞ", "Ⓟ"=>"ⓟ", "Ⓠ"=>"ⓠ", "Ⓡ"=>"ⓡ", "Ⓢ"=>"ⓢ", "Ⓣ"=>"ⓣ", "Ⓤ"=>"ⓤ", "Ⓥ"=>"ⓥ", "Ⓦ"=>"ⓦ", "Ⓧ"=>"ⓧ", "Ⓨ"=>"ⓨ", "Ⓩ"=>"ⓩ", "ff"=>"ff", "fi"=>"fi", "fl"=>"fl", "ffi"=>"ffi", "ffl"=>"ffl", "ſt"=>"st", "st"=>"st", "ﬓ"=>"մն", "ﬔ"=>"մե", "ﬕ"=>"մի", "ﬖ"=>"վն", "ﬗ"=>"մխ", "A"=>"a", "B"=>"b", "C"=>"c", "D"=>"d", "E"=>"e", "F"=>"f", "G"=>"g", "H"=>"h", "I"=>"i", "J"=>"j", "K"=>"k", "L"=>"l", "M"=>"m", "N"=>"n", "O"=>"o", "P"=>"p", "Q"=>"q", "R"=>"r", "S"=>"s", "T"=>"t", "U"=>"u", "V"=>"v", "W"=>"w", "X"=>"x", "Y"=>"y", "Z"=>"z", "𐐀"=>"𐐨", "𐐁"=>"𐐩", "𐐂"=>"𐐪", "𐐃"=>"𐐫", "𐐄"=>"𐐬", "𐐅"=>"𐐭", "𐐆"=>"𐐮", "𐐇"=>"𐐯", "𐐈"=>"𐐰", "𐐉"=>"𐐱", "𐐊"=>"𐐲", "𐐋"=>"𐐳", "𐐌"=>"𐐴", "𐐍"=>"𐐵", "𐐎"=>"𐐶", "𐐏"=>"𐐷", "𐐐"=>"𐐸", "𐐑"=>"𐐹", "𐐒"=>"𐐺", "𐐓"=>"𐐻", "𐐔"=>"𐐼", "𐐕"=>"𐐽", "𐐖"=>"𐐾", "𐐗"=>"𐐿", "𐐘"=>"𐑀", "𐐙"=>"𐑁", "𐐚"=>"𐑂", "𐐛"=>"𐑃", "𐐜"=>"𐑄", "𐐝"=>"𐑅", "𐐞"=>"𐑆", "𐐟"=>"𐑇", "𐐠"=>"𐑈", "𐐡"=>"𐑉", "𐐢"=>"𐑊", "𐐣"=>"𐑋", "𐐤"=>"𐑌", "𐐥"=>"𐑍"}.freeze - - # ASCII space characters \StringPrep\[\"C.1.1\"] - IN_C_1_1 = / /.freeze - - # Non-ASCII space characters \StringPrep\[\"C.1.2\"] - IN_C_1_2 = /[\u200b\p{Zs}&&[^ ]]/.freeze - - # ASCII control characters \StringPrep\[\"C.2.1\"] - IN_C_2_1 = /[\x00-\x1f\x7f]/.freeze - - # Non-ASCII control characters \StringPrep\[\"C.2.2\"] - IN_C_2_2 = /[\u{06dd 070f 180e feff}\u{0080}-\u{009f}\u{200c}-\u{200d}\u{2028}-\u{2029}\u{2060}-\u{2063}\u{206a}-\u{206f}\u{fff9}-\u{fffc}\u{1d173}-\u{1d17a}]/.freeze - - # Private use \StringPrep\[\"C.3\"] - IN_C_3 = /\p{private use}/.freeze - - # Non-character code points \StringPrep\[\"C.4\"] - IN_C_4 = /\p{noncharacter code point}/.freeze - - # Surrogate codes \StringPrep\[\"C.5\"] - IN_C_5 = /\p{surrogate}/.freeze - - # Inappropriate for plain text \StringPrep\[\"C.6\"] - IN_C_6 = /[\p{in specials}&&\p{AGE=3.2}&&\p{^NChar}]/.freeze - - # Inappropriate for canonical representation \StringPrep\[\"C.7\"] - IN_C_7 = /[\p{in ideographic description characters}&&\p{AGE=3.2}]/.freeze - - # Change display properties or are deprecated \StringPrep\[\"C.8\"] - IN_C_8 = /[\u{0340}-\u{0341}\u{200e}-\u{200f}\u{202a}-\u{202e}\u{206a}-\u{206f}]/.freeze - - # Tagging characters \StringPrep\[\"C.9\"] - IN_C_9 = /[\p{in Tags}&&\p{AGE=3.2}]/.freeze - - # Characters with bidirectional property "R" or "AL" \StringPrep\[\"D.1\"] - IN_D_1 = /[\u{05be 05c0 05c3 061b 061f 06dd 0710 07b1 200f fb1d fb3e}\u{05d0}-\u{05ea}\u{05f0}-\u{05f4}\u{0621}-\u{063a}\u{0640}-\u{064a}\u{066d}-\u{066f}\u{0671}-\u{06d5}\u{06e5}-\u{06e6}\u{06fa}-\u{06fe}\u{0700}-\u{070d}\u{0712}-\u{072c}\u{0780}-\u{07a5}\u{fb1f}-\u{fb28}\u{fb2a}-\u{fb36}\u{fb38}-\u{fb3c}\u{fb40}-\u{fb41}\u{fb43}-\u{fb44}\u{fb46}-\u{fbb1}\u{fbd3}-\u{fd3d}\u{fd50}-\u{fd8f}\u{fd92}-\u{fdc7}\u{fdf0}-\u{fdfc}\u{fe70}-\u{fe74}\u{fe76}-\u{fefc}]/.freeze - - # Used to check req3 of bidirectional checks - # Matches the negation of the D.1 table - IN_D_1_NEGATED = /[^\u{05be 05c0 05c3 061b 061f 06dd 0710 07b1 200f fb1d fb3e}\u{05d0}-\u{05ea}\u{05f0}-\u{05f4}\u{0621}-\u{063a}\u{0640}-\u{064a}\u{066d}-\u{066f}\u{0671}-\u{06d5}\u{06e5}-\u{06e6}\u{06fa}-\u{06fe}\u{0700}-\u{070d}\u{0712}-\u{072c}\u{0780}-\u{07a5}\u{fb1f}-\u{fb28}\u{fb2a}-\u{fb36}\u{fb38}-\u{fb3c}\u{fb40}-\u{fb41}\u{fb43}-\u{fb44}\u{fb46}-\u{fbb1}\u{fbd3}-\u{fd3d}\u{fd50}-\u{fd8f}\u{fd92}-\u{fdc7}\u{fdf0}-\u{fdfc}\u{fe70}-\u{fe74}\u{fe76}-\u{fefc}]/.freeze - - # Characters with bidirectional property "L" \StringPrep\[\"D.2\"] - IN_D_2 = /[\u{00aa 00b5 00ba 02ee 037a 0386 038c 0589 0903 0950 09b2 09d7 0a5e 0a83 0a8d 0ac9 0ad0 0ae0 0b40 0b57 0b83 0b9c 0bd7 0cbe 0cde 0d57 0dbd 0e84 0e8a 0e8d 0ea5 0ea7 0ebd 0ec6 0f36 0f38 0f7f 0f85 0fcf 102c 1031 1038 10fb 1248 1258 1288 12b0 12c0 1310 17dc 1f59 1f5b 1f5d 1fbe 200e 2071 207f 2102 2107 2115 2124 2126 2128 2395 1d4a2 1d4bb 1d546}\u{0041}-\u{005a}\u{0061}-\u{007a}\u{00c0}-\u{00d6}\u{00d8}-\u{00f6}\u{00f8}-\u{0220}\u{0222}-\u{0233}\u{0250}-\u{02ad}\u{02b0}-\u{02b8}\u{02bb}-\u{02c1}\u{02d0}-\u{02d1}\u{02e0}-\u{02e4}\u{0388}-\u{038a}\u{038e}-\u{03a1}\u{03a3}-\u{03ce}\u{03d0}-\u{03f5}\u{0400}-\u{0482}\u{048a}-\u{04ce}\u{04d0}-\u{04f5}\u{04f8}-\u{04f9}\u{0500}-\u{050f}\u{0531}-\u{0556}\u{0559}-\u{055f}\u{0561}-\u{0587}\u{0905}-\u{0939}\u{093d}-\u{0940}\u{0949}-\u{094c}\u{0958}-\u{0961}\u{0964}-\u{0970}\u{0982}-\u{0983}\u{0985}-\u{098c}\u{098f}-\u{0990}\u{0993}-\u{09a8}\u{09aa}-\u{09b0}\u{09b6}-\u{09b9}\u{09be}-\u{09c0}\u{09c7}-\u{09c8}\u{09cb}-\u{09cc}\u{09dc}-\u{09dd}\u{09df}-\u{09e1}\u{09e6}-\u{09f1}\u{09f4}-\u{09fa}\u{0a05}-\u{0a0a}\u{0a0f}-\u{0a10}\u{0a13}-\u{0a28}\u{0a2a}-\u{0a30}\u{0a32}-\u{0a33}\u{0a35}-\u{0a36}\u{0a38}-\u{0a39}\u{0a3e}-\u{0a40}\u{0a59}-\u{0a5c}\u{0a66}-\u{0a6f}\u{0a72}-\u{0a74}\u{0a85}-\u{0a8b}\u{0a8f}-\u{0a91}\u{0a93}-\u{0aa8}\u{0aaa}-\u{0ab0}\u{0ab2}-\u{0ab3}\u{0ab5}-\u{0ab9}\u{0abd}-\u{0ac0}\u{0acb}-\u{0acc}\u{0ae6}-\u{0aef}\u{0b02}-\u{0b03}\u{0b05}-\u{0b0c}\u{0b0f}-\u{0b10}\u{0b13}-\u{0b28}\u{0b2a}-\u{0b30}\u{0b32}-\u{0b33}\u{0b36}-\u{0b39}\u{0b3d}-\u{0b3e}\u{0b47}-\u{0b48}\u{0b4b}-\u{0b4c}\u{0b5c}-\u{0b5d}\u{0b5f}-\u{0b61}\u{0b66}-\u{0b70}\u{0b85}-\u{0b8a}\u{0b8e}-\u{0b90}\u{0b92}-\u{0b95}\u{0b99}-\u{0b9a}\u{0b9e}-\u{0b9f}\u{0ba3}-\u{0ba4}\u{0ba8}-\u{0baa}\u{0bae}-\u{0bb5}\u{0bb7}-\u{0bb9}\u{0bbe}-\u{0bbf}\u{0bc1}-\u{0bc2}\u{0bc6}-\u{0bc8}\u{0bca}-\u{0bcc}\u{0be7}-\u{0bf2}\u{0c01}-\u{0c03}\u{0c05}-\u{0c0c}\u{0c0e}-\u{0c10}\u{0c12}-\u{0c28}\u{0c2a}-\u{0c33}\u{0c35}-\u{0c39}\u{0c41}-\u{0c44}\u{0c60}-\u{0c61}\u{0c66}-\u{0c6f}\u{0c82}-\u{0c83}\u{0c85}-\u{0c8c}\u{0c8e}-\u{0c90}\u{0c92}-\u{0ca8}\u{0caa}-\u{0cb3}\u{0cb5}-\u{0cb9}\u{0cc0}-\u{0cc4}\u{0cc7}-\u{0cc8}\u{0cca}-\u{0ccb}\u{0cd5}-\u{0cd6}\u{0ce0}-\u{0ce1}\u{0ce6}-\u{0cef}\u{0d02}-\u{0d03}\u{0d05}-\u{0d0c}\u{0d0e}-\u{0d10}\u{0d12}-\u{0d28}\u{0d2a}-\u{0d39}\u{0d3e}-\u{0d40}\u{0d46}-\u{0d48}\u{0d4a}-\u{0d4c}\u{0d60}-\u{0d61}\u{0d66}-\u{0d6f}\u{0d82}-\u{0d83}\u{0d85}-\u{0d96}\u{0d9a}-\u{0db1}\u{0db3}-\u{0dbb}\u{0dc0}-\u{0dc6}\u{0dcf}-\u{0dd1}\u{0dd8}-\u{0ddf}\u{0df2}-\u{0df4}\u{0e01}-\u{0e30}\u{0e32}-\u{0e33}\u{0e40}-\u{0e46}\u{0e4f}-\u{0e5b}\u{0e81}-\u{0e82}\u{0e87}-\u{0e88}\u{0e94}-\u{0e97}\u{0e99}-\u{0e9f}\u{0ea1}-\u{0ea3}\u{0eaa}-\u{0eab}\u{0ead}-\u{0eb0}\u{0eb2}-\u{0eb3}\u{0ec0}-\u{0ec4}\u{0ed0}-\u{0ed9}\u{0edc}-\u{0edd}\u{0f00}-\u{0f17}\u{0f1a}-\u{0f34}\u{0f3e}-\u{0f47}\u{0f49}-\u{0f6a}\u{0f88}-\u{0f8b}\u{0fbe}-\u{0fc5}\u{0fc7}-\u{0fcc}\u{1000}-\u{1021}\u{1023}-\u{1027}\u{1029}-\u{102a}\u{1040}-\u{1057}\u{10a0}-\u{10c5}\u{10d0}-\u{10f8}\u{1100}-\u{1159}\u{115f}-\u{11a2}\u{11a8}-\u{11f9}\u{1200}-\u{1206}\u{1208}-\u{1246}\u{124a}-\u{124d}\u{1250}-\u{1256}\u{125a}-\u{125d}\u{1260}-\u{1286}\u{128a}-\u{128d}\u{1290}-\u{12ae}\u{12b2}-\u{12b5}\u{12b8}-\u{12be}\u{12c2}-\u{12c5}\u{12c8}-\u{12ce}\u{12d0}-\u{12d6}\u{12d8}-\u{12ee}\u{12f0}-\u{130e}\u{1312}-\u{1315}\u{1318}-\u{131e}\u{1320}-\u{1346}\u{1348}-\u{135a}\u{1361}-\u{137c}\u{13a0}-\u{13f4}\u{1401}-\u{1676}\u{1681}-\u{169a}\u{16a0}-\u{16f0}\u{1700}-\u{170c}\u{170e}-\u{1711}\u{1720}-\u{1731}\u{1735}-\u{1736}\u{1740}-\u{1751}\u{1760}-\u{176c}\u{176e}-\u{1770}\u{1780}-\u{17b6}\u{17be}-\u{17c5}\u{17c7}-\u{17c8}\u{17d4}-\u{17da}\u{17e0}-\u{17e9}\u{1810}-\u{1819}\u{1820}-\u{1877}\u{1880}-\u{18a8}\u{1e00}-\u{1e9b}\u{1ea0}-\u{1ef9}\u{1f00}-\u{1f15}\u{1f18}-\u{1f1d}\u{1f20}-\u{1f45}\u{1f48}-\u{1f4d}\u{1f50}-\u{1f57}\u{1f5f}-\u{1f7d}\u{1f80}-\u{1fb4}\u{1fb6}-\u{1fbc}\u{1fc2}-\u{1fc4}\u{1fc6}-\u{1fcc}\u{1fd0}-\u{1fd3}\u{1fd6}-\u{1fdb}\u{1fe0}-\u{1fec}\u{1ff2}-\u{1ff4}\u{1ff6}-\u{1ffc}\u{210a}-\u{2113}\u{2119}-\u{211d}\u{212a}-\u{212d}\u{212f}-\u{2131}\u{2133}-\u{2139}\u{213d}-\u{213f}\u{2145}-\u{2149}\u{2160}-\u{2183}\u{2336}-\u{237a}\u{249c}-\u{24e9}\u{3005}-\u{3007}\u{3021}-\u{3029}\u{3031}-\u{3035}\u{3038}-\u{303c}\u{3041}-\u{3096}\u{309d}-\u{309f}\u{30a1}-\u{30fa}\u{30fc}-\u{30ff}\u{3105}-\u{312c}\u{3131}-\u{318e}\u{3190}-\u{31b7}\u{31f0}-\u{321c}\u{3220}-\u{3243}\u{3260}-\u{327b}\u{327f}-\u{32b0}\u{32c0}-\u{32cb}\u{32d0}-\u{32fe}\u{3300}-\u{3376}\u{337b}-\u{33dd}\u{33e0}-\u{33fe}\u{3400}-\u{4db5}\u{4e00}-\u{9fa5}\u{a000}-\u{a48c}\u{ac00}-\u{d7a3}\u{e000}-\u{fa2d}\u{fa30}-\u{fa6a}\u{fb00}-\u{fb06}\u{fb13}-\u{fb17}\u{ff21}-\u{ff3a}\u{ff41}-\u{ff5a}\u{ff66}-\u{ffbe}\u{ffc2}-\u{ffc7}\u{ffca}-\u{ffcf}\u{ffd2}-\u{ffd7}\u{ffda}-\u{ffdc}\u{10300}-\u{1031e}\u{10320}-\u{10323}\u{10330}-\u{1034a}\u{10400}-\u{10425}\u{10428}-\u{1044d}\u{1d000}-\u{1d0f5}\u{1d100}-\u{1d126}\u{1d12a}-\u{1d166}\u{1d16a}-\u{1d172}\u{1d183}-\u{1d184}\u{1d18c}-\u{1d1a9}\u{1d1ae}-\u{1d1dd}\u{1d400}-\u{1d454}\u{1d456}-\u{1d49c}\u{1d49e}-\u{1d49f}\u{1d4a5}-\u{1d4a6}\u{1d4a9}-\u{1d4ac}\u{1d4ae}-\u{1d4b9}\u{1d4bd}-\u{1d4c0}\u{1d4c2}-\u{1d4c3}\u{1d4c5}-\u{1d505}\u{1d507}-\u{1d50a}\u{1d50d}-\u{1d514}\u{1d516}-\u{1d51c}\u{1d51e}-\u{1d539}\u{1d53b}-\u{1d53e}\u{1d540}-\u{1d544}\u{1d54a}-\u{1d550}\u{1d552}-\u{1d6a3}\u{1d6a8}-\u{1d7c9}\u{20000}-\u{2a6d6}\u{2f800}-\u{2fa1d}\u{f0000}-\u{ffffd}\u{100000}-\u{10fffd}\p{Cs}]/.freeze - - BIDI_DESC_REQ2 = "A string with RandALCat characters must not contain LCat characters." - - # Bidirectional Characters [StringPrep, §6], Requirement 2 - # >>> - # If a string contains any RandALCat character, the string MUST NOT - # contain any LCat character. - BIDI_FAILS_REQ2 = /(?m-ix:(?-mix:[\u{05be 05c0 05c3 061b 061f 06dd 0710 07b1 200f fb1d fb3e}\u{05d0}-\u{05ea}\u{05f0}-\u{05f4}\u{0621}-\u{063a}\u{0640}-\u{064a}\u{066d}-\u{066f}\u{0671}-\u{06d5}\u{06e5}-\u{06e6}\u{06fa}-\u{06fe}\u{0700}-\u{070d}\u{0712}-\u{072c}\u{0780}-\u{07a5}\u{fb1f}-\u{fb28}\u{fb2a}-\u{fb36}\u{fb38}-\u{fb3c}\u{fb40}-\u{fb41}\u{fb43}-\u{fb44}\u{fb46}-\u{fbb1}\u{fbd3}-\u{fd3d}\u{fd50}-\u{fd8f}\u{fd92}-\u{fdc7}\u{fdf0}-\u{fdfc}\u{fe70}-\u{fe74}\u{fe76}-\u{fefc}]).*?(?-mix:[\u{00aa 00b5 00ba 02ee 037a 0386 038c 0589 0903 0950 09b2 09d7 0a5e 0a83 0a8d 0ac9 0ad0 0ae0 0b40 0b57 0b83 0b9c 0bd7 0cbe 0cde 0d57 0dbd 0e84 0e8a 0e8d 0ea5 0ea7 0ebd 0ec6 0f36 0f38 0f7f 0f85 0fcf 102c 1031 1038 10fb 1248 1258 1288 12b0 12c0 1310 17dc 1f59 1f5b 1f5d 1fbe 200e 2071 207f 2102 2107 2115 2124 2126 2128 2395 1d4a2 1d4bb 1d546}\u{0041}-\u{005a}\u{0061}-\u{007a}\u{00c0}-\u{00d6}\u{00d8}-\u{00f6}\u{00f8}-\u{0220}\u{0222}-\u{0233}\u{0250}-\u{02ad}\u{02b0}-\u{02b8}\u{02bb}-\u{02c1}\u{02d0}-\u{02d1}\u{02e0}-\u{02e4}\u{0388}-\u{038a}\u{038e}-\u{03a1}\u{03a3}-\u{03ce}\u{03d0}-\u{03f5}\u{0400}-\u{0482}\u{048a}-\u{04ce}\u{04d0}-\u{04f5}\u{04f8}-\u{04f9}\u{0500}-\u{050f}\u{0531}-\u{0556}\u{0559}-\u{055f}\u{0561}-\u{0587}\u{0905}-\u{0939}\u{093d}-\u{0940}\u{0949}-\u{094c}\u{0958}-\u{0961}\u{0964}-\u{0970}\u{0982}-\u{0983}\u{0985}-\u{098c}\u{098f}-\u{0990}\u{0993}-\u{09a8}\u{09aa}-\u{09b0}\u{09b6}-\u{09b9}\u{09be}-\u{09c0}\u{09c7}-\u{09c8}\u{09cb}-\u{09cc}\u{09dc}-\u{09dd}\u{09df}-\u{09e1}\u{09e6}-\u{09f1}\u{09f4}-\u{09fa}\u{0a05}-\u{0a0a}\u{0a0f}-\u{0a10}\u{0a13}-\u{0a28}\u{0a2a}-\u{0a30}\u{0a32}-\u{0a33}\u{0a35}-\u{0a36}\u{0a38}-\u{0a39}\u{0a3e}-\u{0a40}\u{0a59}-\u{0a5c}\u{0a66}-\u{0a6f}\u{0a72}-\u{0a74}\u{0a85}-\u{0a8b}\u{0a8f}-\u{0a91}\u{0a93}-\u{0aa8}\u{0aaa}-\u{0ab0}\u{0ab2}-\u{0ab3}\u{0ab5}-\u{0ab9}\u{0abd}-\u{0ac0}\u{0acb}-\u{0acc}\u{0ae6}-\u{0aef}\u{0b02}-\u{0b03}\u{0b05}-\u{0b0c}\u{0b0f}-\u{0b10}\u{0b13}-\u{0b28}\u{0b2a}-\u{0b30}\u{0b32}-\u{0b33}\u{0b36}-\u{0b39}\u{0b3d}-\u{0b3e}\u{0b47}-\u{0b48}\u{0b4b}-\u{0b4c}\u{0b5c}-\u{0b5d}\u{0b5f}-\u{0b61}\u{0b66}-\u{0b70}\u{0b85}-\u{0b8a}\u{0b8e}-\u{0b90}\u{0b92}-\u{0b95}\u{0b99}-\u{0b9a}\u{0b9e}-\u{0b9f}\u{0ba3}-\u{0ba4}\u{0ba8}-\u{0baa}\u{0bae}-\u{0bb5}\u{0bb7}-\u{0bb9}\u{0bbe}-\u{0bbf}\u{0bc1}-\u{0bc2}\u{0bc6}-\u{0bc8}\u{0bca}-\u{0bcc}\u{0be7}-\u{0bf2}\u{0c01}-\u{0c03}\u{0c05}-\u{0c0c}\u{0c0e}-\u{0c10}\u{0c12}-\u{0c28}\u{0c2a}-\u{0c33}\u{0c35}-\u{0c39}\u{0c41}-\u{0c44}\u{0c60}-\u{0c61}\u{0c66}-\u{0c6f}\u{0c82}-\u{0c83}\u{0c85}-\u{0c8c}\u{0c8e}-\u{0c90}\u{0c92}-\u{0ca8}\u{0caa}-\u{0cb3}\u{0cb5}-\u{0cb9}\u{0cc0}-\u{0cc4}\u{0cc7}-\u{0cc8}\u{0cca}-\u{0ccb}\u{0cd5}-\u{0cd6}\u{0ce0}-\u{0ce1}\u{0ce6}-\u{0cef}\u{0d02}-\u{0d03}\u{0d05}-\u{0d0c}\u{0d0e}-\u{0d10}\u{0d12}-\u{0d28}\u{0d2a}-\u{0d39}\u{0d3e}-\u{0d40}\u{0d46}-\u{0d48}\u{0d4a}-\u{0d4c}\u{0d60}-\u{0d61}\u{0d66}-\u{0d6f}\u{0d82}-\u{0d83}\u{0d85}-\u{0d96}\u{0d9a}-\u{0db1}\u{0db3}-\u{0dbb}\u{0dc0}-\u{0dc6}\u{0dcf}-\u{0dd1}\u{0dd8}-\u{0ddf}\u{0df2}-\u{0df4}\u{0e01}-\u{0e30}\u{0e32}-\u{0e33}\u{0e40}-\u{0e46}\u{0e4f}-\u{0e5b}\u{0e81}-\u{0e82}\u{0e87}-\u{0e88}\u{0e94}-\u{0e97}\u{0e99}-\u{0e9f}\u{0ea1}-\u{0ea3}\u{0eaa}-\u{0eab}\u{0ead}-\u{0eb0}\u{0eb2}-\u{0eb3}\u{0ec0}-\u{0ec4}\u{0ed0}-\u{0ed9}\u{0edc}-\u{0edd}\u{0f00}-\u{0f17}\u{0f1a}-\u{0f34}\u{0f3e}-\u{0f47}\u{0f49}-\u{0f6a}\u{0f88}-\u{0f8b}\u{0fbe}-\u{0fc5}\u{0fc7}-\u{0fcc}\u{1000}-\u{1021}\u{1023}-\u{1027}\u{1029}-\u{102a}\u{1040}-\u{1057}\u{10a0}-\u{10c5}\u{10d0}-\u{10f8}\u{1100}-\u{1159}\u{115f}-\u{11a2}\u{11a8}-\u{11f9}\u{1200}-\u{1206}\u{1208}-\u{1246}\u{124a}-\u{124d}\u{1250}-\u{1256}\u{125a}-\u{125d}\u{1260}-\u{1286}\u{128a}-\u{128d}\u{1290}-\u{12ae}\u{12b2}-\u{12b5}\u{12b8}-\u{12be}\u{12c2}-\u{12c5}\u{12c8}-\u{12ce}\u{12d0}-\u{12d6}\u{12d8}-\u{12ee}\u{12f0}-\u{130e}\u{1312}-\u{1315}\u{1318}-\u{131e}\u{1320}-\u{1346}\u{1348}-\u{135a}\u{1361}-\u{137c}\u{13a0}-\u{13f4}\u{1401}-\u{1676}\u{1681}-\u{169a}\u{16a0}-\u{16f0}\u{1700}-\u{170c}\u{170e}-\u{1711}\u{1720}-\u{1731}\u{1735}-\u{1736}\u{1740}-\u{1751}\u{1760}-\u{176c}\u{176e}-\u{1770}\u{1780}-\u{17b6}\u{17be}-\u{17c5}\u{17c7}-\u{17c8}\u{17d4}-\u{17da}\u{17e0}-\u{17e9}\u{1810}-\u{1819}\u{1820}-\u{1877}\u{1880}-\u{18a8}\u{1e00}-\u{1e9b}\u{1ea0}-\u{1ef9}\u{1f00}-\u{1f15}\u{1f18}-\u{1f1d}\u{1f20}-\u{1f45}\u{1f48}-\u{1f4d}\u{1f50}-\u{1f57}\u{1f5f}-\u{1f7d}\u{1f80}-\u{1fb4}\u{1fb6}-\u{1fbc}\u{1fc2}-\u{1fc4}\u{1fc6}-\u{1fcc}\u{1fd0}-\u{1fd3}\u{1fd6}-\u{1fdb}\u{1fe0}-\u{1fec}\u{1ff2}-\u{1ff4}\u{1ff6}-\u{1ffc}\u{210a}-\u{2113}\u{2119}-\u{211d}\u{212a}-\u{212d}\u{212f}-\u{2131}\u{2133}-\u{2139}\u{213d}-\u{213f}\u{2145}-\u{2149}\u{2160}-\u{2183}\u{2336}-\u{237a}\u{249c}-\u{24e9}\u{3005}-\u{3007}\u{3021}-\u{3029}\u{3031}-\u{3035}\u{3038}-\u{303c}\u{3041}-\u{3096}\u{309d}-\u{309f}\u{30a1}-\u{30fa}\u{30fc}-\u{30ff}\u{3105}-\u{312c}\u{3131}-\u{318e}\u{3190}-\u{31b7}\u{31f0}-\u{321c}\u{3220}-\u{3243}\u{3260}-\u{327b}\u{327f}-\u{32b0}\u{32c0}-\u{32cb}\u{32d0}-\u{32fe}\u{3300}-\u{3376}\u{337b}-\u{33dd}\u{33e0}-\u{33fe}\u{3400}-\u{4db5}\u{4e00}-\u{9fa5}\u{a000}-\u{a48c}\u{ac00}-\u{d7a3}\u{e000}-\u{fa2d}\u{fa30}-\u{fa6a}\u{fb00}-\u{fb06}\u{fb13}-\u{fb17}\u{ff21}-\u{ff3a}\u{ff41}-\u{ff5a}\u{ff66}-\u{ffbe}\u{ffc2}-\u{ffc7}\u{ffca}-\u{ffcf}\u{ffd2}-\u{ffd7}\u{ffda}-\u{ffdc}\u{10300}-\u{1031e}\u{10320}-\u{10323}\u{10330}-\u{1034a}\u{10400}-\u{10425}\u{10428}-\u{1044d}\u{1d000}-\u{1d0f5}\u{1d100}-\u{1d126}\u{1d12a}-\u{1d166}\u{1d16a}-\u{1d172}\u{1d183}-\u{1d184}\u{1d18c}-\u{1d1a9}\u{1d1ae}-\u{1d1dd}\u{1d400}-\u{1d454}\u{1d456}-\u{1d49c}\u{1d49e}-\u{1d49f}\u{1d4a5}-\u{1d4a6}\u{1d4a9}-\u{1d4ac}\u{1d4ae}-\u{1d4b9}\u{1d4bd}-\u{1d4c0}\u{1d4c2}-\u{1d4c3}\u{1d4c5}-\u{1d505}\u{1d507}-\u{1d50a}\u{1d50d}-\u{1d514}\u{1d516}-\u{1d51c}\u{1d51e}-\u{1d539}\u{1d53b}-\u{1d53e}\u{1d540}-\u{1d544}\u{1d54a}-\u{1d550}\u{1d552}-\u{1d6a3}\u{1d6a8}-\u{1d7c9}\u{20000}-\u{2a6d6}\u{2f800}-\u{2fa1d}\u{f0000}-\u{ffffd}\u{100000}-\u{10fffd}\p{Cs}]))|(?m-ix:(?-mix:[\u{00aa 00b5 00ba 02ee 037a 0386 038c 0589 0903 0950 09b2 09d7 0a5e 0a83 0a8d 0ac9 0ad0 0ae0 0b40 0b57 0b83 0b9c 0bd7 0cbe 0cde 0d57 0dbd 0e84 0e8a 0e8d 0ea5 0ea7 0ebd 0ec6 0f36 0f38 0f7f 0f85 0fcf 102c 1031 1038 10fb 1248 1258 1288 12b0 12c0 1310 17dc 1f59 1f5b 1f5d 1fbe 200e 2071 207f 2102 2107 2115 2124 2126 2128 2395 1d4a2 1d4bb 1d546}\u{0041}-\u{005a}\u{0061}-\u{007a}\u{00c0}-\u{00d6}\u{00d8}-\u{00f6}\u{00f8}-\u{0220}\u{0222}-\u{0233}\u{0250}-\u{02ad}\u{02b0}-\u{02b8}\u{02bb}-\u{02c1}\u{02d0}-\u{02d1}\u{02e0}-\u{02e4}\u{0388}-\u{038a}\u{038e}-\u{03a1}\u{03a3}-\u{03ce}\u{03d0}-\u{03f5}\u{0400}-\u{0482}\u{048a}-\u{04ce}\u{04d0}-\u{04f5}\u{04f8}-\u{04f9}\u{0500}-\u{050f}\u{0531}-\u{0556}\u{0559}-\u{055f}\u{0561}-\u{0587}\u{0905}-\u{0939}\u{093d}-\u{0940}\u{0949}-\u{094c}\u{0958}-\u{0961}\u{0964}-\u{0970}\u{0982}-\u{0983}\u{0985}-\u{098c}\u{098f}-\u{0990}\u{0993}-\u{09a8}\u{09aa}-\u{09b0}\u{09b6}-\u{09b9}\u{09be}-\u{09c0}\u{09c7}-\u{09c8}\u{09cb}-\u{09cc}\u{09dc}-\u{09dd}\u{09df}-\u{09e1}\u{09e6}-\u{09f1}\u{09f4}-\u{09fa}\u{0a05}-\u{0a0a}\u{0a0f}-\u{0a10}\u{0a13}-\u{0a28}\u{0a2a}-\u{0a30}\u{0a32}-\u{0a33}\u{0a35}-\u{0a36}\u{0a38}-\u{0a39}\u{0a3e}-\u{0a40}\u{0a59}-\u{0a5c}\u{0a66}-\u{0a6f}\u{0a72}-\u{0a74}\u{0a85}-\u{0a8b}\u{0a8f}-\u{0a91}\u{0a93}-\u{0aa8}\u{0aaa}-\u{0ab0}\u{0ab2}-\u{0ab3}\u{0ab5}-\u{0ab9}\u{0abd}-\u{0ac0}\u{0acb}-\u{0acc}\u{0ae6}-\u{0aef}\u{0b02}-\u{0b03}\u{0b05}-\u{0b0c}\u{0b0f}-\u{0b10}\u{0b13}-\u{0b28}\u{0b2a}-\u{0b30}\u{0b32}-\u{0b33}\u{0b36}-\u{0b39}\u{0b3d}-\u{0b3e}\u{0b47}-\u{0b48}\u{0b4b}-\u{0b4c}\u{0b5c}-\u{0b5d}\u{0b5f}-\u{0b61}\u{0b66}-\u{0b70}\u{0b85}-\u{0b8a}\u{0b8e}-\u{0b90}\u{0b92}-\u{0b95}\u{0b99}-\u{0b9a}\u{0b9e}-\u{0b9f}\u{0ba3}-\u{0ba4}\u{0ba8}-\u{0baa}\u{0bae}-\u{0bb5}\u{0bb7}-\u{0bb9}\u{0bbe}-\u{0bbf}\u{0bc1}-\u{0bc2}\u{0bc6}-\u{0bc8}\u{0bca}-\u{0bcc}\u{0be7}-\u{0bf2}\u{0c01}-\u{0c03}\u{0c05}-\u{0c0c}\u{0c0e}-\u{0c10}\u{0c12}-\u{0c28}\u{0c2a}-\u{0c33}\u{0c35}-\u{0c39}\u{0c41}-\u{0c44}\u{0c60}-\u{0c61}\u{0c66}-\u{0c6f}\u{0c82}-\u{0c83}\u{0c85}-\u{0c8c}\u{0c8e}-\u{0c90}\u{0c92}-\u{0ca8}\u{0caa}-\u{0cb3}\u{0cb5}-\u{0cb9}\u{0cc0}-\u{0cc4}\u{0cc7}-\u{0cc8}\u{0cca}-\u{0ccb}\u{0cd5}-\u{0cd6}\u{0ce0}-\u{0ce1}\u{0ce6}-\u{0cef}\u{0d02}-\u{0d03}\u{0d05}-\u{0d0c}\u{0d0e}-\u{0d10}\u{0d12}-\u{0d28}\u{0d2a}-\u{0d39}\u{0d3e}-\u{0d40}\u{0d46}-\u{0d48}\u{0d4a}-\u{0d4c}\u{0d60}-\u{0d61}\u{0d66}-\u{0d6f}\u{0d82}-\u{0d83}\u{0d85}-\u{0d96}\u{0d9a}-\u{0db1}\u{0db3}-\u{0dbb}\u{0dc0}-\u{0dc6}\u{0dcf}-\u{0dd1}\u{0dd8}-\u{0ddf}\u{0df2}-\u{0df4}\u{0e01}-\u{0e30}\u{0e32}-\u{0e33}\u{0e40}-\u{0e46}\u{0e4f}-\u{0e5b}\u{0e81}-\u{0e82}\u{0e87}-\u{0e88}\u{0e94}-\u{0e97}\u{0e99}-\u{0e9f}\u{0ea1}-\u{0ea3}\u{0eaa}-\u{0eab}\u{0ead}-\u{0eb0}\u{0eb2}-\u{0eb3}\u{0ec0}-\u{0ec4}\u{0ed0}-\u{0ed9}\u{0edc}-\u{0edd}\u{0f00}-\u{0f17}\u{0f1a}-\u{0f34}\u{0f3e}-\u{0f47}\u{0f49}-\u{0f6a}\u{0f88}-\u{0f8b}\u{0fbe}-\u{0fc5}\u{0fc7}-\u{0fcc}\u{1000}-\u{1021}\u{1023}-\u{1027}\u{1029}-\u{102a}\u{1040}-\u{1057}\u{10a0}-\u{10c5}\u{10d0}-\u{10f8}\u{1100}-\u{1159}\u{115f}-\u{11a2}\u{11a8}-\u{11f9}\u{1200}-\u{1206}\u{1208}-\u{1246}\u{124a}-\u{124d}\u{1250}-\u{1256}\u{125a}-\u{125d}\u{1260}-\u{1286}\u{128a}-\u{128d}\u{1290}-\u{12ae}\u{12b2}-\u{12b5}\u{12b8}-\u{12be}\u{12c2}-\u{12c5}\u{12c8}-\u{12ce}\u{12d0}-\u{12d6}\u{12d8}-\u{12ee}\u{12f0}-\u{130e}\u{1312}-\u{1315}\u{1318}-\u{131e}\u{1320}-\u{1346}\u{1348}-\u{135a}\u{1361}-\u{137c}\u{13a0}-\u{13f4}\u{1401}-\u{1676}\u{1681}-\u{169a}\u{16a0}-\u{16f0}\u{1700}-\u{170c}\u{170e}-\u{1711}\u{1720}-\u{1731}\u{1735}-\u{1736}\u{1740}-\u{1751}\u{1760}-\u{176c}\u{176e}-\u{1770}\u{1780}-\u{17b6}\u{17be}-\u{17c5}\u{17c7}-\u{17c8}\u{17d4}-\u{17da}\u{17e0}-\u{17e9}\u{1810}-\u{1819}\u{1820}-\u{1877}\u{1880}-\u{18a8}\u{1e00}-\u{1e9b}\u{1ea0}-\u{1ef9}\u{1f00}-\u{1f15}\u{1f18}-\u{1f1d}\u{1f20}-\u{1f45}\u{1f48}-\u{1f4d}\u{1f50}-\u{1f57}\u{1f5f}-\u{1f7d}\u{1f80}-\u{1fb4}\u{1fb6}-\u{1fbc}\u{1fc2}-\u{1fc4}\u{1fc6}-\u{1fcc}\u{1fd0}-\u{1fd3}\u{1fd6}-\u{1fdb}\u{1fe0}-\u{1fec}\u{1ff2}-\u{1ff4}\u{1ff6}-\u{1ffc}\u{210a}-\u{2113}\u{2119}-\u{211d}\u{212a}-\u{212d}\u{212f}-\u{2131}\u{2133}-\u{2139}\u{213d}-\u{213f}\u{2145}-\u{2149}\u{2160}-\u{2183}\u{2336}-\u{237a}\u{249c}-\u{24e9}\u{3005}-\u{3007}\u{3021}-\u{3029}\u{3031}-\u{3035}\u{3038}-\u{303c}\u{3041}-\u{3096}\u{309d}-\u{309f}\u{30a1}-\u{30fa}\u{30fc}-\u{30ff}\u{3105}-\u{312c}\u{3131}-\u{318e}\u{3190}-\u{31b7}\u{31f0}-\u{321c}\u{3220}-\u{3243}\u{3260}-\u{327b}\u{327f}-\u{32b0}\u{32c0}-\u{32cb}\u{32d0}-\u{32fe}\u{3300}-\u{3376}\u{337b}-\u{33dd}\u{33e0}-\u{33fe}\u{3400}-\u{4db5}\u{4e00}-\u{9fa5}\u{a000}-\u{a48c}\u{ac00}-\u{d7a3}\u{e000}-\u{fa2d}\u{fa30}-\u{fa6a}\u{fb00}-\u{fb06}\u{fb13}-\u{fb17}\u{ff21}-\u{ff3a}\u{ff41}-\u{ff5a}\u{ff66}-\u{ffbe}\u{ffc2}-\u{ffc7}\u{ffca}-\u{ffcf}\u{ffd2}-\u{ffd7}\u{ffda}-\u{ffdc}\u{10300}-\u{1031e}\u{10320}-\u{10323}\u{10330}-\u{1034a}\u{10400}-\u{10425}\u{10428}-\u{1044d}\u{1d000}-\u{1d0f5}\u{1d100}-\u{1d126}\u{1d12a}-\u{1d166}\u{1d16a}-\u{1d172}\u{1d183}-\u{1d184}\u{1d18c}-\u{1d1a9}\u{1d1ae}-\u{1d1dd}\u{1d400}-\u{1d454}\u{1d456}-\u{1d49c}\u{1d49e}-\u{1d49f}\u{1d4a5}-\u{1d4a6}\u{1d4a9}-\u{1d4ac}\u{1d4ae}-\u{1d4b9}\u{1d4bd}-\u{1d4c0}\u{1d4c2}-\u{1d4c3}\u{1d4c5}-\u{1d505}\u{1d507}-\u{1d50a}\u{1d50d}-\u{1d514}\u{1d516}-\u{1d51c}\u{1d51e}-\u{1d539}\u{1d53b}-\u{1d53e}\u{1d540}-\u{1d544}\u{1d54a}-\u{1d550}\u{1d552}-\u{1d6a3}\u{1d6a8}-\u{1d7c9}\u{20000}-\u{2a6d6}\u{2f800}-\u{2fa1d}\u{f0000}-\u{ffffd}\u{100000}-\u{10fffd}\p{Cs}]).*?(?-mix:[\u{05be 05c0 05c3 061b 061f 06dd 0710 07b1 200f fb1d fb3e}\u{05d0}-\u{05ea}\u{05f0}-\u{05f4}\u{0621}-\u{063a}\u{0640}-\u{064a}\u{066d}-\u{066f}\u{0671}-\u{06d5}\u{06e5}-\u{06e6}\u{06fa}-\u{06fe}\u{0700}-\u{070d}\u{0712}-\u{072c}\u{0780}-\u{07a5}\u{fb1f}-\u{fb28}\u{fb2a}-\u{fb36}\u{fb38}-\u{fb3c}\u{fb40}-\u{fb41}\u{fb43}-\u{fb44}\u{fb46}-\u{fbb1}\u{fbd3}-\u{fd3d}\u{fd50}-\u{fd8f}\u{fd92}-\u{fdc7}\u{fdf0}-\u{fdfc}\u{fe70}-\u{fe74}\u{fe76}-\u{fefc}]))/.freeze - - BIDI_DESC_REQ3 = "A string with RandALCat characters must start and end with RandALCat characters." - - # Bidirectional Characters [StringPrep, §6], Requirement 3 - # >>> - # If a string contains any RandALCat character, a RandALCat - # character MUST be the first character of the string, and a - # RandALCat character MUST be the last character of the string. - BIDI_FAILS_REQ3 = /(?m-ix:\A(?-mix:[^\u{05be 05c0 05c3 061b 061f 06dd 0710 07b1 200f fb1d fb3e}\u{05d0}-\u{05ea}\u{05f0}-\u{05f4}\u{0621}-\u{063a}\u{0640}-\u{064a}\u{066d}-\u{066f}\u{0671}-\u{06d5}\u{06e5}-\u{06e6}\u{06fa}-\u{06fe}\u{0700}-\u{070d}\u{0712}-\u{072c}\u{0780}-\u{07a5}\u{fb1f}-\u{fb28}\u{fb2a}-\u{fb36}\u{fb38}-\u{fb3c}\u{fb40}-\u{fb41}\u{fb43}-\u{fb44}\u{fb46}-\u{fbb1}\u{fbd3}-\u{fd3d}\u{fd50}-\u{fd8f}\u{fd92}-\u{fdc7}\u{fdf0}-\u{fdfc}\u{fe70}-\u{fe74}\u{fe76}-\u{fefc}]).*?(?-mix:[\u{05be 05c0 05c3 061b 061f 06dd 0710 07b1 200f fb1d fb3e}\u{05d0}-\u{05ea}\u{05f0}-\u{05f4}\u{0621}-\u{063a}\u{0640}-\u{064a}\u{066d}-\u{066f}\u{0671}-\u{06d5}\u{06e5}-\u{06e6}\u{06fa}-\u{06fe}\u{0700}-\u{070d}\u{0712}-\u{072c}\u{0780}-\u{07a5}\u{fb1f}-\u{fb28}\u{fb2a}-\u{fb36}\u{fb38}-\u{fb3c}\u{fb40}-\u{fb41}\u{fb43}-\u{fb44}\u{fb46}-\u{fbb1}\u{fbd3}-\u{fd3d}\u{fd50}-\u{fd8f}\u{fd92}-\u{fdc7}\u{fdf0}-\u{fdfc}\u{fe70}-\u{fe74}\u{fe76}-\u{fefc}]))|(?m-ix:(?-mix:[\u{05be 05c0 05c3 061b 061f 06dd 0710 07b1 200f fb1d fb3e}\u{05d0}-\u{05ea}\u{05f0}-\u{05f4}\u{0621}-\u{063a}\u{0640}-\u{064a}\u{066d}-\u{066f}\u{0671}-\u{06d5}\u{06e5}-\u{06e6}\u{06fa}-\u{06fe}\u{0700}-\u{070d}\u{0712}-\u{072c}\u{0780}-\u{07a5}\u{fb1f}-\u{fb28}\u{fb2a}-\u{fb36}\u{fb38}-\u{fb3c}\u{fb40}-\u{fb41}\u{fb43}-\u{fb44}\u{fb46}-\u{fbb1}\u{fbd3}-\u{fd3d}\u{fd50}-\u{fd8f}\u{fd92}-\u{fdc7}\u{fdf0}-\u{fdfc}\u{fe70}-\u{fe74}\u{fe76}-\u{fefc}]).*?(?-mix:[^\u{05be 05c0 05c3 061b 061f 06dd 0710 07b1 200f fb1d fb3e}\u{05d0}-\u{05ea}\u{05f0}-\u{05f4}\u{0621}-\u{063a}\u{0640}-\u{064a}\u{066d}-\u{066f}\u{0671}-\u{06d5}\u{06e5}-\u{06e6}\u{06fa}-\u{06fe}\u{0700}-\u{070d}\u{0712}-\u{072c}\u{0780}-\u{07a5}\u{fb1f}-\u{fb28}\u{fb2a}-\u{fb36}\u{fb38}-\u{fb3c}\u{fb40}-\u{fb41}\u{fb43}-\u{fb44}\u{fb46}-\u{fbb1}\u{fbd3}-\u{fd3d}\u{fd50}-\u{fd8f}\u{fd92}-\u{fdc7}\u{fdf0}-\u{fdfc}\u{fe70}-\u{fe74}\u{fe76}-\u{fefc}])\z)/.freeze - - # Bidirectional Characters [StringPrep, §6] - BIDI_FAILURE = /(?-mix:(?m-ix:(?-mix:[\u{05be 05c0 05c3 061b 061f 06dd 0710 07b1 200f fb1d fb3e}\u{05d0}-\u{05ea}\u{05f0}-\u{05f4}\u{0621}-\u{063a}\u{0640}-\u{064a}\u{066d}-\u{066f}\u{0671}-\u{06d5}\u{06e5}-\u{06e6}\u{06fa}-\u{06fe}\u{0700}-\u{070d}\u{0712}-\u{072c}\u{0780}-\u{07a5}\u{fb1f}-\u{fb28}\u{fb2a}-\u{fb36}\u{fb38}-\u{fb3c}\u{fb40}-\u{fb41}\u{fb43}-\u{fb44}\u{fb46}-\u{fbb1}\u{fbd3}-\u{fd3d}\u{fd50}-\u{fd8f}\u{fd92}-\u{fdc7}\u{fdf0}-\u{fdfc}\u{fe70}-\u{fe74}\u{fe76}-\u{fefc}]).*?(?-mix:[\u{00aa 00b5 00ba 02ee 037a 0386 038c 0589 0903 0950 09b2 09d7 0a5e 0a83 0a8d 0ac9 0ad0 0ae0 0b40 0b57 0b83 0b9c 0bd7 0cbe 0cde 0d57 0dbd 0e84 0e8a 0e8d 0ea5 0ea7 0ebd 0ec6 0f36 0f38 0f7f 0f85 0fcf 102c 1031 1038 10fb 1248 1258 1288 12b0 12c0 1310 17dc 1f59 1f5b 1f5d 1fbe 200e 2071 207f 2102 2107 2115 2124 2126 2128 2395 1d4a2 1d4bb 1d546}\u{0041}-\u{005a}\u{0061}-\u{007a}\u{00c0}-\u{00d6}\u{00d8}-\u{00f6}\u{00f8}-\u{0220}\u{0222}-\u{0233}\u{0250}-\u{02ad}\u{02b0}-\u{02b8}\u{02bb}-\u{02c1}\u{02d0}-\u{02d1}\u{02e0}-\u{02e4}\u{0388}-\u{038a}\u{038e}-\u{03a1}\u{03a3}-\u{03ce}\u{03d0}-\u{03f5}\u{0400}-\u{0482}\u{048a}-\u{04ce}\u{04d0}-\u{04f5}\u{04f8}-\u{04f9}\u{0500}-\u{050f}\u{0531}-\u{0556}\u{0559}-\u{055f}\u{0561}-\u{0587}\u{0905}-\u{0939}\u{093d}-\u{0940}\u{0949}-\u{094c}\u{0958}-\u{0961}\u{0964}-\u{0970}\u{0982}-\u{0983}\u{0985}-\u{098c}\u{098f}-\u{0990}\u{0993}-\u{09a8}\u{09aa}-\u{09b0}\u{09b6}-\u{09b9}\u{09be}-\u{09c0}\u{09c7}-\u{09c8}\u{09cb}-\u{09cc}\u{09dc}-\u{09dd}\u{09df}-\u{09e1}\u{09e6}-\u{09f1}\u{09f4}-\u{09fa}\u{0a05}-\u{0a0a}\u{0a0f}-\u{0a10}\u{0a13}-\u{0a28}\u{0a2a}-\u{0a30}\u{0a32}-\u{0a33}\u{0a35}-\u{0a36}\u{0a38}-\u{0a39}\u{0a3e}-\u{0a40}\u{0a59}-\u{0a5c}\u{0a66}-\u{0a6f}\u{0a72}-\u{0a74}\u{0a85}-\u{0a8b}\u{0a8f}-\u{0a91}\u{0a93}-\u{0aa8}\u{0aaa}-\u{0ab0}\u{0ab2}-\u{0ab3}\u{0ab5}-\u{0ab9}\u{0abd}-\u{0ac0}\u{0acb}-\u{0acc}\u{0ae6}-\u{0aef}\u{0b02}-\u{0b03}\u{0b05}-\u{0b0c}\u{0b0f}-\u{0b10}\u{0b13}-\u{0b28}\u{0b2a}-\u{0b30}\u{0b32}-\u{0b33}\u{0b36}-\u{0b39}\u{0b3d}-\u{0b3e}\u{0b47}-\u{0b48}\u{0b4b}-\u{0b4c}\u{0b5c}-\u{0b5d}\u{0b5f}-\u{0b61}\u{0b66}-\u{0b70}\u{0b85}-\u{0b8a}\u{0b8e}-\u{0b90}\u{0b92}-\u{0b95}\u{0b99}-\u{0b9a}\u{0b9e}-\u{0b9f}\u{0ba3}-\u{0ba4}\u{0ba8}-\u{0baa}\u{0bae}-\u{0bb5}\u{0bb7}-\u{0bb9}\u{0bbe}-\u{0bbf}\u{0bc1}-\u{0bc2}\u{0bc6}-\u{0bc8}\u{0bca}-\u{0bcc}\u{0be7}-\u{0bf2}\u{0c01}-\u{0c03}\u{0c05}-\u{0c0c}\u{0c0e}-\u{0c10}\u{0c12}-\u{0c28}\u{0c2a}-\u{0c33}\u{0c35}-\u{0c39}\u{0c41}-\u{0c44}\u{0c60}-\u{0c61}\u{0c66}-\u{0c6f}\u{0c82}-\u{0c83}\u{0c85}-\u{0c8c}\u{0c8e}-\u{0c90}\u{0c92}-\u{0ca8}\u{0caa}-\u{0cb3}\u{0cb5}-\u{0cb9}\u{0cc0}-\u{0cc4}\u{0cc7}-\u{0cc8}\u{0cca}-\u{0ccb}\u{0cd5}-\u{0cd6}\u{0ce0}-\u{0ce1}\u{0ce6}-\u{0cef}\u{0d02}-\u{0d03}\u{0d05}-\u{0d0c}\u{0d0e}-\u{0d10}\u{0d12}-\u{0d28}\u{0d2a}-\u{0d39}\u{0d3e}-\u{0d40}\u{0d46}-\u{0d48}\u{0d4a}-\u{0d4c}\u{0d60}-\u{0d61}\u{0d66}-\u{0d6f}\u{0d82}-\u{0d83}\u{0d85}-\u{0d96}\u{0d9a}-\u{0db1}\u{0db3}-\u{0dbb}\u{0dc0}-\u{0dc6}\u{0dcf}-\u{0dd1}\u{0dd8}-\u{0ddf}\u{0df2}-\u{0df4}\u{0e01}-\u{0e30}\u{0e32}-\u{0e33}\u{0e40}-\u{0e46}\u{0e4f}-\u{0e5b}\u{0e81}-\u{0e82}\u{0e87}-\u{0e88}\u{0e94}-\u{0e97}\u{0e99}-\u{0e9f}\u{0ea1}-\u{0ea3}\u{0eaa}-\u{0eab}\u{0ead}-\u{0eb0}\u{0eb2}-\u{0eb3}\u{0ec0}-\u{0ec4}\u{0ed0}-\u{0ed9}\u{0edc}-\u{0edd}\u{0f00}-\u{0f17}\u{0f1a}-\u{0f34}\u{0f3e}-\u{0f47}\u{0f49}-\u{0f6a}\u{0f88}-\u{0f8b}\u{0fbe}-\u{0fc5}\u{0fc7}-\u{0fcc}\u{1000}-\u{1021}\u{1023}-\u{1027}\u{1029}-\u{102a}\u{1040}-\u{1057}\u{10a0}-\u{10c5}\u{10d0}-\u{10f8}\u{1100}-\u{1159}\u{115f}-\u{11a2}\u{11a8}-\u{11f9}\u{1200}-\u{1206}\u{1208}-\u{1246}\u{124a}-\u{124d}\u{1250}-\u{1256}\u{125a}-\u{125d}\u{1260}-\u{1286}\u{128a}-\u{128d}\u{1290}-\u{12ae}\u{12b2}-\u{12b5}\u{12b8}-\u{12be}\u{12c2}-\u{12c5}\u{12c8}-\u{12ce}\u{12d0}-\u{12d6}\u{12d8}-\u{12ee}\u{12f0}-\u{130e}\u{1312}-\u{1315}\u{1318}-\u{131e}\u{1320}-\u{1346}\u{1348}-\u{135a}\u{1361}-\u{137c}\u{13a0}-\u{13f4}\u{1401}-\u{1676}\u{1681}-\u{169a}\u{16a0}-\u{16f0}\u{1700}-\u{170c}\u{170e}-\u{1711}\u{1720}-\u{1731}\u{1735}-\u{1736}\u{1740}-\u{1751}\u{1760}-\u{176c}\u{176e}-\u{1770}\u{1780}-\u{17b6}\u{17be}-\u{17c5}\u{17c7}-\u{17c8}\u{17d4}-\u{17da}\u{17e0}-\u{17e9}\u{1810}-\u{1819}\u{1820}-\u{1877}\u{1880}-\u{18a8}\u{1e00}-\u{1e9b}\u{1ea0}-\u{1ef9}\u{1f00}-\u{1f15}\u{1f18}-\u{1f1d}\u{1f20}-\u{1f45}\u{1f48}-\u{1f4d}\u{1f50}-\u{1f57}\u{1f5f}-\u{1f7d}\u{1f80}-\u{1fb4}\u{1fb6}-\u{1fbc}\u{1fc2}-\u{1fc4}\u{1fc6}-\u{1fcc}\u{1fd0}-\u{1fd3}\u{1fd6}-\u{1fdb}\u{1fe0}-\u{1fec}\u{1ff2}-\u{1ff4}\u{1ff6}-\u{1ffc}\u{210a}-\u{2113}\u{2119}-\u{211d}\u{212a}-\u{212d}\u{212f}-\u{2131}\u{2133}-\u{2139}\u{213d}-\u{213f}\u{2145}-\u{2149}\u{2160}-\u{2183}\u{2336}-\u{237a}\u{249c}-\u{24e9}\u{3005}-\u{3007}\u{3021}-\u{3029}\u{3031}-\u{3035}\u{3038}-\u{303c}\u{3041}-\u{3096}\u{309d}-\u{309f}\u{30a1}-\u{30fa}\u{30fc}-\u{30ff}\u{3105}-\u{312c}\u{3131}-\u{318e}\u{3190}-\u{31b7}\u{31f0}-\u{321c}\u{3220}-\u{3243}\u{3260}-\u{327b}\u{327f}-\u{32b0}\u{32c0}-\u{32cb}\u{32d0}-\u{32fe}\u{3300}-\u{3376}\u{337b}-\u{33dd}\u{33e0}-\u{33fe}\u{3400}-\u{4db5}\u{4e00}-\u{9fa5}\u{a000}-\u{a48c}\u{ac00}-\u{d7a3}\u{e000}-\u{fa2d}\u{fa30}-\u{fa6a}\u{fb00}-\u{fb06}\u{fb13}-\u{fb17}\u{ff21}-\u{ff3a}\u{ff41}-\u{ff5a}\u{ff66}-\u{ffbe}\u{ffc2}-\u{ffc7}\u{ffca}-\u{ffcf}\u{ffd2}-\u{ffd7}\u{ffda}-\u{ffdc}\u{10300}-\u{1031e}\u{10320}-\u{10323}\u{10330}-\u{1034a}\u{10400}-\u{10425}\u{10428}-\u{1044d}\u{1d000}-\u{1d0f5}\u{1d100}-\u{1d126}\u{1d12a}-\u{1d166}\u{1d16a}-\u{1d172}\u{1d183}-\u{1d184}\u{1d18c}-\u{1d1a9}\u{1d1ae}-\u{1d1dd}\u{1d400}-\u{1d454}\u{1d456}-\u{1d49c}\u{1d49e}-\u{1d49f}\u{1d4a5}-\u{1d4a6}\u{1d4a9}-\u{1d4ac}\u{1d4ae}-\u{1d4b9}\u{1d4bd}-\u{1d4c0}\u{1d4c2}-\u{1d4c3}\u{1d4c5}-\u{1d505}\u{1d507}-\u{1d50a}\u{1d50d}-\u{1d514}\u{1d516}-\u{1d51c}\u{1d51e}-\u{1d539}\u{1d53b}-\u{1d53e}\u{1d540}-\u{1d544}\u{1d54a}-\u{1d550}\u{1d552}-\u{1d6a3}\u{1d6a8}-\u{1d7c9}\u{20000}-\u{2a6d6}\u{2f800}-\u{2fa1d}\u{f0000}-\u{ffffd}\u{100000}-\u{10fffd}\p{Cs}]))|(?m-ix:(?-mix:[\u{00aa 00b5 00ba 02ee 037a 0386 038c 0589 0903 0950 09b2 09d7 0a5e 0a83 0a8d 0ac9 0ad0 0ae0 0b40 0b57 0b83 0b9c 0bd7 0cbe 0cde 0d57 0dbd 0e84 0e8a 0e8d 0ea5 0ea7 0ebd 0ec6 0f36 0f38 0f7f 0f85 0fcf 102c 1031 1038 10fb 1248 1258 1288 12b0 12c0 1310 17dc 1f59 1f5b 1f5d 1fbe 200e 2071 207f 2102 2107 2115 2124 2126 2128 2395 1d4a2 1d4bb 1d546}\u{0041}-\u{005a}\u{0061}-\u{007a}\u{00c0}-\u{00d6}\u{00d8}-\u{00f6}\u{00f8}-\u{0220}\u{0222}-\u{0233}\u{0250}-\u{02ad}\u{02b0}-\u{02b8}\u{02bb}-\u{02c1}\u{02d0}-\u{02d1}\u{02e0}-\u{02e4}\u{0388}-\u{038a}\u{038e}-\u{03a1}\u{03a3}-\u{03ce}\u{03d0}-\u{03f5}\u{0400}-\u{0482}\u{048a}-\u{04ce}\u{04d0}-\u{04f5}\u{04f8}-\u{04f9}\u{0500}-\u{050f}\u{0531}-\u{0556}\u{0559}-\u{055f}\u{0561}-\u{0587}\u{0905}-\u{0939}\u{093d}-\u{0940}\u{0949}-\u{094c}\u{0958}-\u{0961}\u{0964}-\u{0970}\u{0982}-\u{0983}\u{0985}-\u{098c}\u{098f}-\u{0990}\u{0993}-\u{09a8}\u{09aa}-\u{09b0}\u{09b6}-\u{09b9}\u{09be}-\u{09c0}\u{09c7}-\u{09c8}\u{09cb}-\u{09cc}\u{09dc}-\u{09dd}\u{09df}-\u{09e1}\u{09e6}-\u{09f1}\u{09f4}-\u{09fa}\u{0a05}-\u{0a0a}\u{0a0f}-\u{0a10}\u{0a13}-\u{0a28}\u{0a2a}-\u{0a30}\u{0a32}-\u{0a33}\u{0a35}-\u{0a36}\u{0a38}-\u{0a39}\u{0a3e}-\u{0a40}\u{0a59}-\u{0a5c}\u{0a66}-\u{0a6f}\u{0a72}-\u{0a74}\u{0a85}-\u{0a8b}\u{0a8f}-\u{0a91}\u{0a93}-\u{0aa8}\u{0aaa}-\u{0ab0}\u{0ab2}-\u{0ab3}\u{0ab5}-\u{0ab9}\u{0abd}-\u{0ac0}\u{0acb}-\u{0acc}\u{0ae6}-\u{0aef}\u{0b02}-\u{0b03}\u{0b05}-\u{0b0c}\u{0b0f}-\u{0b10}\u{0b13}-\u{0b28}\u{0b2a}-\u{0b30}\u{0b32}-\u{0b33}\u{0b36}-\u{0b39}\u{0b3d}-\u{0b3e}\u{0b47}-\u{0b48}\u{0b4b}-\u{0b4c}\u{0b5c}-\u{0b5d}\u{0b5f}-\u{0b61}\u{0b66}-\u{0b70}\u{0b85}-\u{0b8a}\u{0b8e}-\u{0b90}\u{0b92}-\u{0b95}\u{0b99}-\u{0b9a}\u{0b9e}-\u{0b9f}\u{0ba3}-\u{0ba4}\u{0ba8}-\u{0baa}\u{0bae}-\u{0bb5}\u{0bb7}-\u{0bb9}\u{0bbe}-\u{0bbf}\u{0bc1}-\u{0bc2}\u{0bc6}-\u{0bc8}\u{0bca}-\u{0bcc}\u{0be7}-\u{0bf2}\u{0c01}-\u{0c03}\u{0c05}-\u{0c0c}\u{0c0e}-\u{0c10}\u{0c12}-\u{0c28}\u{0c2a}-\u{0c33}\u{0c35}-\u{0c39}\u{0c41}-\u{0c44}\u{0c60}-\u{0c61}\u{0c66}-\u{0c6f}\u{0c82}-\u{0c83}\u{0c85}-\u{0c8c}\u{0c8e}-\u{0c90}\u{0c92}-\u{0ca8}\u{0caa}-\u{0cb3}\u{0cb5}-\u{0cb9}\u{0cc0}-\u{0cc4}\u{0cc7}-\u{0cc8}\u{0cca}-\u{0ccb}\u{0cd5}-\u{0cd6}\u{0ce0}-\u{0ce1}\u{0ce6}-\u{0cef}\u{0d02}-\u{0d03}\u{0d05}-\u{0d0c}\u{0d0e}-\u{0d10}\u{0d12}-\u{0d28}\u{0d2a}-\u{0d39}\u{0d3e}-\u{0d40}\u{0d46}-\u{0d48}\u{0d4a}-\u{0d4c}\u{0d60}-\u{0d61}\u{0d66}-\u{0d6f}\u{0d82}-\u{0d83}\u{0d85}-\u{0d96}\u{0d9a}-\u{0db1}\u{0db3}-\u{0dbb}\u{0dc0}-\u{0dc6}\u{0dcf}-\u{0dd1}\u{0dd8}-\u{0ddf}\u{0df2}-\u{0df4}\u{0e01}-\u{0e30}\u{0e32}-\u{0e33}\u{0e40}-\u{0e46}\u{0e4f}-\u{0e5b}\u{0e81}-\u{0e82}\u{0e87}-\u{0e88}\u{0e94}-\u{0e97}\u{0e99}-\u{0e9f}\u{0ea1}-\u{0ea3}\u{0eaa}-\u{0eab}\u{0ead}-\u{0eb0}\u{0eb2}-\u{0eb3}\u{0ec0}-\u{0ec4}\u{0ed0}-\u{0ed9}\u{0edc}-\u{0edd}\u{0f00}-\u{0f17}\u{0f1a}-\u{0f34}\u{0f3e}-\u{0f47}\u{0f49}-\u{0f6a}\u{0f88}-\u{0f8b}\u{0fbe}-\u{0fc5}\u{0fc7}-\u{0fcc}\u{1000}-\u{1021}\u{1023}-\u{1027}\u{1029}-\u{102a}\u{1040}-\u{1057}\u{10a0}-\u{10c5}\u{10d0}-\u{10f8}\u{1100}-\u{1159}\u{115f}-\u{11a2}\u{11a8}-\u{11f9}\u{1200}-\u{1206}\u{1208}-\u{1246}\u{124a}-\u{124d}\u{1250}-\u{1256}\u{125a}-\u{125d}\u{1260}-\u{1286}\u{128a}-\u{128d}\u{1290}-\u{12ae}\u{12b2}-\u{12b5}\u{12b8}-\u{12be}\u{12c2}-\u{12c5}\u{12c8}-\u{12ce}\u{12d0}-\u{12d6}\u{12d8}-\u{12ee}\u{12f0}-\u{130e}\u{1312}-\u{1315}\u{1318}-\u{131e}\u{1320}-\u{1346}\u{1348}-\u{135a}\u{1361}-\u{137c}\u{13a0}-\u{13f4}\u{1401}-\u{1676}\u{1681}-\u{169a}\u{16a0}-\u{16f0}\u{1700}-\u{170c}\u{170e}-\u{1711}\u{1720}-\u{1731}\u{1735}-\u{1736}\u{1740}-\u{1751}\u{1760}-\u{176c}\u{176e}-\u{1770}\u{1780}-\u{17b6}\u{17be}-\u{17c5}\u{17c7}-\u{17c8}\u{17d4}-\u{17da}\u{17e0}-\u{17e9}\u{1810}-\u{1819}\u{1820}-\u{1877}\u{1880}-\u{18a8}\u{1e00}-\u{1e9b}\u{1ea0}-\u{1ef9}\u{1f00}-\u{1f15}\u{1f18}-\u{1f1d}\u{1f20}-\u{1f45}\u{1f48}-\u{1f4d}\u{1f50}-\u{1f57}\u{1f5f}-\u{1f7d}\u{1f80}-\u{1fb4}\u{1fb6}-\u{1fbc}\u{1fc2}-\u{1fc4}\u{1fc6}-\u{1fcc}\u{1fd0}-\u{1fd3}\u{1fd6}-\u{1fdb}\u{1fe0}-\u{1fec}\u{1ff2}-\u{1ff4}\u{1ff6}-\u{1ffc}\u{210a}-\u{2113}\u{2119}-\u{211d}\u{212a}-\u{212d}\u{212f}-\u{2131}\u{2133}-\u{2139}\u{213d}-\u{213f}\u{2145}-\u{2149}\u{2160}-\u{2183}\u{2336}-\u{237a}\u{249c}-\u{24e9}\u{3005}-\u{3007}\u{3021}-\u{3029}\u{3031}-\u{3035}\u{3038}-\u{303c}\u{3041}-\u{3096}\u{309d}-\u{309f}\u{30a1}-\u{30fa}\u{30fc}-\u{30ff}\u{3105}-\u{312c}\u{3131}-\u{318e}\u{3190}-\u{31b7}\u{31f0}-\u{321c}\u{3220}-\u{3243}\u{3260}-\u{327b}\u{327f}-\u{32b0}\u{32c0}-\u{32cb}\u{32d0}-\u{32fe}\u{3300}-\u{3376}\u{337b}-\u{33dd}\u{33e0}-\u{33fe}\u{3400}-\u{4db5}\u{4e00}-\u{9fa5}\u{a000}-\u{a48c}\u{ac00}-\u{d7a3}\u{e000}-\u{fa2d}\u{fa30}-\u{fa6a}\u{fb00}-\u{fb06}\u{fb13}-\u{fb17}\u{ff21}-\u{ff3a}\u{ff41}-\u{ff5a}\u{ff66}-\u{ffbe}\u{ffc2}-\u{ffc7}\u{ffca}-\u{ffcf}\u{ffd2}-\u{ffd7}\u{ffda}-\u{ffdc}\u{10300}-\u{1031e}\u{10320}-\u{10323}\u{10330}-\u{1034a}\u{10400}-\u{10425}\u{10428}-\u{1044d}\u{1d000}-\u{1d0f5}\u{1d100}-\u{1d126}\u{1d12a}-\u{1d166}\u{1d16a}-\u{1d172}\u{1d183}-\u{1d184}\u{1d18c}-\u{1d1a9}\u{1d1ae}-\u{1d1dd}\u{1d400}-\u{1d454}\u{1d456}-\u{1d49c}\u{1d49e}-\u{1d49f}\u{1d4a5}-\u{1d4a6}\u{1d4a9}-\u{1d4ac}\u{1d4ae}-\u{1d4b9}\u{1d4bd}-\u{1d4c0}\u{1d4c2}-\u{1d4c3}\u{1d4c5}-\u{1d505}\u{1d507}-\u{1d50a}\u{1d50d}-\u{1d514}\u{1d516}-\u{1d51c}\u{1d51e}-\u{1d539}\u{1d53b}-\u{1d53e}\u{1d540}-\u{1d544}\u{1d54a}-\u{1d550}\u{1d552}-\u{1d6a3}\u{1d6a8}-\u{1d7c9}\u{20000}-\u{2a6d6}\u{2f800}-\u{2fa1d}\u{f0000}-\u{ffffd}\u{100000}-\u{10fffd}\p{Cs}]).*?(?-mix:[\u{05be 05c0 05c3 061b 061f 06dd 0710 07b1 200f fb1d fb3e}\u{05d0}-\u{05ea}\u{05f0}-\u{05f4}\u{0621}-\u{063a}\u{0640}-\u{064a}\u{066d}-\u{066f}\u{0671}-\u{06d5}\u{06e5}-\u{06e6}\u{06fa}-\u{06fe}\u{0700}-\u{070d}\u{0712}-\u{072c}\u{0780}-\u{07a5}\u{fb1f}-\u{fb28}\u{fb2a}-\u{fb36}\u{fb38}-\u{fb3c}\u{fb40}-\u{fb41}\u{fb43}-\u{fb44}\u{fb46}-\u{fbb1}\u{fbd3}-\u{fd3d}\u{fd50}-\u{fd8f}\u{fd92}-\u{fdc7}\u{fdf0}-\u{fdfc}\u{fe70}-\u{fe74}\u{fe76}-\u{fefc}])))|(?-mix:(?m-ix:\A(?-mix:[^\u{05be 05c0 05c3 061b 061f 06dd 0710 07b1 200f fb1d fb3e}\u{05d0}-\u{05ea}\u{05f0}-\u{05f4}\u{0621}-\u{063a}\u{0640}-\u{064a}\u{066d}-\u{066f}\u{0671}-\u{06d5}\u{06e5}-\u{06e6}\u{06fa}-\u{06fe}\u{0700}-\u{070d}\u{0712}-\u{072c}\u{0780}-\u{07a5}\u{fb1f}-\u{fb28}\u{fb2a}-\u{fb36}\u{fb38}-\u{fb3c}\u{fb40}-\u{fb41}\u{fb43}-\u{fb44}\u{fb46}-\u{fbb1}\u{fbd3}-\u{fd3d}\u{fd50}-\u{fd8f}\u{fd92}-\u{fdc7}\u{fdf0}-\u{fdfc}\u{fe70}-\u{fe74}\u{fe76}-\u{fefc}]).*?(?-mix:[\u{05be 05c0 05c3 061b 061f 06dd 0710 07b1 200f fb1d fb3e}\u{05d0}-\u{05ea}\u{05f0}-\u{05f4}\u{0621}-\u{063a}\u{0640}-\u{064a}\u{066d}-\u{066f}\u{0671}-\u{06d5}\u{06e5}-\u{06e6}\u{06fa}-\u{06fe}\u{0700}-\u{070d}\u{0712}-\u{072c}\u{0780}-\u{07a5}\u{fb1f}-\u{fb28}\u{fb2a}-\u{fb36}\u{fb38}-\u{fb3c}\u{fb40}-\u{fb41}\u{fb43}-\u{fb44}\u{fb46}-\u{fbb1}\u{fbd3}-\u{fd3d}\u{fd50}-\u{fd8f}\u{fd92}-\u{fdc7}\u{fdf0}-\u{fdfc}\u{fe70}-\u{fe74}\u{fe76}-\u{fefc}]))|(?m-ix:(?-mix:[\u{05be 05c0 05c3 061b 061f 06dd 0710 07b1 200f fb1d fb3e}\u{05d0}-\u{05ea}\u{05f0}-\u{05f4}\u{0621}-\u{063a}\u{0640}-\u{064a}\u{066d}-\u{066f}\u{0671}-\u{06d5}\u{06e5}-\u{06e6}\u{06fa}-\u{06fe}\u{0700}-\u{070d}\u{0712}-\u{072c}\u{0780}-\u{07a5}\u{fb1f}-\u{fb28}\u{fb2a}-\u{fb36}\u{fb38}-\u{fb3c}\u{fb40}-\u{fb41}\u{fb43}-\u{fb44}\u{fb46}-\u{fbb1}\u{fbd3}-\u{fd3d}\u{fd50}-\u{fd8f}\u{fd92}-\u{fdc7}\u{fdf0}-\u{fdfc}\u{fe70}-\u{fe74}\u{fe76}-\u{fefc}]).*?(?-mix:[^\u{05be 05c0 05c3 061b 061f 06dd 0710 07b1 200f fb1d fb3e}\u{05d0}-\u{05ea}\u{05f0}-\u{05f4}\u{0621}-\u{063a}\u{0640}-\u{064a}\u{066d}-\u{066f}\u{0671}-\u{06d5}\u{06e5}-\u{06e6}\u{06fa}-\u{06fe}\u{0700}-\u{070d}\u{0712}-\u{072c}\u{0780}-\u{07a5}\u{fb1f}-\u{fb28}\u{fb2a}-\u{fb36}\u{fb38}-\u{fb3c}\u{fb40}-\u{fb41}\u{fb43}-\u{fb44}\u{fb46}-\u{fbb1}\u{fbd3}-\u{fd3d}\u{fd50}-\u{fd8f}\u{fd92}-\u{fdc7}\u{fdf0}-\u{fdfc}\u{fe70}-\u{fe74}\u{fe76}-\u{fefc}])\z))/.freeze - - # Names of each codepoint table in the RFC-3454 appendices - TITLES = { - "A.1" => "Unassigned code points in Unicode 3.2", - "B.1" => "Commonly mapped to nothing", - "B.2" => "Mapping for case-folding used with NFKC", - "B.3" => "Mapping for case-folding used with no normalization", - "C.1" => "Space characters", - "C.1.1" => "ASCII space characters", - "C.1.2" => "Non-ASCII space characters", - "C.2" => "Control characters", - "C.2.1" => "ASCII control characters", - "C.2.2" => "Non-ASCII control characters", - "C.3" => "Private use", - "C.4" => "Non-character code points", - "C.5" => "Surrogate codes", - "C.6" => "Inappropriate for plain text", - "C.7" => "Inappropriate for canonical representation", - "C.8" => "Change display properties or are deprecated", - "C.9" => "Tagging characters", - "D.1" => "Characters with bidirectional property \"R\" or \"AL\"", - "D.2" => "Characters with bidirectional property \"L\"", - }.freeze - - # Regexps matching each codepoint table in the RFC-3454 appendices - REGEXPS = { - "A.1" => IN_A_1, - "B.1" => IN_B_1, - "B.2" => IN_B_2, - "B.3" => IN_B_3, - "C.1.1" => IN_C_1_1, - "C.1.2" => IN_C_1_2, - "C.2.1" => IN_C_2_1, - "C.2.2" => IN_C_2_2, - "C.3" => IN_C_3, - "C.4" => IN_C_4, - "C.5" => IN_C_5, - "C.6" => IN_C_6, - "C.7" => IN_C_7, - "C.8" => IN_C_8, - "C.9" => IN_C_9, - "D.1" => IN_D_1, - "D.2" => IN_D_2, - }.freeze - - MAPPINGS = { - "B.1" => [IN_B_1, MAP_B_1].freeze, - "B.2" => [IN_B_2, MAP_B_2].freeze, - "B.3" => [IN_B_3, MAP_B_3].freeze, - }.freeze + autoload :IN_A_1, "#{__dir__}/tables/in_a_1.rb" + autoload :IN_B_1, "#{__dir__}/tables/in_b_1.rb" + autoload :IN_B_2, "#{__dir__}/tables/in_b_2.rb" + autoload :IN_B_3, "#{__dir__}/tables/in_b_3.rb" + autoload :IN_C_1_1, "#{__dir__}/tables/in_c_1_1.rb" + autoload :IN_C_1_2, "#{__dir__}/tables/in_c_1_2.rb" + autoload :IN_C_2_1, "#{__dir__}/tables/in_c_2_1.rb" + autoload :IN_C_2_2, "#{__dir__}/tables/in_c_2_2.rb" + autoload :IN_C_3, "#{__dir__}/tables/in_c_3.rb" + autoload :IN_C_4, "#{__dir__}/tables/in_c_4.rb" + autoload :IN_C_5, "#{__dir__}/tables/in_c_5.rb" + autoload :IN_C_6, "#{__dir__}/tables/in_c_6.rb" + autoload :IN_C_7, "#{__dir__}/tables/in_c_7.rb" + autoload :IN_C_8, "#{__dir__}/tables/in_c_8.rb" + autoload :IN_C_9, "#{__dir__}/tables/in_c_9.rb" + autoload :IN_D_1, "#{__dir__}/tables/in_d_1.rb" + autoload :IN_D_1_NEGATED, "#{__dir__}/tables/in_d_1_negated.rb" + autoload :IN_D_2, "#{__dir__}/tables/in_d_2.rb" + autoload :MAP_B_1, "#{__dir__}/tables/map_b_1.rb" + autoload :MAP_B_2, "#{__dir__}/tables/map_b_2.rb" + autoload :MAP_B_3, "#{__dir__}/tables/map_b_3.rb" + autoload :BIDI_DESC_REQ2, "#{__dir__}/tables/bidi_desc_req2.rb" + autoload :BIDI_FAILS_REQ2, "#{__dir__}/tables/bidi_fails_req2.rb" + autoload :BIDI_DESC_REQ3, "#{__dir__}/tables/bidi_desc_req3.rb" + autoload :BIDI_FAILS_REQ3, "#{__dir__}/tables/bidi_fails_req3.rb" + autoload :BIDI_FAILURE, "#{__dir__}/tables/bidi_failure.rb" + autoload :SASLPREP_PROHIBIT, "#{__dir__}/tables/saslprep_prohibit.rb" + autoload :SASLPREP_PROHIBIT_STORED, "#{__dir__}/tables/saslprep_prohibit_stored.rb" + autoload :TRACE_PROHIBIT, "#{__dir__}/tables/trace_prohibit.rb" + autoload :TRACE_PROHIBIT_STORED, "#{__dir__}/tables/trace_prohibit_stored.rb" + autoload :NAMEPREP_PROHIBIT, "#{__dir__}/tables/nameprep_prohibit.rb" + autoload :NAMEPREP_PROHIBIT_STORED, "#{__dir__}/tables/nameprep_prohibit_stored.rb" + autoload :TITLES, "#{__dir__}/tables/titles.rb" + autoload :REGEXPS, "#{__dir__}/tables/regexps.rb" + autoload :MAPPINGS, "#{__dir__}/tables/mappings.rb" end end diff --git a/lib/net/imap/stringprep/tables/bidi_desc_req2.rb b/lib/net/imap/stringprep/tables/bidi_desc_req2.rb new file mode 100644 index 00000000..0b441fc2 --- /dev/null +++ b/lib/net/imap/stringprep/tables/bidi_desc_req2.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +#-- +# This file is generated by `rake stringprep:tables`. Don't edit directly. +#++ + +module Net::IMAP::StringPrep + module Tables + + BIDI_DESC_REQ2 = "A string with RandALCat characters must not contain LCat characters." + + end +end diff --git a/lib/net/imap/stringprep/tables/bidi_desc_req3.rb b/lib/net/imap/stringprep/tables/bidi_desc_req3.rb new file mode 100644 index 00000000..ad70746d --- /dev/null +++ b/lib/net/imap/stringprep/tables/bidi_desc_req3.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +#-- +# This file is generated by `rake stringprep:tables`. Don't edit directly. +#++ + +module Net::IMAP::StringPrep + module Tables + + BIDI_DESC_REQ3 = "A string with RandALCat characters must start and end with RandALCat characters." + + end +end diff --git a/lib/net/imap/stringprep/tables/bidi_fails_req2.rb b/lib/net/imap/stringprep/tables/bidi_fails_req2.rb new file mode 100644 index 00000000..b906c179 --- /dev/null +++ b/lib/net/imap/stringprep/tables/bidi_fails_req2.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +#-- +# This file is generated by `rake stringprep:tables`. Don't edit directly. +#++ + +module Net::IMAP::StringPrep + module Tables + + # Bidirectional Characters [StringPrep, §6], Requirement 2 + # >>> + # If a string contains any RandALCat character, the string MUST NOT + # contain any LCat character. + BIDI_FAILS_REQ2 = /(?m-ix:(?-mix:[\u{05be 05c0 05c3 061b 061f 06dd 0710 07b1 200f fb1d fb3e}\u{05d0}-\u{05ea}\u{05f0}-\u{05f4}\u{0621}-\u{063a}\u{0640}-\u{064a}\u{066d}-\u{066f}\u{0671}-\u{06d5}\u{06e5}-\u{06e6}\u{06fa}-\u{06fe}\u{0700}-\u{070d}\u{0712}-\u{072c}\u{0780}-\u{07a5}\u{fb1f}-\u{fb28}\u{fb2a}-\u{fb36}\u{fb38}-\u{fb3c}\u{fb40}-\u{fb41}\u{fb43}-\u{fb44}\u{fb46}-\u{fbb1}\u{fbd3}-\u{fd3d}\u{fd50}-\u{fd8f}\u{fd92}-\u{fdc7}\u{fdf0}-\u{fdfc}\u{fe70}-\u{fe74}\u{fe76}-\u{fefc}]).*?(?-mix:[\u{00aa 00b5 00ba 02ee 037a 0386 038c 0589 0903 0950 09b2 09d7 0a5e 0a83 0a8d 0ac9 0ad0 0ae0 0b40 0b57 0b83 0b9c 0bd7 0cbe 0cde 0d57 0dbd 0e84 0e8a 0e8d 0ea5 0ea7 0ebd 0ec6 0f36 0f38 0f7f 0f85 0fcf 102c 1031 1038 10fb 1248 1258 1288 12b0 12c0 1310 17dc 1f59 1f5b 1f5d 1fbe 200e 2071 207f 2102 2107 2115 2124 2126 2128 2395 1d4a2 1d4bb 1d546}\u{0041}-\u{005a}\u{0061}-\u{007a}\u{00c0}-\u{00d6}\u{00d8}-\u{00f6}\u{00f8}-\u{0220}\u{0222}-\u{0233}\u{0250}-\u{02ad}\u{02b0}-\u{02b8}\u{02bb}-\u{02c1}\u{02d0}-\u{02d1}\u{02e0}-\u{02e4}\u{0388}-\u{038a}\u{038e}-\u{03a1}\u{03a3}-\u{03ce}\u{03d0}-\u{03f5}\u{0400}-\u{0482}\u{048a}-\u{04ce}\u{04d0}-\u{04f5}\u{04f8}-\u{04f9}\u{0500}-\u{050f}\u{0531}-\u{0556}\u{0559}-\u{055f}\u{0561}-\u{0587}\u{0905}-\u{0939}\u{093d}-\u{0940}\u{0949}-\u{094c}\u{0958}-\u{0961}\u{0964}-\u{0970}\u{0982}-\u{0983}\u{0985}-\u{098c}\u{098f}-\u{0990}\u{0993}-\u{09a8}\u{09aa}-\u{09b0}\u{09b6}-\u{09b9}\u{09be}-\u{09c0}\u{09c7}-\u{09c8}\u{09cb}-\u{09cc}\u{09dc}-\u{09dd}\u{09df}-\u{09e1}\u{09e6}-\u{09f1}\u{09f4}-\u{09fa}\u{0a05}-\u{0a0a}\u{0a0f}-\u{0a10}\u{0a13}-\u{0a28}\u{0a2a}-\u{0a30}\u{0a32}-\u{0a33}\u{0a35}-\u{0a36}\u{0a38}-\u{0a39}\u{0a3e}-\u{0a40}\u{0a59}-\u{0a5c}\u{0a66}-\u{0a6f}\u{0a72}-\u{0a74}\u{0a85}-\u{0a8b}\u{0a8f}-\u{0a91}\u{0a93}-\u{0aa8}\u{0aaa}-\u{0ab0}\u{0ab2}-\u{0ab3}\u{0ab5}-\u{0ab9}\u{0abd}-\u{0ac0}\u{0acb}-\u{0acc}\u{0ae6}-\u{0aef}\u{0b02}-\u{0b03}\u{0b05}-\u{0b0c}\u{0b0f}-\u{0b10}\u{0b13}-\u{0b28}\u{0b2a}-\u{0b30}\u{0b32}-\u{0b33}\u{0b36}-\u{0b39}\u{0b3d}-\u{0b3e}\u{0b47}-\u{0b48}\u{0b4b}-\u{0b4c}\u{0b5c}-\u{0b5d}\u{0b5f}-\u{0b61}\u{0b66}-\u{0b70}\u{0b85}-\u{0b8a}\u{0b8e}-\u{0b90}\u{0b92}-\u{0b95}\u{0b99}-\u{0b9a}\u{0b9e}-\u{0b9f}\u{0ba3}-\u{0ba4}\u{0ba8}-\u{0baa}\u{0bae}-\u{0bb5}\u{0bb7}-\u{0bb9}\u{0bbe}-\u{0bbf}\u{0bc1}-\u{0bc2}\u{0bc6}-\u{0bc8}\u{0bca}-\u{0bcc}\u{0be7}-\u{0bf2}\u{0c01}-\u{0c03}\u{0c05}-\u{0c0c}\u{0c0e}-\u{0c10}\u{0c12}-\u{0c28}\u{0c2a}-\u{0c33}\u{0c35}-\u{0c39}\u{0c41}-\u{0c44}\u{0c60}-\u{0c61}\u{0c66}-\u{0c6f}\u{0c82}-\u{0c83}\u{0c85}-\u{0c8c}\u{0c8e}-\u{0c90}\u{0c92}-\u{0ca8}\u{0caa}-\u{0cb3}\u{0cb5}-\u{0cb9}\u{0cc0}-\u{0cc4}\u{0cc7}-\u{0cc8}\u{0cca}-\u{0ccb}\u{0cd5}-\u{0cd6}\u{0ce0}-\u{0ce1}\u{0ce6}-\u{0cef}\u{0d02}-\u{0d03}\u{0d05}-\u{0d0c}\u{0d0e}-\u{0d10}\u{0d12}-\u{0d28}\u{0d2a}-\u{0d39}\u{0d3e}-\u{0d40}\u{0d46}-\u{0d48}\u{0d4a}-\u{0d4c}\u{0d60}-\u{0d61}\u{0d66}-\u{0d6f}\u{0d82}-\u{0d83}\u{0d85}-\u{0d96}\u{0d9a}-\u{0db1}\u{0db3}-\u{0dbb}\u{0dc0}-\u{0dc6}\u{0dcf}-\u{0dd1}\u{0dd8}-\u{0ddf}\u{0df2}-\u{0df4}\u{0e01}-\u{0e30}\u{0e32}-\u{0e33}\u{0e40}-\u{0e46}\u{0e4f}-\u{0e5b}\u{0e81}-\u{0e82}\u{0e87}-\u{0e88}\u{0e94}-\u{0e97}\u{0e99}-\u{0e9f}\u{0ea1}-\u{0ea3}\u{0eaa}-\u{0eab}\u{0ead}-\u{0eb0}\u{0eb2}-\u{0eb3}\u{0ec0}-\u{0ec4}\u{0ed0}-\u{0ed9}\u{0edc}-\u{0edd}\u{0f00}-\u{0f17}\u{0f1a}-\u{0f34}\u{0f3e}-\u{0f47}\u{0f49}-\u{0f6a}\u{0f88}-\u{0f8b}\u{0fbe}-\u{0fc5}\u{0fc7}-\u{0fcc}\u{1000}-\u{1021}\u{1023}-\u{1027}\u{1029}-\u{102a}\u{1040}-\u{1057}\u{10a0}-\u{10c5}\u{10d0}-\u{10f8}\u{1100}-\u{1159}\u{115f}-\u{11a2}\u{11a8}-\u{11f9}\u{1200}-\u{1206}\u{1208}-\u{1246}\u{124a}-\u{124d}\u{1250}-\u{1256}\u{125a}-\u{125d}\u{1260}-\u{1286}\u{128a}-\u{128d}\u{1290}-\u{12ae}\u{12b2}-\u{12b5}\u{12b8}-\u{12be}\u{12c2}-\u{12c5}\u{12c8}-\u{12ce}\u{12d0}-\u{12d6}\u{12d8}-\u{12ee}\u{12f0}-\u{130e}\u{1312}-\u{1315}\u{1318}-\u{131e}\u{1320}-\u{1346}\u{1348}-\u{135a}\u{1361}-\u{137c}\u{13a0}-\u{13f4}\u{1401}-\u{1676}\u{1681}-\u{169a}\u{16a0}-\u{16f0}\u{1700}-\u{170c}\u{170e}-\u{1711}\u{1720}-\u{1731}\u{1735}-\u{1736}\u{1740}-\u{1751}\u{1760}-\u{176c}\u{176e}-\u{1770}\u{1780}-\u{17b6}\u{17be}-\u{17c5}\u{17c7}-\u{17c8}\u{17d4}-\u{17da}\u{17e0}-\u{17e9}\u{1810}-\u{1819}\u{1820}-\u{1877}\u{1880}-\u{18a8}\u{1e00}-\u{1e9b}\u{1ea0}-\u{1ef9}\u{1f00}-\u{1f15}\u{1f18}-\u{1f1d}\u{1f20}-\u{1f45}\u{1f48}-\u{1f4d}\u{1f50}-\u{1f57}\u{1f5f}-\u{1f7d}\u{1f80}-\u{1fb4}\u{1fb6}-\u{1fbc}\u{1fc2}-\u{1fc4}\u{1fc6}-\u{1fcc}\u{1fd0}-\u{1fd3}\u{1fd6}-\u{1fdb}\u{1fe0}-\u{1fec}\u{1ff2}-\u{1ff4}\u{1ff6}-\u{1ffc}\u{210a}-\u{2113}\u{2119}-\u{211d}\u{212a}-\u{212d}\u{212f}-\u{2131}\u{2133}-\u{2139}\u{213d}-\u{213f}\u{2145}-\u{2149}\u{2160}-\u{2183}\u{2336}-\u{237a}\u{249c}-\u{24e9}\u{3005}-\u{3007}\u{3021}-\u{3029}\u{3031}-\u{3035}\u{3038}-\u{303c}\u{3041}-\u{3096}\u{309d}-\u{309f}\u{30a1}-\u{30fa}\u{30fc}-\u{30ff}\u{3105}-\u{312c}\u{3131}-\u{318e}\u{3190}-\u{31b7}\u{31f0}-\u{321c}\u{3220}-\u{3243}\u{3260}-\u{327b}\u{327f}-\u{32b0}\u{32c0}-\u{32cb}\u{32d0}-\u{32fe}\u{3300}-\u{3376}\u{337b}-\u{33dd}\u{33e0}-\u{33fe}\u{3400}-\u{4db5}\u{4e00}-\u{9fa5}\u{a000}-\u{a48c}\u{ac00}-\u{d7a3}\u{e000}-\u{fa2d}\u{fa30}-\u{fa6a}\u{fb00}-\u{fb06}\u{fb13}-\u{fb17}\u{ff21}-\u{ff3a}\u{ff41}-\u{ff5a}\u{ff66}-\u{ffbe}\u{ffc2}-\u{ffc7}\u{ffca}-\u{ffcf}\u{ffd2}-\u{ffd7}\u{ffda}-\u{ffdc}\u{10300}-\u{1031e}\u{10320}-\u{10323}\u{10330}-\u{1034a}\u{10400}-\u{10425}\u{10428}-\u{1044d}\u{1d000}-\u{1d0f5}\u{1d100}-\u{1d126}\u{1d12a}-\u{1d166}\u{1d16a}-\u{1d172}\u{1d183}-\u{1d184}\u{1d18c}-\u{1d1a9}\u{1d1ae}-\u{1d1dd}\u{1d400}-\u{1d454}\u{1d456}-\u{1d49c}\u{1d49e}-\u{1d49f}\u{1d4a5}-\u{1d4a6}\u{1d4a9}-\u{1d4ac}\u{1d4ae}-\u{1d4b9}\u{1d4bd}-\u{1d4c0}\u{1d4c2}-\u{1d4c3}\u{1d4c5}-\u{1d505}\u{1d507}-\u{1d50a}\u{1d50d}-\u{1d514}\u{1d516}-\u{1d51c}\u{1d51e}-\u{1d539}\u{1d53b}-\u{1d53e}\u{1d540}-\u{1d544}\u{1d54a}-\u{1d550}\u{1d552}-\u{1d6a3}\u{1d6a8}-\u{1d7c9}\u{20000}-\u{2a6d6}\u{2f800}-\u{2fa1d}\u{f0000}-\u{ffffd}\u{100000}-\u{10fffd}\p{Cs}]))|(?m-ix:(?-mix:[\u{00aa 00b5 00ba 02ee 037a 0386 038c 0589 0903 0950 09b2 09d7 0a5e 0a83 0a8d 0ac9 0ad0 0ae0 0b40 0b57 0b83 0b9c 0bd7 0cbe 0cde 0d57 0dbd 0e84 0e8a 0e8d 0ea5 0ea7 0ebd 0ec6 0f36 0f38 0f7f 0f85 0fcf 102c 1031 1038 10fb 1248 1258 1288 12b0 12c0 1310 17dc 1f59 1f5b 1f5d 1fbe 200e 2071 207f 2102 2107 2115 2124 2126 2128 2395 1d4a2 1d4bb 1d546}\u{0041}-\u{005a}\u{0061}-\u{007a}\u{00c0}-\u{00d6}\u{00d8}-\u{00f6}\u{00f8}-\u{0220}\u{0222}-\u{0233}\u{0250}-\u{02ad}\u{02b0}-\u{02b8}\u{02bb}-\u{02c1}\u{02d0}-\u{02d1}\u{02e0}-\u{02e4}\u{0388}-\u{038a}\u{038e}-\u{03a1}\u{03a3}-\u{03ce}\u{03d0}-\u{03f5}\u{0400}-\u{0482}\u{048a}-\u{04ce}\u{04d0}-\u{04f5}\u{04f8}-\u{04f9}\u{0500}-\u{050f}\u{0531}-\u{0556}\u{0559}-\u{055f}\u{0561}-\u{0587}\u{0905}-\u{0939}\u{093d}-\u{0940}\u{0949}-\u{094c}\u{0958}-\u{0961}\u{0964}-\u{0970}\u{0982}-\u{0983}\u{0985}-\u{098c}\u{098f}-\u{0990}\u{0993}-\u{09a8}\u{09aa}-\u{09b0}\u{09b6}-\u{09b9}\u{09be}-\u{09c0}\u{09c7}-\u{09c8}\u{09cb}-\u{09cc}\u{09dc}-\u{09dd}\u{09df}-\u{09e1}\u{09e6}-\u{09f1}\u{09f4}-\u{09fa}\u{0a05}-\u{0a0a}\u{0a0f}-\u{0a10}\u{0a13}-\u{0a28}\u{0a2a}-\u{0a30}\u{0a32}-\u{0a33}\u{0a35}-\u{0a36}\u{0a38}-\u{0a39}\u{0a3e}-\u{0a40}\u{0a59}-\u{0a5c}\u{0a66}-\u{0a6f}\u{0a72}-\u{0a74}\u{0a85}-\u{0a8b}\u{0a8f}-\u{0a91}\u{0a93}-\u{0aa8}\u{0aaa}-\u{0ab0}\u{0ab2}-\u{0ab3}\u{0ab5}-\u{0ab9}\u{0abd}-\u{0ac0}\u{0acb}-\u{0acc}\u{0ae6}-\u{0aef}\u{0b02}-\u{0b03}\u{0b05}-\u{0b0c}\u{0b0f}-\u{0b10}\u{0b13}-\u{0b28}\u{0b2a}-\u{0b30}\u{0b32}-\u{0b33}\u{0b36}-\u{0b39}\u{0b3d}-\u{0b3e}\u{0b47}-\u{0b48}\u{0b4b}-\u{0b4c}\u{0b5c}-\u{0b5d}\u{0b5f}-\u{0b61}\u{0b66}-\u{0b70}\u{0b85}-\u{0b8a}\u{0b8e}-\u{0b90}\u{0b92}-\u{0b95}\u{0b99}-\u{0b9a}\u{0b9e}-\u{0b9f}\u{0ba3}-\u{0ba4}\u{0ba8}-\u{0baa}\u{0bae}-\u{0bb5}\u{0bb7}-\u{0bb9}\u{0bbe}-\u{0bbf}\u{0bc1}-\u{0bc2}\u{0bc6}-\u{0bc8}\u{0bca}-\u{0bcc}\u{0be7}-\u{0bf2}\u{0c01}-\u{0c03}\u{0c05}-\u{0c0c}\u{0c0e}-\u{0c10}\u{0c12}-\u{0c28}\u{0c2a}-\u{0c33}\u{0c35}-\u{0c39}\u{0c41}-\u{0c44}\u{0c60}-\u{0c61}\u{0c66}-\u{0c6f}\u{0c82}-\u{0c83}\u{0c85}-\u{0c8c}\u{0c8e}-\u{0c90}\u{0c92}-\u{0ca8}\u{0caa}-\u{0cb3}\u{0cb5}-\u{0cb9}\u{0cc0}-\u{0cc4}\u{0cc7}-\u{0cc8}\u{0cca}-\u{0ccb}\u{0cd5}-\u{0cd6}\u{0ce0}-\u{0ce1}\u{0ce6}-\u{0cef}\u{0d02}-\u{0d03}\u{0d05}-\u{0d0c}\u{0d0e}-\u{0d10}\u{0d12}-\u{0d28}\u{0d2a}-\u{0d39}\u{0d3e}-\u{0d40}\u{0d46}-\u{0d48}\u{0d4a}-\u{0d4c}\u{0d60}-\u{0d61}\u{0d66}-\u{0d6f}\u{0d82}-\u{0d83}\u{0d85}-\u{0d96}\u{0d9a}-\u{0db1}\u{0db3}-\u{0dbb}\u{0dc0}-\u{0dc6}\u{0dcf}-\u{0dd1}\u{0dd8}-\u{0ddf}\u{0df2}-\u{0df4}\u{0e01}-\u{0e30}\u{0e32}-\u{0e33}\u{0e40}-\u{0e46}\u{0e4f}-\u{0e5b}\u{0e81}-\u{0e82}\u{0e87}-\u{0e88}\u{0e94}-\u{0e97}\u{0e99}-\u{0e9f}\u{0ea1}-\u{0ea3}\u{0eaa}-\u{0eab}\u{0ead}-\u{0eb0}\u{0eb2}-\u{0eb3}\u{0ec0}-\u{0ec4}\u{0ed0}-\u{0ed9}\u{0edc}-\u{0edd}\u{0f00}-\u{0f17}\u{0f1a}-\u{0f34}\u{0f3e}-\u{0f47}\u{0f49}-\u{0f6a}\u{0f88}-\u{0f8b}\u{0fbe}-\u{0fc5}\u{0fc7}-\u{0fcc}\u{1000}-\u{1021}\u{1023}-\u{1027}\u{1029}-\u{102a}\u{1040}-\u{1057}\u{10a0}-\u{10c5}\u{10d0}-\u{10f8}\u{1100}-\u{1159}\u{115f}-\u{11a2}\u{11a8}-\u{11f9}\u{1200}-\u{1206}\u{1208}-\u{1246}\u{124a}-\u{124d}\u{1250}-\u{1256}\u{125a}-\u{125d}\u{1260}-\u{1286}\u{128a}-\u{128d}\u{1290}-\u{12ae}\u{12b2}-\u{12b5}\u{12b8}-\u{12be}\u{12c2}-\u{12c5}\u{12c8}-\u{12ce}\u{12d0}-\u{12d6}\u{12d8}-\u{12ee}\u{12f0}-\u{130e}\u{1312}-\u{1315}\u{1318}-\u{131e}\u{1320}-\u{1346}\u{1348}-\u{135a}\u{1361}-\u{137c}\u{13a0}-\u{13f4}\u{1401}-\u{1676}\u{1681}-\u{169a}\u{16a0}-\u{16f0}\u{1700}-\u{170c}\u{170e}-\u{1711}\u{1720}-\u{1731}\u{1735}-\u{1736}\u{1740}-\u{1751}\u{1760}-\u{176c}\u{176e}-\u{1770}\u{1780}-\u{17b6}\u{17be}-\u{17c5}\u{17c7}-\u{17c8}\u{17d4}-\u{17da}\u{17e0}-\u{17e9}\u{1810}-\u{1819}\u{1820}-\u{1877}\u{1880}-\u{18a8}\u{1e00}-\u{1e9b}\u{1ea0}-\u{1ef9}\u{1f00}-\u{1f15}\u{1f18}-\u{1f1d}\u{1f20}-\u{1f45}\u{1f48}-\u{1f4d}\u{1f50}-\u{1f57}\u{1f5f}-\u{1f7d}\u{1f80}-\u{1fb4}\u{1fb6}-\u{1fbc}\u{1fc2}-\u{1fc4}\u{1fc6}-\u{1fcc}\u{1fd0}-\u{1fd3}\u{1fd6}-\u{1fdb}\u{1fe0}-\u{1fec}\u{1ff2}-\u{1ff4}\u{1ff6}-\u{1ffc}\u{210a}-\u{2113}\u{2119}-\u{211d}\u{212a}-\u{212d}\u{212f}-\u{2131}\u{2133}-\u{2139}\u{213d}-\u{213f}\u{2145}-\u{2149}\u{2160}-\u{2183}\u{2336}-\u{237a}\u{249c}-\u{24e9}\u{3005}-\u{3007}\u{3021}-\u{3029}\u{3031}-\u{3035}\u{3038}-\u{303c}\u{3041}-\u{3096}\u{309d}-\u{309f}\u{30a1}-\u{30fa}\u{30fc}-\u{30ff}\u{3105}-\u{312c}\u{3131}-\u{318e}\u{3190}-\u{31b7}\u{31f0}-\u{321c}\u{3220}-\u{3243}\u{3260}-\u{327b}\u{327f}-\u{32b0}\u{32c0}-\u{32cb}\u{32d0}-\u{32fe}\u{3300}-\u{3376}\u{337b}-\u{33dd}\u{33e0}-\u{33fe}\u{3400}-\u{4db5}\u{4e00}-\u{9fa5}\u{a000}-\u{a48c}\u{ac00}-\u{d7a3}\u{e000}-\u{fa2d}\u{fa30}-\u{fa6a}\u{fb00}-\u{fb06}\u{fb13}-\u{fb17}\u{ff21}-\u{ff3a}\u{ff41}-\u{ff5a}\u{ff66}-\u{ffbe}\u{ffc2}-\u{ffc7}\u{ffca}-\u{ffcf}\u{ffd2}-\u{ffd7}\u{ffda}-\u{ffdc}\u{10300}-\u{1031e}\u{10320}-\u{10323}\u{10330}-\u{1034a}\u{10400}-\u{10425}\u{10428}-\u{1044d}\u{1d000}-\u{1d0f5}\u{1d100}-\u{1d126}\u{1d12a}-\u{1d166}\u{1d16a}-\u{1d172}\u{1d183}-\u{1d184}\u{1d18c}-\u{1d1a9}\u{1d1ae}-\u{1d1dd}\u{1d400}-\u{1d454}\u{1d456}-\u{1d49c}\u{1d49e}-\u{1d49f}\u{1d4a5}-\u{1d4a6}\u{1d4a9}-\u{1d4ac}\u{1d4ae}-\u{1d4b9}\u{1d4bd}-\u{1d4c0}\u{1d4c2}-\u{1d4c3}\u{1d4c5}-\u{1d505}\u{1d507}-\u{1d50a}\u{1d50d}-\u{1d514}\u{1d516}-\u{1d51c}\u{1d51e}-\u{1d539}\u{1d53b}-\u{1d53e}\u{1d540}-\u{1d544}\u{1d54a}-\u{1d550}\u{1d552}-\u{1d6a3}\u{1d6a8}-\u{1d7c9}\u{20000}-\u{2a6d6}\u{2f800}-\u{2fa1d}\u{f0000}-\u{ffffd}\u{100000}-\u{10fffd}\p{Cs}]).*?(?-mix:[\u{05be 05c0 05c3 061b 061f 06dd 0710 07b1 200f fb1d fb3e}\u{05d0}-\u{05ea}\u{05f0}-\u{05f4}\u{0621}-\u{063a}\u{0640}-\u{064a}\u{066d}-\u{066f}\u{0671}-\u{06d5}\u{06e5}-\u{06e6}\u{06fa}-\u{06fe}\u{0700}-\u{070d}\u{0712}-\u{072c}\u{0780}-\u{07a5}\u{fb1f}-\u{fb28}\u{fb2a}-\u{fb36}\u{fb38}-\u{fb3c}\u{fb40}-\u{fb41}\u{fb43}-\u{fb44}\u{fb46}-\u{fbb1}\u{fbd3}-\u{fd3d}\u{fd50}-\u{fd8f}\u{fd92}-\u{fdc7}\u{fdf0}-\u{fdfc}\u{fe70}-\u{fe74}\u{fe76}-\u{fefc}]))/.freeze + + end +end diff --git a/lib/net/imap/stringprep/tables/bidi_fails_req3.rb b/lib/net/imap/stringprep/tables/bidi_fails_req3.rb new file mode 100644 index 00000000..dc8f27d5 --- /dev/null +++ b/lib/net/imap/stringprep/tables/bidi_fails_req3.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +#-- +# This file is generated by `rake stringprep:tables`. Don't edit directly. +#++ + +module Net::IMAP::StringPrep + module Tables + + # Bidirectional Characters [StringPrep, §6], Requirement 3 + # >>> + # If a string contains any RandALCat character, a RandALCat + # character MUST be the first character of the string, and a + # RandALCat character MUST be the last character of the string. + BIDI_FAILS_REQ3 = /(?m-ix:\A(?-mix:[^\u{05be 05c0 05c3 061b 061f 06dd 0710 07b1 200f fb1d fb3e}\u{05d0}-\u{05ea}\u{05f0}-\u{05f4}\u{0621}-\u{063a}\u{0640}-\u{064a}\u{066d}-\u{066f}\u{0671}-\u{06d5}\u{06e5}-\u{06e6}\u{06fa}-\u{06fe}\u{0700}-\u{070d}\u{0712}-\u{072c}\u{0780}-\u{07a5}\u{fb1f}-\u{fb28}\u{fb2a}-\u{fb36}\u{fb38}-\u{fb3c}\u{fb40}-\u{fb41}\u{fb43}-\u{fb44}\u{fb46}-\u{fbb1}\u{fbd3}-\u{fd3d}\u{fd50}-\u{fd8f}\u{fd92}-\u{fdc7}\u{fdf0}-\u{fdfc}\u{fe70}-\u{fe74}\u{fe76}-\u{fefc}]).*?(?-mix:[\u{05be 05c0 05c3 061b 061f 06dd 0710 07b1 200f fb1d fb3e}\u{05d0}-\u{05ea}\u{05f0}-\u{05f4}\u{0621}-\u{063a}\u{0640}-\u{064a}\u{066d}-\u{066f}\u{0671}-\u{06d5}\u{06e5}-\u{06e6}\u{06fa}-\u{06fe}\u{0700}-\u{070d}\u{0712}-\u{072c}\u{0780}-\u{07a5}\u{fb1f}-\u{fb28}\u{fb2a}-\u{fb36}\u{fb38}-\u{fb3c}\u{fb40}-\u{fb41}\u{fb43}-\u{fb44}\u{fb46}-\u{fbb1}\u{fbd3}-\u{fd3d}\u{fd50}-\u{fd8f}\u{fd92}-\u{fdc7}\u{fdf0}-\u{fdfc}\u{fe70}-\u{fe74}\u{fe76}-\u{fefc}]))|(?m-ix:(?-mix:[\u{05be 05c0 05c3 061b 061f 06dd 0710 07b1 200f fb1d fb3e}\u{05d0}-\u{05ea}\u{05f0}-\u{05f4}\u{0621}-\u{063a}\u{0640}-\u{064a}\u{066d}-\u{066f}\u{0671}-\u{06d5}\u{06e5}-\u{06e6}\u{06fa}-\u{06fe}\u{0700}-\u{070d}\u{0712}-\u{072c}\u{0780}-\u{07a5}\u{fb1f}-\u{fb28}\u{fb2a}-\u{fb36}\u{fb38}-\u{fb3c}\u{fb40}-\u{fb41}\u{fb43}-\u{fb44}\u{fb46}-\u{fbb1}\u{fbd3}-\u{fd3d}\u{fd50}-\u{fd8f}\u{fd92}-\u{fdc7}\u{fdf0}-\u{fdfc}\u{fe70}-\u{fe74}\u{fe76}-\u{fefc}]).*?(?-mix:[^\u{05be 05c0 05c3 061b 061f 06dd 0710 07b1 200f fb1d fb3e}\u{05d0}-\u{05ea}\u{05f0}-\u{05f4}\u{0621}-\u{063a}\u{0640}-\u{064a}\u{066d}-\u{066f}\u{0671}-\u{06d5}\u{06e5}-\u{06e6}\u{06fa}-\u{06fe}\u{0700}-\u{070d}\u{0712}-\u{072c}\u{0780}-\u{07a5}\u{fb1f}-\u{fb28}\u{fb2a}-\u{fb36}\u{fb38}-\u{fb3c}\u{fb40}-\u{fb41}\u{fb43}-\u{fb44}\u{fb46}-\u{fbb1}\u{fbd3}-\u{fd3d}\u{fd50}-\u{fd8f}\u{fd92}-\u{fdc7}\u{fdf0}-\u{fdfc}\u{fe70}-\u{fe74}\u{fe76}-\u{fefc}])\z)/.freeze + + end +end diff --git a/lib/net/imap/stringprep/saslprep_tables.rb b/lib/net/imap/stringprep/tables/bidi_failure.rb similarity index 78% rename from lib/net/imap/stringprep/saslprep_tables.rb rename to lib/net/imap/stringprep/tables/bidi_failure.rb index fac7f0be..bd2a870b 100644 --- a/lib/net/imap/stringprep/saslprep_tables.rb +++ b/lib/net/imap/stringprep/tables/bidi_failure.rb @@ -1,96 +1,14 @@ # frozen_string_literal: true #-- -# This file is generated from RFC3454, by rake. Don't edit directly. +# This file is generated by `rake stringprep:tables`. Don't edit directly. #++ module Net::IMAP::StringPrep - - module SASLprep - - # RFC4013 §2.1 Mapping - mapped to space - # >>> - # non-ASCII space characters (\StringPrep\[\"C.1.2\"]) that can - # be mapped to SPACE (U+0020) - # - # Equal to \StringPrep\[\"C.1.2\"]. - # Redefined here to avoid loading StringPrep::Tables unless necessary. - MAP_TO_SPACE = /[\u200b\p{Zs}&&[^ ]]/.freeze - - # RFC4013 §2.1 Mapping - mapped to nothing - # >>> - # the "commonly mapped to nothing" characters - # (\StringPrep\[\"B.1\"]) that can be mapped to nothing. - # - # Equal to \StringPrep\[\"B.1\"]. - # Redefined here to avoid loading StringPrep::Tables unless necessary. - MAP_TO_NOTHING = /[\u{00ad 034f 1806 2060 feff}\u{180b}-\u{180d}\u{200b}-\u{200d}\u{fe00}-\u{fe0f}]/.freeze - - # RFC4013 §2.3 Prohibited Output - # >>> - # * Non-ASCII space characters — \StringPrep\[\"C.1.2\"] - # * ASCII control characters — \StringPrep\[\"C.2.1\"] - # * Non-ASCII control characters — \StringPrep\[\"C.2.2\"] - # * Private Use characters — \StringPrep\[\"C.3\"] - # * Non-character code points — \StringPrep\[\"C.4\"] - # * Surrogate code points — \StringPrep\[\"C.5\"] - # * Inappropriate for plain text characters — \StringPrep\[\"C.6\"] - # * Inappropriate for canonical representation characters — \StringPrep\[\"C.7\"] - # * Change display properties or deprecated characters — \StringPrep\[\"C.8\"] - # * Tagging characters — \StringPrep\[\"C.9\"] - TABLES_PROHIBITED = ["C.1.2", "C.2.1", "C.2.2", "C.3", "C.4", "C.5", "C.6", "C.7", "C.8", "C.9"].freeze - - # Adds unassigned (by Unicode 3.2) codepoints to TABLES_PROHIBITED. - # - # RFC4013 §2.5 Unassigned Code Points - # >>> - # This profile specifies the \StringPrep\[\"A.1\"] table as its - # list of unassigned code points. - TABLES_PROHIBITED_STORED = ["A.1", *TABLES_PROHIBITED].freeze - - # A Regexp matching codepoints prohibited by RFC4013 §2.3. - # - # This combines all of the TABLES_PROHIBITED tables. - PROHIBITED_OUTPUT = /[\u{06dd 070f 1680 180e 3000 feff e0001}\u{0000}-\u{001f}\u{007f}-\u{00a0}\u{0340}-\u{0341}\u{2000}-\u{200f}\u{2028}-\u{202f}\u{205f}-\u{2063}\u{206a}-\u{206f}\u{2ff0}-\u{2ffb}\u{e000}-\u{f8ff}\u{fdd0}-\u{fdef}\u{fff9}-\u{ffff}\u{1d173}-\u{1d17a}\u{1fffe}-\u{1ffff}\u{2fffe}-\u{2ffff}\u{3fffe}-\u{3ffff}\u{4fffe}-\u{4ffff}\u{5fffe}-\u{5ffff}\u{6fffe}-\u{6ffff}\u{7fffe}-\u{7ffff}\u{8fffe}-\u{8ffff}\u{9fffe}-\u{9ffff}\u{afffe}-\u{affff}\u{bfffe}-\u{bffff}\u{cfffe}-\u{cffff}\u{dfffe}-\u{dffff}\u{e0020}-\u{e007f}\u{efffe}-\u{10ffff}\p{Cs}]/.freeze - - # RFC4013 §2.5 Unassigned Code Points - # >>> - # This profile specifies the \StringPrep\[\"A.1\"] table as its - # list of unassigned code points. - # - # Equal to \StringPrep\[\"A.1\"]. - # Redefined here to avoid loading StringPrep::Tables unless necessary. - UNASSIGNED = /\p{^AGE=3.2}/.freeze - - # A Regexp matching codepoints prohibited by RFC4013 §2.3 and §2.5. - # - # This combines PROHIBITED_OUTPUT and UNASSIGNED. - PROHIBITED_OUTPUT_STORED = Regexp.union( - UNASSIGNED, PROHIBITED_OUTPUT - ).freeze + module Tables # Bidirectional Characters [StringPrep, §6] - # - # A Regexp for strings that don't satisfy StringPrep's Bidirectional - # Characters rules. - # - # Equal to StringPrep::Tables::BIDI_FAILURE. - # Redefined here to avoid loading StringPrep::Tables unless necessary. BIDI_FAILURE = /(?-mix:(?m-ix:(?-mix:[\u{05be 05c0 05c3 061b 061f 06dd 0710 07b1 200f fb1d fb3e}\u{05d0}-\u{05ea}\u{05f0}-\u{05f4}\u{0621}-\u{063a}\u{0640}-\u{064a}\u{066d}-\u{066f}\u{0671}-\u{06d5}\u{06e5}-\u{06e6}\u{06fa}-\u{06fe}\u{0700}-\u{070d}\u{0712}-\u{072c}\u{0780}-\u{07a5}\u{fb1f}-\u{fb28}\u{fb2a}-\u{fb36}\u{fb38}-\u{fb3c}\u{fb40}-\u{fb41}\u{fb43}-\u{fb44}\u{fb46}-\u{fbb1}\u{fbd3}-\u{fd3d}\u{fd50}-\u{fd8f}\u{fd92}-\u{fdc7}\u{fdf0}-\u{fdfc}\u{fe70}-\u{fe74}\u{fe76}-\u{fefc}]).*?(?-mix:[\u{00aa 00b5 00ba 02ee 037a 0386 038c 0589 0903 0950 09b2 09d7 0a5e 0a83 0a8d 0ac9 0ad0 0ae0 0b40 0b57 0b83 0b9c 0bd7 0cbe 0cde 0d57 0dbd 0e84 0e8a 0e8d 0ea5 0ea7 0ebd 0ec6 0f36 0f38 0f7f 0f85 0fcf 102c 1031 1038 10fb 1248 1258 1288 12b0 12c0 1310 17dc 1f59 1f5b 1f5d 1fbe 200e 2071 207f 2102 2107 2115 2124 2126 2128 2395 1d4a2 1d4bb 1d546}\u{0041}-\u{005a}\u{0061}-\u{007a}\u{00c0}-\u{00d6}\u{00d8}-\u{00f6}\u{00f8}-\u{0220}\u{0222}-\u{0233}\u{0250}-\u{02ad}\u{02b0}-\u{02b8}\u{02bb}-\u{02c1}\u{02d0}-\u{02d1}\u{02e0}-\u{02e4}\u{0388}-\u{038a}\u{038e}-\u{03a1}\u{03a3}-\u{03ce}\u{03d0}-\u{03f5}\u{0400}-\u{0482}\u{048a}-\u{04ce}\u{04d0}-\u{04f5}\u{04f8}-\u{04f9}\u{0500}-\u{050f}\u{0531}-\u{0556}\u{0559}-\u{055f}\u{0561}-\u{0587}\u{0905}-\u{0939}\u{093d}-\u{0940}\u{0949}-\u{094c}\u{0958}-\u{0961}\u{0964}-\u{0970}\u{0982}-\u{0983}\u{0985}-\u{098c}\u{098f}-\u{0990}\u{0993}-\u{09a8}\u{09aa}-\u{09b0}\u{09b6}-\u{09b9}\u{09be}-\u{09c0}\u{09c7}-\u{09c8}\u{09cb}-\u{09cc}\u{09dc}-\u{09dd}\u{09df}-\u{09e1}\u{09e6}-\u{09f1}\u{09f4}-\u{09fa}\u{0a05}-\u{0a0a}\u{0a0f}-\u{0a10}\u{0a13}-\u{0a28}\u{0a2a}-\u{0a30}\u{0a32}-\u{0a33}\u{0a35}-\u{0a36}\u{0a38}-\u{0a39}\u{0a3e}-\u{0a40}\u{0a59}-\u{0a5c}\u{0a66}-\u{0a6f}\u{0a72}-\u{0a74}\u{0a85}-\u{0a8b}\u{0a8f}-\u{0a91}\u{0a93}-\u{0aa8}\u{0aaa}-\u{0ab0}\u{0ab2}-\u{0ab3}\u{0ab5}-\u{0ab9}\u{0abd}-\u{0ac0}\u{0acb}-\u{0acc}\u{0ae6}-\u{0aef}\u{0b02}-\u{0b03}\u{0b05}-\u{0b0c}\u{0b0f}-\u{0b10}\u{0b13}-\u{0b28}\u{0b2a}-\u{0b30}\u{0b32}-\u{0b33}\u{0b36}-\u{0b39}\u{0b3d}-\u{0b3e}\u{0b47}-\u{0b48}\u{0b4b}-\u{0b4c}\u{0b5c}-\u{0b5d}\u{0b5f}-\u{0b61}\u{0b66}-\u{0b70}\u{0b85}-\u{0b8a}\u{0b8e}-\u{0b90}\u{0b92}-\u{0b95}\u{0b99}-\u{0b9a}\u{0b9e}-\u{0b9f}\u{0ba3}-\u{0ba4}\u{0ba8}-\u{0baa}\u{0bae}-\u{0bb5}\u{0bb7}-\u{0bb9}\u{0bbe}-\u{0bbf}\u{0bc1}-\u{0bc2}\u{0bc6}-\u{0bc8}\u{0bca}-\u{0bcc}\u{0be7}-\u{0bf2}\u{0c01}-\u{0c03}\u{0c05}-\u{0c0c}\u{0c0e}-\u{0c10}\u{0c12}-\u{0c28}\u{0c2a}-\u{0c33}\u{0c35}-\u{0c39}\u{0c41}-\u{0c44}\u{0c60}-\u{0c61}\u{0c66}-\u{0c6f}\u{0c82}-\u{0c83}\u{0c85}-\u{0c8c}\u{0c8e}-\u{0c90}\u{0c92}-\u{0ca8}\u{0caa}-\u{0cb3}\u{0cb5}-\u{0cb9}\u{0cc0}-\u{0cc4}\u{0cc7}-\u{0cc8}\u{0cca}-\u{0ccb}\u{0cd5}-\u{0cd6}\u{0ce0}-\u{0ce1}\u{0ce6}-\u{0cef}\u{0d02}-\u{0d03}\u{0d05}-\u{0d0c}\u{0d0e}-\u{0d10}\u{0d12}-\u{0d28}\u{0d2a}-\u{0d39}\u{0d3e}-\u{0d40}\u{0d46}-\u{0d48}\u{0d4a}-\u{0d4c}\u{0d60}-\u{0d61}\u{0d66}-\u{0d6f}\u{0d82}-\u{0d83}\u{0d85}-\u{0d96}\u{0d9a}-\u{0db1}\u{0db3}-\u{0dbb}\u{0dc0}-\u{0dc6}\u{0dcf}-\u{0dd1}\u{0dd8}-\u{0ddf}\u{0df2}-\u{0df4}\u{0e01}-\u{0e30}\u{0e32}-\u{0e33}\u{0e40}-\u{0e46}\u{0e4f}-\u{0e5b}\u{0e81}-\u{0e82}\u{0e87}-\u{0e88}\u{0e94}-\u{0e97}\u{0e99}-\u{0e9f}\u{0ea1}-\u{0ea3}\u{0eaa}-\u{0eab}\u{0ead}-\u{0eb0}\u{0eb2}-\u{0eb3}\u{0ec0}-\u{0ec4}\u{0ed0}-\u{0ed9}\u{0edc}-\u{0edd}\u{0f00}-\u{0f17}\u{0f1a}-\u{0f34}\u{0f3e}-\u{0f47}\u{0f49}-\u{0f6a}\u{0f88}-\u{0f8b}\u{0fbe}-\u{0fc5}\u{0fc7}-\u{0fcc}\u{1000}-\u{1021}\u{1023}-\u{1027}\u{1029}-\u{102a}\u{1040}-\u{1057}\u{10a0}-\u{10c5}\u{10d0}-\u{10f8}\u{1100}-\u{1159}\u{115f}-\u{11a2}\u{11a8}-\u{11f9}\u{1200}-\u{1206}\u{1208}-\u{1246}\u{124a}-\u{124d}\u{1250}-\u{1256}\u{125a}-\u{125d}\u{1260}-\u{1286}\u{128a}-\u{128d}\u{1290}-\u{12ae}\u{12b2}-\u{12b5}\u{12b8}-\u{12be}\u{12c2}-\u{12c5}\u{12c8}-\u{12ce}\u{12d0}-\u{12d6}\u{12d8}-\u{12ee}\u{12f0}-\u{130e}\u{1312}-\u{1315}\u{1318}-\u{131e}\u{1320}-\u{1346}\u{1348}-\u{135a}\u{1361}-\u{137c}\u{13a0}-\u{13f4}\u{1401}-\u{1676}\u{1681}-\u{169a}\u{16a0}-\u{16f0}\u{1700}-\u{170c}\u{170e}-\u{1711}\u{1720}-\u{1731}\u{1735}-\u{1736}\u{1740}-\u{1751}\u{1760}-\u{176c}\u{176e}-\u{1770}\u{1780}-\u{17b6}\u{17be}-\u{17c5}\u{17c7}-\u{17c8}\u{17d4}-\u{17da}\u{17e0}-\u{17e9}\u{1810}-\u{1819}\u{1820}-\u{1877}\u{1880}-\u{18a8}\u{1e00}-\u{1e9b}\u{1ea0}-\u{1ef9}\u{1f00}-\u{1f15}\u{1f18}-\u{1f1d}\u{1f20}-\u{1f45}\u{1f48}-\u{1f4d}\u{1f50}-\u{1f57}\u{1f5f}-\u{1f7d}\u{1f80}-\u{1fb4}\u{1fb6}-\u{1fbc}\u{1fc2}-\u{1fc4}\u{1fc6}-\u{1fcc}\u{1fd0}-\u{1fd3}\u{1fd6}-\u{1fdb}\u{1fe0}-\u{1fec}\u{1ff2}-\u{1ff4}\u{1ff6}-\u{1ffc}\u{210a}-\u{2113}\u{2119}-\u{211d}\u{212a}-\u{212d}\u{212f}-\u{2131}\u{2133}-\u{2139}\u{213d}-\u{213f}\u{2145}-\u{2149}\u{2160}-\u{2183}\u{2336}-\u{237a}\u{249c}-\u{24e9}\u{3005}-\u{3007}\u{3021}-\u{3029}\u{3031}-\u{3035}\u{3038}-\u{303c}\u{3041}-\u{3096}\u{309d}-\u{309f}\u{30a1}-\u{30fa}\u{30fc}-\u{30ff}\u{3105}-\u{312c}\u{3131}-\u{318e}\u{3190}-\u{31b7}\u{31f0}-\u{321c}\u{3220}-\u{3243}\u{3260}-\u{327b}\u{327f}-\u{32b0}\u{32c0}-\u{32cb}\u{32d0}-\u{32fe}\u{3300}-\u{3376}\u{337b}-\u{33dd}\u{33e0}-\u{33fe}\u{3400}-\u{4db5}\u{4e00}-\u{9fa5}\u{a000}-\u{a48c}\u{ac00}-\u{d7a3}\u{e000}-\u{fa2d}\u{fa30}-\u{fa6a}\u{fb00}-\u{fb06}\u{fb13}-\u{fb17}\u{ff21}-\u{ff3a}\u{ff41}-\u{ff5a}\u{ff66}-\u{ffbe}\u{ffc2}-\u{ffc7}\u{ffca}-\u{ffcf}\u{ffd2}-\u{ffd7}\u{ffda}-\u{ffdc}\u{10300}-\u{1031e}\u{10320}-\u{10323}\u{10330}-\u{1034a}\u{10400}-\u{10425}\u{10428}-\u{1044d}\u{1d000}-\u{1d0f5}\u{1d100}-\u{1d126}\u{1d12a}-\u{1d166}\u{1d16a}-\u{1d172}\u{1d183}-\u{1d184}\u{1d18c}-\u{1d1a9}\u{1d1ae}-\u{1d1dd}\u{1d400}-\u{1d454}\u{1d456}-\u{1d49c}\u{1d49e}-\u{1d49f}\u{1d4a5}-\u{1d4a6}\u{1d4a9}-\u{1d4ac}\u{1d4ae}-\u{1d4b9}\u{1d4bd}-\u{1d4c0}\u{1d4c2}-\u{1d4c3}\u{1d4c5}-\u{1d505}\u{1d507}-\u{1d50a}\u{1d50d}-\u{1d514}\u{1d516}-\u{1d51c}\u{1d51e}-\u{1d539}\u{1d53b}-\u{1d53e}\u{1d540}-\u{1d544}\u{1d54a}-\u{1d550}\u{1d552}-\u{1d6a3}\u{1d6a8}-\u{1d7c9}\u{20000}-\u{2a6d6}\u{2f800}-\u{2fa1d}\u{f0000}-\u{ffffd}\u{100000}-\u{10fffd}\p{Cs}]))|(?m-ix:(?-mix:[\u{00aa 00b5 00ba 02ee 037a 0386 038c 0589 0903 0950 09b2 09d7 0a5e 0a83 0a8d 0ac9 0ad0 0ae0 0b40 0b57 0b83 0b9c 0bd7 0cbe 0cde 0d57 0dbd 0e84 0e8a 0e8d 0ea5 0ea7 0ebd 0ec6 0f36 0f38 0f7f 0f85 0fcf 102c 1031 1038 10fb 1248 1258 1288 12b0 12c0 1310 17dc 1f59 1f5b 1f5d 1fbe 200e 2071 207f 2102 2107 2115 2124 2126 2128 2395 1d4a2 1d4bb 1d546}\u{0041}-\u{005a}\u{0061}-\u{007a}\u{00c0}-\u{00d6}\u{00d8}-\u{00f6}\u{00f8}-\u{0220}\u{0222}-\u{0233}\u{0250}-\u{02ad}\u{02b0}-\u{02b8}\u{02bb}-\u{02c1}\u{02d0}-\u{02d1}\u{02e0}-\u{02e4}\u{0388}-\u{038a}\u{038e}-\u{03a1}\u{03a3}-\u{03ce}\u{03d0}-\u{03f5}\u{0400}-\u{0482}\u{048a}-\u{04ce}\u{04d0}-\u{04f5}\u{04f8}-\u{04f9}\u{0500}-\u{050f}\u{0531}-\u{0556}\u{0559}-\u{055f}\u{0561}-\u{0587}\u{0905}-\u{0939}\u{093d}-\u{0940}\u{0949}-\u{094c}\u{0958}-\u{0961}\u{0964}-\u{0970}\u{0982}-\u{0983}\u{0985}-\u{098c}\u{098f}-\u{0990}\u{0993}-\u{09a8}\u{09aa}-\u{09b0}\u{09b6}-\u{09b9}\u{09be}-\u{09c0}\u{09c7}-\u{09c8}\u{09cb}-\u{09cc}\u{09dc}-\u{09dd}\u{09df}-\u{09e1}\u{09e6}-\u{09f1}\u{09f4}-\u{09fa}\u{0a05}-\u{0a0a}\u{0a0f}-\u{0a10}\u{0a13}-\u{0a28}\u{0a2a}-\u{0a30}\u{0a32}-\u{0a33}\u{0a35}-\u{0a36}\u{0a38}-\u{0a39}\u{0a3e}-\u{0a40}\u{0a59}-\u{0a5c}\u{0a66}-\u{0a6f}\u{0a72}-\u{0a74}\u{0a85}-\u{0a8b}\u{0a8f}-\u{0a91}\u{0a93}-\u{0aa8}\u{0aaa}-\u{0ab0}\u{0ab2}-\u{0ab3}\u{0ab5}-\u{0ab9}\u{0abd}-\u{0ac0}\u{0acb}-\u{0acc}\u{0ae6}-\u{0aef}\u{0b02}-\u{0b03}\u{0b05}-\u{0b0c}\u{0b0f}-\u{0b10}\u{0b13}-\u{0b28}\u{0b2a}-\u{0b30}\u{0b32}-\u{0b33}\u{0b36}-\u{0b39}\u{0b3d}-\u{0b3e}\u{0b47}-\u{0b48}\u{0b4b}-\u{0b4c}\u{0b5c}-\u{0b5d}\u{0b5f}-\u{0b61}\u{0b66}-\u{0b70}\u{0b85}-\u{0b8a}\u{0b8e}-\u{0b90}\u{0b92}-\u{0b95}\u{0b99}-\u{0b9a}\u{0b9e}-\u{0b9f}\u{0ba3}-\u{0ba4}\u{0ba8}-\u{0baa}\u{0bae}-\u{0bb5}\u{0bb7}-\u{0bb9}\u{0bbe}-\u{0bbf}\u{0bc1}-\u{0bc2}\u{0bc6}-\u{0bc8}\u{0bca}-\u{0bcc}\u{0be7}-\u{0bf2}\u{0c01}-\u{0c03}\u{0c05}-\u{0c0c}\u{0c0e}-\u{0c10}\u{0c12}-\u{0c28}\u{0c2a}-\u{0c33}\u{0c35}-\u{0c39}\u{0c41}-\u{0c44}\u{0c60}-\u{0c61}\u{0c66}-\u{0c6f}\u{0c82}-\u{0c83}\u{0c85}-\u{0c8c}\u{0c8e}-\u{0c90}\u{0c92}-\u{0ca8}\u{0caa}-\u{0cb3}\u{0cb5}-\u{0cb9}\u{0cc0}-\u{0cc4}\u{0cc7}-\u{0cc8}\u{0cca}-\u{0ccb}\u{0cd5}-\u{0cd6}\u{0ce0}-\u{0ce1}\u{0ce6}-\u{0cef}\u{0d02}-\u{0d03}\u{0d05}-\u{0d0c}\u{0d0e}-\u{0d10}\u{0d12}-\u{0d28}\u{0d2a}-\u{0d39}\u{0d3e}-\u{0d40}\u{0d46}-\u{0d48}\u{0d4a}-\u{0d4c}\u{0d60}-\u{0d61}\u{0d66}-\u{0d6f}\u{0d82}-\u{0d83}\u{0d85}-\u{0d96}\u{0d9a}-\u{0db1}\u{0db3}-\u{0dbb}\u{0dc0}-\u{0dc6}\u{0dcf}-\u{0dd1}\u{0dd8}-\u{0ddf}\u{0df2}-\u{0df4}\u{0e01}-\u{0e30}\u{0e32}-\u{0e33}\u{0e40}-\u{0e46}\u{0e4f}-\u{0e5b}\u{0e81}-\u{0e82}\u{0e87}-\u{0e88}\u{0e94}-\u{0e97}\u{0e99}-\u{0e9f}\u{0ea1}-\u{0ea3}\u{0eaa}-\u{0eab}\u{0ead}-\u{0eb0}\u{0eb2}-\u{0eb3}\u{0ec0}-\u{0ec4}\u{0ed0}-\u{0ed9}\u{0edc}-\u{0edd}\u{0f00}-\u{0f17}\u{0f1a}-\u{0f34}\u{0f3e}-\u{0f47}\u{0f49}-\u{0f6a}\u{0f88}-\u{0f8b}\u{0fbe}-\u{0fc5}\u{0fc7}-\u{0fcc}\u{1000}-\u{1021}\u{1023}-\u{1027}\u{1029}-\u{102a}\u{1040}-\u{1057}\u{10a0}-\u{10c5}\u{10d0}-\u{10f8}\u{1100}-\u{1159}\u{115f}-\u{11a2}\u{11a8}-\u{11f9}\u{1200}-\u{1206}\u{1208}-\u{1246}\u{124a}-\u{124d}\u{1250}-\u{1256}\u{125a}-\u{125d}\u{1260}-\u{1286}\u{128a}-\u{128d}\u{1290}-\u{12ae}\u{12b2}-\u{12b5}\u{12b8}-\u{12be}\u{12c2}-\u{12c5}\u{12c8}-\u{12ce}\u{12d0}-\u{12d6}\u{12d8}-\u{12ee}\u{12f0}-\u{130e}\u{1312}-\u{1315}\u{1318}-\u{131e}\u{1320}-\u{1346}\u{1348}-\u{135a}\u{1361}-\u{137c}\u{13a0}-\u{13f4}\u{1401}-\u{1676}\u{1681}-\u{169a}\u{16a0}-\u{16f0}\u{1700}-\u{170c}\u{170e}-\u{1711}\u{1720}-\u{1731}\u{1735}-\u{1736}\u{1740}-\u{1751}\u{1760}-\u{176c}\u{176e}-\u{1770}\u{1780}-\u{17b6}\u{17be}-\u{17c5}\u{17c7}-\u{17c8}\u{17d4}-\u{17da}\u{17e0}-\u{17e9}\u{1810}-\u{1819}\u{1820}-\u{1877}\u{1880}-\u{18a8}\u{1e00}-\u{1e9b}\u{1ea0}-\u{1ef9}\u{1f00}-\u{1f15}\u{1f18}-\u{1f1d}\u{1f20}-\u{1f45}\u{1f48}-\u{1f4d}\u{1f50}-\u{1f57}\u{1f5f}-\u{1f7d}\u{1f80}-\u{1fb4}\u{1fb6}-\u{1fbc}\u{1fc2}-\u{1fc4}\u{1fc6}-\u{1fcc}\u{1fd0}-\u{1fd3}\u{1fd6}-\u{1fdb}\u{1fe0}-\u{1fec}\u{1ff2}-\u{1ff4}\u{1ff6}-\u{1ffc}\u{210a}-\u{2113}\u{2119}-\u{211d}\u{212a}-\u{212d}\u{212f}-\u{2131}\u{2133}-\u{2139}\u{213d}-\u{213f}\u{2145}-\u{2149}\u{2160}-\u{2183}\u{2336}-\u{237a}\u{249c}-\u{24e9}\u{3005}-\u{3007}\u{3021}-\u{3029}\u{3031}-\u{3035}\u{3038}-\u{303c}\u{3041}-\u{3096}\u{309d}-\u{309f}\u{30a1}-\u{30fa}\u{30fc}-\u{30ff}\u{3105}-\u{312c}\u{3131}-\u{318e}\u{3190}-\u{31b7}\u{31f0}-\u{321c}\u{3220}-\u{3243}\u{3260}-\u{327b}\u{327f}-\u{32b0}\u{32c0}-\u{32cb}\u{32d0}-\u{32fe}\u{3300}-\u{3376}\u{337b}-\u{33dd}\u{33e0}-\u{33fe}\u{3400}-\u{4db5}\u{4e00}-\u{9fa5}\u{a000}-\u{a48c}\u{ac00}-\u{d7a3}\u{e000}-\u{fa2d}\u{fa30}-\u{fa6a}\u{fb00}-\u{fb06}\u{fb13}-\u{fb17}\u{ff21}-\u{ff3a}\u{ff41}-\u{ff5a}\u{ff66}-\u{ffbe}\u{ffc2}-\u{ffc7}\u{ffca}-\u{ffcf}\u{ffd2}-\u{ffd7}\u{ffda}-\u{ffdc}\u{10300}-\u{1031e}\u{10320}-\u{10323}\u{10330}-\u{1034a}\u{10400}-\u{10425}\u{10428}-\u{1044d}\u{1d000}-\u{1d0f5}\u{1d100}-\u{1d126}\u{1d12a}-\u{1d166}\u{1d16a}-\u{1d172}\u{1d183}-\u{1d184}\u{1d18c}-\u{1d1a9}\u{1d1ae}-\u{1d1dd}\u{1d400}-\u{1d454}\u{1d456}-\u{1d49c}\u{1d49e}-\u{1d49f}\u{1d4a5}-\u{1d4a6}\u{1d4a9}-\u{1d4ac}\u{1d4ae}-\u{1d4b9}\u{1d4bd}-\u{1d4c0}\u{1d4c2}-\u{1d4c3}\u{1d4c5}-\u{1d505}\u{1d507}-\u{1d50a}\u{1d50d}-\u{1d514}\u{1d516}-\u{1d51c}\u{1d51e}-\u{1d539}\u{1d53b}-\u{1d53e}\u{1d540}-\u{1d544}\u{1d54a}-\u{1d550}\u{1d552}-\u{1d6a3}\u{1d6a8}-\u{1d7c9}\u{20000}-\u{2a6d6}\u{2f800}-\u{2fa1d}\u{f0000}-\u{ffffd}\u{100000}-\u{10fffd}\p{Cs}]).*?(?-mix:[\u{05be 05c0 05c3 061b 061f 06dd 0710 07b1 200f fb1d fb3e}\u{05d0}-\u{05ea}\u{05f0}-\u{05f4}\u{0621}-\u{063a}\u{0640}-\u{064a}\u{066d}-\u{066f}\u{0671}-\u{06d5}\u{06e5}-\u{06e6}\u{06fa}-\u{06fe}\u{0700}-\u{070d}\u{0712}-\u{072c}\u{0780}-\u{07a5}\u{fb1f}-\u{fb28}\u{fb2a}-\u{fb36}\u{fb38}-\u{fb3c}\u{fb40}-\u{fb41}\u{fb43}-\u{fb44}\u{fb46}-\u{fbb1}\u{fbd3}-\u{fd3d}\u{fd50}-\u{fd8f}\u{fd92}-\u{fdc7}\u{fdf0}-\u{fdfc}\u{fe70}-\u{fe74}\u{fe76}-\u{fefc}])))|(?-mix:(?m-ix:\A(?-mix:[^\u{05be 05c0 05c3 061b 061f 06dd 0710 07b1 200f fb1d fb3e}\u{05d0}-\u{05ea}\u{05f0}-\u{05f4}\u{0621}-\u{063a}\u{0640}-\u{064a}\u{066d}-\u{066f}\u{0671}-\u{06d5}\u{06e5}-\u{06e6}\u{06fa}-\u{06fe}\u{0700}-\u{070d}\u{0712}-\u{072c}\u{0780}-\u{07a5}\u{fb1f}-\u{fb28}\u{fb2a}-\u{fb36}\u{fb38}-\u{fb3c}\u{fb40}-\u{fb41}\u{fb43}-\u{fb44}\u{fb46}-\u{fbb1}\u{fbd3}-\u{fd3d}\u{fd50}-\u{fd8f}\u{fd92}-\u{fdc7}\u{fdf0}-\u{fdfc}\u{fe70}-\u{fe74}\u{fe76}-\u{fefc}]).*?(?-mix:[\u{05be 05c0 05c3 061b 061f 06dd 0710 07b1 200f fb1d fb3e}\u{05d0}-\u{05ea}\u{05f0}-\u{05f4}\u{0621}-\u{063a}\u{0640}-\u{064a}\u{066d}-\u{066f}\u{0671}-\u{06d5}\u{06e5}-\u{06e6}\u{06fa}-\u{06fe}\u{0700}-\u{070d}\u{0712}-\u{072c}\u{0780}-\u{07a5}\u{fb1f}-\u{fb28}\u{fb2a}-\u{fb36}\u{fb38}-\u{fb3c}\u{fb40}-\u{fb41}\u{fb43}-\u{fb44}\u{fb46}-\u{fbb1}\u{fbd3}-\u{fd3d}\u{fd50}-\u{fd8f}\u{fd92}-\u{fdc7}\u{fdf0}-\u{fdfc}\u{fe70}-\u{fe74}\u{fe76}-\u{fefc}]))|(?m-ix:(?-mix:[\u{05be 05c0 05c3 061b 061f 06dd 0710 07b1 200f fb1d fb3e}\u{05d0}-\u{05ea}\u{05f0}-\u{05f4}\u{0621}-\u{063a}\u{0640}-\u{064a}\u{066d}-\u{066f}\u{0671}-\u{06d5}\u{06e5}-\u{06e6}\u{06fa}-\u{06fe}\u{0700}-\u{070d}\u{0712}-\u{072c}\u{0780}-\u{07a5}\u{fb1f}-\u{fb28}\u{fb2a}-\u{fb36}\u{fb38}-\u{fb3c}\u{fb40}-\u{fb41}\u{fb43}-\u{fb44}\u{fb46}-\u{fbb1}\u{fbd3}-\u{fd3d}\u{fd50}-\u{fd8f}\u{fd92}-\u{fdc7}\u{fdf0}-\u{fdfc}\u{fe70}-\u{fe74}\u{fe76}-\u{fefc}]).*?(?-mix:[^\u{05be 05c0 05c3 061b 061f 06dd 0710 07b1 200f fb1d fb3e}\u{05d0}-\u{05ea}\u{05f0}-\u{05f4}\u{0621}-\u{063a}\u{0640}-\u{064a}\u{066d}-\u{066f}\u{0671}-\u{06d5}\u{06e5}-\u{06e6}\u{06fa}-\u{06fe}\u{0700}-\u{070d}\u{0712}-\u{072c}\u{0780}-\u{07a5}\u{fb1f}-\u{fb28}\u{fb2a}-\u{fb36}\u{fb38}-\u{fb3c}\u{fb40}-\u{fb41}\u{fb43}-\u{fb44}\u{fb46}-\u{fbb1}\u{fbd3}-\u{fd3d}\u{fd50}-\u{fd8f}\u{fd92}-\u{fdc7}\u{fdf0}-\u{fdfc}\u{fe70}-\u{fe74}\u{fe76}-\u{fefc}])\z))/.freeze - # A Regexp matching strings prohibited by RFC4013 §2.3 and §2.4. - # - # This combines PROHIBITED_OUTPUT and BIDI_FAILURE. - PROHIBITED = Regexp.union( - PROHIBITED_OUTPUT, BIDI_FAILURE, - ) - - # A Regexp matching strings prohibited by RFC4013 §2.3, §2.4, and §2.5. - # - # This combines PROHIBITED_OUTPUT_STORED and BIDI_FAILURE. - PROHIBITED_STORED = Regexp.union( - PROHIBITED_OUTPUT_STORED, BIDI_FAILURE, - ) - end end diff --git a/lib/net/imap/stringprep/tables/in_a_1.rb b/lib/net/imap/stringprep/tables/in_a_1.rb new file mode 100644 index 00000000..52c06d33 --- /dev/null +++ b/lib/net/imap/stringprep/tables/in_a_1.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +#-- +# This file is generated by `rake stringprep:tables`. Don't edit directly. +#++ + +module Net::IMAP::StringPrep + module Tables + + # Unassigned code points in Unicode 3.2 \StringPrep\[\"A.1\"] + IN_A_1 = /\p{^AGE=3.2}/.freeze + + end +end diff --git a/lib/net/imap/stringprep/tables/in_b_1.rb b/lib/net/imap/stringprep/tables/in_b_1.rb new file mode 100644 index 00000000..0ed39802 --- /dev/null +++ b/lib/net/imap/stringprep/tables/in_b_1.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +#-- +# This file is generated by `rake stringprep:tables`. Don't edit directly. +#++ + +module Net::IMAP::StringPrep + module Tables + + # Commonly mapped to nothing \StringPrep\[\"B.1\"] + IN_B_1 = /[\u{00ad 034f 1806 2060 feff}\u{180b}-\u{180d}\u{200b}-\u{200d}\u{fe00}-\u{fe0f}]/.freeze + + end +end diff --git a/lib/net/imap/stringprep/tables/in_b_2.rb b/lib/net/imap/stringprep/tables/in_b_2.rb new file mode 100644 index 00000000..4d523176 --- /dev/null +++ b/lib/net/imap/stringprep/tables/in_b_2.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +#-- +# This file is generated by `rake stringprep:tables`. Don't edit directly. +#++ + +module Net::IMAP::StringPrep + module Tables + + # Mapping for case-folding used with NFKC \StringPrep\[\"B.2\"] + IN_B_2 = /[\u{00b5 0100 0102 0104 0106 0108 010a 010c 010e 0110 0112 0114 0116 0118 011a 011c 011e 0120 0122 0124 0126 0128 012a 012c 012e 0130 0132 0134 0136 0139 013b 013d 013f 0141 0143 0145 0147 014c 014e 0150 0152 0154 0156 0158 015a 015c 015e 0160 0162 0164 0166 0168 016a 016c 016e 0170 0172 0174 0176 017b 017d 017f 0184 01a2 01a4 01a9 01ac 01b5 01bc 01cd 01cf 01d1 01d3 01d5 01d7 01d9 01db 01de 01e0 01e2 01e4 01e6 01e8 01ea 01ec 01ee 01f4 01fa 01fc 01fe 0200 0202 0204 0206 0208 020a 020c 020e 0210 0212 0214 0216 0218 021a 021c 021e 0220 0222 0224 0226 0228 022a 022c 022e 0230 0232 0345 037a 0386 038c 03b0 03c2 03d8 03da 03dc 03de 03e0 03e2 03e4 03e6 03e8 03ea 03ec 03ee 0460 0462 0464 0466 0468 046a 046c 046e 0470 0472 0474 0476 0478 047a 047c 047e 0480 048a 048c 048e 0490 0492 0494 0496 0498 049a 049c 049e 04a0 04a2 04a4 04a6 04a8 04aa 04ac 04ae 04b0 04b2 04b4 04b6 04b8 04ba 04bc 04be 04c1 04c3 04c5 04c7 04c9 04cb 04cd 04d0 04d2 04d4 04d6 04d8 04da 04dc 04de 04e0 04e2 04e4 04e6 04e8 04ea 04ec 04ee 04f0 04f2 04f4 04f8 0500 0502 0504 0506 0508 050a 050c 050e 0587 1e00 1e02 1e04 1e06 1e08 1e0a 1e0c 1e0e 1e10 1e12 1e14 1e16 1e18 1e1a 1e1c 1e1e 1e20 1e22 1e24 1e26 1e28 1e2a 1e2c 1e2e 1e30 1e32 1e34 1e36 1e38 1e3a 1e3c 1e3e 1e40 1e42 1e44 1e46 1e48 1e4a 1e4c 1e4e 1e50 1e52 1e54 1e56 1e58 1e5a 1e5c 1e5e 1e60 1e62 1e64 1e66 1e68 1e6a 1e6c 1e6e 1e70 1e72 1e74 1e76 1e78 1e7a 1e7c 1e7e 1e80 1e82 1e84 1e86 1e88 1e8a 1e8c 1e8e 1e90 1e92 1e94 1ea0 1ea2 1ea4 1ea6 1ea8 1eaa 1eac 1eae 1eb0 1eb2 1eb4 1eb6 1eb8 1eba 1ebc 1ebe 1ec0 1ec2 1ec4 1ec6 1ec8 1eca 1ecc 1ece 1ed0 1ed2 1ed4 1ed6 1ed8 1eda 1edc 1ede 1ee0 1ee2 1ee4 1ee6 1ee8 1eea 1eec 1eee 1ef0 1ef2 1ef4 1ef6 1ef8 1f50 1f52 1f54 1f56 1f59 1f5b 1f5d 1f5f 1fbe 20a8 2107 2109 2124 2126 2128 2133 2145 3371 3373 3375 33c3 33cb 33d7 1d49c 1d4a2 1d546 1d6d3 1d70d 1d747 1d781 1d7bb}\u{0041}-\u{005a}\u{00c0}-\u{00d6}\u{00d8}-\u{00df}\u{0149}-\u{014a}\u{0178}-\u{0179}\u{0181}-\u{0182}\u{0186}-\u{0187}\u{0189}-\u{018b}\u{018e}-\u{0191}\u{0193}-\u{0194}\u{0196}-\u{0198}\u{019c}-\u{019d}\u{019f}-\u{01a0}\u{01a6}-\u{01a7}\u{01ae}-\u{01af}\u{01b1}-\u{01b3}\u{01b7}-\u{01b8}\u{01c4}-\u{01c5}\u{01c7}-\u{01c8}\u{01ca}-\u{01cb}\u{01f0}-\u{01f2}\u{01f6}-\u{01f8}\u{0388}-\u{038a}\u{038e}-\u{03a1}\u{03a3}-\u{03ab}\u{03d0}-\u{03d6}\u{03f0}-\u{03f2}\u{03f4}-\u{03f5}\u{0400}-\u{042f}\u{0531}-\u{0556}\u{1e96}-\u{1e9b}\u{1f08}-\u{1f0f}\u{1f18}-\u{1f1d}\u{1f28}-\u{1f2f}\u{1f38}-\u{1f3f}\u{1f48}-\u{1f4d}\u{1f68}-\u{1f6f}\u{1f80}-\u{1faf}\u{1fb2}-\u{1fb4}\u{1fb6}-\u{1fbc}\u{1fc2}-\u{1fc4}\u{1fc6}-\u{1fcc}\u{1fd2}-\u{1fd3}\u{1fd6}-\u{1fdb}\u{1fe2}-\u{1fe4}\u{1fe6}-\u{1fec}\u{1ff2}-\u{1ff4}\u{1ff6}-\u{1ffc}\u{2102}-\u{2103}\u{210b}-\u{210d}\u{2110}-\u{2112}\u{2115}-\u{2116}\u{2119}-\u{211d}\u{2120}-\u{2122}\u{212a}-\u{212d}\u{2130}-\u{2131}\u{213e}-\u{213f}\u{2160}-\u{216f}\u{24b6}-\u{24cf}\u{3380}-\u{3387}\u{338a}-\u{338c}\u{3390}-\u{3394}\u{33a9}-\u{33ac}\u{33b4}-\u{33c1}\u{33c6}-\u{33c9}\u{33cd}-\u{33ce}\u{33d9}-\u{33da}\u{33dc}-\u{33dd}\u{fb00}-\u{fb06}\u{fb13}-\u{fb17}\u{ff21}-\u{ff3a}\u{10400}-\u{10425}\u{1d400}-\u{1d419}\u{1d434}-\u{1d44d}\u{1d468}-\u{1d481}\u{1d49e}-\u{1d49f}\u{1d4a5}-\u{1d4a6}\u{1d4a9}-\u{1d4ac}\u{1d4ae}-\u{1d4b5}\u{1d4d0}-\u{1d4e9}\u{1d504}-\u{1d505}\u{1d507}-\u{1d50a}\u{1d50d}-\u{1d514}\u{1d516}-\u{1d51c}\u{1d538}-\u{1d539}\u{1d53b}-\u{1d53e}\u{1d540}-\u{1d544}\u{1d54a}-\u{1d550}\u{1d56c}-\u{1d585}\u{1d5a0}-\u{1d5b9}\u{1d5d4}-\u{1d5ed}\u{1d608}-\u{1d621}\u{1d63c}-\u{1d655}\u{1d670}-\u{1d689}\u{1d6a8}-\u{1d6c0}\u{1d6e2}-\u{1d6fa}\u{1d71c}-\u{1d734}\u{1d756}-\u{1d76e}\u{1d790}-\u{1d7a8}]/.freeze + + end +end diff --git a/lib/net/imap/stringprep/tables/in_b_3.rb b/lib/net/imap/stringprep/tables/in_b_3.rb new file mode 100644 index 00000000..45bcec00 --- /dev/null +++ b/lib/net/imap/stringprep/tables/in_b_3.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +#-- +# This file is generated by `rake stringprep:tables`. Don't edit directly. +#++ + +module Net::IMAP::StringPrep + module Tables + + # Mapping for case-folding used with no normalization \StringPrep\[\"B.3\"] + IN_B_3 = /[\u{00b5 0100 0102 0104 0106 0108 010a 010c 010e 0110 0112 0114 0116 0118 011a 011c 011e 0120 0122 0124 0126 0128 012a 012c 012e 0130 0132 0134 0136 0139 013b 013d 013f 0141 0143 0145 0147 014c 014e 0150 0152 0154 0156 0158 015a 015c 015e 0160 0162 0164 0166 0168 016a 016c 016e 0170 0172 0174 0176 017b 017d 017f 0184 01a2 01a4 01a9 01ac 01b5 01bc 01cd 01cf 01d1 01d3 01d5 01d7 01d9 01db 01de 01e0 01e2 01e4 01e6 01e8 01ea 01ec 01ee 01f4 01fa 01fc 01fe 0200 0202 0204 0206 0208 020a 020c 020e 0210 0212 0214 0216 0218 021a 021c 021e 0220 0222 0224 0226 0228 022a 022c 022e 0230 0232 0345 0386 038c 03b0 03c2 03d8 03da 03dc 03de 03e0 03e2 03e4 03e6 03e8 03ea 03ec 03ee 0460 0462 0464 0466 0468 046a 046c 046e 0470 0472 0474 0476 0478 047a 047c 047e 0480 048a 048c 048e 0490 0492 0494 0496 0498 049a 049c 049e 04a0 04a2 04a4 04a6 04a8 04aa 04ac 04ae 04b0 04b2 04b4 04b6 04b8 04ba 04bc 04be 04c1 04c3 04c5 04c7 04c9 04cb 04cd 04d0 04d2 04d4 04d6 04d8 04da 04dc 04de 04e0 04e2 04e4 04e6 04e8 04ea 04ec 04ee 04f0 04f2 04f4 04f8 0500 0502 0504 0506 0508 050a 050c 050e 0587 1e00 1e02 1e04 1e06 1e08 1e0a 1e0c 1e0e 1e10 1e12 1e14 1e16 1e18 1e1a 1e1c 1e1e 1e20 1e22 1e24 1e26 1e28 1e2a 1e2c 1e2e 1e30 1e32 1e34 1e36 1e38 1e3a 1e3c 1e3e 1e40 1e42 1e44 1e46 1e48 1e4a 1e4c 1e4e 1e50 1e52 1e54 1e56 1e58 1e5a 1e5c 1e5e 1e60 1e62 1e64 1e66 1e68 1e6a 1e6c 1e6e 1e70 1e72 1e74 1e76 1e78 1e7a 1e7c 1e7e 1e80 1e82 1e84 1e86 1e88 1e8a 1e8c 1e8e 1e90 1e92 1e94 1ea0 1ea2 1ea4 1ea6 1ea8 1eaa 1eac 1eae 1eb0 1eb2 1eb4 1eb6 1eb8 1eba 1ebc 1ebe 1ec0 1ec2 1ec4 1ec6 1ec8 1eca 1ecc 1ece 1ed0 1ed2 1ed4 1ed6 1ed8 1eda 1edc 1ede 1ee0 1ee2 1ee4 1ee6 1ee8 1eea 1eec 1eee 1ef0 1ef2 1ef4 1ef6 1ef8 1f50 1f52 1f54 1f56 1f59 1f5b 1f5d 1f5f 1fbe 2126}\u{0041}-\u{005a}\u{00c0}-\u{00d6}\u{00d8}-\u{00df}\u{0149}-\u{014a}\u{0178}-\u{0179}\u{0181}-\u{0182}\u{0186}-\u{0187}\u{0189}-\u{018b}\u{018e}-\u{0191}\u{0193}-\u{0194}\u{0196}-\u{0198}\u{019c}-\u{019d}\u{019f}-\u{01a0}\u{01a6}-\u{01a7}\u{01ae}-\u{01af}\u{01b1}-\u{01b3}\u{01b7}-\u{01b8}\u{01c4}-\u{01c5}\u{01c7}-\u{01c8}\u{01ca}-\u{01cb}\u{01f0}-\u{01f2}\u{01f6}-\u{01f8}\u{0388}-\u{038a}\u{038e}-\u{03a1}\u{03a3}-\u{03ab}\u{03d0}-\u{03d1}\u{03d5}-\u{03d6}\u{03f0}-\u{03f2}\u{03f4}-\u{03f5}\u{0400}-\u{042f}\u{0531}-\u{0556}\u{1e96}-\u{1e9b}\u{1f08}-\u{1f0f}\u{1f18}-\u{1f1d}\u{1f28}-\u{1f2f}\u{1f38}-\u{1f3f}\u{1f48}-\u{1f4d}\u{1f68}-\u{1f6f}\u{1f80}-\u{1faf}\u{1fb2}-\u{1fb4}\u{1fb6}-\u{1fbc}\u{1fc2}-\u{1fc4}\u{1fc6}-\u{1fcc}\u{1fd2}-\u{1fd3}\u{1fd6}-\u{1fdb}\u{1fe2}-\u{1fe4}\u{1fe6}-\u{1fec}\u{1ff2}-\u{1ff4}\u{1ff6}-\u{1ffc}\u{212a}-\u{212b}\u{2160}-\u{216f}\u{24b6}-\u{24cf}\u{fb00}-\u{fb06}\u{fb13}-\u{fb17}\u{ff21}-\u{ff3a}\u{10400}-\u{10425}]/.freeze + + end +end diff --git a/lib/net/imap/stringprep/tables/in_c_1_1.rb b/lib/net/imap/stringprep/tables/in_c_1_1.rb new file mode 100644 index 00000000..74a888c8 --- /dev/null +++ b/lib/net/imap/stringprep/tables/in_c_1_1.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +#-- +# This file is generated by `rake stringprep:tables`. Don't edit directly. +#++ + +module Net::IMAP::StringPrep + module Tables + + # ASCII space characters \StringPrep\[\"C.1.1\"] + IN_C_1_1 = / /.freeze + + end +end diff --git a/lib/net/imap/stringprep/tables/in_c_1_2.rb b/lib/net/imap/stringprep/tables/in_c_1_2.rb new file mode 100644 index 00000000..f3e6e953 --- /dev/null +++ b/lib/net/imap/stringprep/tables/in_c_1_2.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +#-- +# This file is generated by `rake stringprep:tables`. Don't edit directly. +#++ + +module Net::IMAP::StringPrep + module Tables + + # Non-ASCII space characters \StringPrep\[\"C.1.2\"] + IN_C_1_2 = /[\u200b\p{Zs}&&[^ ]]/.freeze + + end +end diff --git a/lib/net/imap/stringprep/tables/in_c_2_1.rb b/lib/net/imap/stringprep/tables/in_c_2_1.rb new file mode 100644 index 00000000..1c350213 --- /dev/null +++ b/lib/net/imap/stringprep/tables/in_c_2_1.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +#-- +# This file is generated by `rake stringprep:tables`. Don't edit directly. +#++ + +module Net::IMAP::StringPrep + module Tables + + # ASCII control characters \StringPrep\[\"C.2.1\"] + IN_C_2_1 = /[\x00-\x1f\x7f]/.freeze + + end +end diff --git a/lib/net/imap/stringprep/tables/in_c_2_2.rb b/lib/net/imap/stringprep/tables/in_c_2_2.rb new file mode 100644 index 00000000..4f4c1377 --- /dev/null +++ b/lib/net/imap/stringprep/tables/in_c_2_2.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +#-- +# This file is generated by `rake stringprep:tables`. Don't edit directly. +#++ + +module Net::IMAP::StringPrep + module Tables + + # Non-ASCII control characters \StringPrep\[\"C.2.2\"] + IN_C_2_2 = /[\u{06dd 070f 180e feff}\u{0080}-\u{009f}\u{200c}-\u{200d}\u{2028}-\u{2029}\u{2060}-\u{2063}\u{206a}-\u{206f}\u{fff9}-\u{fffc}\u{1d173}-\u{1d17a}]/.freeze + + end +end diff --git a/lib/net/imap/stringprep/tables/in_c_3.rb b/lib/net/imap/stringprep/tables/in_c_3.rb new file mode 100644 index 00000000..1404c643 --- /dev/null +++ b/lib/net/imap/stringprep/tables/in_c_3.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +#-- +# This file is generated by `rake stringprep:tables`. Don't edit directly. +#++ + +module Net::IMAP::StringPrep + module Tables + + # Private use \StringPrep\[\"C.3\"] + IN_C_3 = /\p{private use}/.freeze + + end +end diff --git a/lib/net/imap/stringprep/tables/in_c_4.rb b/lib/net/imap/stringprep/tables/in_c_4.rb new file mode 100644 index 00000000..329387c0 --- /dev/null +++ b/lib/net/imap/stringprep/tables/in_c_4.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +#-- +# This file is generated by `rake stringprep:tables`. Don't edit directly. +#++ + +module Net::IMAP::StringPrep + module Tables + + # Non-character code points \StringPrep\[\"C.4\"] + IN_C_4 = /\p{noncharacter code point}/.freeze + + end +end diff --git a/lib/net/imap/stringprep/tables/in_c_5.rb b/lib/net/imap/stringprep/tables/in_c_5.rb new file mode 100644 index 00000000..d7fc9701 --- /dev/null +++ b/lib/net/imap/stringprep/tables/in_c_5.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +#-- +# This file is generated by `rake stringprep:tables`. Don't edit directly. +#++ + +module Net::IMAP::StringPrep + module Tables + + # Surrogate codes \StringPrep\[\"C.5\"] + IN_C_5 = /\p{surrogate}/.freeze + + end +end diff --git a/lib/net/imap/stringprep/tables/in_c_6.rb b/lib/net/imap/stringprep/tables/in_c_6.rb new file mode 100644 index 00000000..c6b58cb0 --- /dev/null +++ b/lib/net/imap/stringprep/tables/in_c_6.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +#-- +# This file is generated by `rake stringprep:tables`. Don't edit directly. +#++ + +module Net::IMAP::StringPrep + module Tables + + # Inappropriate for plain text \StringPrep\[\"C.6\"] + IN_C_6 = /[\p{in specials}&&\p{AGE=3.2}&&\p{^NChar}]/.freeze + + end +end diff --git a/lib/net/imap/stringprep/tables/in_c_7.rb b/lib/net/imap/stringprep/tables/in_c_7.rb new file mode 100644 index 00000000..eb99aadc --- /dev/null +++ b/lib/net/imap/stringprep/tables/in_c_7.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +#-- +# This file is generated by `rake stringprep:tables`. Don't edit directly. +#++ + +module Net::IMAP::StringPrep + module Tables + + # Inappropriate for canonical representation \StringPrep\[\"C.7\"] + IN_C_7 = /[\p{in ideographic description characters}&&\p{AGE=3.2}]/.freeze + + end +end diff --git a/lib/net/imap/stringprep/tables/in_c_8.rb b/lib/net/imap/stringprep/tables/in_c_8.rb new file mode 100644 index 00000000..90cbd5ab --- /dev/null +++ b/lib/net/imap/stringprep/tables/in_c_8.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +#-- +# This file is generated by `rake stringprep:tables`. Don't edit directly. +#++ + +module Net::IMAP::StringPrep + module Tables + + # Change display properties or are deprecated \StringPrep\[\"C.8\"] + IN_C_8 = /[\u{0340}-\u{0341}\u{200e}-\u{200f}\u{202a}-\u{202e}\u{206a}-\u{206f}]/.freeze + + end +end diff --git a/lib/net/imap/stringprep/tables/in_c_9.rb b/lib/net/imap/stringprep/tables/in_c_9.rb new file mode 100644 index 00000000..e9240eff --- /dev/null +++ b/lib/net/imap/stringprep/tables/in_c_9.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +#-- +# This file is generated by `rake stringprep:tables`. Don't edit directly. +#++ + +module Net::IMAP::StringPrep + module Tables + + # Tagging characters \StringPrep\[\"C.9\"] + IN_C_9 = /[\p{in Tags}&&\p{AGE=3.2}]/.freeze + + end +end diff --git a/lib/net/imap/stringprep/tables/in_d_1.rb b/lib/net/imap/stringprep/tables/in_d_1.rb new file mode 100644 index 00000000..7f3c8cf4 --- /dev/null +++ b/lib/net/imap/stringprep/tables/in_d_1.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +#-- +# This file is generated by `rake stringprep:tables`. Don't edit directly. +#++ + +module Net::IMAP::StringPrep + module Tables + + # Characters with bidirectional property "R" or "AL" \StringPrep\[\"D.1\"] + IN_D_1 = /[\u{05be 05c0 05c3 061b 061f 06dd 0710 07b1 200f fb1d fb3e}\u{05d0}-\u{05ea}\u{05f0}-\u{05f4}\u{0621}-\u{063a}\u{0640}-\u{064a}\u{066d}-\u{066f}\u{0671}-\u{06d5}\u{06e5}-\u{06e6}\u{06fa}-\u{06fe}\u{0700}-\u{070d}\u{0712}-\u{072c}\u{0780}-\u{07a5}\u{fb1f}-\u{fb28}\u{fb2a}-\u{fb36}\u{fb38}-\u{fb3c}\u{fb40}-\u{fb41}\u{fb43}-\u{fb44}\u{fb46}-\u{fbb1}\u{fbd3}-\u{fd3d}\u{fd50}-\u{fd8f}\u{fd92}-\u{fdc7}\u{fdf0}-\u{fdfc}\u{fe70}-\u{fe74}\u{fe76}-\u{fefc}]/.freeze + + end +end diff --git a/lib/net/imap/stringprep/tables/in_d_1_negated.rb b/lib/net/imap/stringprep/tables/in_d_1_negated.rb new file mode 100644 index 00000000..ba763f0b --- /dev/null +++ b/lib/net/imap/stringprep/tables/in_d_1_negated.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +#-- +# This file is generated by `rake stringprep:tables`. Don't edit directly. +#++ + +module Net::IMAP::StringPrep + module Tables + + # Matches the negation of the D.1 table + IN_D_1_NEGATED = /[^\u{05be 05c0 05c3 061b 061f 06dd 0710 07b1 200f fb1d fb3e}\u{05d0}-\u{05ea}\u{05f0}-\u{05f4}\u{0621}-\u{063a}\u{0640}-\u{064a}\u{066d}-\u{066f}\u{0671}-\u{06d5}\u{06e5}-\u{06e6}\u{06fa}-\u{06fe}\u{0700}-\u{070d}\u{0712}-\u{072c}\u{0780}-\u{07a5}\u{fb1f}-\u{fb28}\u{fb2a}-\u{fb36}\u{fb38}-\u{fb3c}\u{fb40}-\u{fb41}\u{fb43}-\u{fb44}\u{fb46}-\u{fbb1}\u{fbd3}-\u{fd3d}\u{fd50}-\u{fd8f}\u{fd92}-\u{fdc7}\u{fdf0}-\u{fdfc}\u{fe70}-\u{fe74}\u{fe76}-\u{fefc}]/.freeze + + end +end diff --git a/lib/net/imap/stringprep/tables/in_d_2.rb b/lib/net/imap/stringprep/tables/in_d_2.rb new file mode 100644 index 00000000..d15aec11 --- /dev/null +++ b/lib/net/imap/stringprep/tables/in_d_2.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +#-- +# This file is generated by `rake stringprep:tables`. Don't edit directly. +#++ + +module Net::IMAP::StringPrep + module Tables + + # Characters with bidirectional property "L" \StringPrep\[\"D.2\"] + IN_D_2 = /[\u{00aa 00b5 00ba 02ee 037a 0386 038c 0589 0903 0950 09b2 09d7 0a5e 0a83 0a8d 0ac9 0ad0 0ae0 0b40 0b57 0b83 0b9c 0bd7 0cbe 0cde 0d57 0dbd 0e84 0e8a 0e8d 0ea5 0ea7 0ebd 0ec6 0f36 0f38 0f7f 0f85 0fcf 102c 1031 1038 10fb 1248 1258 1288 12b0 12c0 1310 17dc 1f59 1f5b 1f5d 1fbe 200e 2071 207f 2102 2107 2115 2124 2126 2128 2395 1d4a2 1d4bb 1d546}\u{0041}-\u{005a}\u{0061}-\u{007a}\u{00c0}-\u{00d6}\u{00d8}-\u{00f6}\u{00f8}-\u{0220}\u{0222}-\u{0233}\u{0250}-\u{02ad}\u{02b0}-\u{02b8}\u{02bb}-\u{02c1}\u{02d0}-\u{02d1}\u{02e0}-\u{02e4}\u{0388}-\u{038a}\u{038e}-\u{03a1}\u{03a3}-\u{03ce}\u{03d0}-\u{03f5}\u{0400}-\u{0482}\u{048a}-\u{04ce}\u{04d0}-\u{04f5}\u{04f8}-\u{04f9}\u{0500}-\u{050f}\u{0531}-\u{0556}\u{0559}-\u{055f}\u{0561}-\u{0587}\u{0905}-\u{0939}\u{093d}-\u{0940}\u{0949}-\u{094c}\u{0958}-\u{0961}\u{0964}-\u{0970}\u{0982}-\u{0983}\u{0985}-\u{098c}\u{098f}-\u{0990}\u{0993}-\u{09a8}\u{09aa}-\u{09b0}\u{09b6}-\u{09b9}\u{09be}-\u{09c0}\u{09c7}-\u{09c8}\u{09cb}-\u{09cc}\u{09dc}-\u{09dd}\u{09df}-\u{09e1}\u{09e6}-\u{09f1}\u{09f4}-\u{09fa}\u{0a05}-\u{0a0a}\u{0a0f}-\u{0a10}\u{0a13}-\u{0a28}\u{0a2a}-\u{0a30}\u{0a32}-\u{0a33}\u{0a35}-\u{0a36}\u{0a38}-\u{0a39}\u{0a3e}-\u{0a40}\u{0a59}-\u{0a5c}\u{0a66}-\u{0a6f}\u{0a72}-\u{0a74}\u{0a85}-\u{0a8b}\u{0a8f}-\u{0a91}\u{0a93}-\u{0aa8}\u{0aaa}-\u{0ab0}\u{0ab2}-\u{0ab3}\u{0ab5}-\u{0ab9}\u{0abd}-\u{0ac0}\u{0acb}-\u{0acc}\u{0ae6}-\u{0aef}\u{0b02}-\u{0b03}\u{0b05}-\u{0b0c}\u{0b0f}-\u{0b10}\u{0b13}-\u{0b28}\u{0b2a}-\u{0b30}\u{0b32}-\u{0b33}\u{0b36}-\u{0b39}\u{0b3d}-\u{0b3e}\u{0b47}-\u{0b48}\u{0b4b}-\u{0b4c}\u{0b5c}-\u{0b5d}\u{0b5f}-\u{0b61}\u{0b66}-\u{0b70}\u{0b85}-\u{0b8a}\u{0b8e}-\u{0b90}\u{0b92}-\u{0b95}\u{0b99}-\u{0b9a}\u{0b9e}-\u{0b9f}\u{0ba3}-\u{0ba4}\u{0ba8}-\u{0baa}\u{0bae}-\u{0bb5}\u{0bb7}-\u{0bb9}\u{0bbe}-\u{0bbf}\u{0bc1}-\u{0bc2}\u{0bc6}-\u{0bc8}\u{0bca}-\u{0bcc}\u{0be7}-\u{0bf2}\u{0c01}-\u{0c03}\u{0c05}-\u{0c0c}\u{0c0e}-\u{0c10}\u{0c12}-\u{0c28}\u{0c2a}-\u{0c33}\u{0c35}-\u{0c39}\u{0c41}-\u{0c44}\u{0c60}-\u{0c61}\u{0c66}-\u{0c6f}\u{0c82}-\u{0c83}\u{0c85}-\u{0c8c}\u{0c8e}-\u{0c90}\u{0c92}-\u{0ca8}\u{0caa}-\u{0cb3}\u{0cb5}-\u{0cb9}\u{0cc0}-\u{0cc4}\u{0cc7}-\u{0cc8}\u{0cca}-\u{0ccb}\u{0cd5}-\u{0cd6}\u{0ce0}-\u{0ce1}\u{0ce6}-\u{0cef}\u{0d02}-\u{0d03}\u{0d05}-\u{0d0c}\u{0d0e}-\u{0d10}\u{0d12}-\u{0d28}\u{0d2a}-\u{0d39}\u{0d3e}-\u{0d40}\u{0d46}-\u{0d48}\u{0d4a}-\u{0d4c}\u{0d60}-\u{0d61}\u{0d66}-\u{0d6f}\u{0d82}-\u{0d83}\u{0d85}-\u{0d96}\u{0d9a}-\u{0db1}\u{0db3}-\u{0dbb}\u{0dc0}-\u{0dc6}\u{0dcf}-\u{0dd1}\u{0dd8}-\u{0ddf}\u{0df2}-\u{0df4}\u{0e01}-\u{0e30}\u{0e32}-\u{0e33}\u{0e40}-\u{0e46}\u{0e4f}-\u{0e5b}\u{0e81}-\u{0e82}\u{0e87}-\u{0e88}\u{0e94}-\u{0e97}\u{0e99}-\u{0e9f}\u{0ea1}-\u{0ea3}\u{0eaa}-\u{0eab}\u{0ead}-\u{0eb0}\u{0eb2}-\u{0eb3}\u{0ec0}-\u{0ec4}\u{0ed0}-\u{0ed9}\u{0edc}-\u{0edd}\u{0f00}-\u{0f17}\u{0f1a}-\u{0f34}\u{0f3e}-\u{0f47}\u{0f49}-\u{0f6a}\u{0f88}-\u{0f8b}\u{0fbe}-\u{0fc5}\u{0fc7}-\u{0fcc}\u{1000}-\u{1021}\u{1023}-\u{1027}\u{1029}-\u{102a}\u{1040}-\u{1057}\u{10a0}-\u{10c5}\u{10d0}-\u{10f8}\u{1100}-\u{1159}\u{115f}-\u{11a2}\u{11a8}-\u{11f9}\u{1200}-\u{1206}\u{1208}-\u{1246}\u{124a}-\u{124d}\u{1250}-\u{1256}\u{125a}-\u{125d}\u{1260}-\u{1286}\u{128a}-\u{128d}\u{1290}-\u{12ae}\u{12b2}-\u{12b5}\u{12b8}-\u{12be}\u{12c2}-\u{12c5}\u{12c8}-\u{12ce}\u{12d0}-\u{12d6}\u{12d8}-\u{12ee}\u{12f0}-\u{130e}\u{1312}-\u{1315}\u{1318}-\u{131e}\u{1320}-\u{1346}\u{1348}-\u{135a}\u{1361}-\u{137c}\u{13a0}-\u{13f4}\u{1401}-\u{1676}\u{1681}-\u{169a}\u{16a0}-\u{16f0}\u{1700}-\u{170c}\u{170e}-\u{1711}\u{1720}-\u{1731}\u{1735}-\u{1736}\u{1740}-\u{1751}\u{1760}-\u{176c}\u{176e}-\u{1770}\u{1780}-\u{17b6}\u{17be}-\u{17c5}\u{17c7}-\u{17c8}\u{17d4}-\u{17da}\u{17e0}-\u{17e9}\u{1810}-\u{1819}\u{1820}-\u{1877}\u{1880}-\u{18a8}\u{1e00}-\u{1e9b}\u{1ea0}-\u{1ef9}\u{1f00}-\u{1f15}\u{1f18}-\u{1f1d}\u{1f20}-\u{1f45}\u{1f48}-\u{1f4d}\u{1f50}-\u{1f57}\u{1f5f}-\u{1f7d}\u{1f80}-\u{1fb4}\u{1fb6}-\u{1fbc}\u{1fc2}-\u{1fc4}\u{1fc6}-\u{1fcc}\u{1fd0}-\u{1fd3}\u{1fd6}-\u{1fdb}\u{1fe0}-\u{1fec}\u{1ff2}-\u{1ff4}\u{1ff6}-\u{1ffc}\u{210a}-\u{2113}\u{2119}-\u{211d}\u{212a}-\u{212d}\u{212f}-\u{2131}\u{2133}-\u{2139}\u{213d}-\u{213f}\u{2145}-\u{2149}\u{2160}-\u{2183}\u{2336}-\u{237a}\u{249c}-\u{24e9}\u{3005}-\u{3007}\u{3021}-\u{3029}\u{3031}-\u{3035}\u{3038}-\u{303c}\u{3041}-\u{3096}\u{309d}-\u{309f}\u{30a1}-\u{30fa}\u{30fc}-\u{30ff}\u{3105}-\u{312c}\u{3131}-\u{318e}\u{3190}-\u{31b7}\u{31f0}-\u{321c}\u{3220}-\u{3243}\u{3260}-\u{327b}\u{327f}-\u{32b0}\u{32c0}-\u{32cb}\u{32d0}-\u{32fe}\u{3300}-\u{3376}\u{337b}-\u{33dd}\u{33e0}-\u{33fe}\u{3400}-\u{4db5}\u{4e00}-\u{9fa5}\u{a000}-\u{a48c}\u{ac00}-\u{d7a3}\u{e000}-\u{fa2d}\u{fa30}-\u{fa6a}\u{fb00}-\u{fb06}\u{fb13}-\u{fb17}\u{ff21}-\u{ff3a}\u{ff41}-\u{ff5a}\u{ff66}-\u{ffbe}\u{ffc2}-\u{ffc7}\u{ffca}-\u{ffcf}\u{ffd2}-\u{ffd7}\u{ffda}-\u{ffdc}\u{10300}-\u{1031e}\u{10320}-\u{10323}\u{10330}-\u{1034a}\u{10400}-\u{10425}\u{10428}-\u{1044d}\u{1d000}-\u{1d0f5}\u{1d100}-\u{1d126}\u{1d12a}-\u{1d166}\u{1d16a}-\u{1d172}\u{1d183}-\u{1d184}\u{1d18c}-\u{1d1a9}\u{1d1ae}-\u{1d1dd}\u{1d400}-\u{1d454}\u{1d456}-\u{1d49c}\u{1d49e}-\u{1d49f}\u{1d4a5}-\u{1d4a6}\u{1d4a9}-\u{1d4ac}\u{1d4ae}-\u{1d4b9}\u{1d4bd}-\u{1d4c0}\u{1d4c2}-\u{1d4c3}\u{1d4c5}-\u{1d505}\u{1d507}-\u{1d50a}\u{1d50d}-\u{1d514}\u{1d516}-\u{1d51c}\u{1d51e}-\u{1d539}\u{1d53b}-\u{1d53e}\u{1d540}-\u{1d544}\u{1d54a}-\u{1d550}\u{1d552}-\u{1d6a3}\u{1d6a8}-\u{1d7c9}\u{20000}-\u{2a6d6}\u{2f800}-\u{2fa1d}\u{f0000}-\u{ffffd}\u{100000}-\u{10fffd}\p{Cs}]/.freeze + + end +end diff --git a/lib/net/imap/stringprep/tables/map_b_1.rb b/lib/net/imap/stringprep/tables/map_b_1.rb new file mode 100644 index 00000000..bae9811b --- /dev/null +++ b/lib/net/imap/stringprep/tables/map_b_1.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +#-- +# This file is generated by `rake stringprep:tables`. Don't edit directly. +#++ + +module Net::IMAP::StringPrep + module Tables + + # Replacements for IN_B.1 + MAP_B_1 = {"­"=>"", "͏"=>"", "᠆"=>"", "᠋"=>"", "᠌"=>"", "᠍"=>"", "​"=>"", "‌"=>"", "‍"=>"", "⁠"=>"", "︀"=>"", "︁"=>"", "︂"=>"", "︃"=>"", "︄"=>"", "︅"=>"", "︆"=>"", "︇"=>"", "︈"=>"", "︉"=>"", "︊"=>"", "︋"=>"", "︌"=>"", "︍"=>"", "︎"=>"", "️"=>"", ""=>""}.freeze + + end +end diff --git a/lib/net/imap/stringprep/tables/map_b_2.rb b/lib/net/imap/stringprep/tables/map_b_2.rb new file mode 100644 index 00000000..c325923f --- /dev/null +++ b/lib/net/imap/stringprep/tables/map_b_2.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +#-- +# This file is generated by `rake stringprep:tables`. Don't edit directly. +#++ + +module Net::IMAP::StringPrep + module Tables + + # Replacements for IN_B.2 + MAP_B_2 = {"A"=>"a", "B"=>"b", "C"=>"c", "D"=>"d", "E"=>"e", "F"=>"f", "G"=>"g", "H"=>"h", "I"=>"i", "J"=>"j", "K"=>"k", "L"=>"l", "M"=>"m", "N"=>"n", "O"=>"o", "P"=>"p", "Q"=>"q", "R"=>"r", "S"=>"s", "T"=>"t", "U"=>"u", "V"=>"v", "W"=>"w", "X"=>"x", "Y"=>"y", "Z"=>"z", "µ"=>"μ", "À"=>"à", "Á"=>"á", "Â"=>"â", "Ã"=>"ã", "Ä"=>"ä", "Å"=>"å", "Æ"=>"æ", "Ç"=>"ç", "È"=>"è", "É"=>"é", "Ê"=>"ê", "Ë"=>"ë", "Ì"=>"ì", "Í"=>"í", "Î"=>"î", "Ï"=>"ï", "Ð"=>"ð", "Ñ"=>"ñ", "Ò"=>"ò", "Ó"=>"ó", "Ô"=>"ô", "Õ"=>"õ", "Ö"=>"ö", "Ø"=>"ø", "Ù"=>"ù", "Ú"=>"ú", "Û"=>"û", "Ü"=>"ü", "Ý"=>"ý", "Þ"=>"þ", "ß"=>"ss", "Ā"=>"ā", "Ă"=>"ă", "Ą"=>"ą", "Ć"=>"ć", "Ĉ"=>"ĉ", "Ċ"=>"ċ", "Č"=>"č", "Ď"=>"ď", "Đ"=>"đ", "Ē"=>"ē", "Ĕ"=>"ĕ", "Ė"=>"ė", "Ę"=>"ę", "Ě"=>"ě", "Ĝ"=>"ĝ", "Ğ"=>"ğ", "Ġ"=>"ġ", "Ģ"=>"ģ", "Ĥ"=>"ĥ", "Ħ"=>"ħ", "Ĩ"=>"ĩ", "Ī"=>"ī", "Ĭ"=>"ĭ", "Į"=>"į", "İ"=>"i̇", "IJ"=>"ij", "Ĵ"=>"ĵ", "Ķ"=>"ķ", "Ĺ"=>"ĺ", "Ļ"=>"ļ", "Ľ"=>"ľ", "Ŀ"=>"ŀ", "Ł"=>"ł", "Ń"=>"ń", "Ņ"=>"ņ", "Ň"=>"ň", "ʼn"=>"ʼn", "Ŋ"=>"ŋ", "Ō"=>"ō", "Ŏ"=>"ŏ", "Ő"=>"ő", "Œ"=>"œ", "Ŕ"=>"ŕ", "Ŗ"=>"ŗ", "Ř"=>"ř", "Ś"=>"ś", "Ŝ"=>"ŝ", "Ş"=>"ş", "Š"=>"š", "Ţ"=>"ţ", "Ť"=>"ť", "Ŧ"=>"ŧ", "Ũ"=>"ũ", "Ū"=>"ū", "Ŭ"=>"ŭ", "Ů"=>"ů", "Ű"=>"ű", "Ų"=>"ų", "Ŵ"=>"ŵ", "Ŷ"=>"ŷ", "Ÿ"=>"ÿ", "Ź"=>"ź", "Ż"=>"ż", "Ž"=>"ž", "ſ"=>"s", "Ɓ"=>"ɓ", "Ƃ"=>"ƃ", "Ƅ"=>"ƅ", "Ɔ"=>"ɔ", "Ƈ"=>"ƈ", "Ɖ"=>"ɖ", "Ɗ"=>"ɗ", "Ƌ"=>"ƌ", "Ǝ"=>"ǝ", "Ə"=>"ə", "Ɛ"=>"ɛ", "Ƒ"=>"ƒ", "Ɠ"=>"ɠ", "Ɣ"=>"ɣ", "Ɩ"=>"ɩ", "Ɨ"=>"ɨ", "Ƙ"=>"ƙ", "Ɯ"=>"ɯ", "Ɲ"=>"ɲ", "Ɵ"=>"ɵ", "Ơ"=>"ơ", "Ƣ"=>"ƣ", "Ƥ"=>"ƥ", "Ʀ"=>"ʀ", "Ƨ"=>"ƨ", "Ʃ"=>"ʃ", "Ƭ"=>"ƭ", "Ʈ"=>"ʈ", "Ư"=>"ư", "Ʊ"=>"ʊ", "Ʋ"=>"ʋ", "Ƴ"=>"ƴ", "Ƶ"=>"ƶ", "Ʒ"=>"ʒ", "Ƹ"=>"ƹ", "Ƽ"=>"ƽ", "DŽ"=>"dž", "Dž"=>"dž", "LJ"=>"lj", "Lj"=>"lj", "NJ"=>"nj", "Nj"=>"nj", "Ǎ"=>"ǎ", "Ǐ"=>"ǐ", "Ǒ"=>"ǒ", "Ǔ"=>"ǔ", "Ǖ"=>"ǖ", "Ǘ"=>"ǘ", "Ǚ"=>"ǚ", "Ǜ"=>"ǜ", "Ǟ"=>"ǟ", "Ǡ"=>"ǡ", "Ǣ"=>"ǣ", "Ǥ"=>"ǥ", "Ǧ"=>"ǧ", "Ǩ"=>"ǩ", "Ǫ"=>"ǫ", "Ǭ"=>"ǭ", "Ǯ"=>"ǯ", "ǰ"=>"ǰ", "DZ"=>"dz", "Dz"=>"dz", "Ǵ"=>"ǵ", "Ƕ"=>"ƕ", "Ƿ"=>"ƿ", "Ǹ"=>"ǹ", "Ǻ"=>"ǻ", "Ǽ"=>"ǽ", "Ǿ"=>"ǿ", "Ȁ"=>"ȁ", "Ȃ"=>"ȃ", "Ȅ"=>"ȅ", "Ȇ"=>"ȇ", "Ȉ"=>"ȉ", "Ȋ"=>"ȋ", "Ȍ"=>"ȍ", "Ȏ"=>"ȏ", "Ȑ"=>"ȑ", "Ȓ"=>"ȓ", "Ȕ"=>"ȕ", "Ȗ"=>"ȗ", "Ș"=>"ș", "Ț"=>"ț", "Ȝ"=>"ȝ", "Ȟ"=>"ȟ", "Ƞ"=>"ƞ", "Ȣ"=>"ȣ", "Ȥ"=>"ȥ", "Ȧ"=>"ȧ", "Ȩ"=>"ȩ", "Ȫ"=>"ȫ", "Ȭ"=>"ȭ", "Ȯ"=>"ȯ", "Ȱ"=>"ȱ", "Ȳ"=>"ȳ", "ͅ"=>"ι", "ͺ"=>" ι", "Ά"=>"ά", "Έ"=>"έ", "Ή"=>"ή", "Ί"=>"ί", "Ό"=>"ό", "Ύ"=>"ύ", "Ώ"=>"ώ", "ΐ"=>"ΐ", "Α"=>"α", "Β"=>"β", "Γ"=>"γ", "Δ"=>"δ", "Ε"=>"ε", "Ζ"=>"ζ", "Η"=>"η", "Θ"=>"θ", "Ι"=>"ι", "Κ"=>"κ", "Λ"=>"λ", "Μ"=>"μ", "Ν"=>"ν", "Ξ"=>"ξ", "Ο"=>"ο", "Π"=>"π", "Ρ"=>"ρ", "Σ"=>"σ", "Τ"=>"τ", "Υ"=>"υ", "Φ"=>"φ", "Χ"=>"χ", "Ψ"=>"ψ", "Ω"=>"ω", "Ϊ"=>"ϊ", "Ϋ"=>"ϋ", "ΰ"=>"ΰ", "ς"=>"σ", "ϐ"=>"β", "ϑ"=>"θ", "ϒ"=>"υ", "ϓ"=>"ύ", "ϔ"=>"ϋ", "ϕ"=>"φ", "ϖ"=>"π", "Ϙ"=>"ϙ", "Ϛ"=>"ϛ", "Ϝ"=>"ϝ", "Ϟ"=>"ϟ", "Ϡ"=>"ϡ", "Ϣ"=>"ϣ", "Ϥ"=>"ϥ", "Ϧ"=>"ϧ", "Ϩ"=>"ϩ", "Ϫ"=>"ϫ", "Ϭ"=>"ϭ", "Ϯ"=>"ϯ", "ϰ"=>"κ", "ϱ"=>"ρ", "ϲ"=>"σ", "ϴ"=>"θ", "ϵ"=>"ε", "Ѐ"=>"ѐ", "Ё"=>"ё", "Ђ"=>"ђ", "Ѓ"=>"ѓ", "Є"=>"є", "Ѕ"=>"ѕ", "І"=>"і", "Ї"=>"ї", "Ј"=>"ј", "Љ"=>"љ", "Њ"=>"њ", "Ћ"=>"ћ", "Ќ"=>"ќ", "Ѝ"=>"ѝ", "Ў"=>"ў", "Џ"=>"џ", "А"=>"а", "Б"=>"б", "В"=>"в", "Г"=>"г", "Д"=>"д", "Е"=>"е", "Ж"=>"ж", "З"=>"з", "И"=>"и", "Й"=>"й", "К"=>"к", "Л"=>"л", "М"=>"м", "Н"=>"н", "О"=>"о", "П"=>"п", "Р"=>"р", "С"=>"с", "Т"=>"т", "У"=>"у", "Ф"=>"ф", "Х"=>"х", "Ц"=>"ц", "Ч"=>"ч", "Ш"=>"ш", "Щ"=>"щ", "Ъ"=>"ъ", "Ы"=>"ы", "Ь"=>"ь", "Э"=>"э", "Ю"=>"ю", "Я"=>"я", "Ѡ"=>"ѡ", "Ѣ"=>"ѣ", "Ѥ"=>"ѥ", "Ѧ"=>"ѧ", "Ѩ"=>"ѩ", "Ѫ"=>"ѫ", "Ѭ"=>"ѭ", "Ѯ"=>"ѯ", "Ѱ"=>"ѱ", "Ѳ"=>"ѳ", "Ѵ"=>"ѵ", "Ѷ"=>"ѷ", "Ѹ"=>"ѹ", "Ѻ"=>"ѻ", "Ѽ"=>"ѽ", "Ѿ"=>"ѿ", "Ҁ"=>"ҁ", "Ҋ"=>"ҋ", "Ҍ"=>"ҍ", "Ҏ"=>"ҏ", "Ґ"=>"ґ", "Ғ"=>"ғ", "Ҕ"=>"ҕ", "Җ"=>"җ", "Ҙ"=>"ҙ", "Қ"=>"қ", "Ҝ"=>"ҝ", "Ҟ"=>"ҟ", "Ҡ"=>"ҡ", "Ң"=>"ң", "Ҥ"=>"ҥ", "Ҧ"=>"ҧ", "Ҩ"=>"ҩ", "Ҫ"=>"ҫ", "Ҭ"=>"ҭ", "Ү"=>"ү", "Ұ"=>"ұ", "Ҳ"=>"ҳ", "Ҵ"=>"ҵ", "Ҷ"=>"ҷ", "Ҹ"=>"ҹ", "Һ"=>"һ", "Ҽ"=>"ҽ", "Ҿ"=>"ҿ", "Ӂ"=>"ӂ", "Ӄ"=>"ӄ", "Ӆ"=>"ӆ", "Ӈ"=>"ӈ", "Ӊ"=>"ӊ", "Ӌ"=>"ӌ", "Ӎ"=>"ӎ", "Ӑ"=>"ӑ", "Ӓ"=>"ӓ", "Ӕ"=>"ӕ", "Ӗ"=>"ӗ", "Ә"=>"ә", "Ӛ"=>"ӛ", "Ӝ"=>"ӝ", "Ӟ"=>"ӟ", "Ӡ"=>"ӡ", "Ӣ"=>"ӣ", "Ӥ"=>"ӥ", "Ӧ"=>"ӧ", "Ө"=>"ө", "Ӫ"=>"ӫ", "Ӭ"=>"ӭ", "Ӯ"=>"ӯ", "Ӱ"=>"ӱ", "Ӳ"=>"ӳ", "Ӵ"=>"ӵ", "Ӹ"=>"ӹ", "Ԁ"=>"ԁ", "Ԃ"=>"ԃ", "Ԅ"=>"ԅ", "Ԇ"=>"ԇ", "Ԉ"=>"ԉ", "Ԋ"=>"ԋ", "Ԍ"=>"ԍ", "Ԏ"=>"ԏ", "Ա"=>"ա", "Բ"=>"բ", "Գ"=>"գ", "Դ"=>"դ", "Ե"=>"ե", "Զ"=>"զ", "Է"=>"է", "Ը"=>"ը", "Թ"=>"թ", "Ժ"=>"ժ", "Ի"=>"ի", "Լ"=>"լ", "Խ"=>"խ", "Ծ"=>"ծ", "Կ"=>"կ", "Հ"=>"հ", "Ձ"=>"ձ", "Ղ"=>"ղ", "Ճ"=>"ճ", "Մ"=>"մ", "Յ"=>"յ", "Ն"=>"ն", "Շ"=>"շ", "Ո"=>"ո", "Չ"=>"չ", "Պ"=>"պ", "Ջ"=>"ջ", "Ռ"=>"ռ", "Ս"=>"ս", "Վ"=>"վ", "Տ"=>"տ", "Ր"=>"ր", "Ց"=>"ց", "Ւ"=>"ւ", "Փ"=>"փ", "Ք"=>"ք", "Օ"=>"օ", "Ֆ"=>"ֆ", "և"=>"եւ", "Ḁ"=>"ḁ", "Ḃ"=>"ḃ", "Ḅ"=>"ḅ", "Ḇ"=>"ḇ", "Ḉ"=>"ḉ", "Ḋ"=>"ḋ", "Ḍ"=>"ḍ", "Ḏ"=>"ḏ", "Ḑ"=>"ḑ", "Ḓ"=>"ḓ", "Ḕ"=>"ḕ", "Ḗ"=>"ḗ", "Ḙ"=>"ḙ", "Ḛ"=>"ḛ", "Ḝ"=>"ḝ", "Ḟ"=>"ḟ", "Ḡ"=>"ḡ", "Ḣ"=>"ḣ", "Ḥ"=>"ḥ", "Ḧ"=>"ḧ", "Ḩ"=>"ḩ", "Ḫ"=>"ḫ", "Ḭ"=>"ḭ", "Ḯ"=>"ḯ", "Ḱ"=>"ḱ", "Ḳ"=>"ḳ", "Ḵ"=>"ḵ", "Ḷ"=>"ḷ", "Ḹ"=>"ḹ", "Ḻ"=>"ḻ", "Ḽ"=>"ḽ", "Ḿ"=>"ḿ", "Ṁ"=>"ṁ", "Ṃ"=>"ṃ", "Ṅ"=>"ṅ", "Ṇ"=>"ṇ", "Ṉ"=>"ṉ", "Ṋ"=>"ṋ", "Ṍ"=>"ṍ", "Ṏ"=>"ṏ", "Ṑ"=>"ṑ", "Ṓ"=>"ṓ", "Ṕ"=>"ṕ", "Ṗ"=>"ṗ", "Ṙ"=>"ṙ", "Ṛ"=>"ṛ", "Ṝ"=>"ṝ", "Ṟ"=>"ṟ", "Ṡ"=>"ṡ", "Ṣ"=>"ṣ", "Ṥ"=>"ṥ", "Ṧ"=>"ṧ", "Ṩ"=>"ṩ", "Ṫ"=>"ṫ", "Ṭ"=>"ṭ", "Ṯ"=>"ṯ", "Ṱ"=>"ṱ", "Ṳ"=>"ṳ", "Ṵ"=>"ṵ", "Ṷ"=>"ṷ", "Ṹ"=>"ṹ", "Ṻ"=>"ṻ", "Ṽ"=>"ṽ", "Ṿ"=>"ṿ", "Ẁ"=>"ẁ", "Ẃ"=>"ẃ", "Ẅ"=>"ẅ", "Ẇ"=>"ẇ", "Ẉ"=>"ẉ", "Ẋ"=>"ẋ", "Ẍ"=>"ẍ", "Ẏ"=>"ẏ", "Ẑ"=>"ẑ", "Ẓ"=>"ẓ", "Ẕ"=>"ẕ", "ẖ"=>"ẖ", "ẗ"=>"ẗ", "ẘ"=>"ẘ", "ẙ"=>"ẙ", "ẚ"=>"aʾ", "ẛ"=>"ṡ", "Ạ"=>"ạ", "Ả"=>"ả", "Ấ"=>"ấ", "Ầ"=>"ầ", "Ẩ"=>"ẩ", "Ẫ"=>"ẫ", "Ậ"=>"ậ", "Ắ"=>"ắ", "Ằ"=>"ằ", "Ẳ"=>"ẳ", "Ẵ"=>"ẵ", "Ặ"=>"ặ", "Ẹ"=>"ẹ", "Ẻ"=>"ẻ", "Ẽ"=>"ẽ", "Ế"=>"ế", "Ề"=>"ề", "Ể"=>"ể", "Ễ"=>"ễ", "Ệ"=>"ệ", "Ỉ"=>"ỉ", "Ị"=>"ị", "Ọ"=>"ọ", "Ỏ"=>"ỏ", "Ố"=>"ố", "Ồ"=>"ồ", "Ổ"=>"ổ", "Ỗ"=>"ỗ", "Ộ"=>"ộ", "Ớ"=>"ớ", "Ờ"=>"ờ", "Ở"=>"ở", "Ỡ"=>"ỡ", "Ợ"=>"ợ", "Ụ"=>"ụ", "Ủ"=>"ủ", "Ứ"=>"ứ", "Ừ"=>"ừ", "Ử"=>"ử", "Ữ"=>"ữ", "Ự"=>"ự", "Ỳ"=>"ỳ", "Ỵ"=>"ỵ", "Ỷ"=>"ỷ", "Ỹ"=>"ỹ", "Ἀ"=>"ἀ", "Ἁ"=>"ἁ", "Ἂ"=>"ἂ", "Ἃ"=>"ἃ", "Ἄ"=>"ἄ", "Ἅ"=>"ἅ", "Ἆ"=>"ἆ", "Ἇ"=>"ἇ", "Ἐ"=>"ἐ", "Ἑ"=>"ἑ", "Ἒ"=>"ἒ", "Ἓ"=>"ἓ", "Ἔ"=>"ἔ", "Ἕ"=>"ἕ", "Ἠ"=>"ἠ", "Ἡ"=>"ἡ", "Ἢ"=>"ἢ", "Ἣ"=>"ἣ", "Ἤ"=>"ἤ", "Ἥ"=>"ἥ", "Ἦ"=>"ἦ", "Ἧ"=>"ἧ", "Ἰ"=>"ἰ", "Ἱ"=>"ἱ", "Ἲ"=>"ἲ", "Ἳ"=>"ἳ", "Ἴ"=>"ἴ", "Ἵ"=>"ἵ", "Ἶ"=>"ἶ", "Ἷ"=>"ἷ", "Ὀ"=>"ὀ", "Ὁ"=>"ὁ", "Ὂ"=>"ὂ", "Ὃ"=>"ὃ", "Ὄ"=>"ὄ", "Ὅ"=>"ὅ", "ὐ"=>"ὐ", "ὒ"=>"ὒ", "ὔ"=>"ὔ", "ὖ"=>"ὖ", "Ὑ"=>"ὑ", "Ὓ"=>"ὓ", "Ὕ"=>"ὕ", "Ὗ"=>"ὗ", "Ὠ"=>"ὠ", "Ὡ"=>"ὡ", "Ὢ"=>"ὢ", "Ὣ"=>"ὣ", "Ὤ"=>"ὤ", "Ὥ"=>"ὥ", "Ὦ"=>"ὦ", "Ὧ"=>"ὧ", "ᾀ"=>"ἀι", "ᾁ"=>"ἁι", "ᾂ"=>"ἂι", "ᾃ"=>"ἃι", "ᾄ"=>"ἄι", "ᾅ"=>"ἅι", "ᾆ"=>"ἆι", "ᾇ"=>"ἇι", "ᾈ"=>"ἀι", "ᾉ"=>"ἁι", "ᾊ"=>"ἂι", "ᾋ"=>"ἃι", "ᾌ"=>"ἄι", "ᾍ"=>"ἅι", "ᾎ"=>"ἆι", "ᾏ"=>"ἇι", "ᾐ"=>"ἠι", "ᾑ"=>"ἡι", "ᾒ"=>"ἢι", "ᾓ"=>"ἣι", "ᾔ"=>"ἤι", "ᾕ"=>"ἥι", "ᾖ"=>"ἦι", "ᾗ"=>"ἧι", "ᾘ"=>"ἠι", "ᾙ"=>"ἡι", "ᾚ"=>"ἢι", "ᾛ"=>"ἣι", "ᾜ"=>"ἤι", "ᾝ"=>"ἥι", "ᾞ"=>"ἦι", "ᾟ"=>"ἧι", "ᾠ"=>"ὠι", "ᾡ"=>"ὡι", "ᾢ"=>"ὢι", "ᾣ"=>"ὣι", "ᾤ"=>"ὤι", "ᾥ"=>"ὥι", "ᾦ"=>"ὦι", "ᾧ"=>"ὧι", "ᾨ"=>"ὠι", "ᾩ"=>"ὡι", "ᾪ"=>"ὢι", "ᾫ"=>"ὣι", "ᾬ"=>"ὤι", "ᾭ"=>"ὥι", "ᾮ"=>"ὦι", "ᾯ"=>"ὧι", "ᾲ"=>"ὰι", "ᾳ"=>"αι", "ᾴ"=>"άι", "ᾶ"=>"ᾶ", "ᾷ"=>"ᾶι", "Ᾰ"=>"ᾰ", "Ᾱ"=>"ᾱ", "Ὰ"=>"ὰ", "Ά"=>"ά", "ᾼ"=>"αι", "ι"=>"ι", "ῂ"=>"ὴι", "ῃ"=>"ηι", "ῄ"=>"ήι", "ῆ"=>"ῆ", "ῇ"=>"ῆι", "Ὲ"=>"ὲ", "Έ"=>"έ", "Ὴ"=>"ὴ", "Ή"=>"ή", "ῌ"=>"ηι", "ῒ"=>"ῒ", "ΐ"=>"ΐ", "ῖ"=>"ῖ", "ῗ"=>"ῗ", "Ῐ"=>"ῐ", "Ῑ"=>"ῑ", "Ὶ"=>"ὶ", "Ί"=>"ί", "ῢ"=>"ῢ", "ΰ"=>"ΰ", "ῤ"=>"ῤ", "ῦ"=>"ῦ", "ῧ"=>"ῧ", "Ῠ"=>"ῠ", "Ῡ"=>"ῡ", "Ὺ"=>"ὺ", "Ύ"=>"ύ", "Ῥ"=>"ῥ", "ῲ"=>"ὼι", "ῳ"=>"ωι", "ῴ"=>"ώι", "ῶ"=>"ῶ", "ῷ"=>"ῶι", "Ὸ"=>"ὸ", "Ό"=>"ό", "Ὼ"=>"ὼ", "Ώ"=>"ώ", "ῼ"=>"ωι", "₨"=>"rs", "ℂ"=>"c", "℃"=>"°c", "ℇ"=>"ɛ", "℉"=>"°f", "ℋ"=>"h", "ℌ"=>"h", "ℍ"=>"h", "ℐ"=>"i", "ℑ"=>"i", "ℒ"=>"l", "ℕ"=>"n", "№"=>"no", "ℙ"=>"p", "ℚ"=>"q", "ℛ"=>"r", "ℜ"=>"r", "ℝ"=>"r", "℠"=>"sm", "℡"=>"tel", "™"=>"tm", "ℤ"=>"z", "Ω"=>"ω", "ℨ"=>"z", "K"=>"k", "Å"=>"å", "ℬ"=>"b", "ℭ"=>"c", "ℰ"=>"e", "ℱ"=>"f", "ℳ"=>"m", "ℾ"=>"γ", "ℿ"=>"π", "ⅅ"=>"d", "Ⅰ"=>"ⅰ", "Ⅱ"=>"ⅱ", "Ⅲ"=>"ⅲ", "Ⅳ"=>"ⅳ", "Ⅴ"=>"ⅴ", "Ⅵ"=>"ⅵ", "Ⅶ"=>"ⅶ", "Ⅷ"=>"ⅷ", "Ⅸ"=>"ⅸ", "Ⅹ"=>"ⅹ", "Ⅺ"=>"ⅺ", "Ⅻ"=>"ⅻ", "Ⅼ"=>"ⅼ", "Ⅽ"=>"ⅽ", "Ⅾ"=>"ⅾ", "Ⅿ"=>"ⅿ", "Ⓐ"=>"ⓐ", "Ⓑ"=>"ⓑ", "Ⓒ"=>"ⓒ", "Ⓓ"=>"ⓓ", "Ⓔ"=>"ⓔ", "Ⓕ"=>"ⓕ", "Ⓖ"=>"ⓖ", "Ⓗ"=>"ⓗ", "Ⓘ"=>"ⓘ", "Ⓙ"=>"ⓙ", "Ⓚ"=>"ⓚ", "Ⓛ"=>"ⓛ", "Ⓜ"=>"ⓜ", "Ⓝ"=>"ⓝ", "Ⓞ"=>"ⓞ", "Ⓟ"=>"ⓟ", "Ⓠ"=>"ⓠ", "Ⓡ"=>"ⓡ", "Ⓢ"=>"ⓢ", "Ⓣ"=>"ⓣ", "Ⓤ"=>"ⓤ", "Ⓥ"=>"ⓥ", "Ⓦ"=>"ⓦ", "Ⓧ"=>"ⓧ", "Ⓨ"=>"ⓨ", "Ⓩ"=>"ⓩ", "㍱"=>"hpa", "㍳"=>"au", "㍵"=>"ov", "㎀"=>"pa", "㎁"=>"na", "㎂"=>"μa", "㎃"=>"ma", "㎄"=>"ka", "㎅"=>"kb", "㎆"=>"mb", "㎇"=>"gb", "㎊"=>"pf", "㎋"=>"nf", "㎌"=>"μf", "㎐"=>"hz", "㎑"=>"khz", "㎒"=>"mhz", "㎓"=>"ghz", "㎔"=>"thz", "㎩"=>"pa", "㎪"=>"kpa", "㎫"=>"mpa", "㎬"=>"gpa", "㎴"=>"pv", "㎵"=>"nv", "㎶"=>"μv", "㎷"=>"mv", "㎸"=>"kv", "㎹"=>"mv", "㎺"=>"pw", "㎻"=>"nw", "㎼"=>"μw", "㎽"=>"mw", "㎾"=>"kw", "㎿"=>"mw", "㏀"=>"kω", "㏁"=>"mω", "㏃"=>"bq", "㏆"=>"c∕kg", "㏇"=>"co.", "㏈"=>"db", "㏉"=>"gy", "㏋"=>"hp", "㏍"=>"kk", "㏎"=>"km", "㏗"=>"ph", "㏙"=>"ppm", "㏚"=>"pr", "㏜"=>"sv", "㏝"=>"wb", "ff"=>"ff", "fi"=>"fi", "fl"=>"fl", "ffi"=>"ffi", "ffl"=>"ffl", "ſt"=>"st", "st"=>"st", "ﬓ"=>"մն", "ﬔ"=>"մե", "ﬕ"=>"մի", "ﬖ"=>"վն", "ﬗ"=>"մխ", "A"=>"a", "B"=>"b", "C"=>"c", "D"=>"d", "E"=>"e", "F"=>"f", "G"=>"g", "H"=>"h", "I"=>"i", "J"=>"j", "K"=>"k", "L"=>"l", "M"=>"m", "N"=>"n", "O"=>"o", "P"=>"p", "Q"=>"q", "R"=>"r", "S"=>"s", "T"=>"t", "U"=>"u", "V"=>"v", "W"=>"w", "X"=>"x", "Y"=>"y", "Z"=>"z", "𐐀"=>"𐐨", "𐐁"=>"𐐩", "𐐂"=>"𐐪", "𐐃"=>"𐐫", "𐐄"=>"𐐬", "𐐅"=>"𐐭", "𐐆"=>"𐐮", "𐐇"=>"𐐯", "𐐈"=>"𐐰", "𐐉"=>"𐐱", "𐐊"=>"𐐲", "𐐋"=>"𐐳", "𐐌"=>"𐐴", "𐐍"=>"𐐵", "𐐎"=>"𐐶", "𐐏"=>"𐐷", "𐐐"=>"𐐸", "𐐑"=>"𐐹", "𐐒"=>"𐐺", "𐐓"=>"𐐻", "𐐔"=>"𐐼", "𐐕"=>"𐐽", "𐐖"=>"𐐾", "𐐗"=>"𐐿", "𐐘"=>"𐑀", "𐐙"=>"𐑁", "𐐚"=>"𐑂", "𐐛"=>"𐑃", "𐐜"=>"𐑄", "𐐝"=>"𐑅", "𐐞"=>"𐑆", "𐐟"=>"𐑇", "𐐠"=>"𐑈", "𐐡"=>"𐑉", "𐐢"=>"𐑊", "𐐣"=>"𐑋", "𐐤"=>"𐑌", "𐐥"=>"𐑍", "𝐀"=>"a", "𝐁"=>"b", "𝐂"=>"c", "𝐃"=>"d", "𝐄"=>"e", "𝐅"=>"f", "𝐆"=>"g", "𝐇"=>"h", "𝐈"=>"i", "𝐉"=>"j", "𝐊"=>"k", "𝐋"=>"l", "𝐌"=>"m", "𝐍"=>"n", "𝐎"=>"o", "𝐏"=>"p", "𝐐"=>"q", "𝐑"=>"r", "𝐒"=>"s", "𝐓"=>"t", "𝐔"=>"u", "𝐕"=>"v", "𝐖"=>"w", "𝐗"=>"x", "𝐘"=>"y", "𝐙"=>"z", "𝐴"=>"a", "𝐵"=>"b", "𝐶"=>"c", "𝐷"=>"d", "𝐸"=>"e", "𝐹"=>"f", "𝐺"=>"g", "𝐻"=>"h", "𝐼"=>"i", "𝐽"=>"j", "𝐾"=>"k", "𝐿"=>"l", "𝑀"=>"m", "𝑁"=>"n", "𝑂"=>"o", "𝑃"=>"p", "𝑄"=>"q", "𝑅"=>"r", "𝑆"=>"s", "𝑇"=>"t", "𝑈"=>"u", "𝑉"=>"v", "𝑊"=>"w", "𝑋"=>"x", "𝑌"=>"y", "𝑍"=>"z", "𝑨"=>"a", "𝑩"=>"b", "𝑪"=>"c", "𝑫"=>"d", "𝑬"=>"e", "𝑭"=>"f", "𝑮"=>"g", "𝑯"=>"h", "𝑰"=>"i", "𝑱"=>"j", "𝑲"=>"k", "𝑳"=>"l", "𝑴"=>"m", "𝑵"=>"n", "𝑶"=>"o", "𝑷"=>"p", "𝑸"=>"q", "𝑹"=>"r", "𝑺"=>"s", "𝑻"=>"t", "𝑼"=>"u", "𝑽"=>"v", "𝑾"=>"w", "𝑿"=>"x", "𝒀"=>"y", "𝒁"=>"z", "𝒜"=>"a", "𝒞"=>"c", "𝒟"=>"d", "𝒢"=>"g", "𝒥"=>"j", "𝒦"=>"k", "𝒩"=>"n", "𝒪"=>"o", "𝒫"=>"p", "𝒬"=>"q", "𝒮"=>"s", "𝒯"=>"t", "𝒰"=>"u", "𝒱"=>"v", "𝒲"=>"w", "𝒳"=>"x", "𝒴"=>"y", "𝒵"=>"z", "𝓐"=>"a", "𝓑"=>"b", "𝓒"=>"c", "𝓓"=>"d", "𝓔"=>"e", "𝓕"=>"f", "𝓖"=>"g", "𝓗"=>"h", "𝓘"=>"i", "𝓙"=>"j", "𝓚"=>"k", "𝓛"=>"l", "𝓜"=>"m", "𝓝"=>"n", "𝓞"=>"o", "𝓟"=>"p", "𝓠"=>"q", "𝓡"=>"r", "𝓢"=>"s", "𝓣"=>"t", "𝓤"=>"u", "𝓥"=>"v", "𝓦"=>"w", "𝓧"=>"x", "𝓨"=>"y", "𝓩"=>"z", "𝔄"=>"a", "𝔅"=>"b", "𝔇"=>"d", "𝔈"=>"e", "𝔉"=>"f", "𝔊"=>"g", "𝔍"=>"j", "𝔎"=>"k", "𝔏"=>"l", "𝔐"=>"m", "𝔑"=>"n", "𝔒"=>"o", "𝔓"=>"p", "𝔔"=>"q", "𝔖"=>"s", "𝔗"=>"t", "𝔘"=>"u", "𝔙"=>"v", "𝔚"=>"w", "𝔛"=>"x", "𝔜"=>"y", "𝔸"=>"a", "𝔹"=>"b", "𝔻"=>"d", "𝔼"=>"e", "𝔽"=>"f", "𝔾"=>"g", "𝕀"=>"i", "𝕁"=>"j", "𝕂"=>"k", "𝕃"=>"l", "𝕄"=>"m", "𝕆"=>"o", "𝕊"=>"s", "𝕋"=>"t", "𝕌"=>"u", "𝕍"=>"v", "𝕎"=>"w", "𝕏"=>"x", "𝕐"=>"y", "𝕬"=>"a", "𝕭"=>"b", "𝕮"=>"c", "𝕯"=>"d", "𝕰"=>"e", "𝕱"=>"f", "𝕲"=>"g", "𝕳"=>"h", "𝕴"=>"i", "𝕵"=>"j", "𝕶"=>"k", "𝕷"=>"l", "𝕸"=>"m", "𝕹"=>"n", "𝕺"=>"o", "𝕻"=>"p", "𝕼"=>"q", "𝕽"=>"r", "𝕾"=>"s", "𝕿"=>"t", "𝖀"=>"u", "𝖁"=>"v", "𝖂"=>"w", "𝖃"=>"x", "𝖄"=>"y", "𝖅"=>"z", "𝖠"=>"a", "𝖡"=>"b", "𝖢"=>"c", "𝖣"=>"d", "𝖤"=>"e", "𝖥"=>"f", "𝖦"=>"g", "𝖧"=>"h", "𝖨"=>"i", "𝖩"=>"j", "𝖪"=>"k", "𝖫"=>"l", "𝖬"=>"m", "𝖭"=>"n", "𝖮"=>"o", "𝖯"=>"p", "𝖰"=>"q", "𝖱"=>"r", "𝖲"=>"s", "𝖳"=>"t", "𝖴"=>"u", "𝖵"=>"v", "𝖶"=>"w", "𝖷"=>"x", "𝖸"=>"y", "𝖹"=>"z", "𝗔"=>"a", "𝗕"=>"b", "𝗖"=>"c", "𝗗"=>"d", "𝗘"=>"e", "𝗙"=>"f", "𝗚"=>"g", "𝗛"=>"h", "𝗜"=>"i", "𝗝"=>"j", "𝗞"=>"k", "𝗟"=>"l", "𝗠"=>"m", "𝗡"=>"n", "𝗢"=>"o", "𝗣"=>"p", "𝗤"=>"q", "𝗥"=>"r", "𝗦"=>"s", "𝗧"=>"t", "𝗨"=>"u", "𝗩"=>"v", "𝗪"=>"w", "𝗫"=>"x", "𝗬"=>"y", "𝗭"=>"z", "𝘈"=>"a", "𝘉"=>"b", "𝘊"=>"c", "𝘋"=>"d", "𝘌"=>"e", "𝘍"=>"f", "𝘎"=>"g", "𝘏"=>"h", "𝘐"=>"i", "𝘑"=>"j", "𝘒"=>"k", "𝘓"=>"l", "𝘔"=>"m", "𝘕"=>"n", "𝘖"=>"o", "𝘗"=>"p", "𝘘"=>"q", "𝘙"=>"r", "𝘚"=>"s", "𝘛"=>"t", "𝘜"=>"u", "𝘝"=>"v", "𝘞"=>"w", "𝘟"=>"x", "𝘠"=>"y", "𝘡"=>"z", "𝘼"=>"a", "𝘽"=>"b", "𝘾"=>"c", "𝘿"=>"d", "𝙀"=>"e", "𝙁"=>"f", "𝙂"=>"g", "𝙃"=>"h", "𝙄"=>"i", "𝙅"=>"j", "𝙆"=>"k", "𝙇"=>"l", "𝙈"=>"m", "𝙉"=>"n", "𝙊"=>"o", "𝙋"=>"p", "𝙌"=>"q", "𝙍"=>"r", "𝙎"=>"s", "𝙏"=>"t", "𝙐"=>"u", "𝙑"=>"v", "𝙒"=>"w", "𝙓"=>"x", "𝙔"=>"y", "𝙕"=>"z", "𝙰"=>"a", "𝙱"=>"b", "𝙲"=>"c", "𝙳"=>"d", "𝙴"=>"e", "𝙵"=>"f", "𝙶"=>"g", "𝙷"=>"h", "𝙸"=>"i", "𝙹"=>"j", "𝙺"=>"k", "𝙻"=>"l", "𝙼"=>"m", "𝙽"=>"n", "𝙾"=>"o", "𝙿"=>"p", "𝚀"=>"q", "𝚁"=>"r", "𝚂"=>"s", "𝚃"=>"t", "𝚄"=>"u", "𝚅"=>"v", "𝚆"=>"w", "𝚇"=>"x", "𝚈"=>"y", "𝚉"=>"z", "𝚨"=>"α", "𝚩"=>"β", "𝚪"=>"γ", "𝚫"=>"δ", "𝚬"=>"ε", "𝚭"=>"ζ", "𝚮"=>"η", "𝚯"=>"θ", "𝚰"=>"ι", "𝚱"=>"κ", "𝚲"=>"λ", "𝚳"=>"μ", "𝚴"=>"ν", "𝚵"=>"ξ", "𝚶"=>"ο", "𝚷"=>"π", "𝚸"=>"ρ", "𝚹"=>"θ", "𝚺"=>"σ", "𝚻"=>"τ", "𝚼"=>"υ", "𝚽"=>"φ", "𝚾"=>"χ", "𝚿"=>"ψ", "𝛀"=>"ω", "𝛓"=>"σ", "𝛢"=>"α", "𝛣"=>"β", "𝛤"=>"γ", "𝛥"=>"δ", "𝛦"=>"ε", "𝛧"=>"ζ", "𝛨"=>"η", "𝛩"=>"θ", "𝛪"=>"ι", "𝛫"=>"κ", "𝛬"=>"λ", "𝛭"=>"μ", "𝛮"=>"ν", "𝛯"=>"ξ", "𝛰"=>"ο", "𝛱"=>"π", "𝛲"=>"ρ", "𝛳"=>"θ", "𝛴"=>"σ", "𝛵"=>"τ", "𝛶"=>"υ", "𝛷"=>"φ", "𝛸"=>"χ", "𝛹"=>"ψ", "𝛺"=>"ω", "𝜍"=>"σ", "𝜜"=>"α", "𝜝"=>"β", "𝜞"=>"γ", "𝜟"=>"δ", "𝜠"=>"ε", "𝜡"=>"ζ", "𝜢"=>"η", "𝜣"=>"θ", "𝜤"=>"ι", "𝜥"=>"κ", "𝜦"=>"λ", "𝜧"=>"μ", "𝜨"=>"ν", "𝜩"=>"ξ", "𝜪"=>"ο", "𝜫"=>"π", "𝜬"=>"ρ", "𝜭"=>"θ", "𝜮"=>"σ", "𝜯"=>"τ", "𝜰"=>"υ", "𝜱"=>"φ", "𝜲"=>"χ", "𝜳"=>"ψ", "𝜴"=>"ω", "𝝇"=>"σ", "𝝖"=>"α", "𝝗"=>"β", "𝝘"=>"γ", "𝝙"=>"δ", "𝝚"=>"ε", "𝝛"=>"ζ", "𝝜"=>"η", "𝝝"=>"θ", "𝝞"=>"ι", "𝝟"=>"κ", "𝝠"=>"λ", "𝝡"=>"μ", "𝝢"=>"ν", "𝝣"=>"ξ", "𝝤"=>"ο", "𝝥"=>"π", "𝝦"=>"ρ", "𝝧"=>"θ", "𝝨"=>"σ", "𝝩"=>"τ", "𝝪"=>"υ", "𝝫"=>"φ", "𝝬"=>"χ", "𝝭"=>"ψ", "𝝮"=>"ω", "𝞁"=>"σ", "𝞐"=>"α", "𝞑"=>"β", "𝞒"=>"γ", "𝞓"=>"δ", "𝞔"=>"ε", "𝞕"=>"ζ", "𝞖"=>"η", "𝞗"=>"θ", "𝞘"=>"ι", "𝞙"=>"κ", "𝞚"=>"λ", "𝞛"=>"μ", "𝞜"=>"ν", "𝞝"=>"ξ", "𝞞"=>"ο", "𝞟"=>"π", "𝞠"=>"ρ", "𝞡"=>"θ", "𝞢"=>"σ", "𝞣"=>"τ", "𝞤"=>"υ", "𝞥"=>"φ", "𝞦"=>"χ", "𝞧"=>"ψ", "𝞨"=>"ω", "𝞻"=>"σ"}.freeze + + end +end diff --git a/lib/net/imap/stringprep/tables/map_b_3.rb b/lib/net/imap/stringprep/tables/map_b_3.rb new file mode 100644 index 00000000..060172db --- /dev/null +++ b/lib/net/imap/stringprep/tables/map_b_3.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +#-- +# This file is generated by `rake stringprep:tables`. Don't edit directly. +#++ + +module Net::IMAP::StringPrep + module Tables + + # Replacements for IN_B.3 + MAP_B_3 = {"A"=>"a", "B"=>"b", "C"=>"c", "D"=>"d", "E"=>"e", "F"=>"f", "G"=>"g", "H"=>"h", "I"=>"i", "J"=>"j", "K"=>"k", "L"=>"l", "M"=>"m", "N"=>"n", "O"=>"o", "P"=>"p", "Q"=>"q", "R"=>"r", "S"=>"s", "T"=>"t", "U"=>"u", "V"=>"v", "W"=>"w", "X"=>"x", "Y"=>"y", "Z"=>"z", "µ"=>"μ", "À"=>"à", "Á"=>"á", "Â"=>"â", "Ã"=>"ã", "Ä"=>"ä", "Å"=>"å", "Æ"=>"æ", "Ç"=>"ç", "È"=>"è", "É"=>"é", "Ê"=>"ê", "Ë"=>"ë", "Ì"=>"ì", "Í"=>"í", "Î"=>"î", "Ï"=>"ï", "Ð"=>"ð", "Ñ"=>"ñ", "Ò"=>"ò", "Ó"=>"ó", "Ô"=>"ô", "Õ"=>"õ", "Ö"=>"ö", "Ø"=>"ø", "Ù"=>"ù", "Ú"=>"ú", "Û"=>"û", "Ü"=>"ü", "Ý"=>"ý", "Þ"=>"þ", "ß"=>"ss", "Ā"=>"ā", "Ă"=>"ă", "Ą"=>"ą", "Ć"=>"ć", "Ĉ"=>"ĉ", "Ċ"=>"ċ", "Č"=>"č", "Ď"=>"ď", "Đ"=>"đ", "Ē"=>"ē", "Ĕ"=>"ĕ", "Ė"=>"ė", "Ę"=>"ę", "Ě"=>"ě", "Ĝ"=>"ĝ", "Ğ"=>"ğ", "Ġ"=>"ġ", "Ģ"=>"ģ", "Ĥ"=>"ĥ", "Ħ"=>"ħ", "Ĩ"=>"ĩ", "Ī"=>"ī", "Ĭ"=>"ĭ", "Į"=>"į", "İ"=>"i̇", "IJ"=>"ij", "Ĵ"=>"ĵ", "Ķ"=>"ķ", "Ĺ"=>"ĺ", "Ļ"=>"ļ", "Ľ"=>"ľ", "Ŀ"=>"ŀ", "Ł"=>"ł", "Ń"=>"ń", "Ņ"=>"ņ", "Ň"=>"ň", "ʼn"=>"ʼn", "Ŋ"=>"ŋ", "Ō"=>"ō", "Ŏ"=>"ŏ", "Ő"=>"ő", "Œ"=>"œ", "Ŕ"=>"ŕ", "Ŗ"=>"ŗ", "Ř"=>"ř", "Ś"=>"ś", "Ŝ"=>"ŝ", "Ş"=>"ş", "Š"=>"š", "Ţ"=>"ţ", "Ť"=>"ť", "Ŧ"=>"ŧ", "Ũ"=>"ũ", "Ū"=>"ū", "Ŭ"=>"ŭ", "Ů"=>"ů", "Ű"=>"ű", "Ų"=>"ų", "Ŵ"=>"ŵ", "Ŷ"=>"ŷ", "Ÿ"=>"ÿ", "Ź"=>"ź", "Ż"=>"ż", "Ž"=>"ž", "ſ"=>"s", "Ɓ"=>"ɓ", "Ƃ"=>"ƃ", "Ƅ"=>"ƅ", "Ɔ"=>"ɔ", "Ƈ"=>"ƈ", "Ɖ"=>"ɖ", "Ɗ"=>"ɗ", "Ƌ"=>"ƌ", "Ǝ"=>"ǝ", "Ə"=>"ə", "Ɛ"=>"ɛ", "Ƒ"=>"ƒ", "Ɠ"=>"ɠ", "Ɣ"=>"ɣ", "Ɩ"=>"ɩ", "Ɨ"=>"ɨ", "Ƙ"=>"ƙ", "Ɯ"=>"ɯ", "Ɲ"=>"ɲ", "Ɵ"=>"ɵ", "Ơ"=>"ơ", "Ƣ"=>"ƣ", "Ƥ"=>"ƥ", "Ʀ"=>"ʀ", "Ƨ"=>"ƨ", "Ʃ"=>"ʃ", "Ƭ"=>"ƭ", "Ʈ"=>"ʈ", "Ư"=>"ư", "Ʊ"=>"ʊ", "Ʋ"=>"ʋ", "Ƴ"=>"ƴ", "Ƶ"=>"ƶ", "Ʒ"=>"ʒ", "Ƹ"=>"ƹ", "Ƽ"=>"ƽ", "DŽ"=>"dž", "Dž"=>"dž", "LJ"=>"lj", "Lj"=>"lj", "NJ"=>"nj", "Nj"=>"nj", "Ǎ"=>"ǎ", "Ǐ"=>"ǐ", "Ǒ"=>"ǒ", "Ǔ"=>"ǔ", "Ǖ"=>"ǖ", "Ǘ"=>"ǘ", "Ǚ"=>"ǚ", "Ǜ"=>"ǜ", "Ǟ"=>"ǟ", "Ǡ"=>"ǡ", "Ǣ"=>"ǣ", "Ǥ"=>"ǥ", "Ǧ"=>"ǧ", "Ǩ"=>"ǩ", "Ǫ"=>"ǫ", "Ǭ"=>"ǭ", "Ǯ"=>"ǯ", "ǰ"=>"ǰ", "DZ"=>"dz", "Dz"=>"dz", "Ǵ"=>"ǵ", "Ƕ"=>"ƕ", "Ƿ"=>"ƿ", "Ǹ"=>"ǹ", "Ǻ"=>"ǻ", "Ǽ"=>"ǽ", "Ǿ"=>"ǿ", "Ȁ"=>"ȁ", "Ȃ"=>"ȃ", "Ȅ"=>"ȅ", "Ȇ"=>"ȇ", "Ȉ"=>"ȉ", "Ȋ"=>"ȋ", "Ȍ"=>"ȍ", "Ȏ"=>"ȏ", "Ȑ"=>"ȑ", "Ȓ"=>"ȓ", "Ȕ"=>"ȕ", "Ȗ"=>"ȗ", "Ș"=>"ș", "Ț"=>"ț", "Ȝ"=>"ȝ", "Ȟ"=>"ȟ", "Ƞ"=>"ƞ", "Ȣ"=>"ȣ", "Ȥ"=>"ȥ", "Ȧ"=>"ȧ", "Ȩ"=>"ȩ", "Ȫ"=>"ȫ", "Ȭ"=>"ȭ", "Ȯ"=>"ȯ", "Ȱ"=>"ȱ", "Ȳ"=>"ȳ", "ͅ"=>"ι", "Ά"=>"ά", "Έ"=>"έ", "Ή"=>"ή", "Ί"=>"ί", "Ό"=>"ό", "Ύ"=>"ύ", "Ώ"=>"ώ", "ΐ"=>"ΐ", "Α"=>"α", "Β"=>"β", "Γ"=>"γ", "Δ"=>"δ", "Ε"=>"ε", "Ζ"=>"ζ", "Η"=>"η", "Θ"=>"θ", "Ι"=>"ι", "Κ"=>"κ", "Λ"=>"λ", "Μ"=>"μ", "Ν"=>"ν", "Ξ"=>"ξ", "Ο"=>"ο", "Π"=>"π", "Ρ"=>"ρ", "Σ"=>"σ", "Τ"=>"τ", "Υ"=>"υ", "Φ"=>"φ", "Χ"=>"χ", "Ψ"=>"ψ", "Ω"=>"ω", "Ϊ"=>"ϊ", "Ϋ"=>"ϋ", "ΰ"=>"ΰ", "ς"=>"σ", "ϐ"=>"β", "ϑ"=>"θ", "ϕ"=>"φ", "ϖ"=>"π", "Ϙ"=>"ϙ", "Ϛ"=>"ϛ", "Ϝ"=>"ϝ", "Ϟ"=>"ϟ", "Ϡ"=>"ϡ", "Ϣ"=>"ϣ", "Ϥ"=>"ϥ", "Ϧ"=>"ϧ", "Ϩ"=>"ϩ", "Ϫ"=>"ϫ", "Ϭ"=>"ϭ", "Ϯ"=>"ϯ", "ϰ"=>"κ", "ϱ"=>"ρ", "ϲ"=>"σ", "ϴ"=>"θ", "ϵ"=>"ε", "Ѐ"=>"ѐ", "Ё"=>"ё", "Ђ"=>"ђ", "Ѓ"=>"ѓ", "Є"=>"є", "Ѕ"=>"ѕ", "І"=>"і", "Ї"=>"ї", "Ј"=>"ј", "Љ"=>"љ", "Њ"=>"њ", "Ћ"=>"ћ", "Ќ"=>"ќ", "Ѝ"=>"ѝ", "Ў"=>"ў", "Џ"=>"џ", "А"=>"а", "Б"=>"б", "В"=>"в", "Г"=>"г", "Д"=>"д", "Е"=>"е", "Ж"=>"ж", "З"=>"з", "И"=>"и", "Й"=>"й", "К"=>"к", "Л"=>"л", "М"=>"м", "Н"=>"н", "О"=>"о", "П"=>"п", "Р"=>"р", "С"=>"с", "Т"=>"т", "У"=>"у", "Ф"=>"ф", "Х"=>"х", "Ц"=>"ц", "Ч"=>"ч", "Ш"=>"ш", "Щ"=>"щ", "Ъ"=>"ъ", "Ы"=>"ы", "Ь"=>"ь", "Э"=>"э", "Ю"=>"ю", "Я"=>"я", "Ѡ"=>"ѡ", "Ѣ"=>"ѣ", "Ѥ"=>"ѥ", "Ѧ"=>"ѧ", "Ѩ"=>"ѩ", "Ѫ"=>"ѫ", "Ѭ"=>"ѭ", "Ѯ"=>"ѯ", "Ѱ"=>"ѱ", "Ѳ"=>"ѳ", "Ѵ"=>"ѵ", "Ѷ"=>"ѷ", "Ѹ"=>"ѹ", "Ѻ"=>"ѻ", "Ѽ"=>"ѽ", "Ѿ"=>"ѿ", "Ҁ"=>"ҁ", "Ҋ"=>"ҋ", "Ҍ"=>"ҍ", "Ҏ"=>"ҏ", "Ґ"=>"ґ", "Ғ"=>"ғ", "Ҕ"=>"ҕ", "Җ"=>"җ", "Ҙ"=>"ҙ", "Қ"=>"қ", "Ҝ"=>"ҝ", "Ҟ"=>"ҟ", "Ҡ"=>"ҡ", "Ң"=>"ң", "Ҥ"=>"ҥ", "Ҧ"=>"ҧ", "Ҩ"=>"ҩ", "Ҫ"=>"ҫ", "Ҭ"=>"ҭ", "Ү"=>"ү", "Ұ"=>"ұ", "Ҳ"=>"ҳ", "Ҵ"=>"ҵ", "Ҷ"=>"ҷ", "Ҹ"=>"ҹ", "Һ"=>"һ", "Ҽ"=>"ҽ", "Ҿ"=>"ҿ", "Ӂ"=>"ӂ", "Ӄ"=>"ӄ", "Ӆ"=>"ӆ", "Ӈ"=>"ӈ", "Ӊ"=>"ӊ", "Ӌ"=>"ӌ", "Ӎ"=>"ӎ", "Ӑ"=>"ӑ", "Ӓ"=>"ӓ", "Ӕ"=>"ӕ", "Ӗ"=>"ӗ", "Ә"=>"ә", "Ӛ"=>"ӛ", "Ӝ"=>"ӝ", "Ӟ"=>"ӟ", "Ӡ"=>"ӡ", "Ӣ"=>"ӣ", "Ӥ"=>"ӥ", "Ӧ"=>"ӧ", "Ө"=>"ө", "Ӫ"=>"ӫ", "Ӭ"=>"ӭ", "Ӯ"=>"ӯ", "Ӱ"=>"ӱ", "Ӳ"=>"ӳ", "Ӵ"=>"ӵ", "Ӹ"=>"ӹ", "Ԁ"=>"ԁ", "Ԃ"=>"ԃ", "Ԅ"=>"ԅ", "Ԇ"=>"ԇ", "Ԉ"=>"ԉ", "Ԋ"=>"ԋ", "Ԍ"=>"ԍ", "Ԏ"=>"ԏ", "Ա"=>"ա", "Բ"=>"բ", "Գ"=>"գ", "Դ"=>"դ", "Ե"=>"ե", "Զ"=>"զ", "Է"=>"է", "Ը"=>"ը", "Թ"=>"թ", "Ժ"=>"ժ", "Ի"=>"ի", "Լ"=>"լ", "Խ"=>"խ", "Ծ"=>"ծ", "Կ"=>"կ", "Հ"=>"հ", "Ձ"=>"ձ", "Ղ"=>"ղ", "Ճ"=>"ճ", "Մ"=>"մ", "Յ"=>"յ", "Ն"=>"ն", "Շ"=>"շ", "Ո"=>"ո", "Չ"=>"չ", "Պ"=>"պ", "Ջ"=>"ջ", "Ռ"=>"ռ", "Ս"=>"ս", "Վ"=>"վ", "Տ"=>"տ", "Ր"=>"ր", "Ց"=>"ց", "Ւ"=>"ւ", "Փ"=>"փ", "Ք"=>"ք", "Օ"=>"օ", "Ֆ"=>"ֆ", "և"=>"եւ", "Ḁ"=>"ḁ", "Ḃ"=>"ḃ", "Ḅ"=>"ḅ", "Ḇ"=>"ḇ", "Ḉ"=>"ḉ", "Ḋ"=>"ḋ", "Ḍ"=>"ḍ", "Ḏ"=>"ḏ", "Ḑ"=>"ḑ", "Ḓ"=>"ḓ", "Ḕ"=>"ḕ", "Ḗ"=>"ḗ", "Ḙ"=>"ḙ", "Ḛ"=>"ḛ", "Ḝ"=>"ḝ", "Ḟ"=>"ḟ", "Ḡ"=>"ḡ", "Ḣ"=>"ḣ", "Ḥ"=>"ḥ", "Ḧ"=>"ḧ", "Ḩ"=>"ḩ", "Ḫ"=>"ḫ", "Ḭ"=>"ḭ", "Ḯ"=>"ḯ", "Ḱ"=>"ḱ", "Ḳ"=>"ḳ", "Ḵ"=>"ḵ", "Ḷ"=>"ḷ", "Ḹ"=>"ḹ", "Ḻ"=>"ḻ", "Ḽ"=>"ḽ", "Ḿ"=>"ḿ", "Ṁ"=>"ṁ", "Ṃ"=>"ṃ", "Ṅ"=>"ṅ", "Ṇ"=>"ṇ", "Ṉ"=>"ṉ", "Ṋ"=>"ṋ", "Ṍ"=>"ṍ", "Ṏ"=>"ṏ", "Ṑ"=>"ṑ", "Ṓ"=>"ṓ", "Ṕ"=>"ṕ", "Ṗ"=>"ṗ", "Ṙ"=>"ṙ", "Ṛ"=>"ṛ", "Ṝ"=>"ṝ", "Ṟ"=>"ṟ", "Ṡ"=>"ṡ", "Ṣ"=>"ṣ", "Ṥ"=>"ṥ", "Ṧ"=>"ṧ", "Ṩ"=>"ṩ", "Ṫ"=>"ṫ", "Ṭ"=>"ṭ", "Ṯ"=>"ṯ", "Ṱ"=>"ṱ", "Ṳ"=>"ṳ", "Ṵ"=>"ṵ", "Ṷ"=>"ṷ", "Ṹ"=>"ṹ", "Ṻ"=>"ṻ", "Ṽ"=>"ṽ", "Ṿ"=>"ṿ", "Ẁ"=>"ẁ", "Ẃ"=>"ẃ", "Ẅ"=>"ẅ", "Ẇ"=>"ẇ", "Ẉ"=>"ẉ", "Ẋ"=>"ẋ", "Ẍ"=>"ẍ", "Ẏ"=>"ẏ", "Ẑ"=>"ẑ", "Ẓ"=>"ẓ", "Ẕ"=>"ẕ", "ẖ"=>"ẖ", "ẗ"=>"ẗ", "ẘ"=>"ẘ", "ẙ"=>"ẙ", "ẚ"=>"aʾ", "ẛ"=>"ṡ", "Ạ"=>"ạ", "Ả"=>"ả", "Ấ"=>"ấ", "Ầ"=>"ầ", "Ẩ"=>"ẩ", "Ẫ"=>"ẫ", "Ậ"=>"ậ", "Ắ"=>"ắ", "Ằ"=>"ằ", "Ẳ"=>"ẳ", "Ẵ"=>"ẵ", "Ặ"=>"ặ", "Ẹ"=>"ẹ", "Ẻ"=>"ẻ", "Ẽ"=>"ẽ", "Ế"=>"ế", "Ề"=>"ề", "Ể"=>"ể", "Ễ"=>"ễ", "Ệ"=>"ệ", "Ỉ"=>"ỉ", "Ị"=>"ị", "Ọ"=>"ọ", "Ỏ"=>"ỏ", "Ố"=>"ố", "Ồ"=>"ồ", "Ổ"=>"ổ", "Ỗ"=>"ỗ", "Ộ"=>"ộ", "Ớ"=>"ớ", "Ờ"=>"ờ", "Ở"=>"ở", "Ỡ"=>"ỡ", "Ợ"=>"ợ", "Ụ"=>"ụ", "Ủ"=>"ủ", "Ứ"=>"ứ", "Ừ"=>"ừ", "Ử"=>"ử", "Ữ"=>"ữ", "Ự"=>"ự", "Ỳ"=>"ỳ", "Ỵ"=>"ỵ", "Ỷ"=>"ỷ", "Ỹ"=>"ỹ", "Ἀ"=>"ἀ", "Ἁ"=>"ἁ", "Ἂ"=>"ἂ", "Ἃ"=>"ἃ", "Ἄ"=>"ἄ", "Ἅ"=>"ἅ", "Ἆ"=>"ἆ", "Ἇ"=>"ἇ", "Ἐ"=>"ἐ", "Ἑ"=>"ἑ", "Ἒ"=>"ἒ", "Ἓ"=>"ἓ", "Ἔ"=>"ἔ", "Ἕ"=>"ἕ", "Ἠ"=>"ἠ", "Ἡ"=>"ἡ", "Ἢ"=>"ἢ", "Ἣ"=>"ἣ", "Ἤ"=>"ἤ", "Ἥ"=>"ἥ", "Ἦ"=>"ἦ", "Ἧ"=>"ἧ", "Ἰ"=>"ἰ", "Ἱ"=>"ἱ", "Ἲ"=>"ἲ", "Ἳ"=>"ἳ", "Ἴ"=>"ἴ", "Ἵ"=>"ἵ", "Ἶ"=>"ἶ", "Ἷ"=>"ἷ", "Ὀ"=>"ὀ", "Ὁ"=>"ὁ", "Ὂ"=>"ὂ", "Ὃ"=>"ὃ", "Ὄ"=>"ὄ", "Ὅ"=>"ὅ", "ὐ"=>"ὐ", "ὒ"=>"ὒ", "ὔ"=>"ὔ", "ὖ"=>"ὖ", "Ὑ"=>"ὑ", "Ὓ"=>"ὓ", "Ὕ"=>"ὕ", "Ὗ"=>"ὗ", "Ὠ"=>"ὠ", "Ὡ"=>"ὡ", "Ὢ"=>"ὢ", "Ὣ"=>"ὣ", "Ὤ"=>"ὤ", "Ὥ"=>"ὥ", "Ὦ"=>"ὦ", "Ὧ"=>"ὧ", "ᾀ"=>"ἀι", "ᾁ"=>"ἁι", "ᾂ"=>"ἂι", "ᾃ"=>"ἃι", "ᾄ"=>"ἄι", "ᾅ"=>"ἅι", "ᾆ"=>"ἆι", "ᾇ"=>"ἇι", "ᾈ"=>"ἀι", "ᾉ"=>"ἁι", "ᾊ"=>"ἂι", "ᾋ"=>"ἃι", "ᾌ"=>"ἄι", "ᾍ"=>"ἅι", "ᾎ"=>"ἆι", "ᾏ"=>"ἇι", "ᾐ"=>"ἠι", "ᾑ"=>"ἡι", "ᾒ"=>"ἢι", "ᾓ"=>"ἣι", "ᾔ"=>"ἤι", "ᾕ"=>"ἥι", "ᾖ"=>"ἦι", "ᾗ"=>"ἧι", "ᾘ"=>"ἠι", "ᾙ"=>"ἡι", "ᾚ"=>"ἢι", "ᾛ"=>"ἣι", "ᾜ"=>"ἤι", "ᾝ"=>"ἥι", "ᾞ"=>"ἦι", "ᾟ"=>"ἧι", "ᾠ"=>"ὠι", "ᾡ"=>"ὡι", "ᾢ"=>"ὢι", "ᾣ"=>"ὣι", "ᾤ"=>"ὤι", "ᾥ"=>"ὥι", "ᾦ"=>"ὦι", "ᾧ"=>"ὧι", "ᾨ"=>"ὠι", "ᾩ"=>"ὡι", "ᾪ"=>"ὢι", "ᾫ"=>"ὣι", "ᾬ"=>"ὤι", "ᾭ"=>"ὥι", "ᾮ"=>"ὦι", "ᾯ"=>"ὧι", "ᾲ"=>"ὰι", "ᾳ"=>"αι", "ᾴ"=>"άι", "ᾶ"=>"ᾶ", "ᾷ"=>"ᾶι", "Ᾰ"=>"ᾰ", "Ᾱ"=>"ᾱ", "Ὰ"=>"ὰ", "Ά"=>"ά", "ᾼ"=>"αι", "ι"=>"ι", "ῂ"=>"ὴι", "ῃ"=>"ηι", "ῄ"=>"ήι", "ῆ"=>"ῆ", "ῇ"=>"ῆι", "Ὲ"=>"ὲ", "Έ"=>"έ", "Ὴ"=>"ὴ", "Ή"=>"ή", "ῌ"=>"ηι", "ῒ"=>"ῒ", "ΐ"=>"ΐ", "ῖ"=>"ῖ", "ῗ"=>"ῗ", "Ῐ"=>"ῐ", "Ῑ"=>"ῑ", "Ὶ"=>"ὶ", "Ί"=>"ί", "ῢ"=>"ῢ", "ΰ"=>"ΰ", "ῤ"=>"ῤ", "ῦ"=>"ῦ", "ῧ"=>"ῧ", "Ῠ"=>"ῠ", "Ῡ"=>"ῡ", "Ὺ"=>"ὺ", "Ύ"=>"ύ", "Ῥ"=>"ῥ", "ῲ"=>"ὼι", "ῳ"=>"ωι", "ῴ"=>"ώι", "ῶ"=>"ῶ", "ῷ"=>"ῶι", "Ὸ"=>"ὸ", "Ό"=>"ό", "Ὼ"=>"ὼ", "Ώ"=>"ώ", "ῼ"=>"ωι", "Ω"=>"ω", "K"=>"k", "Å"=>"å", "Ⅰ"=>"ⅰ", "Ⅱ"=>"ⅱ", "Ⅲ"=>"ⅲ", "Ⅳ"=>"ⅳ", "Ⅴ"=>"ⅴ", "Ⅵ"=>"ⅵ", "Ⅶ"=>"ⅶ", "Ⅷ"=>"ⅷ", "Ⅸ"=>"ⅸ", "Ⅹ"=>"ⅹ", "Ⅺ"=>"ⅺ", "Ⅻ"=>"ⅻ", "Ⅼ"=>"ⅼ", "Ⅽ"=>"ⅽ", "Ⅾ"=>"ⅾ", "Ⅿ"=>"ⅿ", "Ⓐ"=>"ⓐ", "Ⓑ"=>"ⓑ", "Ⓒ"=>"ⓒ", "Ⓓ"=>"ⓓ", "Ⓔ"=>"ⓔ", "Ⓕ"=>"ⓕ", "Ⓖ"=>"ⓖ", "Ⓗ"=>"ⓗ", "Ⓘ"=>"ⓘ", "Ⓙ"=>"ⓙ", "Ⓚ"=>"ⓚ", "Ⓛ"=>"ⓛ", "Ⓜ"=>"ⓜ", "Ⓝ"=>"ⓝ", "Ⓞ"=>"ⓞ", "Ⓟ"=>"ⓟ", "Ⓠ"=>"ⓠ", "Ⓡ"=>"ⓡ", "Ⓢ"=>"ⓢ", "Ⓣ"=>"ⓣ", "Ⓤ"=>"ⓤ", "Ⓥ"=>"ⓥ", "Ⓦ"=>"ⓦ", "Ⓧ"=>"ⓧ", "Ⓨ"=>"ⓨ", "Ⓩ"=>"ⓩ", "ff"=>"ff", "fi"=>"fi", "fl"=>"fl", "ffi"=>"ffi", "ffl"=>"ffl", "ſt"=>"st", "st"=>"st", "ﬓ"=>"մն", "ﬔ"=>"մե", "ﬕ"=>"մի", "ﬖ"=>"վն", "ﬗ"=>"մխ", "A"=>"a", "B"=>"b", "C"=>"c", "D"=>"d", "E"=>"e", "F"=>"f", "G"=>"g", "H"=>"h", "I"=>"i", "J"=>"j", "K"=>"k", "L"=>"l", "M"=>"m", "N"=>"n", "O"=>"o", "P"=>"p", "Q"=>"q", "R"=>"r", "S"=>"s", "T"=>"t", "U"=>"u", "V"=>"v", "W"=>"w", "X"=>"x", "Y"=>"y", "Z"=>"z", "𐐀"=>"𐐨", "𐐁"=>"𐐩", "𐐂"=>"𐐪", "𐐃"=>"𐐫", "𐐄"=>"𐐬", "𐐅"=>"𐐭", "𐐆"=>"𐐮", "𐐇"=>"𐐯", "𐐈"=>"𐐰", "𐐉"=>"𐐱", "𐐊"=>"𐐲", "𐐋"=>"𐐳", "𐐌"=>"𐐴", "𐐍"=>"𐐵", "𐐎"=>"𐐶", "𐐏"=>"𐐷", "𐐐"=>"𐐸", "𐐑"=>"𐐹", "𐐒"=>"𐐺", "𐐓"=>"𐐻", "𐐔"=>"𐐼", "𐐕"=>"𐐽", "𐐖"=>"𐐾", "𐐗"=>"𐐿", "𐐘"=>"𐑀", "𐐙"=>"𐑁", "𐐚"=>"𐑂", "𐐛"=>"𐑃", "𐐜"=>"𐑄", "𐐝"=>"𐑅", "𐐞"=>"𐑆", "𐐟"=>"𐑇", "𐐠"=>"𐑈", "𐐡"=>"𐑉", "𐐢"=>"𐑊", "𐐣"=>"𐑋", "𐐤"=>"𐑌", "𐐥"=>"𐑍"}.freeze + + end +end diff --git a/lib/net/imap/stringprep/tables/mappings.rb b/lib/net/imap/stringprep/tables/mappings.rb new file mode 100644 index 00000000..a57bd013 --- /dev/null +++ b/lib/net/imap/stringprep/tables/mappings.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +#-- +# This file is generated by `rake stringprep:tables`. Don't edit directly. +#++ + +module Net::IMAP::StringPrep + module Tables + + # Regexps and substitutions matching the RFC-3454 Appendix B tables + MAPPINGS = { + "B.1" => [IN_B_1, MAP_B_1].freeze, + "B.2" => [IN_B_2, MAP_B_2].freeze, + "B.3" => [IN_B_3, MAP_B_3].freeze, + }.freeze + + end +end diff --git a/lib/net/imap/stringprep/tables/nameprep_prohibit.rb b/lib/net/imap/stringprep/tables/nameprep_prohibit.rb new file mode 100644 index 00000000..0655a70d --- /dev/null +++ b/lib/net/imap/stringprep/tables/nameprep_prohibit.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +#-- +# This file is generated by `rake stringprep:tables`. Don't edit directly. +#++ + +module Net::IMAP::StringPrep + module Tables + + # Combines C.1.2, C.2.2, C.3, C.4, C.5, C.6, C.7, C.8, C.9. + # Used by the "nameprep" profile. + NAMEPREP_PROHIBIT = /[\u{06dd 070f 1680 180e 3000 feff e0001}\u{0080}-\u{00a0}\u{0340}-\u{0341}\u{2000}-\u{200f}\u{2028}-\u{202f}\u{205f}-\u{2063}\u{206a}-\u{206f}\u{2ff0}-\u{2ffb}\u{e000}-\u{f8ff}\u{fdd0}-\u{fdef}\u{fff9}-\u{ffff}\u{1d173}-\u{1d17a}\u{1fffe}-\u{1ffff}\u{2fffe}-\u{2ffff}\u{3fffe}-\u{3ffff}\u{4fffe}-\u{4ffff}\u{5fffe}-\u{5ffff}\u{6fffe}-\u{6ffff}\u{7fffe}-\u{7ffff}\u{8fffe}-\u{8ffff}\u{9fffe}-\u{9ffff}\u{afffe}-\u{affff}\u{bfffe}-\u{bffff}\u{cfffe}-\u{cffff}\u{dfffe}-\u{dffff}\u{e0020}-\u{e007f}\u{efffe}-\u{10ffff}\p{Cs}]/.freeze + + end +end diff --git a/lib/net/imap/stringprep/tables/nameprep_prohibit_stored.rb b/lib/net/imap/stringprep/tables/nameprep_prohibit_stored.rb new file mode 100644 index 00000000..7408d02a --- /dev/null +++ b/lib/net/imap/stringprep/tables/nameprep_prohibit_stored.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +#-- +# This file is generated by `rake stringprep:tables`. Don't edit directly. +#++ + +module Net::IMAP::StringPrep + module Tables + + # Combines C.1.2, C.2.2, C.3, C.4, C.5, C.6, C.7, C.8, C.9, + # and A.1. Used by the "nameprep" profile. + NAMEPREP_PROHIBIT_STORED = + Regexp.union(IN_A_1, NAMEPREP_PROHIBIT).freeze + + end +end diff --git a/lib/net/imap/stringprep/tables/regexps.rb b/lib/net/imap/stringprep/tables/regexps.rb new file mode 100644 index 00000000..ed473740 --- /dev/null +++ b/lib/net/imap/stringprep/tables/regexps.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +#-- +# This file is generated by `rake stringprep:tables`. Don't edit directly. +#++ + +module Net::IMAP::StringPrep + module Tables + + # Regexps matching each codepoint table in the RFC-3454 appendices + REGEXPS = { + "A.1" => IN_A_1, + "B.1" => IN_B_1, + "B.2" => IN_B_2, + "B.3" => IN_B_3, + "C.1.1" => IN_C_1_1, + "C.1.2" => IN_C_1_2, + "C.2.1" => IN_C_2_1, + "C.2.2" => IN_C_2_2, + "C.3" => IN_C_3, + "C.4" => IN_C_4, + "C.5" => IN_C_5, + "C.6" => IN_C_6, + "C.7" => IN_C_7, + "C.8" => IN_C_8, + "C.9" => IN_C_9, + "D.1" => IN_D_1, + "D.2" => IN_D_2, + }.freeze + + end +end diff --git a/lib/net/imap/stringprep/tables/saslprep_prohibit.rb b/lib/net/imap/stringprep/tables/saslprep_prohibit.rb new file mode 100644 index 00000000..a8b5d038 --- /dev/null +++ b/lib/net/imap/stringprep/tables/saslprep_prohibit.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +#-- +# This file is generated by `rake stringprep:tables`. Don't edit directly. +#++ + +module Net::IMAP::StringPrep + module Tables + + # Combines C.1.2, C.2.1, C.2.2, C.3, C.4, C.5, C.6, C.7, C.8, C.9. + # Used by the "SASLprep" profile. + SASLPREP_PROHIBIT = /[\u{06dd 070f 1680 180e 3000 feff e0001}\u{0000}-\u{001f}\u{007f}-\u{00a0}\u{0340}-\u{0341}\u{2000}-\u{200f}\u{2028}-\u{202f}\u{205f}-\u{2063}\u{206a}-\u{206f}\u{2ff0}-\u{2ffb}\u{e000}-\u{f8ff}\u{fdd0}-\u{fdef}\u{fff9}-\u{ffff}\u{1d173}-\u{1d17a}\u{1fffe}-\u{1ffff}\u{2fffe}-\u{2ffff}\u{3fffe}-\u{3ffff}\u{4fffe}-\u{4ffff}\u{5fffe}-\u{5ffff}\u{6fffe}-\u{6ffff}\u{7fffe}-\u{7ffff}\u{8fffe}-\u{8ffff}\u{9fffe}-\u{9ffff}\u{afffe}-\u{affff}\u{bfffe}-\u{bffff}\u{cfffe}-\u{cffff}\u{dfffe}-\u{dffff}\u{e0020}-\u{e007f}\u{efffe}-\u{10ffff}\p{Cs}]/.freeze + + end +end diff --git a/lib/net/imap/stringprep/tables/saslprep_prohibit_stored.rb b/lib/net/imap/stringprep/tables/saslprep_prohibit_stored.rb new file mode 100644 index 00000000..ada6a9b4 --- /dev/null +++ b/lib/net/imap/stringprep/tables/saslprep_prohibit_stored.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +#-- +# This file is generated by `rake stringprep:tables`. Don't edit directly. +#++ + +module Net::IMAP::StringPrep + module Tables + + # Combines C.1.2, C.2.1, C.2.2, C.3, C.4, C.5, C.6, C.7, C.8, C.9, + # and A.1. Used by the "SASLprep" profile. + SASLPREP_PROHIBIT_STORED = + Regexp.union(IN_A_1, SASLPREP_PROHIBIT).freeze + + end +end diff --git a/lib/net/imap/stringprep/tables/titles.rb b/lib/net/imap/stringprep/tables/titles.rb new file mode 100644 index 00000000..1e6e9ce3 --- /dev/null +++ b/lib/net/imap/stringprep/tables/titles.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +#-- +# This file is generated by `rake stringprep:tables`. Don't edit directly. +#++ + +module Net::IMAP::StringPrep + module Tables + + # Names of each codepoint table in the RFC-3454 appendices + TITLES = { + "A.1" => "Unassigned code points in Unicode 3.2", + "B.1" => "Commonly mapped to nothing", + "B.2" => "Mapping for case-folding used with NFKC", + "B.3" => "Mapping for case-folding used with no normalization", + "C.1" => "Space characters", + "C.1.1" => "ASCII space characters", + "C.1.2" => "Non-ASCII space characters", + "C.2" => "Control characters", + "C.2.1" => "ASCII control characters", + "C.2.2" => "Non-ASCII control characters", + "C.3" => "Private use", + "C.4" => "Non-character code points", + "C.5" => "Surrogate codes", + "C.6" => "Inappropriate for plain text", + "C.7" => "Inappropriate for canonical representation", + "C.8" => "Change display properties or are deprecated", + "C.9" => "Tagging characters", + "D.1" => "Characters with bidirectional property \"R\" or \"AL\"", + "D.2" => "Characters with bidirectional property \"L\"", + }.freeze + + end +end diff --git a/lib/net/imap/stringprep/tables/trace_prohibit.rb b/lib/net/imap/stringprep/tables/trace_prohibit.rb new file mode 100644 index 00000000..68d9ab81 --- /dev/null +++ b/lib/net/imap/stringprep/tables/trace_prohibit.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +#-- +# This file is generated by `rake stringprep:tables`. Don't edit directly. +#++ + +module Net::IMAP::StringPrep + module Tables + + # Combines C.2.1, C.2.2, C.3, C.4, C.5, C.6, C.8, C.9. + # Used by the "trace" profile. + TRACE_PROHIBIT = /[\u{06dd 070f 180e feff e0001}\u{0000}-\u{001f}\u{007f}-\u{009f}\u{0340}-\u{0341}\u{200c}-\u{200f}\u{2028}-\u{202e}\u{2060}-\u{2063}\u{206a}-\u{206f}\u{e000}-\u{f8ff}\u{fdd0}-\u{fdef}\u{fff9}-\u{ffff}\u{1d173}-\u{1d17a}\u{1fffe}-\u{1ffff}\u{2fffe}-\u{2ffff}\u{3fffe}-\u{3ffff}\u{4fffe}-\u{4ffff}\u{5fffe}-\u{5ffff}\u{6fffe}-\u{6ffff}\u{7fffe}-\u{7ffff}\u{8fffe}-\u{8ffff}\u{9fffe}-\u{9ffff}\u{afffe}-\u{affff}\u{bfffe}-\u{bffff}\u{cfffe}-\u{cffff}\u{dfffe}-\u{dffff}\u{e0020}-\u{e007f}\u{efffe}-\u{10ffff}\p{Cs}]/.freeze + + end +end diff --git a/lib/net/imap/stringprep/tables/trace_prohibit_stored.rb b/lib/net/imap/stringprep/tables/trace_prohibit_stored.rb new file mode 100644 index 00000000..ff60b35e --- /dev/null +++ b/lib/net/imap/stringprep/tables/trace_prohibit_stored.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +#-- +# This file is generated by `rake stringprep:tables`. Don't edit directly. +#++ + +module Net::IMAP::StringPrep + module Tables + + # Combines C.2.1, C.2.2, C.3, C.4, C.5, C.6, C.8, C.9, + # and A.1. Used by the "trace" profile. + TRACE_PROHIBIT_STORED = + Regexp.union(IN_A_1, TRACE_PROHIBIT).freeze + + end +end diff --git a/rakelib/rfc3454_table_parser.rb b/rakelib/rfc3454_table_parser.rb new file mode 100644 index 00000000..0c104d92 --- /dev/null +++ b/rakelib/rfc3454_table_parser.rb @@ -0,0 +1,89 @@ +# frozen_string_literal: true + +# Extracts the Appendix tables from RFC3454 into a #tables hash of table name to +# codepoints array or mapping hash. Table #titles are also extracted. +class RFC3454TableParser + STRINGPREP_RFC_FILE = "rfcs/rfc3454.txt" + STRINGPREP_JSON_FILE = "rfcs/rfc3454-stringprep_tables.json" + + attr_reader :json_filename, :rfc_filename + + def initialize(rfc_filename: STRINGPREP_RFC_FILE, + json_filename: STRINGPREP_JSON_FILE) + @rfc_filename = rfc_filename + @json_filename = json_filename + end + + def inspect; "#<#{self.class}>" end + + def tables; @tables || load_from_json.first end + def titles; @titles || load_from_json.last end + + def table_names; tables.keys end + def mapping_names; mapping_tables.keys end + + def mapping_tables + @mapping_tables ||= tables + .select { _2.is_a?(Hash) } + .transform_values { to_map _1 } + end + + def write_json_file! + require "json" + rfc_filename + .then { File.read _1 } + .then { parse_rfc_text _1 } + .then { JSON.pretty_generate _1 } + .then { File.write json_filename, _1 } + end + + def load_from_json + write_json_file! unless File.exist?(json_filename) + require "json" + @tables = json_filename + .then(&File.method(:read)) + .then(&JSON.method(:parse)) + @titles = @tables.delete "titles" + [@tables, @titles] + end + + def rake_deps; Rake::FileList.new __FILE__, rfc_filename end + def rake_output; Rake::FileList.new json_filename end + + private + + # TODO: DRY with unicode_normalize + def to_map(table) + table.to_hash + .to_h { [Integer(_1, 16), _2.map {|cp| Integer(cp, 16) }] } + .to_h { [[_1].pack("U*"), _2.pack("U*")] } + end + + def parse_rfc_text(rfc3454_text) + titles = {} + tables, = rfc3454_text + .lines + .each_with_object([]) {|line, acc| + current, table = acc.last + case line + when /^([A-D]\.[1-9](?:\.[1-9])?) (.*)/ + titles[$1] = $2 + when /^ {3}-{5} Start Table (\S*)/ + acc << [$1, []] + when /^ {3}-{5} End Table / + acc << [nil, nil] + when /^ {3}([0-9A-F]+); ([ 0-9A-F]*)(?:;[^;]*)$/ # mapping tables + table << [$1, $2.split(/ +/)] if current + when /^ {3}([-0-9A-F]+)(?:;[^;]*)?$/ # regular tables + table << $1 if current + when /^ {3}(.*)/ + raise "expected to match %p" % $1 if current + end + } + .to_h.compact + .transform_values {|t| t.first.size == 2 ? t.to_h : t } + tables["titles"] = titles + tables + end + +end diff --git a/rakelib/saslprep.rake b/rakelib/saslprep.rake deleted file mode 100644 index 3d56f8a3..00000000 --- a/rakelib/saslprep.rake +++ /dev/null @@ -1,30 +0,0 @@ -# frozen_string_literal: true - -require_relative "string_prep_tables_generator" - -generator = StringPrepTablesGenerator.new - -file generator.json_filename => generator.json_deps do |t| - generator.generate_json_data_file -end - -directory "lib/net/imap/sasl" - -file "lib/net/imap/stringprep/tables.rb" => generator.rb_deps do |t| - File.write t.name, generator.stringprep_rb -end - -file "lib/net/imap/stringprep/saslprep_tables.rb" => generator.rb_deps do |t| - File.write t.name, generator.saslprep_rb -end - -GENERATED_RUBY = FileList.new( - "lib/net/imap/stringprep/tables.rb", - "lib/net/imap/stringprep/saslprep_tables.rb", -) - -CLEAN.include generator.clean_deps -CLOBBER.include GENERATED_RUBY - -task saslprep_rb: GENERATED_RUBY -task test: :saslprep_rb diff --git a/rakelib/string_prep_tables_generator.rb b/rakelib/string_prep_tables_generator.rb index 59028a69..04ac6ce5 100644 --- a/rakelib/string_prep_tables_generator.rb +++ b/rakelib/string_prep_tables_generator.rb @@ -1,344 +1,231 @@ # frozen_string_literal: true -require "set" unless defined?(::Set) +require_relative "rfc3454_table_parser" +require_relative "stringprep_table_transformer" -# Generator for stringprep regexps. +# Generator for stringprep StringPrep::Tables constants (primarily regexps). # # Combines Unicode character classes with generated tables. Generated regexps # are still used to test that the written regexps conform to the specification. # Some tables don't match up well with any character properties available to # ruby's regexp engine. Those use the table-generated regexps. class StringPrepTablesGenerator - STRINGPREP_RFC_FILE = "rfcs/rfc3454.txt" - STRINGPREP_JSON_FILE = "rfcs/rfc3454-stringprep_tables.json" + INDENT = " " - # valid UTF-8 can't contain these codepoints - # checking for them anyway, using /\p{Cs}/ ;) - SURROGATES_RANGE = 0xD800..0xDFFF + attr_reader :tables_dir, :transformer - attr_reader :json_filename, :rfc_filename - - def initialize(rfc_filename: STRINGPREP_RFC_FILE, - json_filename: STRINGPREP_JSON_FILE) - @rfc_filename = rfc_filename - @json_filename = json_filename + def initialize(tables_dir: "lib/net/imap/stringprep/tables") + @parser = RFC3454TableParser.new + @transformer = StringPrepTableTransformer.new(self) + @tables_dir = tables_dir end + def inspect; "#<#{self.class}>" end + + def asgn_regexps; @asgn_regexps || asgn_regexps! end + def consts; @consts ||= define_consts end + + # delegated to @parser + def json_filename; @parser.json_filename end + def tables; @parser.tables end + def titles; @parser.titles end + def table_names; @parser.table_names end + def mapping_names; @parser.mapping_names end + # for rake deps - def json_deps; Rake::FileList.new __FILE__, STRINGPREP_RFC_FILE end - def rb_deps; Rake::FileList.new __FILE__, STRINGPREP_JSON_FILE end - def clean_deps; Rake::FileList.new STRINGPREP_JSON_FILE end - - def generate_json_data_file - require "json" - rfc_filename - .then(&File.method(:read)) - .then(&method(:parse_rfc_text)) - .then(&JSON.method(:pretty_generate)) - .then {|data| File.write json_filename, data } - end + def json_deps; @parser.rake_deps end + def clean_deps; @parser.rake_output end # TODO: add table files to this list? + def generate_json_data_file; @parser.write_json_file! end - def tables; @tables ||= load_tables_and_titles_from_json!.first end - def titles; @titles ||= load_tables_and_titles_from_json!.last end - def ranges; @ranges ||= tables.transform_values(&method(:to_ranges)) end - def arrays; @arrays ||= ranges.transform_values{|t| t.flat_map(&:to_a) } end - def sets; @sets ||= arrays.transform_values(&:to_set) end - def regexps; @regexps ||= arrays.transform_values(&method(:to_regexp)) end - def asgn_regexps; @asgn_regexps || asgn_regexps! end - - def merged_tables_regex(*table_names, negate: false) - table_names - .flat_map(&arrays.method(:fetch)) - .then {|array| to_regexp(array, negate: negate) } - end + # delegated to @transformer + def merged_tables_regex(...) @transformer.merged_tables_regex(...) end + + # for rake deps + def rb_deps; Rake::FileList[json_deps, clean_deps, __FILE__] end + def table_files; consts.each_key.map { "#{tables_dir}/#{_1.downcase}.rb" } end def regexp_for(*names, negate: false) asgn_regexps[[*names, negate]] ||= merged_tables_regex(*names, negate: negate) end def stringprep_rb + stringprep_tables_file_template do + consts.each_key.map {|name| + 'autoload %-26s "#{__dir__}/tables/%s.rb"' % [ + name.to_sym.inspect + ",", + name.downcase + ] + }.join("\n") + end + end + + def stringprep_table_file(const_name) + stringprep_tables_file_template { + value = consts.fetch(const_name) + case value + in {table:, negate:, regexp: Regexp} + asgn_table table, negate: negate + in {table:, map: Hash | String | Proc} + asgn_mapping table + in {comment:, union:} + "%s\n%s =\n Regexp.union(%s).freeze" % [ + comment.gsub(/^/, "# "), const_name, union, + ] + in {comment:, regexp:} + "%s\n%s = %p.freeze" % [ + comment.gsub(/^/, "# "), const_name, regexp, + ] + in {comment:, hash:, literals:} + "%s\n%s = {\n%s\n}.freeze" % [ + comment.gsub(/^/, "# "), + const_name, + hash_contents(hash, literals: literals), + ] + in String => str + "%s = %p" % [const_name, str] + end + } + end + + def stringprep_tables_file_template + content = indent yield.strip, level: 2 <<~RUBY # frozen_string_literal: true #-- - # This file is generated from RFC3454, by rake. Don't edit directly. + # This file is generated by `rake stringprep:tables`. Don't edit directly. #++ module Net::IMAP::StringPrep - module Tables - #{asgn_table "A.1"} - - #{asgn_table "B.1"} - - #{asgn_table "B.2"} - - #{asgn_table "B.3"} - - #{asgn_mapping "B.1", ""} - - #{asgn_mapping "B.2"} - - #{asgn_mapping "B.3"} - - #{asgn_table "C.1.1"} - - #{asgn_table "C.1.2"} - - #{asgn_table "C.2.1"} - - #{asgn_table "C.2.2"} - - #{asgn_table "C.3"} - - #{asgn_table "C.4"} - - #{asgn_table "C.5"} - - #{asgn_table "C.6"} - - #{asgn_table "C.7"} - - #{asgn_table "C.8"} - - #{asgn_table "C.9"} - - #{asgn_table "D.1"} - - # Used to check req3 of bidirectional checks - #{asgn_table "D.1", negate: true} - - #{asgn_table "D.2"} - - BIDI_DESC_REQ2 = "A string with RandALCat characters must not contain LCat characters." - - # Bidirectional Characters [StringPrep, §6], Requirement 2 - # >>> - # If a string contains any RandALCat character, the string MUST NOT - # contain any LCat character. - BIDI_FAILS_REQ2 = #{bidi_fails_req2.inspect}.freeze - - BIDI_DESC_REQ3 = "A string with RandALCat characters must start and end with RandALCat characters." - - # Bidirectional Characters [StringPrep, §6], Requirement 3 - # >>> - # If a string contains any RandALCat character, a RandALCat - # character MUST be the first character of the string, and a - # RandALCat character MUST be the last character of the string. - BIDI_FAILS_REQ3 = #{bidi_fails_req3.inspect}.freeze - - # Bidirectional Characters [StringPrep, §6] - BIDI_FAILURE = #{bidi_failure_regexp.inspect}.freeze - - # Names of each codepoint table in the RFC-3454 appendices - TITLES = { - #{table_titles_rb} - }.freeze - - # Regexps matching each codepoint table in the RFC-3454 appendices - REGEXPS = { - #{table_regexps_rb} - }.freeze - - MAPPINGS = { - "B.1" => [IN_B_1, MAP_B_1].freeze, - "B.2" => [IN_B_2, MAP_B_2].freeze, - "B.3" => [IN_B_3, MAP_B_3].freeze, - }.freeze + #{content.strip} end end RUBY end - def table_titles_rb(indent = 3) - titles - .map{|t| "%p => %p," % t } - .join("\n#{" "*indent}") + def hash_contents(hash, literals: false, indent: 1) + keylen = hash.keys.map(&:inspect).map(&:length).max + format = "%-#{keylen}p => %#{literals ? ?s : ?p}," + indent hash.map {|kv| format % kv }.join("\n"), level: indent end - def table_regexps_rb(indent = 3) - asgn_regexps # => { ["A.1", false] => regexp, ... } - .reject {|(_, n), _| n } - .map {|(t, _), _| "%p => %s," % [t, regexp_const_name(t)] } - .join("\n#{" "*indent}") + def tables_to_const_names + asgn_regexps + .reject {|(_table, negate), _regexp| negate } + .to_h {|(table, _negate), _regexp| [table, regexp_const_name(table)] } end - def saslprep_rb - <<~RUBY - # frozen_string_literal: true - - #-- - # This file is generated from RFC3454, by rake. Don't edit directly. - #++ - - module Net::IMAP::StringPrep - - module SASLprep - - # RFC4013 §2.1 Mapping - mapped to space - # >>> - # non-ASCII space characters (\\StringPrep\\[\\"C.1.2\\"]) that can - # be mapped to SPACE (U+0020) - # - # Equal to \\StringPrep\\[\\"C.1.2\\"]. - # Redefined here to avoid loading StringPrep::Tables unless necessary. - MAP_TO_SPACE = #{regex_str "C.1.2"} - - # RFC4013 §2.1 Mapping - mapped to nothing - # >>> - # the "commonly mapped to nothing" characters - # (\\StringPrep\\[\\"B.1\\"]) that can be mapped to nothing. - # - # Equal to \\StringPrep\\[\\"B.1\\"]. - # Redefined here to avoid loading StringPrep::Tables unless necessary. - MAP_TO_NOTHING = #{regex_str "B.1"} - - # RFC4013 §2.3 Prohibited Output - # >>> - # * Non-ASCII space characters — \\StringPrep\\[\\"C.1.2\\"] - # * ASCII control characters — \\StringPrep\\[\\"C.2.1\\"] - # * Non-ASCII control characters — \\StringPrep\\[\\"C.2.2\\"] - # * Private Use characters — \\StringPrep\\[\\"C.3\\"] - # * Non-character code points — \\StringPrep\\[\\"C.4\\"] - # * Surrogate code points — \\StringPrep\\[\\"C.5\\"] - # * Inappropriate for plain text characters — \\StringPrep\\[\\"C.6\\"] - # * Inappropriate for canonical representation characters — \\StringPrep\\[\\"C.7\\"] - # * Change display properties or deprecated characters — \\StringPrep\\[\\"C.8\\"] - # * Tagging characters — \\StringPrep\\[\\"C.9\\"] - TABLES_PROHIBITED = #{SASL_TABLES_PROHIBITED.inspect}.freeze - - # Adds unassigned (by Unicode 3.2) codepoints to TABLES_PROHIBITED. - # - # RFC4013 §2.5 Unassigned Code Points - # >>> - # This profile specifies the \\StringPrep\\[\\"A.1\\"] table as its - # list of unassigned code points. - TABLES_PROHIBITED_STORED = ["A.1", *TABLES_PROHIBITED].freeze - - # A Regexp matching codepoints prohibited by RFC4013 §2.3. - # - # This combines all of the TABLES_PROHIBITED tables. - PROHIBITED_OUTPUT = #{regex_str(*SASL_TABLES_PROHIBITED)} - - # RFC4013 §2.5 Unassigned Code Points - # >>> - # This profile specifies the \\StringPrep\\[\\"A.1\\"] table as its - # list of unassigned code points. - # - # Equal to \\StringPrep\\[\\"A.1\\"]. - # Redefined here to avoid loading StringPrep::Tables unless necessary. - UNASSIGNED = #{regex_str "A.1"} - - # A Regexp matching codepoints prohibited by RFC4013 §2.3 and §2.5. - # - # This combines PROHIBITED_OUTPUT and UNASSIGNED. - PROHIBITED_OUTPUT_STORED = Regexp.union( - UNASSIGNED, PROHIBITED_OUTPUT - ).freeze - - # Bidirectional Characters [StringPrep, §6] - # - # A Regexp for strings that don't satisfy StringPrep's Bidirectional - # Characters rules. - # - # Equal to StringPrep::Tables::BIDI_FAILURE. - # Redefined here to avoid loading StringPrep::Tables unless necessary. - BIDI_FAILURE = #{bidi_failure_regexp.inspect}.freeze - - # A Regexp matching strings prohibited by RFC4013 §2.3 and §2.4. - # - # This combines PROHIBITED_OUTPUT and BIDI_FAILURE. - PROHIBITED = Regexp.union( - PROHIBITED_OUTPUT, BIDI_FAILURE, - ) - - # A Regexp matching strings prohibited by RFC4013 §2.3, §2.4, and §2.5. - # - # This combines PROHIBITED_OUTPUT_STORED and BIDI_FAILURE. - PROHIBITED_STORED = Regexp.union( - PROHIBITED_OUTPUT_STORED, BIDI_FAILURE, - ) - - end - end - RUBY + def table_regexps_rb(indent = 3) + tables_to_const_names + .map {|table, const| "%-7p => %s," % [table, const] } + .join("\n") end private - def parse_rfc_text(rfc3454_text) - titles = {} - tables, = rfc3454_text - .lines - .each_with_object([]) {|line, acc| - current, table = acc.last - case line - when /^([A-D]\.[1-9](?:\.[1-9])?) (.*)/ - titles[$1] = $2 - when /^ {3}-{5} Start Table (\S*)/ - acc << [$1, []] - when /^ {3}-{5} End Table / - acc << [nil, nil] - when /^ {3}([0-9A-F]+); ([ 0-9A-F]*)(?:;[^;]*)$/ # mapping tables - table << [$1, $2.split(/ +/)] if current - when /^ {3}([-0-9A-F]+)(?:;[^;]*)?$/ # regular tables - table << $1 if current - when /^ {3}(.*)/ - raise "expected to match %p" % $1 if current - end - } - .to_h.compact - .transform_values {|t| t.first.size == 2 ? t.to_h : t } - tables["titles"] = titles - tables + def define_consts + {}.merge!(table_regexp_consts, + table_mappings_consts, + bidi_failure_consts, + *profile_consts, + meta_consts) end - def load_tables_and_titles_from_json! - require "json" - @tables = json_filename - .then(&File.method(:read)) - .then(&JSON.method(:parse)) - @titles = @tables.delete "titles" - [@tables, @titles] + def table_regexp_consts + asgn_regexps.to_h {|(t, n), r| + [regexp_const_name(t, negate: n), {table: t, negate: n, regexp: r}] + } end - def to_ranges(table) - (table.is_a?(Hash) ? table.keys : table) - .map{|range| range.split(?-).map{|cp| Integer cp, 16} } - .map{|s,e| s..(e || s)} + def table_mappings_consts + @parser.mapping_tables.to_h {|table, map| + [mapping_const_name(table), {table: table, map: map}] + } end - # TODO: DRY with unicode_normalize - def to_map(table) - table = table.to_hash - .transform_keys { Integer _1, 16 } - .transform_keys { [_1].pack("U*") } - .transform_values {|cps| cps.map { Integer _1, 16 } } - .transform_values { _1.pack("U*") } + def bidi_failure_consts + { + BIDI_DESC_REQ2: "A string with RandALCat characters " \ + "must not contain LCat characters.", + BIDI_FAILS_REQ2: {regexp: bidi_fails_req2, comment: <<~DESC.strip}, + Bidirectional Characters [StringPrep, §6], Requirement 2 + >>> + If a string contains any RandALCat character, the string MUST NOT + contain any LCat character. + DESC + + BIDI_DESC_REQ3: "A string with RandALCat characters " \ + "must start and end with RandALCat characters.", + BIDI_FAILS_REQ3: {regexp: bidi_fails_req3, comment: <<~DESC.strip}, + Bidirectional Characters [StringPrep, §6], Requirement 3 + >>> + If a string contains any RandALCat character, a RandALCat + character MUST be the first character of the string, and a + RandALCat character MUST be the last character of the string. + DESC + + BIDI_FAILURE: {regexp: bidi_failure_regexp, comment: <<~DESC.strip}, + Bidirectional Characters [StringPrep, §6] + DESC + } end - # Starting from a codepoints array (rather than ranges) to deduplicate merged - # tables. - def to_regexp(codepoints, negate: false) - codepoints - .grep_v(SURROGATES_RANGE) # remove surrogate codepoints from C.5 and D.2 - .uniq - .sort - .chunk_while {|cp1,cp2| cp1 + 1 == cp2 } # find contiguous chunks - .map {|chunk| chunk.map{|cp| "%04x" % cp } } # convert to hex strings - .partition {|chunk| chunk[1] } # ranges vs singles - .then {|ranges, singles| - singles.flatten! - [ - negate ? "^" : "", - singles.flatten.any? ? "\\u{%s}" % singles.join(" ") : "", - ranges.map {|r| "\\u{%s}-\\u{%s}" % [r.first, r.last] }.join, - codepoints.any?(SURROGATES_RANGE) ? "\\p{Cs}" : "", # not necessary :) - ].join + def profile_consts + { + SASLprep: %w[C.1.2 C.2.1 C.2.2 C.3 C.4 C.5 C.6 C.7 C.8 C.9], + trace: %w[C.2.1 C.2.2 C.3 C.4 C.5 C.6 C.8 C.9], + nameprep: %w[C.1.2 C.2.2 C.3 C.4 C.5 C.6 C.7 C.8 C.9], + } + .map {|name, tables| + { + :"#{name.upcase}_PROHIBIT" => { + regexp: regexp_for(*tables), + comment: <<~DESC.strip, + Combines #{tables.join(", ")}. + Used by the "#{name}" profile. + DESC + }, + :"#{name.upcase}_PROHIBIT_STORED" => { + union: "IN_A_1, #{name.upcase}_PROHIBIT", + regexp: regexp_for(*tables), + comment: <<~DESC.strip, + Combines #{tables.join(", ")}, + and A.1. Used by the "#{name}" profile. + DESC + } + } } - .then {|char_class| Regexp.new "[#{char_class}]" } + end + + def meta_consts + { + TITLES: {hash: titles, literals: false, comment: <<~DESC.strip}, + Names of each codepoint table in the RFC-3454 appendices + DESC + + REGEXPS: { + comment: <<~DESC.strip, + Regexps matching each codepoint table in the RFC-3454 appendices + DESC + hash: tables_to_const_names, + literals: true, + }, + + MAPPINGS: { + comment: <<~DESC.strip, + Regexps and substitutions matching the RFC-3454 Appendix B tables + DESC + hash: { + "B.1" => "[IN_B_1, MAP_B_1].freeze", + "B.2" => "[IN_B_2, MAP_B_2].freeze", + "B.3" => "[IN_B_3, MAP_B_3].freeze", + }.freeze, + literals: true, + } + } end def asgn_regexps! @@ -374,23 +261,30 @@ def asgn_regexps! # Class=R}\p{bc=AL}]/. On the other hand, StringPrep (based on Unicode 3.2) # might not be a good match for the modern (14.0) property value anyway. asgn_table "D.1" - asgn_table "D.1", negate: true # used by BIDI_FAILS_REQ3 + # Used to check req3 of bidirectional checks + asgn_table "D.1", negate: true asgn_table "D.2" @asgn_regexps end + def indent(str, level: 2) str.gsub(/^(?!$)/, INDENT * level) end + def regex_str(*names, negate: false) "%p.freeze" % regexp_for(*names, negate: negate) end + def table(name, negate: false) + asgn_regex(name, regexp_for(name, negate: negate), negate: negate) + end + def asgn_table(name, negate: false) asgn_regex(name, regexp_for(name, negate: negate), negate: negate) end - def asgn_mapping(name, replacement = to_map(tables[name])) + def asgn_mapping(name, replacement = @parser.mapping_tables.fetch(name)) cname = name.tr(?., ?_).upcase - "# Replacements for %s\n%s%s = %p.freeze" % [ - "IN_#{name}", " " * 2, "MAP_#{cname}", replacement, + "# Replacements for %s\n%s = %p.freeze" % [ + "IN_#{name}", "MAP_#{cname}", replacement, ] end @@ -400,16 +294,23 @@ def regexp_const_desc(name, negate: false) end end + def const_name(prefix, table, suffix = nil) + [prefix, table.tr(?., ?_), suffix].compact.join(?_).to_sym + end + def regexp_const_name(table_name, negate: false) - "IN_%s%s" % [table_name.tr(".", "_"), negate ? "_NEGATED" : ""] + const_name :IN, table_name, negate ? :NEGATED : nil + end + + def mapping_const_name(table_name) + const_name :MAP, table_name end def asgn_regex(name, regexp, negate: false) asgn_regexps[[name, negate]] = regexp - "# %s\n%s%s = %p.freeze" % [ - regexp_const_desc(name, negate: negate), " " * 4, - regexp_const_name(name, negate: negate), - regexp, + "# %s\n%s = %p.freeze" % [ + regexp_const_desc(name, negate: negate), + regexp_const_name(name, negate: negate), regexp, ] end @@ -436,12 +337,4 @@ def bidi_failure_regexp Regexp.union(bidi_fails_req2, bidi_fails_req3) end - SASL_TABLES_PROHIBITED = %w[ - C.1.2 C.2.1 C.2.2 C.3 C.4 C.5 C.6 C.7 C.8 C.9 - ].freeze - - SASL_TABLES_PROHIBITED_STORED = %w[ - 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 - ].freeze - end diff --git a/rakelib/stringprep.rake b/rakelib/stringprep.rake new file mode 100644 index 00000000..39555b35 --- /dev/null +++ b/rakelib/stringprep.rake @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +require_relative "string_prep_tables_generator" + +generator = StringPrepTablesGenerator.new +GENERATED_RUBY = FileList.new +GENERATED_RUBY.include "#{generator.tables_dir}.rb" +GENERATED_RUBY.include generator.tables_dir +table_deps = GENERATED_RUBY.dup.include generator.rb_deps + +file generator.json_filename => generator.json_deps do |t| + generator.generate_json_data_file +end + +directory "lib/net/imap/sasl" +directory generator.tables_dir + +file "#{generator.tables_dir}.rb" => generator.rb_deps do |t| + File.write t.name, generator.stringprep_rb +end + +rule(%r{#{Regexp.escape(generator.tables_dir)}/[^/]+\.rb} => table_deps) do |t| + const_name = File.basename(t.name, ".rb").upcase.to_sym + File.write t.name, generator.stringprep_table_file(const_name) +end + +task "stringprep:tables": table_deps do + generator.table_files.map { Rake::Task[_1] }.each do |t| + t.invoke + end +end + +CLEAN.include generator.clean_deps +CLOBBER.include GENERATED_RUBY + +task "stringprep:tables": GENERATED_RUBY +task test: "stringprep:tables" diff --git a/rakelib/stringprep_table_transformer.rb b/rakelib/stringprep_table_transformer.rb new file mode 100644 index 00000000..cec65dba --- /dev/null +++ b/rakelib/stringprep_table_transformer.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +require "set" unless defined?(::Set) + +# Converts RFC3454 tables into ranges, arrays, sets, regexps. +class StringPrepTableTransformer + + # valid UTF-8 can't contain these codepoints + # checking for them anyway, using /\p{Cs}/ ;) + SURROGATES_RANGE = 0xD800..0xDFFF + + def initialize(table_source) + @table_source = table_source + end + + def inspect; "#<#{self.class}>" end + + def tables; @table_source.tables end + def ranges; @ranges ||= tables.transform_values(&method(:to_ranges)) end + def arrays; @arrays ||= ranges.transform_values{|t| t.flat_map(&:to_a) } end + def sets; @sets ||= arrays.transform_values(&:to_set) end + def regexps; @regexps ||= arrays.transform_values(&method(:to_regexp)) end + + def merged_tables_regex(*table_names, negate: false) + table_names + .flat_map { arrays.fetch _1 } + .then { to_regexp(_1, negate: negate) } + end + + private + + def to_ranges(table) + (table.is_a?(Hash) ? table.keys : table) + .map{|range| range.split(?-).map {|cp| Integer cp, 16} } + .map{|s,e| s..(e || s)} + end + + # Starting from a codepoints array (rather than ranges) to deduplicate merged + # tables. + def to_regexp(codepoints, negate: false) + codepoints + .grep_v(SURROGATES_RANGE) # remove surrogate codepoints from C.5 and D.2 + .uniq.sort + .chunk_while {|cp1,cp2| cp1 + 1 == cp2 } # find contiguous chunks + .map {|chunk| chunk.map{|cp| "%04x" % cp } } # convert to hex strings + .partition {|chunk| chunk[1] } # ranges vs singles + .then {|ranges, singles| + singles.flatten! + [ + negate ? "^" : "", + singles.flatten.any? ? "\\u{%s}" % singles.join(" ") : "", + ranges.map {|r| "\\u{%s}-\\u{%s}" % [r.first, r.last] }.join, + codepoints.any?(SURROGATES_RANGE) ? "\\p{Cs}" : "", # not necessary :) + ].join + } + .then {|char_class| Regexp.new "[#{char_class}]" } + end + +end diff --git a/test/net/imap/test_imap_authenticators.rb b/test/net/imap/test_imap_authenticators.rb index d896bf53..bcdf99f2 100644 --- a/test/net/imap/test_imap_authenticators.rb +++ b/test/net/imap/test_imap_authenticators.rb @@ -269,10 +269,10 @@ def test_anonymous_response end def test_anonymous_stringprep - assert_raise(Net::IMAP::SASL::ProhibitedCodepoint) { + assert_raise(Net::IMAP::StringPrep::ProhibitedCodepoint) { anonymous("no\ncontrol\rchars").process(nil) } - assert_raise(Net::IMAP::SASL::ProhibitedCodepoint) { + assert_raise(Net::IMAP::StringPrep::ProhibitedCodepoint) { anonymous("regional flags use tagging chars: e.g." \ "🏴󠁧󠁢󠁥󠁮󠁧󠁿 England, " \ "🏴󠁧󠁢󠁳󠁣󠁴󠁿 Scotland, " \ diff --git a/test/net/imap/test_regexps.rb b/test/net/imap/test_regexps.rb index 3432f62e..b35b9ceb 100644 --- a/test/net/imap/test_regexps.rb +++ b/test/net/imap/test_regexps.rb @@ -29,6 +29,15 @@ class IMAPRegexpsTest < Test::Unit::TestCase PlainAuthenticator XOauth2Authenticator ], # deprecated + Net::IMAP::StringPrep::SASLprep => %i[ + UNASSIGNED + ], + Net::IMAP::SASL => %i[ + StringPrepError + ProhibitedCodepoint + BidiStringError + StringPrep + ], # deprecated }, ).to_h ) diff --git a/test/net/imap/test_saslprep.rb b/test/net/imap/test_saslprep.rb index 117ffe92..6010e993 100644 --- a/test/net/imap/test_saslprep.rb +++ b/test/net/imap/test_saslprep.rb @@ -31,6 +31,7 @@ def test_saslprep_valid_inputs "\u{1f468}\u{1f469}\u{1f467}" # map ZWJ to nothing }.each do |input, output| assert_equal output, Net::IMAP.saslprep(input) + assert_equal output, Net::IMAP.saslprep(input, exception: true) end end diff --git a/test/net/imap/test_stringprep_tables.rb b/test/net/imap/test_stringprep_tables.rb index b87d1efe..c4d3e8fc 100644 --- a/test/net/imap/test_stringprep_tables.rb +++ b/test/net/imap/test_stringprep_tables.rb @@ -12,10 +12,10 @@ class StringPrepTablesTest < Test::Unit::TestCase # Surrogates are excluded. They are handled by enforcing valid UTF8 encoding. VALID_CODEPOINTS = (0..0x10_ffff).map{|cp| cp.chr("UTF-8") rescue nil}.compact - rfc3454_generator = StringPrepTablesGenerator.new + rfc3454_transformer = StringPrepTablesGenerator.new.transformer # testing with set inclusion, just in case the regexp generation is buggy - RFC3454_TABLE_SETS = rfc3454_generator.sets + RFC3454_TABLE_SETS = rfc3454_transformer.sets # The library regexps are a mixture of generated vs handcrafted, in order to # reduce load-time and memory footprint of the largest tables. @@ -23,7 +23,7 @@ class StringPrepTablesTest < Test::Unit::TestCase # These are the simple generated regexps, which directly translate each table # into a character class with every codepoint. These can be used to verify # the hand-crafted regexps are correct, for every supported version of ruby. - RFC3454_TABLE_REGEXPS = rfc3454_generator.regexps + RFC3454_TABLE_REGEXPS = rfc3454_transformer.regexps # C.5 (surrogates) aren't really tested here. # D.2 includes surrogates... which also aren't tested here.