// Unicode 15.0.0 default case folding for Markdown reference identifiers.
// Generated by scripts/generate_unicode_casefold.py; Unicode License V3.

///|
let document_unicode_casefold_ranges : Array[(Int, Int, Int, Int)] = [
  (0x41, 0x5A, 1, 32),
  (0xB5, 0xB5, 1, 775),
  (0xC0, 0xD6, 1, 32),
  (0xD8, 0xDE, 1, 32),
  (0x100, 0x12E, 2, 1),
  (0x132, 0x136, 2, 1),
  (0x139, 0x147, 2, 1),
  (0x14A, 0x176, 2, 1),
  (0x178, 0x178, 1, -121),
  (0x179, 0x17D, 2, 1),
  (0x17F, 0x17F, 1, -268),
  (0x181, 0x181, 1, 210),
  (0x182, 0x184, 2, 1),
  (0x186, 0x186, 1, 206),
  (0x187, 0x187, 1, 1),
  (0x189, 0x18A, 1, 205),
  (0x18B, 0x18B, 1, 1),
  (0x18E, 0x18E, 1, 79),
  (0x18F, 0x18F, 1, 202),
  (0x190, 0x190, 1, 203),
  (0x191, 0x191, 1, 1),
  (0x193, 0x193, 1, 205),
  (0x194, 0x194, 1, 207),
  (0x196, 0x196, 1, 211),
  (0x197, 0x197, 1, 209),
  (0x198, 0x198, 1, 1),
  (0x19C, 0x19C, 1, 211),
  (0x19D, 0x19D, 1, 213),
  (0x19F, 0x19F, 1, 214),
  (0x1A0, 0x1A4, 2, 1),
  (0x1A6, 0x1A6, 1, 218),
  (0x1A7, 0x1A7, 1, 1),
  (0x1A9, 0x1A9, 1, 218),
  (0x1AC, 0x1AC, 1, 1),
  (0x1AE, 0x1AE, 1, 218),
  (0x1AF, 0x1AF, 1, 1),
  (0x1B1, 0x1B2, 1, 217),
  (0x1B3, 0x1B5, 2, 1),
  (0x1B7, 0x1B7, 1, 219),
  (0x1B8, 0x1B8, 1, 1),
  (0x1BC, 0x1BC, 1, 1),
  (0x1C4, 0x1C4, 1, 2),
  (0x1C5, 0x1C5, 1, 1),
  (0x1C7, 0x1C7, 1, 2),
  (0x1C8, 0x1C8, 1, 1),
  (0x1CA, 0x1CA, 1, 2),
  (0x1CB, 0x1DB, 2, 1),
  (0x1DE, 0x1EE, 2, 1),
  (0x1F1, 0x1F1, 1, 2),
  (0x1F2, 0x1F4, 2, 1),
  (0x1F6, 0x1F6, 1, -97),
  (0x1F7, 0x1F7, 1, -56),
  (0x1F8, 0x21E, 2, 1),
  (0x220, 0x220, 1, -130),
  (0x222, 0x232, 2, 1),
  (0x23A, 0x23A, 1, 10795),
  (0x23B, 0x23B, 1, 1),
  (0x23D, 0x23D, 1, -163),
  (0x23E, 0x23E, 1, 10792),
  (0x241, 0x241, 1, 1),
  (0x243, 0x243, 1, -195),
  (0x244, 0x244, 1, 69),
  (0x245, 0x245, 1, 71),
  (0x246, 0x24E, 2, 1),
  (0x345, 0x345, 1, 116),
  (0x370, 0x372, 2, 1),
  (0x376, 0x376, 1, 1),
  (0x37F, 0x37F, 1, 116),
  (0x386, 0x386, 1, 38),
  (0x388, 0x38A, 1, 37),
  (0x38C, 0x38C, 1, 64),
  (0x38E, 0x38F, 1, 63),
  (0x391, 0x3A1, 1, 32),
  (0x3A3, 0x3AB, 1, 32),
  (0x3C2, 0x3C2, 1, 1),
  (0x3CF, 0x3CF, 1, 8),
  (0x3D0, 0x3D0, 1, -30),
  (0x3D1, 0x3D1, 1, -25),
  (0x3D5, 0x3D5, 1, -15),
  (0x3D6, 0x3D6, 1, -22),
  (0x3D8, 0x3EE, 2, 1),
  (0x3F0, 0x3F0, 1, -54),
  (0x3F1, 0x3F1, 1, -48),
  (0x3F4, 0x3F4, 1, -60),
  (0x3F5, 0x3F5, 1, -64),
  (0x3F7, 0x3F7, 1, 1),
  (0x3F9, 0x3F9, 1, -7),
  (0x3FA, 0x3FA, 1, 1),
  (0x3FD, 0x3FF, 1, -130),
  (0x400, 0x40F, 1, 80),
  (0x410, 0x42F, 1, 32),
  (0x460, 0x480, 2, 1),
  (0x48A, 0x4BE, 2, 1),
  (0x4C0, 0x4C0, 1, 15),
  (0x4C1, 0x4CD, 2, 1),
  (0x4D0, 0x52E, 2, 1),
  (0x531, 0x556, 1, 48),
  (0x10A0, 0x10C5, 1, 7264),
  (0x10C7, 0x10C7, 1, 7264),
  (0x10CD, 0x10CD, 1, 7264),
  (0x13F8, 0x13FD, 1, -8),
  (0x1C80, 0x1C80, 1, -6222),
  (0x1C81, 0x1C81, 1, -6221),
  (0x1C82, 0x1C82, 1, -6212),
  (0x1C83, 0x1C84, 1, -6210),
  (0x1C85, 0x1C85, 1, -6211),
  (0x1C86, 0x1C86, 1, -6204),
  (0x1C87, 0x1C87, 1, -6180),
  (0x1C88, 0x1C88, 1, 35267),
  (0x1C90, 0x1CBA, 1, -3008),
  (0x1CBD, 0x1CBF, 1, -3008),
  (0x1E00, 0x1E94, 2, 1),
  (0x1E9B, 0x1E9B, 1, -58),
  (0x1EA0, 0x1EFE, 2, 1),
  (0x1F08, 0x1F0F, 1, -8),
  (0x1F18, 0x1F1D, 1, -8),
  (0x1F28, 0x1F2F, 1, -8),
  (0x1F38, 0x1F3F, 1, -8),
  (0x1F48, 0x1F4D, 1, -8),
  (0x1F59, 0x1F5F, 2, -8),
  (0x1F68, 0x1F6F, 1, -8),
  (0x1FB8, 0x1FB9, 1, -8),
  (0x1FBA, 0x1FBB, 1, -74),
  (0x1FBE, 0x1FBE, 1, -7173),
  (0x1FC8, 0x1FCB, 1, -86),
  (0x1FD8, 0x1FD9, 1, -8),
  (0x1FDA, 0x1FDB, 1, -100),
  (0x1FE8, 0x1FE9, 1, -8),
  (0x1FEA, 0x1FEB, 1, -112),
  (0x1FEC, 0x1FEC, 1, -7),
  (0x1FF8, 0x1FF9, 1, -128),
  (0x1FFA, 0x1FFB, 1, -126),
  (0x2126, 0x2126, 1, -7517),
  (0x212A, 0x212A, 1, -8383),
  (0x212B, 0x212B, 1, -8262),
  (0x2132, 0x2132, 1, 28),
  (0x2160, 0x216F, 1, 16),
  (0x2183, 0x2183, 1, 1),
  (0x24B6, 0x24CF, 1, 26),
  (0x2C00, 0x2C2F, 1, 48),
  (0x2C60, 0x2C60, 1, 1),
  (0x2C62, 0x2C62, 1, -10743),
  (0x2C63, 0x2C63, 1, -3814),
  (0x2C64, 0x2C64, 1, -10727),
  (0x2C67, 0x2C6B, 2, 1),
  (0x2C6D, 0x2C6D, 1, -10780),
  (0x2C6E, 0x2C6E, 1, -10749),
  (0x2C6F, 0x2C6F, 1, -10783),
  (0x2C70, 0x2C70, 1, -10782),
  (0x2C72, 0x2C72, 1, 1),
  (0x2C75, 0x2C75, 1, 1),
  (0x2C7E, 0x2C7F, 1, -10815),
  (0x2C80, 0x2CE2, 2, 1),
  (0x2CEB, 0x2CED, 2, 1),
  (0x2CF2, 0x2CF2, 1, 1),
  (0xA640, 0xA66C, 2, 1),
  (0xA680, 0xA69A, 2, 1),
  (0xA722, 0xA72E, 2, 1),
  (0xA732, 0xA76E, 2, 1),
  (0xA779, 0xA77B, 2, 1),
  (0xA77D, 0xA77D, 1, -35332),
  (0xA77E, 0xA786, 2, 1),
  (0xA78B, 0xA78B, 1, 1),
  (0xA78D, 0xA78D, 1, -42280),
  (0xA790, 0xA792, 2, 1),
  (0xA796, 0xA7A8, 2, 1),
  (0xA7AA, 0xA7AA, 1, -42308),
  (0xA7AB, 0xA7AB, 1, -42319),
  (0xA7AC, 0xA7AC, 1, -42315),
  (0xA7AD, 0xA7AD, 1, -42305),
  (0xA7AE, 0xA7AE, 1, -42308),
  (0xA7B0, 0xA7B0, 1, -42258),
  (0xA7B1, 0xA7B1, 1, -42282),
  (0xA7B2, 0xA7B2, 1, -42261),
  (0xA7B3, 0xA7B3, 1, 928),
  (0xA7B4, 0xA7C2, 2, 1),
  (0xA7C4, 0xA7C4, 1, -48),
  (0xA7C5, 0xA7C5, 1, -42307),
  (0xA7C6, 0xA7C6, 1, -35384),
  (0xA7C7, 0xA7C9, 2, 1),
  (0xA7D0, 0xA7D0, 1, 1),
  (0xA7D6, 0xA7D8, 2, 1),
  (0xA7F5, 0xA7F5, 1, 1),
  (0xAB70, 0xABBF, 1, -38864),
  (0xFF21, 0xFF3A, 1, 32),
  (0x10400, 0x10427, 1, 40),
  (0x104B0, 0x104D3, 1, 40),
  (0x10570, 0x1057A, 1, 39),
  (0x1057C, 0x1058A, 1, 39),
  (0x1058C, 0x10592, 1, 39),
  (0x10594, 0x10595, 1, 39),
  (0x10C80, 0x10CB2, 1, 64),
  (0x118A0, 0x118BF, 1, 32),
  (0x16E40, 0x16E5F, 1, 32),
  (0x1E900, 0x1E921, 1, 34),
]

