/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
 * This source file is part of the Cangjie project, licensed under Apache-2.0
 * with Runtime Library Exception.
 *
 * See https://cangjie-lang.cn/pages/LICENSE for license information.
 */

package std.unicode

import std.collection.*

struct CaseRange {
    CaseRange(
        var start: Int32,
        var end: Int32,
        var upper: Int32,
        var lower: Int32,
        var title: Int32
    ) {}
}

struct UnicodeRange {
    UnicodeRange(var start: Int32, var end: Int32) {}
}

struct SpecialCaseRange {
    SpecialCaseRange(
        var codePoint: UInt32,
        var lower: Array<UInt32>,
        var title: Array<UInt32>,
        var upper: Array<UInt32>
    ) {}
}

/**
 * Following arrays are used to determine the type of the input character according to the Unicode standard.
 * Current Unicode standard version is 13.0.0.
 */
let LOWER_CASE_LETTER: Array<UnicodeRange> = [
    UnicodeRange(0X0061, 0X007A),
    UnicodeRange(0X00B5, 0X00B5),
    UnicodeRange(0X00DF, 0X00F6),
    UnicodeRange(0X00F8, 0X00FF),
    UnicodeRange(0X0101, 0X0101),
    UnicodeRange(0X0103, 0X0103),
    UnicodeRange(0X0105, 0X0105),
    UnicodeRange(0X0107, 0X0107),
    UnicodeRange(0X0109, 0X0109),
    UnicodeRange(0X010B, 0X010B),
    UnicodeRange(0X010D, 0X010D),
    UnicodeRange(0X010F, 0X010F),
    UnicodeRange(0X0111, 0X0111),
    UnicodeRange(0X0113, 0X0113),
    UnicodeRange(0X0115, 0X0115),
    UnicodeRange(0X0117, 0X0117),
    UnicodeRange(0X0119, 0X0119),
    UnicodeRange(0X011B, 0X011B),
    UnicodeRange(0X011D, 0X011D),
    UnicodeRange(0X011F, 0X011F),
    UnicodeRange(0X0121, 0X0121),
    UnicodeRange(0X0123, 0X0123),
    UnicodeRange(0X0125, 0X0125),
    UnicodeRange(0X0127, 0X0127),
    UnicodeRange(0X0129, 0X0129),
    UnicodeRange(0X012B, 0X012B),
    UnicodeRange(0X012D, 0X012D),
    UnicodeRange(0X012F, 0X012F),
    UnicodeRange(0X0131, 0X0131),
    UnicodeRange(0X0133, 0X0133),
    UnicodeRange(0X0135, 0X0135),
    UnicodeRange(0X0137, 0X0138),
    UnicodeRange(0X013A, 0X013A),
    UnicodeRange(0X013C, 0X013C),
    UnicodeRange(0X013E, 0X013E),
    UnicodeRange(0X0140, 0X0140),
    UnicodeRange(0X0142, 0X0142),
    UnicodeRange(0X0144, 0X0144),
    UnicodeRange(0X0146, 0X0146),
    UnicodeRange(0X0148, 0X0149),
    UnicodeRange(0X014B, 0X014B),
    UnicodeRange(0X014D, 0X014D),
    UnicodeRange(0X014F, 0X014F),
    UnicodeRange(0X0151, 0X0151),
    UnicodeRange(0X0153, 0X0153),
    UnicodeRange(0X0155, 0X0155),
    UnicodeRange(0X0157, 0X0157),
    UnicodeRange(0X0159, 0X0159),
    UnicodeRange(0X015B, 0X015B),
    UnicodeRange(0X015D, 0X015D),
    UnicodeRange(0X015F, 0X015F),
    UnicodeRange(0X0161, 0X0161),
    UnicodeRange(0X0163, 0X0163),
    UnicodeRange(0X0165, 0X0165),
    UnicodeRange(0X0167, 0X0167),
    UnicodeRange(0X0169, 0X0169),
    UnicodeRange(0X016B, 0X016B),
    UnicodeRange(0X016D, 0X016D),
    UnicodeRange(0X016F, 0X016F),
    UnicodeRange(0X0171, 0X0171),
    UnicodeRange(0X0173, 0X0173),
    UnicodeRange(0X0175, 0X0175),
    UnicodeRange(0X0177, 0X0177),
    UnicodeRange(0X017A, 0X017A),
    UnicodeRange(0X017C, 0X017C),
    UnicodeRange(0X017E, 0X0180),
    UnicodeRange(0X0183, 0X0183),
    UnicodeRange(0X0185, 0X0185),
    UnicodeRange(0X0188, 0X0188),
    UnicodeRange(0X018C, 0X018D),
    UnicodeRange(0X0192, 0X0192),
    UnicodeRange(0X0195, 0X0195),
    UnicodeRange(0X0199, 0X019B),
    UnicodeRange(0X019E, 0X019E),
    UnicodeRange(0X01A1, 0X01A1),
    UnicodeRange(0X01A3, 0X01A3),
    UnicodeRange(0X01A5, 0X01A5),
    UnicodeRange(0X01A8, 0X01A8),
    UnicodeRange(0X01AA, 0X01AB),
    UnicodeRange(0X01AD, 0X01AD),
    UnicodeRange(0X01B0, 0X01B0),
    UnicodeRange(0X01B4, 0X01B4),
    UnicodeRange(0X01B6, 0X01B6),
    UnicodeRange(0X01B9, 0X01BA),
    UnicodeRange(0X01BD, 0X01BF),
    UnicodeRange(0X01C6, 0X01C6),
    UnicodeRange(0X01C9, 0X01C9),
    UnicodeRange(0X01CC, 0X01CC),
    UnicodeRange(0X01CE, 0X01CE),
    UnicodeRange(0X01D0, 0X01D0),
    UnicodeRange(0X01D2, 0X01D2),
    UnicodeRange(0X01D4, 0X01D4),
    UnicodeRange(0X01D6, 0X01D6),
    UnicodeRange(0X01D8, 0X01D8),
    UnicodeRange(0X01DA, 0X01DA),
    UnicodeRange(0X01DC, 0X01DD),
    UnicodeRange(0X01DF, 0X01DF),
    UnicodeRange(0X01E1, 0X01E1),
    UnicodeRange(0X01E3, 0X01E3),
    UnicodeRange(0X01E5, 0X01E5),
    UnicodeRange(0X01E7, 0X01E7),
    UnicodeRange(0X01E9, 0X01E9),
    UnicodeRange(0X01EB, 0X01EB),
    UnicodeRange(0X01ED, 0X01ED),
    UnicodeRange(0X01EF, 0X01F0),
    UnicodeRange(0X01F3, 0X01F3),
    UnicodeRange(0X01F5, 0X01F5),
    UnicodeRange(0X01F9, 0X01F9),
    UnicodeRange(0X01FB, 0X01FB),
    UnicodeRange(0X01FD, 0X01FD),
    UnicodeRange(0X01FF, 0X01FF),
    UnicodeRange(0X0201, 0X0201),
    UnicodeRange(0X0203, 0X0203),
    UnicodeRange(0X0205, 0X0205),
    UnicodeRange(0X0207, 0X0207),
    UnicodeRange(0X0209, 0X0209),
    UnicodeRange(0X020B, 0X020B),
    UnicodeRange(0X020D, 0X020D),
    UnicodeRange(0X020F, 0X020F),
    UnicodeRange(0X0211, 0X0211),
    UnicodeRange(0X0213, 0X0213),
    UnicodeRange(0X0215, 0X0215),
    UnicodeRange(0X0217, 0X0217),
    UnicodeRange(0X0219, 0X0219),
    UnicodeRange(0X021B, 0X021B),
    UnicodeRange(0X021D, 0X021D),
    UnicodeRange(0X021F, 0X021F),
    UnicodeRange(0X0221, 0X0221),
    UnicodeRange(0X0223, 0X0223),
    UnicodeRange(0X0225, 0X0225),
    UnicodeRange(0X0227, 0X0227),
    UnicodeRange(0X0229, 0X0229),
    UnicodeRange(0X022B, 0X022B),
    UnicodeRange(0X022D, 0X022D),
    UnicodeRange(0X022F, 0X022F),
    UnicodeRange(0X0231, 0X0231),
    UnicodeRange(0X0233, 0X0239),
    UnicodeRange(0X023C, 0X023C),
    UnicodeRange(0X023F, 0X0240),
    UnicodeRange(0X0242, 0X0242),
    UnicodeRange(0X0247, 0X0247),
    UnicodeRange(0X0249, 0X0249),
    UnicodeRange(0X024B, 0X024B),
    UnicodeRange(0X024D, 0X024D),
    UnicodeRange(0X024F, 0X0293),
    UnicodeRange(0X0295, 0X02AF),
    UnicodeRange(0X0371, 0X0371),
    UnicodeRange(0X0373, 0X0373),
    UnicodeRange(0X0377, 0X0377),
    UnicodeRange(0X037B, 0X037D),
    UnicodeRange(0X0390, 0X0390),
    UnicodeRange(0X03AC, 0X03CE),
    UnicodeRange(0X03D0, 0X03D1),
    UnicodeRange(0X03D5, 0X03D7),
    UnicodeRange(0X03D9, 0X03D9),
    UnicodeRange(0X03DB, 0X03DB),
    UnicodeRange(0X03DD, 0X03DD),
    UnicodeRange(0X03DF, 0X03DF),
    UnicodeRange(0X03E1, 0X03E1),
    UnicodeRange(0X03E3, 0X03E3),
    UnicodeRange(0X03E5, 0X03E5),
    UnicodeRange(0X03E7, 0X03E7),
    UnicodeRange(0X03E9, 0X03E9),
    UnicodeRange(0X03EB, 0X03EB),
    UnicodeRange(0X03ED, 0X03ED),
    UnicodeRange(0X03EF, 0X03F3),
    UnicodeRange(0X03F5, 0X03F5),
    UnicodeRange(0X03F8, 0X03F8),
    UnicodeRange(0X03FB, 0X03FC),
    UnicodeRange(0X0430, 0X045F),
    UnicodeRange(0X0461, 0X0461),
    UnicodeRange(0X0463, 0X0463),
    UnicodeRange(0X0465, 0X0465),
    UnicodeRange(0X0467, 0X0467),
    UnicodeRange(0X0469, 0X0469),
    UnicodeRange(0X046B, 0X046B),
    UnicodeRange(0X046D, 0X046D),
    UnicodeRange(0X046F, 0X046F),
    UnicodeRange(0X0471, 0X0471),
    UnicodeRange(0X0473, 0X0473),
    UnicodeRange(0X0475, 0X0475),
    UnicodeRange(0X0477, 0X0477),
    UnicodeRange(0X0479, 0X0479),
    UnicodeRange(0X047B, 0X047B),
    UnicodeRange(0X047D, 0X047D),
    UnicodeRange(0X047F, 0X047F),
    UnicodeRange(0X0481, 0X0481),
    UnicodeRange(0X048B, 0X048B),
    UnicodeRange(0X048D, 0X048D),
    UnicodeRange(0X048F, 0X048F),
    UnicodeRange(0X0491, 0X0491),
    UnicodeRange(0X0493, 0X0493),
    UnicodeRange(0X0495, 0X0495),
    UnicodeRange(0X0497, 0X0497),
    UnicodeRange(0X0499, 0X0499),
    UnicodeRange(0X049B, 0X049B),
    UnicodeRange(0X049D, 0X049D),
    UnicodeRange(0X049F, 0X049F),
    UnicodeRange(0X04A1, 0X04A1),
    UnicodeRange(0X04A3, 0X04A3),
    UnicodeRange(0X04A5, 0X04A5),
    UnicodeRange(0X04A7, 0X04A7),
    UnicodeRange(0X04A9, 0X04A9),
    UnicodeRange(0X04AB, 0X04AB),
    UnicodeRange(0X04AD, 0X04AD),
    UnicodeRange(0X04AF, 0X04AF),
    UnicodeRange(0X04B1, 0X04B1),
    UnicodeRange(0X04B3, 0X04B3),
    UnicodeRange(0X04B5, 0X04B5),
    UnicodeRange(0X04B7, 0X04B7),
    UnicodeRange(0X04B9, 0X04B9),
    UnicodeRange(0X04BB, 0X04BB),
    UnicodeRange(0X04BD, 0X04BD),
    UnicodeRange(0X04BF, 0X04BF),
    UnicodeRange(0X04C2, 0X04C2),
    UnicodeRange(0X04C4, 0X04C4),
    UnicodeRange(0X04C6, 0X04C6),
    UnicodeRange(0X04C8, 0X04C8),
    UnicodeRange(0X04CA, 0X04CA),
    UnicodeRange(0X04CC, 0X04CC),
    UnicodeRange(0X04CE, 0X04CF),
    UnicodeRange(0X04D1, 0X04D1),
    UnicodeRange(0X04D3, 0X04D3),
    UnicodeRange(0X04D5, 0X04D5),
    UnicodeRange(0X04D7, 0X04D7),
    UnicodeRange(0X04D9, 0X04D9),
    UnicodeRange(0X04DB, 0X04DB),
    UnicodeRange(0X04DD, 0X04DD),
    UnicodeRange(0X04DF, 0X04DF),
    UnicodeRange(0X04E1, 0X04E1),
    UnicodeRange(0X04E3, 0X04E3),
    UnicodeRange(0X04E5, 0X04E5),
    UnicodeRange(0X04E7, 0X04E7),
    UnicodeRange(0X04E9, 0X04E9),
    UnicodeRange(0X04EB, 0X04EB),
    UnicodeRange(0X04ED, 0X04ED),
    UnicodeRange(0X04EF, 0X04EF),
    UnicodeRange(0X04F1, 0X04F1),
    UnicodeRange(0X04F3, 0X04F3),
    UnicodeRange(0X04F5, 0X04F5),
    UnicodeRange(0X04F7, 0X04F7),
    UnicodeRange(0X04F9, 0X04F9),
    UnicodeRange(0X04FB, 0X04FB),
    UnicodeRange(0X04FD, 0X04FD),
    UnicodeRange(0X04FF, 0X04FF),
    UnicodeRange(0X0501, 0X0501),
    UnicodeRange(0X0503, 0X0503),
    UnicodeRange(0X0505, 0X0505),
    UnicodeRange(0X0507, 0X0507),
    UnicodeRange(0X0509, 0X0509),
    UnicodeRange(0X050B, 0X050B),
    UnicodeRange(0X050D, 0X050D),
    UnicodeRange(0X050F, 0X050F),
    UnicodeRange(0X0511, 0X0511),
    UnicodeRange(0X0513, 0X0513),
    UnicodeRange(0X0515, 0X0515),
    UnicodeRange(0X0517, 0X0517),
    UnicodeRange(0X0519, 0X0519),
    UnicodeRange(0X051B, 0X051B),
    UnicodeRange(0X051D, 0X051D),
    UnicodeRange(0X051F, 0X051F),
    UnicodeRange(0X0521, 0X0521),
    UnicodeRange(0X0523, 0X0523),
    UnicodeRange(0X0525, 0X0525),
    UnicodeRange(0X0527, 0X0527),
    UnicodeRange(0X0529, 0X0529),
    UnicodeRange(0X052B, 0X052B),
    UnicodeRange(0X052D, 0X052D),
    UnicodeRange(0X052F, 0X052F),
    UnicodeRange(0X0560, 0X0588),
    UnicodeRange(0X10D0, 0X10FA),
    UnicodeRange(0X10FD, 0X10FF),
    UnicodeRange(0X13F8, 0X13FD),
    UnicodeRange(0X1C80, 0X1C88),
    UnicodeRange(0X1D00, 0X1D2B),
    UnicodeRange(0X1D6B, 0X1D77),
    UnicodeRange(0X1D79, 0X1D9A),
    UnicodeRange(0X1E01, 0X1E01),
    UnicodeRange(0X1E03, 0X1E03),
    UnicodeRange(0X1E05, 0X1E05),
    UnicodeRange(0X1E07, 0X1E07),
    UnicodeRange(0X1E09, 0X1E09),
    UnicodeRange(0X1E0B, 0X1E0B),
    UnicodeRange(0X1E0D, 0X1E0D),
    UnicodeRange(0X1E0F, 0X1E0F),
    UnicodeRange(0X1E11, 0X1E11),
    UnicodeRange(0X1E13, 0X1E13),
    UnicodeRange(0X1E15, 0X1E15),
    UnicodeRange(0X1E17, 0X1E17),
    UnicodeRange(0X1E19, 0X1E19),
    UnicodeRange(0X1E1B, 0X1E1B),
    UnicodeRange(0X1E1D, 0X1E1D),
    UnicodeRange(0X1E1F, 0X1E1F),
    UnicodeRange(0X1E21, 0X1E21),
    UnicodeRange(0X1E23, 0X1E23),
    UnicodeRange(0X1E25, 0X1E25),
    UnicodeRange(0X1E27, 0X1E27),
    UnicodeRange(0X1E29, 0X1E29),
    UnicodeRange(0X1E2B, 0X1E2B),
    UnicodeRange(0X1E2D, 0X1E2D),
    UnicodeRange(0X1E2F, 0X1E2F),
    UnicodeRange(0X1E31, 0X1E31),
    UnicodeRange(0X1E33, 0X1E33),
    UnicodeRange(0X1E35, 0X1E35),
    UnicodeRange(0X1E37, 0X1E37),
    UnicodeRange(0X1E39, 0X1E39),
    UnicodeRange(0X1E3B, 0X1E3B),
    UnicodeRange(0X1E3D, 0X1E3D),
    UnicodeRange(0X1E3F, 0X1E3F),
    UnicodeRange(0X1E41, 0X1E41),
    UnicodeRange(0X1E43, 0X1E43),
    UnicodeRange(0X1E45, 0X1E45),
    UnicodeRange(0X1E47, 0X1E47),
    UnicodeRange(0X1E49, 0X1E49),
    UnicodeRange(0X1E4B, 0X1E4B),
    UnicodeRange(0X1E4D, 0X1E4D),
    UnicodeRange(0X1E4F, 0X1E4F),
    UnicodeRange(0X1E51, 0X1E51),
    UnicodeRange(0X1E53, 0X1E53),
    UnicodeRange(0X1E55, 0X1E55),
    UnicodeRange(0X1E57, 0X1E57),
    UnicodeRange(0X1E59, 0X1E59),
    UnicodeRange(0X1E5B, 0X1E5B),
    UnicodeRange(0X1E5D, 0X1E5D),
    UnicodeRange(0X1E5F, 0X1E5F),
    UnicodeRange(0X1E61, 0X1E61),
    UnicodeRange(0X1E63, 0X1E63),
    UnicodeRange(0X1E65, 0X1E65),
    UnicodeRange(0X1E67, 0X1E67),
    UnicodeRange(0X1E69, 0X1E69),
    UnicodeRange(0X1E6B, 0X1E6B),
    UnicodeRange(0X1E6D, 0X1E6D),
    UnicodeRange(0X1E6F, 0X1E6F),
    UnicodeRange(0X1E71, 0X1E71),
    UnicodeRange(0X1E73, 0X1E73),
    UnicodeRange(0X1E75, 0X1E75),
    UnicodeRange(0X1E77, 0X1E77),
    UnicodeRange(0X1E79, 0X1E79),
    UnicodeRange(0X1E7B, 0X1E7B),
    UnicodeRange(0X1E7D, 0X1E7D),
    UnicodeRange(0X1E7F, 0X1E7F),
    UnicodeRange(0X1E81, 0X1E81),
    UnicodeRange(0X1E83, 0X1E83),
    UnicodeRange(0X1E85, 0X1E85),
    UnicodeRange(0X1E87, 0X1E87),
    UnicodeRange(0X1E89, 0X1E89),
    UnicodeRange(0X1E8B, 0X1E8B),
    UnicodeRange(0X1E8D, 0X1E8D),
    UnicodeRange(0X1E8F, 0X1E8F),
    UnicodeRange(0X1E91, 0X1E91),
    UnicodeRange(0X1E93, 0X1E93),
    UnicodeRange(0X1E95, 0X1E9D),
    UnicodeRange(0X1E9F, 0X1E9F),
    UnicodeRange(0X1EA1, 0X1EA1),
    UnicodeRange(0X1EA3, 0X1EA3),
    UnicodeRange(0X1EA5, 0X1EA5),
    UnicodeRange(0X1EA7, 0X1EA7),
    UnicodeRange(0X1EA9, 0X1EA9),
    UnicodeRange(0X1EAB, 0X1EAB),
    UnicodeRange(0X1EAD, 0X1EAD),
    UnicodeRange(0X1EAF, 0X1EAF),
    UnicodeRange(0X1EB1, 0X1EB1),
    UnicodeRange(0X1EB3, 0X1EB3),
    UnicodeRange(0X1EB5, 0X1EB5),
    UnicodeRange(0X1EB7, 0X1EB7),
    UnicodeRange(0X1EB9, 0X1EB9),
    UnicodeRange(0X1EBB, 0X1EBB),
    UnicodeRange(0X1EBD, 0X1EBD),
    UnicodeRange(0X1EBF, 0X1EBF),
    UnicodeRange(0X1EC1, 0X1EC1),
    UnicodeRange(0X1EC3, 0X1EC3),
    UnicodeRange(0X1EC5, 0X1EC5),
    UnicodeRange(0X1EC7, 0X1EC7),
    UnicodeRange(0X1EC9, 0X1EC9),
    UnicodeRange(0X1ECB, 0X1ECB),
    UnicodeRange(0X1ECD, 0X1ECD),
    UnicodeRange(0X1ECF, 0X1ECF),
    UnicodeRange(0X1ED1, 0X1ED1),
    UnicodeRange(0X1ED3, 0X1ED3),
    UnicodeRange(0X1ED5, 0X1ED5),
    UnicodeRange(0X1ED7, 0X1ED7),
    UnicodeRange(0X1ED9, 0X1ED9),
    UnicodeRange(0X1EDB, 0X1EDB),
    UnicodeRange(0X1EDD, 0X1EDD),
    UnicodeRange(0X1EDF, 0X1EDF),
    UnicodeRange(0X1EE1, 0X1EE1),
    UnicodeRange(0X1EE3, 0X1EE3),
    UnicodeRange(0X1EE5, 0X1EE5),
    UnicodeRange(0X1EE7, 0X1EE7),
    UnicodeRange(0X1EE9, 0X1EE9),
    UnicodeRange(0X1EEB, 0X1EEB),
    UnicodeRange(0X1EED, 0X1EED),
    UnicodeRange(0X1EEF, 0X1EEF),
    UnicodeRange(0X1EF1, 0X1EF1),
    UnicodeRange(0X1EF3, 0X1EF3),
    UnicodeRange(0X1EF5, 0X1EF5),
    UnicodeRange(0X1EF7, 0X1EF7),
    UnicodeRange(0X1EF9, 0X1EF9),
    UnicodeRange(0X1EFB, 0X1EFB),
    UnicodeRange(0X1EFD, 0X1EFD),
    UnicodeRange(0X1EFF, 0X1F07),
    UnicodeRange(0X1F10, 0X1F15),
    UnicodeRange(0X1F20, 0X1F27),
    UnicodeRange(0X1F30, 0X1F37),
    UnicodeRange(0X1F40, 0X1F45),
    UnicodeRange(0X1F50, 0X1F57),
    UnicodeRange(0X1F60, 0X1F67),
    UnicodeRange(0X1F70, 0X1F7D),
    UnicodeRange(0X1F80, 0X1F87),
    UnicodeRange(0X1F90, 0X1F97),
    UnicodeRange(0X1FA0, 0X1FA7),
    UnicodeRange(0X1FB0, 0X1FB4),
    UnicodeRange(0X1FB6, 0X1FB7),
    UnicodeRange(0X1FBE, 0X1FBE),
    UnicodeRange(0X1FC2, 0X1FC4),
    UnicodeRange(0X1FC6, 0X1FC7),
    UnicodeRange(0X1FD0, 0X1FD3),
    UnicodeRange(0X1FD6, 0X1FD7),
    UnicodeRange(0X1FE0, 0X1FE7),
    UnicodeRange(0X1FF2, 0X1FF4),
    UnicodeRange(0X1FF6, 0X1FF7),
    UnicodeRange(0X210A, 0X210A),
    UnicodeRange(0X210E, 0X210F),
    UnicodeRange(0X2113, 0X2113),
    UnicodeRange(0X212F, 0X212F),
    UnicodeRange(0X2134, 0X2134),
    UnicodeRange(0X2139, 0X2139),
    UnicodeRange(0X213C, 0X213D),
    UnicodeRange(0X2146, 0X2149),
    UnicodeRange(0X214E, 0X214E),
    UnicodeRange(0X2184, 0X2184),
    UnicodeRange(0X2C30, 0X2C5E),
    UnicodeRange(0X2C61, 0X2C61),
    UnicodeRange(0X2C65, 0X2C66),
    UnicodeRange(0X2C68, 0X2C68),
    UnicodeRange(0X2C6A, 0X2C6A),
    UnicodeRange(0X2C6C, 0X2C6C),
    UnicodeRange(0X2C71, 0X2C71),
    UnicodeRange(0X2C73, 0X2C74),
    UnicodeRange(0X2C76, 0X2C7B),
    UnicodeRange(0X2C81, 0X2C81),
    UnicodeRange(0X2C83, 0X2C83),
    UnicodeRange(0X2C85, 0X2C85),
    UnicodeRange(0X2C87, 0X2C87),
    UnicodeRange(0X2C89, 0X2C89),
    UnicodeRange(0X2C8B, 0X2C8B),
    UnicodeRange(0X2C8D, 0X2C8D),
    UnicodeRange(0X2C8F, 0X2C8F),
    UnicodeRange(0X2C91, 0X2C91),
    UnicodeRange(0X2C93, 0X2C93),
    UnicodeRange(0X2C95, 0X2C95),
    UnicodeRange(0X2C97, 0X2C97),
    UnicodeRange(0X2C99, 0X2C99),
    UnicodeRange(0X2C9B, 0X2C9B),
    UnicodeRange(0X2C9D, 0X2C9D),
    UnicodeRange(0X2C9F, 0X2C9F),
    UnicodeRange(0X2CA1, 0X2CA1),
    UnicodeRange(0X2CA3, 0X2CA3),
    UnicodeRange(0X2CA5, 0X2CA5),
    UnicodeRange(0X2CA7, 0X2CA7),
    UnicodeRange(0X2CA9, 0X2CA9),
    UnicodeRange(0X2CAB, 0X2CAB),
    UnicodeRange(0X2CAD, 0X2CAD),
    UnicodeRange(0X2CAF, 0X2CAF),
    UnicodeRange(0X2CB1, 0X2CB1),
    UnicodeRange(0X2CB3, 0X2CB3),
    UnicodeRange(0X2CB5, 0X2CB5),
    UnicodeRange(0X2CB7, 0X2CB7),
    UnicodeRange(0X2CB9, 0X2CB9),
    UnicodeRange(0X2CBB, 0X2CBB),
    UnicodeRange(0X2CBD, 0X2CBD),
    UnicodeRange(0X2CBF, 0X2CBF),
    UnicodeRange(0X2CC1, 0X2CC1),
    UnicodeRange(0X2CC3, 0X2CC3),
    UnicodeRange(0X2CC5, 0X2CC5),
    UnicodeRange(0X2CC7, 0X2CC7),
    UnicodeRange(0X2CC9, 0X2CC9),
    UnicodeRange(0X2CCB, 0X2CCB),
    UnicodeRange(0X2CCD, 0X2CCD),
    UnicodeRange(0X2CCF, 0X2CCF),
    UnicodeRange(0X2CD1, 0X2CD1),
    UnicodeRange(0X2CD3, 0X2CD3),
    UnicodeRange(0X2CD5, 0X2CD5),
    UnicodeRange(0X2CD7, 0X2CD7),
    UnicodeRange(0X2CD9, 0X2CD9),
    UnicodeRange(0X2CDB, 0X2CDB),
    UnicodeRange(0X2CDD, 0X2CDD),
    UnicodeRange(0X2CDF, 0X2CDF),
    UnicodeRange(0X2CE1, 0X2CE1),
    UnicodeRange(0X2CE3, 0X2CE4),
    UnicodeRange(0X2CEC, 0X2CEC),
    UnicodeRange(0X2CEE, 0X2CEE),
    UnicodeRange(0X2CF3, 0X2CF3),
    UnicodeRange(0X2D00, 0X2D25),
    UnicodeRange(0X2D27, 0X2D27),
    UnicodeRange(0X2D2D, 0X2D2D),
    UnicodeRange(0XA641, 0XA641),
    UnicodeRange(0XA643, 0XA643),
    UnicodeRange(0XA645, 0XA645),
    UnicodeRange(0XA647, 0XA647),
    UnicodeRange(0XA649, 0XA649),
    UnicodeRange(0XA64B, 0XA64B),
    UnicodeRange(0XA64D, 0XA64D),
    UnicodeRange(0XA64F, 0XA64F),
    UnicodeRange(0XA651, 0XA651),
    UnicodeRange(0XA653, 0XA653),
    UnicodeRange(0XA655, 0XA655),
    UnicodeRange(0XA657, 0XA657),
    UnicodeRange(0XA659, 0XA659),
    UnicodeRange(0XA65B, 0XA65B),
    UnicodeRange(0XA65D, 0XA65D),
    UnicodeRange(0XA65F, 0XA65F),
    UnicodeRange(0XA661, 0XA661),
    UnicodeRange(0XA663, 0XA663),
    UnicodeRange(0XA665, 0XA665),
    UnicodeRange(0XA667, 0XA667),
    UnicodeRange(0XA669, 0XA669),
    UnicodeRange(0XA66B, 0XA66B),
    UnicodeRange(0XA66D, 0XA66D),
    UnicodeRange(0XA681, 0XA681),
    UnicodeRange(0XA683, 0XA683),
    UnicodeRange(0XA685, 0XA685),
    UnicodeRange(0XA687, 0XA687),
    UnicodeRange(0XA689, 0XA689),
    UnicodeRange(0XA68B, 0XA68B),
    UnicodeRange(0XA68D, 0XA68D),
    UnicodeRange(0XA68F, 0XA68F),
    UnicodeRange(0XA691, 0XA691),
    UnicodeRange(0XA693, 0XA693),
    UnicodeRange(0XA695, 0XA695),
    UnicodeRange(0XA697, 0XA697),
    UnicodeRange(0XA699, 0XA699),
    UnicodeRange(0XA69B, 0XA69B),
    UnicodeRange(0XA723, 0XA723),
    UnicodeRange(0XA725, 0XA725),
    UnicodeRange(0XA727, 0XA727),
    UnicodeRange(0XA729, 0XA729),
    UnicodeRange(0XA72B, 0XA72B),
    UnicodeRange(0XA72D, 0XA72D),
    UnicodeRange(0XA72F, 0XA731),
    UnicodeRange(0XA733, 0XA733),
    UnicodeRange(0XA735, 0XA735),
    UnicodeRange(0XA737, 0XA737),
    UnicodeRange(0XA739, 0XA739),
    UnicodeRange(0XA73B, 0XA73B),
    UnicodeRange(0XA73D, 0XA73D),
    UnicodeRange(0XA73F, 0XA73F),
    UnicodeRange(0XA741, 0XA741),
    UnicodeRange(0XA743, 0XA743),
    UnicodeRange(0XA745, 0XA745),
    UnicodeRange(0XA747, 0XA747),
    UnicodeRange(0XA749, 0XA749),
    UnicodeRange(0XA74B, 0XA74B),
    UnicodeRange(0XA74D, 0XA74D),
    UnicodeRange(0XA74F, 0XA74F),
    UnicodeRange(0XA751, 0XA751),
    UnicodeRange(0XA753, 0XA753),
    UnicodeRange(0XA755, 0XA755),
    UnicodeRange(0XA757, 0XA757),
    UnicodeRange(0XA759, 0XA759),
    UnicodeRange(0XA75B, 0XA75B),
    UnicodeRange(0XA75D, 0XA75D),
    UnicodeRange(0XA75F, 0XA75F),
    UnicodeRange(0XA761, 0XA761),
    UnicodeRange(0XA763, 0XA763),
    UnicodeRange(0XA765, 0XA765),
    UnicodeRange(0XA767, 0XA767),
    UnicodeRange(0XA769, 0XA769),
    UnicodeRange(0XA76B, 0XA76B),
    UnicodeRange(0XA76D, 0XA76D),
    UnicodeRange(0XA76F, 0XA76F),
    UnicodeRange(0XA771, 0XA778),
    UnicodeRange(0XA77A, 0XA77A),
    UnicodeRange(0XA77C, 0XA77C),
    UnicodeRange(0XA77F, 0XA77F),
    UnicodeRange(0XA781, 0XA781),
    UnicodeRange(0XA783, 0XA783),
    UnicodeRange(0XA785, 0XA785),
    UnicodeRange(0XA787, 0XA787),
    UnicodeRange(0XA78C, 0XA78C),
    UnicodeRange(0XA78E, 0XA78E),
    UnicodeRange(0XA791, 0XA791),
    UnicodeRange(0XA793, 0XA795),
    UnicodeRange(0XA797, 0XA797),
    UnicodeRange(0XA799, 0XA799),
    UnicodeRange(0XA79B, 0XA79B),
    UnicodeRange(0XA79D, 0XA79D),
    UnicodeRange(0XA79F, 0XA79F),
    UnicodeRange(0XA7A1, 0XA7A1),
    UnicodeRange(0XA7A3, 0XA7A3),
    UnicodeRange(0XA7A5, 0XA7A5),
    UnicodeRange(0XA7A7, 0XA7A7),
    UnicodeRange(0XA7A9, 0XA7A9),
    UnicodeRange(0XA7AF, 0XA7AF),
    UnicodeRange(0XA7B5, 0XA7B5),
    UnicodeRange(0XA7B7, 0XA7B7),
    UnicodeRange(0XA7B9, 0XA7B9),
    UnicodeRange(0XA7BB, 0XA7BB),
    UnicodeRange(0XA7BD, 0XA7BD),
    UnicodeRange(0XA7BF, 0XA7BF),
    UnicodeRange(0XA7C3, 0XA7C3),
    UnicodeRange(0XA7C8, 0XA7C8),
    UnicodeRange(0XA7CA, 0XA7CA),
    UnicodeRange(0XA7F6, 0XA7F6),
    UnicodeRange(0XA7FA, 0XA7FA),
    UnicodeRange(0XAB30, 0XAB5A),
    UnicodeRange(0XAB60, 0XAB68),
    UnicodeRange(0XAB70, 0XABBF),
    UnicodeRange(0XFB00, 0XFB06),
    UnicodeRange(0XFB13, 0XFB17),
    UnicodeRange(0XFF41, 0XFF5A),
    UnicodeRange(0X10428, 0X1044F),
    UnicodeRange(0X104D8, 0X104FB),
    UnicodeRange(0X10CC0, 0X10CF2),
    UnicodeRange(0X118C0, 0X118DF),
    UnicodeRange(0X16E60, 0X16E7F),
    UnicodeRange(0X1D41A, 0X1D433),
    UnicodeRange(0X1D44E, 0X1D454),
    UnicodeRange(0X1D456, 0X1D467),
    UnicodeRange(0X1D482, 0X1D49B),
    UnicodeRange(0X1D4B6, 0X1D4B9),
    UnicodeRange(0X1D4BB, 0X1D4BB),
    UnicodeRange(0X1D4BD, 0X1D4C3),
    UnicodeRange(0X1D4C5, 0X1D4CF),
    UnicodeRange(0X1D4EA, 0X1D503),
    UnicodeRange(0X1D51E, 0X1D537),
    UnicodeRange(0X1D552, 0X1D56B),
    UnicodeRange(0X1D586, 0X1D59F),
    UnicodeRange(0X1D5BA, 0X1D5D3),
    UnicodeRange(0X1D5EE, 0X1D607),
    UnicodeRange(0X1D622, 0X1D63B),
    UnicodeRange(0X1D656, 0X1D66F),
    UnicodeRange(0X1D68A, 0X1D6A5),
    UnicodeRange(0X1D6C2, 0X1D6DA),
    UnicodeRange(0X1D6DC, 0X1D6E1),
    UnicodeRange(0X1D6FC, 0X1D714),
    UnicodeRange(0X1D716, 0X1D71B),
    UnicodeRange(0X1D736, 0X1D74E),
    UnicodeRange(0X1D750, 0X1D755),
    UnicodeRange(0X1D770, 0X1D788),
    UnicodeRange(0X1D78A, 0X1D78F),
    UnicodeRange(0X1D7AA, 0X1D7C2),
    UnicodeRange(0X1D7C4, 0X1D7C9),
    UnicodeRange(0X1D7CB, 0X1D7CB),
    UnicodeRange(0X1E922, 0X1E943)
]
let OTHER_LOWER_CASE: Array<UnicodeRange> = [
    UnicodeRange(0X00AA, 0X00AA),
    UnicodeRange(0X00BA, 0X00BA),
    UnicodeRange(0X02B0, 0X02B8),
    UnicodeRange(0X02C0, 0X02C1),
    UnicodeRange(0X02E0, 0X02E4),
    UnicodeRange(0X0345, 0X0345),
    UnicodeRange(0X037A, 0X037A),
    UnicodeRange(0X1D2C, 0X1D6A),
    UnicodeRange(0X1D78, 0X1D78),
    UnicodeRange(0X1D9B, 0X1DBF),
    UnicodeRange(0X2071, 0X2071),
    UnicodeRange(0X207F, 0X207F),
    UnicodeRange(0X2090, 0X209C),
    UnicodeRange(0X2170, 0X217F),
    UnicodeRange(0X24D0, 0X24E9),
    UnicodeRange(0X2C7C, 0X2C7D),
    UnicodeRange(0XA69C, 0XA69D),
    UnicodeRange(0XA770, 0XA770),
    UnicodeRange(0XA7F8, 0XA7F9),
    UnicodeRange(0XAB5C, 0XAB5F)
]
let UPPER_CASE_LETTER: Array<UnicodeRange> = [
    UnicodeRange(0X0041, 0X005A),
    UnicodeRange(0X00C0, 0X00D6),
    UnicodeRange(0X00D8, 0X00DE),
    UnicodeRange(0X0100, 0X0100),
    UnicodeRange(0X0102, 0X0102),
    UnicodeRange(0X0104, 0X0104),
    UnicodeRange(0X0106, 0X0106),
    UnicodeRange(0X0108, 0X0108),
    UnicodeRange(0X010A, 0X010A),
    UnicodeRange(0X010C, 0X010C),
    UnicodeRange(0X010E, 0X010E),
    UnicodeRange(0X0110, 0X0110),
    UnicodeRange(0X0112, 0X0112),
    UnicodeRange(0X0114, 0X0114),
    UnicodeRange(0X0116, 0X0116),
    UnicodeRange(0X0118, 0X0118),
    UnicodeRange(0X011A, 0X011A),
    UnicodeRange(0X011C, 0X011C),
    UnicodeRange(0X011E, 0X011E),
    UnicodeRange(0X0120, 0X0120),
    UnicodeRange(0X0122, 0X0122),
    UnicodeRange(0X0124, 0X0124),
    UnicodeRange(0X0126, 0X0126),
    UnicodeRange(0X0128, 0X0128),
    UnicodeRange(0X012A, 0X012A),
    UnicodeRange(0X012C, 0X012C),
    UnicodeRange(0X012E, 0X012E),
    UnicodeRange(0X0130, 0X0130),
    UnicodeRange(0X0132, 0X0132),
    UnicodeRange(0X0134, 0X0134),
    UnicodeRange(0X0136, 0X0136),
    UnicodeRange(0X0139, 0X0139),
    UnicodeRange(0X013B, 0X013B),
    UnicodeRange(0X013D, 0X013D),
    UnicodeRange(0X013F, 0X013F),
    UnicodeRange(0X0141, 0X0141),
    UnicodeRange(0X0143, 0X0143),
    UnicodeRange(0X0145, 0X0145),
    UnicodeRange(0X0147, 0X0147),
    UnicodeRange(0X014A, 0X014A),
    UnicodeRange(0X014C, 0X014C),
    UnicodeRange(0X014E, 0X014E),
    UnicodeRange(0X0150, 0X0150),
    UnicodeRange(0X0152, 0X0152),
    UnicodeRange(0X0154, 0X0154),
    UnicodeRange(0X0156, 0X0156),
    UnicodeRange(0X0158, 0X0158),
    UnicodeRange(0X015A, 0X015A),
    UnicodeRange(0X015C, 0X015C),
    UnicodeRange(0X015E, 0X015E),
    UnicodeRange(0X0160, 0X0160),
    UnicodeRange(0X0162, 0X0162),
    UnicodeRange(0X0164, 0X0164),
    UnicodeRange(0X0166, 0X0166),
    UnicodeRange(0X0168, 0X0168),
    UnicodeRange(0X016A, 0X016A),
    UnicodeRange(0X016C, 0X016C),
    UnicodeRange(0X016E, 0X016E),
    UnicodeRange(0X0170, 0X0170),
    UnicodeRange(0X0172, 0X0172),
    UnicodeRange(0X0174, 0X0174),
    UnicodeRange(0X0176, 0X0176),
    UnicodeRange(0X0178, 0X0179),
    UnicodeRange(0X017B, 0X017B),
    UnicodeRange(0X017D, 0X017D),
    UnicodeRange(0X0181, 0X0182),
    UnicodeRange(0X0184, 0X0184),
    UnicodeRange(0X0186, 0X0187),
    UnicodeRange(0X0189, 0X018B),
    UnicodeRange(0X018E, 0X0191),
    UnicodeRange(0X0193, 0X0194),
    UnicodeRange(0X0196, 0X0198),
    UnicodeRange(0X019C, 0X019D),
    UnicodeRange(0X019F, 0X01A0),
    UnicodeRange(0X01A2, 0X01A2),
    UnicodeRange(0X01A4, 0X01A4),
    UnicodeRange(0X01A6, 0X01A7),
    UnicodeRange(0X01A9, 0X01A9),
    UnicodeRange(0X01AC, 0X01AC),
    UnicodeRange(0X01AE, 0X01AF),
    UnicodeRange(0X01B1, 0X01B3),
    UnicodeRange(0X01B5, 0X01B5),
    UnicodeRange(0X01B7, 0X01B8),
    UnicodeRange(0X01BC, 0X01BC),
    UnicodeRange(0X01C4, 0X01C4),
    UnicodeRange(0X01C7, 0X01C7),
    UnicodeRange(0X01CA, 0X01CA),
    UnicodeRange(0X01CD, 0X01CD),
    UnicodeRange(0X01CF, 0X01CF),
    UnicodeRange(0X01D1, 0X01D1),
    UnicodeRange(0X01D3, 0X01D3),
    UnicodeRange(0X01D5, 0X01D5),
    UnicodeRange(0X01D7, 0X01D7),
    UnicodeRange(0X01D9, 0X01D9),
    UnicodeRange(0X01DB, 0X01DB),
    UnicodeRange(0X01DE, 0X01DE),
    UnicodeRange(0X01E0, 0X01E0),
    UnicodeRange(0X01E2, 0X01E2),
    UnicodeRange(0X01E4, 0X01E4),
    UnicodeRange(0X01E6, 0X01E6),
    UnicodeRange(0X01E8, 0X01E8),
    UnicodeRange(0X01EA, 0X01EA),
    UnicodeRange(0X01EC, 0X01EC),
    UnicodeRange(0X01EE, 0X01EE),
    UnicodeRange(0X01F1, 0X01F1),
    UnicodeRange(0X01F4, 0X01F4),
    UnicodeRange(0X01F6, 0X01F8),
    UnicodeRange(0X01FA, 0X01FA),
    UnicodeRange(0X01FC, 0X01FC),
    UnicodeRange(0X01FE, 0X01FE),
    UnicodeRange(0X0200, 0X0200),
    UnicodeRange(0X0202, 0X0202),
    UnicodeRange(0X0204, 0X0204),
    UnicodeRange(0X0206, 0X0206),
    UnicodeRange(0X0208, 0X0208),
    UnicodeRange(0X020A, 0X020A),
    UnicodeRange(0X020C, 0X020C),
    UnicodeRange(0X020E, 0X020E),
    UnicodeRange(0X0210, 0X0210),
    UnicodeRange(0X0212, 0X0212),
    UnicodeRange(0X0214, 0X0214),
    UnicodeRange(0X0216, 0X0216),
    UnicodeRange(0X0218, 0X0218),
    UnicodeRange(0X021A, 0X021A),
    UnicodeRange(0X021C, 0X021C),
    UnicodeRange(0X021E, 0X021E),
    UnicodeRange(0X0220, 0X0220),
    UnicodeRange(0X0222, 0X0222),
    UnicodeRange(0X0224, 0X0224),
    UnicodeRange(0X0226, 0X0226),
    UnicodeRange(0X0228, 0X0228),
    UnicodeRange(0X022A, 0X022A),
    UnicodeRange(0X022C, 0X022C),
    UnicodeRange(0X022E, 0X022E),
    UnicodeRange(0X0230, 0X0230),
    UnicodeRange(0X0232, 0X0232),
    UnicodeRange(0X023A, 0X023B),
    UnicodeRange(0X023D, 0X023E),
    UnicodeRange(0X0241, 0X0241),
    UnicodeRange(0X0243, 0X0246),
    UnicodeRange(0X0248, 0X0248),
    UnicodeRange(0X024A, 0X024A),
    UnicodeRange(0X024C, 0X024C),
    UnicodeRange(0X024E, 0X024E),
    UnicodeRange(0X0370, 0X0370),
    UnicodeRange(0X0372, 0X0372),
    UnicodeRange(0X0376, 0X0376),
    UnicodeRange(0X037F, 0X037F),
    UnicodeRange(0X0386, 0X0386),
    UnicodeRange(0X0388, 0X038A),
    UnicodeRange(0X038C, 0X038C),
    UnicodeRange(0X038E, 0X038F),
    UnicodeRange(0X0391, 0X03A1),
    UnicodeRange(0X03A3, 0X03AB),
    UnicodeRange(0X03CF, 0X03CF),
    UnicodeRange(0X03D2, 0X03D4),
    UnicodeRange(0X03D8, 0X03D8),
    UnicodeRange(0X03DA, 0X03DA),
    UnicodeRange(0X03DC, 0X03DC),
    UnicodeRange(0X03DE, 0X03DE),
    UnicodeRange(0X03E0, 0X03E0),
    UnicodeRange(0X03E2, 0X03E2),
    UnicodeRange(0X03E4, 0X03E4),
    UnicodeRange(0X03E6, 0X03E6),
    UnicodeRange(0X03E8, 0X03E8),
    UnicodeRange(0X03EA, 0X03EA),
    UnicodeRange(0X03EC, 0X03EC),
    UnicodeRange(0X03EE, 0X03EE),
    UnicodeRange(0X03F4, 0X03F4),
    UnicodeRange(0X03F7, 0X03F7),
    UnicodeRange(0X03F9, 0X03FA),
    UnicodeRange(0X03FD, 0X042F),
    UnicodeRange(0X0460, 0X0460),
    UnicodeRange(0X0462, 0X0462),
    UnicodeRange(0X0464, 0X0464),
    UnicodeRange(0X0466, 0X0466),
    UnicodeRange(0X0468, 0X0468),
    UnicodeRange(0X046A, 0X046A),
    UnicodeRange(0X046C, 0X046C),
    UnicodeRange(0X046E, 0X046E),
    UnicodeRange(0X0470, 0X0470),
    UnicodeRange(0X0472, 0X0472),
    UnicodeRange(0X0474, 0X0474),
    UnicodeRange(0X0476, 0X0476),
    UnicodeRange(0X0478, 0X0478),
    UnicodeRange(0X047A, 0X047A),
    UnicodeRange(0X047C, 0X047C),
    UnicodeRange(0X047E, 0X047E),
    UnicodeRange(0X0480, 0X0480),
    UnicodeRange(0X048A, 0X048A),
    UnicodeRange(0X048C, 0X048C),
    UnicodeRange(0X048E, 0X048E),
    UnicodeRange(0X0490, 0X0490),
    UnicodeRange(0X0492, 0X0492),
    UnicodeRange(0X0494, 0X0494),
    UnicodeRange(0X0496, 0X0496),
    UnicodeRange(0X0498, 0X0498),
    UnicodeRange(0X049A, 0X049A),
    UnicodeRange(0X049C, 0X049C),
    UnicodeRange(0X049E, 0X049E),
    UnicodeRange(0X04A0, 0X04A0),
    UnicodeRange(0X04A2, 0X04A2),
    UnicodeRange(0X04A4, 0X04A4),
    UnicodeRange(0X04A6, 0X04A6),
    UnicodeRange(0X04A8, 0X04A8),
    UnicodeRange(0X04AA, 0X04AA),
    UnicodeRange(0X04AC, 0X04AC),
    UnicodeRange(0X04AE, 0X04AE),
    UnicodeRange(0X04B0, 0X04B0),
    UnicodeRange(0X04B2, 0X04B2),
    UnicodeRange(0X04B4, 0X04B4),
    UnicodeRange(0X04B6, 0X04B6),
    UnicodeRange(0X04B8, 0X04B8),
    UnicodeRange(0X04BA, 0X04BA),
    UnicodeRange(0X04BC, 0X04BC),
    UnicodeRange(0X04BE, 0X04BE),
    UnicodeRange(0X04C0, 0X04C1),
    UnicodeRange(0X04C3, 0X04C3),
    UnicodeRange(0X04C5, 0X04C5),
    UnicodeRange(0X04C7, 0X04C7),
    UnicodeRange(0X04C9, 0X04C9),
    UnicodeRange(0X04CB, 0X04CB),
    UnicodeRange(0X04CD, 0X04CD),
    UnicodeRange(0X04D0, 0X04D0),
    UnicodeRange(0X04D2, 0X04D2),
    UnicodeRange(0X04D4, 0X04D4),
    UnicodeRange(0X04D6, 0X04D6),
    UnicodeRange(0X04D8, 0X04D8),
    UnicodeRange(0X04DA, 0X04DA),
    UnicodeRange(0X04DC, 0X04DC),
    UnicodeRange(0X04DE, 0X04DE),
    UnicodeRange(0X04E0, 0X04E0),
    UnicodeRange(0X04E2, 0X04E2),
    UnicodeRange(0X04E4, 0X04E4),
    UnicodeRange(0X04E6, 0X04E6),
    UnicodeRange(0X04E8, 0X04E8),
    UnicodeRange(0X04EA, 0X04EA),
    UnicodeRange(0X04EC, 0X04EC),
    UnicodeRange(0X04EE, 0X04EE),
    UnicodeRange(0X04F0, 0X04F0),
    UnicodeRange(0X04F2, 0X04F2),
    UnicodeRange(0X04F4, 0X04F4),
    UnicodeRange(0X04F6, 0X04F6),
    UnicodeRange(0X04F8, 0X04F8),
    UnicodeRange(0X04FA, 0X04FA),
    UnicodeRange(0X04FC, 0X04FC),
    UnicodeRange(0X04FE, 0X04FE),
    UnicodeRange(0X0500, 0X0500),
    UnicodeRange(0X0502, 0X0502),
    UnicodeRange(0X0504, 0X0504),
    UnicodeRange(0X0506, 0X0506),
    UnicodeRange(0X0508, 0X0508),
    UnicodeRange(0X050A, 0X050A),
    UnicodeRange(0X050C, 0X050C),
    UnicodeRange(0X050E, 0X050E),
    UnicodeRange(0X0510, 0X0510),
    UnicodeRange(0X0512, 0X0512),
    UnicodeRange(0X0514, 0X0514),
    UnicodeRange(0X0516, 0X0516),
    UnicodeRange(0X0518, 0X0518),
    UnicodeRange(0X051A, 0X051A),
    UnicodeRange(0X051C, 0X051C),
    UnicodeRange(0X051E, 0X051E),
    UnicodeRange(0X0520, 0X0520),
    UnicodeRange(0X0522, 0X0522),
    UnicodeRange(0X0524, 0X0524),
    UnicodeRange(0X0526, 0X0526),
    UnicodeRange(0X0528, 0X0528),
    UnicodeRange(0X052A, 0X052A),
    UnicodeRange(0X052C, 0X052C),
    UnicodeRange(0X052E, 0X052E),
    UnicodeRange(0X0531, 0X0556),
    UnicodeRange(0X10A0, 0X10C5),
    UnicodeRange(0X10C7, 0X10C7),
    UnicodeRange(0X10CD, 0X10CD),
    UnicodeRange(0X13A0, 0X13F5),
    UnicodeRange(0X1C90, 0X1CBA),
    UnicodeRange(0X1CBD, 0X1CBF),
    UnicodeRange(0X1E00, 0X1E00),
    UnicodeRange(0X1E02, 0X1E02),
    UnicodeRange(0X1E04, 0X1E04),
    UnicodeRange(0X1E06, 0X1E06),
    UnicodeRange(0X1E08, 0X1E08),
    UnicodeRange(0X1E0A, 0X1E0A),
    UnicodeRange(0X1E0C, 0X1E0C),
    UnicodeRange(0X1E0E, 0X1E0E),
    UnicodeRange(0X1E10, 0X1E10),
    UnicodeRange(0X1E12, 0X1E12),
    UnicodeRange(0X1E14, 0X1E14),
    UnicodeRange(0X1E16, 0X1E16),
    UnicodeRange(0X1E18, 0X1E18),
    UnicodeRange(0X1E1A, 0X1E1A),
    UnicodeRange(0X1E1C, 0X1E1C),
    UnicodeRange(0X1E1E, 0X1E1E),
    UnicodeRange(0X1E20, 0X1E20),
    UnicodeRange(0X1E22, 0X1E22),
    UnicodeRange(0X1E24, 0X1E24),
    UnicodeRange(0X1E26, 0X1E26),
    UnicodeRange(0X1E28, 0X1E28),
    UnicodeRange(0X1E2A, 0X1E2A),
    UnicodeRange(0X1E2C, 0X1E2C),
    UnicodeRange(0X1E2E, 0X1E2E),
    UnicodeRange(0X1E30, 0X1E30),
    UnicodeRange(0X1E32, 0X1E32),
    UnicodeRange(0X1E34, 0X1E34),
    UnicodeRange(0X1E36, 0X1E36),
    UnicodeRange(0X1E38, 0X1E38),
    UnicodeRange(0X1E3A, 0X1E3A),
    UnicodeRange(0X1E3C, 0X1E3C),
    UnicodeRange(0X1E3E, 0X1E3E),
    UnicodeRange(0X1E40, 0X1E40),
    UnicodeRange(0X1E42, 0X1E42),
    UnicodeRange(0X1E44, 0X1E44),
    UnicodeRange(0X1E46, 0X1E46),
    UnicodeRange(0X1E48, 0X1E48),
    UnicodeRange(0X1E4A, 0X1E4A),
    UnicodeRange(0X1E4C, 0X1E4C),
    UnicodeRange(0X1E4E, 0X1E4E),
    UnicodeRange(0X1E50, 0X1E50),
    UnicodeRange(0X1E52, 0X1E52),
    UnicodeRange(0X1E54, 0X1E54),
    UnicodeRange(0X1E56, 0X1E56),
    UnicodeRange(0X1E58, 0X1E58),
    UnicodeRange(0X1E5A, 0X1E5A),
    UnicodeRange(0X1E5C, 0X1E5C),
    UnicodeRange(0X1E5E, 0X1E5E),
    UnicodeRange(0X1E60, 0X1E60),
    UnicodeRange(0X1E62, 0X1E62),
    UnicodeRange(0X1E64, 0X1E64),
    UnicodeRange(0X1E66, 0X1E66),
    UnicodeRange(0X1E68, 0X1E68),
    UnicodeRange(0X1E6A, 0X1E6A),
    UnicodeRange(0X1E6C, 0X1E6C),
    UnicodeRange(0X1E6E, 0X1E6E),
    UnicodeRange(0X1E70, 0X1E70),
    UnicodeRange(0X1E72, 0X1E72),
    UnicodeRange(0X1E74, 0X1E74),
    UnicodeRange(0X1E76, 0X1E76),
    UnicodeRange(0X1E78, 0X1E78),
    UnicodeRange(0X1E7A, 0X1E7A),
    UnicodeRange(0X1E7C, 0X1E7C),
    UnicodeRange(0X1E7E, 0X1E7E),
    UnicodeRange(0X1E80, 0X1E80),
    UnicodeRange(0X1E82, 0X1E82),
    UnicodeRange(0X1E84, 0X1E84),
    UnicodeRange(0X1E86, 0X1E86),
    UnicodeRange(0X1E88, 0X1E88),
    UnicodeRange(0X1E8A, 0X1E8A),
    UnicodeRange(0X1E8C, 0X1E8C),
    UnicodeRange(0X1E8E, 0X1E8E),
    UnicodeRange(0X1E90, 0X1E90),
    UnicodeRange(0X1E92, 0X1E92),
    UnicodeRange(0X1E94, 0X1E94),
    UnicodeRange(0X1E9E, 0X1E9E),
    UnicodeRange(0X1EA0, 0X1EA0),
    UnicodeRange(0X1EA2, 0X1EA2),
    UnicodeRange(0X1EA4, 0X1EA4),
    UnicodeRange(0X1EA6, 0X1EA6),
    UnicodeRange(0X1EA8, 0X1EA8),
    UnicodeRange(0X1EAA, 0X1EAA),
    UnicodeRange(0X1EAC, 0X1EAC),
    UnicodeRange(0X1EAE, 0X1EAE),
    UnicodeRange(0X1EB0, 0X1EB0),
    UnicodeRange(0X1EB2, 0X1EB2),
    UnicodeRange(0X1EB4, 0X1EB4),
    UnicodeRange(0X1EB6, 0X1EB6),
    UnicodeRange(0X1EB8, 0X1EB8),
    UnicodeRange(0X1EBA, 0X1EBA),
    UnicodeRange(0X1EBC, 0X1EBC),
    UnicodeRange(0X1EBE, 0X1EBE),
    UnicodeRange(0X1EC0, 0X1EC0),
    UnicodeRange(0X1EC2, 0X1EC2),
    UnicodeRange(0X1EC4, 0X1EC4),
    UnicodeRange(0X1EC6, 0X1EC6),
    UnicodeRange(0X1EC8, 0X1EC8),
    UnicodeRange(0X1ECA, 0X1ECA),
    UnicodeRange(0X1ECC, 0X1ECC),
    UnicodeRange(0X1ECE, 0X1ECE),
    UnicodeRange(0X1ED0, 0X1ED0),
    UnicodeRange(0X1ED2, 0X1ED2),
    UnicodeRange(0X1ED4, 0X1ED4),
    UnicodeRange(0X1ED6, 0X1ED6),
    UnicodeRange(0X1ED8, 0X1ED8),
    UnicodeRange(0X1EDA, 0X1EDA),
    UnicodeRange(0X1EDC, 0X1EDC),
    UnicodeRange(0X1EDE, 0X1EDE),
    UnicodeRange(0X1EE0, 0X1EE0),
    UnicodeRange(0X1EE2, 0X1EE2),
    UnicodeRange(0X1EE4, 0X1EE4),
    UnicodeRange(0X1EE6, 0X1EE6),
    UnicodeRange(0X1EE8, 0X1EE8),
    UnicodeRange(0X1EEA, 0X1EEA),
    UnicodeRange(0X1EEC, 0X1EEC),
    UnicodeRange(0X1EEE, 0X1EEE),
    UnicodeRange(0X1EF0, 0X1EF0),
    UnicodeRange(0X1EF2, 0X1EF2),
    UnicodeRange(0X1EF4, 0X1EF4),
    UnicodeRange(0X1EF6, 0X1EF6),
    UnicodeRange(0X1EF8, 0X1EF8),
    UnicodeRange(0X1EFA, 0X1EFA),
    UnicodeRange(0X1EFC, 0X1EFC),
    UnicodeRange(0X1EFE, 0X1EFE),
    UnicodeRange(0X1F08, 0X1F0F),
    UnicodeRange(0X1F18, 0X1F1D),
    UnicodeRange(0X1F28, 0X1F2F),
    UnicodeRange(0X1F38, 0X1F3F),
    UnicodeRange(0X1F48, 0X1F4D),
    UnicodeRange(0X1F59, 0X1F59),
    UnicodeRange(0X1F5B, 0X1F5B),
    UnicodeRange(0X1F5D, 0X1F5D),
    UnicodeRange(0X1F5F, 0X1F5F),
    UnicodeRange(0X1F68, 0X1F6F),
    UnicodeRange(0X1FB8, 0X1FBB),
    UnicodeRange(0X1FC8, 0X1FCB),
    UnicodeRange(0X1FD8, 0X1FDB),
    UnicodeRange(0X1FE8, 0X1FEC),
    UnicodeRange(0X1FF8, 0X1FFB),
    UnicodeRange(0X2102, 0X2102),
    UnicodeRange(0X2107, 0X2107),
    UnicodeRange(0X210B, 0X210D),
    UnicodeRange(0X2110, 0X2112),
    UnicodeRange(0X2115, 0X2115),
    UnicodeRange(0X2119, 0X211D),
    UnicodeRange(0X2124, 0X2124),
    UnicodeRange(0X2126, 0X2126),
    UnicodeRange(0X2128, 0X2128),
    UnicodeRange(0X212A, 0X212D),
    UnicodeRange(0X2130, 0X2133),
    UnicodeRange(0X213E, 0X213F),
    UnicodeRange(0X2145, 0X2145),
    UnicodeRange(0X2183, 0X2183),
    UnicodeRange(0X2C00, 0X2C2E),
    UnicodeRange(0X2C60, 0X2C60),
    UnicodeRange(0X2C62, 0X2C64),
    UnicodeRange(0X2C67, 0X2C67),
    UnicodeRange(0X2C69, 0X2C69),
    UnicodeRange(0X2C6B, 0X2C6B),
    UnicodeRange(0X2C6D, 0X2C70),
    UnicodeRange(0X2C72, 0X2C72),
    UnicodeRange(0X2C75, 0X2C75),
    UnicodeRange(0X2C7E, 0X2C80),
    UnicodeRange(0X2C82, 0X2C82),
    UnicodeRange(0X2C84, 0X2C84),
    UnicodeRange(0X2C86, 0X2C86),
    UnicodeRange(0X2C88, 0X2C88),
    UnicodeRange(0X2C8A, 0X2C8A),
    UnicodeRange(0X2C8C, 0X2C8C),
    UnicodeRange(0X2C8E, 0X2C8E),
    UnicodeRange(0X2C90, 0X2C90),
    UnicodeRange(0X2C92, 0X2C92),
    UnicodeRange(0X2C94, 0X2C94),
    UnicodeRange(0X2C96, 0X2C96),
    UnicodeRange(0X2C98, 0X2C98),
    UnicodeRange(0X2C9A, 0X2C9A),
    UnicodeRange(0X2C9C, 0X2C9C),
    UnicodeRange(0X2C9E, 0X2C9E),
    UnicodeRange(0X2CA0, 0X2CA0),
    UnicodeRange(0X2CA2, 0X2CA2),
    UnicodeRange(0X2CA4, 0X2CA4),
    UnicodeRange(0X2CA6, 0X2CA6),
    UnicodeRange(0X2CA8, 0X2CA8),
    UnicodeRange(0X2CAA, 0X2CAA),
    UnicodeRange(0X2CAC, 0X2CAC),
    UnicodeRange(0X2CAE, 0X2CAE),
    UnicodeRange(0X2CB0, 0X2CB0),
    UnicodeRange(0X2CB2, 0X2CB2),
    UnicodeRange(0X2CB4, 0X2CB4),
    UnicodeRange(0X2CB6, 0X2CB6),
    UnicodeRange(0X2CB8, 0X2CB8),
    UnicodeRange(0X2CBA, 0X2CBA),
    UnicodeRange(0X2CBC, 0X2CBC),
    UnicodeRange(0X2CBE, 0X2CBE),
    UnicodeRange(0X2CC0, 0X2CC0),
    UnicodeRange(0X2CC2, 0X2CC2),
    UnicodeRange(0X2CC4, 0X2CC4),
    UnicodeRange(0X2CC6, 0X2CC6),
    UnicodeRange(0X2CC8, 0X2CC8),
    UnicodeRange(0X2CCA, 0X2CCA),
    UnicodeRange(0X2CCC, 0X2CCC),
    UnicodeRange(0X2CCE, 0X2CCE),
    UnicodeRange(0X2CD0, 0X2CD0),
    UnicodeRange(0X2CD2, 0X2CD2),
    UnicodeRange(0X2CD4, 0X2CD4),
    UnicodeRange(0X2CD6, 0X2CD6),
    UnicodeRange(0X2CD8, 0X2CD8),
    UnicodeRange(0X2CDA, 0X2CDA),
    UnicodeRange(0X2CDC, 0X2CDC),
    UnicodeRange(0X2CDE, 0X2CDE),
    UnicodeRange(0X2CE0, 0X2CE0),
    UnicodeRange(0X2CE2, 0X2CE2),
    UnicodeRange(0X2CEB, 0X2CEB),
    UnicodeRange(0X2CED, 0X2CED),
    UnicodeRange(0X2CF2, 0X2CF2),
    UnicodeRange(0XA640, 0XA640),
    UnicodeRange(0XA642, 0XA642),
    UnicodeRange(0XA644, 0XA644),
    UnicodeRange(0XA646, 0XA646),
    UnicodeRange(0XA648, 0XA648),
    UnicodeRange(0XA64A, 0XA64A),
    UnicodeRange(0XA64C, 0XA64C),
    UnicodeRange(0XA64E, 0XA64E),
    UnicodeRange(0XA650, 0XA650),
    UnicodeRange(0XA652, 0XA652),
    UnicodeRange(0XA654, 0XA654),
    UnicodeRange(0XA656, 0XA656),
    UnicodeRange(0XA658, 0XA658),
    UnicodeRange(0XA65A, 0XA65A),
    UnicodeRange(0XA65C, 0XA65C),
    UnicodeRange(0XA65E, 0XA65E),
    UnicodeRange(0XA660, 0XA660),
    UnicodeRange(0XA662, 0XA662),
    UnicodeRange(0XA664, 0XA664),
    UnicodeRange(0XA666, 0XA666),
    UnicodeRange(0XA668, 0XA668),
    UnicodeRange(0XA66A, 0XA66A),
    UnicodeRange(0XA66C, 0XA66C),
    UnicodeRange(0XA680, 0XA680),
    UnicodeRange(0XA682, 0XA682),
    UnicodeRange(0XA684, 0XA684),
    UnicodeRange(0XA686, 0XA686),
    UnicodeRange(0XA688, 0XA688),
    UnicodeRange(0XA68A, 0XA68A),
    UnicodeRange(0XA68C, 0XA68C),
    UnicodeRange(0XA68E, 0XA68E),
    UnicodeRange(0XA690, 0XA690),
    UnicodeRange(0XA692, 0XA692),
    UnicodeRange(0XA694, 0XA694),
    UnicodeRange(0XA696, 0XA696),
    UnicodeRange(0XA698, 0XA698),
    UnicodeRange(0XA69A, 0XA69A),
    UnicodeRange(0XA722, 0XA722),
    UnicodeRange(0XA724, 0XA724),
    UnicodeRange(0XA726, 0XA726),
    UnicodeRange(0XA728, 0XA728),
    UnicodeRange(0XA72A, 0XA72A),
    UnicodeRange(0XA72C, 0XA72C),
    UnicodeRange(0XA72E, 0XA72E),
    UnicodeRange(0XA732, 0XA732),
    UnicodeRange(0XA734, 0XA734),
    UnicodeRange(0XA736, 0XA736),
    UnicodeRange(0XA738, 0XA738),
    UnicodeRange(0XA73A, 0XA73A),
    UnicodeRange(0XA73C, 0XA73C),
    UnicodeRange(0XA73E, 0XA73E),
    UnicodeRange(0XA740, 0XA740),
    UnicodeRange(0XA742, 0XA742),
    UnicodeRange(0XA744, 0XA744),
    UnicodeRange(0XA746, 0XA746),
    UnicodeRange(0XA748, 0XA748),
    UnicodeRange(0XA74A, 0XA74A),
    UnicodeRange(0XA74C, 0XA74C),
    UnicodeRange(0XA74E, 0XA74E),
    UnicodeRange(0XA750, 0XA750),
    UnicodeRange(0XA752, 0XA752),
    UnicodeRange(0XA754, 0XA754),
    UnicodeRange(0XA756, 0XA756),
    UnicodeRange(0XA758, 0XA758),
    UnicodeRange(0XA75A, 0XA75A),
    UnicodeRange(0XA75C, 0XA75C),
    UnicodeRange(0XA75E, 0XA75E),
    UnicodeRange(0XA760, 0XA760),
    UnicodeRange(0XA762, 0XA762),
    UnicodeRange(0XA764, 0XA764),
    UnicodeRange(0XA766, 0XA766),
    UnicodeRange(0XA768, 0XA768),
    UnicodeRange(0XA76A, 0XA76A),
    UnicodeRange(0XA76C, 0XA76C),
    UnicodeRange(0XA76E, 0XA76E),
    UnicodeRange(0XA779, 0XA779),
    UnicodeRange(0XA77B, 0XA77B),
    UnicodeRange(0XA77D, 0XA77E),
    UnicodeRange(0XA780, 0XA780),
    UnicodeRange(0XA782, 0XA782),
    UnicodeRange(0XA784, 0XA784),
    UnicodeRange(0XA786, 0XA786),
    UnicodeRange(0XA78B, 0XA78B),
    UnicodeRange(0XA78D, 0XA78D),
    UnicodeRange(0XA790, 0XA790),
    UnicodeRange(0XA792, 0XA792),
    UnicodeRange(0XA796, 0XA796),
    UnicodeRange(0XA798, 0XA798),
    UnicodeRange(0XA79A, 0XA79A),
    UnicodeRange(0XA79C, 0XA79C),
    UnicodeRange(0XA79E, 0XA79E),
    UnicodeRange(0XA7A0, 0XA7A0),
    UnicodeRange(0XA7A2, 0XA7A2),
    UnicodeRange(0XA7A4, 0XA7A4),
    UnicodeRange(0XA7A6, 0XA7A6),
    UnicodeRange(0XA7A8, 0XA7A8),
    UnicodeRange(0XA7AA, 0XA7AE),
    UnicodeRange(0XA7B0, 0XA7B4),
    UnicodeRange(0XA7B6, 0XA7B6),
    UnicodeRange(0XA7B8, 0XA7B8),
    UnicodeRange(0XA7BA, 0XA7BA),
    UnicodeRange(0XA7BC, 0XA7BC),
    UnicodeRange(0XA7BE, 0XA7BE),
    UnicodeRange(0XA7C2, 0XA7C2),
    UnicodeRange(0XA7C4, 0XA7C7),
    UnicodeRange(0XA7C9, 0XA7C9),
    UnicodeRange(0XA7F5, 0XA7F5),
    UnicodeRange(0XFF21, 0XFF3A),
    UnicodeRange(0X10400, 0X10427),
    UnicodeRange(0X104B0, 0X104D3),
    UnicodeRange(0X10C80, 0X10CB2),
    UnicodeRange(0X118A0, 0X118BF),
    UnicodeRange(0X16E40, 0X16E5F),
    UnicodeRange(0X1D400, 0X1D419),
    UnicodeRange(0X1D434, 0X1D44D),
    UnicodeRange(0X1D468, 0X1D481),
    UnicodeRange(0X1D49C, 0X1D49C),
    UnicodeRange(0X1D49E, 0X1D49F),
    UnicodeRange(0X1D4A2, 0X1D4A2),
    UnicodeRange(0X1D4A5, 0X1D4A6),
    UnicodeRange(0X1D4A9, 0X1D4AC),
    UnicodeRange(0X1D4AE, 0X1D4B5),
    UnicodeRange(0X1D4D0, 0X1D4E9),
    UnicodeRange(0X1D504, 0X1D505),
    UnicodeRange(0X1D507, 0X1D50A),
    UnicodeRange(0X1D50D, 0X1D514),
    UnicodeRange(0X1D516, 0X1D51C),
    UnicodeRange(0X1D538, 0X1D539),
    UnicodeRange(0X1D53B, 0X1D53E),
    UnicodeRange(0X1D540, 0X1D544),
    UnicodeRange(0X1D546, 0X1D546),
    UnicodeRange(0X1D54A, 0X1D550),
    UnicodeRange(0X1D56C, 0X1D585),
    UnicodeRange(0X1D5A0, 0X1D5B9),
    UnicodeRange(0X1D5D4, 0X1D5ED),
    UnicodeRange(0X1D608, 0X1D621),
    UnicodeRange(0X1D63C, 0X1D655),
    UnicodeRange(0X1D670, 0X1D689),
    UnicodeRange(0X1D6A8, 0X1D6C0),
    UnicodeRange(0X1D6E2, 0X1D6FA),
    UnicodeRange(0X1D71C, 0X1D734),
    UnicodeRange(0X1D756, 0X1D76E),
    UnicodeRange(0X1D790, 0X1D7A8),
    UnicodeRange(0X1D7CA, 0X1D7CA),
    UnicodeRange(0X1E900, 0X1E921)
]
let OTHER_UPPER_CASE: Array<UnicodeRange> = [
    UnicodeRange(0X2160, 0X216F),
    UnicodeRange(0X24B6, 0X24CF),
    UnicodeRange(0X1F130, 0X1F149),
    UnicodeRange(0X1F150, 0X1F169),
    UnicodeRange(0X1F170, 0X1F189)
]
let TITLE_CASE_LETTER: Array<UnicodeRange> = [
    UnicodeRange(0X01C5, 0X01C5),
    UnicodeRange(0X01C8, 0X01C8),
    UnicodeRange(0X01CB, 0X01CB),
    UnicodeRange(0X01F2, 0X01F2),
    UnicodeRange(0X1F88, 0X1F8F),
    UnicodeRange(0X1F98, 0X1F9F),
    UnicodeRange(0X1FA8, 0X1FAF),
    UnicodeRange(0X1FBC, 0X1FBC),
    UnicodeRange(0X1FCC, 0X1FCC),
    UnicodeRange(0X1FFC, 0X1FFC)
]
let MODIFIER_LETTER: Array<UnicodeRange> = [
    UnicodeRange(0X02B0, 0X02C1),
    UnicodeRange(0X02C6, 0X02D1),
    UnicodeRange(0X02E0, 0X02E4),
    UnicodeRange(0X02EC, 0X02EC),
    UnicodeRange(0X02EE, 0X02EE),
    UnicodeRange(0X0374, 0X0374),
    UnicodeRange(0X037A, 0X037A),
    UnicodeRange(0X0559, 0X0559),
    UnicodeRange(0X0640, 0X0640),
    UnicodeRange(0X06E5, 0X06E6),
    UnicodeRange(0X07F4, 0X07F5),
    UnicodeRange(0X07FA, 0X07FA),
    UnicodeRange(0X081A, 0X081A),
    UnicodeRange(0X0824, 0X0824),
    UnicodeRange(0X0828, 0X0828),
    UnicodeRange(0X0971, 0X0971),
    UnicodeRange(0X0E46, 0X0E46),
    UnicodeRange(0X0EC6, 0X0EC6),
    UnicodeRange(0X10FC, 0X10FC),
    UnicodeRange(0X17D7, 0X17D7),
    UnicodeRange(0X1843, 0X1843),
    UnicodeRange(0X1AA7, 0X1AA7),
    UnicodeRange(0X1C78, 0X1C7D),
    UnicodeRange(0X1D2C, 0X1D6A),
    UnicodeRange(0X1D78, 0X1D78),
    UnicodeRange(0X1D9B, 0X1DBF),
    UnicodeRange(0X2071, 0X2071),
    UnicodeRange(0X207F, 0X207F),
    UnicodeRange(0X2090, 0X209C),
    UnicodeRange(0X2C7C, 0X2C7D),
    UnicodeRange(0X2D6F, 0X2D6F),
    UnicodeRange(0X2E2F, 0X2E2F),
    UnicodeRange(0X3005, 0X3005),
    UnicodeRange(0X3031, 0X3035),
    UnicodeRange(0X303B, 0X303B),
    UnicodeRange(0X309D, 0X309E),
    UnicodeRange(0X30FC, 0X30FE),
    UnicodeRange(0XA015, 0XA015),
    UnicodeRange(0XA4F8, 0XA4FD),
    UnicodeRange(0XA60C, 0XA60C),
    UnicodeRange(0XA67F, 0XA67F),
    UnicodeRange(0XA69C, 0XA69D),
    UnicodeRange(0XA717, 0XA71F),
    UnicodeRange(0XA770, 0XA770),
    UnicodeRange(0XA788, 0XA788),
    UnicodeRange(0XA7F8, 0XA7F9),
    UnicodeRange(0XA9CF, 0XA9CF),
    UnicodeRange(0XA9E6, 0XA9E6),
    UnicodeRange(0XAA70, 0XAA70),
    UnicodeRange(0XAADD, 0XAADD),
    UnicodeRange(0XAAF3, 0XAAF4),
    UnicodeRange(0XAB5C, 0XAB5F),
    UnicodeRange(0XAB69, 0XAB69),
    UnicodeRange(0XFF70, 0XFF70),
    UnicodeRange(0XFF9E, 0XFF9F),
    UnicodeRange(0X16B40, 0X16B43),
    UnicodeRange(0X16F93, 0X16F9F),
    UnicodeRange(0X16FE0, 0X16FE1),
    UnicodeRange(0X16FE3, 0X16FE3),
    UnicodeRange(0X1E137, 0X1E13D),
    UnicodeRange(0X1E94B, 0X1E94B)
]
let OTHER_LETTER: Array<UnicodeRange> = [
    UnicodeRange(0X00AA, 0X00AA),
    UnicodeRange(0X00BA, 0X00BA),
    UnicodeRange(0X01BB, 0X01BB),
    UnicodeRange(0X01C0, 0X01C3),
    UnicodeRange(0X0294, 0X0294),
    UnicodeRange(0X05D0, 0X05EA),
    UnicodeRange(0X05EF, 0X05F2),
    UnicodeRange(0X0620, 0X063F),
    UnicodeRange(0X0641, 0X064A),
    UnicodeRange(0X066E, 0X066F),
    UnicodeRange(0X0671, 0X06D3),
    UnicodeRange(0X06D5, 0X06D5),
    UnicodeRange(0X06EE, 0X06EF),
    UnicodeRange(0X06FA, 0X06FC),
    UnicodeRange(0X06FF, 0X06FF),
    UnicodeRange(0X0710, 0X0710),
    UnicodeRange(0X0712, 0X072F),
    UnicodeRange(0X074D, 0X07A5),
    UnicodeRange(0X07B1, 0X07B1),
    UnicodeRange(0X07CA, 0X07EA),
    UnicodeRange(0X0800, 0X0815),
    UnicodeRange(0X0840, 0X0858),
    UnicodeRange(0X0860, 0X086A),
    UnicodeRange(0X08A0, 0X08B4),
    UnicodeRange(0X08B6, 0X08C7),
    UnicodeRange(0X0904, 0X0939),
    UnicodeRange(0X093D, 0X093D),
    UnicodeRange(0X0950, 0X0950),
    UnicodeRange(0X0958, 0X0961),
    UnicodeRange(0X0972, 0X0980),
    UnicodeRange(0X0985, 0X098C),
    UnicodeRange(0X098F, 0X0990),
    UnicodeRange(0X0993, 0X09A8),
    UnicodeRange(0X09AA, 0X09B0),
    UnicodeRange(0X09B2, 0X09B2),
    UnicodeRange(0X09B6, 0X09B9),
    UnicodeRange(0X09BD, 0X09BD),
    UnicodeRange(0X09CE, 0X09CE),
    UnicodeRange(0X09DC, 0X09DD),
    UnicodeRange(0X09DF, 0X09E1),
    UnicodeRange(0X09F0, 0X09F1),
    UnicodeRange(0X09FC, 0X09FC),
    UnicodeRange(0X0A05, 0X0A0A),
    UnicodeRange(0X0A0F, 0X0A10),
    UnicodeRange(0X0A13, 0X0A28),
    UnicodeRange(0X0A2A, 0X0A30),
    UnicodeRange(0X0A32, 0X0A33),
    UnicodeRange(0X0A35, 0X0A36),
    UnicodeRange(0X0A38, 0X0A39),
    UnicodeRange(0X0A59, 0X0A5C),
    UnicodeRange(0X0A5E, 0X0A5E),
    UnicodeRange(0X0A72, 0X0A74),
    UnicodeRange(0X0A85, 0X0A8D),
    UnicodeRange(0X0A8F, 0X0A91),
    UnicodeRange(0X0A93, 0X0AA8),
    UnicodeRange(0X0AAA, 0X0AB0),
    UnicodeRange(0X0AB2, 0X0AB3),
    UnicodeRange(0X0AB5, 0X0AB9),
    UnicodeRange(0X0ABD, 0X0ABD),
    UnicodeRange(0X0AD0, 0X0AD0),
    UnicodeRange(0X0AE0, 0X0AE1),
    UnicodeRange(0X0AF9, 0X0AF9),
    UnicodeRange(0X0B05, 0X0B0C),
    UnicodeRange(0X0B0F, 0X0B10),
    UnicodeRange(0X0B13, 0X0B28),
    UnicodeRange(0X0B2A, 0X0B30),
    UnicodeRange(0X0B32, 0X0B33),
    UnicodeRange(0X0B35, 0X0B39),
    UnicodeRange(0X0B3D, 0X0B3D),
    UnicodeRange(0X0B5C, 0X0B5D),
    UnicodeRange(0X0B5F, 0X0B61),
    UnicodeRange(0X0B71, 0X0B71),
    UnicodeRange(0X0B83, 0X0B83),
    UnicodeRange(0X0B85, 0X0B8A),
    UnicodeRange(0X0B8E, 0X0B90),
    UnicodeRange(0X0B92, 0X0B95),
    UnicodeRange(0X0B99, 0X0B9A),
    UnicodeRange(0X0B9C, 0X0B9C),
    UnicodeRange(0X0B9E, 0X0B9F),
    UnicodeRange(0X0BA3, 0X0BA4),
    UnicodeRange(0X0BA8, 0X0BAA),
    UnicodeRange(0X0BAE, 0X0BB9),
    UnicodeRange(0X0BD0, 0X0BD0),
    UnicodeRange(0X0C05, 0X0C0C),
    UnicodeRange(0X0C0E, 0X0C10),
    UnicodeRange(0X0C12, 0X0C28),
    UnicodeRange(0X0C2A, 0X0C39),
    UnicodeRange(0X0C3D, 0X0C3D),
    UnicodeRange(0X0C58, 0X0C5A),
    UnicodeRange(0X0C60, 0X0C61),
    UnicodeRange(0X0C80, 0X0C80),
    UnicodeRange(0X0C85, 0X0C8C),
    UnicodeRange(0X0C8E, 0X0C90),
    UnicodeRange(0X0C92, 0X0CA8),
    UnicodeRange(0X0CAA, 0X0CB3),
    UnicodeRange(0X0CB5, 0X0CB9),
    UnicodeRange(0X0CBD, 0X0CBD),
    UnicodeRange(0X0CDE, 0X0CDE),
    UnicodeRange(0X0CE0, 0X0CE1),
    UnicodeRange(0X0CF1, 0X0CF2),
    UnicodeRange(0X0D04, 0X0D0C),
    UnicodeRange(0X0D0E, 0X0D10),
    UnicodeRange(0X0D12, 0X0D3A),
    UnicodeRange(0X0D3D, 0X0D3D),
    UnicodeRange(0X0D4E, 0X0D4E),
    UnicodeRange(0X0D54, 0X0D56),
    UnicodeRange(0X0D5F, 0X0D61),
    UnicodeRange(0X0D7A, 0X0D7F),
    UnicodeRange(0X0D85, 0X0D96),
    UnicodeRange(0X0D9A, 0X0DB1),
    UnicodeRange(0X0DB3, 0X0DBB),
    UnicodeRange(0X0DBD, 0X0DBD),
    UnicodeRange(0X0DC0, 0X0DC6),
    UnicodeRange(0X0E01, 0X0E30),
    UnicodeRange(0X0E32, 0X0E33),
    UnicodeRange(0X0E40, 0X0E45),
    UnicodeRange(0X0E81, 0X0E82),
    UnicodeRange(0X0E84, 0X0E84),
    UnicodeRange(0X0E86, 0X0E8A),
    UnicodeRange(0X0E8C, 0X0EA3),
    UnicodeRange(0X0EA5, 0X0EA5),
    UnicodeRange(0X0EA7, 0X0EB0),
    UnicodeRange(0X0EB2, 0X0EB3),
    UnicodeRange(0X0EBD, 0X0EBD),
    UnicodeRange(0X0EC0, 0X0EC4),
    UnicodeRange(0X0EDC, 0X0EDF),
    UnicodeRange(0X0F00, 0X0F00),
    UnicodeRange(0X0F40, 0X0F47),
    UnicodeRange(0X0F49, 0X0F6C),
    UnicodeRange(0X0F88, 0X0F8C),
    UnicodeRange(0X1000, 0X102A),
    UnicodeRange(0X103F, 0X103F),
    UnicodeRange(0X1050, 0X1055),
    UnicodeRange(0X105A, 0X105D),
    UnicodeRange(0X1061, 0X1061),
    UnicodeRange(0X1065, 0X1066),
    UnicodeRange(0X106E, 0X1070),
    UnicodeRange(0X1075, 0X1081),
    UnicodeRange(0X108E, 0X108E),
    UnicodeRange(0X1100, 0X1248),
    UnicodeRange(0X124A, 0X124D),
    UnicodeRange(0X1250, 0X1256),
    UnicodeRange(0X1258, 0X1258),
    UnicodeRange(0X125A, 0X125D),
    UnicodeRange(0X1260, 0X1288),
    UnicodeRange(0X128A, 0X128D),
    UnicodeRange(0X1290, 0X12B0),
    UnicodeRange(0X12B2, 0X12B5),
    UnicodeRange(0X12B8, 0X12BE),
    UnicodeRange(0X12C0, 0X12C0),
    UnicodeRange(0X12C2, 0X12C5),
    UnicodeRange(0X12C8, 0X12D6),
    UnicodeRange(0X12D8, 0X1310),
    UnicodeRange(0X1312, 0X1315),
    UnicodeRange(0X1318, 0X135A),
    UnicodeRange(0X1380, 0X138F),
    UnicodeRange(0X1401, 0X166C),
    UnicodeRange(0X166F, 0X167F),
    UnicodeRange(0X1681, 0X169A),
    UnicodeRange(0X16A0, 0X16EA),
    UnicodeRange(0X16F1, 0X16F8),
    UnicodeRange(0X1700, 0X170C),
    UnicodeRange(0X170E, 0X1711),
    UnicodeRange(0X1720, 0X1731),
    UnicodeRange(0X1740, 0X1751),
    UnicodeRange(0X1760, 0X176C),
    UnicodeRange(0X176E, 0X1770),
    UnicodeRange(0X1780, 0X17B3),
    UnicodeRange(0X17DC, 0X17DC),
    UnicodeRange(0X1820, 0X1842),
    UnicodeRange(0X1844, 0X1878),
    UnicodeRange(0X1880, 0X1884),
    UnicodeRange(0X1887, 0X18A8),
    UnicodeRange(0X18AA, 0X18AA),
    UnicodeRange(0X18B0, 0X18F5),
    UnicodeRange(0X1900, 0X191E),
    UnicodeRange(0X1950, 0X196D),
    UnicodeRange(0X1970, 0X1974),
    UnicodeRange(0X1980, 0X19AB),
    UnicodeRange(0X19B0, 0X19C9),
    UnicodeRange(0X1A00, 0X1A16),
    UnicodeRange(0X1A20, 0X1A54),
    UnicodeRange(0X1B05, 0X1B33),
    UnicodeRange(0X1B45, 0X1B4B),
    UnicodeRange(0X1B83, 0X1BA0),
    UnicodeRange(0X1BAE, 0X1BAF),
    UnicodeRange(0X1BBA, 0X1BE5),
    UnicodeRange(0X1C00, 0X1C23),
    UnicodeRange(0X1C4D, 0X1C4F),
    UnicodeRange(0X1C5A, 0X1C77),
    UnicodeRange(0X1CE9, 0X1CEC),
    UnicodeRange(0X1CEE, 0X1CF3),
    UnicodeRange(0X1CF5, 0X1CF6),
    UnicodeRange(0X1CFA, 0X1CFA),
    UnicodeRange(0X2135, 0X2138),
    UnicodeRange(0X2D30, 0X2D67),
    UnicodeRange(0X2D80, 0X2D96),
    UnicodeRange(0X2DA0, 0X2DA6),
    UnicodeRange(0X2DA8, 0X2DAE),
    UnicodeRange(0X2DB0, 0X2DB6),
    UnicodeRange(0X2DB8, 0X2DBE),
    UnicodeRange(0X2DC0, 0X2DC6),
    UnicodeRange(0X2DC8, 0X2DCE),
    UnicodeRange(0X2DD0, 0X2DD6),
    UnicodeRange(0X2DD8, 0X2DDE),
    UnicodeRange(0X3006, 0X3006),
    UnicodeRange(0X303C, 0X303C),
    UnicodeRange(0X3041, 0X3096),
    UnicodeRange(0X309F, 0X309F),
    UnicodeRange(0X30A1, 0X30FA),
    UnicodeRange(0X30FF, 0X30FF),
    UnicodeRange(0X3105, 0X312F),
    UnicodeRange(0X3131, 0X318E),
    UnicodeRange(0X31A0, 0X31BF),
    UnicodeRange(0X31F0, 0X31FF),
    UnicodeRange(0X3400, 0X4DBF),
    UnicodeRange(0X4E00, 0X9FFC),
    UnicodeRange(0XA000, 0XA014),
    UnicodeRange(0XA016, 0XA48C),
    UnicodeRange(0XA4D0, 0XA4F7),
    UnicodeRange(0XA500, 0XA60B),
    UnicodeRange(0XA610, 0XA61F),
    UnicodeRange(0XA62A, 0XA62B),
    UnicodeRange(0XA66E, 0XA66E),
    UnicodeRange(0XA6A0, 0XA6E5),
    UnicodeRange(0XA78F, 0XA78F),
    UnicodeRange(0XA7F7, 0XA7F7),
    UnicodeRange(0XA7FB, 0XA801),
    UnicodeRange(0XA803, 0XA805),
    UnicodeRange(0XA807, 0XA80A),
    UnicodeRange(0XA80C, 0XA822),
    UnicodeRange(0XA840, 0XA873),
    UnicodeRange(0XA882, 0XA8B3),
    UnicodeRange(0XA8F2, 0XA8F7),
    UnicodeRange(0XA8FB, 0XA8FB),
    UnicodeRange(0XA8FD, 0XA8FE),
    UnicodeRange(0XA90A, 0XA925),
    UnicodeRange(0XA930, 0XA946),
    UnicodeRange(0XA960, 0XA97C),
    UnicodeRange(0XA984, 0XA9B2),
    UnicodeRange(0XA9E0, 0XA9E4),
    UnicodeRange(0XA9E7, 0XA9EF),
    UnicodeRange(0XA9FA, 0XA9FE),
    UnicodeRange(0XAA00, 0XAA28),
    UnicodeRange(0XAA40, 0XAA42),
    UnicodeRange(0XAA44, 0XAA4B),
    UnicodeRange(0XAA60, 0XAA6F),
    UnicodeRange(0XAA71, 0XAA76),
    UnicodeRange(0XAA7A, 0XAA7A),
    UnicodeRange(0XAA7E, 0XAAAF),
    UnicodeRange(0XAAB1, 0XAAB1),
    UnicodeRange(0XAAB5, 0XAAB6),
    UnicodeRange(0XAAB9, 0XAABD),
    UnicodeRange(0XAAC0, 0XAAC0),
    UnicodeRange(0XAAC2, 0XAAC2),
    UnicodeRange(0XAADB, 0XAADC),
    UnicodeRange(0XAAE0, 0XAAEA),
    UnicodeRange(0XAAF2, 0XAAF2),
    UnicodeRange(0XAB01, 0XAB06),
    UnicodeRange(0XAB09, 0XAB0E),
    UnicodeRange(0XAB11, 0XAB16),
    UnicodeRange(0XAB20, 0XAB26),
    UnicodeRange(0XAB28, 0XAB2E),
    UnicodeRange(0XABC0, 0XABE2),
    UnicodeRange(0XAC00, 0XD7A3),
    UnicodeRange(0XD7B0, 0XD7C6),
    UnicodeRange(0XD7CB, 0XD7FB),
    UnicodeRange(0XF900, 0XFA6D),
    UnicodeRange(0XFA70, 0XFAD9),
    UnicodeRange(0XFB1D, 0XFB1D),
    UnicodeRange(0XFB1F, 0XFB28),
    UnicodeRange(0XFB2A, 0XFB36),
    UnicodeRange(0XFB38, 0XFB3C),
    UnicodeRange(0XFB3E, 0XFB3E),
    UnicodeRange(0XFB40, 0XFB41),
    UnicodeRange(0XFB43, 0XFB44),
    UnicodeRange(0XFB46, 0XFBB1),
    UnicodeRange(0XFBD3, 0XFD3D),
    UnicodeRange(0XFD50, 0XFD8F),
    UnicodeRange(0XFD92, 0XFDC7),
    UnicodeRange(0XFDF0, 0XFDFB),
    UnicodeRange(0XFE70, 0XFE74),
    UnicodeRange(0XFE76, 0XFEFC),
    UnicodeRange(0XFF66, 0XFF6F),
    UnicodeRange(0XFF71, 0XFF9D),
    UnicodeRange(0XFFA0, 0XFFBE),
    UnicodeRange(0XFFC2, 0XFFC7),
    UnicodeRange(0XFFCA, 0XFFCF),
    UnicodeRange(0XFFD2, 0XFFD7),
    UnicodeRange(0XFFDA, 0XFFDC),
    UnicodeRange(0X10000, 0X1000B),
    UnicodeRange(0X1000D, 0X10026),
    UnicodeRange(0X10028, 0X1003A),
    UnicodeRange(0X1003C, 0X1003D),
    UnicodeRange(0X1003F, 0X1004D),
    UnicodeRange(0X10050, 0X1005D),
    UnicodeRange(0X10080, 0X100FA),
    UnicodeRange(0X10280, 0X1029C),
    UnicodeRange(0X102A0, 0X102D0),
    UnicodeRange(0X10300, 0X1031F),
    UnicodeRange(0X1032D, 0X10340),
    UnicodeRange(0X10342, 0X10349),
    UnicodeRange(0X10350, 0X10375),
    UnicodeRange(0X10380, 0X1039D),
    UnicodeRange(0X103A0, 0X103C3),
    UnicodeRange(0X103C8, 0X103CF),
    UnicodeRange(0X10450, 0X1049D),
    UnicodeRange(0X10500, 0X10527),
    UnicodeRange(0X10530, 0X10563),
    UnicodeRange(0X10600, 0X10736),
    UnicodeRange(0X10740, 0X10755),
    UnicodeRange(0X10760, 0X10767),
    UnicodeRange(0X10800, 0X10805),
    UnicodeRange(0X10808, 0X10808),
    UnicodeRange(0X1080A, 0X10835),
    UnicodeRange(0X10837, 0X10838),
    UnicodeRange(0X1083C, 0X1083C),
    UnicodeRange(0X1083F, 0X10855),
    UnicodeRange(0X10860, 0X10876),
    UnicodeRange(0X10880, 0X1089E),
    UnicodeRange(0X108E0, 0X108F2),
    UnicodeRange(0X108F4, 0X108F5),
    UnicodeRange(0X10900, 0X10915),
    UnicodeRange(0X10920, 0X10939),
    UnicodeRange(0X10980, 0X109B7),
    UnicodeRange(0X109BE, 0X109BF),
    UnicodeRange(0X10A00, 0X10A00),
    UnicodeRange(0X10A10, 0X10A13),
    UnicodeRange(0X10A15, 0X10A17),
    UnicodeRange(0X10A19, 0X10A35),
    UnicodeRange(0X10A60, 0X10A7C),
    UnicodeRange(0X10A80, 0X10A9C),
    UnicodeRange(0X10AC0, 0X10AC7),
    UnicodeRange(0X10AC9, 0X10AE4),
    UnicodeRange(0X10B00, 0X10B35),
    UnicodeRange(0X10B40, 0X10B55),
    UnicodeRange(0X10B60, 0X10B72),
    UnicodeRange(0X10B80, 0X10B91),
    UnicodeRange(0X10C00, 0X10C48),
    UnicodeRange(0X10D00, 0X10D23),
    UnicodeRange(0X10E80, 0X10EA9),
    UnicodeRange(0X10EB0, 0X10EB1),
    UnicodeRange(0X10F00, 0X10F1C),
    UnicodeRange(0X10F27, 0X10F27),
    UnicodeRange(0X10F30, 0X10F45),
    UnicodeRange(0X10FB0, 0X10FC4),
    UnicodeRange(0X10FE0, 0X10FF6),
    UnicodeRange(0X11003, 0X11037),
    UnicodeRange(0X11083, 0X110AF),
    UnicodeRange(0X110D0, 0X110E8),
    UnicodeRange(0X11103, 0X11126),
    UnicodeRange(0X11144, 0X11144),
    UnicodeRange(0X11147, 0X11147),
    UnicodeRange(0X11150, 0X11172),
    UnicodeRange(0X11176, 0X11176),
    UnicodeRange(0X11183, 0X111B2),
    UnicodeRange(0X111C1, 0X111C4),
    UnicodeRange(0X111DA, 0X111DA),
    UnicodeRange(0X111DC, 0X111DC),
    UnicodeRange(0X11200, 0X11211),
    UnicodeRange(0X11213, 0X1122B),
    UnicodeRange(0X11280, 0X11286),
    UnicodeRange(0X11288, 0X11288),
    UnicodeRange(0X1128A, 0X1128D),
    UnicodeRange(0X1128F, 0X1129D),
    UnicodeRange(0X1129F, 0X112A8),
    UnicodeRange(0X112B0, 0X112DE),
    UnicodeRange(0X11305, 0X1130C),
    UnicodeRange(0X1130F, 0X11310),
    UnicodeRange(0X11313, 0X11328),
    UnicodeRange(0X1132A, 0X11330),
    UnicodeRange(0X11332, 0X11333),
    UnicodeRange(0X11335, 0X11339),
    UnicodeRange(0X1133D, 0X1133D),
    UnicodeRange(0X11350, 0X11350),
    UnicodeRange(0X1135D, 0X11361),
    UnicodeRange(0X11400, 0X11434),
    UnicodeRange(0X11447, 0X1144A),
    UnicodeRange(0X1145F, 0X11461),
    UnicodeRange(0X11480, 0X114AF),
    UnicodeRange(0X114C4, 0X114C5),
    UnicodeRange(0X114C7, 0X114C7),
    UnicodeRange(0X11580, 0X115AE),
    UnicodeRange(0X115D8, 0X115DB),
    UnicodeRange(0X11600, 0X1162F),
    UnicodeRange(0X11644, 0X11644),
    UnicodeRange(0X11680, 0X116AA),
    UnicodeRange(0X116B8, 0X116B8),
    UnicodeRange(0X11700, 0X1171A),
    UnicodeRange(0X11800, 0X1182B),
    UnicodeRange(0X118FF, 0X11906),
    UnicodeRange(0X11909, 0X11909),
    UnicodeRange(0X1190C, 0X11913),
    UnicodeRange(0X11915, 0X11916),
    UnicodeRange(0X11918, 0X1192F),
    UnicodeRange(0X1193F, 0X1193F),
    UnicodeRange(0X11941, 0X11941),
    UnicodeRange(0X119A0, 0X119A7),
    UnicodeRange(0X119AA, 0X119D0),
    UnicodeRange(0X119E1, 0X119E1),
    UnicodeRange(0X119E3, 0X119E3),
    UnicodeRange(0X11A00, 0X11A00),
    UnicodeRange(0X11A0B, 0X11A32),
    UnicodeRange(0X11A3A, 0X11A3A),
    UnicodeRange(0X11A50, 0X11A50),
    UnicodeRange(0X11A5C, 0X11A89),
    UnicodeRange(0X11A9D, 0X11A9D),
    UnicodeRange(0X11AC0, 0X11AF8),
    UnicodeRange(0X11C00, 0X11C08),
    UnicodeRange(0X11C0A, 0X11C2E),
    UnicodeRange(0X11C40, 0X11C40),
    UnicodeRange(0X11C72, 0X11C8F),
    UnicodeRange(0X11D00, 0X11D06),
    UnicodeRange(0X11D08, 0X11D09),
    UnicodeRange(0X11D0B, 0X11D30),
    UnicodeRange(0X11D46, 0X11D46),
    UnicodeRange(0X11D60, 0X11D65),
    UnicodeRange(0X11D67, 0X11D68),
    UnicodeRange(0X11D6A, 0X11D89),
    UnicodeRange(0X11D98, 0X11D98),
    UnicodeRange(0X11EE0, 0X11EF2),
    UnicodeRange(0X11FB0, 0X11FB0),
    UnicodeRange(0X12000, 0X12399),
    UnicodeRange(0X12480, 0X12543),
    UnicodeRange(0X13000, 0X1342E),
    UnicodeRange(0X14400, 0X14646),
    UnicodeRange(0X16800, 0X16A38),
    UnicodeRange(0X16A40, 0X16A5E),
    UnicodeRange(0X16AD0, 0X16AED),
    UnicodeRange(0X16B00, 0X16B2F),
    UnicodeRange(0X16B63, 0X16B77),
    UnicodeRange(0X16B7D, 0X16B8F),
    UnicodeRange(0X16F00, 0X16F4A),
    UnicodeRange(0X16F50, 0X16F50),
    UnicodeRange(0X17000, 0X187F7),
    UnicodeRange(0X18800, 0X18CD5),
    UnicodeRange(0X18D00, 0X18D08),
    UnicodeRange(0X1B000, 0X1B11E),
    UnicodeRange(0X1B150, 0X1B152),
    UnicodeRange(0X1B164, 0X1B167),
    UnicodeRange(0X1B170, 0X1B2FB),
    UnicodeRange(0X1BC00, 0X1BC6A),
    UnicodeRange(0X1BC70, 0X1BC7C),
    UnicodeRange(0X1BC80, 0X1BC88),
    UnicodeRange(0X1BC90, 0X1BC99),
    UnicodeRange(0X1E100, 0X1E12C),
    UnicodeRange(0X1E14E, 0X1E14E),
    UnicodeRange(0X1E2C0, 0X1E2EB),
    UnicodeRange(0X1E800, 0X1E8C4),
    UnicodeRange(0X1EE00, 0X1EE03),
    UnicodeRange(0X1EE05, 0X1EE1F),
    UnicodeRange(0X1EE21, 0X1EE22),
    UnicodeRange(0X1EE24, 0X1EE24),
    UnicodeRange(0X1EE27, 0X1EE27),
    UnicodeRange(0X1EE29, 0X1EE32),
    UnicodeRange(0X1EE34, 0X1EE37),
    UnicodeRange(0X1EE39, 0X1EE39),
    UnicodeRange(0X1EE3B, 0X1EE3B),
    UnicodeRange(0X1EE42, 0X1EE42),
    UnicodeRange(0X1EE47, 0X1EE47),
    UnicodeRange(0X1EE49, 0X1EE49),
    UnicodeRange(0X1EE4B, 0X1EE4B),
    UnicodeRange(0X1EE4D, 0X1EE4F),
    UnicodeRange(0X1EE51, 0X1EE52),
    UnicodeRange(0X1EE54, 0X1EE54),
    UnicodeRange(0X1EE57, 0X1EE57),
    UnicodeRange(0X1EE59, 0X1EE59),
    UnicodeRange(0X1EE5B, 0X1EE5B),
    UnicodeRange(0X1EE5D, 0X1EE5D),
    UnicodeRange(0X1EE5F, 0X1EE5F),
    UnicodeRange(0X1EE61, 0X1EE62),
    UnicodeRange(0X1EE64, 0X1EE64),
    UnicodeRange(0X1EE67, 0X1EE6A),
    UnicodeRange(0X1EE6C, 0X1EE72),
    UnicodeRange(0X1EE74, 0X1EE77),
    UnicodeRange(0X1EE79, 0X1EE7C),
    UnicodeRange(0X1EE7E, 0X1EE7E),
    UnicodeRange(0X1EE80, 0X1EE89),
    UnicodeRange(0X1EE8B, 0X1EE9B),
    UnicodeRange(0X1EEA1, 0X1EEA3),
    UnicodeRange(0X1EEA5, 0X1EEA9),
    UnicodeRange(0X1EEAB, 0X1EEBB),
    UnicodeRange(0X20000, 0X2A6DD),
    UnicodeRange(0X2A700, 0X2B734),
    UnicodeRange(0X2B740, 0X2B81D),
    UnicodeRange(0X2B820, 0X2CEA1),
    UnicodeRange(0X2CEB0, 0X2EBE0),
    UnicodeRange(0X2F800, 0X2FA1D),
    UnicodeRange(0X30000, 0X3134A)
]
let DECIMAL_NUMBER: Array<UnicodeRange> = [
    UnicodeRange(0X0030, 0X0039),
    UnicodeRange(0X0660, 0X0669),
    UnicodeRange(0X06F0, 0X06F9),
    UnicodeRange(0X07C0, 0X07C9),
    UnicodeRange(0X0966, 0X096F),
    UnicodeRange(0X09E6, 0X09EF),
    UnicodeRange(0X0A66, 0X0A6F),
    UnicodeRange(0X0AE6, 0X0AEF),
    UnicodeRange(0X0B66, 0X0B6F),
    UnicodeRange(0X0BE6, 0X0BEF),
    UnicodeRange(0X0C66, 0X0C6F),
    UnicodeRange(0X0CE6, 0X0CEF),
    UnicodeRange(0X0D66, 0X0D6F),
    UnicodeRange(0X0DE6, 0X0DEF),
    UnicodeRange(0X0E50, 0X0E59),
    UnicodeRange(0X0ED0, 0X0ED9),
    UnicodeRange(0X0F20, 0X0F29),
    UnicodeRange(0X1040, 0X1049),
    UnicodeRange(0X1090, 0X1099),
    UnicodeRange(0X17E0, 0X17E9),
    UnicodeRange(0X1810, 0X1819),
    UnicodeRange(0X1946, 0X194F),
    UnicodeRange(0X19D0, 0X19D9),
    UnicodeRange(0X1A80, 0X1A89),
    UnicodeRange(0X1A90, 0X1A99),
    UnicodeRange(0X1B50, 0X1B59),
    UnicodeRange(0X1BB0, 0X1BB9),
    UnicodeRange(0X1C40, 0X1C49),
    UnicodeRange(0X1C50, 0X1C59),
    UnicodeRange(0XA620, 0XA629),
    UnicodeRange(0XA8D0, 0XA8D9),
    UnicodeRange(0XA900, 0XA909),
    UnicodeRange(0XA9D0, 0XA9D9),
    UnicodeRange(0XA9F0, 0XA9F9),
    UnicodeRange(0XAA50, 0XAA59),
    UnicodeRange(0XABF0, 0XABF9),
    UnicodeRange(0XFF10, 0XFF19),
    UnicodeRange(0X104A0, 0X104A9),
    UnicodeRange(0X10D30, 0X10D39),
    UnicodeRange(0X11066, 0X1106F),
    UnicodeRange(0X110F0, 0X110F9),
    UnicodeRange(0X11136, 0X1113F),
    UnicodeRange(0X111D0, 0X111D9),
    UnicodeRange(0X112F0, 0X112F9),
    UnicodeRange(0X11450, 0X11459),
    UnicodeRange(0X114D0, 0X114D9),
    UnicodeRange(0X11650, 0X11659),
    UnicodeRange(0X116C0, 0X116C9),
    UnicodeRange(0X11730, 0X11739),
    UnicodeRange(0X118E0, 0X118E9),
    UnicodeRange(0X11950, 0X11959),
    UnicodeRange(0X11C50, 0X11C59),
    UnicodeRange(0X11D50, 0X11D59),
    UnicodeRange(0X11DA0, 0X11DA9),
    UnicodeRange(0X16A60, 0X16A69),
    UnicodeRange(0X16B50, 0X16B59),
    UnicodeRange(0X1D7CE, 0X1D7FF),
    UnicodeRange(0X1E140, 0X1E149),
    UnicodeRange(0X1E2F0, 0X1E2F9),
    UnicodeRange(0X1E950, 0X1E959),
    UnicodeRange(0X1FBF0, 0X1FBF9)
]
let LETTER_NUMBER: Array<UnicodeRange> = [
    UnicodeRange(0X16EE, 0X16F0),
    UnicodeRange(0X2160, 0X2182),
    UnicodeRange(0X2185, 0X2188),
    UnicodeRange(0X3007, 0X3007),
    UnicodeRange(0X3021, 0X3029),
    UnicodeRange(0X3038, 0X303A),
    UnicodeRange(0XA6E6, 0XA6EF),
    UnicodeRange(0X10140, 0X10174),
    UnicodeRange(0X10341, 0X10341),
    UnicodeRange(0X1034A, 0X1034A),
    UnicodeRange(0X103D1, 0X103D5),
    UnicodeRange(0X12400, 0X1246E)
]
let OTHER_NUMBER: Array<UnicodeRange> = [
    UnicodeRange(0X00B2, 0X00B3),
    UnicodeRange(0X00B9, 0X00B9),
    UnicodeRange(0X00BC, 0X00BE),
    UnicodeRange(0X09F4, 0X09F9),
    UnicodeRange(0X0B72, 0X0B77),
    UnicodeRange(0X0BF0, 0X0BF2),
    UnicodeRange(0X0C78, 0X0C7E),
    UnicodeRange(0X0D58, 0X0D5E),
    UnicodeRange(0X0D70, 0X0D78),
    UnicodeRange(0X0F2A, 0X0F33),
    UnicodeRange(0X1369, 0X137C),
    UnicodeRange(0X17F0, 0X17F9),
    UnicodeRange(0X19DA, 0X19DA),
    UnicodeRange(0X2070, 0X2070),
    UnicodeRange(0X2074, 0X2079),
    UnicodeRange(0X2080, 0X2089),
    UnicodeRange(0X2150, 0X215F),
    UnicodeRange(0X2189, 0X2189),
    UnicodeRange(0X2460, 0X249B),
    UnicodeRange(0X24EA, 0X24FF),
    UnicodeRange(0X2776, 0X2793),
    UnicodeRange(0X2CFD, 0X2CFD),
    UnicodeRange(0X3192, 0X3195),
    UnicodeRange(0X3220, 0X3229),
    UnicodeRange(0X3248, 0X324F),
    UnicodeRange(0X3251, 0X325F),
    UnicodeRange(0X3280, 0X3289),
    UnicodeRange(0X32B1, 0X32BF),
    UnicodeRange(0XA830, 0XA835),
    UnicodeRange(0X10107, 0X10133),
    UnicodeRange(0X10175, 0X10178),
    UnicodeRange(0X1018A, 0X1018B),
    UnicodeRange(0X102E1, 0X102FB),
    UnicodeRange(0X10320, 0X10323),
    UnicodeRange(0X10858, 0X1085F),
    UnicodeRange(0X10879, 0X1087F),
    UnicodeRange(0X108A7, 0X108AF),
    UnicodeRange(0X108FB, 0X108FF),
    UnicodeRange(0X10916, 0X1091B),
    UnicodeRange(0X109BC, 0X109BD),
    UnicodeRange(0X109C0, 0X109CF),
    UnicodeRange(0X109D2, 0X109FF),
    UnicodeRange(0X10A40, 0X10A48),
    UnicodeRange(0X10A7D, 0X10A7E),
    UnicodeRange(0X10A9D, 0X10A9F),
    UnicodeRange(0X10AEB, 0X10AEF),
    UnicodeRange(0X10B58, 0X10B5F),
    UnicodeRange(0X10B78, 0X10B7F),
    UnicodeRange(0X10BA9, 0X10BAF),
    UnicodeRange(0X10CFA, 0X10CFF),
    UnicodeRange(0X10E60, 0X10E7E),
    UnicodeRange(0X10F1D, 0X10F26),
    UnicodeRange(0X10F51, 0X10F54),
    UnicodeRange(0X10FC5, 0X10FCB),
    UnicodeRange(0X11052, 0X11065),
    UnicodeRange(0X111E1, 0X111F4),
    UnicodeRange(0X1173A, 0X1173B),
    UnicodeRange(0X118EA, 0X118F2),
    UnicodeRange(0X11C5A, 0X11C6C),
    UnicodeRange(0X11FC0, 0X11FD4),
    UnicodeRange(0X16B5B, 0X16B61),
    UnicodeRange(0X16E80, 0X16E96),
    UnicodeRange(0X1D2E0, 0X1D2F3),
    UnicodeRange(0X1D360, 0X1D378),
    UnicodeRange(0X1E8C7, 0X1E8CF),
    UnicodeRange(0X1EC71, 0X1ECAB),
    UnicodeRange(0X1ECAD, 0X1ECAF),
    UnicodeRange(0X1ECB1, 0X1ECB4),
    UnicodeRange(0X1ED01, 0X1ED2D),
    UnicodeRange(0X1ED2F, 0X1ED3D),
    UnicodeRange(0X1F100, 0X1F10C)
]
let WHITE_SPACE: Array<UnicodeRange> = [
    UnicodeRange(0X0009, 0X000D),
    UnicodeRange(0X0020, 0X0020),
    UnicodeRange(0X0085, 0X0085),
    UnicodeRange(0X00A0, 0X00A0),
    UnicodeRange(0X1680, 0X1680),
    UnicodeRange(0X2000, 0X200A),
    UnicodeRange(0X2028, 0X2028),
    UnicodeRange(0X2029, 0X2029),
    UnicodeRange(0X202F, 0X202F),
    UnicodeRange(0X205F, 0X205F),
    UnicodeRange(0X3000, 0X3000)
]
let COMBINING_MARK_RANGES: Array<UnicodeRange> = [
    UnicodeRange(0x00AD, 0x00AD),
    UnicodeRange(0x0300, 0x036F),
    UnicodeRange(0x034F, 0x034F),
    UnicodeRange(0x0483, 0x0489),
    UnicodeRange(0x0591, 0x05BD),
    UnicodeRange(0x05BF, 0x05CF),
    UnicodeRange(0x0610, 0x061A),
    UnicodeRange(0x061C, 0x061C),
    UnicodeRange(0x064B, 0x065F),
    UnicodeRange(0x0670, 0x0670),
    UnicodeRange(0x06D6, 0x06DC),
    UnicodeRange(0x06DF, 0x06E4),
    UnicodeRange(0x06E7, 0x06E8),
    UnicodeRange(0x06EA, 0x06ED),
    UnicodeRange(0x0711, 0x0711),
    UnicodeRange(0x0730, 0x074A),
    UnicodeRange(0x07A6, 0x07B0),
    UnicodeRange(0x07EB, 0x07F3),
    UnicodeRange(0x0816, 0x0819),
    UnicodeRange(0x081B, 0x0823),
    UnicodeRange(0x0825, 0x0827),
    UnicodeRange(0x0829, 0x082D),
    UnicodeRange(0x0859, 0x085B),
    UnicodeRange(0x08D4, 0x08E1),
    UnicodeRange(0x08E3, 0x08FF),
    UnicodeRange(0x0900, 0x0902),
    UnicodeRange(0x093A, 0x093A),
    UnicodeRange(0x093C, 0x094C),
    UnicodeRange(0x094E, 0x094F),
    UnicodeRange(0x0982, 0x0983),
    UnicodeRange(0x09BC, 0x09BC),
    UnicodeRange(0x09BE, 0x09C4),
    UnicodeRange(0x09C7, 0x09C8),
    UnicodeRange(0x09CB, 0x09CD),
    UnicodeRange(0x09D7, 0x09D7),
    UnicodeRange(0x09E2, 0x09E3),
    UnicodeRange(0x0A01, 0x0A02),
    UnicodeRange(0x0A3C, 0x0A3C),
    UnicodeRange(0x0A41, 0x0A42),
    UnicodeRange(0x0A47, 0x0A48),
    UnicodeRange(0x0A4B, 0x0A4D),
    UnicodeRange(0x0A70, 0x0A71),
    UnicodeRange(0x0A75, 0x0A75),
    UnicodeRange(0x0A81, 0x0A82),
    UnicodeRange(0x0ABC, 0x0ABC),
    UnicodeRange(0x0AC1, 0x0AC5),
    UnicodeRange(0x0AC7, 0x0AC8),
    UnicodeRange(0x0ACD, 0x0ACD),
    UnicodeRange(0x0AE2, 0x0AE3),
    UnicodeRange(0x0B01, 0x0B01),
    UnicodeRange(0x0B3C, 0x0B3C),
    UnicodeRange(0x0B3E, 0x0B43),
    UnicodeRange(0x0B47, 0x0B48),
    UnicodeRange(0x0B4B, 0x0B4D),
    UnicodeRange(0x0B56, 0x0B56),
    UnicodeRange(0x0B57, 0x0B57),
    UnicodeRange(0x0B82, 0x0B82),
    UnicodeRange(0x0BBE, 0x0BC2),
    UnicodeRange(0x0BC6, 0x0BC8),
    UnicodeRange(0x0BCA, 0x0BCD),
    UnicodeRange(0x0BD7, 0x0BD7),
    UnicodeRange(0x0C01, 0x0C03),
    UnicodeRange(0x0C41, 0x0C44),
    UnicodeRange(0x0C82, 0x0C82),
    UnicodeRange(0x0CBE, 0x0CC4),
    UnicodeRange(0x0CC6, 0x0CC8),
    UnicodeRange(0x0CCA, 0x0CCD),
    UnicodeRange(0x0CD5, 0x0CD6),
    UnicodeRange(0x0D02, 0x0D03),
    UnicodeRange(0x0D3E, 0x0D43),
    UnicodeRange(0x0D46, 0x0D48),
    UnicodeRange(0x0D4A, 0x0D4D),
    UnicodeRange(0x0D57, 0x0D57),
    UnicodeRange(0x0D82, 0x0D82),
    UnicodeRange(0x0DCA, 0x0DCA),
    UnicodeRange(0x0DCF, 0x0DD4),
    UnicodeRange(0x0DD6, 0x0DD6),
    UnicodeRange(0x0DD8, 0x0DDF),
    UnicodeRange(0x0DF2, 0x0DF3),
    UnicodeRange(0x0E34, 0x0E3A),
    UnicodeRange(0x0E47, 0x0E4E),
    UnicodeRange(0x0EB4, 0x0EB9),
    UnicodeRange(0x0EBB, 0x0EBC),
    UnicodeRange(0x0EC8, 0x0ECD),
    UnicodeRange(0x0F18, 0x0F19),
    UnicodeRange(0x0F35, 0x0F35),
    UnicodeRange(0x0F37, 0x0F37),
    UnicodeRange(0x0F39, 0x0F39),
    UnicodeRange(0x0F71, 0x0F7E),
    UnicodeRange(0x0F80, 0x0F84),
    UnicodeRange(0x0F86, 0x0F87),
    UnicodeRange(0x0F90, 0x0F97),
    UnicodeRange(0x0F99, 0x0FBC),
    UnicodeRange(0x0FC6, 0x0FC6),
    UnicodeRange(0x102D, 0x1030),
    UnicodeRange(0x1032, 0x1037),
    UnicodeRange(0x1039, 0x103A),
    UnicodeRange(0x103D, 0x103E),
    UnicodeRange(0x1058, 0x1059),
    UnicodeRange(0x105E, 0x1060),
    UnicodeRange(0x1071, 0x1074),
    UnicodeRange(0x1082, 0x1082),
    UnicodeRange(0x1085, 0x1086),
    UnicodeRange(0x108D, 0x108D),
    UnicodeRange(0x109D, 0x109D),
    UnicodeRange(0x135D, 0x135F),
    UnicodeRange(0x1712, 0x1714),
    UnicodeRange(0x1732, 0x1734),
    UnicodeRange(0x1752, 0x1753),
    UnicodeRange(0x1772, 0x1773),
    UnicodeRange(0x17B4, 0x17B5),
    UnicodeRange(0x17B7, 0x17BD),
    UnicodeRange(0x17C6, 0x17C6),
    UnicodeRange(0x17C8, 0x17D3),
    UnicodeRange(0x17DD, 0x17DD),
    UnicodeRange(0x180B, 0x180D),
    UnicodeRange(0x18A9, 0x18A9),
    UnicodeRange(0x1920, 0x192B),
    UnicodeRange(0x1930, 0x193B),
    UnicodeRange(0x1946, 0x194F),
    UnicodeRange(0x19D0, 0x19D9),
    UnicodeRange(0x1A17, 0x1A1B),
    UnicodeRange(0x1A55, 0x1A5E),
    UnicodeRange(0x1A60, 0x1A7C),
    UnicodeRange(0x1A7F, 0x1A7F),
    UnicodeRange(0x1B00, 0x1B03),
    UnicodeRange(0x1B34, 0x1B34),
    UnicodeRange(0x1B36, 0x1B3A),
    UnicodeRange(0x1B3C, 0x1B3C),
    UnicodeRange(0x1B42, 0x1B42),
    UnicodeRange(0x1B6B, 0x1B73),
    UnicodeRange(0x1B80, 0x1B81),
    UnicodeRange(0x1BA2, 0x1BA5),
    UnicodeRange(0x1BA8, 0x1BA9),
    UnicodeRange(0x1BAB, 0x1BAD),
    UnicodeRange(0x1BE6, 0x1BE6),
    UnicodeRange(0x1BE8, 0x1BE9),
    UnicodeRange(0x1BEA, 0x1BEC),
    UnicodeRange(0x1BEE, 0x1BEE),
    UnicodeRange(0x1BF2, 0x1BF3),
    UnicodeRange(0x1C24, 0x1C2B),
    UnicodeRange(0x1C34, 0x1C35),
    UnicodeRange(0x1CE1, 0x1CE1),
    UnicodeRange(0x1CF2, 0x1CF3),
    UnicodeRange(0x200B, 0x200F),
    UnicodeRange(0x202A, 0x202E),
    UnicodeRange(0x2060, 0x2064),
    UnicodeRange(0x2066, 0x206F),
    UnicodeRange(0x2D20, 0x2D2F),
    UnicodeRange(0x2D30, 0x2D67),
    UnicodeRange(0x2D6F, 0x2D6F),
    UnicodeRange(0x2D80, 0x2D96),
    UnicodeRange(0x2DA0, 0x2DA6),
    UnicodeRange(0x2DA8, 0x2DAE),
    UnicodeRange(0x2DB0, 0x2DB6),
    UnicodeRange(0x2DB8, 0x2DBE),
    UnicodeRange(0x2DC0, 0x2DC6),
    UnicodeRange(0x2DC8, 0x2DCE),
    UnicodeRange(0x2DD0, 0x2DD6),
    UnicodeRange(0x2DD8, 0x2DDE),
    UnicodeRange(0x3029, 0x302D),
    UnicodeRange(0x3099, 0x309A),
    UnicodeRange(0xA66F, 0xA66F),
    UnicodeRange(0xA674, 0xA67D),
    UnicodeRange(0xA69F, 0xA69F),
    UnicodeRange(0xA6F0, 0xA6F1),
    UnicodeRange(0xA802, 0xA802),
    UnicodeRange(0xA806, 0xA806),
    UnicodeRange(0xA80B, 0xA80B),
    UnicodeRange(0xA825, 0xA826),
    UnicodeRange(0xA8C4, 0xA8C4),
    UnicodeRange(0xA8E0, 0xA8E1),
    UnicodeRange(0xA926, 0xA92D),
    UnicodeRange(0xA947, 0xA951),
    UnicodeRange(0xA980, 0xA982),
    UnicodeRange(0xA9B3, 0xA9B3),
    UnicodeRange(0xA9B6, 0xA9B9),
    UnicodeRange(0xA9BC, 0xA9BC),
    UnicodeRange(0xAA29, 0xAA2E),
    UnicodeRange(0xAA31, 0xAA32),
    UnicodeRange(0xAA35, 0xAA36),
    UnicodeRange(0xAA43, 0xAA43),
    UnicodeRange(0xAA4C, 0xAA4C),
    UnicodeRange(0xAAB0, 0xAAB0),
    UnicodeRange(0xAAB2, 0xAAB4),
    UnicodeRange(0xAAB7, 0xAAB8),
    UnicodeRange(0xAABE, 0xAABF),
    UnicodeRange(0xAAC1, 0xAAC1),
    UnicodeRange(0xAAEB, 0xAAEB),
    UnicodeRange(0xAAEE, 0xAAEF),
    UnicodeRange(0xAAF5, 0xAAF5),
    UnicodeRange(0xABE3, 0xABE4),
    UnicodeRange(0xABE6, 0xABE7),
    UnicodeRange(0xABE9, 0xABEA),
    UnicodeRange(0xABEC, 0xABED),
    UnicodeRange(0xFB1E, 0xFB1E),
    UnicodeRange(0xFE00, 0xFE0F),
    UnicodeRange(0xFE20, 0xFE26),
    UnicodeRange(0xFEFF, 0xFEFF),
    UnicodeRange(0x10A01, 0x10A03),
    UnicodeRange(0x10A05, 0x10A06),
    UnicodeRange(0x10A0C, 0x10A0F),
    UnicodeRange(0x10A38, 0x10A3A),
    UnicodeRange(0x10A3F, 0x10A3F),
    UnicodeRange(0x1D167, 0x1D169),
    UnicodeRange(0x1D17B, 0x1D182),
    UnicodeRange(0x1D185, 0x1D18B),
    UnicodeRange(0x1D1AA, 0x1D1AD),
    UnicodeRange(0x1D242, 0x1D244),
    UnicodeRange(0x1E000, 0x1E006),
    UnicodeRange(0x1E008, 0x1E018),
    UnicodeRange(0x1E01B, 0x1E021),
    UnicodeRange(0x1E023, 0x1E024),
    UnicodeRange(0x1E026, 0x1E02A),
    UnicodeRange(0x1E8D0, 0x1E8D6),
    UnicodeRange(0x1E944, 0x1E94A)
]

