Suite of AT Protocol TypeScript libraries built on web standards
1export function utf8Len(str: string): number {
2 return new TextEncoder().encode(str).byteLength;
3}
4
5export function graphemeLen(str: string): number {
6 if (typeof Intl !== "undefined" && "Segmenter" in Intl) {
7 const segmenter = new Intl.Segmenter(undefined, {
8 granularity: "grapheme",
9 });
10 return Array.from(segmenter.segment(str)).length;
11 }
12 return Array.from(str).length;
13}
14
15const bcp47Regexp =
16 /^((?<grandfathered>(en-GB-oed|i-ami|i-bnn|i-default|i-enochian|i-hak|i-klingon|i-lux|i-mingo|i-navajo|i-pwn|i-tao|i-tay|i-tsu|sgn-BE-FR|sgn-BE-NL|sgn-CH-DE)|(art-lojban|cel-gaulish|no-bok|no-nyn|zh-guoyu|zh-hakka|zh-min|zh-min-nan|zh-xiang))|((?<language>([A-Za-z]{2,3}(-(?<extlang>[A-Za-z]{3}(-[A-Za-z]{3}){0,2}))?)|[A-Za-z]{4}|[A-Za-z]{5,8})(-(?<script>[A-Za-z]{4}))?(-(?<region>[A-Za-z]{2}|[0-9]{3}))?(-(?<variant>[A-Za-z0-9]{5,8}|[0-9][A-Za-z0-9]{3}))*(-(?<extension>[0-9A-WY-Za-wy-z](-[A-Za-z0-9]{2,8})+))*(-(?<privateUseA>x(-[A-Za-z0-9]{1,8})+))?)|(?<privateUseB>x(-[A-Za-z0-9]{1,8})+))$/;
17
18export function isLanguage(input: string): boolean {
19 return bcp47Regexp.test(input);
20}