///|
let document_unicode_casefold_expansions : Array[(Int, String)] = [
  (0xDF, "\u{73}\u{73}"),
  (0x130, "\u{69}\u{307}"),
  (0x149, "\u{2BC}\u{6E}"),
  (0x1F0, "\u{6A}\u{30C}"),
  (0x390, "\u{3B9}\u{308}\u{301}"),
  (0x3B0, "\u{3C5}\u{308}\u{301}"),
  (0x587, "\u{565}\u{582}"),
  (0x1E96, "\u{68}\u{331}"),
  (0x1E97, "\u{74}\u{308}"),
  (0x1E98, "\u{77}\u{30A}"),
  (0x1E99, "\u{79}\u{30A}"),
  (0x1E9A, "\u{61}\u{2BE}"),
  (0x1E9E, "\u{73}\u{73}"),
  (0x1F50, "\u{3C5}\u{313}"),
  (0x1F52, "\u{3C5}\u{313}\u{300}"),
  (0x1F54, "\u{3C5}\u{313}\u{301}"),
  (0x1F56, "\u{3C5}\u{313}\u{342}"),
  (0x1F80, "\u{1F00}\u{3B9}"),
  (0x1F81, "\u{1F01}\u{3B9}"),
  (0x1F82, "\u{1F02}\u{3B9}"),
  (0x1F83, "\u{1F03}\u{3B9}"),
  (0x1F84, "\u{1F04}\u{3B9}"),
  (0x1F85, "\u{1F05}\u{3B9}"),
  (0x1F86, "\u{1F06}\u{3B9}"),
  (0x1F87, "\u{1F07}\u{3B9}"),
  (0x1F88, "\u{1F00}\u{3B9}"),
  (0x1F89, "\u{1F01}\u{3B9}"),
  (0x1F8A, "\u{1F02}\u{3B9}"),
  (0x1F8B, "\u{1F03}\u{3B9}"),
  (0x1F8C, "\u{1F04}\u{3B9}"),
  (0x1F8D, "\u{1F05}\u{3B9}"),
  (0x1F8E, "\u{1F06}\u{3B9}"),
  (0x1F8F, "\u{1F07}\u{3B9}"),
  (0x1F90, "\u{1F20}\u{3B9}"),
  (0x1F91, "\u{1F21}\u{3B9}"),
  (0x1F92, "\u{1F22}\u{3B9}"),
  (0x1F93, "\u{1F23}\u{3B9}"),
  (0x1F94, "\u{1F24}\u{3B9}"),
  (0x1F95, "\u{1F25}\u{3B9}"),
  (0x1F96, "\u{1F26}\u{3B9}"),
  (0x1F97, "\u{1F27}\u{3B9}"),
  (0x1F98, "\u{1F20}\u{3B9}"),
  (0x1F99, "\u{1F21}\u{3B9}"),
  (0x1F9A, "\u{1F22}\u{3B9}"),
  (0x1F9B, "\u{1F23}\u{3B9}"),
  (0x1F9C, "\u{1F24}\u{3B9}"),
  (0x1F9D, "\u{1F25}\u{3B9}"),
  (0x1F9E, "\u{1F26}\u{3B9}"),
  (0x1F9F, "\u{1F27}\u{3B9}"),
  (0x1FA0, "\u{1F60}\u{3B9}"),
  (0x1FA1, "\u{1F61}\u{3B9}"),
  (0x1FA2, "\u{1F62}\u{3B9}"),
  (0x1FA3, "\u{1F63}\u{3B9}"),
  (0x1FA4, "\u{1F64}\u{3B9}"),
  (0x1FA5, "\u{1F65}\u{3B9}"),
  (0x1FA6, "\u{1F66}\u{3B9}"),
  (0x1FA7, "\u{1F67}\u{3B9}"),
  (0x1FA8, "\u{1F60}\u{3B9}"),
  (0x1FA9, "\u{1F61}\u{3B9}"),
  (0x1FAA, "\u{1F62}\u{3B9}"),
  (0x1FAB, "\u{1F63}\u{3B9}"),
  (0x1FAC, "\u{1F64}\u{3B9}"),
  (0x1FAD, "\u{1F65}\u{3B9}"),
  (0x1FAE, "\u{1F66}\u{3B9}"),
  (0x1FAF, "\u{1F67}\u{3B9}"),
  (0x1FB2, "\u{1F70}\u{3B9}"),
  (0x1FB3, "\u{3B1}\u{3B9}"),
  (0x1FB4, "\u{3AC}\u{3B9}"),
  (0x1FB6, "\u{3B1}\u{342}"),
  (0x1FB7, "\u{3B1}\u{342}\u{3B9}"),
  (0x1FBC, "\u{3B1}\u{3B9}"),
  (0x1FC2, "\u{1F74}\u{3B9}"),
  (0x1FC3, "\u{3B7}\u{3B9}"),
  (0x1FC4, "\u{3AE}\u{3B9}"),
  (0x1FC6, "\u{3B7}\u{342}"),
  (0x1FC7, "\u{3B7}\u{342}\u{3B9}"),
  (0x1FCC, "\u{3B7}\u{3B9}"),
  (0x1FD2, "\u{3B9}\u{308}\u{300}"),
  (0x1FD3, "\u{3B9}\u{308}\u{301}"),
  (0x1FD6, "\u{3B9}\u{342}"),
  (0x1FD7, "\u{3B9}\u{308}\u{342}"),
  (0x1FE2, "\u{3C5}\u{308}\u{300}"),
  (0x1FE3, "\u{3C5}\u{308}\u{301}"),
  (0x1FE4, "\u{3C1}\u{313}"),
  (0x1FE6, "\u{3C5}\u{342}"),
  (0x1FE7, "\u{3C5}\u{308}\u{342}"),
  (0x1FF2, "\u{1F7C}\u{3B9}"),
  (0x1FF3, "\u{3C9}\u{3B9}"),
  (0x1FF4, "\u{3CE}\u{3B9}"),
  (0x1FF6, "\u{3C9}\u{342}"),
  (0x1FF7, "\u{3C9}\u{342}\u{3B9}"),
  (0x1FFC, "\u{3C9}\u{3B9}"),
  (0xFB00, "\u{66}\u{66}"),
  (0xFB01, "\u{66}\u{69}"),
  (0xFB02, "\u{66}\u{6C}"),
  (0xFB03, "\u{66}\u{66}\u{69}"),
  (0xFB04, "\u{66}\u{66}\u{6C}"),
  (0xFB05, "\u{73}\u{74}"),
  (0xFB06, "\u{73}\u{74}"),
  (0xFB13, "\u{574}\u{576}"),
  (0xFB14, "\u{574}\u{565}"),
  (0xFB15, "\u{574}\u{56B}"),
  (0xFB16, "\u{57E}\u{576}"),
  (0xFB17, "\u{574}\u{56D}"),
]

///|
fn document_unicode_casefold(text : String) -> String {
  let output = StringBuilder()
  for ch in text.iter() {
    let code = ch.to_int()
    let mut low = 0
    let mut high = document_unicode_casefold_expansions.length()
    let mut expanded = false
    while low < high {
      let middle = (low + high) / 2
      let (point, value) = document_unicode_casefold_expansions[middle]
      if code < point {
        high = middle
      } else if code > point {
        low = middle + 1
      } else {
        output.write_string(value)
        expanded = true
        break
      }
    }
    if expanded {
      continue
    }
    low = 0
    high = document_unicode_casefold_ranges.length()
    let mut lowered = ch
    while low < high {
      let middle = (low + high) / 2
      let (start, end, step, delta) = document_unicode_casefold_ranges[middle]
      if code < start {
        high = middle
      } else if code > end {
        low = middle + 1
      } else {
        if (code - start) % step == 0 {
          lowered = (code + delta).to_char().unwrap()
        }
        break
      }
    }
    output.write_char(lowered)
  }
  output.to_string()
}