let CASE_IGNORABLE_RANGES: Array<UnicodeRange> = [
    UnicodeRange(0X0027, 0X0027),
    UnicodeRange(0X002E, 0X002E),
    UnicodeRange(0X003A, 0X003A),
    UnicodeRange(0X0060, 0X0060),
    UnicodeRange(0X00B7, 0X00B7),
    UnicodeRange(0X02B0, 0X02FF),
    UnicodeRange(0X0300, 0X036F),
    UnicodeRange(0X034F, 0X034F),
    UnicodeRange(0X0483, 0X0489),
    UnicodeRange(0X0591, 0X05BD),
    UnicodeRange(0X05BF, 0X05CF),
    UnicodeRange(0X0610, 0X061A),
    UnicodeRange(0X061C, 0X061C),
    UnicodeRange(0X064B, 0X065F),
    UnicodeRange(0X0670, 0X0670),
    UnicodeRange(0X06D6, 0X06DC),
    UnicodeRange(0X06DF, 0X06E4),
    UnicodeRange(0X06E7, 0X06E8),
    UnicodeRange(0X06EA, 0X06ED),
    UnicodeRange(0X0711, 0X0711),
    UnicodeRange(0X0730, 0X074A),
    UnicodeRange(0X07A6, 0X07B0),
    UnicodeRange(0X07EB, 0X07F3),
    UnicodeRange(0X0816, 0X0819),
    UnicodeRange(0X081B, 0X0823),
    UnicodeRange(0X0825, 0X0827),
    UnicodeRange(0X0829, 0X082D),
    UnicodeRange(0X0859, 0X085B),
    UnicodeRange(0X08D4, 0X08E1),
    UnicodeRange(0X08E3, 0X08FF),
    UnicodeRange(0X0900, 0X0902),
    UnicodeRange(0X093A, 0X093A),
    UnicodeRange(0X093C, 0X094C),
    UnicodeRange(0X094E, 0X094F),
    UnicodeRange(0X0982, 0X0983),
    UnicodeRange(0X09BC, 0X09BC),
    UnicodeRange(0X09BE, 0X09C4),
    UnicodeRange(0X09C7, 0X09C8),
    UnicodeRange(0X09CB, 0X09CD),
    UnicodeRange(0X09D7, 0X09D7),
    UnicodeRange(0X09E2, 0X09E3),
    UnicodeRange(0X0A01, 0X0A02),
    UnicodeRange(0X0A3C, 0X0A3C),
    UnicodeRange(0X0A41, 0X0A42),
    UnicodeRange(0X0A47, 0X0A48),
    UnicodeRange(0X0A4B, 0X0A4D),
    UnicodeRange(0X0A70, 0X0A71),
    UnicodeRange(0X0A75, 0X0A75),
    UnicodeRange(0X0A81, 0X0A82),
    UnicodeRange(0X0ABC, 0X0ABC),
    UnicodeRange(0X0AC1, 0X0AC5),
    UnicodeRange(0X0AC7, 0X0AC8),
    UnicodeRange(0X0ACD, 0X0ACD),
    UnicodeRange(0X0AE2, 0X0AE3),
    UnicodeRange(0X0B01, 0X0B01),
    UnicodeRange(0X0B3C, 0X0B3C),
    UnicodeRange(0X0B3E, 0X0B43),
    UnicodeRange(0X0B47, 0X0B48),
    UnicodeRange(0X0B4B, 0X0B4D),
    UnicodeRange(0X0B56, 0X0B56),
    UnicodeRange(0X0B57, 0X0B57),
    UnicodeRange(0X0B82, 0X0B82),
    UnicodeRange(0X0BBE, 0X0BC2),
    UnicodeRange(0X0BC6, 0X0BC8),
    UnicodeRange(0X0BCA, 0X0BCD),
    UnicodeRange(0X0BD7, 0X0BD7),
    UnicodeRange(0X0C01, 0X0C03),
    UnicodeRange(0X0C41, 0X0C44),
    UnicodeRange(0X0C82, 0X0C82),
    UnicodeRange(0X0CBE, 0X0CC4),
    UnicodeRange(0X0CC6, 0X0CC8),
    UnicodeRange(0X0CCA, 0X0CCD),
    UnicodeRange(0X0CD5, 0X0CD6),
    UnicodeRange(0X0D02, 0X0D03),
    UnicodeRange(0X0D3E, 0X0D43),
    UnicodeRange(0X0D46, 0X0D48),
    UnicodeRange(0X0D4A, 0X0D4D),
    UnicodeRange(0X0D57, 0X0D57),
    UnicodeRange(0X0D82, 0X0D82),
    UnicodeRange(0X0DCA, 0X0DCA),
    UnicodeRange(0X0DCF, 0X0DD4),
    UnicodeRange(0X0DD6, 0X0DD6),
    UnicodeRange(0X0DD8, 0X0DDF),
    UnicodeRange(0X0DF2, 0X0DF3),
    UnicodeRange(0X0E34, 0X0E3A),
    UnicodeRange(0X0E47, 0X0E4E),
    UnicodeRange(0X0EB4, 0X0EB9),
    UnicodeRange(0X0EBB, 0X0EBC),
    UnicodeRange(0X0EC8, 0X0ECD),
    UnicodeRange(0X0F18, 0X0F19),
    UnicodeRange(0X0F35, 0X0F35),
    UnicodeRange(0X0F37, 0X0F37),
    UnicodeRange(0X0F39, 0X0F39),
    UnicodeRange(0X0F71, 0X0F7E),
    UnicodeRange(0X0F80, 0X0F84),
    UnicodeRange(0X0F86, 0X0F87),
    UnicodeRange(0X0F90, 0X0F97),
    UnicodeRange(0X0F99, 0XFBC),
    UnicodeRange(0X0FC6, 0X0FC6),
    UnicodeRange(0X102D, 0X1030),
    UnicodeRange(0X1032, 0X1037),
    UnicodeRange(0X1039, 0X103A),
    UnicodeRange(0X103D, 0X103E),
    UnicodeRange(0X1058, 0X1059),
    UnicodeRange(0X105E, 0X1060),
    UnicodeRange(0X1071, 0X1074),
    UnicodeRange(0X1082, 0X1082),
    UnicodeRange(0X1085, 0X1086),
    UnicodeRange(0X108D, 0X108D),
    UnicodeRange(0X109D, 0X109D),
    UnicodeRange(0X135D, 0X135F),
    UnicodeRange(0X1712, 0X1714),
    UnicodeRange(0X1732, 0X1734),
    UnicodeRange(0X1752, 0X1753),
    UnicodeRange(0X1772, 0X1773),
    UnicodeRange(0X17B4, 0X17B5),
    UnicodeRange(0X17B7, 0X17BD),
    UnicodeRange(0X17C6, 0X17C6),
    UnicodeRange(0X17C8, 0X17D3),
    UnicodeRange(0X17DD, 0X17DD),
    UnicodeRange(0X180B, 0X180D),
    UnicodeRange(0X18A9, 0X18A9),
    UnicodeRange(0X1920, 0X192B),
    UnicodeRange(0X1930, 0X193B),
    UnicodeRange(0X1946, 0X194F),
    UnicodeRange(0X19D0, 0X19D9),
    UnicodeRange(0X1A17, 0X1A1B),
    UnicodeRange(0X1A55, 0X1A5E),
    UnicodeRange(0X1A60, 0X1A7C),
    UnicodeRange(0X1A7F, 0X1A7F),
    UnicodeRange(0X1B00, 0X1B03),
    UnicodeRange(0X1B34, 0X1B34),
    UnicodeRange(0X1B36, 0X1B3A),
    UnicodeRange(0X1B3C, 0X1B3C),
    UnicodeRange(0X1B42, 0X1B42),
    UnicodeRange(0X1B6B, 0X1B73),
    UnicodeRange(0X1B80, 0X1B81),
    UnicodeRange(0X1BA2, 0X1BA5),
    UnicodeRange(0X1BA8, 0X1BA9),
    UnicodeRange(0X1BAB, 0X1BAD),
    UnicodeRange(0X1BE6, 0X1BE6),
    UnicodeRange(0X1BE8, 0X1BE9),
    UnicodeRange(0X1BEA, 0X1BEC),
    UnicodeRange(0X1BEE, 0X1BEE),
    UnicodeRange(0X1BF2, 0X1BF3),
    UnicodeRange(0X1C24, 0X1C2B),
    UnicodeRange(0X1C34, 0X1C35),
    UnicodeRange(0X1CE1, 0X1CE1),
    UnicodeRange(0X1CF2, 0X1CF3),
    UnicodeRange(0X200B, 0X200F),
    UnicodeRange(0X202A, 0X202E),
    UnicodeRange(0X2060, 0X2064),
    UnicodeRange(0X2066, 0X206F),
    UnicodeRange(0X2D20, 0X2D2F),
    UnicodeRange(0X2D30, 0X2D67),
    UnicodeRange(0X2D6F, 0X2D6F),
    UnicodeRange(0X2D80, 0X2D96),
    UnicodeRange(0X2DA0, 0X2DA6),
    UnicodeRange(0X2DA8, 0X2DAE),
    UnicodeRange(0X2DB0, 0X2DB6),
    UnicodeRange(0X2DB8, 0X2DBE),
    UnicodeRange(0X2DC0, 0X2DC6),
    UnicodeRange(0X2DC8, 0X2DCE),
    UnicodeRange(0X2DD0, 0X2DD6),
    UnicodeRange(0X2DD8, 0X2DDE),
    UnicodeRange(0X3029, 0X302D),
    UnicodeRange(0X3099, 0X309A),
    UnicodeRange(0XA66F, 0XA66F),
    UnicodeRange(0XA674, 0XA67D),
    UnicodeRange(0XA69F, 0XA69F),
    UnicodeRange(0XA6F0, 0XA6F1),
    UnicodeRange(0XA802, 0XA802),
    UnicodeRange(0XA806, 0XA806),
    UnicodeRange(0XA80B, 0XA80B),
    UnicodeRange(0XA825, 0XA826),
    UnicodeRange(0XA8C4, 0XA8C4),
    UnicodeRange(0XA8E0, 0XA8E1),
    UnicodeRange(0XA926, 0XA92D),
    UnicodeRange(0XA947, 0XA951),
    UnicodeRange(0XA980, 0XA982),
    UnicodeRange(0XA9B3, 0XA9B3),
    UnicodeRange(0XA9B6, 0XA9B9),
    UnicodeRange(0XA9BC, 0XA9BC),
    UnicodeRange(0XAA29, 0XAA2E),
    UnicodeRange(0XAA31, 0XAA32),
    UnicodeRange(0XAA35, 0XAA36),
    UnicodeRange(0XAA43, 0XAA43),
    UnicodeRange(0XAA4C, 0XAA4C),
    UnicodeRange(0XAAB0, 0XAAB0),
    UnicodeRange(0XAAB2, 0XAAB4),
    UnicodeRange(0XAAB7, 0XAAB8),
    UnicodeRange(0XAABE, 0XAABF),
    UnicodeRange(0XAAC1, 0XAAC1),
    UnicodeRange(0XAAEB, 0XAAEB),
    UnicodeRange(0XAAEE, 0XAAEF),
    UnicodeRange(0XAAF5, 0XAAF5),
    UnicodeRange(0XABE3, 0XABE4),
    UnicodeRange(0XABE6, 0XABE7),
    UnicodeRange(0XABE9, 0XABEA),
    UnicodeRange(0XABEC, 0XABED),
    UnicodeRange(0XFB1E, 0XFB1E),
    UnicodeRange(0XFE00, 0XFE0F),
    UnicodeRange(0XFE20, 0XFE26),
    UnicodeRange(0XFEFF, 0XFEFF),
    UnicodeRange(0X10A01, 0X10A03),
    UnicodeRange(0X10A05, 0X10A06),
    UnicodeRange(0X10A0C, 0X10A0F),
    UnicodeRange(0X10A38, 0X10A3A),
    UnicodeRange(0X10A3F, 0X10A3F),
    UnicodeRange(0X1D167, 0X1D169),
    UnicodeRange(0X1D17B, 0X1D182),
    UnicodeRange(0X1D185, 0X1D18B),
    UnicodeRange(0X1D1AA, 0X1D1AD),
    UnicodeRange(0X1D242, 0X1D244),
    UnicodeRange(0X1E000, 0X1E006),
    UnicodeRange(0X1E008, 0X1E018),
    UnicodeRange(0X1E01B, 0X1E021),
    UnicodeRange(0X1E023, 0X1E024),
    UnicodeRange(0X1E026, 0X1E02A),
    UnicodeRange(0X1E8D0, 0X1E8D6),
    UnicodeRange(0X1E944, 0X1E94A)
]

