package util

import 

var cjkRadicalsSupplement = &unicode.RangeTable{
	R16: []unicode.Range16{
		{0x2E80, 0x2EFF, 1},
	},
}

var kangxiRadicals = &unicode.RangeTable{
	R16: []unicode.Range16{
		{0x2F00, 0x2FDF, 1},
	},
}

var ideographicDescriptionCharacters = &unicode.RangeTable{
	R16: []unicode.Range16{
		{0x2FF0, 0x2FFF, 1},
	},
}

var cjkSymbolsAndPunctuation = &unicode.RangeTable{
	R16: []unicode.Range16{
		{0x3000, 0x303F, 1},
	},
}

var hiragana = &unicode.RangeTable{
	R16: []unicode.Range16{
		{0x3040, 0x309F, 1},
	},
}

var katakana = &unicode.RangeTable{
	R16: []unicode.Range16{
		{0x30A0, 0x30FF, 1},
	},
}

var kanbun = &unicode.RangeTable{
	R16: []unicode.Range16{
		{0x3130, 0x318F, 1},
		{0x3190, 0x319F, 1},
	},
}

var cjkStrokes = &unicode.RangeTable{
	R16: []unicode.Range16{
		{0x31C0, 0x31EF, 1},
	},
}

var katakanaPhoneticExtensions = &unicode.RangeTable{
	R16: []unicode.Range16{
		{0x31F0, 0x31FF, 1},
	},
}

var cjkCompatibility = &unicode.RangeTable{
	R16: []unicode.Range16{
		{0x3300, 0x33FF, 1},
	},
}

var cjkUnifiedIdeographsExtensionA = &unicode.RangeTable{
	R16: []unicode.Range16{
		{0x3400, 0x4DBF, 1},
	},
}

var cjkUnifiedIdeographs = &unicode.RangeTable{
	R16: []unicode.Range16{
		{0x4E00, 0x9FFF, 1},
	},
}

var yiSyllables = &unicode.RangeTable{
	R16: []unicode.Range16{
		{0xA000, 0xA48F, 1},
	},
}

var yiRadicals = &unicode.RangeTable{
	R16: []unicode.Range16{
		{0xA490, 0xA4CF, 1},
	},
}

var cjkCompatibilityIdeographs = &unicode.RangeTable{
	R16: []unicode.Range16{
		{0xF900, 0xFAFF, 1},
	},
}

var verticalForms = &unicode.RangeTable{
	R16: []unicode.Range16{
		{0xFE10, 0xFE1F, 1},
	},
}

var cjkCompatibilityForms = &unicode.RangeTable{
	R16: []unicode.Range16{
		{0xFE30, 0xFE4F, 1},
	},
}

var smallFormVariants = &unicode.RangeTable{
	R16: []unicode.Range16{
		{0xFE50, 0xFE6F, 1},
	},
}

var halfwidthAndFullwidthForms = &unicode.RangeTable{
	R16: []unicode.Range16{
		{0xFF00, 0xFFEF, 1},
	},
}

var kanaSupplement = &unicode.RangeTable{
	R32: []unicode.Range32{
		{0x1B000, 0x1B0FF, 1},
	},
}

var kanaExtendedA = &unicode.RangeTable{
	R32: []unicode.Range32{
		{0x1B100, 0x1B12F, 1},
	},
}

var smallKanaExtension = &unicode.RangeTable{
	R32: []unicode.Range32{
		{0x1B130, 0x1B16F, 1},
	},
}

var cjkUnifiedIdeographsExtensionB = &unicode.RangeTable{
	R32: []unicode.Range32{
		{0x20000, 0x2A6DF, 1},
	},
}

var cjkUnifiedIdeographsExtensionC = &unicode.RangeTable{
	R32: []unicode.Range32{
		{0x2A700, 0x2B73F, 1},
	},
}

var cjkUnifiedIdeographsExtensionD = &unicode.RangeTable{
	R32: []unicode.Range32{
		{0x2B740, 0x2B81F, 1},
	},
}

var cjkUnifiedIdeographsExtensionE = &unicode.RangeTable{
	R32: []unicode.Range32{
		{0x2B820, 0x2CEAF, 1},
	},
}

var cjkUnifiedIdeographsExtensionF = &unicode.RangeTable{
	R32: []unicode.Range32{
		{0x2CEB0, 0x2EBEF, 1},
	},
}

var cjkCompatibilityIdeographsSupplement = &unicode.RangeTable{
	R32: []unicode.Range32{
		{0x2F800, 0x2FA1F, 1},
	},
}

