translit.ts raw
1 // Shared search normalization: transliterate cyrillic to latin, lowercase,
2 // drop latin y so "Sofia" matches "София" and vice versa. Used by both the
3 // client-side city selector and the server-side office filter.
4
5 export function toSearch(s: string): string {
6 return s
7 .toLowerCase()
8 .replace(/щ/g, 'sht')
9 .replace(/ш/g, 'sh')
10 .replace(/ч/g, 'ch')
11 .replace(/ж/g, 'zh')
12 .replace(/ц/g, 'ts')
13 .replace(/ю/g, 'yu')
14 .replace(/я/g, 'ya')
15 .replace(/ъ/g, 'a')
16 .replace(/ь/g, 'y')
17 .replace(/й/g, 'i')
18 .replace(/а/g, 'a')
19 .replace(/б/g, 'b')
20 .replace(/в/g, 'v')
21 .replace(/г/g, 'g')
22 .replace(/д/g, 'd')
23 .replace(/е/g, 'e')
24 .replace(/з/g, 'z')
25 .replace(/и/g, 'i')
26 .replace(/к/g, 'k')
27 .replace(/л/g, 'l')
28 .replace(/м/g, 'm')
29 .replace(/н/g, 'n')
30 .replace(/о/g, 'o')
31 .replace(/п/g, 'p')
32 .replace(/р/g, 'r')
33 .replace(/с/g, 's')
34 .replace(/т/g, 't')
35 .replace(/у/g, 'u')
36 .replace(/ф/g, 'f')
37 .replace(/х/g, 'h')
38 .replace(/y/g, '')
39 .replace(/[^a-z0-9 ]/g, ' ')
40 .replace(/\s+/g, ' ')
41 .trim();
42 }
43