/**
 * denotes a code point uppercase-lowercase pattern
 */
const UPPERLOWER: Int32 = 0xFFFFFF
const SPECIAL_UNICODE: Int32 = 0xFFFFFE
const GREECE_RUNE_LEFT_INTERVAL: UInt32 = 0x0370
const GREECE_RUNE_RIGHT_INTERVAL: UInt32 = 0x03FF
let GREECE_PUNCTUATION: Array<UInt32> = [0x0374, 0x0375, 0x037A, 0x037E, 0x0384, 0x0385, 0x0387]
let CAPITAL_I: UInt32 = 0x0049
let SMALL_I: UInt32 = 0x0069
let CAPITAL_J: UInt32 = 0x004A
let SMALL_J: UInt32 = 0x006A
let CAPITAL_I_OGONEK: UInt32 = 0x012E
let SMALL_I_OGONEK: UInt32 = 0x012F
let CAPITAL_I_WITH_DOT_ABOVE: UInt32 = 0x0130
let SMALL_I_WITHOUT_DOT_ABOVE: UInt32 = 0x0131
let CAPITAL_SIGMA: UInt32 = 0x03A3
let SMALL_SIGMA_END: UInt32 = 0x03C2
let DOT_ABOVE: UInt32 = 0x0307
let ABOVE_COMBINING_MARK_RANGES: Array<UnicodeRange> = [
    UnicodeRange(0x0300, 0x0314),
    UnicodeRange(0x0342, 0x0345),
    UnicodeRange(0x034A, 0x034E),
    UnicodeRange(0x0350, 0x0357),
    UnicodeRange(0x035D, 0x0363),
    UnicodeRange(0x0366, 0x036F),
    UnicodeRange(0x1DC0, 0x1DFF),
    UnicodeRange(0x20D0, 0x20F0),
    UnicodeRange(0xFE20, 0xFE26)
]
let LITHUANIA_SPECIAL_RUNE = HashMap<UInt32, Array<UInt32>>(
    [
        (0x00CC, [0x0069, 0x0307, 0x0300]),
        (0x00CD, [0x0069, 0x0307, 0x0301]),
        (0x0128, [0x0069, 0x0307, 0x0303])
    ]
)