var cjkUnifiedIdeographsExtensionG = &unicode.RangeTable{
	R32: []unicode.Range32{
		{0x30000, 0x3134F, 1},
	},
}

// IsEastAsianWideRune returns trhe if the given rune is an east asian wide character, otherwise false.
func ( rune) bool {
	return unicode.Is(unicode.Hiragana, ) ||
		unicode.Is(unicode.Katakana, ) ||
		unicode.Is(unicode.Han, ) ||
		unicode.Is(unicode.Lm, ) ||
		unicode.Is(unicode.Hangul, ) ||
		unicode.Is(cjkSymbolsAndPunctuation, )
}

// IsSpaceDiscardingUnicodeRune returns true if the given rune is space-discarding unicode character, otherwise false.
// See https://www.w3.org/TR/2020/WD-css-text-3-20200429/#space-discard-set
func ( rune) bool {
	return unicode.Is(cjkRadicalsSupplement, ) ||
		unicode.Is(kangxiRadicals, ) ||
		unicode.Is(ideographicDescriptionCharacters, ) ||
		unicode.Is(cjkSymbolsAndPunctuation, ) ||
		unicode.Is(hiragana, ) ||
		unicode.Is(katakana, ) ||
		unicode.Is(kanbun, ) ||
		unicode.Is(cjkStrokes, ) ||
		unicode.Is(katakanaPhoneticExtensions, ) ||
		unicode.Is(cjkCompatibility, ) ||
		unicode.Is(cjkUnifiedIdeographsExtensionA, ) ||
		unicode.Is(cjkUnifiedIdeographs, ) ||
		unicode.Is(yiSyllables, ) ||
		unicode.Is(yiRadicals, ) ||
		unicode.Is(cjkCompatibilityIdeographs, ) ||
		unicode.Is(verticalForms, ) ||
		unicode.Is(cjkCompatibilityForms, ) ||
		unicode.Is(smallFormVariants, ) ||
		unicode.Is(halfwidthAndFullwidthForms, ) ||
		unicode.Is(kanaSupplement, ) ||
		unicode.Is(kanaExtendedA, ) ||
		unicode.Is(smallKanaExtension, ) ||
		unicode.Is(cjkUnifiedIdeographsExtensionB, ) ||
		unicode.Is(cjkUnifiedIdeographsExtensionC, ) ||
		unicode.Is(cjkUnifiedIdeographsExtensionD, ) ||
		unicode.Is(cjkUnifiedIdeographsExtensionE, ) ||
		unicode.Is(cjkUnifiedIdeographsExtensionF, ) ||
		unicode.Is(cjkCompatibilityIdeographsSupplement, ) ||
		unicode.Is(cjkUnifiedIdeographsExtensionG, )
}

