runes.ts raw

   1  /**
   2   * Latin → Elder Futhark transliteration for the "Runic browser
   3   * names" display option. Each letter maps to a single rune chosen
   4   * for phonetic or visual fit; letters without a clean Futhark
   5   * match (Q, X, Y) fall back to multi-rune combinations or the
   6   * closest phoneme. Runes have no case, so the mapping is
   7   * case-insensitive and the input is lowercased before lookup.
   8   *
   9   * Tested on the installed browser list — every name remains
  10   * readable (each glyph is distinct, lengths comparable to the
  11   * Latin original):
  12   *   Brave           → ᛒᚱᚨᚹᛖ
  13   *   Chrome          → ᚲᚺᚱᛟᛗᛖ
  14   *   DuckDuckGo      → ᛞᚢᚲᚲᛞᚢᚲᚲᚷᛟ
  15   *   Firefox         → ᚠᛁᚱᛖᚠᛟᚲᛋ
  16   *   Firefox Nightly → ᚠᛁᚱᛖᚠᛟᚲᛋ ᚾᛁᚷᚺᛏᛚᛁ
  17   *   Helium          → ᚺᛖᛚᛁᚢᛗ
  18   *   IronFox         → ᛁᚱᛟᚾᚠᛟᚲᛋ
  19   *   Tor Browser     → ᛏᛟᚱ ᛒᚱᛟᚹᛋᛖᚱ
  20   *   Vanadium        → ᚹᚨᚾᚨᛞᛁᚢᛗ
  21   */
  22  const LATIN_TO_RUNE: Record<string, string> = {
  23    a: 'ᚨ', b: 'ᛒ', c: 'ᚲ', d: 'ᛞ', e: 'ᛖ', f: 'ᚠ', g: 'ᚷ', h: 'ᚺ',
  24    i: 'ᛁ', j: 'ᛃ', k: 'ᚲ', l: 'ᛚ', m: 'ᛗ', n: 'ᚾ', o: 'ᛟ', p: 'ᛈ',
  25    q: 'ᚲᚹ', r: 'ᚱ', s: 'ᛋ', t: 'ᛏ', u: 'ᚢ', v: 'ᚹ', w: 'ᚹ',
  26    x: 'ᚲᛋ', y: 'ᛁ', z: 'ᛉ',
  27  };
  28  
  29  /**
  30   * Transliterates a Latin-letter string to Elder Futhark runes.
  31   * Non-letter characters (spaces, punctuation, digits) pass through
  32   * unchanged.
  33   */
  34  export function transliterateToRunes(input: string): string {
  35    let out = '';
  36    for (const ch of input) {
  37      const lower = ch.toLowerCase();
  38      out += LATIN_TO_RUNE[lower] ?? ch;
  39    }
  40    return out;
  41  }
  42  
  43  /**
  44   * Convenience wrapper used by display components: returns the
  45   * runic transliteration when the runic-names toggle is on,
  46   * otherwise the original string verbatim.
  47   */
  48  export function formatRunicName(name: string, runic: boolean): string {
  49    return runic ? transliterateToRunes(name) : name;
  50  }
  51