/**
 * these case ranges are sorted by start offset, and do not overlap
 * so we can do a binary search
 */
let CASE_RANGES: Array<CaseRange> = [
    CaseRange(0x0041, 0x005A, 0, 32, 0),
    CaseRange(0x0061, 0x007A, -32, 0, -32),
    CaseRange(0x00B5, 0x00B5, 743, 0, 743),
    CaseRange(0x00C0, 0x00D6, 0, 32, 0),
    CaseRange(0x00D8, 0x00DE, 0, 32, 0),
    CaseRange(0x00DF, 0x00DF, SPECIAL_UNICODE, SPECIAL_UNICODE, SPECIAL_UNICODE),
    CaseRange(0x00E0, 0x00F6, -32, 0, -32),
    CaseRange(0x00F8, 0x00FE, -32, 0, -32),
    CaseRange(0x00FF, 0x00FF, 121, 0, 121),
    CaseRange(0x0100, 0x012F, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x0130, 0x0130, 0, SPECIAL_UNICODE, 0),
    CaseRange(0x0131, 0x0131, -232, 0, -232),
    CaseRange(0x0132, 0x0137, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x0139, 0x0148, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x0149, 0x0149, SPECIAL_UNICODE, SPECIAL_UNICODE, SPECIAL_UNICODE),
    CaseRange(0x014A, 0x0177, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x0178, 0x0178, 0, -121, 0),
    CaseRange(0x0179, 0x017E, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x017F, 0x017F, -300, 0, -300),
    CaseRange(0x0180, 0x0180, 195, 0, 195),
    CaseRange(0x0181, 0x0181, 0, 210, 0),
    CaseRange(0x0182, 0x0185, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x0186, 0x0186, 0, 206, 0),
    CaseRange(0x0187, 0x0188, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x0189, 0x018A, 0, 205, 0),
    CaseRange(0x018B, 0x018C, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x018E, 0x018E, 0, 79, 0),
    CaseRange(0x018F, 0x018F, 0, 202, 0),
    CaseRange(0x0190, 0x0190, 0, 203, 0),
    CaseRange(0x0191, 0x0192, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x0193, 0x0193, 0, 205, 0),
    CaseRange(0x0194, 0x0194, 0, 207, 0),
    CaseRange(0x0195, 0x0195, 97, 0, 97),
    CaseRange(0x0196, 0x0196, 0, 211, 0),
    CaseRange(0x0197, 0x0197, 0, 209, 0),
    CaseRange(0x0198, 0x0199, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x019A, 0x019A, 163, 0, 163),
    CaseRange(0x019C, 0x019C, 0, 211, 0),
    CaseRange(0x019D, 0x019D, 0, 213, 0),
    CaseRange(0x019E, 0x019E, 130, 0, 130),
    CaseRange(0x019F, 0x019F, 0, 214, 0),
    CaseRange(0x01A0, 0x01A5, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x01A6, 0x01A6, 0, 218, 0),
    CaseRange(0x01A7, 0x01A8, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x01A9, 0x01A9, 0, 218, 0),
    CaseRange(0x01AC, 0x01AD, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x01AE, 0x01AE, 0, 218, 0),
    CaseRange(0x01AF, 0x01B0, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x01B1, 0x01B2, 0, 217, 0),
    CaseRange(0x01B3, 0x01B6, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x01B7, 0x01B7, 0, 219, 0),
    CaseRange(0x01B8, 0x01B9, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x01BC, 0x01BD, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x01BF, 0x01BF, 56, 0, 56),
    CaseRange(0x01C4, 0x01C4, 0, 2, 1),
    CaseRange(0x01C5, 0x01C5, -1, 1, 0),
    CaseRange(0x01C6, 0x01C6, -2, 0, -1),
    CaseRange(0x01C7, 0x01C7, 0, 2, 1),
    CaseRange(0x01C8, 0x01C8, -1, 1, 0),
    CaseRange(0x01C9, 0x01C9, -2, 0, -1),
    CaseRange(0x01CA, 0x01CA, 0, 2, 1),
    CaseRange(0x01CB, 0x01CB, -1, 1, 0),
    CaseRange(0x01CC, 0x01CC, -2, 0, -1),
    CaseRange(0x01CD, 0x01DC, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x01DD, 0x01DD, -79, 0, -79),
    CaseRange(0x01DE, 0x01EF, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x01F0, 0x01F0, SPECIAL_UNICODE, SPECIAL_UNICODE, SPECIAL_UNICODE),
    CaseRange(0x01F1, 0x01F1, 0, 2, 1),
    CaseRange(0x01F2, 0x01F2, -1, 1, 0),
    CaseRange(0x01F3, 0x01F3, -2, 0, -1),
    CaseRange(0x01F4, 0x01F5, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x01F6, 0x01F6, 0, -97, 0),
    CaseRange(0x01F7, 0x01F7, 0, -56, 0),
    CaseRange(0x01F8, 0x021F, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x0220, 0x0220, 0, -130, 0),
    CaseRange(0x0222, 0x0233, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x023A, 0x023A, 0, 10795, 0),
    CaseRange(0x023B, 0x023C, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x023D, 0x023D, 0, -163, 0),
    CaseRange(0x023E, 0x023E, 0, 10792, 0),
    CaseRange(0x023F, 0x0240, 10815, 0, 10815),
    CaseRange(0x0241, 0x0242, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x0243, 0x0243, 0, -195, 0),
    CaseRange(0x0244, 0x0244, 0, 69, 0),
    CaseRange(0x0245, 0x0245, 0, 71, 0),
    CaseRange(0x0246, 0x024F, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x0250, 0x0250, 10783, 0, 10783),
    CaseRange(0x0251, 0x0251, 10780, 0, 10780),
    CaseRange(0x0252, 0x0252, 10782, 0, 10782),
    CaseRange(0x0253, 0x0253, -210, 0, -210),
    CaseRange(0x0254, 0x0254, -206, 0, -206),
    CaseRange(0x0256, 0x0257, -205, 0, -205),
    CaseRange(0x0259, 0x0259, -202, 0, -202),
    CaseRange(0x025B, 0x025B, -203, 0, -203),
    CaseRange(0x025C, 0x025C, 42319, 0, 42319),
    CaseRange(0x0260, 0x0260, -205, 0, -205),
    CaseRange(0x0261, 0x0261, 42315, 0, 42315),
    CaseRange(0x0263, 0x0263, -207, 0, -207),
    CaseRange(0x0265, 0x0265, 42280, 0, 42280),
    CaseRange(0x0266, 0x0266, 42308, 0, 42308),
    CaseRange(0x0268, 0x0268, -209, 0, -209),
    CaseRange(0x0269, 0x0269, -211, 0, -211),
    CaseRange(0x026A, 0x026A, 42308, 0, 42308),
    CaseRange(0x026B, 0x026B, 10743, 0, 10743),
    CaseRange(0x026C, 0x026C, 42305, 0, 42305),
    CaseRange(0x026F, 0x026F, -211, 0, -211),
    CaseRange(0x0271, 0x0271, 10749, 0, 10749),
    CaseRange(0x0272, 0x0272, -213, 0, -213),
    CaseRange(0x0275, 0x0275, -214, 0, -214),
    CaseRange(0x027D, 0x027D, 10727, 0, 10727),
    CaseRange(0x0280, 0x0280, -218, 0, -218),
    CaseRange(0x0283, 0x0283, -218, 0, -218),
    CaseRange(0x0287, 0x0287, 42282, 0, 42282),
    CaseRange(0x0288, 0x0288, -218, 0, -218),
    CaseRange(0x0289, 0x0289, -69, 0, -69),
    CaseRange(0x028A, 0x028B, -217, 0, -217),
    CaseRange(0x028C, 0x028C, -71, 0, -71),
    CaseRange(0x0292, 0x0292, -219, 0, -219),
    CaseRange(0x029D, 0x029D, 42261, 0, 42261),
    CaseRange(0x029E, 0x029E, 42258, 0, 42258),
    CaseRange(0x0345, 0x0345, 84, 0, 84),
    CaseRange(0x0370, 0x0373, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x0376, 0x0377, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x037B, 0x037D, 130, 0, 130),
    CaseRange(0x037F, 0x037F, 0, 116, 0),
    CaseRange(0x0386, 0x0386, 0, 38, 0),
    CaseRange(0x0388, 0x038A, 0, 37, 0),
    CaseRange(0x038C, 0x038C, 0, 64, 0),
    CaseRange(0x038E, 0x038F, 0, 63, 0),
    CaseRange(0x0390, 0x0390, SPECIAL_UNICODE, SPECIAL_UNICODE, SPECIAL_UNICODE),
    CaseRange(0x0391, 0x03A1, 0, 32, 0),
    CaseRange(0x03A3, 0x03AB, 0, 32, 0),
    CaseRange(0x03AC, 0x03AC, -38, 0, -38),
    CaseRange(0x03AD, 0x03AF, -37, 0, -37),
    CaseRange(0x03B0, 0x03B0, SPECIAL_UNICODE, SPECIAL_UNICODE, SPECIAL_UNICODE),
    CaseRange(0x03B1, 0x03C1, -32, 0, -32),
    CaseRange(0x03C2, 0x03C2, -31, 0, -31),
    CaseRange(0x03C3, 0x03CB, -32, 0, -32),
    CaseRange(0x03CC, 0x03CC, -64, 0, -64),
    CaseRange(0x03CD, 0x03CE, -63, 0, -63),
    CaseRange(0x03CF, 0x03CF, 0, 8, 0),
    CaseRange(0x03D0, 0x03D0, -62, 0, -62),
    CaseRange(0x03D1, 0x03D1, -57, 0, -57),
    CaseRange(0x03D5, 0x03D5, -47, 0, -47),
    CaseRange(0x03D6, 0x03D6, -54, 0, -54),
    CaseRange(0x03D7, 0x03D7, -8, 0, -8),
    CaseRange(0x03D8, 0x03EF, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x03F0, 0x03F0, -86, 0, -86),
    CaseRange(0x03F1, 0x03F1, -80, 0, -80),
    CaseRange(0x03F2, 0x03F2, 7, 0, 7),
    CaseRange(0x03F3, 0x03F3, -116, 0, -116),
    CaseRange(0x03F4, 0x03F4, 0, -60, 0),
    CaseRange(0x03F5, 0x03F5, -96, 0, -96),
    CaseRange(0x03F7, 0x03F8, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x03F9, 0x03F9, 0, -7, 0),
    CaseRange(0x03FA, 0x03FB, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x03FD, 0x03FF, 0, -130, 0),
    CaseRange(0x0400, 0x040F, 0, 80, 0),
    CaseRange(0x0410, 0x042F, 0, 32, 0),
    CaseRange(0x0430, 0x044F, -32, 0, -32),
    CaseRange(0x0450, 0x045F, -80, 0, -80),
    CaseRange(0x0460, 0x0481, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x048A, 0x04BF, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x04C0, 0x04C0, 0, 15, 0),
    CaseRange(0x04C1, 0x04CE, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x04CF, 0x04CF, -15, 0, -15),
    CaseRange(0x04D0, 0x052F, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x0531, 0x0556, 0, 48, 0),
    CaseRange(0x0561, 0x0586, -48, 0, -48),
    CaseRange(0x0587, 0x0587, SPECIAL_UNICODE, SPECIAL_UNICODE, SPECIAL_UNICODE),
    CaseRange(0x10A0, 0x10C5, 0, 7264, 0),
    CaseRange(0x10C7, 0x10C7, 0, 7264, 0),
    CaseRange(0x10CD, 0x10CD, 0, 7264, 0),
    CaseRange(0x13A0, 0x13EF, 0, 38864, 0),
    CaseRange(0x13F0, 0x13F5, 0, 8, 0),
    CaseRange(0x13F8, 0x13FD, -8, 0, -8),
    CaseRange(0x1C80, 0x1C80, -6254, 0, -6254),
    CaseRange(0x1C81, 0x1C81, -6253, 0, -6253),
    CaseRange(0x1C82, 0x1C82, -6244, 0, -6244),
    CaseRange(0x1C83, 0x1C84, -6242, 0, -6242),
    CaseRange(0x1C85, 0x1C85, -6243, 0, -6243),
    CaseRange(0x1C86, 0x1C86, -6236, 0, -6236),
    CaseRange(0x1C87, 0x1C87, -6181, 0, -6181),
    CaseRange(0x1C88, 0x1C88, 35266, 0, 35266),
    CaseRange(0x1D79, 0x1D79, 35332, 0, 35332),
    CaseRange(0x1D7D, 0x1D7D, 3814, 0, 3814),
    CaseRange(0x1E00, 0x1E95, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x1E96, 0x1E9A, SPECIAL_UNICODE, SPECIAL_UNICODE, SPECIAL_UNICODE),
    CaseRange(0x1E9B, 0x1E9B, -59, 0, -59),
    CaseRange(0x1E9E, 0x1E9E, 0, -7615, 0),
    CaseRange(0x1EA0, 0x1EFF, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x1F00, 0x1F07, 8, 0, 8),
    CaseRange(0x1F08, 0x1F0F, 0, -8, 0),
    CaseRange(0x1F10, 0x1F15, 8, 0, 8),
    CaseRange(0x1F18, 0x1F1D, 0, -8, 0),
    CaseRange(0x1F20, 0x1F27, 8, 0, 8),
    CaseRange(0x1F28, 0x1F2F, 0, -8, 0),
    CaseRange(0x1F30, 0x1F37, 8, 0, 8),
    CaseRange(0x1F38, 0x1F3F, 0, -8, 0),
    CaseRange(0x1F40, 0x1F45, 8, 0, 8),
    CaseRange(0x1F48, 0x1F4D, 0, -8, 0),
    CaseRange(0x1F50, 0x1F50, SPECIAL_UNICODE, SPECIAL_UNICODE, SPECIAL_UNICODE),
    CaseRange(0x1F51, 0x1F51, 8, 0, 8),
    CaseRange(0x1F52, 0x1F52, SPECIAL_UNICODE, SPECIAL_UNICODE, SPECIAL_UNICODE),
    CaseRange(0x1F53, 0x1F53, 8, 0, 8),
    CaseRange(0x1F54, 0x1F54, SPECIAL_UNICODE, SPECIAL_UNICODE, SPECIAL_UNICODE),
    CaseRange(0x1F55, 0x1F55, 8, 0, 8),
    CaseRange(0x1F56, 0x1F56, SPECIAL_UNICODE, SPECIAL_UNICODE, SPECIAL_UNICODE),
    CaseRange(0x1F57, 0x1F57, 8, 0, 8),
    CaseRange(0x1F59, 0x1F59, 0, -8, 0),
    CaseRange(0x1F5B, 0x1F5B, 0, -8, 0),
    CaseRange(0x1F5D, 0x1F5D, 0, -8, 0),
    CaseRange(0x1F5F, 0x1F5F, 0, -8, 0),
    CaseRange(0x1F60, 0x1F67, 8, 0, 8),
    CaseRange(0x1F68, 0x1F6F, 0, -8, 0),
    CaseRange(0x1F70, 0x1F71, 74, 0, 74),
    CaseRange(0x1F72, 0x1F75, 86, 0, 86),
    CaseRange(0x1F76, 0x1F77, 100, 0, 100),
    CaseRange(0x1F78, 0x1F79, 128, 0, 128),
    CaseRange(0x1F7A, 0x1F7B, 112, 0, 112),
    CaseRange(0x1F7C, 0x1F7D, 126, 0, 126),
    CaseRange(0x1F80, 0x1F87, SPECIAL_UNICODE, 0, 8),
    CaseRange(0x1F88, 0x1F8F, SPECIAL_UNICODE, -8, 0),
    CaseRange(0x1F90, 0x1F97, SPECIAL_UNICODE, 0, 8),
    CaseRange(0x1F98, 0x1F9F, SPECIAL_UNICODE, -8, 0),
    CaseRange(0x1FA0, 0x1FA7, SPECIAL_UNICODE, 0, 8),
    CaseRange(0x1FA8, 0x1FAF, SPECIAL_UNICODE, -8, 0),
    CaseRange(0x1FB0, 0x1FB1, 8, 0, 8),
    CaseRange(0x1FB2, 0x1FB2, SPECIAL_UNICODE, SPECIAL_UNICODE, SPECIAL_UNICODE),
    CaseRange(0x1FB3, 0x1FB3, SPECIAL_UNICODE, 0, 9),
    CaseRange(0x1FB4, 0x1FB4, SPECIAL_UNICODE, SPECIAL_UNICODE, SPECIAL_UNICODE),
    CaseRange(0x1FB6, 0x1FB6, SPECIAL_UNICODE, SPECIAL_UNICODE, SPECIAL_UNICODE),
    CaseRange(0x1FB7, 0x1FB7, SPECIAL_UNICODE, SPECIAL_UNICODE, SPECIAL_UNICODE),
    CaseRange(0x1FB8, 0x1FB9, 0, -8, 0),
    CaseRange(0x1FBA, 0x1FBB, 0, -74, 0),
    CaseRange(0x1FBC, 0x1FBC, SPECIAL_UNICODE, -9, 0),
    CaseRange(0x1FBE, 0x1FBE, -7205, 0, -7205),
    CaseRange(0x1FC2, 0x1FC2, SPECIAL_UNICODE, SPECIAL_UNICODE, SPECIAL_UNICODE),
    CaseRange(0x1FC3, 0x1FC3, SPECIAL_UNICODE, 0, 9),
    CaseRange(0x1FC4, 0x1FC4, SPECIAL_UNICODE, SPECIAL_UNICODE, SPECIAL_UNICODE),
    CaseRange(0x1FC6, 0x1FC6, SPECIAL_UNICODE, SPECIAL_UNICODE, SPECIAL_UNICODE),
    CaseRange(0x1FC7, 0x1FC7, SPECIAL_UNICODE, SPECIAL_UNICODE, SPECIAL_UNICODE),
    CaseRange(0x1FC8, 0x1FCB, 0, -86, 0),
    CaseRange(0x1FCC, 0x1FCC, SPECIAL_UNICODE, -9, 0),
    CaseRange(0x1FD0, 0x1FD1, 8, 0, 8),
    CaseRange(0x1FD2, 0x1FD3, SPECIAL_UNICODE, SPECIAL_UNICODE, SPECIAL_UNICODE),
    CaseRange(0x1FD6, 0x1FD7, SPECIAL_UNICODE, SPECIAL_UNICODE, SPECIAL_UNICODE),
    CaseRange(0x1FD8, 0x1FD9, 0, -8, 0),
    CaseRange(0x1FDA, 0x1FDB, 0, -100, 0),
    CaseRange(0x1FE0, 0x1FE1, 8, 0, 8),
    CaseRange(0x1FE2, 0x1FE4, SPECIAL_UNICODE, SPECIAL_UNICODE, SPECIAL_UNICODE),
    CaseRange(0x1FE5, 0x1FE5, 7, 0, 7),
    CaseRange(0x1FE6, 0x1FE7, SPECIAL_UNICODE, SPECIAL_UNICODE, SPECIAL_UNICODE),
    CaseRange(0x1FE8, 0x1FE9, 0, -8, 0),
    CaseRange(0x1FEA, 0x1FEB, 0, -112, 0),
    CaseRange(0x1FEC, 0x1FEC, 0, -7, 0),
    CaseRange(0x1FF2, 0x1FF2, SPECIAL_UNICODE, SPECIAL_UNICODE, SPECIAL_UNICODE),
    CaseRange(0x1FF3, 0x1FF3, SPECIAL_UNICODE, 0, 9),
    CaseRange(0x1FF4, 0x1FF4, SPECIAL_UNICODE, SPECIAL_UNICODE, SPECIAL_UNICODE),
    CaseRange(0x1FF6, 0x1FF6, SPECIAL_UNICODE, SPECIAL_UNICODE, SPECIAL_UNICODE),
    CaseRange(0x1FF7, 0x1FF7, SPECIAL_UNICODE, SPECIAL_UNICODE, SPECIAL_UNICODE),
    CaseRange(0x1FF8, 0x1FF9, 0, -128, 0),
    CaseRange(0x1FFA, 0x1FFB, 0, -126, 0),
    CaseRange(0x1FFC, 0x1FFC, SPECIAL_UNICODE, -9, 0),
    CaseRange(0x2126, 0x2126, 0, -7517, 0),
    CaseRange(0x212A, 0x212A, 0, -8383, 0),
    CaseRange(0x212B, 0x212B, 0, -8262, 0),
    CaseRange(0x2132, 0x2132, 0, 28, 0),
    CaseRange(0x214E, 0x214E, -28, 0, -28),
    CaseRange(0x2160, 0x216F, 0, 16, 0),
    CaseRange(0x2170, 0x217F, -16, 0, -16),
    CaseRange(0x2183, 0x2184, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x24B6, 0x24CF, 0, 26, 0),
    CaseRange(0x24D0, 0x24E9, -26, 0, -26),
    CaseRange(0x2C00, 0x2C2E, 0, 48, 0),
    CaseRange(0x2C30, 0x2C5E, -48, 0, -48),
    CaseRange(0x2C60, 0x2C61, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x2C62, 0x2C62, 0, -10743, 0),
    CaseRange(0x2C63, 0x2C63, 0, -3814, 0),
    CaseRange(0x2C64, 0x2C64, 0, -10727, 0),
    CaseRange(0x2C65, 0x2C65, -10795, 0, -10795),
    CaseRange(0x2C66, 0x2C66, -10792, 0, -10792),
    CaseRange(0x2C67, 0x2C6C, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x2C6D, 0x2C6D, 0, -10780, 0),
    CaseRange(0x2C6E, 0x2C6E, 0, -10749, 0),
    CaseRange(0x2C6F, 0x2C6F, 0, -10783, 0),
    CaseRange(0x2C70, 0x2C70, 0, -10782, 0),
    CaseRange(0x2C72, 0x2C73, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x2C75, 0x2C76, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x2C7E, 0x2C7F, 0, -10815, 0),
    CaseRange(0x2C80, 0x2CE3, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x2CEB, 0x2CEE, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x2CF2, 0x2CF3, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0x2D00, 0x2D25, -7264, 0, -7264),
    CaseRange(0x2D27, 0x2D27, -7264, 0, -7264),
    CaseRange(0x2D2D, 0x2D2D, -7264, 0, -7264),
    CaseRange(0xA640, 0xA66D, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0xA680, 0xA69B, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0xA722, 0xA72F, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0xA732, 0xA76F, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0xA779, 0xA77C, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0xA77D, 0xA77D, 0, -35332, 0),
    CaseRange(0xA77E, 0xA787, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0xA78B, 0xA78C, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0xA78D, 0xA78D, 0, -42280, 0),
    CaseRange(0xA790, 0xA793, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0xA796, 0xA7A9, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0xA7AA, 0xA7AA, 0, -42308, 0),
    CaseRange(0xA7AB, 0xA7AB, 0, -42319, 0),
    CaseRange(0xA7AC, 0xA7AC, 0, -42315, 0),
    CaseRange(0xA7AD, 0xA7AD, 0, -42305, 0),
    CaseRange(0xA7AE, 0xA7AE, 0, -42308, 0),
    CaseRange(0xA7B0, 0xA7B0, 0, -42258, 0),
    CaseRange(0xA7B1, 0xA7B1, 0, -42282, 0),
    CaseRange(0xA7B2, 0xA7B2, 0, -42261, 0),
    CaseRange(0xA7B3, 0xA7B3, 0, 928, 0),
    CaseRange(0xA7B4, 0xA7B7, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0xA7B8, 0xA7BF, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0xA7C0, 0xA7C3, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0xA7C4, 0xA7C4, 0, -48, 0),
    CaseRange(0xA7C5, 0xA7C5, 0, -42307, 0),
    CaseRange(0xA7C6, 0xA7C6, 0, -35384, 0),
    CaseRange(0xA7C7, 0xA7CA, UPPERLOWER, UPPERLOWER, UPPERLOWER),
    CaseRange(0xAB53, 0xAB53, -928, 0, -928),
    CaseRange(0xAB70, 0xABBF, -38864, 0, -38864),
    CaseRange(0xFB00, 0xFB06, SPECIAL_UNICODE, SPECIAL_UNICODE, SPECIAL_UNICODE),
    CaseRange(0xFB13, 0xFB17, SPECIAL_UNICODE, SPECIAL_UNICODE, SPECIAL_UNICODE),
    CaseRange(0xFF21, 0xFF3A, 0, 32, 0),
    CaseRange(0xFF41, 0xFF5A, -32, 0, -32),
    CaseRange(0x10400, 0x10427, 0, 40, 0),
    CaseRange(0x10428, 0x1044F, -40, 0, -40),
    CaseRange(0x104B0, 0x104D3, 0, 40, 0),
    CaseRange(0x104D8, 0x104FB, -40, 0, -40),
    CaseRange(0x10C80, 0x10CB2, 0, 64, 0),
    CaseRange(0x10CC0, 0x10CF2, -64, 0, -64),
    CaseRange(0x118A0, 0x118BF, 0, 32, 0),
    CaseRange(0x118C0, 0x118DF, -32, 0, -32),
    CaseRange(0x1E900, 0x1E921, 0, 34, 0),
    CaseRange(0x1E922, 0x1E943, -34, 0, -34)
]
let SPECIAL_CASE_RANGES: Array<SpecialCaseRange> = [
    SpecialCaseRange(0x00DF, [0x00DF], [0x0053, 0x0073], [0x0053, 0x0053]),
    SpecialCaseRange(0x0130, [0x0069, 0x0307], [0x0130], [0x0130]),
    SpecialCaseRange(0x0149, [0x0149], [0x02BC, 0x004E], [0x02BC, 0x004E]),
    SpecialCaseRange(0x01F0, [0x01F0], [0x004A, 0x030C], [0x004A, 0x030C]),
    SpecialCaseRange(0x0390, [0x0390], [0x0399, 0x0308, 0x0301], [0x0399, 0x0308, 0x0301]),
    SpecialCaseRange(0x03B0, [0x03B0], [0x03A5, 0x0308, 0x0301], [0x03A5, 0x0308, 0x0301]),
    SpecialCaseRange(0x0587, [0x0587], [0x0535, 0x0582], [0x0535, 0x0552]),
    SpecialCaseRange(0x1E96, [0x1E96], [0x0048, 0x0331], [0x0048, 0x0331]),
    SpecialCaseRange(0x1E97, [0x1E97], [0x0054, 0x0308], [0x0054, 0x0308]),
    SpecialCaseRange(0x1E98, [0x1E98], [0x0057, 0x030A], [0x0057, 0x030A]),
    SpecialCaseRange(0x1E99, [0x1E99], [0x0059, 0x030A], [0x0059, 0x030A]),
    SpecialCaseRange(0x1E9A, [0x1E9A], [0x0041, 0x02BE], [0x0041, 0x02BE]),
    SpecialCaseRange(0x1F50, [0x1F50], [0x03A5, 0x0313], [0x03A5, 0x0313]),
    SpecialCaseRange(0x1F52, [0x1F52], [0x03A5, 0x0313, 0x0300], [0x03A5, 0x0313, 0x0300]),
    SpecialCaseRange(0x1F54, [0x1F54], [0x03A5, 0x0313, 0x0301], [0x03A5, 0x0313, 0x0301]),
    SpecialCaseRange(0x1F56, [0x1F56], [0x03A5, 0x0313, 0x0342], [0x03A5, 0x0313, 0x0342]),
    SpecialCaseRange(0x1F80, [0x1F80], [0x1F88], [0x1F08, 0x0399]),
    SpecialCaseRange(0x1F81, [0x1F81], [0x1F89], [0x1F09, 0x0399]),
    SpecialCaseRange(0x1F82, [0x1F82], [0x1F8A], [0x1F0A, 0x0399]),
    SpecialCaseRange(0x1F83, [0x1F83], [0x1F8B], [0x1F0B, 0x0399]),
    SpecialCaseRange(0x1F84, [0x1F84], [0x1F8C], [0x1F0C, 0x0399]),
    SpecialCaseRange(0x1F85, [0x1F85], [0x1F8D], [0x1F0D, 0x0399]),
    SpecialCaseRange(0x1F86, [0x1F86], [0x1F8E], [0x1F0E, 0x0399]),
    SpecialCaseRange(0x1F87, [0x1F87], [0x1F8F], [0x1F0F, 0x0399]),
    SpecialCaseRange(0x1F88, [0x1F80], [0x1F88], [0x1F08, 0x0399]),
    SpecialCaseRange(0x1F89, [0x1F81], [0x1F89], [0x1F09, 0x0399]),
    SpecialCaseRange(0x1F8A, [0x1F82], [0x1F8A], [0x1F0A, 0x0399]),
    SpecialCaseRange(0x1F8B, [0x1F83], [0x1F8B], [0x1F0B, 0x0399]),
    SpecialCaseRange(0x1F8C, [0x1F84], [0x1F8C], [0x1F0C, 0x0399]),
    SpecialCaseRange(0x1F8D, [0x1F85], [0x1F8D], [0x1F0D, 0x0399]),
    SpecialCaseRange(0x1F8E, [0x1F86], [0x1F8E], [0x1F0E, 0x0399]),
    SpecialCaseRange(0x1F8F, [0x1F87], [0x1F8F], [0x1F0F, 0x0399]),
    SpecialCaseRange(0x1F90, [0x1F90], [0x1F98], [0x1F28, 0x0399]),
    SpecialCaseRange(0x1F91, [0x1F91], [0x1F99], [0x1F29, 0x0399]),
    SpecialCaseRange(0x1F92, [0x1F92], [0x1F9A], [0x1F2A, 0x0399]),
    SpecialCaseRange(0x1F93, [0x1F93], [0x1F9B], [0x1F2B, 0x0399]),
    SpecialCaseRange(0x1F94, [0x1F94], [0x1F9C], [0x1F2C, 0x0399]),
    SpecialCaseRange(0x1F95, [0x1F95], [0x1F9D], [0x1F2D, 0x0399]),
    SpecialCaseRange(0x1F96, [0x1F96], [0x1F9E], [0x1F2E, 0x0399]),
    SpecialCaseRange(0x1F97, [0x1F97], [0x1F9F], [0x1F2F, 0x0399]),
    SpecialCaseRange(0x1F98, [0x1F90], [0x1F98], [0x1F28, 0x0399]),
    SpecialCaseRange(0x1F99, [0x1F91], [0x1F99], [0x1F29, 0x0399]),
    SpecialCaseRange(0x1F9A, [0x1F92], [0x1F9A], [0x1F2A, 0x0399]),
    SpecialCaseRange(0x1F9B, [0x1F93], [0x1F9B], [0x1F2B, 0x0399]),
    SpecialCaseRange(0x1F9C, [0x1F94], [0x1F9C], [0x1F2C, 0x0399]),
    SpecialCaseRange(0x1F9D, [0x1F95], [0x1F9D], [0x1F2D, 0x0399]),
    SpecialCaseRange(0x1F9E, [0x1F96], [0x1F9E], [0x1F2E, 0x0399]),
    SpecialCaseRange(0x1F9F, [0x1F97], [0x1F9F], [0x1F2F, 0x0399]),
    SpecialCaseRange(0x1FA0, [0x1FA0], [0x1FA8], [0x1F68, 0x0399]),
    SpecialCaseRange(0x1FA1, [0x1FA1], [0x1FA9], [0x1F69, 0x0399]),
    SpecialCaseRange(0x1FA2, [0x1FA2], [0x1FAA], [0x1F6A, 0x0399]),
    SpecialCaseRange(0x1FA3, [0x1FA3], [0x1FAB], [0x1F6B, 0x0399]),
    SpecialCaseRange(0x1FA4, [0x1FA4], [0x1FAC], [0x1F6C, 0x0399]),
    SpecialCaseRange(0x1FA5, [0x1FA5], [0x1FAD], [0x1F6D, 0x0399]),
    SpecialCaseRange(0x1FA6, [0x1FA6], [0x1FAE], [0x1F6E, 0x0399]),
    SpecialCaseRange(0x1FA7, [0x1FA7], [0x1FAF], [0x1F6F, 0x0399]),
    SpecialCaseRange(0x1FA8, [0x1FA0], [0x1FA8], [0x1F68, 0x0399]),
    SpecialCaseRange(0x1FA9, [0x1FA1], [0x1FA9], [0x1F69, 0x0399]),
    SpecialCaseRange(0x1FAA, [0x1FA2], [0x1FAA], [0x1F6A, 0x0399]),
    SpecialCaseRange(0x1FAB, [0x1FA3], [0x1FAB], [0x1F6B, 0x0399]),
    SpecialCaseRange(0x1FAC, [0x1FA4], [0x1FAC], [0x1F6C, 0x0399]),
    SpecialCaseRange(0x1FAD, [0x1FA5], [0x1FAD], [0x1F6D, 0x0399]),
    SpecialCaseRange(0x1FAE, [0x1FA6], [0x1FAE], [0x1F6E, 0x0399]),
    SpecialCaseRange(0x1FAF, [0x1FA7], [0x1FAF], [0x1F6F, 0x0399]),
    SpecialCaseRange(0x1FB2, [0x1FB2], [0x1FBA, 0x0345], [0x1FBA, 0x0399]),
    SpecialCaseRange(0x1FB3, [0x1FB3], [0x1FBC], [0x0391, 0x0399]),
    SpecialCaseRange(0x1FB4, [0x1FB4], [0x0386, 0x0345], [0x0386, 0x0399]),
    SpecialCaseRange(0x1FB6, [0x1FB6], [0x0391, 0x0342], [0x0391, 0x0342]),
    SpecialCaseRange(0x1FB7, [0x1FB7], [0x0391, 0x0342, 0x0345], [0x0391, 0x0342, 0x0399]),
    SpecialCaseRange(0x1FBC, [0x1FB3], [0x1FBC], [0x0391, 0x0399]),
    SpecialCaseRange(0x1FC2, [0x1FC2], [0x1FCA, 0x0345], [0x1FCA, 0x0399]),
    SpecialCaseRange(0x1FC3, [0x1FC3], [0x1FCC], [0x0397, 0x0399]),
    SpecialCaseRange(0x1FC4, [0x1FC4], [0x0389, 0x0345], [0x0389, 0x0399]),
    SpecialCaseRange(0x1FC6, [0x1FC6], [0x0397, 0x0342], [0x0397, 0x0342]),
    SpecialCaseRange(0x1FC7, [0x1FC7], [0x0397, 0x0342, 0x0345], [0x0397, 0x0342, 0x0399]),
    SpecialCaseRange(0x1FCC, [0x1FC3], [0x1FCC], [0x0397, 0x0399]),
    SpecialCaseRange(0x1FD2, [0x1FD2], [0x0399, 0x0308, 0x0300], [0x0399, 0x0308, 0x0300]),
    SpecialCaseRange(0x1FD3, [0x1FD3], [0x0399, 0x0308, 0x0301], [0x0399, 0x0308, 0x0301]),
    SpecialCaseRange(0x1FD6, [0x1FD6], [0x0399, 0x0342], [0x0399, 0x0342]),
    SpecialCaseRange(0x1FD7, [0x1FD7], [0x0399, 0x0308, 0x0342], [0x0399, 0x0308, 0x0342]),
    SpecialCaseRange(0x1FE2, [0x1FE2], [0x03A5, 0x0308, 0x0300], [0x03A5, 0x0308, 0x0300]),
    SpecialCaseRange(0x1FE3, [0x1FE3], [0x03A5, 0x0308, 0x0301], [0x03A5, 0x0308, 0x0301]),
    SpecialCaseRange(0x1FE4, [0x1FE4], [0x03A1, 0x0313], [0x03A1, 0x0313]),
    SpecialCaseRange(0x1FE6, [0x1FE6], [0x03A5, 0x0342], [0x03A5, 0x0342]),
    SpecialCaseRange(0x1FE7, [0x1FE7], [0x03A5, 0x0308, 0x0342], [0x03A5, 0x0308, 0x0342]),
    SpecialCaseRange(0x1FF2, [0x1FF2], [0x1FFA, 0x0345], [0x1FFA, 0x0399]),
    SpecialCaseRange(0x1FF3, [0x1FF3], [0x1FFC], [0x03A9, 0x0399]),
    SpecialCaseRange(0x1FF4, [0x1FF4], [0x038F, 0x0345], [0x038F, 0x0399]),
    SpecialCaseRange(0x1FF6, [0x1FF6], [0x03A9, 0x0342], [0x03A9, 0x0342]),
    SpecialCaseRange(0x1FF7, [0x1FF7], [0x03A9, 0x0342, 0x0345], [0x03A9, 0x0342, 0x0399]),
    SpecialCaseRange(0x1FFC, [0x1FF3], [0x1FFC], [0x03A9, 0x0399]),
    SpecialCaseRange(0xFB00, [0xFB00], [0x0046, 0x0066], [0x0046, 0x0046]),
    SpecialCaseRange(0xFB01, [0xFB01], [0x0046, 0x0069], [0x0046, 0x0049]),
    SpecialCaseRange(0xFB02, [0xFB02], [0x0046, 0x006C], [0x0046, 0x004C]),
    SpecialCaseRange(0xFB03, [0xFB03], [0x0046, 0x0066, 0x0069], [0x0046, 0x0046, 0x0049]),
    SpecialCaseRange(0xFB04, [0xFB04], [0x0046, 0x0066, 0x006C], [0x0046, 0x0046, 0x004C]),
    SpecialCaseRange(0xFB05, [0xFB05], [0x0053, 0x0074], [0x0053, 0x0054]),
    SpecialCaseRange(0xFB06, [0xFB06], [0x0053, 0x0074], [0x0053, 0x0054]),
    SpecialCaseRange(0xFB13, [0xFB13], [0x0544, 0x0576], [0x0544, 0x0546]),
    SpecialCaseRange(0xFB14, [0xFB14], [0x0544, 0x0565], [0x0544, 0x0535]),
    SpecialCaseRange(0xFB15, [0xFB15], [0x0544, 0x056B], [0x0544, 0x053B]),
    SpecialCaseRange(0xFB16, [0xFB16], [0x054E, 0x0576], [0x054E, 0x0546]),
    SpecialCaseRange(0xFB17, [0xFB17], [0x0544, 0x056D], [0x0544, 0x053D])
]

