This app provides monitoring and information features for the common freifunk user and the technical stuff of a freifunk community.
Code base is taken from a TUM Practical Course project and added here to see if Freifunk Altdorf can use it.
https://www.freifunk-altdorf.de
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
173 lines
4.4 KiB
173 lines
4.4 KiB
/** |
|
* Copyright (c) 2013-present, Facebook, Inc. |
|
* |
|
* This source code is licensed under the MIT license found in the |
|
* LICENSE file in the root directory of this source tree. |
|
* |
|
* @providesModule UnicodeCJK |
|
* @typechecks |
|
*/ |
|
|
|
/** |
|
* Unicode algorithms for CJK (Chinese, Japanese, Korean) writing systems. |
|
* |
|
* Utilities for Hanzi/Kanji/Hanja logographs and Kanas (Katakana and Hiragana) |
|
* syllables. |
|
* |
|
* For Korean Hangul see module `UnicodeHangulKorean`. |
|
*/ |
|
|
|
'use strict'; |
|
|
|
/** |
|
* Latin |
|
* |
|
* NOTE: The code assumes these sets include only BMP characters. |
|
*/ |
|
|
|
const R_LATIN_ASCII = 'a-zA-Z'; |
|
const R_LATIN_FULLWIDTH = '\uFF21-\uFF3A\uFF41-\uFF5A'; |
|
const R_LATIN = R_LATIN_ASCII + R_LATIN_FULLWIDTH; |
|
|
|
/** |
|
* Hiragana & Katakana |
|
* |
|
* NOTE: Some ranges include non-BMP characters. We do not support those ranges |
|
* for now. |
|
*/ |
|
const R_HIRAGANA = '\u3040-\u309F'; |
|
const R_KATAKANA = '\u30A0-\u30FF'; |
|
const R_KATAKANA_PHONETIC = '\u31F0-\u31FF'; |
|
const R_KATAKANA_HALFWIDTH = '\uFF65-\uFF9F'; |
|
// var R_KANA_SUPPLEMENT = '\U0001B000-\U0001B0FF'; |
|
const R_KATAKANA_ALL = R_KATAKANA + R_KATAKANA_PHONETIC + R_KATAKANA_HALFWIDTH; |
|
const R_KANA = R_HIRAGANA + R_KATAKANA_ALL; |
|
|
|
const I_HIRAGANA = [0x3040, 0x309F]; |
|
const I_KATAKANA = [0x30A0, 0x30FF]; |
|
const I_HIRAGANA_TO_KATAKANA = I_KATAKANA[0] - I_HIRAGANA[0]; |
|
|
|
/** |
|
* Hanzi/Kanji/Hanja |
|
* |
|
* NOTE: Some ranges include non-BMP characters. We do not support those ranges |
|
* for now. |
|
*/ |
|
const R_IDEO_MAIN = '\u4E00-\u9FCF'; |
|
const R_IDEO_EXT_A = '\u3400-\u4DBF'; |
|
// var R_IDEO_EXT_B = '\U00020000-\U0002A6DF'; |
|
// var R_IDEO_EXT_C = '\U0002A700-\U0002B73F'; |
|
// var R_IDEO_EXT_D = '\U0002B740-\U0002B81F'; |
|
const R_IDEO = R_IDEO_MAIN + R_IDEO_EXT_A; |
|
|
|
/** |
|
* Hangul |
|
*/ |
|
// var R_HANGUL_JAMO = '\u1100-\u11FF'; |
|
// var R_HANGUL_JAMO_EXT_A = '\uA960-\uA97F'; |
|
// var R_HANGUL_JAMO_EXT_B = '\uD7B0-\uD7FF'; |
|
// var R_HANGUL_COMPATIBILITY = '\u3130-\u318F'; |
|
// var R_HANGUL_COMP_HALFWIDTH = '\uFFA0-\uFFDF'; |
|
const R_HANGUL_SYLLABLES = '\uAC00-\uD7AF'; |
|
|
|
/** |
|
* Globals |
|
*/ |
|
const R_IDEO_OR_SYLL = R_IDEO + R_KANA + R_HANGUL_SYLLABLES; |
|
|
|
let REGEX_IDEO = null; |
|
let REGEX_KANA = null; |
|
let REGEX_IDEO_OR_SYLL = null; |
|
let REGEX_IS_KANA_WITH_TRAILING_LATIN = null; |
|
|
|
/** |
|
* Whether the string includes any Katakana or Hiragana characters. |
|
* |
|
* @param {string} str |
|
* @return {boolean} |
|
*/ |
|
function hasKana(str) { |
|
REGEX_KANA = REGEX_KANA || new RegExp('[' + R_KANA + ']'); |
|
return REGEX_KANA.test(str); |
|
} |
|
|
|
/** |
|
* Whether the string includes any CJK Ideograph characters. |
|
* |
|
* @param {string} str |
|
* @return {boolean} |
|
*/ |
|
function hasIdeograph(str) { |
|
REGEX_IDEO = REGEX_IDEO || new RegExp('[' + R_IDEO + ']'); |
|
return REGEX_IDEO.test(str); |
|
} |
|
|
|
/** |
|
* Whether the string includes any CJK Ideograph or Syllable characters. |
|
* |
|
* @param {string} str |
|
* @return {boolean} |
|
*/ |
|
function hasIdeoOrSyll(str) { |
|
REGEX_IDEO_OR_SYLL = REGEX_IDEO_OR_SYLL || new RegExp('[' + R_IDEO_OR_SYLL + ']'); |
|
return REGEX_IDEO_OR_SYLL.test(str); |
|
} |
|
|
|
/** |
|
* @param {string} chr |
|
* @output {string} |
|
*/ |
|
function charCodeToKatakana(chr) { |
|
const charCode = chr.charCodeAt(0); |
|
return String.fromCharCode(charCode < I_HIRAGANA[0] || charCode > I_HIRAGANA[1] ? charCode : charCode + I_HIRAGANA_TO_KATAKANA); |
|
} |
|
|
|
/** |
|
* Replace any Hiragana character with the matching Katakana |
|
* |
|
* @param {string} str |
|
* @output {string} |
|
*/ |
|
function hiraganaToKatakana(str) { |
|
if (!hasKana(str)) { |
|
return str; |
|
} |
|
return str.split('').map(charCodeToKatakana).join(''); |
|
} |
|
|
|
/** |
|
* Whether the string is exactly a sequence of Kana characters followed by one |
|
* Latin character. |
|
* |
|
* @param {string} str |
|
* @output {string} |
|
*/ |
|
function isKanaWithTrailingLatin(str) { |
|
REGEX_IS_KANA_WITH_TRAILING_LATIN = REGEX_IS_KANA_WITH_TRAILING_LATIN || new RegExp('^' + '[' + R_KANA + ']+' + '[' + R_LATIN + ']' + '$'); |
|
return REGEX_IS_KANA_WITH_TRAILING_LATIN.test(str); |
|
} |
|
|
|
/** |
|
* Drops the trailing Latin character from a string that is exactly a sequence |
|
* of Kana characters followed by one Latin character. |
|
* |
|
* @param {string} str |
|
* @output {string} |
|
*/ |
|
function kanaRemoveTrailingLatin(str) { |
|
if (isKanaWithTrailingLatin(str)) { |
|
return str.substr(0, str.length - 1); |
|
} |
|
return str; |
|
} |
|
|
|
const UnicodeCJK = { |
|
hasKana: hasKana, |
|
hasIdeograph: hasIdeograph, |
|
hasIdeoOrSyll: hasIdeoOrSyll, |
|
hiraganaToKatakana: hiraganaToKatakana, |
|
isKanaWithTrailingLatin: isKanaWithTrailingLatin, |
|
kanaRemoveTrailingLatin: kanaRemoveTrailingLatin |
|
}; |
|
|
|
module.exports = UnicodeCJK; |