// EastAsianWidth returns the east asian width of the given rune.
// See https://www.unicode.org/reports/tr11/tr11-36.html
func ( rune) string {
	switch {
	case  == 0x3000,
		(0xFF01 <=  &&  <= 0xFF60),
		(0xFFE0 <=  &&  <= 0xFFE6):
		return "F"

	case  == 0x20A9,
		(0xFF61 <=  &&  <= 0xFFBE),
		(0xFFC2 <=  &&  <= 0xFFC7),
		(0xFFCA <=  &&  <= 0xFFCF),
		(0xFFD2 <=  &&  <= 0xFFD7),
		(0xFFDA <=  &&  <= 0xFFDC),
		(0xFFE8 <=  &&  <= 0xFFEE):
		return "H"

	case (0x1100 <=  &&  <= 0x115F),
		(0x11A3 <=  &&  <= 0x11A7),
		(0x11FA <=  &&  <= 0x11FF),
		(0x2329 <=  &&  <= 0x232A),
		(0x2E80 <=  &&  <= 0x2E99),
		(0x2E9B <=  &&  <= 0x2EF3),
		(0x2F00 <=  &&  <= 0x2FD5),
		(0x2FF0 <=  &&  <= 0x2FFB),
		(0x3001 <=  &&  <= 0x303E),
		(0x3041 <=  &&  <= 0x3096),
		(0x3099 <=  &&  <= 0x30FF),
		(0x3105 <=  &&  <= 0x312D),
		(0x3131 <=  &&  <= 0x318E),
		(0x3190 <=  &&  <= 0x31BA),
		(0x31C0 <=  &&  <= 0x31E3),
		(0x31F0 <=  &&  <= 0x321E),
		(0x3220 <=  &&  <= 0x3247),
		(0x3250 <=  &&  <= 0x32FE),
		(0x3300 <=  &&  <= 0x4DBF),
		(0x4E00 <=  &&  <= 0xA48C),
		(0xA490 <=  &&  <= 0xA4C6),
		(0xA960 <=  &&  <= 0xA97C),
		(0xAC00 <=  &&  <= 0xD7A3),
		(0xD7B0 <=  &&  <= 0xD7C6),
		(0xD7CB <=  &&  <= 0xD7FB),
		(0xF900 <=  &&  <= 0xFAFF),
		(0xFE10 <=  &&  <= 0xFE19),
		(0xFE30 <=  &&  <= 0xFE52),
		(0xFE54 <=  &&  <= 0xFE66),
		(0xFE68 <=  &&  <= 0xFE6B),
		(0x1B000 <=  &&  <= 0x1B001),
		(0x1F200 <=  &&  <= 0x1F202),
		(0x1F210 <=  &&  <= 0x1F23A),
		(0x1F240 <=  &&  <= 0x1F248),
		(0x1F250 <=  &&  <= 0x1F251),
		(0x20000 <=  &&  <= 0x2F73F),
		(0x2B740 <=  &&  <= 0x2FFFD),
		(0x30000 <=  &&  <= 0x3FFFD):
		return "W"

	case (0x0020 <=  &&  <= 0x007E),
		(0x00A2 <=  &&  <= 0x00A3),
		(0x00A5 <=  &&  <= 0x00A6),
		 == 0x00AC,
		 == 0x00AF,
		(0x27E6 <=  &&  <= 0x27ED),
		(0x2985 <=  &&  <= 0x2986):
		return "Na"

	case (0x00A1 == ),
		(0x00A4 == ),
		(0x00A7 <=  &&  <= 0x00A8),
		(0x00AA == ),
		(0x00AD <=  &&  <= 0x00AE),
		(0x00B0 <=  &&  <= 0x00B4),
		(0x00B6 <=  &&  <= 0x00BA),
		(0x00BC <=  &&  <= 0x00BF),
		(0x00C6 == ),
		(0x00D0 == ),
		(0x00D7 <=  &&  <= 0x00D8),
		(0x00DE <=  &&  <= 0x00E1),
		(0x00E6 == ),
		(0x00E8 <=  &&  <= 0x00EA),
		(0x00EC <=  &&  <= 0x00ED),
		(0x00F0 == ),
		(0x00F2 <=  &&  <= 0x00F3),
		(0x00F7 <=  &&  <= 0x00FA),
		(0x00FC == ),
		(0x00FE == ),
		(0x0101 == ),
		(0x0111 == ),
		(0x0113 == ),
		(0x011B == ),
		(0x0126 <=  &&  <= 0x0127),
		(0x012B == ),
		(0x0131 <=  &&  <= 0x0133),
		(0x0138 == ),
		(0x013F <=  &&  <= 0x0142),
		(0x0144 == ),
		(0x0148 <=  &&  <= 0x014B),
		(0x014D == ),
		(0x0152 <=  &&  <= 0x0153),
		(0x0166 <=  &&  <= 0x0167),
		(0x016B == ),
		(0x01CE == ),
		(0x01D0 == ),
		(0x01D2 == ),
		(0x01D4 == ),
		(0x01D6 == ),
		(0x01D8 == ),
		(0x01DA == ),
		(0x01DC == ),
		(0x0251 == ),
		(0x0261 == ),
		(0x02C4 == ),
		(0x02C7 == ),
		(0x02C9 <=  &&  <= 0x02CB),
		(0x02CD == ),
		(0x02D0 == ),
		(0x02D8 <=  &&  <= 0x02DB),
		(0x02DD == ),
		(0x02DF == ),
		(0x0300 <=  &&  <= 0x036F),
		(0x0391 <=  &&  <= 0x03A1),
		(0x03A3 <=  &&  <= 0x03A9),
		(0x03B1 <=  &&  <= 0x03C1),
		(0x03C3 <=  &&  <= 0x03C9),
		(0x0401 == ),
		(0x0410 <=  &&  <= 0x044F),
		(0x0451 == ),
		(0x2010 == ),
		(0x2013 <=  &&  <= 0x2016),
		(0x2018 <=  &&  <= 0x2019),
		(0x201C <=  &&  <= 0x201D),
		(0x2020 <=  &&  <= 0x2022),
		(0x2024 <=  &&  <= 0x2027),
		(0x2030 == ),
		(0x2032 <=  &&  <= 0x2033),
		(0x2035 == ),
		(0x203B == ),
		(0x203E == ),
		(0x2074 == ),
		(0x207F == ),
		(0x2081 <=  &&  <= 0x2084),
		(0x20AC == ),
		(0x2103 == ),
		(0x2105 == ),
		(0x2109 == ),
		(0x2113 == ),
		(0x2116 == ),
		(0x2121 <=  &&  <= 0x2122),
		(0x2126 == ),
		(0x212B == ),
		(0x2153 <=  &&  <= 0x2154),
		(0x215B <=  &&  <= 0x215E),
		(0x2160 <=  &&  <= 0x216B),
		(0x2170 <=  &&  <= 0x2179),
		(0x2189 == ),
		(0x2190 <=  &&  <= 0x2199),
		(0x21B8 <=  &&  <= 0x21B9),
		(0x21D2 == ),
		(0x21D4 == ),
		(0x21E7 == ),
		(0x2200 == ),
		(0x2202 <=  &&  <= 0x2203),
		(0x2207 <=  &&  <= 0x2208),
		(0x220B == ),
		(0x220F == ),
		(0x2211 == ),
		(0x2215 == ),
		(0x221A == ),
		(0x221D <=  &&  <= 0x2220),
		(0x2223 == ),
		(0x2225 == ),
		(0x2227 <=  &&  <= 0x222C),
		(0x222E == ),
		(0x2234 <=  &&  <= 0x2237),
		(0x223C <=  &&  <= 0x223D),
		(0x2248 == ),
		(0x224C == ),
		(0x2252 == ),
		(0x2260 <=  &&  <= 0x2261),
		(0x2264 <=  &&  <= 0x2267),
		(0x226A <=  &&  <= 0x226B),
		(0x226E <=  &&  <= 0x226F),
		(0x2282 <=  &&  <= 0x2283),
		(0x2286 <=  &&  <= 0x2287),
		(0x2295 == ),
		(0x2299 == ),
		(0x22A5 == ),
		(0x22BF == ),
		(0x2312 == ),
		(0x2460 <=  &&  <= 0x24E9),
		(0x24EB <=  &&  <= 0x254B),
		(0x2550 <=  &&  <= 0x2573),
		(0x2580 <=  &&  <= 0x258F),
		(0x2592 <=  &&  <= 0x2595),
		(0x25A0 <=  &&  <= 0x25A1),
		(0x25A3 <=  &&  <= 0x25A9),
		(0x25B2 <=  &&  <= 0x25B3),
		(0x25B6 <=  &&  <= 0x25B7),
		(0x25BC <=  &&  <= 0x25BD),
		(0x25C0 <=  &&  <= 0x25C1),
		(0x25C6 <=  &&  <= 0x25C8),
		(0x25CB == ),
		(0x25CE <=  &&  <= 0x25D1),
		(0x25E2 <=  &&  <= 0x25E5),
		(0x25EF == ),
		(0x2605 <=  &&  <= 0x2606),
		(0x2609 == ),
		(0x260E <=  &&  <= 0x260F),
		(0x2614 <=  &&  <= 0x2615),
		(0x261C == ),
		(0x261E == ),
		(0x2640 == ),
		(0x2642 == ),
		(0x2660 <=  &&  <= 0x2661),
		(0x2663 <=  &&  <= 0x2665),
		(0x2667 <=  &&  <= 0x266A),
		(0x266C <=  &&  <= 0x266D),
		(0x266F == ),
		(0x269E <=  &&  <= 0x269F),
		(0x26BE <=  &&  <= 0x26BF),
		(0x26C4 <=  &&  <= 0x26CD),
		(0x26CF <=  &&  <= 0x26E1),
		(0x26E3 == ),
		(0x26E8 <=  &&  <= 0x26FF),
		(0x273D == ),
		(0x2757 == ),
		(0x2776 <=  &&  <= 0x277F),
		(0x2B55 <=  &&  <= 0x2B59),
		(0x3248 <=  &&  <= 0x324F),
		(0xE000 <=  &&  <= 0xF8FF),
		(0xFE00 <=  &&  <= 0xFE0F),
		(0xFFFD == ),
		(0x1F100 <=  &&  <= 0x1F10A),
		(0x1F110 <=  &&  <= 0x1F12D),
		(0x1F130 <=  &&  <= 0x1F169),
		(0x1F170 <=  &&  <= 0x1F19A),
		(0xE0100 <=  &&  <= 0xE01EF),
		(0xF0000 <=  &&  <= 0xFFFFD),
		(0x100000 <=  &&  <= 0x10FFFD):
		return "A"

	default:
		return "N"
	}
}