enum CaseType {
    Upper | Lower | Title
}

public enum CasingOption {
    // Turkish
    | TR
    // Azeri
    | AZ
    // Lithuanian
    | LT
    | Other

    operator func ==(right: CasingOption): Bool {
        match ((this, right)) {
            case (TR, TR) => true
            case (AZ, AZ) => true
            case (LT, LT) => true
            case (Other, Other) => true
            case _ => false
        }
    }
}

func findCaseRange(rune: Rune): ?CaseRange {
    let codePosition: Int32 = Int32(UInt32(rune))
    var leftInterval: Int64 = 0
    var rightInterval: Int64 = CASE_RANGES.size
    while ((rightInterval > leftInterval)) {
        var intervalMid = (leftInterval + rightInterval) / 2
        let caseRange = CASE_RANGES[intervalMid]
        let start = caseRange.start
        let end = caseRange.end

        if (codePosition < start) {
            rightInterval = intervalMid
            continue
        }
        if (codePosition > end) {
            leftInterval = intervalMid + 1
            continue
        }
        return caseRange
    }
    return None
}

func findSpecialCaseRange(codePoint: UInt32): ?SpecialCaseRange {
    var leftInterval: Int64 = 0
    var rightInterval: Int64 = SPECIAL_CASE_RANGES.size
    while ((rightInterval > leftInterval)) {
        var intervalMid = (leftInterval + rightInterval) / 2
        let caseRange = SPECIAL_CASE_RANGES[intervalMid]
        if (codePoint == caseRange.codePoint) {
            return caseRange
        }
        if (codePoint < caseRange.codePoint) {
            rightInterval = intervalMid
        } else {
            leftInterval = intervalMid + 1
        }
    }
    return None
}

