├── .gitignore ├── .travis.yml ├── LANGUAGES.md ├── LICENSE ├── README.md ├── doc_test.go ├── getlang.go ├── getlang_test.go └── profiles.go /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.dll 4 | *.so 5 | *.dylib 6 | 7 | # Test binary, build with `go test -c` 8 | *.test 9 | 10 | # Output of the go coverage tool, specifically when used with LiteIDE 11 | *.out 12 | 13 | # Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 14 | .glide/ 15 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | go: 4 | - master 5 | -------------------------------------------------------------------------------- /LANGUAGES.md: -------------------------------------------------------------------------------- 1 | # getlang 2 | 3 | Fast natural language detection. 4 | 5 | ## Supported Languages 6 | 7 | | Language | ISO 639-1 | 8 | | -------------- | --------- | 9 | | Arabic | ar | 10 | | Bengali (Bangla) | bn | 11 | | German | de | 12 | | Greek | el | 13 | | English | en | 14 | | Spanish | es | 15 | | French | fr | 16 | | Hebrew | he | 17 | | Hindi | hi | 18 | | Hungarian | hu | 19 | | Armenian | hy | 20 | | Gujarati | gu | 21 | | Italian | it | 22 | | Dutch | nl | 23 | | Polish | pl | 24 | | Portuguese | pt | 25 | | Punjabi | pa | 26 | | Japanese | ja | 27 | | Kannada | ka | 28 | | Korean | ko | 29 | | Tamil | ta | 30 | | Telugu | te | 31 | | Tagalog | tl | 32 | | Thai | th | 33 | | Russian | ru | 34 | | Serbian | sr | 35 | | Vietnamese | vi | 36 | | Ukrainian | uk | 37 | | Chinese | zh | 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Rylan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # getlang 2 | 3 | [![GoDoc](https://godoc.org/github.com/rylans/getlang?status.svg)](https://godoc.org/github.com/rylans/getlang) [![Go Report Card](https://goreportcard.com/badge/github.com/rylans/getlang)](https://goreportcard.com/report/github.com/rylans/getlang) [![Build Status](https://travis-ci.org/rylans/getlang.svg?branch=master)](https://travis-ci.org/rylans/getlang) ![cover.run go](https://cover.run/go/github.com/rylans/getlang.svg?tag=golang-1.10) 4 | 5 | getlang provides fast natural language detection in Go. 6 | 7 | ## Features 8 | 9 | * Offline -- no internet connection required 10 | * Supports [29 languages](https://github.com/rylans/getlang/blob/master/LANGUAGES.md) 11 | * Provides ISO 639 language codes 12 | * Fast 13 | 14 | ## Getting started 15 | 16 | Installation: 17 | ```sh 18 | go get -u github.com/rylans/getlang 19 | ``` 20 | 21 | example: 22 | ```go 23 | package main 24 | 25 | import ( 26 | "fmt" 27 | "github.com/rylans/getlang" 28 | ) 29 | 30 | func main(){ 31 | info := getlang.FromString("Wszyscy ludzie rodzą się wolni i równi w swojej godności i prawach") 32 | fmt.Println(info.LanguageCode(), info.Confidence()) 33 | } 34 | ``` 35 | 36 | ## Documentation 37 | [getlang on godoc](https://godoc.org/github.com/rylans/getlang) 38 | 39 | ## License 40 | [MIT](https://github.com/rylans/getlang/blob/master/LICENSE) 41 | 42 | ## Acknowledgements and Citations 43 | * Thanks to [abadojack](https://github.com/abadojack) for the trigram generation logic in whatlanggo 44 | * Cavnar, William B., and John M. Trenkle. "N-gram-based text categorization." Ann arbor mi 48113.2 (1994): 161-175. 45 | -------------------------------------------------------------------------------- /doc_test.go: -------------------------------------------------------------------------------- 1 | package getlang_test 2 | 3 | import ( 4 | "fmt" 5 | "github.com/rylans/getlang" 6 | ) 7 | 8 | func ExampleInfo_Confidence() { 9 | short := getlang.FromString("short text") 10 | long := getlang.FromString("this sentence is a bit longer") 11 | fmt.Println(long.Confidence() > short.Confidence()) 12 | // Output: true 13 | } 14 | 15 | func ExampleInfo_LanguageCode() { 16 | fmt.Println(getlang.FromString("статей на русском").LanguageCode()) 17 | // Output: ru 18 | } 19 | 20 | func ExampleInfo_LanguageName() { 21 | fmt.Println(getlang.FromString("何ですか?").LanguageName()) 22 | // Output: Japanese 23 | } 24 | 25 | func ExampleInfo_SelfName() { 26 | fmt.Println(getlang.FromString("何ですか?").SelfName()) 27 | // Output: 日本語 28 | } 29 | 30 | func ExampleInfo_Tag() { 31 | fmt.Println(getlang.FromString("何ですか?").Tag().IsRoot()) 32 | // Output: false 33 | } 34 | -------------------------------------------------------------------------------- /getlang.go: -------------------------------------------------------------------------------- 1 | // Package getlang provides fast natural language detection for various languages 2 | // 3 | // getlang compares input text to a characteristic profile of each supported language and 4 | // returns the language that best matches the input text 5 | package getlang 6 | 7 | import ( 8 | "golang.org/x/text/language" 9 | "golang.org/x/text/language/display" 10 | "io" 11 | "io/ioutil" 12 | "math" 13 | "sort" 14 | "unicode" 15 | ) 16 | 17 | const undeterminedRate int = 41 18 | const undetermined string = "und" 19 | const rescale = 0.5 20 | const scriptCountFactor int = 2 21 | const expOverflow = 7.09e+02 22 | 23 | var langs = map[string][]string{ 24 | "de": de, 25 | "en": en, 26 | "es": es, 27 | "fr": fr, 28 | "hi": hi, 29 | "hu": hu, 30 | "it": it, 31 | "nl": nl, 32 | "pl": pl, 33 | "pt": pt, 34 | "ru": ru, 35 | "sr-Latn": srLatin, 36 | "sr-Cyrl": srCyr, 37 | "tl": tl, 38 | "uk": uk, 39 | "vi": vi, 40 | } 41 | 42 | var scripts = map[string][]*unicode.RangeTable{ 43 | "ar": {unicode.Arabic}, 44 | "bn": {unicode.Bengali}, 45 | "el": {unicode.Greek}, 46 | "gu": {unicode.Gujarati}, 47 | "he": {unicode.Hebrew}, 48 | "hy": {unicode.Armenian}, 49 | "ja": {unicode.Hiragana, unicode.Katakana}, 50 | "kn": {unicode.Kannada}, 51 | "ko": {unicode.Hangul}, 52 | "pa": {unicode.Gurmukhi}, 53 | "ta": {unicode.Tamil}, 54 | "te": {unicode.Telugu}, 55 | "th": {unicode.Thai}, 56 | "zh": {unicode.Han}, 57 | } 58 | 59 | // Info is the language detection result 60 | type Info struct { 61 | lang string 62 | probability float64 63 | langTag language.Tag 64 | } 65 | 66 | // Tag returns the language.Tag of the detected language 67 | func (info Info) Tag() language.Tag { 68 | return info.langTag 69 | } 70 | 71 | // LanguageCode returns the ISO 639-1 code for the detected language 72 | func (info Info) LanguageCode() string { 73 | codeLen := len(info.lang) 74 | if codeLen < 4 { 75 | return info.lang 76 | } 77 | return info.lang[:2] 78 | } 79 | 80 | // Confidence returns a measure of reliability for the language classification 81 | // 82 | // The output value is in the range [0, 1.0] inclusive 83 | func (info Info) Confidence() float64 { 84 | return info.probability 85 | } 86 | 87 | // LanguageName returns the English name of the detected language 88 | func (info Info) LanguageName() string { 89 | return display.English.Tags().Name(info.langTag) 90 | } 91 | 92 | // SelfName returns the name of the language in the language itself 93 | func (info Info) SelfName() string { 94 | return display.Self.Name(info.langTag) 95 | } 96 | 97 | // FromReader detects the language from an io.Reader 98 | // 99 | // This function will read all bytes until an EOF is reached 100 | func FromReader(reader io.Reader) (Info, error) { 101 | bytes, err := ioutil.ReadAll(reader) 102 | return FromString(string(bytes)), err 103 | } 104 | 105 | // FromString detects the language from the given string 106 | func FromString(text string) Info { 107 | langMatches := make(map[string]int) 108 | langMatches[undetermined] = 1 109 | 110 | trigs := sortedTrigs(text) 111 | for k, v := range langs { 112 | matchWith(k, trigs, v, langMatches) 113 | } 114 | 115 | for k, v := range scripts { 116 | matchScript(k, text, langMatches, v...) 117 | } 118 | 119 | smx := softMax(langMatches) 120 | maxk := maxKey(langMatches) 121 | return Info{maxk, smx[maxk], language.MustParse(maxk)} 122 | } 123 | 124 | func softMax(mapping map[string]int) map[string]float64 { 125 | softMaxMap := make(map[string]float64) 126 | var denom float64 127 | overflowed := false 128 | for _, v := range mapping { 129 | denom += math.Exp(float64(v) * rescale) 130 | if v > expOverflow { 131 | overflowed = true 132 | } 133 | } 134 | for k := range mapping { 135 | if !overflowed { 136 | softMaxMap[k] = math.Exp(rescale*float64(mapping[k])) / denom 137 | } else { 138 | softMaxMap[k] = 1.0 139 | } 140 | } 141 | return softMaxMap 142 | } 143 | 144 | func maxKey(mapping map[string]int) string { 145 | var max int 146 | var key string 147 | for k, v := range mapping { 148 | if v > max { 149 | max = v 150 | key = k 151 | } 152 | } 153 | return key 154 | } 155 | 156 | func matchScript(langName, text string, matches map[string]int, ranges ...*unicode.RangeTable) { 157 | for _, r := range text { 158 | if unicode.In(r, ranges...) { 159 | matches[langName] += scriptCountFactor 160 | } 161 | } 162 | } 163 | 164 | func matchWith(langName string, trigs []trigram, langProfile []string, matches map[string]int) { 165 | var undeterminedCount int 166 | prof := make(map[string]int) 167 | for _, x := range langProfile { 168 | prof[x] = 1 169 | } 170 | 171 | for _, trig := range trigs { 172 | if _, exists := prof[trig.trigram]; exists { 173 | matches[langName] += trig.count 174 | } else { 175 | undeterminedCount++ 176 | if (undeterminedCount % undeterminedRate) == 0 { 177 | matches[undetermined]++ 178 | } 179 | } 180 | } 181 | } 182 | 183 | func countedTrigrams(text string) map[string]int { 184 | trigrams := map[string]int{} 185 | var txt []rune 186 | 187 | for _, r := range text { 188 | txt = append(txt, unicode.ToLower(toTrigramChar(r))) 189 | } 190 | txt = append(txt, ' ') 191 | 192 | r1, r2 := ' ', txt[0] 193 | var r3 rune 194 | for i := 1; i < len(txt); i++ { 195 | r3 = txt[i] 196 | if !(r2 == ' ' && (r1 == ' ' || r3 == ' ')) { 197 | trigram := []rune{r1, r2, r3} 198 | if trigrams[string(trigram)] == 0 { 199 | trigrams[string(trigram)] = 1 200 | } else { 201 | trigrams[string(trigram)]++ 202 | } 203 | } 204 | r1, r2 = r2, r3 205 | } 206 | 207 | return trigrams 208 | } 209 | 210 | type trigram struct { 211 | trigram string 212 | count int 213 | } 214 | 215 | func sortedTrigs(s string) []trigram { 216 | counterMap := countedTrigrams(s) 217 | trigrams := make([]trigram, len(counterMap)) 218 | 219 | var i int 220 | for tg, count := range counterMap { 221 | trigrams[i] = trigram{tg, count} 222 | i++ 223 | } 224 | sort.SliceStable(trigrams, func(i, j int) bool { 225 | if trigrams[i].count == trigrams[j].count { 226 | return trigrams[i].trigram < trigrams[j].trigram 227 | } 228 | return trigrams[i].count > trigrams[j].count 229 | }) 230 | return trigrams 231 | } 232 | 233 | func toTrigramChar(ch rune) rune { 234 | if unicode.IsPunct(ch) || unicode.IsSpace(ch) { 235 | return ' ' 236 | } 237 | return ch 238 | } 239 | -------------------------------------------------------------------------------- /getlang_test.go: -------------------------------------------------------------------------------- 1 | package getlang 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "strings" 6 | "testing" 7 | ) 8 | 9 | func TestEmptyStringFromReader(t *testing.T) { 10 | info, _ := FromReader(strings.NewReader("")) 11 | assert.Equal(t, "und", info.LanguageCode()) 12 | } 13 | 14 | func TestEnglishPhraseFromBigReader(t *testing.T) { 15 | largeText := "" 16 | for i := 0; i < 800; i++ { 17 | largeText += "this is more language as you can see " 18 | } 19 | info, _ := FromReader(strings.NewReader(largeText)) 20 | assert.Equal(t, "en", info.LanguageCode()) 21 | assert.Equal(t, true, info.Confidence() > 0.999) 22 | } 23 | 24 | func TestEnglishPhraseFromReader(t *testing.T) { 25 | info, _ := FromReader(strings.NewReader("this is the language")) 26 | assert.Equal(t, "en", info.LanguageCode()) 27 | assert.Equal(t, true, info.Confidence() > 0.75) 28 | } 29 | 30 | func TestEnglishPhraseTag(t *testing.T) { 31 | info, _ := FromReader(strings.NewReader("this is the language")) 32 | tag := info.Tag() 33 | 34 | assert.Equal(t, "en", tag.String()) 35 | assert.Equal(t, false, tag.IsRoot()) 36 | assert.Equal(t, true, tag.Parent().IsRoot()) 37 | } 38 | 39 | func TestEnglishPhraseUSDI(t *testing.T) { 40 | text := "We hold these truths to be self-evident, that all men are created equal" 41 | ensureClassifiedWithConfidence( 42 | t, 43 | text, 44 | "en", 45 | 0.95) 46 | 47 | ensureClassifiedTextNamed( 48 | t, 49 | text, 50 | "English", 51 | "English") 52 | } 53 | 54 | func TestGermanPhraseUSDI(t *testing.T) { 55 | text := "Wir halten diese Wahrheiten für ausgemacht, daß alle Menschen gleich erschaffen worden" 56 | ensureClassifiedWithConfidence( 57 | t, 58 | text, 59 | "de", 60 | 0.95) 61 | 62 | ensureClassifiedTextNamed( 63 | t, 64 | text, 65 | "German", 66 | "Deutsch") 67 | } 68 | 69 | func TestEnglishMixedGerman(t *testing.T) { 70 | ensureClassifiedWithConfidence( 71 | t, 72 | "If you wanted to greet someone in this language, you'd say 'wie geht es'", 73 | "en", 74 | 0.35) 75 | } 76 | 77 | func TestEnglishMixedUkrainian(t *testing.T) { 78 | ensureClassifiedWithConfidence( 79 | t, 80 | "the best thing to say is своїй гідності in my opinon of this.", 81 | "en", 82 | 0.55) 83 | } 84 | 85 | func TestSpanishPhraseUSDI(t *testing.T) { 86 | ensureClassifiedWithConfidence( 87 | t, 88 | "Sostenemos como evidentes estas verdades: que los hombres son creados iguales", 89 | "es", 90 | 0.75) 91 | } 92 | 93 | func TestPortuguesePhraseUSDI(t *testing.T) { 94 | ensureClassifiedWithConfidence( 95 | t, 96 | "Consideramos estas verdades como autoevidentes, que todos os homens são criados iguais", 97 | "pt", 98 | 0.95) 99 | } 100 | 101 | func TestPolishPhraseUDHR(t *testing.T) { 102 | ensureClassifiedWithConfidence( 103 | t, 104 | "Wszyscy ludzie rodzą się wolni i równi w swojej godności i prawach", 105 | "pl", 106 | 0.95) 107 | } 108 | 109 | func TestPunjabiPhrase(t *testing.T) { 110 | text := "ਮੇਰਾ ਨਾਮ ਭਰਤ ਹੈ." 111 | lang := "ਪੰਜਾਬੀ" 112 | 113 | ensureClassifiedWithConfidence( 114 | t, 115 | text, 116 | "pa", 117 | 0.95) 118 | 119 | ensureClassifiedTextNamed( 120 | t, 121 | text, 122 | "Punjabi", 123 | lang) 124 | } 125 | 126 | func TestHungarianPhraseUDHR(t *testing.T) { 127 | ensureClassifiedWithConfidence( 128 | t, 129 | "Minden emberi lény szabadon születik és egyenlő méltósága és joga van", 130 | "hu", 131 | 0.95) 132 | } 133 | 134 | func TestItalianPhraseUDHR(t *testing.T) { 135 | ensureClassifiedWithConfidence( 136 | t, 137 | "Tutti gli esseri umani nascono liberi ed eguali in dignità e diritti", 138 | "it", 139 | 0.95) 140 | } 141 | 142 | func TestRussianPhraseUDHR(t *testing.T) { 143 | ensureClassifiedWithConfidence( 144 | t, 145 | "Все люди рождаются свободными и равными в своем достоинстве и правах", 146 | "ru", 147 | 0.55) 148 | } 149 | 150 | func TestUkrainianPhraseUDHR(t *testing.T) { 151 | ensureClassifiedWithConfidence( 152 | t, 153 | "Всі люди народжуються вільними і рівними у своїй гідності та правах", 154 | "uk", 155 | 0.80) 156 | } 157 | 158 | func TestFrenchPhraseUDHR(t *testing.T) { 159 | ensureClassifiedWithConfidence( 160 | t, 161 | "Tous les êtres humains naissent libres et égaux", 162 | "fr", 163 | 0.95) 164 | } 165 | 166 | func TestKoreanPhrase(t *testing.T) { 167 | ensureClassifiedWithConfidence( 168 | t, 169 | "원래 AB형 사람이 똑똑해", 170 | "ko", 171 | 0.95) 172 | } 173 | 174 | func TestJapanesePhrase(t *testing.T) { 175 | text := "何を食べますか" 176 | ensureClassifiedWithConfidence( 177 | t, 178 | text, 179 | "ja", 180 | 0.90) 181 | 182 | ensureClassifiedTextNamed( 183 | t, 184 | text, 185 | "Japanese", 186 | "日本語") 187 | } 188 | 189 | func TestChinesePhrase(t *testing.T) { 190 | text := "球的采编网络,记者遍布" 191 | ensureClassifiedWithConfidence( 192 | t, 193 | text, 194 | "zh", 195 | 0.95) 196 | 197 | ensureClassifiedTextNamed( 198 | t, 199 | text, 200 | "Chinese", 201 | "中文") 202 | } 203 | 204 | func TestArabicPhrase(t *testing.T) { 205 | text := "اهتمامًا بذلك المشروع. المجموعة الوحيدة التي " 206 | lang := "العربية" 207 | ensureClassifiedWithConfidence( 208 | t, 209 | text, 210 | "ar", 211 | 0.55) 212 | 213 | ensureClassifiedTextNamed( 214 | t, 215 | text, 216 | "Arabic", 217 | lang) 218 | } 219 | 220 | func TestBanglaPhrase(t *testing.T) { 221 | text := "এই গবেষণায় রত, তাঁদেরকে বলা হয় ভাষাবিজ্ঞানী।ভাষাবিজ্ঞানীরা নৈর্ব্যক্তিক" 222 | lang := "বাংলা" 223 | 224 | ensureClassifiedWithConfidence( 225 | t, 226 | text, 227 | "bn", 228 | 0.85) 229 | 230 | ensureClassifiedTextNamed( 231 | t, 232 | text, 233 | "Bangla", 234 | lang) 235 | } 236 | 237 | func TestHindiPhrase(t *testing.T) { 238 | text := "ब तक लगातार चल रहा है। इसका प्रसारण प्रत्येक शनिवार और रविवार को रात 10 बजे होता है। इसका पुनः प्रसारण सोनी पल चैनल पर रात 9 बजे होता" 239 | lang := "हिन्दी" 240 | 241 | ensureClassifiedWithConfidence( 242 | t, 243 | text, 244 | "hi", 245 | 0.75) 246 | 247 | ensureClassifiedTextNamed( 248 | t, 249 | text, 250 | "Hindi", 251 | lang) 252 | } 253 | 254 | func TestGreekPhrase(t *testing.T) { 255 | text := "Ολοι οι άνθρωποι γεννιούνται ελεύθεροι και ίσοι στην αξιοπρέπεια και στα δικαιώματα" 256 | 257 | ensureClassifiedWithConfidence( 258 | t, 259 | text, 260 | "el", 261 | 0.95) 262 | 263 | ensureClassifiedTextNamed( 264 | t, 265 | text, 266 | "Greek", 267 | "Ελληνικά") 268 | } 269 | 270 | func TestHebrewPhrase(t *testing.T) { 271 | text := "כראוי. בִּדקו את כותרת הדף" 272 | lang := "עברית" 273 | 274 | ensureClassifiedWithConfidence( 275 | t, 276 | text, 277 | "he", 278 | 0.95) 279 | 280 | ensureClassifiedTextNamed( 281 | t, 282 | text, 283 | "Hebrew", 284 | lang) 285 | } 286 | 287 | func TestGujaratiPhrase(t *testing.T) { 288 | text := "ગુજરાતી" 289 | lang := "ગુજરાતી" 290 | 291 | ensureClassifiedWithConfidence( 292 | t, 293 | text, 294 | "gu", 295 | 0.95) 296 | 297 | ensureClassifiedTextNamed( 298 | t, 299 | text, 300 | "Gujarati", 301 | lang) 302 | } 303 | 304 | func TestThaiPhrase(t *testing.T) { 305 | text := "ไทย ไทยไทย" 306 | lang := "ไทย" 307 | 308 | ensureClassifiedWithConfidence( 309 | t, 310 | text, 311 | "th", 312 | 0.95) 313 | 314 | ensureClassifiedTextNamed( 315 | t, 316 | text, 317 | "Thai", 318 | lang) 319 | } 320 | 321 | func TestArmenianPhrase(t *testing.T) { 322 | text := "ըստ Գրիգորյան օրացույցի" 323 | lang := "հայերեն" 324 | 325 | ensureClassifiedWithConfidence( 326 | t, 327 | text, 328 | "hy", 329 | 0.95) 330 | 331 | ensureClassifiedTextNamed( 332 | t, 333 | text, 334 | "Armenian", 335 | lang) 336 | } 337 | 338 | func TestSerbianLatinPhrase(t *testing.T) { 339 | text := "ljudi ne znaju jer me uglavnom vide" 340 | lang := "srpskohrvatski" 341 | 342 | ensureClassifiedWithConfidence( 343 | t, 344 | text, 345 | "sr", 346 | 0.85) 347 | 348 | ensureClassifiedTextNamed( 349 | t, 350 | text, 351 | "Serbo-Croatian", 352 | lang) 353 | } 354 | 355 | func TestSerbianCyrillicPhrase(t *testing.T) { 356 | text := "Код животиња су ове реакције посебно важне при зарастању рана" 357 | lang := "српски" 358 | 359 | ensureClassifiedWithConfidence( 360 | t, 361 | text, 362 | "sr", 363 | 0.95) 364 | 365 | ensureClassifiedTextNamed( 366 | t, 367 | text, 368 | "Serbian (Cyrillic)", 369 | lang) 370 | } 371 | 372 | func TestVietnamesePhrase(t *testing.T) { 373 | text := "Truyền thông Việt Nam vào dịp này đăng bài ký tên ông" 374 | lang := "Tiếng Việt" 375 | 376 | ensureClassifiedWithConfidence( 377 | t, 378 | text, 379 | "vi", 380 | 0.95) 381 | 382 | ensureClassifiedTextNamed( 383 | t, 384 | text, 385 | "Vietnamese", 386 | lang) 387 | } 388 | 389 | func TestTeluguPhrase(t *testing.T) { 390 | text := "భారతదేశంలోని దక్షిణ" 391 | lang := "తెలుగు" 392 | 393 | ensureClassifiedWithConfidence( 394 | t, 395 | text, 396 | "te", 397 | 0.95) 398 | 399 | ensureClassifiedTextNamed( 400 | t, 401 | text, 402 | "Telugu", 403 | lang) 404 | } 405 | 406 | func TestTamilPhrase(t *testing.T) { 407 | text := " நீளமான, கிளைக்காத" 408 | lang := "தமிழ்" 409 | 410 | ensureClassifiedWithConfidence( 411 | t, 412 | text, 413 | "ta", 414 | 0.95) 415 | 416 | ensureClassifiedTextNamed( 417 | t, 418 | text, 419 | "Tamil", 420 | lang) 421 | } 422 | 423 | func TestTagalogPhrase(t *testing.T) { 424 | text := "ano ang nangyayari sa iyo at ang mah-ina mo ay hindi mo" 425 | lang := "Filipino" 426 | 427 | ensureClassifiedWithConfidence( 428 | t, 429 | text, 430 | "tl", 431 | 0.95) 432 | 433 | ensureClassifiedTextNamed( 434 | t, 435 | text, 436 | "Filipino", 437 | lang) 438 | } 439 | 440 | func TestDutchPhrase(t *testing.T) { 441 | text := "Een ieder heeft, waar hij zich ook bevindt, het recht als persoon erkend te worden voor de wet" 442 | lang := "Nederlands" 443 | 444 | ensureClassifiedWithConfidence( 445 | t, 446 | text, 447 | "nl", 448 | 0.95) 449 | 450 | ensureClassifiedTextNamed( 451 | t, 452 | text, 453 | "Dutch", 454 | lang) 455 | } 456 | 457 | func TestKannadaPhrase(t *testing.T) { 458 | text := "ನನ್ನ ಹೆಸರು ಭಾರತ್." 459 | lang := "ಕನ್ನಡ" 460 | 461 | ensureClassifiedWithConfidence( 462 | t, 463 | text, 464 | "kn", 465 | 0.95) 466 | 467 | ensureClassifiedTextNamed( 468 | t, 469 | text, 470 | "Kannada", 471 | lang) 472 | } 473 | 474 | func TestNonsense(t *testing.T) { 475 | text := "wep lvna eeii vl jkk azc nmn iuah ppl zccl c%l aa1z" 476 | ensureClassifiedWithConfidence( 477 | t, 478 | text, 479 | "und", 480 | 0.75) 481 | 482 | ensureClassifiedTextNamed( 483 | t, 484 | text, 485 | "Unknown language", 486 | "") 487 | } 488 | 489 | func ensureClassifiedWithConfidence(t *testing.T, text string, expectedLang string, minConfidence float64) { 490 | info := FromString(text) 491 | 492 | assert.Equal(t, expectedLang, info.LanguageCode(), "Misclassified text: "+text) 493 | assert.Equal(t, true, info.Confidence() > minConfidence) 494 | } 495 | 496 | func ensureClassifiedTextNamed(t *testing.T, text string, expectedEnglishName string, expectedSelfName string) { 497 | info := FromString(text) 498 | 499 | assert.Equal(t, expectedEnglishName, info.LanguageName(), "Wrong language name: "+text) 500 | assert.Equal(t, expectedSelfName, info.SelfName(), "Wrong self lang name: "+text) 501 | } 502 | -------------------------------------------------------------------------------- /profiles.go: -------------------------------------------------------------------------------- 1 | package getlang 2 | 3 | var en = []string{" th", "the", "he ", "er ", "ed ", " an", "nd ", " to", " he", "and", "to ", "ing", " of", "ng ", "of ", "her", " ha", "as ", "at ", " in", " be", "re ", "on ", "in ", "is ", " wa", " a ", " no", " co", " hi", " wh", "hat", " sh", " i ", "or ", "it ", "ly ", " it", " wi", "you", " yo", "d t", "tha", "e t", "en ", "ll ", "was", "for", "ver", "n t", "ere", " fo", "me ", "e w", "ld ", "ve ", "ent", "ad ", "an ", "she", "his", "e s", " ma", "th ", "not", "st ", " re", "t t", "ion", "ter", "e h", "e a", " so", "ut ", "ot ", " on", "ou ", " as", "es ", "ry ", "thi", "all", "e o", "ne ", "ith", "had", "oul", "le ", "eve", "nt ", "ch ", "ce ", "uld", "d h", " we", "wit", "be ", "t i", "s a", " mo", "tio", " al", " se", "se ", "d a", "hin", " wo", "e i", " do", "ave", "s t", "nce", " at", "t a", " ca", "t h", "rs ", "e c", " sa", "hav", "e m", "t w", " su", " bu", "hou", " me", "ome", "our", "ow ", "ay ", " lo", " is", "ess", " ho", "him", "ss ", "f t", "ear", "ain", "ght", " li", " si", "n a", "s o", "r t", "but", "one", "d b", "ugh", " de", "ill", "rea", " di", "ery", " pr", "d s", "t o", "oth", " st", "con", "im ", "s s", "d i", "cou", " pa", " fr", "ers", "y t", "ati", "t s", "res", "id ", "ell", "ted", " mi", "r s", "d n", "r a", "e f", "int", "een", "oug", " mu", "eli", "by ", "ht ", "om ", "red", "n h", "men", "hen", "com", "te ", "are", " ev", "ir ", "ann", "e p", "g t", "ey ", "ore", "wer", "ty ", "sel", " la", "igh", "whi", "ate", " fa", "ect", "ble", "o t", "lin", "e b", "d w", " s ", "nne", "e d", "ove", " go", "ur ", "y a", "d o", "rd ", "now", "ure", " by", "o h", "tho", "ard", "out", " ch", " el", " mr", "ts ", "s w", "han", " my", "uch", "est", "man", "ous", "s i", "per", " fe", "so ", "s h", " ne", "lf ", "hey", "et ", "ind", "rom", "al ", "ons", "art"} 4 | 5 | var es = []string{" de", "de ", " la", "os ", "la ", "es ", "e l", " y ", " co", "ión", "ón ", "as ", "los", "o d", " lo", " un", "ad ", "dad", "ent", "s d", " es", "el ", "aci", "cio", "con", "ion", "res", "al ", "com", "ida", "les", "uni", " pr", " re", "ció", "rta", "s y", "tad", "a u", "ale", "cia", "del", "der", "ere", "est", "nci", "nes", "nió", "rec", "s c", " en", "a c", "a d", "a l", "ado", "ech", "nal", "ona", " a ", " ca", " eu", "art", "cho", "esp", "eur", "las", "lib", "n d", "nte", "rop", "s e", "uro", "y d", " el", " li", " so", "ada", "ar ", "ber", "en ", "hos", "n e", "one", "ons", "s a", "s p", "te ", "to ", " pa", " tr", "a e", "car", "do ", "e e", "e s", "enc", "ert", "ia ", "ibe", "ici", "io ", "man", "men", "mo ", "na ", "ntr", "o e", "omo", "sta", "sí ", "ta ", " as", " ba", " fu", " hu", " in", " ju", " mi", " po", " su", "a p", "a y", "así", "cci", "d d", "den", "des", "dos", "e c", "e d", "ers", "hum", "ico", "idi", "ien", "l c", "l p", "mie", "mun", "nta", "omu", "ope", "or ", "par", "pro", "rad", "s m", "sid", "sti", "tal", "ten", "tri", "uma", "una", "ven", "í c", " ci", " di", " se", " va", "a a", "a r", "a s", "act", "ade", "alo", "ame", "ana", "ano", "ant", "ara", "ari", "ble", "bro", "cie", "cip", "cos", "cul", "dam", "das", "dic", "ecc", "eda", "emb", "end", "eni", "fun", "ibu", "iem", "ili", "inc", "ios", "ipi", "ir ", "itu", "iza", "jo ", "l d", "l y", "lid", "lor", "mbr", "n c", "n y", "nac", "nda", "nos", "nti", "nve", "o l", "oci", "ont", "onv", "opa", "ore", "pa ", "pet", "pio", "por", "pri", "r e", "r l", "r u", "re ", "rea", "rib", "rid", "rin", "ro ", "ros", "s f", "s i", "soc", "spe", "tar", "tec", "tic", "tra", "tro", "tua", "ual", "un ", "und", "une", "uri", "val", "y l", " ac", " al", " cr", " fo", " me", " na", " pe", " pu", " qu"} 6 | 7 | var pt = []string{"os ", " da", " e ", "da ", " co", " do", "as ", "de ", "e d", "ão ", "dad", "ade", "do ", "es ", " a ", "o d", " de", "o e", "s d", "dos", "ent", "s e", " pr", "con", "res", "a c", "a e", "com", "eit", "ida", "is ", "uni", "ção", " se", " un", "das", "est", "ito", " di", " es", " re", "a u", "ais", "al ", "ião", "niã", "to ", "uro", " pa", "a d", "ada", "dir", "ia ", "nte", "o p", "rei", "s p", " as", " ca", " eu", " pe", "a p", "a s", "ado", "cia", "des", "em ", "eur", "ire", "men", "ra ", "rop", "s c", "ta ", " li", " no", " so", "a a", "art", "esp", "ion", "lib", "o c", "ona", "ons", "par", "pro", "rad", "s a", "sen", "ser", "sta", "te ", "tos", "ura", "çõe", "ões", " in", " um", "ara", "ber", "car", "cio", "e c", "erd", "ibe", "mem", "nal", "no ", "omo", "pei", "pel", "rda", "rta", "s s", "sid", "tad", "tri", "um ", "uma", " ao", " be", " fu", " ju", " me", " na", " o ", " po", " tr", "a o", "aci", "ass", "açã", "ca ", "e a", "e p", "eia", "ela", "ese", "ess", "ibu", "idi", "ili", "io ", "l e", "lid", "mo ", "mun", "nci", "ndo", "ns ", "nta", "nto", "o s", "omu", "ope", "rib", "rin", "s i", "s m", "sti", "ual", "ver", "vol", " ci", " hu", " os", " va", "a l", "a r", "alo", "ame", "ano", "ar ", "açõ", "bem", "bil", "bro", "cie", "cíp", "dam", "div", "e e", "e n", "ece", "eda", "egu", "emb", "end", "enç", "er ", "erv", "hum", "ica", "ied", "ime", "inc", "ind", "itu", "içõ", "lor", "m c", "m d", "ma ", "man", "mbr", "na ", "nac", "nai", "ncí", "nve", "nçã", "o r", "oci", "ome", "ont", "onv", "opa", "ore", "pa ", "pio", "pre", "pri", "r u", "ras", "ros", "s f", "seg", "soc", "sse", "sso", "ste", "tai", "tra", "tur", "uns", "val", "ven", "ça ", "ípi", " at", " en", " ev", " ho", " ma", " ne", " ob", " qu", " su", " te", "a i", "abe", "abi", "adi", "aes", "ani"} 8 | 9 | var pl = []string{"ch ", " i ", " pr", "ych", "nie", "ści", " po", "ośc", "prz", "ci ", "ego", "go ", "ie ", "pra", " na", "nyc", "raw", "rze", "eni", "noś", " or", " un", "art", "dzi", "h p", "ora", "stw", "uni", "wie", " eu", " ko", " za", "az ", "eur", "h w", "ia ", "ien", "kie", "owa", "owi", "raz", "rop", "rzy", "ski", "uro", "wa ", "ym ", " ka", " sp", " ty", " w ", "czn", "ej ", "ejs", "i o", "iej", "lno", "lny", "neg", "nia", "rod", "sta", "zło", "ńst", " cz", " wo", " ws", "a p", "aln", "aw ", "cji", "czł", "ecz", "i i", "i p", "ji ", "kar", "kon", "na ", "orz", "twa", "w c", "wsp", "óln", " pa", " ro", " sw", " tr", " wy", " z ", "a s", "ach", "ada", "ady", "ani", "aro", "ańs", "dow", "dy ", "ez ", "i s", "i z", "ich", "icz", "ied", "ier", "ii ", "jsk", "kow", "nar", "nii", "obo", "oln", "ope", "ows", "owy", "ość", "pań", "pej", "pod", "pól", "rów", "spo", "spó", "tyc", "tym", "war", "wol", "wyc", "y p", "za ", "zez", "zie", "zy ", "ść ", " dz", " je", " ni", " ob", " oc", " op", " os", " ró", " so", " st", " to", " wa", "a z", "asa", "awi", "ału", "ań ", "chr", "ctw", "cze", "dno", "e o", "e p", "e z", "em ", "ent", "est", "hro", "ict", "iąz", "ię ", "ju ", "m k", "ne ", "nic", "nko", "now", "nwe", "ny ", "nym", "o i", "o o", "och", "odn", "oju", "onk", "onw", "ony", "opr", "opy", "ozw", "ołe", "pie", "pow", "poł", "pre", "py ", "rad", "ron", "roz", "rto", "sad", "się", "sob", "sza", "taw", "toś", "two", "um ", "wan", "wen", "wia", "wią", "wni", "wob", "woj", "wsk", "yni", "ysz", "z t", "z z", "zas", "zki", "zny", "zwo", "zyn", "zys", "ówn", "ą p", "łec", "łon", "łu ", " ce", " do", " ic", " in", " kt", " lu", " mi", " od", " re", " si", " są", " us", " zw", "a i", "a j", "a k", "a n", "a u", "a w", "acj", "ano", "ate", "awa", "awo", "bli", "bod", "bow", "bun", "bą "} 10 | 11 | var hu = []string{"és ", " a ", " és", " az", "az ", " sz", "ség", "s a", "ság", " kö", "ala", "ek ", "en ", "z e", "egy", "jog", "köz", "ok ", " eg", " jo", "a t", "gok", "n a", " al", " el", " un", "art", "ben", "ele", "lam", "nió", "nt ", "tt ", "tás", "uni", " eu", "a s", "ai ", "eur", "ió ", "ogo", "róp", "uró", "z u", "ége", "ópa", " fe", " me", " ta", " ér", "a a", "aba", "ak ", "bad", "i k", "k é", "nak", "sza", "t é", "tel", "zab", " ch", " va", "ads", "ami", "at ", "cha", "dsá", "emb", "eri", "ett", "gye", "gál", "har", "int", "kat", "lap", "mbe", "meg", "oka", "pai", "ri ", "s e", "s é", "sze", "szt", "t a", "val", "zet", "áll", "ány", "ás ", "éke", "ért", "özö", " e ", " em", " ha", "a j", "an ", "ber", "hat", "ksé", "let", "lla", "ló ", "mi ", "min", "mok", "mán", "nek", "rán", "sa ", "szo", "ti ", "zös", "ág ", "ágo", "ása", "át ", "ény", "ét ", "ósá", " bí", " ki", " ne", " so", " te", " tá", "ada", "agy", "agá", "alm", "amo", "apu", "ata", "atá", "ban", "bír", "ból", "dés", "e s", "ege", "ejl", "ell", "elv", "elő", "emz", "ent", "eze", "fej", "fel", "g é", "gy ", "hoz", "ik ", "itá", "ja ", "k e", "k k", "kek", "kés", "lis", "lmi", "lye", "lős", "mze", "mél", "n t", "nem", "omá", "ott", "pul", "rtá", "rté", "rós", "s f", "s h", "s k", "sok", "ssé", "szi", "sít", "t e", "tag", "tar", "tja", "ték", "vet", "yek", "zto", "ába", "ágá", "ált", "án ", "ána", "árs", "ásá", "ég ", "égé", "ésé", "író", "ítá", "ól ", "öks", "ös ", "ől ", " bi", " ho", " ir", " jö", " ko", " lé", " né", " os", " ti", " tu", " ál", "a c", "a k", "a é", "apv", "ari", "biz", "ből", "dal", "dat", "e j", "e t", "edé", "eho", "ei ", "eke", "el ", "elm", "eln", "ely", "emé", "enn", "erő", "es ", "esz", "et ", "etb", "ete", "etk", "ető", "ez ", "ezé", "ge ", "gei", "ger", "gon", "gya", "gyo", "gán"} 12 | 13 | var it = []string{" de", "la ", " e ", " di", "ell", "del", "to ", "e d", " co", "le ", " la", "re ", "di ", "o d", "lla", "ne ", "ti ", " un", "ion", "i d", "ent", "li ", "e l", "a s", "con", "do ", "one", " il", " in", "a d", "che", "gli", "il ", "e i", "he ", "i s", "no ", "a c", "zio", " pr", "e c", "te ", "el ", " ch", "a p", "e e", "ava", "na ", "nte", "tà ", " da", " ne", "o e", "tti", " al", " ca", " qu", "ale", "all", "azi", "ndo", "i p", "ia ", "ni ", "ri ", "va ", "si ", " no", " ri", "lo ", "ond", "rit", "ta ", " a ", " le", " po", " st", "ant", "ato", "e s", "ess", "lle", "ra ", "ro ", "sta", "tto", "van", " pe", " si", " so", "a e", "e n", "era", "est", "itt", "per", "sse", "uni", "com", "dir", "ei ", "i e", "iri", "man", "nel", "o c", " gi", " pa", "a l", "i c", "l u", "men", "o s", "sti", "tra", "un ", " li", " su", "e a", "ll ", "mon", "o l", "on ", "se ", "so ", " l ", " ma", " me", "al ", "ber", "dei", "e p", "ibe", "ide", "in ", "io ", "lib", "nto", "pro", "res", "val", "ali", "ard", "are", "da ", "der", "er ", "ere", "ers", "i a", "l c", "lor", "non", "pre", "ver", "za ", " fo", " i ", " ra", " sp", "a a", "ann", "ert", "ett", "llo", "nti", "o a", "ons", "ore", "que", "str", "a t", "ano", "dal", "eva", "gni", "imo", "qua", "rat", "rtà", "ser", "sid", "tat", " do", " te", " tr", " um", "a r", "cor", "cos", "end", "gio", "i i", "ian", "l p", "nio", "o i", "r l", "rdo", "sa ", "ter", "tri", "uma", " pi", " se", "a f", "ass", "att", "cav", "e g", "gua", "isp", "ità", "l s", "me ", "mo ", "nal", "nda", "nza", "omu", "oni", "ono", "ort", "osc", "ott", "ris", "rop", "rta", "spe", "spo", "tal", "ven", " av", " lo", " mo", " re", " sa", " sc", "a g", "a i", "a m", "a n", "ame", "anz", "bil", "ear", "egl", "eri", "fon", "i g", "i m", "i u", "l l", "lea", "ma ", "n u"} 14 | 15 | var de = []string{"en ", "er ", " de", "der", "ich", " un", "ie ", "nd ", "und", "ein", "ch ", "sch", "te ", " di", "die", "cht", "es ", " ge", "che", " si", "den", "in ", " ei", " au", " da", "ine", "nde", "gen", "ne ", "sie", "ung", "em ", "e s", "e d", "n d", " mi", " we", "ht ", "n u", "ion", "lic", "ng ", "as ", "ber", " in", " zu", "hen", "her", "nen", "ten", " so", "r s", "st ", " be", " er", "aus", "ech", "ist", "it ", "on ", "ste", "ler", "t d", " ha", "ar ", "das", "eit", "end", "n g", " an", " re", " st", "abe", "d d", "r e", "ter", "cha", "des", " fr", " ic", "dem", "ent", "ers", "hte", "r d", "ver", "n s", "rec", " he", " is", " sa", " sc", "auf", "ese", "he ", "men", "mit", "nte", " ni", " se", " vo", " wa", "ach", "ale", "and", "e e", "ies", "len", "rei", "ren", "s d", "sic", " al", " fa", " ih", " ke", " me", " ve", " wi", "alt", "ben", "e f", "e n", "e u", "ell", "ert", "isc", "n e", "nge", "rt ", " ab", " en", "chl", "e i", "g d", "ger", "hei", "ihr", "mei", "nic", "r a", "r g", "s s", "tio", "enn", "ens", "fre", "hre", "ied", "lei", "lie", "ner", "nn ", "nsc", "r h", "rde", "t u", "uf ", "ur ", "war", "zu ", " do", " le", "ati", "e a", "erk", "fal", "ier", "n a", "nst", "r m", "s i", "tan", " od", "ede", "erz", "hau", "lle", "ls ", "nie", "och", "ode", "rte", "t e", "wer", "wie", " ba", " du", " es", " nu", "als", "at ", "e w", "erb", "ere", "ete", "f d", "h d", "n v", "r b", "rau", "re ", "spr", "sta", "tte", " sp", "eih", "ene", "eri", "ft ", "ges", "gte", "ige", "ihe", "ind", "ite", "kei", "lt ", "n f", "n r", "n z", "nne", "ns ", "ons", "run", "s a", "se ", "sen", "t s", "tel", "tha", "tig", "tun", "uni", "uns", "wei", "ät ", " gr", " je", " ko", " kü", " na", " no", " pr", "ann", "ck ", "d g", "d s", "de ", "det", "e h", "e m", "eic", "eme", "eni", "epp"} 16 | 17 | var ru = []string{"ой ", " со", " в ", " не", "али", "ии ", " ко", " пр", " де", "ть ", " бо", " во", " на", " по", "иал", " и ", "ист", "кон", "ли ", "лис", "аци", "дел", "соц", "ции", "ени", "ие ", "их ", "ия ", "не ", " за", "еле", "кой", "но ", "оль", "оци", "ско", "циа", " бы", " го", " ре", "иче", "ла ", "при", "бол", "то ", " об", "ей ", "ере", "и с", "лег", "льш", "ны ", "ото", "рен", "ста", "чес", " ра", " св", " ст", "ая ", "вой", "ега", "жен", "и о", "люц", "на ", "ной", "нци", "олю", "ств", "ьше", "юци", " же", " ка", " от", " с ", "был", "го ", "еви", "енц", "еск", "и п", "ло ", "ни ", "нфе", "ов ", "оло", "онф", "сво", "сти", "сто", "ся ", "тор", "фер", "ция", "шев", " ру", " то", "а и", "ать", "вал", "гол", "е н", "е с", "енщ", "ерн", "за ", "ка ", "ки ", "кот", "ние", "нщи", "ова", "ого", "одн", "ом ", "ост", "пер", "ски", "стр", "тел", "тич", "щин", "я с", " им", " к ", " ме", " ни", " чт", " эт", "бы ", "вол", "гац", "гов", "е в", "еме", "ет ", "й в", "кла", "льн", "мен", "мир", "ово", "про", "раб", "сь ", "ую ", "что", "ые ", "ый ", " до", " ми", "або", "ала", "ара", "аро", "аст", "в т", "вре", "дно", "ево", "енн", "ецк", "и в", "им ", "ию ", "й к", "й р", "кие", "лар", "лос", "мец", "нар", "нем", "о в", "о п", "ове", "ойн", "она", "ран", "рез", "рем", "рти", "тер", "тки", "тра", "х с", "ь с", " ве", " вр", " вы", " из", " но", " о ", " од", " па", " са", " те", "а д", "а п", "а с", "ак ", "ани", "арт", "асс", "ате", "бор", "в к", "ва ", "вич", "вши", "да ", "дат", "еде", "ее ", "езо", "ело", "ем ", "ен ", "ест", "зол", "и б", "из ", "ий ", "ико", "име", "ион", "й б", "й д", "й п", "йны", "кая", "ких", "лен", "му ", "нац", "нно", "о с", "об ", "оди", "ок ", "ому", "осо", "от ", "пар", "пос", "рас", "рев", "род", "сам", "сле", "соз", "тва", "том", "цио", "ых "} 18 | 19 | var uk = []string{" на", " пр", "их ", "ого", "ми ", " за", " та", "го ", "ння", "ів ", "льн", "від", "ня ", "та ", "ть ", " до", "на ", " ві", "аці", " по", "ий ", "ни ", "ні ", "аль", "них", " ви", "ки ", "ник", "ої ", "про", " ро", " і ", "кра", "нів", "ста", " що", "анн", "енн", "раї", "іст", " сп", " ук", "аїн", "ере", "роз", "ти ", " не", " у ", "ний", "ово", "ред", " пе", "вер", "ног", "ови", "ост", "ють", "ії ", " ст", "ерс", "сит", "ува", "укр", "ьни", "ьно", "їни", " в ", " мо", " ун", "али", "ван", "вни", "ими", "ите", "но ", "ові", "ою ", "пре", "рси", "ськ", "ся ", "тет", "уні", "іве", " ко", "аук", "ент", "жен", "за ", "и в", "и н", "ист", "ли ", "нал", "нау", "нов", "о н", "пер", "так", "що ", " ма", " ор", " пі", " як", "дов", "ка ", "ков", "ом ", "тов", "тор", "ями", " бу", " з ", " це", "а п", "а с", "ати", "бро", "збр", "и з", "и п", "ків", "лен", "ним", "о п", "о с", "під", "рга", "ції", "ідн", "ійс", " де", " си", "ана", "вал", "ган", "док", "дос", "и о", "кан", "лом", "не ", "ням", "ніс", "о о", "ову", "окр", "орг", "рос", "слі", "ько", "я п", "і з", " ки", " ні", " ін", "алі", "ано", "вищ", "вод", "ві ", "ету", "йсь", "ком", "лід", "ної", "одн", "одо", "ори", "пов", "рив", "рів", "спе", "сто", "сть", "ту ", "ючи", "іал", "іль", " но", " об", " їх", "а т", "ало", "ані", "аюч", "ден", "дер", "дно", "зна", "им ", "иїв", "ких", "киї", "кла", "ло ", "нос", "о з", "ова", "озб", "омб", "ото", "пло", "рис", "тьс", "ті ", "уко", "ціа", "чен", "чи ", "ься", "і о", "ід ", "ій ", "їх ", " а ", " ка", " кв", " кр", " лі", " мі", " оз", " оп", " су", " те", " хр", "ада", "алу", "ами", "ают", "бет", "був", "бул", "в н", "вор", "гот", "дни", "дні", "до ", "дій", "ебе", "етн", "еці", "ивн", "ити", "й н", "йни", "каз", "кор", "кри", "ку ", "му ", "над", "нта", "ну ", "оло"} 20 | 21 | var fr = []string{" de", "it ", "es ", "de ", "ait", " le", "le ", "nt ", "re ", " la", " qu", "ent", "il ", " pa", " un", "la ", "e l", "que", " il", "on ", "e d", "et ", " et", "ne ", "ns ", " en", "is ", " ma", "ur ", " co", "ue ", "e s", "ui ", "t d", "en ", " à ", " se", "ant", "e p", "er ", "s d", "te ", "un ", " l ", "ais", "ill", "les", "us ", "t l", " so", " au", "lle", "par", "our", "e m", " du", "qui", "r l", "t p", " d ", "du ", "s l", " mo", " pe", "ans", "e c", " re", " to", "ier", "ien", "ion", "me ", "se ", "tou", "tre", "vai", "des", "l a", "son", "tai", "ce ", " av", " ét", "e t", " ce", " sa", " vo", "out", " ch", "ut ", "ux ", "e r", "s p", "éta", " di", " je", "che", "mai", "tio", "con", "dan", "eur", "n a", " fa", " po", " pr", " vi", "ati", "e n", "men", "rin", " da", " su", "au ", "ava", "je ", "pas", "té ", " pl", "cha", "e e", "sai", " te", " tr", "ar ", "e f", "ons", "r d", "rs ", "tte", " ca", " fi", "e a", "est", "in ", "n d", "ois", "ous", "qu ", "rre", "une", "as ", "e v", "err", "ge ", "ine", "iss", "lui", "rai", "ran", "res", "s a", "s c", "s e", "t m", "ère", " gr", "plu", "sur", "ter", "ts ", " mi", "eme", "end", "ett", "ire", "lus", "mme", "pou", "sa ", "t a", " es", " lu", "ain", "eil", "eux", "ir ", "moi", "omm", "onn", "t s", " bo", " m ", "a p", "ass", "com", "e q", "fai", "iqu", "ont", "s t", "st ", "t à", "tri", " me", " ne", " no", " ou", "a c", "ard", "arr", "aud", "ers", "ieu", "mag", "s s", "t c", "t e", "t t", "é d", " a ", " ap", " ar", " n ", " ro", "ali", "eau", "ell", "int", "nte", "oi ", "ssa", "ure", "ute", " fr", "aie", "and", "aut", "cou", "gau", "l e", "lai", "lat", "lie", "n p", "s m", "s q", "ses", "u i", "vil", "ée ", " bi", " pi", " ré", "aga", "anc", "bie", "d u", "dit", "he ", "ité", "nde", "ou ", "ouv", "pré", "s b"} 22 | 23 | var hi = []string{"के ", "ें ", " के", "में", " मे", "की ", "ने ", " की", "ा क", " को", "या ", "को ", " है", "ना ", "से ", "िया", " का", "ा प", " कि", " से", "ी क", "ार ", " उस", " ने", "र क", "े क", " प्", " सा", "ता ", "प्र", " पह", " बा", "का ", " और", " खि", "और ", "ले ", "े ह", " उन", " कर", " स्", "ं क", "पहल", "है ", "े प", "े म", " मु", " हो", "कार", "्रा", " पर", " वर", "िन ", "े ब", "ों ", " इस", "थी ", "न क", "बाद", "ही ", "ार्", "िला", "ी ज", " मा", "कि ", "खिल", "रण ", "ला ", "स्ट", "ा स", "ाद ", "ी प", "ी ह", "े द", " अप", " थी", " पु", "ं प", "अपन", "उसक", "कर ", "निय", "पर ", "यता", "र म", "री ", "रीय", "रे ", "र्ग", "र्ट", "वरी", "स क", "हले", "ा द", "ा म", "ानि", "िए ", "िस ", "ीं ", "ीयत", "े आ", "े स", "्ग ", "्त ", " था", " दे", " दो", " वि", "इस ", "उन्", "क्ष", "गी ", "द्र", "न्ह", "प्त", "र स", "राप", "ल क", "लिस", "सान", "हैं", "ाब ", "ाल ", "ी ब", "ी स", "े उ", "े ख", "े ग", "े र", "ैं ", " ओप", " क्", " ती", " तो", " मै", " रह", " ले", " लड़", " हा", " ही", "ं ह", "ंड ", "उनक", "ओपन", "क्व", "त क", "तो ", "न म", "पन ", "पने", "पुल", "म क", "मार", "मुद", "र उ", "ल म", "ली ", "लड़क", "वार", "सरे", "हों", "ाइन", "ाई ", "ाने", "ाप्", "िक ", "िता", "ुद्", "ुलि", "े ल", "ोर्", "ौर ", " 20", " एक", " कु", " गए", " गा", " जी", " दू", " दौ", " पड", " फि", " फ्", " बत", " भी", " रा", " रू", " वा", " सक", " सु", " हम", "200", "ं उ", "ं म", "ं स", "ंच ", "इनल", "उसन", "करन", "कों", "खित", "गए ", "घर ", "ट क", "ड़ा", "डाल", "ताब", "था ", "द क", "दौर", "न ह", "नल ", "नी ", "नेड", "प म", "पड़", "पी ", "फाइ", "फ्र", "बता", "भी ", "र प", "र फ", "रका", "रें", "र्म", "लाफ", "व म", "वा ", "सकी", "सने", "होग", "़ा ", "ान ", "ाफ ", "ाया", "ी थ", "ी न", "े भ", "ेडा", "ेने", "ो स", "्रे", "ड़की", " 14", " आर", " खे", " गई", " चै", " जब", " जर", " दि", " ना", " पा", " फा", " बे"} 24 | 25 | var vi = []string{"ng ", " nh", " ch", "nh ", " tr", " kh", " ng", "ên ", " và", "ông", "g t", "g c", "n t", "n c", "ào ", " củ", "của", "iên", "ại ", "ủa ", " gi", " vi", "i t", " ph", "và ", "ác ", " cá", " là", "c t", "g đ", "g n", "i c", "ất ", "ời ", "g v", "là ", "t n", "ến ", "ều ", " qu", "ch ", "các", "iều", "ột ", " có", " ti", "có ", "n n", "ngư", "nhậ", "u t", "ày ", "áo ", " ho", " tư", " tấ", " đi", "ang", "cho", "hi ", "ho ", "khi", "ong", "việ", "ới ", " cô", " tạ", " ở ", "côn", "hủ ", "i n", "ron", "tro", "vào", " đã", "anh", "c c", "gườ", "hiệ", "hật", "tấn", "ăm ", "ười", "ấn ", "ật ", " na", " nà", " đư", "h n", "h đ", "hoa", "hàn", "hôn", "nhi", "o n", "o t", "oa ", "t t", "tại", "ân ", "đã ", "ết ", " an", " bi", " cả", " mộ", " nó", " nă", "a h", "a t", "khô", "m t", "một", "n b", "n v", "n đ", "t c", "t đ", "tiê", "à c", "ình", "ược", "ện ", "ợc ", " ba", " bá", " bắ", " hi", " sẽ", " đầ", "ao ", "báo", "hữn", "iệc", "iện", "m c", "ngà", "nhữ", "năm", "sẽ ", "tri", "ách", "đượ", "đầu", "ầu ", "ệc ", "ững", " ra", " đà", " độ", "a a", "a n", "c m", "c đ", "gày", "h s", "hác", "i đ", "iến", "iết", "khá", "nói", "riề", "ung", "uộc", "át ", "ói ", "đào", "ộc ", "ộng", " bị", " họ", " to", " vẫ", " ôn", " đế", " đồ", "am ", "ay ", "bị ", "chi", "g h", "g k", "g l", "hiế", "hán", "hất", "i v", "này", "ra ", "t b", "t l", "thá", "u k", "vẫn", "à n", "à đ", "ành", "áng", "ó t", "ùng", "đến", "đồn", "ước", "ườn", "ản ", "ẫn ", "ớc ", "ờng", " bả", " cu", " du", " hà", " nư", " sá", " tu", " về", " vớ", "bản", "chủ", "cản", "g ở", "h t", "hin", "hiê", "họ ", "i h", "i m", "iệt", "nhấ", "nướ", "o b", "o l", "o s", "o v", "o đ", "qua", "thủ", "tướ", "uan", "viê", "về ", "với", "ya ", "àn ", "ướn", "ải ", "ảnh", "ần ", "ận ", "ập ", "ệnh", "ệt ", "ối ", "ớng"} 26 | 27 | var srLatin = []string{"je ", " na", " je", " po", "na ", " ko", "gra", " i ", "da ", " da", " pr", "rad", "a s", "ju ", "koj", "ma ", " ka", "a k", " iz", "i n", "ne ", " u ", "ako", "e s", "ko ", "ji ", "la ", " su", " sv", " gr", " ne", " za", "a d", "su ", " st", "a i", "ao ", "e p", "ije", "li ", "no ", "o j", "sta", "te ", "e n", "ima", "ogr", "oji", "ti ", "u s", " bi", " sa", "i s", "ila", "io ", "ja ", "ost", " do", " se", "a j", "a n", "a u", "e k", "i p", "ni ", "oj ", "pre", "se ", "u p", " fo", "avi", "cij", "e i", "e u", "i d", "kak", "nje", "om ", "pos", "ta ", " a ", " dr", " to", "ada", "aju", "as ", "e d", "las", "pro", "že ", " re", " ta", "a p", "ali", "dru", "e g", "e m", "e o", "ija", "nik", "o p", "ozi", "ruš", "sti", "svo", "ven", "za ", "će ", " be", " ob", " on", " vo", " će", "ado", "bi ", "de ", "eli", "em ", "fot", "i i", "ih ", "im ", "ist", "iz ", "ić ", "nač", "nim", "o b", "oni", "oto", "raf", "str", "tog", "tra", "u i", "ve ", "voj", " mr", " ni", " od", " op", " pa", " sl", " sn", " ul", "a o", "afi", "ala", "aln", "ama", "ava", "beo", "do ", "eka", "eni", "enj", "eog", "fij", "iti", "ka ", "kom", "ku ", "lic", "lju", "mre", "nal", "nu ", "o n", "o o", "o s", "og ", "oje", "ona", "ova", "poz", "pra", "raj", "rem", "rež", "ste", "sve", "tve", "u n", "ušt", "štv", " ak", " lj", " mo", " si", " tr", " ve", " vi", "a v", "ana", "ani", "anj", "ate", "ače", "di ", "dio", "don", "e j", "e r", "ene", "enu", "ga ", "gla", "i o", "i u", "ici", "iji", "ile", "ite", "jem", "kol", "le ", "lit", "m p", "m s", "mal", "men", "nja", "nji", "nos", "ora", "orm", "pri", "red", "sao", "tak", "tal", "tan", "to ", "tru", "uli", "uri", "voz", "čel", " bu", " go", " ma", " nj", " os", " ra", " sr", " us", "aci", "ad ", "aj ", "aje", "ak ", "am ", "asn", "aza", "azi", "ači"} 28 | 29 | var srCyr = []string{"је ", " у ", " и ", " је", " ко", " на", " се", " пр", "на ", "се ", "не ", "ост", " по", "ма ", "ом ", "е с", "има", " су", "а с", "вар", " од", "е п", "ије", "ста", "а и", " не", " ре", "ара", "кор", "а у", "ија", "е к", "е о", "им ", "ке ", "ог ", "ју ", " ос", " са", "да ", "е и", "е у", "ина", "ств", "су ", " кр", " ма", " ме", " ст", "а к", "ами", "ање", "и с", "про", "ско", "та ", "тва", " де", " ка", "ао ", "ва ", "и п", "ине", "ита", "мин", "ни ", "ног", "ова", "рањ", "сти", " за", "вит", "м с", "ном", "ске", "у у", "циј", "ња ", " би", " да", "а н", "ада", "е ј", "ели", "еме", "ено", "ла ", "лик", "нај", "ови", "од ", "орб", "пор", "са ", "там", "то ", "тра", "у м", "аст", "аци", "за ", "и к", "крв", "ним", "но ", "о с", "сле", "спо", "у и", "у о", "ја ", " ки", " мо", " ц ", "а п", "ава", "већ", "и и", "и н", "ио ", "исе", "их ", "ка ", "ли ", "ра ", "ран", "ри ", "ст ", "сте", "у с", "ње ", " ви", " ра", " св", " те", "а м", "али", "ано", "ају", "бин", "гра", "е д", "е з", "е н", "едо", "ем ", "ент", "еђу", "ећа", "и у", "ико", "ков", "кос", "мен", "међ", "нед", "нос", "нте", "око", "оли", "оре", "рва", "ром", "тан", "тим", "у п", "јав", " из", "а д", "а ј", "ан ", "био", "д с", "дно", "дов", "ду ", "е м", "ења", "зе ", "кис", "ко ", "кој", "лин", "мећ", "нск", "ој ", "пос", "пре", "при", "рем", "сел", " ас", " бо", " ве", " до", " си", " сп", " тр", " хи", " ја", "а р", "а ц", "ала", "ама", "аре", "ари", "аск", "ве ", "е в", "ене", "ени", "ери", "ива", "иво", "ила", "инт", "кол", "м к", "о н", "о у", "оди", "оже", "раз", "рез", "рењ", "соб", "тат", "тер", "у к", "ји ", "њен", "њу ", " вл", " ис", " ни", " пе", " ск", " сл", " хр", " че", "а б", "ави", "ављ", "ане", "ани", "бог", "вањ", "вла", "вља", "г с", "га ", "ест", "же ", "зна", "и д", "ино"} 30 | 31 | var tl = []string{"ng ", "ang", " na", " an", "ay ", " sa", " ng", "an ", "sa ", " ma", "na ", " pa", " ka", "at ", "g m", " ay", "ala", "g p", "n n", " at", "g t", "ing", " ba", "pag", "apa", "ga ", "isa", "hin", "in ", "ong", "san", " ta", "a n", "a a", " mg", "man", "mga", "ata", "nga", "ama", "g i", "lan", " ni", " is", "aka", "awa", "a p", " hi", " si", "g n", "a s", "g k", "ina", "a m", "di ", "n a", "yan", "asa", " tu", "aba", "aga", "g a", "pan", "a b", "aki", "ila", "t n", " da", "a k", "aha", "ara", "g b", "g d", "ind", " la", "ali", "aya", "ndi", "tan", "abi", "aw ", "g s", "iya", "nag", "ta ", "y n", "ya ", "ag ", "al ", "gan", "iny", "nin", "o a", "yo ", " di", "ili", "lin", "mat", "ni ", "nyo", "on ", "po ", "gaw", "mag", "nan", "pin", "uma", "wa ", "y a", " pi", " po", "a t", "ban", "gka", "i m", "ito", "kin", "l a", "n s", "o s", "ung", "agp", "ana", "and", "dal", "ini", "nak", "nap", "no ", "o n", "sal", "to ", "wan", " ak", " y ", "ail", "ati", "bab", "g h", "i n", "it ", "ita", "kab", "kan", "si ", "t s", " bu", " in", " mi", "agk", "ain", "ani", "aon", "bat", "g l", "gal", "i s", "kal", "kas", "kit", "ko ", "lak", "mal", "may", "nda", "ngg", "pat", "rin", "tag", "tin", "ula", "yon", " ko", " pu", "as ", "hai", "il ", "ipi", "kay", "kha", "lal", "law", "mik", "nat", "ot ", "pap", "siy", "tul", " ha", " it", " t ", " wa", " ya", "a h", "ad ", "ags", "ari", "bil", "eri", "gpa", "ihi", "ikh", "ka ", "kap", "l n", "la ", "o y", "pam", "pil", "t a", "utu", "wal", "y i", " ga", " hu", " ju", " se", " ti", "a i", "aan", "ahi", "ano", "any", "api", "ayo", "bak", "d n", "g u", "gay", "gin", "iki", "lab", "lam", "mar", "nas", "os ", "pak", "ral", "raw", "sti", "tat", "ter", "w a", " du", " ku", " no", "ako", "alu", "atu", "ba ", "bal", "bis", "cia", "el ", "eme", "g g"} 32 | 33 | var nl = []string{"en ", " de", "de ", "er ", "et ", "an ", " he", "den", "een", " en", "n d", "aar", " ee", "te ", " ge", "gen", " wa", " va", " te", "ar ", "het", "ver", "van", "ij ", "nde", " we", " zi", " in", " da", "in ", "oor", " vo", "sch", "n e", "der", "ten", " me", "n h", " ve", " on", "cht", " be", "at ", "n v", " di", "n w", "ing", " op", "eer", "aan", "ijn", "zij", "ren", "n o", "ken", "el ", "ng ", "die", "ond", "op ", " al", " ha", "jn ", "or ", "ter", "ie ", "ste", " zo", "e v", "ijk", "nge", "lij", "n z", " ze", " na", "dat", "n t", "ere", "men", " hi", "n g", "is ", "ze ", "and", "voo", "ers", " st", "nd ", " aa", "r d", " ma", " to", " er", "rde", "iet", "len", "t d", " do", "e b", "n b", "nie", " wi", "end", "ns ", "ach", "met", "hij", "t h", " ho", "ls ", "al ", "erd", "n s", " is", "ich", "lle", " ni", " mo", "as ", "ele", "n m", "n a", "e h", "eli", "uit", "maa", "als", "e d", "e o", "waa", "ige", "t e", "wij", "che", "ik ", "om ", " om", "n k", "t v", "e s", "ig ", "was", "e w", "ven", " la", "n i", "gel", "eel", "e m", "ht ", "ove", "we ", "wee", "st ", "est", "ege", " bi", "ge ", "ch ", "ier", " ko", "e k", "e z", "eid", "nen", "it ", "n n", "ang", "naa", "ede", "ord", "r h", "doo", "e g", "bij", " ik", "hee", "e e", "lan", "oet", "jk ", "eve", "ien", "haa", " wo", "ens", "r e", "moe", "rij", " oo", " sp", " ui", "of ", " gr", "ons", "t o", "zoo", "hte", "t z", "t w", "pen", "t g", "eld", "sta", " no", "s e", "aat", "kke", " bo", " ka", "toe", "nne", " ov", " mi", "r o", "zic", "es ", "mee", "e l", "oot", "voe", "t i", "n l", "oen", " li", "all", "had", "ts ", "ete", " of", " sc", "r v", "laa", "rs ", "roo", "ind", "ad ", "are", "e t", "s d", "og ", "r w", "dan", "e p", "tig", "n p", "erk", "ome", "ot ", " re", "s v", "wor", " za", "gro", "nt ", "e a"} 34 | --------------------------------------------------------------------------------