const MAX_UNICODE_CODEPOINT: UInt32 = 0x10FFFF

func safeAddCodepoint(codePosition: Int32, offset: Int32): UInt32 {
    let result: Int64 = Int64(codePosition) + Int64(offset)
    if (result < 0 || result > Int64(MAX_UNICODE_CODEPOINT)) {
        return UInt32(codePosition)
    }
    return UInt32(result)
}

func findRune(rune: Rune, caseRange: CaseRange, caseType: CaseType): Rune {
    let start = caseRange.start
    let codePosition: Int32 = Int32(UInt32(rune))
    match (caseType) {
        case Upper => match {
            case caseRange.upper == UPPERLOWER => Rune(UInt32(start + ((codePosition - start) & !1)))
            case caseRange.upper == SPECIAL_UNICODE => rune
            case _ => Rune(safeAddCodepoint(codePosition, caseRange.upper))
        }
        case Lower => match {
            case caseRange.lower == UPPERLOWER => Rune(UInt32(start + ((codePosition - start) | 1)))
            case caseRange.lower == SPECIAL_UNICODE => rune
            case _ => Rune(safeAddCodepoint(codePosition, caseRange.lower))
        }
        case Title => match {
            case caseRange.title == UPPERLOWER => Rune(UInt32(start + ((codePosition - start) & !1)))
            case caseRange.title == SPECIAL_UNICODE => rune
            case _ => Rune(safeAddCodepoint(codePosition, caseRange.title))
        }
    }
}

func caseChangeForLetterI(codePosition: Int32, caseRange: CaseRange, caseType: CaseType, opt: CasingOption): Rune {
    match (caseType) {
        case Upper =>
            if ((opt == TR || opt == AZ) && UInt32(codePosition) == SMALL_I) {
                Rune(CAPITAL_I_WITH_DOT_ABOVE)
            } else {
                Rune(safeAddCodepoint(codePosition, caseRange.upper))
            }
        case Lower =>
            if ((opt == TR || opt == AZ) && UInt32(codePosition) == CAPITAL_I) {
                Rune(SMALL_I_WITHOUT_DOT_ABOVE)
            } else {
                Rune(safeAddCodepoint(codePosition, caseRange.lower))
            }
        case Title =>
            if ((opt == TR || opt == AZ) && UInt32(codePosition) == SMALL_I) {
                Rune(CAPITAL_I_WITH_DOT_ABOVE)
            } else {
                Rune(safeAddCodepoint(codePosition, caseRange.title))
            }
    }
}

func findRuneWithOption(rune: Rune, caseRange: CaseRange, caseType: CaseType, opt: CasingOption): Rune {
    let start = caseRange.start
    let codePosition: Int32 = Int32(UInt32(rune))
    match (caseType) {
        case Upper => match {
            case caseRange.upper == UPPERLOWER => Rune(UInt32(start + ((codePosition - start) & !1)))
            case caseRange.upper == SPECIAL_UNICODE => rune
            case _ => caseChangeForLetterI(codePosition, caseRange, caseType, opt)
        }
        case Lower => match {
            case caseRange.lower == UPPERLOWER => Rune(UInt32(start + ((codePosition - start) | 1)))
            case caseRange.lower == SPECIAL_UNICODE => rune
            case _ => caseChangeForLetterI(codePosition, caseRange, caseType, opt)
        }
        case Title => match {
            case caseRange.title == UPPERLOWER => Rune(UInt32(start + ((codePosition - start) & !1)))
            case caseRange.title == SPECIAL_UNICODE => rune
            case _ => caseChangeForLetterI(codePosition, caseRange, caseType, opt)
        }
    }
}

func findRuneArray(rune: Rune, caseRange: CaseRange, caseType: CaseType): Array<UInt32> {
    let start = caseRange.start
    let codePosition: Int32 = Int32(UInt32(rune))
    match (caseType) {
        case Upper => match {
            case caseRange.upper == UPPERLOWER => [UInt32(start + ((codePosition - start) & !1))]
            case caseRange.upper == SPECIAL_UNICODE => match (findSpecialCaseRange(UInt32(rune))) {
                case Some(specialCase) => specialCase.upper
                case None => [UInt32(rune)]
            }
            case _ => [safeAddCodepoint(codePosition, caseRange.upper)]
        }
        case Lower => match {
            case caseRange.lower == UPPERLOWER => [UInt32(start + ((codePosition - start) | 1))]
            case caseRange.lower == SPECIAL_UNICODE => match (findSpecialCaseRange(UInt32(rune))) {
                case Some(specialCase) => specialCase.lower
                case None => [UInt32(rune)]
            }
            case _ => [safeAddCodepoint(codePosition, caseRange.lower)]
        }
        case Title => match {
            case caseRange.title == UPPERLOWER => [UInt32(start + ((codePosition - start) & !1))]
            case caseRange.title == SPECIAL_UNICODE => match (findSpecialCaseRange(UInt32(rune))) {
                case Some(specialCase) => specialCase.title
                case None => [UInt32(rune)]
            }
            case _ => [safeAddCodepoint(codePosition, caseRange.title)]
        }
    }
}

func toCase(rune: Rune, caseType: CaseType): Rune {
    match (findCaseRange(rune)) {
        case Some(caseRange) => findRune(rune, caseRange, caseType)
        case None => rune
    }
}

func toCaseWithOption(rune: Rune, caseType: CaseType, opt: CasingOption): Rune {
    match (findCaseRange(rune)) {
        case Some(caseRange) => findRuneWithOption(rune, caseRange, caseType, opt)
        case None => rune
    }
}

func toCaseSpecialArray(rune: Rune, caseType: CaseType): Array<UInt32> {
    match (findCaseRange(rune)) {
        case Some(caseRange) => findRuneArray(rune, caseRange, caseType)
        case None => [UInt32(rune)]
    }
}

/**
 * Binary search a character in the given array.
 */
func isRuneInRange(arr: Array<UnicodeRange>, rune: Rune): Bool {
    /* code point */
    let codePosition: Int32 = Int32(UInt32(rune))

    var leftInterval: Int64 = 0
    var rightInterval: Int64 = arr.size
    while (rightInterval > leftInterval) {
        var intervalMid = (leftInterval + rightInterval) / 2
        let caseRange = arr[intervalMid]
        let start = caseRange.start
        let end = caseRange.end

        if (codePosition < start) {
            rightInterval = intervalMid
        } else if (codePosition > end) {
            leftInterval = intervalMid + 1
        } else {
            return true
        }
    }
    return false
}

/* Methods for  Unicode. */
public interface UnicodeRuneExtension {
    func isLetter(): Bool
    func isNumber(): Bool
    func isLowerCase(): Bool
    func isUpperCase(): Bool
    func isTitleCase(): Bool
    func isWhiteSpace(): Bool
    func toUpperCase(): Rune
    func toLowerCase(): Rune
    func toTitleCase(): Rune
    func toUpperCase(opt: CasingOption): Rune
    func toLowerCase(opt: CasingOption): Rune
    func toTitleCase(opt: CasingOption): Rune
}

extend Rune <: UnicodeRuneExtension {
    /**
     * Returns true if this Unicode character is Letter.
     * In Unicode, Letter includes Uppercase_Letter, Lowercase_Letter, Titlecase_Letter, Modifier_Letter and Other_Letter.
     */
    public func isLetter(): Bool {
        return isRuneInRange(LOWER_CASE_LETTER, this) || isRuneInRange(UPPER_CASE_LETTER, this) || isRuneInRange(
            TITLE_CASE_LETTER, this) || isRuneInRange(MODIFIER_LETTER, this) || isRuneInRange(OTHER_LETTER, this)
    }

    /**
     * Returns true if this Unicode character is Number.
     * In Unicode, Number includes Decimal_Number, Letter_Number and Other_Number.
     */
    public func isNumber(): Bool {
        return isRuneInRange(DECIMAL_NUMBER, this) || isRuneInRange(LETTER_NUMBER, this) || isRuneInRange(OTHER_NUMBER,
            this)
    }

    /** Returns true if this Unicode character is Lowercase. */
    public func isLowerCase(): Bool {
        return isRuneInRange(LOWER_CASE_LETTER, this) || isRuneInRange(OTHER_LOWER_CASE, this)
    }

    /** Returns true if this Unicode character is Uppercase. */
    public func isUpperCase(): Bool {
        return isRuneInRange(UPPER_CASE_LETTER, this) || isRuneInRange(OTHER_UPPER_CASE, this)
    }

    /** Returns true if this Unicode character is Titlecase. */
    public func isTitleCase(): Bool {
        return isRuneInRange(TITLE_CASE_LETTER, this)
    }

    /** Returns true if this Unicode character is whitespace. */
    public func isWhiteSpace(): Bool {
        return isRuneInRange(WHITE_SPACE, this)
    }

    /** Returns the uppercase of this Unicode character. */
    public func toUpperCase(): Rune {
        return toCase(this, CaseType.Upper)
    }

    /** Returns the lowercase of this Unicode character. */
    public func toLowerCase(): Rune {
        return toCase(this, CaseType.Lower)
    }

    /** Returns the titlecase of this Unicode character. */
    public func toTitleCase(): Rune {
        return toCase(this, CaseType.Title)
    }

    /** Returns the uppercase of this Unicode character. */
    public func toUpperCase(opt: CasingOption): Rune {
        match (opt) {
            case Other => return toCase(this, CaseType.Upper)
            case _ => return toCaseWithOption(this, CaseType.Upper, opt)
        }
    }

    /** Returns the lowercase of this Unicode character. */
    public func toLowerCase(opt: CasingOption): Rune {
        match (opt) {
            case Other => return toCase(this, CaseType.Lower)
            case _ => return toCaseWithOption(this, CaseType.Lower, opt)
        }
    }

    /** Returns the titlecase of this Unicode character. */
    public func toTitleCase(opt: CasingOption): Rune {
        match (opt) {
            case Other => return toCase(this, CaseType.Title)
            case _ => return toCaseWithOption(this, CaseType.Title, opt)
        }
    }
}

public interface UnicodeStringExtension {
    func isBlank(): Bool
    func toLower(): String
    func toLower(opt: CasingOption): String
    func toTitle(): String
    func toTitle(opt: CasingOption): String
    func toUpper(): String
    func toUpper(opt: CasingOption): String
    func trim(): String

    @Deprecated[message: "Use member function `func trimEnd(): String` instead."]
    func trimRight(): String

    @Deprecated[message: "Use member function `func trimStart(): String` instead."]
    func trimLeft(): String
    func trimStart(): String
    func trimEnd(): String
}

extend String <: UnicodeStringExtension {
    /**
     * Returns true if this string is empty or contains only whitespace Unicode, otherwise `false`.
     */
    public func isBlank(): Bool {
        for (i in this.runes()) {
            if (!i.isWhiteSpace()) {
                return false
            }
        }
        return true
    }

    /**
     * @return a string which is the result of converting every character in this
     *         string to its lower case.
     * @throws IllegalArgumentException if there is an invalid utf8 leading code
     *         in array `itemBytes`.
     */
    public func toLower(): String {
        return toCaseInternal(Lower)
    }

    /**
     * @return a string which is the result of converting every character in
     *         this string to its upper case.
     * @throws IllegalArgumentException if there is an invalid utf8 leading code
     *         in array `itemBytes`.
     */
    public func toUpper(): String {
        return toCaseInternal(Upper)
    }

    /**
     * @return a string which is the result of converting every character in
     *         this string to its title case.
     * @throws IllegalArgumentException if there is an invalid utf8 leading code
     *         in array `itemBytes`.
     */
    public func toTitle(): String {
        return toCaseInternal(Title)
    }

    /**
     * @return a string which is the result of converting every character in this
     *         string to its lower case.
     * @throws IllegalArgumentException if there is an invalid utf8 leading code
     *         in array `itemBytes`.
     */
    public func toLower(opt: CasingOption): String {
        match (opt) {
            case Other => return toCaseInternal(Lower)
            case _ => return toCaseInternalWithOption(Lower, opt)
        }
    }

    /**
     * @return a string which is the result of converting every character in
     *         this string to its upper case.
     * @throws IllegalArgumentException if there is an invalid utf8 leading code
     *         in array `itemBytes`.
     */
    public func toUpper(opt: CasingOption): String {
        match (opt) {
            case Other => return toCaseInternal(Upper)
            case _ => return toCaseInternalWithOption(Upper, opt)
        }
    }

    /**
     * @return a string which is the result of converting every character in
     *         this string to its title case.
     * @throws IllegalArgumentException if there is an invalid utf8 leading code
     *         in array `itemBytes`.
     */
    public func toTitle(opt: CasingOption): String {
        match (opt) {
            case Other => return toCaseInternal(Title)
            case _ => return toCaseInternalWithOption(Title, opt)
        }
    }

    private func isGreekChar(rune: Rune): Bool {
        let runeVal = UInt32(rune)
        if ((runeVal >= GREECE_RUNE_LEFT_INTERVAL) && (runeVal <= GREECE_RUNE_RIGHT_INTERVAL)) {
            if (!GREECE_PUNCTUATION.contains(runeVal)) {
                return true
            }
        }
        if ((runeVal >= 0x1F00) && (runeVal <= 0x1FFF)) {
            return true
        }
        return false
    }

    private func isCombiningMark(rune: Rune): Bool {
        return isRuneInRange(COMBINING_MARK_RANGES, rune)
    }

    private func isCaseIgnorable(rune: Rune): Bool {
        return isRuneInRange(CASE_IGNORABLE_RANGES, rune)
    }

    private func isAboveCombiningMark(rune: Rune): Bool {
        return isRuneInRange(ABOVE_COMBINING_MARK_RANGES, rune)
    }

    private func isCasedGreek(rune: Rune): Bool {
        let runeVal = UInt32(rune)
        if (runeVal >= 0x0370 && runeVal <= 0x03FF) {
            if (GREECE_PUNCTUATION.contains(runeVal)) {
                return false
            }
            return isRuneInRange(UPPER_CASE_LETTER, rune) || isRuneInRange(LOWER_CASE_LETTER, rune) || isRuneInRange(
                TITLE_CASE_LETTER, rune)
        }
        if (runeVal >= 0x1F00 && runeVal <= 0x1FFF) {
            return isRuneInRange(UPPER_CASE_LETTER, rune) || isRuneInRange(LOWER_CASE_LETTER, rune) || isRuneInRange(
                TITLE_CASE_LETTER, rune)
        }
        return false
    }

    private func isCased(rune: Rune): Bool {
        return isRuneInRange(UPPER_CASE_LETTER, rune) || isRuneInRange(LOWER_CASE_LETTER, rune) || isRuneInRange(
            TITLE_CASE_LETTER, rune)
    }

    private func isNeedChange(srcData: Array<UInt8>, pos: Int64, num: Int64): Bool {
        var hasCasedBefore = false
        var i = pos - 1
        while (i >= 0 && srcData[i] >= UInt8(0x80) && srcData[i] < UInt8(0xC0)) {
            i -= 1
        }
        while (i >= 0) {
            let (prevChar, prevNum) = Rune.fromUtf8(srcData, i)
            if (!isCaseIgnorable(prevChar)) {
                if (isCased(prevChar)) {
                    hasCasedBefore = true
                }
                break
            }
            i -= prevNum
        }

        i = pos + num
        while (i < srcData.size) {
            let (nextChar, nextNum) = Rune.fromUtf8(srcData, i)
            if (!isCaseIgnorable(nextChar)) {
                if (isCased(nextChar)) {
                    return false
                } else {
                    return hasCasedBefore
                }
            }
            i += nextNum
        }
        return hasCasedBefore
    }

    private func getUInt32Arr(ct: CaseType, rune: Rune, itemBytes: Array<UInt8>, param: (Int64, Int64)): Array<UInt32> {
        return match (ct) {
            case Upper => toCaseSpecialArray(rune, Upper)
            case Lower =>
                if (rune == Rune(CAPITAL_SIGMA) && isNeedChange(itemBytes, param[0], param[1])) {
                    [SMALL_SIGMA_END]
                } else {
                    toCaseSpecialArray(rune, Lower)
                }
            case Title => toCaseSpecialArray(rune, Title)
        }
    }

    private func toCaseInternal(ct: CaseType): String {
        let result = ArrayList<UInt8>()
        let itemBytes = this.toArray()
        var i = 0
        while (i < itemBytes.size) {
            let (rune, num) = Rune.fromUtf8(itemBytes, i)
            let uint32arr = getUInt32Arr(ct, rune, itemBytes, (i, num))
            for (uint32 in uint32arr) {
                for (code in Rune(uint32).toString().toArray()) {
                    result.add(code)
                }
            }
            i += num
        }
        return String.fromUtf8(result.toArray())
    }

    private func isDotFollow(data: Array<UInt8>, pos: Int64): Bool {
        var i = pos
        while (i < data.size) {
            let (rune, num) = Rune.fromUtf8(data, i)
            if (rune == Rune(DOT_ABOVE)) {
                return true
            }
            if (!isCombiningMark(rune) || isAboveCombiningMark(rune)) {
                break
            }
            i += num
        }
        return false
    }

    private func isMoreAbove(data: Array<UInt8>, pos: Int64): Bool {
        var i = pos
        while (i < data.size) {
            let (rune, num) = Rune.fromUtf8(data, i)
            if (isAboveCombiningMark(rune)) {
                return true
            }
            if (!isCombiningMark(rune)) {
                break
            }
            i += num
        }
        return false
    }

    private func dotFollowChangeI(data: Array<UInt8>, pos: Int64): (UInt32, Bool) {
        if (isDotFollow(data, pos)) {
            (SMALL_I, true)
        } else {
            (SMALL_I_WITHOUT_DOT_ABOVE, false)
        }
    }

    private func toSpecialChange(rune: Rune, ct: CaseType, opt: CasingOption): Array<UInt32> {
        if ((opt == TR || opt == AZ) && (rune == Rune(SMALL_I))) {
            [CAPITAL_I_WITH_DOT_ABOVE]
        } else {
            toCaseSpecialArray(rune, ct)
        }
    }

    private func getUInt32ArrWithOption(ct: CaseType, rune: Rune, itemBytes: Array<UInt8>, param: (Int64, Int64),
        opt: CasingOption): (Array<UInt32>, Bool) {
        var skipNextDotAbove = false
        let uint32arr: Array<UInt32> = match (ct) {
            case Upper => toSpecialChange(rune, ct, opt)
            case Lower =>
                if (rune == Rune(CAPITAL_SIGMA) && isNeedChange(itemBytes, param[0], param[1])) {
                    [SMALL_SIGMA_END]
                } else if ((opt == TR || opt == AZ) && (rune == Rune(CAPITAL_I_WITH_DOT_ABOVE))) {
                    [SMALL_I]
                } else if (opt == LT && LITHUANIA_SPECIAL_RUNE.contains(UInt32(rune))) {
                    match (LITHUANIA_SPECIAL_RUNE.get(UInt32(rune))) {
                        case Some(arr) => arr
                        case None => [UInt32(rune)]
                    }
                } else if (opt == LT && rune == Rune(CAPITAL_I) && isMoreAbove(itemBytes, param[0] + param[1])) {
                    [SMALL_I, DOT_ABOVE]
                } else if (opt == LT && rune == Rune(CAPITAL_J) && isMoreAbove(itemBytes, param[0] + param[1])) {
                    [SMALL_J, DOT_ABOVE]
                } else if (opt == LT && rune == Rune(CAPITAL_I_OGONEK) && isMoreAbove(itemBytes, param[0] + param[1])) {
                    [SMALL_I_OGONEK, DOT_ABOVE]
                } else if ((opt == TR || opt == AZ) && (rune == Rune(CAPITAL_I))) {
                    let (arr, needJump) = dotFollowChangeI(itemBytes, param[0] + param[1])
                    skipNextDotAbove = needJump
                    [arr]
                } else {
                    toCaseSpecialArray(rune, Lower)
                }
            case Title => toSpecialChange(rune, ct, opt)
        }
        return (uint32arr, skipNextDotAbove)
    }

    private func toCaseInternalWithOption(ct: CaseType, opt: CasingOption): String {
        let itemBytes = this.toArray()
        let result = ArrayList<UInt8>()
        var i = 0
        var skipNextDotAbove = false
        while (i < itemBytes.size) {
            let (rune, num) = Rune.fromUtf8(itemBytes, i)
            if (skipNextDotAbove && rune == Rune(DOT_ABOVE)) {
                i += num
                skipNextDotAbove = false
                continue
            }
            let (uint32arr, needSkipNextDotAbove) = getUInt32ArrWithOption(ct, rune, itemBytes, (i, num), opt)
            if (needSkipNextDotAbove) {
                skipNextDotAbove = true
            }
            for (uint32 in uint32arr) {
                for (code in Rune(uint32).toString().toArray()) {
                    result.add(code)
                }
            }
            i += num
        }
        return String.fromUtf8(result.toArray())
    }

    /**
     * @return a string which is the result of removing the leading and trailing
     *         whitespace of this string.
     * @throws IllegalArgumentException if there is no valid utf8 code in array `myData`.
     */
    public func trim(): String {
        trimInternal(true, true)
    }

    /**
     * @return a string which is the result of removing the leading whitespace of this string.
     * @throws IllegalArgumentException if there is no valid utf8 leading code in array `myData`.
     */
    @Deprecated[message: "Use member function ` public func trimStart(): String` instead."]
    public func trimLeft(): String {
        return trimInternal(true, false)
    }

    /**
     * @return a string which is the result of removing the trailing whitespace of this string.
     * @throws IllegalArgumentException if there is no valid utf8 code in array `myData`.
     */
    @Deprecated[message: "Use member function ` public func trimEnd(): String` instead."]
    public func trimRight(): String {
        return trimInternal(false, true)
    }

    /**
     * @return a string which is the result of removing the leading whitespace of this string.
     * @throws IllegalArgumentException if there is no valid utf8 leading code in array `myData`.
     */
    public func trimStart(): String {
        return trimInternal(true, false)
    }

    /**
     * @return a string which is the result of removing the trailing whitespace of this string.
     * @throws IllegalArgumentException if there is no valid utf8 code in array `myData`.
     */
    public func trimEnd(): String {
        return trimInternal(false, true)
    }

    private func trimInternal(left: Bool, right: Bool): String {
        let myData = this.toArray()
        var start = 0
        var end = myData.size
        if (left) {
            while (start < end) {
                var (rune, num) = Rune.fromUtf8(myData, start)
                if (!rune.isWhiteSpace()) {
                    break
                }
                start += num
            }
        }
        if (right) {
            while (end > start) {
                var (rune, num) = Rune.getPreviousFromUtf8(myData, end)
                if (!rune.isWhiteSpace()) {
                    break
                }
                end -= num
            }
        }
        if (start >= end) {
            return String.empty
        }
        return String.fromUtf8(myData[start..end])
    }
}