_ZN3ada4idna13utf8_to_utf32EPKcmPDi:
  151|  13.4k|size_t utf8_to_utf32(const char* buf, size_t len, char32_t* utf32_output) {
  152|  13.4k|  const uint8_t* data = reinterpret_cast<const uint8_t*>(buf);
  153|  13.4k|  size_t pos = 0;
  154|  13.4k|  const char32_t* start{utf32_output};
  155|   174k|  while (pos < len) {
  ------------------
  |  Branch (155:10): [True: 161k, False: 12.7k]
  ------------------
  156|       |    // try to convert the next block of 16 ASCII bytes
  157|   161k|    if (pos + 16 <= len) {  // if it is safe to read 16 more
  ------------------
  |  Branch (157:9): [True: 87.5k, False: 74.3k]
  ------------------
  158|       |                            // bytes, check that they are ascii
  159|  87.5k|      uint64_t v1;
  160|  87.5k|      std::memcpy(&v1, data + pos, sizeof(uint64_t));
  161|  87.5k|      uint64_t v2;
  162|  87.5k|      std::memcpy(&v2, data + pos + sizeof(uint64_t), sizeof(uint64_t));
  163|  87.5k|      uint64_t v{v1 | v2};
  164|  87.5k|      if ((v & 0x8080808080808080) == 0) {
  ------------------
  |  Branch (164:11): [True: 10.1k, False: 77.3k]
  ------------------
  165|  10.1k|        size_t final_pos = pos + 16;
  166|   172k|        while (pos < final_pos) {
  ------------------
  |  Branch (166:16): [True: 162k, False: 10.1k]
  ------------------
  167|   162k|          *utf32_output++ = char32_t(buf[pos]);
  168|   162k|          pos++;
  169|   162k|        }
  170|  10.1k|        continue;
  171|  10.1k|      }
  172|  87.5k|    }
  173|   151k|    uint8_t leading_byte = data[pos];  // leading byte
  174|   151k|    if (leading_byte < 0b10000000) {
  ------------------
  |  Branch (174:9): [True: 82.8k, False: 68.8k]
  ------------------
  175|       |      // converting one ASCII byte !!!
  176|  82.8k|      *utf32_output++ = char32_t(leading_byte);
  177|  82.8k|      pos++;
  178|  82.8k|    } else if ((leading_byte & 0b11100000) == 0b11000000) {
  ------------------
  |  Branch (178:16): [True: 14.5k, False: 54.3k]
  ------------------
  179|       |      // We have a two-byte UTF-8
  180|  14.5k|      if (pos + 1 >= len) {
  ------------------
  |  Branch (180:11): [True: 56, False: 14.4k]
  ------------------
  181|     56|        return 0;
  182|     56|      }  // minimal bound checking
  183|  14.4k|      if ((data[pos + 1] & 0b11000000) != 0b10000000) {
  ------------------
  |  Branch (183:11): [True: 69, False: 14.4k]
  ------------------
  184|     69|        return 0;
  185|     69|      }
  186|       |      // range check
  187|  14.4k|      uint32_t code_point =
  188|  14.4k|          (leading_byte & 0b00011111) << 6 | (data[pos + 1] & 0b00111111);
  189|  14.4k|      if (code_point < 0x80 || 0x7ff < code_point) {
  ------------------
  |  Branch (189:11): [True: 12, False: 14.4k]
  |  Branch (189:32): [True: 0, False: 14.4k]
  ------------------
  190|     12|        return 0;
  191|     12|      }
  192|  14.4k|      *utf32_output++ = char32_t(code_point);
  193|  14.4k|      pos += 2;
  194|  54.3k|    } else if ((leading_byte & 0b11110000) == 0b11100000) {
  ------------------
  |  Branch (194:16): [True: 52.2k, False: 2.04k]
  ------------------
  195|       |      // We have a three-byte UTF-8
  196|  52.2k|      if (pos + 2 >= len) {
  ------------------
  |  Branch (196:11): [True: 24, False: 52.2k]
  ------------------
  197|     24|        return 0;
  198|     24|      }  // minimal bound checking
  199|       |
  200|  52.2k|      if ((data[pos + 1] & 0b11000000) != 0b10000000) {
  ------------------
  |  Branch (200:11): [True: 20, False: 52.2k]
  ------------------
  201|     20|        return 0;
  202|     20|      }
  203|  52.2k|      if ((data[pos + 2] & 0b11000000) != 0b10000000) {
  ------------------
  |  Branch (203:11): [True: 21, False: 52.2k]
  ------------------
  204|     21|        return 0;
  205|     21|      }
  206|       |      // range check
  207|  52.2k|      uint32_t code_point = (leading_byte & 0b00001111) << 12 |
  208|  52.2k|                            (data[pos + 1] & 0b00111111) << 6 |
  209|  52.2k|                            (data[pos + 2] & 0b00111111);
  210|  52.2k|      if (code_point < 0x800 || 0xffff < code_point ||
  ------------------
  |  Branch (210:11): [True: 24, False: 52.1k]
  |  Branch (210:33): [True: 0, False: 52.1k]
  ------------------
  211|  52.1k|          (0xd7ff < code_point && code_point < 0xe000)) {
  ------------------
  |  Branch (211:12): [True: 21.0k, False: 31.1k]
  |  Branch (211:35): [True: 8, False: 21.0k]
  ------------------
  212|     32|        return 0;
  213|     32|      }
  214|  52.1k|      *utf32_output++ = char32_t(code_point);
  215|  52.1k|      pos += 3;
  216|  52.1k|    } else if ((leading_byte & 0b11111000) == 0b11110000) {  // 0b11110000
  ------------------
  |  Branch (216:16): [True: 1.76k, False: 278]
  ------------------
  217|       |      // we have a 4-byte UTF-8 word.
  218|  1.76k|      if (pos + 3 >= len) {
  ------------------
  |  Branch (218:11): [True: 28, False: 1.73k]
  ------------------
  219|     28|        return 0;
  220|     28|      }  // minimal bound checking
  221|  1.73k|      if ((data[pos + 1] & 0b11000000) != 0b10000000) {
  ------------------
  |  Branch (221:11): [True: 41, False: 1.69k]
  ------------------
  222|     41|        return 0;
  223|     41|      }
  224|  1.69k|      if ((data[pos + 2] & 0b11000000) != 0b10000000) {
  ------------------
  |  Branch (224:11): [True: 12, False: 1.68k]
  ------------------
  225|     12|        return 0;
  226|     12|      }
  227|  1.68k|      if ((data[pos + 3] & 0b11000000) != 0b10000000) {
  ------------------
  |  Branch (227:11): [True: 16, False: 1.66k]
  ------------------
  228|     16|        return 0;
  229|     16|      }
  230|       |
  231|       |      // range check
  232|  1.66k|      uint32_t code_point = (leading_byte & 0b00000111) << 18 |
  233|  1.66k|                            (data[pos + 1] & 0b00111111) << 12 |
  234|  1.66k|                            (data[pos + 2] & 0b00111111) << 6 |
  235|  1.66k|                            (data[pos + 3] & 0b00111111);
  236|  1.66k|      if (code_point <= 0xffff || 0x10ffff < code_point) {
  ------------------
  |  Branch (236:11): [True: 20, False: 1.64k]
  |  Branch (236:35): [True: 20, False: 1.62k]
  ------------------
  237|     40|        return 0;
  238|     40|      }
  239|  1.62k|      *utf32_output++ = char32_t(code_point);
  240|  1.62k|      pos += 4;
  241|  1.62k|    } else {
  242|    278|      return 0;
  243|    278|    }
  244|   151k|  }
  245|  12.7k|  return utf32_output - start;
  246|  13.4k|}
_ZN3ada4idna22utf8_length_from_utf32EPKDim:
  248|  9.16k|size_t utf8_length_from_utf32(const char32_t* buf, size_t len) {
  249|       |  // We are not BOM aware.
  250|  9.16k|  const uint32_t* p = reinterpret_cast<const uint32_t*>(buf);
  251|  9.16k|  size_t counter{0};
  252|   176k|  for (size_t i = 0; i != len; ++i) {
  ------------------
  |  Branch (252:22): [True: 167k, False: 9.16k]
  ------------------
  253|   167k|    ++counter;                                      // ASCII
  254|   167k|    counter += static_cast<size_t>(p[i] > 0x7F);    // two-byte
  255|   167k|    counter += static_cast<size_t>(p[i] > 0x7FF);   // three-byte
  256|   167k|    counter += static_cast<size_t>(p[i] > 0xFFFF);  // four-bytes
  257|   167k|  }
  258|  9.16k|  return counter;
  259|  9.16k|}
_ZN3ada4idna22utf32_length_from_utf8EPKcm:
  261|  13.5k|size_t utf32_length_from_utf8(const char* buf, size_t len) {
  262|  13.5k|  const int8_t* p = reinterpret_cast<const int8_t*>(buf);
  263|  13.5k|  return std::count_if(p, std::next(p, len), [](int8_t c) {
  264|       |    // -65 is 0b10111111, anything larger in two-complement's
  265|       |    // should start a new code point.
  266|  13.5k|    return c > -65;
  267|  13.5k|  });
  268|  13.5k|}
_ZN3ada4idna13utf32_to_utf8EPKDimPc:
  270|  9.16k|size_t utf32_to_utf8(const char32_t* buf, size_t len, char* utf8_output) {
  271|  9.16k|  const uint32_t* data = reinterpret_cast<const uint32_t*>(buf);
  272|  9.16k|  size_t pos = 0;
  273|  9.16k|  const char* start{utf8_output};
  274|   140k|  while (pos < len) {
  ------------------
  |  Branch (274:10): [True: 130k, False: 9.16k]
  ------------------
  275|       |    // try to convert the next block of 2 ASCII characters
  276|   130k|    if (pos + 2 <= len) {  // if it is safe to read 8 more
  ------------------
  |  Branch (276:9): [True: 122k, False: 8.25k]
  ------------------
  277|       |                           // bytes, check that they are ascii
  278|   122k|      uint64_t v;
  279|   122k|      std::memcpy(&v, data + pos, sizeof(uint64_t));
  280|   122k|      if ((v & 0xFFFFFF80FFFFFF80) == 0) {
  ------------------
  |  Branch (280:11): [True: 36.0k, False: 86.6k]
  ------------------
  281|  36.0k|        *utf8_output++ = char(buf[pos]);
  282|  36.0k|        *utf8_output++ = char(buf[pos + 1]);
  283|  36.0k|        pos += 2;
  284|  36.0k|        continue;
  285|  36.0k|      }
  286|   122k|    }
  287|  94.9k|    uint32_t word = data[pos];
  288|  94.9k|    if ((word & 0xFFFFFF80) == 0) {
  ------------------
  |  Branch (288:9): [True: 13.3k, False: 81.6k]
  ------------------
  289|       |      // will generate one UTF-8 bytes
  290|  13.3k|      *utf8_output++ = char(word);
  291|  13.3k|      pos++;
  292|  81.6k|    } else if ((word & 0xFFFFF800) == 0) {
  ------------------
  |  Branch (292:16): [True: 50.3k, False: 31.3k]
  ------------------
  293|       |      // will generate two UTF-8 bytes
  294|       |      // we have 0b110XXXXX 0b10XXXXXX
  295|  50.3k|      *utf8_output++ = char((word >> 6) | 0b11000000);
  296|  50.3k|      *utf8_output++ = char((word & 0b111111) | 0b10000000);
  297|  50.3k|      pos++;
  298|  50.3k|    } else if ((word & 0xFFFF0000) == 0) {
  ------------------
  |  Branch (298:16): [True: 27.4k, False: 3.84k]
  ------------------
  299|       |      // will generate three UTF-8 bytes
  300|       |      // we have 0b1110XXXX 0b10XXXXXX 0b10XXXXXX
  301|  27.4k|      if (word >= 0xD800 && word <= 0xDFFF) {
  ------------------
  |  Branch (301:11): [True: 5.24k, False: 22.2k]
  |  Branch (301:29): [True: 0, False: 5.24k]
  ------------------
  302|      0|        return 0;
  303|      0|      }
  304|  27.4k|      *utf8_output++ = char((word >> 12) | 0b11100000);
  305|  27.4k|      *utf8_output++ = char(((word >> 6) & 0b111111) | 0b10000000);
  306|  27.4k|      *utf8_output++ = char((word & 0b111111) | 0b10000000);
  307|  27.4k|      pos++;
  308|  27.4k|    } else {
  309|       |      // will generate four UTF-8 bytes
  310|       |      // we have 0b11110XXX 0b10XXXXXX 0b10XXXXXX
  311|       |      // 0b10XXXXXX
  312|  3.84k|      if (word > 0x10FFFF) {
  ------------------
  |  Branch (312:11): [True: 0, False: 3.84k]
  ------------------
  313|      0|        return 0;
  314|      0|      }
  315|  3.84k|      *utf8_output++ = char((word >> 18) | 0b11110000);
  316|  3.84k|      *utf8_output++ = char(((word >> 12) & 0b111111) | 0b10000000);
  317|  3.84k|      *utf8_output++ = char(((word >> 6) & 0b111111) | 0b10000000);
  318|  3.84k|      *utf8_output++ = char((word & 0b111111) | 0b10000000);
  319|  3.84k|      pos++;
  320|  3.84k|    }
  321|  94.9k|  }
  322|  9.16k|  return utf8_output - start;
  323|  9.16k|}
_ZN3ada4idna9ascii_mapEPcm:
 2837|  12.3k|void ascii_map(char* input, size_t length) {
 2838|  12.3k|  auto broadcast = [](uint8_t v) -> uint64_t {
 2839|  12.3k|    return 0x101010101010101ull * v;
 2840|  12.3k|  };
 2841|  12.3k|  uint64_t broadcast_80 = broadcast(0x80);
 2842|  12.3k|  uint64_t broadcast_Ap = broadcast(128 - 'A');
 2843|  12.3k|  uint64_t broadcast_Zp = broadcast(128 - 'Z' - 1);
 2844|  12.3k|  size_t i = 0;
 2845|       |
 2846|  43.3k|  for (; i + 7 < length; i += 8) {
  ------------------
  |  Branch (2846:10): [True: 31.0k, False: 12.3k]
  ------------------
 2847|  31.0k|    uint64_t word{};
 2848|  31.0k|    std::memcpy(&word, input + i, sizeof(word));
 2849|  31.0k|    word ^=
 2850|  31.0k|        (((word + broadcast_Ap) ^ (word + broadcast_Zp)) & broadcast_80) >> 2;
 2851|  31.0k|    std::memcpy(input + i, &word, sizeof(word));
 2852|  31.0k|  }
 2853|  12.3k|  if (i < length) {
  ------------------
  |  Branch (2853:7): [True: 10.7k, False: 1.59k]
  ------------------
 2854|  10.7k|    uint64_t word{};
 2855|  10.7k|    std::memcpy(&word, input + i, length - i);
 2856|  10.7k|    word ^=
 2857|  10.7k|        (((word + broadcast_Ap) ^ (word + broadcast_Zp)) & broadcast_80) >> 2;
 2858|  10.7k|    std::memcpy(input + i, &word, length - i);
 2859|  10.7k|  }
 2860|  12.3k|}
_ZN3ada4idna3mapENSt3__117basic_string_viewIDiNS1_11char_traitsIDiEEEERNS1_12basic_stringIDiS4_NS1_9allocatorIDiEEEE:
 2866|  19.9k|bool map(std::u32string_view input, std::u32string& out) {
 2867|       |  //  [Map](https://www.unicode.org/reports/tr46/#ProcessingStepMap).
 2868|       |  //  For each code point in the domain_name string, look up the status
 2869|       |  //  value in Section 5, [IDNA Mapping
 2870|       |  //  Table](https://www.unicode.org/reports/tr46/#IDNA_Mapping_Table),
 2871|       |  //  and take the following actions:
 2872|       |  //    * disallowed: Leave the code point unchanged in the string, and
 2873|       |  //    record that there was an error.
 2874|       |  //    * ignored: Remove the code point from the string.
 2875|       |  //    * mapped: Replace the code point in the string by the value for
 2876|       |  //    the mapping in Section 5, [IDNA Mapping
 2877|       |  //    Table](https://www.unicode.org/reports/tr46/#IDNA_Mapping_Table).
 2878|       |  //    * valid: Leave the code point unchanged in the string.
 2879|  19.9k|  out.clear();
 2880|  19.9k|  out.reserve(input.size());
 2881|   315k|  for (char32_t x : input) {
  ------------------
  |  Branch (2881:19): [True: 315k, False: 18.5k]
  ------------------
 2882|   315k|    uint16_t status = idna_lookup(static_cast<uint32_t>(x));
 2883|   315k|    if (status == IDNA_DISALLOWED) {
  ------------------
  |  Branch (2883:9): [True: 1.39k, False: 313k]
  ------------------
 2884|  1.39k|      return false;
 2885|  1.39k|    }
 2886|   313k|    if (status == IDNA_VALID) {
  ------------------
  |  Branch (2886:9): [True: 277k, False: 36.5k]
  ------------------
 2887|   277k|      out.push_back(x);
 2888|   277k|      continue;
 2889|   277k|    }
 2890|       |    // IDNA_IGNORED (status==0) falls through: idna_utf8_mappings[0] == 0x00
 2891|       |    // (null terminator), so the decode loop below produces nothing.
 2892|       |
 2893|       |    // Mapped (or ignored): decode null-terminated UTF-8 from the mapping table.
 2894|  36.5k|    const uint8_t* ptr = idna_utf8_mappings + status;
 2895|   333k|    while (*ptr != 0) {
  ------------------
  |  Branch (2895:12): [True: 297k, False: 36.5k]
  ------------------
 2896|   297k|      out.push_back(utf8_next(ptr));
 2897|   297k|    }
 2898|  36.5k|  }
 2899|  18.5k|  return true;
 2900|  19.9k|}
_ZN3ada4idna3mapENSt3__117basic_string_viewIDiNS1_11char_traitsIDiEEEE:
 2902|  3.49k|std::u32string map(std::u32string_view input) {
 2903|  3.49k|  std::u32string answer;
 2904|  3.49k|  if (!map(input, answer)) {
  ------------------
  |  Branch (2904:7): [True: 24, False: 3.47k]
  ------------------
 2905|     24|    return {};
 2906|     24|  }
 2907|  3.47k|  return answer;
 2908|  3.49k|}
_ZN3ada4idna28compute_decomposition_lengthENSt3__117basic_string_viewIDiNS1_11char_traitsIDiEEEE:
 7828|  18.2k|    const std::u32string_view input) noexcept {
 7829|  18.2k|  bool decomposition_needed{false};
 7830|  18.2k|  size_t additional_elements{0};
 7831|   405k|  for (char32_t current_character : input) {
  ------------------
  |  Branch (7831:35): [True: 405k, False: 18.2k]
  ------------------
 7832|   405k|    size_t decomposition_length{0};
 7833|       |
 7834|   405k|    if (current_character >= hangul_sbase &&
  ------------------
  |  Branch (7834:9): [True: 22.3k, False: 383k]
  ------------------
 7835|  22.3k|        current_character < hangul_sbase + hangul_scount) {
  ------------------
  |  Branch (7835:9): [True: 7.79k, False: 14.5k]
  ------------------
 7836|  7.79k|      decomposition_length = 2;
 7837|  7.79k|      if ((current_character - hangul_sbase) % hangul_tcount) {
  ------------------
  |  Branch (7837:11): [True: 5.46k, False: 2.32k]
  ------------------
 7838|  5.46k|        decomposition_length = 3;
 7839|  5.46k|      }
 7840|   397k|    } else if (current_character < 0x110000) {
  ------------------
  |  Branch (7840:16): [True: 397k, False: 0]
  ------------------
 7841|   397k|      const uint8_t di = decomposition_index[current_character >> 8];
 7842|   397k|      const uint16_t* const decomposition =
 7843|   397k|          decomposition_block[di] + (current_character % 256);
 7844|   397k|      decomposition_length = (decomposition[1] >> 2) - (decomposition[0] >> 2);
 7845|   397k|      if ((decomposition_length > 0) && (decomposition[0] & 1)) {
  ------------------
  |  Branch (7845:11): [True: 19.8k, False: 378k]
  |  Branch (7845:41): [True: 11.3k, False: 8.57k]
  ------------------
 7846|  11.3k|        decomposition_length = 0;
 7847|  11.3k|      }
 7848|   397k|    }
 7849|   405k|    if (decomposition_length != 0) {
  ------------------
  |  Branch (7849:9): [True: 16.3k, False: 389k]
  ------------------
 7850|  16.3k|      decomposition_needed = true;
 7851|  16.3k|      additional_elements += decomposition_length - 1;
 7852|  16.3k|    }
 7853|   405k|  }
 7854|  18.2k|  return {decomposition_needed, additional_elements};
 7855|  18.2k|}
_ZN3ada4idna9decomposeERNSt3__112basic_stringIDiNS1_11char_traitsIDiEENS1_9allocatorIDiEEEEm:
 7857|  4.54k|void decompose(std::u32string& input, size_t additional_elements) {
 7858|  4.54k|  input.resize(input.size() + additional_elements);
 7859|  4.54k|  for (size_t descending_idx = input.size(),
 7860|  4.54k|              input_count = descending_idx - additional_elements;
 7861|   105k|       input_count--;) {
  ------------------
  |  Branch (7861:8): [True: 101k, False: 4.54k]
  ------------------
 7862|   101k|    if (input[input_count] >= hangul_sbase &&
  ------------------
  |  Branch (7862:9): [True: 11.3k, False: 89.8k]
  ------------------
 7863|  11.3k|        input[input_count] < hangul_sbase + hangul_scount) {
  ------------------
  |  Branch (7863:9): [True: 7.79k, False: 3.55k]
  ------------------
 7864|       |      // Hangul decomposition.
 7865|  7.79k|      char32_t s_index = input[input_count] - hangul_sbase;
 7866|  7.79k|      if (s_index % hangul_tcount != 0) {
  ------------------
  |  Branch (7866:11): [True: 5.46k, False: 2.32k]
  ------------------
 7867|  5.46k|        input[--descending_idx] = hangul_tbase + s_index % hangul_tcount;
 7868|  5.46k|      }
 7869|  7.79k|      input[--descending_idx] =
 7870|  7.79k|          hangul_vbase + (s_index % hangul_ncount) / hangul_tcount;
 7871|  7.79k|      input[--descending_idx] = hangul_lbase + s_index / hangul_ncount;
 7872|  93.4k|    } else if (input[input_count] < 0x110000) {
  ------------------
  |  Branch (7872:16): [True: 93.4k, False: 0]
  ------------------
 7873|       |      // Check decomposition_data.
 7874|  93.4k|      const uint16_t* decomposition =
 7875|  93.4k|          decomposition_block[decomposition_index[input[input_count] >> 8]] +
 7876|  93.4k|          (input[input_count] % 256);
 7877|  93.4k|      uint16_t decomposition_length =
 7878|  93.4k|          (decomposition[1] >> 2) - (decomposition[0] >> 2);
 7879|  93.4k|      if (decomposition_length > 0 && (decomposition[0] & 1)) {
  ------------------
  |  Branch (7879:11): [True: 10.6k, False: 82.7k]
  |  Branch (7879:39): [True: 2.09k, False: 8.57k]
  ------------------
 7880|  2.09k|        decomposition_length = 0;
 7881|  2.09k|      }
 7882|  93.4k|      if (decomposition_length > 0) {
  ------------------
  |  Branch (7882:11): [True: 8.57k, False: 84.8k]
  ------------------
 7883|       |        // Non-recursive decomposition.
 7884|  29.0k|        while (decomposition_length-- > 0) {
  ------------------
  |  Branch (7884:16): [True: 20.4k, False: 8.57k]
  ------------------
 7885|  20.4k|          input[--descending_idx] = decomposition_data[(decomposition[0] >> 2) +
 7886|  20.4k|                                                       decomposition_length];
 7887|  20.4k|        }
 7888|  84.8k|      } else {
 7889|       |        // No decomposition.
 7890|  84.8k|        input[--descending_idx] = input[input_count];
 7891|  84.8k|      }
 7892|  93.4k|    } else {
 7893|       |      // Non-Unicode character.
 7894|      0|      input[--descending_idx] = input[input_count];
 7895|      0|    }
 7896|   101k|  }
 7897|  4.54k|}
_ZN3ada4idna7get_cccEDi:
 7899|   832k|uint8_t get_ccc(char32_t c) noexcept {
 7900|   832k|  return c < 0x110000 ? canonical_combining_class_block
  ------------------
  |  Branch (7900:10): [True: 832k, False: 0]
  ------------------
 7901|   832k|                            [canonical_combining_class_index[c >> 8]][c % 256]
 7902|   832k|                      : 0;
 7903|   832k|}
_ZN3ada4idna10sort_marksERNSt3__112basic_stringIDiNS1_11char_traitsIDiEENS1_9allocatorIDiEEEE:
 7905|  18.2k|void sort_marks(std::u32string& input) {
 7906|   430k|  for (size_t idx = 1; idx < input.size(); idx++) {
  ------------------
  |  Branch (7906:24): [True: 412k, False: 18.2k]
  ------------------
 7907|   412k|    uint8_t ccc = get_ccc(input[idx]);
 7908|   412k|    if (ccc == 0) {
  ------------------
  |  Branch (7908:9): [True: 393k, False: 19.4k]
  ------------------
 7909|   393k|      continue;
 7910|   393k|    }  // Skip non-combining characters.
 7911|  19.4k|    auto current_character = input[idx];
 7912|  19.4k|    size_t back_idx = idx;
 7913|  30.0k|    while (back_idx != 0 && get_ccc(input[back_idx - 1]) > ccc) {
  ------------------
  |  Branch (7913:12): [True: 29.8k, False: 221]
  |  Branch (7913:29): [True: 10.5k, False: 19.2k]
  ------------------
 7914|  10.5k|      input[back_idx] = input[back_idx - 1];
 7915|  10.5k|      back_idx--;
 7916|  10.5k|    }
 7917|  19.4k|    input[back_idx] = current_character;
 7918|  19.4k|  }
 7919|  18.2k|}
_ZN3ada4idna13decompose_nfcERNSt3__112basic_stringIDiNS1_11char_traitsIDiEENS1_9allocatorIDiEEEE:
 7921|  18.2k|void decompose_nfc(std::u32string& input) {
 7922|       |  /**
 7923|       |   * Decompose the domain_name string to Unicode Normalization Form C.
 7924|       |   * @see https://www.unicode.org/reports/tr46/#ProcessingStepDecompose
 7925|       |   */
 7926|  18.2k|  auto [decomposition_needed, additional_elements] =
 7927|  18.2k|      compute_decomposition_length(input);
 7928|  18.2k|  if (decomposition_needed) {
  ------------------
  |  Branch (7928:7): [True: 4.54k, False: 13.6k]
  ------------------
 7929|  4.54k|    decompose(input, additional_elements);
 7930|  4.54k|  }
 7931|  18.2k|  sort_marks(input);
 7932|  18.2k|}
_ZN3ada4idna7composeERNSt3__112basic_stringIDiNS1_11char_traitsIDiEENS1_9allocatorIDiEEEE:
 7934|  18.2k|void compose(std::u32string& input) {
 7935|       |  /**
 7936|       |   * Compose the domain_name string to Unicode Normalization Form C.
 7937|       |   * @see https://www.unicode.org/reports/tr46/#ProcessingStepCompose
 7938|       |   */
 7939|  18.2k|  size_t input_count{0};
 7940|  18.2k|  size_t composition_count{0};
 7941|   416k|  for (; input_count < input.size(); input_count++, composition_count++) {
  ------------------
  |  Branch (7941:10): [True: 397k, False: 18.2k]
  ------------------
 7942|   397k|    input[composition_count] = input[input_count];
 7943|   397k|    if (input[input_count] >= hangul_lbase &&
  ------------------
  |  Branch (7943:9): [True: 61.3k, False: 336k]
  ------------------
 7944|  61.3k|        input[input_count] < hangul_lbase + hangul_lcount) {
  ------------------
  |  Branch (7944:9): [True: 10.1k, False: 51.1k]
  ------------------
 7945|  10.1k|      if (input_count + 1 < input.size() &&
  ------------------
  |  Branch (7945:11): [True: 9.66k, False: 502]
  ------------------
 7946|  9.66k|          input[input_count + 1] >= hangul_vbase &&
  ------------------
  |  Branch (7946:11): [True: 8.06k, False: 1.59k]
  ------------------
 7947|  8.06k|          input[input_count + 1] < hangul_vbase + hangul_vcount) {
  ------------------
  |  Branch (7947:11): [True: 7.79k, False: 270]
  ------------------
 7948|  7.79k|        input[composition_count] =
 7949|  7.79k|            hangul_sbase +
 7950|  7.79k|            ((input[input_count] - hangul_lbase) * hangul_vcount +
 7951|  7.79k|             input[input_count + 1] - hangul_vbase) *
 7952|  7.79k|                hangul_tcount;
 7953|  7.79k|        input_count++;
 7954|  7.79k|        if (input_count + 1 < input.size() &&
  ------------------
  |  Branch (7954:13): [True: 7.42k, False: 377]
  ------------------
 7955|  7.42k|            input[input_count + 1] > hangul_tbase &&
  ------------------
  |  Branch (7955:13): [True: 5.87k, False: 1.54k]
  ------------------
 7956|  5.87k|            input[input_count + 1] < hangul_tbase + hangul_tcount) {
  ------------------
  |  Branch (7956:13): [True: 5.46k, False: 409]
  ------------------
 7957|  5.46k|          input[composition_count] += input[++input_count] - hangul_tbase;
 7958|  5.46k|        }
 7959|  7.79k|      }
 7960|   387k|    } else if (input[input_count] >= hangul_sbase &&
  ------------------
  |  Branch (7960:16): [True: 13.6k, False: 374k]
  ------------------
 7961|  13.6k|               input[input_count] < hangul_sbase + hangul_scount) {
  ------------------
  |  Branch (7961:16): [True: 0, False: 13.6k]
  ------------------
 7962|      0|      if ((input[input_count] - hangul_sbase) % hangul_tcount &&
  ------------------
  |  Branch (7962:11): [True: 0, False: 0]
  ------------------
 7963|      0|          input_count + 1 < input.size() &&
  ------------------
  |  Branch (7963:11): [True: 0, False: 0]
  ------------------
 7964|      0|          input[input_count + 1] > hangul_tbase &&
  ------------------
  |  Branch (7964:11): [True: 0, False: 0]
  ------------------
 7965|      0|          input[input_count + 1] < hangul_tbase + hangul_tcount) {
  ------------------
  |  Branch (7965:11): [True: 0, False: 0]
  ------------------
 7966|      0|        input[composition_count] += input[++input_count] - hangul_tbase;
 7967|      0|      }
 7968|   387k|    } else if (input[input_count] < 0x110000) {
  ------------------
  |  Branch (7968:16): [True: 387k, False: 0]
  ------------------
 7969|   387k|      const uint16_t* composition =
 7970|   387k|          &composition_block[composition_index[input[input_count] >> 8]]
 7971|   387k|                            [input[input_count] % 256];
 7972|   387k|      size_t initial_composition_count = composition_count;
 7973|   407k|      for (int32_t previous_ccc = -1; input_count + 1 < input.size();
  ------------------
  |  Branch (7973:39): [True: 390k, False: 16.9k]
  ------------------
 7974|   390k|           input_count++) {
 7975|   390k|        uint8_t ccc = get_ccc(input[input_count + 1]);
 7976|       |
 7977|   390k|        if (composition[1] != composition[0] && previous_ccc < ccc) {
  ------------------
  |  Branch (7977:13): [True: 113k, False: 277k]
  |  Branch (7977:49): [True: 111k, False: 1.95k]
  ------------------
 7978|       |          // Try finding a composition.
 7979|   111k|          int left = composition[0];
 7980|   111k|          int right = composition[1];
 7981|   303k|          while (left + 2 < right) {
  ------------------
  |  Branch (7981:18): [True: 192k, False: 111k]
  ------------------
 7982|       |            // mean without overflow
 7983|   192k|            int middle = left + (((right - left) >> 1) & ~1);
 7984|   192k|            if (composition_data[middle] <= input[input_count + 1]) {
  ------------------
  |  Branch (7984:17): [True: 22.6k, False: 169k]
  ------------------
 7985|  22.6k|              left = middle;
 7986|  22.6k|            }
 7987|   192k|            if (composition_data[middle] >= input[input_count + 1]) {
  ------------------
  |  Branch (7987:17): [True: 177k, False: 15.0k]
  ------------------
 7988|   177k|              right = middle;
 7989|   177k|            }
 7990|   192k|          }
 7991|   111k|          if (composition_data[left] == input[input_count + 1]) {
  ------------------
  |  Branch (7991:15): [True: 11.0k, False: 100k]
  ------------------
 7992|  11.0k|            input[initial_composition_count] = composition_data[left + 1];
 7993|  11.0k|            composition =
 7994|  11.0k|                &composition_block
 7995|  11.0k|                    [composition_index[composition_data[left + 1] >> 8]]
 7996|  11.0k|                    [composition_data[left + 1] % 256];
 7997|  11.0k|            continue;
 7998|  11.0k|          }
 7999|   111k|        }
 8000|       |
 8001|   379k|        if (ccc == 0) {
  ------------------
  |  Branch (8001:13): [True: 370k, False: 8.60k]
  ------------------
 8002|   370k|          break;
 8003|   370k|        }  // Not a combining character.
 8004|  8.60k|        previous_ccc = ccc;
 8005|  8.60k|        input[++composition_count] = input[input_count + 1];
 8006|  8.60k|      }
 8007|   387k|    }
 8008|   397k|  }
 8009|       |
 8010|  18.2k|  if (composition_count < input_count) {
  ------------------
  |  Branch (8010:7): [True: 4.48k, False: 13.7k]
  ------------------
 8011|  4.48k|    input.resize(composition_count);
 8012|  4.48k|  }
 8013|  18.2k|}
_ZN3ada4idna9normalizeERNSt3__112basic_stringIDiNS1_11char_traitsIDiEENS1_9allocatorIDiEEEE:
 8015|  18.2k|void normalize(std::u32string& input) {
 8016|       |  /**
 8017|       |   * Normalize the domain_name string to Unicode Normalization Form C.
 8018|       |   * @see https://www.unicode.org/reports/tr46/#ProcessingStepNormalize
 8019|       |   */
 8020|  18.2k|  decompose_nfc(input);
 8021|  18.2k|  compose(input);
 8022|  18.2k|}
_ZN3ada4idna17punycode_to_utf32ENSt3__117basic_string_viewIcNS1_11char_traitsIcEEEERNS1_12basic_stringIDiNS3_IDiEENS1_9allocatorIDiEEEE:
 8065|  28.3k|bool punycode_to_utf32(std::string_view input, std::u32string &out) {
 8066|  28.3k|  int32_t written_out{0};
 8067|  28.3k|  out.reserve(out.size() + input.size());
 8068|  28.3k|  uint32_t n = initial_n;
 8069|  28.3k|  int32_t i = 0;
 8070|  28.3k|  int32_t bias = initial_bias;
 8071|       |  // grab ascii content
 8072|  28.3k|  size_t end_of_ascii = input.find_last_of('-');
 8073|  28.3k|  if (end_of_ascii != std::string_view::npos) {
  ------------------
  |  Branch (8073:7): [True: 4.99k, False: 23.3k]
  ------------------
 8074|  70.3k|    for (uint8_t c : input.substr(0, end_of_ascii)) {
  ------------------
  |  Branch (8074:20): [True: 70.3k, False: 4.63k]
  ------------------
 8075|  70.3k|      if (c >= 0x80) {
  ------------------
  |  Branch (8075:11): [True: 353, False: 70.0k]
  ------------------
 8076|    353|        return false;
 8077|    353|      }
 8078|  70.0k|      out.push_back(c);
 8079|  70.0k|      written_out++;
 8080|  70.0k|    }
 8081|  4.63k|    input.remove_prefix(end_of_ascii + 1);
 8082|  4.63k|  }
 8083|   199k|  while (!input.empty()) {
  ------------------
  |  Branch (8083:10): [True: 176k, False: 23.3k]
  ------------------
 8084|   176k|    int32_t oldi = i;
 8085|   176k|    int32_t w = 1;
 8086|   246k|    for (int32_t k = base;; k += base) {
 8087|   246k|      if (input.empty()) {
  ------------------
  |  Branch (8087:11): [True: 451, False: 245k]
  ------------------
 8088|    451|        return false;
 8089|    451|      }
 8090|   245k|      uint8_t code_point = input.front();
 8091|   245k|      input.remove_prefix(1);
 8092|   245k|      int32_t digit = char_to_digit_value(code_point);
 8093|   245k|      if (digit < 0) {
  ------------------
  |  Branch (8093:11): [True: 3.86k, False: 242k]
  ------------------
 8094|  3.86k|        return false;
 8095|  3.86k|      }
 8096|   242k|      if (digit > (0x7fffffff - i) / w) {
  ------------------
  |  Branch (8096:11): [True: 146, False: 241k]
  ------------------
 8097|    146|        return false;
 8098|    146|      }
 8099|   241k|      i = i + digit * w;
 8100|   241k|      int32_t t = k <= bias ? tmin : k >= bias + tmax ? tmax : k - bias;
  ------------------
  |  Branch (8100:19): [True: 44.1k, False: 197k]
  |  Branch (8100:38): [True: 184k, False: 13.5k]
  ------------------
 8101|   241k|      if (digit < t) {
  ------------------
  |  Branch (8101:11): [True: 172k, False: 69.7k]
  ------------------
 8102|   172k|        break;
 8103|   172k|      }
 8104|  69.7k|      if (w > 0x7fffffff / (base - t)) {
  ------------------
  |  Branch (8104:11): [True: 0, False: 69.7k]
  ------------------
 8105|      0|        return false;
 8106|      0|      }
 8107|  69.7k|      w = w * (base - t);
 8108|  69.7k|    }
 8109|   172k|    bias = adapt(i - oldi, written_out + 1, oldi == 0);
 8110|   172k|    if (i / (written_out + 1) > int32_t(0x7fffffff - n)) {
  ------------------
  |  Branch (8110:9): [True: 181, False: 171k]
  ------------------
 8111|    181|      return false;
 8112|    181|    }
 8113|   171k|    n = n + i / (written_out + 1);
 8114|   171k|    i = i % (written_out + 1);
 8115|   171k|    if (n < 0x80) {
  ------------------
  |  Branch (8115:9): [True: 0, False: 171k]
  ------------------
 8116|      0|      return false;
 8117|      0|    }
 8118|   171k|    out.insert(out.begin() + i, n);
 8119|   171k|    written_out++;
 8120|   171k|    ++i;
 8121|   171k|  }
 8122|       |  // See https://github.com/whatwg/url/issues/803
 8123|       |  // Reject labels whose decoded form begins with "xn--" (double-encoded ACE).
 8124|  23.3k|  if (out.size() >= 4 && out[0] == U'x' && out[1] == U'n' && out[2] == U'-' &&
  ------------------
  |  Branch (8124:7): [True: 5.34k, False: 17.9k]
  |  Branch (8124:26): [True: 471, False: 4.87k]
  |  Branch (8124:44): [True: 338, False: 133]
  |  Branch (8124:62): [True: 242, False: 96]
  ------------------
 8125|    242|      out[3] == U'-') {
  ------------------
  |  Branch (8125:7): [True: 153, False: 89]
  ------------------
 8126|    153|    return false;
 8127|    153|  }
 8128|  23.1k|  return true;
 8129|  23.3k|}
_ZN3ada4idna15verify_punycodeENSt3__117basic_string_viewIcNS1_11char_traitsIcEEEE:
 8131|  3.69k|bool verify_punycode(std::string_view input) {
 8132|       |  // Track only the first 4 decoded code points to check for the "xn--" prefix.
 8133|       |  // This avoids heap allocation while still detecting double-encoded ACE
 8134|       |  // labels.
 8135|  3.69k|  uint32_t first4[4]{};
 8136|  3.69k|  size_t written_out{0};
 8137|  3.69k|  uint32_t n = initial_n;
 8138|  3.69k|  int32_t i = 0;
 8139|  3.69k|  int32_t bias = initial_bias;
 8140|       |  // grab ascii content
 8141|  3.69k|  size_t end_of_ascii = input.find_last_of('-');
 8142|  3.69k|  if (end_of_ascii != std::string_view::npos) {
  ------------------
  |  Branch (8142:7): [True: 1.81k, False: 1.87k]
  ------------------
 8143|  30.0k|    for (uint8_t c : input.substr(0, end_of_ascii)) {
  ------------------
  |  Branch (8143:20): [True: 30.0k, False: 1.47k]
  ------------------
 8144|  30.0k|      if (c >= 0x80) {
  ------------------
  |  Branch (8144:11): [True: 343, False: 29.6k]
  ------------------
 8145|    343|        return false;
 8146|    343|      }
 8147|  29.6k|      if (written_out < 4) {
  ------------------
  |  Branch (8147:11): [True: 5.39k, False: 24.2k]
  ------------------
 8148|  5.39k|        first4[written_out] = c;
 8149|  5.39k|      }
 8150|  29.6k|      written_out++;
 8151|  29.6k|    }
 8152|  1.47k|    input.remove_prefix(end_of_ascii + 1);
 8153|  1.47k|  }
 8154|  10.0k|  while (!input.empty()) {
  ------------------
  |  Branch (8154:10): [True: 9.34k, False: 731]
  ------------------
 8155|  9.34k|    int32_t oldi = i;
 8156|  9.34k|    int32_t w = 1;
 8157|  14.9k|    for (int32_t k = base;; k += base) {
 8158|  14.9k|      if (input.empty()) {
  ------------------
  |  Branch (8158:11): [True: 69, False: 14.8k]
  ------------------
 8159|     69|        return false;
 8160|     69|      }
 8161|  14.8k|      uint8_t code_point = input.front();
 8162|  14.8k|      input.remove_prefix(1);
 8163|  14.8k|      int32_t digit = char_to_digit_value(code_point);
 8164|  14.8k|      if (digit < 0) {
  ------------------
  |  Branch (8164:11): [True: 2.52k, False: 12.3k]
  ------------------
 8165|  2.52k|        return false;
 8166|  2.52k|      }
 8167|  12.3k|      if (digit > (0x7fffffff - i) / w) {
  ------------------
  |  Branch (8167:11): [True: 25, False: 12.3k]
  ------------------
 8168|     25|        return false;
 8169|     25|      }
 8170|  12.3k|      i = i + digit * w;
 8171|  12.3k|      int32_t t = k <= bias ? tmin : k >= bias + tmax ? tmax : k - bias;
  ------------------
  |  Branch (8171:19): [True: 3.80k, False: 8.51k]
  |  Branch (8171:38): [True: 7.96k, False: 556]
  ------------------
 8172|  12.3k|      if (digit < t) {
  ------------------
  |  Branch (8172:11): [True: 6.73k, False: 5.59k]
  ------------------
 8173|  6.73k|        break;
 8174|  6.73k|      }
 8175|  5.59k|      if (w > 0x7fffffff / (base - t)) {
  ------------------
  |  Branch (8175:11): [True: 0, False: 5.59k]
  ------------------
 8176|      0|        return false;
 8177|      0|      }
 8178|  5.59k|      w = w * (base - t);
 8179|  5.59k|    }
 8180|  6.73k|    bias = adapt(i - oldi, int32_t(written_out + 1), oldi == 0);
 8181|  6.73k|    if (i / (written_out + 1) > 0x7fffffff - n) {
  ------------------
  |  Branch (8181:9): [True: 0, False: 6.73k]
  ------------------
 8182|      0|      return false;
 8183|      0|    }
 8184|  6.73k|    n = n + i / int32_t(written_out + 1);
 8185|  6.73k|    i = i % int32_t(written_out + 1);
 8186|  6.73k|    if (n < 0x80) {
  ------------------
  |  Branch (8186:9): [True: 0, False: 6.73k]
  ------------------
 8187|      0|      return false;
 8188|      0|    }
 8189|       |    // Simulate insert at position i, maintaining only the first 4 slots.
 8190|  6.73k|    size_t insert_pos = size_t(i);
 8191|  6.73k|    if (insert_pos < 4) {
  ------------------
  |  Branch (8191:9): [True: 1.72k, False: 5.00k]
  ------------------
 8192|  4.40k|      for (size_t j = 3; j > insert_pos; j--) {
  ------------------
  |  Branch (8192:26): [True: 2.67k, False: 1.72k]
  ------------------
 8193|  2.67k|        first4[j] = first4[j - 1];
 8194|  2.67k|      }
 8195|  1.72k|      first4[insert_pos] = n;
 8196|  1.72k|    }
 8197|  6.73k|    written_out++;
 8198|  6.73k|    ++i;
 8199|  6.73k|  }
 8200|       |  // See https://github.com/whatwg/url/issues/803
 8201|       |  // Reject labels whose decoded form begins with "xn--" (double-encoded ACE).
 8202|    731|  if (written_out >= 4 && first4[0] == U'x' && first4[1] == U'n' &&
  ------------------
  |  Branch (8202:7): [True: 711, False: 20]
  |  Branch (8202:27): [True: 420, False: 291]
  |  Branch (8202:48): [True: 311, False: 109]
  ------------------
 8203|    311|      first4[2] == U'-' && first4[3] == U'-') {
  ------------------
  |  Branch (8203:7): [True: 236, False: 75]
  |  Branch (8203:28): [True: 153, False: 83]
  ------------------
 8204|    153|    return false;
 8205|    153|  }
 8206|    578|  return true;
 8207|    731|}
_ZN3ada4idna17utf32_to_punycodeENSt3__117basic_string_viewIDiNS1_11char_traitsIDiEEEERNS1_12basic_stringIcNS3_IcEENS1_9allocatorIcEEEE:
 8209|  4.08k|bool utf32_to_punycode(std::u32string_view input, std::string &out) {
 8210|  4.08k|  out.reserve(input.size() + out.size());
 8211|  4.08k|  uint32_t n = initial_n;
 8212|  4.08k|  int32_t d = 0;
 8213|  4.08k|  int32_t bias = initial_bias;
 8214|  4.08k|  size_t h = 0;
 8215|       |  // first push the ascii content
 8216|  84.1k|  for (uint32_t c : input) {
  ------------------
  |  Branch (8216:19): [True: 84.1k, False: 3.94k]
  ------------------
 8217|  84.1k|    if (c < 0x80) {
  ------------------
  |  Branch (8217:9): [True: 20.2k, False: 63.9k]
  ------------------
 8218|  20.2k|      ++h;
 8219|  20.2k|      out.push_back(char(c));
 8220|  20.2k|    }
 8221|  84.1k|    if (c > 0x10ffff || (c >= 0xd800 && c < 0xe000)) {
  ------------------
  |  Branch (8221:9): [True: 137, False: 84.0k]
  |  Branch (8221:26): [True: 824, False: 83.2k]
  |  Branch (8221:41): [True: 2, False: 822]
  ------------------
 8222|    139|      return false;
 8223|    139|    }
 8224|  84.1k|  }
 8225|  3.94k|  size_t b = h;
 8226|  3.94k|  if (b > 0) {
  ------------------
  |  Branch (8226:7): [True: 1.72k, False: 2.21k]
  ------------------
 8227|  1.72k|    out.push_back('-');
 8228|  1.72k|  }
 8229|  16.7k|  while (h < input.size()) {
  ------------------
  |  Branch (8229:10): [True: 12.7k, False: 3.94k]
  ------------------
 8230|  12.7k|    uint32_t m = 0x10FFFF;
 8231|   931k|    for (auto code_point : input) {
  ------------------
  |  Branch (8231:26): [True: 931k, False: 12.7k]
  ------------------
 8232|   931k|      if (code_point >= n && code_point < m) m = code_point;
  ------------------
  |  Branch (8232:11): [True: 367k, False: 564k]
  |  Branch (8232:30): [True: 22.2k, False: 345k]
  ------------------
 8233|   931k|    }
 8234|       |
 8235|  12.7k|    if ((m - n) > (0x7fffffff - d) / (h + 1)) {
  ------------------
  |  Branch (8235:9): [True: 0, False: 12.7k]
  ------------------
 8236|      0|      return false;
 8237|      0|    }
 8238|  12.7k|    d = d + int32_t((m - n) * (h + 1));
 8239|  12.7k|    n = m;
 8240|   931k|    for (auto c : input) {
  ------------------
  |  Branch (8240:17): [True: 931k, False: 12.7k]
  ------------------
 8241|   931k|      if (c < n) {
  ------------------
  |  Branch (8241:11): [True: 564k, False: 367k]
  ------------------
 8242|   564k|        if (d == 0x7fffffff) {
  ------------------
  |  Branch (8242:13): [True: 0, False: 564k]
  ------------------
 8243|      0|          return false;
 8244|      0|        }
 8245|   564k|        ++d;
 8246|   564k|      }
 8247|   931k|      if (c == n) {
  ------------------
  |  Branch (8247:11): [True: 63.7k, False: 867k]
  ------------------
 8248|  63.7k|        int32_t q = d;
 8249|  86.9k|        for (int32_t k = base;; k += base) {
 8250|  86.9k|          int32_t t = k <= bias ? tmin : k >= bias + tmax ? tmax : k - bias;
  ------------------
  |  Branch (8250:23): [True: 10.8k, False: 76.1k]
  |  Branch (8250:42): [True: 70.7k, False: 5.36k]
  ------------------
 8251|       |
 8252|  86.9k|          if (q < t) {
  ------------------
  |  Branch (8252:15): [True: 63.7k, False: 23.2k]
  ------------------
 8253|  63.7k|            break;
 8254|  63.7k|          }
 8255|  23.2k|          out.push_back(digit_to_char(t + ((q - t) % (base - t))));
 8256|  23.2k|          q = (q - t) / (base - t);
 8257|  23.2k|        }
 8258|  63.7k|        out.push_back(digit_to_char(q));
 8259|  63.7k|        bias = adapt(d, int32_t(h + 1), h == b);
 8260|  63.7k|        d = 0;
 8261|  63.7k|        ++h;
 8262|  63.7k|      }
 8263|   931k|    }
 8264|  12.7k|    ++d;
 8265|  12.7k|    ++n;
 8266|  12.7k|  }
 8267|  3.94k|  return true;
 8268|  3.94k|}
_ZN3ada4idna14is_label_validENSt3__117basic_string_viewIDiNS1_11char_traitsIDiEEEE:
 9077|  16.5k|bool is_label_valid(const std::u32string_view label) {
 9078|  16.5k|  if (label.empty()) {
  ------------------
  |  Branch (9078:7): [True: 0, False: 16.5k]
  ------------------
 9079|      0|    return true;
 9080|      0|  }
 9081|       |
 9082|       |  ///////////////
 9083|       |  // We have a normalization step which ensures that we are in NFC.
 9084|       |  // If we receive punycode, we normalize and check that the normalized
 9085|       |  // version matches the original.
 9086|       |  // --------------------------------------
 9087|       |  // The label must be in Unicode Normalization Form NFC.
 9088|       |
 9089|       |  // Current URL standard indicatest that CheckHyphens is set to false.
 9090|       |  // ---------------------------------------
 9091|       |  // If CheckHyphens, the label must not contain a U+002D HYPHEN-MINUS character
 9092|       |  // in both the third and fourth positions. If CheckHyphens, the label must
 9093|       |  // neither begin nor end with a U+002D HYPHEN-MINUS character.
 9094|       |
 9095|       |  // This is not necessary because we segment the
 9096|       |  // labels by '.'.
 9097|       |  // ---------------------------------------
 9098|       |  // The label must not contain a U+002E ( . ) FULL STOP.
 9099|       |  // if (label.find('.') != std::string_view::npos) return false;
 9100|       |
 9101|       |  // The label must not begin with a combining mark, that is:
 9102|       |  // General_Category=Mark.
 9103|  16.5k|  constexpr static uint32_t combining[] = {
 9104|  16.5k|      0x300,   0x301,   0x302,   0x303,   0x304,   0x305,   0x306,   0x307,
 9105|  16.5k|      0x308,   0x309,   0x30a,   0x30b,   0x30c,   0x30d,   0x30e,   0x30f,
 9106|  16.5k|      0x310,   0x311,   0x312,   0x313,   0x314,   0x315,   0x316,   0x317,
 9107|  16.5k|      0x318,   0x319,   0x31a,   0x31b,   0x31c,   0x31d,   0x31e,   0x31f,
 9108|  16.5k|      0x320,   0x321,   0x322,   0x323,   0x324,   0x325,   0x326,   0x327,
 9109|  16.5k|      0x328,   0x329,   0x32a,   0x32b,   0x32c,   0x32d,   0x32e,   0x32f,
 9110|  16.5k|      0x330,   0x331,   0x332,   0x333,   0x334,   0x335,   0x336,   0x337,
 9111|  16.5k|      0x338,   0x339,   0x33a,   0x33b,   0x33c,   0x33d,   0x33e,   0x33f,
 9112|  16.5k|      0x340,   0x341,   0x342,   0x343,   0x344,   0x345,   0x346,   0x347,
 9113|  16.5k|      0x348,   0x349,   0x34a,   0x34b,   0x34c,   0x34d,   0x34e,   0x34f,
 9114|  16.5k|      0x350,   0x351,   0x352,   0x353,   0x354,   0x355,   0x356,   0x357,
 9115|  16.5k|      0x358,   0x359,   0x35a,   0x35b,   0x35c,   0x35d,   0x35e,   0x35f,
 9116|  16.5k|      0x360,   0x361,   0x362,   0x363,   0x364,   0x365,   0x366,   0x367,
 9117|  16.5k|      0x368,   0x369,   0x36a,   0x36b,   0x36c,   0x36d,   0x36e,   0x36f,
 9118|  16.5k|      0x483,   0x484,   0x485,   0x486,   0x487,   0x488,   0x489,   0x591,
 9119|  16.5k|      0x592,   0x593,   0x594,   0x595,   0x596,   0x597,   0x598,   0x599,
 9120|  16.5k|      0x59a,   0x59b,   0x59c,   0x59d,   0x59e,   0x59f,   0x5a0,   0x5a1,
 9121|  16.5k|      0x5a2,   0x5a3,   0x5a4,   0x5a5,   0x5a6,   0x5a7,   0x5a8,   0x5a9,
 9122|  16.5k|      0x5aa,   0x5ab,   0x5ac,   0x5ad,   0x5ae,   0x5af,   0x5b0,   0x5b1,
 9123|  16.5k|      0x5b2,   0x5b3,   0x5b4,   0x5b5,   0x5b6,   0x5b7,   0x5b8,   0x5b9,
 9124|  16.5k|      0x5ba,   0x5bb,   0x5bc,   0x5bd,   0x5bf,   0x5c1,   0x5c2,   0x5c4,
 9125|  16.5k|      0x5c5,   0x5c7,   0x610,   0x611,   0x612,   0x613,   0x614,   0x615,
 9126|  16.5k|      0x616,   0x617,   0x618,   0x619,   0x61a,   0x64b,   0x64c,   0x64d,
 9127|  16.5k|      0x64e,   0x64f,   0x650,   0x651,   0x652,   0x653,   0x654,   0x655,
 9128|  16.5k|      0x656,   0x657,   0x658,   0x659,   0x65a,   0x65b,   0x65c,   0x65d,
 9129|  16.5k|      0x65e,   0x65f,   0x670,   0x6d6,   0x6d7,   0x6d8,   0x6d9,   0x6da,
 9130|  16.5k|      0x6db,   0x6dc,   0x6df,   0x6e0,   0x6e1,   0x6e2,   0x6e3,   0x6e4,
 9131|  16.5k|      0x6e7,   0x6e8,   0x6ea,   0x6eb,   0x6ec,   0x6ed,   0x711,   0x730,
 9132|  16.5k|      0x731,   0x732,   0x733,   0x734,   0x735,   0x736,   0x737,   0x738,
 9133|  16.5k|      0x739,   0x73a,   0x73b,   0x73c,   0x73d,   0x73e,   0x73f,   0x740,
 9134|  16.5k|      0x741,   0x742,   0x743,   0x744,   0x745,   0x746,   0x747,   0x748,
 9135|  16.5k|      0x749,   0x74a,   0x7a6,   0x7a7,   0x7a8,   0x7a9,   0x7aa,   0x7ab,
 9136|  16.5k|      0x7ac,   0x7ad,   0x7ae,   0x7af,   0x7b0,   0x7eb,   0x7ec,   0x7ed,
 9137|  16.5k|      0x7ee,   0x7ef,   0x7f0,   0x7f1,   0x7f2,   0x7f3,   0x7fd,   0x816,
 9138|  16.5k|      0x817,   0x818,   0x819,   0x81b,   0x81c,   0x81d,   0x81e,   0x81f,
 9139|  16.5k|      0x820,   0x821,   0x822,   0x823,   0x825,   0x826,   0x827,   0x829,
 9140|  16.5k|      0x82a,   0x82b,   0x82c,   0x82d,   0x859,   0x85a,   0x85b,   0x8d3,
 9141|  16.5k|      0x8d4,   0x8d5,   0x8d6,   0x8d7,   0x8d8,   0x8d9,   0x8da,   0x8db,
 9142|  16.5k|      0x8dc,   0x8dd,   0x8de,   0x8df,   0x8e0,   0x8e1,   0x8e3,   0x8e4,
 9143|  16.5k|      0x8e5,   0x8e6,   0x8e7,   0x8e8,   0x8e9,   0x8ea,   0x8eb,   0x8ec,
 9144|  16.5k|      0x8ed,   0x8ee,   0x8ef,   0x8f0,   0x8f1,   0x8f2,   0x8f3,   0x8f4,
 9145|  16.5k|      0x8f5,   0x8f6,   0x8f7,   0x8f8,   0x8f9,   0x8fa,   0x8fb,   0x8fc,
 9146|  16.5k|      0x8fd,   0x8fe,   0x8ff,   0x900,   0x901,   0x902,   0x903,   0x93a,
 9147|  16.5k|      0x93b,   0x93c,   0x93e,   0x93f,   0x940,   0x941,   0x942,   0x943,
 9148|  16.5k|      0x944,   0x945,   0x946,   0x947,   0x948,   0x949,   0x94a,   0x94b,
 9149|  16.5k|      0x94c,   0x94d,   0x94e,   0x94f,   0x951,   0x952,   0x953,   0x954,
 9150|  16.5k|      0x955,   0x956,   0x957,   0x962,   0x963,   0x981,   0x982,   0x983,
 9151|  16.5k|      0x9bc,   0x9be,   0x9bf,   0x9c0,   0x9c1,   0x9c2,   0x9c3,   0x9c4,
 9152|  16.5k|      0x9c7,   0x9c8,   0x9cb,   0x9cc,   0x9cd,   0x9d7,   0x9e2,   0x9e3,
 9153|  16.5k|      0x9fe,   0xa01,   0xa02,   0xa03,   0xa3c,   0xa3e,   0xa3f,   0xa40,
 9154|  16.5k|      0xa41,   0xa42,   0xa47,   0xa48,   0xa4b,   0xa4c,   0xa4d,   0xa51,
 9155|  16.5k|      0xa70,   0xa71,   0xa75,   0xa81,   0xa82,   0xa83,   0xabc,   0xabe,
 9156|  16.5k|      0xabf,   0xac0,   0xac1,   0xac2,   0xac3,   0xac4,   0xac5,   0xac7,
 9157|  16.5k|      0xac8,   0xac9,   0xacb,   0xacc,   0xacd,   0xae2,   0xae3,   0xafa,
 9158|  16.5k|      0xafb,   0xafc,   0xafd,   0xafe,   0xaff,   0xb01,   0xb02,   0xb03,
 9159|  16.5k|      0xb3c,   0xb3e,   0xb3f,   0xb40,   0xb41,   0xb42,   0xb43,   0xb44,
 9160|  16.5k|      0xb47,   0xb48,   0xb4b,   0xb4c,   0xb4d,   0xb55,   0xb56,   0xb57,
 9161|  16.5k|      0xb62,   0xb63,   0xb82,   0xbbe,   0xbbf,   0xbc0,   0xbc1,   0xbc2,
 9162|  16.5k|      0xbc6,   0xbc7,   0xbc8,   0xbca,   0xbcb,   0xbcc,   0xbcd,   0xbd7,
 9163|  16.5k|      0xc00,   0xc01,   0xc02,   0xc03,   0xc04,   0xc3e,   0xc3f,   0xc40,
 9164|  16.5k|      0xc41,   0xc42,   0xc43,   0xc44,   0xc46,   0xc47,   0xc48,   0xc4a,
 9165|  16.5k|      0xc4b,   0xc4c,   0xc4d,   0xc55,   0xc56,   0xc62,   0xc63,   0xc81,
 9166|  16.5k|      0xc82,   0xc83,   0xcbc,   0xcbe,   0xcbf,   0xcc0,   0xcc1,   0xcc2,
 9167|  16.5k|      0xcc3,   0xcc4,   0xcc6,   0xcc7,   0xcc8,   0xcca,   0xccb,   0xccc,
 9168|  16.5k|      0xccd,   0xcd5,   0xcd6,   0xce2,   0xce3,   0xd00,   0xd01,   0xd02,
 9169|  16.5k|      0xd03,   0xd3b,   0xd3c,   0xd3e,   0xd3f,   0xd40,   0xd41,   0xd42,
 9170|  16.5k|      0xd43,   0xd44,   0xd46,   0xd47,   0xd48,   0xd4a,   0xd4b,   0xd4c,
 9171|  16.5k|      0xd4d,   0xd57,   0xd62,   0xd63,   0xd81,   0xd82,   0xd83,   0xdca,
 9172|  16.5k|      0xdcf,   0xdd0,   0xdd1,   0xdd2,   0xdd3,   0xdd4,   0xdd6,   0xdd8,
 9173|  16.5k|      0xdd9,   0xdda,   0xddb,   0xddc,   0xddd,   0xdde,   0xddf,   0xdf2,
 9174|  16.5k|      0xdf3,   0xe31,   0xe34,   0xe35,   0xe36,   0xe37,   0xe38,   0xe39,
 9175|  16.5k|      0xe3a,   0xe47,   0xe48,   0xe49,   0xe4a,   0xe4b,   0xe4c,   0xe4d,
 9176|  16.5k|      0xe4e,   0xeb1,   0xeb4,   0xeb5,   0xeb6,   0xeb7,   0xeb8,   0xeb9,
 9177|  16.5k|      0xeba,   0xebb,   0xebc,   0xec8,   0xec9,   0xeca,   0xecb,   0xecc,
 9178|  16.5k|      0xecd,   0xf18,   0xf19,   0xf35,   0xf37,   0xf39,   0xf3e,   0xf3f,
 9179|  16.5k|      0xf71,   0xf72,   0xf73,   0xf74,   0xf75,   0xf76,   0xf77,   0xf78,
 9180|  16.5k|      0xf79,   0xf7a,   0xf7b,   0xf7c,   0xf7d,   0xf7e,   0xf7f,   0xf80,
 9181|  16.5k|      0xf81,   0xf82,   0xf83,   0xf84,   0xf86,   0xf87,   0xf8d,   0xf8e,
 9182|  16.5k|      0xf8f,   0xf90,   0xf91,   0xf92,   0xf93,   0xf94,   0xf95,   0xf96,
 9183|  16.5k|      0xf97,   0xf99,   0xf9a,   0xf9b,   0xf9c,   0xf9d,   0xf9e,   0xf9f,
 9184|  16.5k|      0xfa0,   0xfa1,   0xfa2,   0xfa3,   0xfa4,   0xfa5,   0xfa6,   0xfa7,
 9185|  16.5k|      0xfa8,   0xfa9,   0xfaa,   0xfab,   0xfac,   0xfad,   0xfae,   0xfaf,
 9186|  16.5k|      0xfb0,   0xfb1,   0xfb2,   0xfb3,   0xfb4,   0xfb5,   0xfb6,   0xfb7,
 9187|  16.5k|      0xfb8,   0xfb9,   0xfba,   0xfbb,   0xfbc,   0xfc6,   0x102b,  0x102c,
 9188|  16.5k|      0x102d,  0x102e,  0x102f,  0x1030,  0x1031,  0x1032,  0x1033,  0x1034,
 9189|  16.5k|      0x1035,  0x1036,  0x1037,  0x1038,  0x1039,  0x103a,  0x103b,  0x103c,
 9190|  16.5k|      0x103d,  0x103e,  0x1056,  0x1057,  0x1058,  0x1059,  0x105e,  0x105f,
 9191|  16.5k|      0x1060,  0x1062,  0x1063,  0x1064,  0x1067,  0x1068,  0x1069,  0x106a,
 9192|  16.5k|      0x106b,  0x106c,  0x106d,  0x1071,  0x1072,  0x1073,  0x1074,  0x1082,
 9193|  16.5k|      0x1083,  0x1084,  0x1085,  0x1086,  0x1087,  0x1088,  0x1089,  0x108a,
 9194|  16.5k|      0x108b,  0x108c,  0x108d,  0x108f,  0x109a,  0x109b,  0x109c,  0x109d,
 9195|  16.5k|      0x135d,  0x135e,  0x135f,  0x1712,  0x1713,  0x1714,  0x1732,  0x1733,
 9196|  16.5k|      0x1734,  0x1752,  0x1753,  0x1772,  0x1773,  0x17b4,  0x17b5,  0x17b6,
 9197|  16.5k|      0x17b7,  0x17b8,  0x17b9,  0x17ba,  0x17bb,  0x17bc,  0x17bd,  0x17be,
 9198|  16.5k|      0x17bf,  0x17c0,  0x17c1,  0x17c2,  0x17c3,  0x17c4,  0x17c5,  0x17c6,
 9199|  16.5k|      0x17c7,  0x17c8,  0x17c9,  0x17ca,  0x17cb,  0x17cc,  0x17cd,  0x17ce,
 9200|  16.5k|      0x17cf,  0x17d0,  0x17d1,  0x17d2,  0x17d3,  0x17dd,  0x180b,  0x180c,
 9201|  16.5k|      0x180d,  0x1885,  0x1886,  0x18a9,  0x1920,  0x1921,  0x1922,  0x1923,
 9202|  16.5k|      0x1924,  0x1925,  0x1926,  0x1927,  0x1928,  0x1929,  0x192a,  0x192b,
 9203|  16.5k|      0x1930,  0x1931,  0x1932,  0x1933,  0x1934,  0x1935,  0x1936,  0x1937,
 9204|  16.5k|      0x1938,  0x1939,  0x193a,  0x193b,  0x1a17,  0x1a18,  0x1a19,  0x1a1a,
 9205|  16.5k|      0x1a1b,  0x1a55,  0x1a56,  0x1a57,  0x1a58,  0x1a59,  0x1a5a,  0x1a5b,
 9206|  16.5k|      0x1a5c,  0x1a5d,  0x1a5e,  0x1a60,  0x1a61,  0x1a62,  0x1a63,  0x1a64,
 9207|  16.5k|      0x1a65,  0x1a66,  0x1a67,  0x1a68,  0x1a69,  0x1a6a,  0x1a6b,  0x1a6c,
 9208|  16.5k|      0x1a6d,  0x1a6e,  0x1a6f,  0x1a70,  0x1a71,  0x1a72,  0x1a73,  0x1a74,
 9209|  16.5k|      0x1a75,  0x1a76,  0x1a77,  0x1a78,  0x1a79,  0x1a7a,  0x1a7b,  0x1a7c,
 9210|  16.5k|      0x1a7f,  0x1ab0,  0x1ab1,  0x1ab2,  0x1ab3,  0x1ab4,  0x1ab5,  0x1ab6,
 9211|  16.5k|      0x1ab7,  0x1ab8,  0x1ab9,  0x1aba,  0x1abb,  0x1abc,  0x1abd,  0x1abe,
 9212|  16.5k|      0x1abf,  0x1ac0,  0x1b00,  0x1b01,  0x1b02,  0x1b03,  0x1b04,  0x1b34,
 9213|  16.5k|      0x1b35,  0x1b36,  0x1b37,  0x1b38,  0x1b39,  0x1b3a,  0x1b3b,  0x1b3c,
 9214|  16.5k|      0x1b3d,  0x1b3e,  0x1b3f,  0x1b40,  0x1b41,  0x1b42,  0x1b43,  0x1b44,
 9215|  16.5k|      0x1b6b,  0x1b6c,  0x1b6d,  0x1b6e,  0x1b6f,  0x1b70,  0x1b71,  0x1b72,
 9216|  16.5k|      0x1b73,  0x1b80,  0x1b81,  0x1b82,  0x1ba1,  0x1ba2,  0x1ba3,  0x1ba4,
 9217|  16.5k|      0x1ba5,  0x1ba6,  0x1ba7,  0x1ba8,  0x1ba9,  0x1baa,  0x1bab,  0x1bac,
 9218|  16.5k|      0x1bad,  0x1be6,  0x1be7,  0x1be8,  0x1be9,  0x1bea,  0x1beb,  0x1bec,
 9219|  16.5k|      0x1bed,  0x1bee,  0x1bef,  0x1bf0,  0x1bf1,  0x1bf2,  0x1bf3,  0x1c24,
 9220|  16.5k|      0x1c25,  0x1c26,  0x1c27,  0x1c28,  0x1c29,  0x1c2a,  0x1c2b,  0x1c2c,
 9221|  16.5k|      0x1c2d,  0x1c2e,  0x1c2f,  0x1c30,  0x1c31,  0x1c32,  0x1c33,  0x1c34,
 9222|  16.5k|      0x1c35,  0x1c36,  0x1c37,  0x1cd0,  0x1cd1,  0x1cd2,  0x1cd4,  0x1cd5,
 9223|  16.5k|      0x1cd6,  0x1cd7,  0x1cd8,  0x1cd9,  0x1cda,  0x1cdb,  0x1cdc,  0x1cdd,
 9224|  16.5k|      0x1cde,  0x1cdf,  0x1ce0,  0x1ce1,  0x1ce2,  0x1ce3,  0x1ce4,  0x1ce5,
 9225|  16.5k|      0x1ce6,  0x1ce7,  0x1ce8,  0x1ced,  0x1cf4,  0x1cf7,  0x1cf8,  0x1cf9,
 9226|  16.5k|      0x1dc0,  0x1dc1,  0x1dc2,  0x1dc3,  0x1dc4,  0x1dc5,  0x1dc6,  0x1dc7,
 9227|  16.5k|      0x1dc8,  0x1dc9,  0x1dca,  0x1dcb,  0x1dcc,  0x1dcd,  0x1dce,  0x1dcf,
 9228|  16.5k|      0x1dd0,  0x1dd1,  0x1dd2,  0x1dd3,  0x1dd4,  0x1dd5,  0x1dd6,  0x1dd7,
 9229|  16.5k|      0x1dd8,  0x1dd9,  0x1dda,  0x1ddb,  0x1ddc,  0x1ddd,  0x1dde,  0x1ddf,
 9230|  16.5k|      0x1de0,  0x1de1,  0x1de2,  0x1de3,  0x1de4,  0x1de5,  0x1de6,  0x1de7,
 9231|  16.5k|      0x1de8,  0x1de9,  0x1dea,  0x1deb,  0x1dec,  0x1ded,  0x1dee,  0x1def,
 9232|  16.5k|      0x1df0,  0x1df1,  0x1df2,  0x1df3,  0x1df4,  0x1df5,  0x1df6,  0x1df7,
 9233|  16.5k|      0x1df8,  0x1df9,  0x1dfb,  0x1dfc,  0x1dfd,  0x1dfe,  0x1dff,  0x20d0,
 9234|  16.5k|      0x20d1,  0x20d2,  0x20d3,  0x20d4,  0x20d5,  0x20d6,  0x20d7,  0x20d8,
 9235|  16.5k|      0x20d9,  0x20da,  0x20db,  0x20dc,  0x20dd,  0x20de,  0x20df,  0x20e0,
 9236|  16.5k|      0x20e1,  0x20e2,  0x20e3,  0x20e4,  0x20e5,  0x20e6,  0x20e7,  0x20e8,
 9237|  16.5k|      0x20e9,  0x20ea,  0x20eb,  0x20ec,  0x20ed,  0x20ee,  0x20ef,  0x20f0,
 9238|  16.5k|      0x2cef,  0x2cf0,  0x2cf1,  0x2d7f,  0x2de0,  0x2de1,  0x2de2,  0x2de3,
 9239|  16.5k|      0x2de4,  0x2de5,  0x2de6,  0x2de7,  0x2de8,  0x2de9,  0x2dea,  0x2deb,
 9240|  16.5k|      0x2dec,  0x2ded,  0x2dee,  0x2def,  0x2df0,  0x2df1,  0x2df2,  0x2df3,
 9241|  16.5k|      0x2df4,  0x2df5,  0x2df6,  0x2df7,  0x2df8,  0x2df9,  0x2dfa,  0x2dfb,
 9242|  16.5k|      0x2dfc,  0x2dfd,  0x2dfe,  0x2dff,  0x302a,  0x302b,  0x302c,  0x302d,
 9243|  16.5k|      0x302e,  0x302f,  0x3099,  0x309a,  0xa66f,  0xa670,  0xa671,  0xa672,
 9244|  16.5k|      0xa674,  0xa675,  0xa676,  0xa677,  0xa678,  0xa679,  0xa67a,  0xa67b,
 9245|  16.5k|      0xa67c,  0xa67d,  0xa69e,  0xa69f,  0xa6f0,  0xa6f1,  0xa802,  0xa806,
 9246|  16.5k|      0xa80b,  0xa823,  0xa824,  0xa825,  0xa826,  0xa827,  0xa82c,  0xa880,
 9247|  16.5k|      0xa881,  0xa8b4,  0xa8b5,  0xa8b6,  0xa8b7,  0xa8b8,  0xa8b9,  0xa8ba,
 9248|  16.5k|      0xa8bb,  0xa8bc,  0xa8bd,  0xa8be,  0xa8bf,  0xa8c0,  0xa8c1,  0xa8c2,
 9249|  16.5k|      0xa8c3,  0xa8c4,  0xa8c5,  0xa8e0,  0xa8e1,  0xa8e2,  0xa8e3,  0xa8e4,
 9250|  16.5k|      0xa8e5,  0xa8e6,  0xa8e7,  0xa8e8,  0xa8e9,  0xa8ea,  0xa8eb,  0xa8ec,
 9251|  16.5k|      0xa8ed,  0xa8ee,  0xa8ef,  0xa8f0,  0xa8f1,  0xa8ff,  0xa926,  0xa927,
 9252|  16.5k|      0xa928,  0xa929,  0xa92a,  0xa92b,  0xa92c,  0xa92d,  0xa947,  0xa948,
 9253|  16.5k|      0xa949,  0xa94a,  0xa94b,  0xa94c,  0xa94d,  0xa94e,  0xa94f,  0xa950,
 9254|  16.5k|      0xa951,  0xa952,  0xa953,  0xa980,  0xa981,  0xa982,  0xa983,  0xa9b3,
 9255|  16.5k|      0xa9b4,  0xa9b5,  0xa9b6,  0xa9b7,  0xa9b8,  0xa9b9,  0xa9ba,  0xa9bb,
 9256|  16.5k|      0xa9bc,  0xa9bd,  0xa9be,  0xa9bf,  0xa9c0,  0xa9e5,  0xaa29,  0xaa2a,
 9257|  16.5k|      0xaa2b,  0xaa2c,  0xaa2d,  0xaa2e,  0xaa2f,  0xaa30,  0xaa31,  0xaa32,
 9258|  16.5k|      0xaa33,  0xaa34,  0xaa35,  0xaa36,  0xaa43,  0xaa4c,  0xaa4d,  0xaa7b,
 9259|  16.5k|      0xaa7c,  0xaa7d,  0xaab0,  0xaab2,  0xaab3,  0xaab4,  0xaab7,  0xaab8,
 9260|  16.5k|      0xaabe,  0xaabf,  0xaac1,  0xaaeb,  0xaaec,  0xaaed,  0xaaee,  0xaaef,
 9261|  16.5k|      0xaaf5,  0xaaf6,  0xabe3,  0xabe4,  0xabe5,  0xabe6,  0xabe7,  0xabe8,
 9262|  16.5k|      0xabe9,  0xabea,  0xabec,  0xabed,  0xfb1e,  0xfe00,  0xfe01,  0xfe02,
 9263|  16.5k|      0xfe03,  0xfe04,  0xfe05,  0xfe06,  0xfe07,  0xfe08,  0xfe09,  0xfe0a,
 9264|  16.5k|      0xfe0b,  0xfe0c,  0xfe0d,  0xfe0e,  0xfe0f,  0xfe20,  0xfe21,  0xfe22,
 9265|  16.5k|      0xfe23,  0xfe24,  0xfe25,  0xfe26,  0xfe27,  0xfe28,  0xfe29,  0xfe2a,
 9266|  16.5k|      0xfe2b,  0xfe2c,  0xfe2d,  0xfe2e,  0xfe2f,  0x101fd, 0x102e0, 0x10376,
 9267|  16.5k|      0x10377, 0x10378, 0x10379, 0x1037a, 0x10a01, 0x10a02, 0x10a03, 0x10a05,
 9268|  16.5k|      0x10a06, 0x10a0c, 0x10a0d, 0x10a0e, 0x10a0f, 0x10a38, 0x10a39, 0x10a3a,
 9269|  16.5k|      0x10a3f, 0x10ae5, 0x10ae6, 0x10d24, 0x10d25, 0x10d26, 0x10d27, 0x10eab,
 9270|  16.5k|      0x10eac, 0x10f46, 0x10f47, 0x10f48, 0x10f49, 0x10f4a, 0x10f4b, 0x10f4c,
 9271|  16.5k|      0x10f4d, 0x10f4e, 0x10f4f, 0x10f50, 0x11000, 0x11001, 0x11002, 0x11038,
 9272|  16.5k|      0x11039, 0x1103a, 0x1103b, 0x1103c, 0x1103d, 0x1103e, 0x1103f, 0x11040,
 9273|  16.5k|      0x11041, 0x11042, 0x11043, 0x11044, 0x11045, 0x11046, 0x1107f, 0x11080,
 9274|  16.5k|      0x11081, 0x11082, 0x110b0, 0x110b1, 0x110b2, 0x110b3, 0x110b4, 0x110b5,
 9275|  16.5k|      0x110b6, 0x110b7, 0x110b8, 0x110b9, 0x110ba, 0x11100, 0x11101, 0x11102,
 9276|  16.5k|      0x11127, 0x11128, 0x11129, 0x1112a, 0x1112b, 0x1112c, 0x1112d, 0x1112e,
 9277|  16.5k|      0x1112f, 0x11130, 0x11131, 0x11132, 0x11133, 0x11134, 0x11145, 0x11146,
 9278|  16.5k|      0x11173, 0x11180, 0x11181, 0x11182, 0x111b3, 0x111b4, 0x111b5, 0x111b6,
 9279|  16.5k|      0x111b7, 0x111b8, 0x111b9, 0x111ba, 0x111bb, 0x111bc, 0x111bd, 0x111be,
 9280|  16.5k|      0x111bf, 0x111c0, 0x111c9, 0x111ca, 0x111cb, 0x111cc, 0x111ce, 0x111cf,
 9281|  16.5k|      0x1122c, 0x1122d, 0x1122e, 0x1122f, 0x11230, 0x11231, 0x11232, 0x11233,
 9282|  16.5k|      0x11234, 0x11235, 0x11236, 0x11237, 0x1123e, 0x112df, 0x112e0, 0x112e1,
 9283|  16.5k|      0x112e2, 0x112e3, 0x112e4, 0x112e5, 0x112e6, 0x112e7, 0x112e8, 0x112e9,
 9284|  16.5k|      0x112ea, 0x11300, 0x11301, 0x11302, 0x11303, 0x1133b, 0x1133c, 0x1133e,
 9285|  16.5k|      0x1133f, 0x11340, 0x11341, 0x11342, 0x11343, 0x11344, 0x11347, 0x11348,
 9286|  16.5k|      0x1134b, 0x1134c, 0x1134d, 0x11357, 0x11362, 0x11363, 0x11366, 0x11367,
 9287|  16.5k|      0x11368, 0x11369, 0x1136a, 0x1136b, 0x1136c, 0x11370, 0x11371, 0x11372,
 9288|  16.5k|      0x11373, 0x11374, 0x11435, 0x11436, 0x11437, 0x11438, 0x11439, 0x1143a,
 9289|  16.5k|      0x1143b, 0x1143c, 0x1143d, 0x1143e, 0x1143f, 0x11440, 0x11441, 0x11442,
 9290|  16.5k|      0x11443, 0x11444, 0x11445, 0x11446, 0x1145e, 0x114b0, 0x114b1, 0x114b2,
 9291|  16.5k|      0x114b3, 0x114b4, 0x114b5, 0x114b6, 0x114b7, 0x114b8, 0x114b9, 0x114ba,
 9292|  16.5k|      0x114bb, 0x114bc, 0x114bd, 0x114be, 0x114bf, 0x114c0, 0x114c1, 0x114c2,
 9293|  16.5k|      0x114c3, 0x115af, 0x115b0, 0x115b1, 0x115b2, 0x115b3, 0x115b4, 0x115b5,
 9294|  16.5k|      0x115b8, 0x115b9, 0x115ba, 0x115bb, 0x115bc, 0x115bd, 0x115be, 0x115bf,
 9295|  16.5k|      0x115c0, 0x115dc, 0x115dd, 0x11630, 0x11631, 0x11632, 0x11633, 0x11634,
 9296|  16.5k|      0x11635, 0x11636, 0x11637, 0x11638, 0x11639, 0x1163a, 0x1163b, 0x1163c,
 9297|  16.5k|      0x1163d, 0x1163e, 0x1163f, 0x11640, 0x116ab, 0x116ac, 0x116ad, 0x116ae,
 9298|  16.5k|      0x116af, 0x116b0, 0x116b1, 0x116b2, 0x116b3, 0x116b4, 0x116b5, 0x116b6,
 9299|  16.5k|      0x116b7, 0x1171d, 0x1171e, 0x1171f, 0x11720, 0x11721, 0x11722, 0x11723,
 9300|  16.5k|      0x11724, 0x11725, 0x11726, 0x11727, 0x11728, 0x11729, 0x1172a, 0x1172b,
 9301|  16.5k|      0x1182c, 0x1182d, 0x1182e, 0x1182f, 0x11830, 0x11831, 0x11832, 0x11833,
 9302|  16.5k|      0x11834, 0x11835, 0x11836, 0x11837, 0x11838, 0x11839, 0x1183a, 0x11930,
 9303|  16.5k|      0x11931, 0x11932, 0x11933, 0x11934, 0x11935, 0x11937, 0x11938, 0x1193b,
 9304|  16.5k|      0x1193c, 0x1193d, 0x1193e, 0x11940, 0x11942, 0x11943, 0x119d1, 0x119d2,
 9305|  16.5k|      0x119d3, 0x119d4, 0x119d5, 0x119d6, 0x119d7, 0x119da, 0x119db, 0x119dc,
 9306|  16.5k|      0x119dd, 0x119de, 0x119df, 0x119e0, 0x119e4, 0x11a01, 0x11a02, 0x11a03,
 9307|  16.5k|      0x11a04, 0x11a05, 0x11a06, 0x11a07, 0x11a08, 0x11a09, 0x11a0a, 0x11a33,
 9308|  16.5k|      0x11a34, 0x11a35, 0x11a36, 0x11a37, 0x11a38, 0x11a39, 0x11a3b, 0x11a3c,
 9309|  16.5k|      0x11a3d, 0x11a3e, 0x11a47, 0x11a51, 0x11a52, 0x11a53, 0x11a54, 0x11a55,
 9310|  16.5k|      0x11a56, 0x11a57, 0x11a58, 0x11a59, 0x11a5a, 0x11a5b, 0x11a8a, 0x11a8b,
 9311|  16.5k|      0x11a8c, 0x11a8d, 0x11a8e, 0x11a8f, 0x11a90, 0x11a91, 0x11a92, 0x11a93,
 9312|  16.5k|      0x11a94, 0x11a95, 0x11a96, 0x11a97, 0x11a98, 0x11a99, 0x11c2f, 0x11c30,
 9313|  16.5k|      0x11c31, 0x11c32, 0x11c33, 0x11c34, 0x11c35, 0x11c36, 0x11c38, 0x11c39,
 9314|  16.5k|      0x11c3a, 0x11c3b, 0x11c3c, 0x11c3d, 0x11c3e, 0x11c3f, 0x11c92, 0x11c93,
 9315|  16.5k|      0x11c94, 0x11c95, 0x11c96, 0x11c97, 0x11c98, 0x11c99, 0x11c9a, 0x11c9b,
 9316|  16.5k|      0x11c9c, 0x11c9d, 0x11c9e, 0x11c9f, 0x11ca0, 0x11ca1, 0x11ca2, 0x11ca3,
 9317|  16.5k|      0x11ca4, 0x11ca5, 0x11ca6, 0x11ca7, 0x11ca9, 0x11caa, 0x11cab, 0x11cac,
 9318|  16.5k|      0x11cad, 0x11cae, 0x11caf, 0x11cb0, 0x11cb1, 0x11cb2, 0x11cb3, 0x11cb4,
 9319|  16.5k|      0x11cb5, 0x11cb6, 0x11d31, 0x11d32, 0x11d33, 0x11d34, 0x11d35, 0x11d36,
 9320|  16.5k|      0x11d3a, 0x11d3c, 0x11d3d, 0x11d3f, 0x11d40, 0x11d41, 0x11d42, 0x11d43,
 9321|  16.5k|      0x11d44, 0x11d45, 0x11d47, 0x11d8a, 0x11d8b, 0x11d8c, 0x11d8d, 0x11d8e,
 9322|  16.5k|      0x11d90, 0x11d91, 0x11d93, 0x11d94, 0x11d95, 0x11d96, 0x11d97, 0x11ef3,
 9323|  16.5k|      0x11ef4, 0x11ef5, 0x11ef6, 0x16af0, 0x16af1, 0x16af2, 0x16af3, 0x16af4,
 9324|  16.5k|      0x16b30, 0x16b31, 0x16b32, 0x16b33, 0x16b34, 0x16b35, 0x16b36, 0x16f4f,
 9325|  16.5k|      0x16f51, 0x16f52, 0x16f53, 0x16f54, 0x16f55, 0x16f56, 0x16f57, 0x16f58,
 9326|  16.5k|      0x16f59, 0x16f5a, 0x16f5b, 0x16f5c, 0x16f5d, 0x16f5e, 0x16f5f, 0x16f60,
 9327|  16.5k|      0x16f61, 0x16f62, 0x16f63, 0x16f64, 0x16f65, 0x16f66, 0x16f67, 0x16f68,
 9328|  16.5k|      0x16f69, 0x16f6a, 0x16f6b, 0x16f6c, 0x16f6d, 0x16f6e, 0x16f6f, 0x16f70,
 9329|  16.5k|      0x16f71, 0x16f72, 0x16f73, 0x16f74, 0x16f75, 0x16f76, 0x16f77, 0x16f78,
 9330|  16.5k|      0x16f79, 0x16f7a, 0x16f7b, 0x16f7c, 0x16f7d, 0x16f7e, 0x16f7f, 0x16f80,
 9331|  16.5k|      0x16f81, 0x16f82, 0x16f83, 0x16f84, 0x16f85, 0x16f86, 0x16f87, 0x16f8f,
 9332|  16.5k|      0x16f90, 0x16f91, 0x16f92, 0x16fe4, 0x16ff0, 0x16ff1, 0x1bc9d, 0x1bc9e,
 9333|  16.5k|      0x1d165, 0x1d166, 0x1d167, 0x1d168, 0x1d169, 0x1d16d, 0x1d16e, 0x1d16f,
 9334|  16.5k|      0x1d170, 0x1d171, 0x1d172, 0x1d17b, 0x1d17c, 0x1d17d, 0x1d17e, 0x1d17f,
 9335|  16.5k|      0x1d180, 0x1d181, 0x1d182, 0x1d185, 0x1d186, 0x1d187, 0x1d188, 0x1d189,
 9336|  16.5k|      0x1d18a, 0x1d18b, 0x1d1aa, 0x1d1ab, 0x1d1ac, 0x1d1ad, 0x1d242, 0x1d243,
 9337|  16.5k|      0x1d244, 0x1da00, 0x1da01, 0x1da02, 0x1da03, 0x1da04, 0x1da05, 0x1da06,
 9338|  16.5k|      0x1da07, 0x1da08, 0x1da09, 0x1da0a, 0x1da0b, 0x1da0c, 0x1da0d, 0x1da0e,
 9339|  16.5k|      0x1da0f, 0x1da10, 0x1da11, 0x1da12, 0x1da13, 0x1da14, 0x1da15, 0x1da16,
 9340|  16.5k|      0x1da17, 0x1da18, 0x1da19, 0x1da1a, 0x1da1b, 0x1da1c, 0x1da1d, 0x1da1e,
 9341|  16.5k|      0x1da1f, 0x1da20, 0x1da21, 0x1da22, 0x1da23, 0x1da24, 0x1da25, 0x1da26,
 9342|  16.5k|      0x1da27, 0x1da28, 0x1da29, 0x1da2a, 0x1da2b, 0x1da2c, 0x1da2d, 0x1da2e,
 9343|  16.5k|      0x1da2f, 0x1da30, 0x1da31, 0x1da32, 0x1da33, 0x1da34, 0x1da35, 0x1da36,
 9344|  16.5k|      0x1da3b, 0x1da3c, 0x1da3d, 0x1da3e, 0x1da3f, 0x1da40, 0x1da41, 0x1da42,
 9345|  16.5k|      0x1da43, 0x1da44, 0x1da45, 0x1da46, 0x1da47, 0x1da48, 0x1da49, 0x1da4a,
 9346|  16.5k|      0x1da4b, 0x1da4c, 0x1da4d, 0x1da4e, 0x1da4f, 0x1da50, 0x1da51, 0x1da52,
 9347|  16.5k|      0x1da53, 0x1da54, 0x1da55, 0x1da56, 0x1da57, 0x1da58, 0x1da59, 0x1da5a,
 9348|  16.5k|      0x1da5b, 0x1da5c, 0x1da5d, 0x1da5e, 0x1da5f, 0x1da60, 0x1da61, 0x1da62,
 9349|  16.5k|      0x1da63, 0x1da64, 0x1da65, 0x1da66, 0x1da67, 0x1da68, 0x1da69, 0x1da6a,
 9350|  16.5k|      0x1da6b, 0x1da6c, 0x1da75, 0x1da84, 0x1da9b, 0x1da9c, 0x1da9d, 0x1da9e,
 9351|  16.5k|      0x1da9f, 0x1daa1, 0x1daa2, 0x1daa3, 0x1daa4, 0x1daa5, 0x1daa6, 0x1daa7,
 9352|  16.5k|      0x1daa8, 0x1daa9, 0x1daaa, 0x1daab, 0x1daac, 0x1daad, 0x1daae, 0x1daaf,
 9353|  16.5k|      0x1e000, 0x1e001, 0x1e002, 0x1e003, 0x1e004, 0x1e005, 0x1e006, 0x1e008,
 9354|  16.5k|      0x1e009, 0x1e00a, 0x1e00b, 0x1e00c, 0x1e00d, 0x1e00e, 0x1e00f, 0x1e010,
 9355|  16.5k|      0x1e011, 0x1e012, 0x1e013, 0x1e014, 0x1e015, 0x1e016, 0x1e017, 0x1e018,
 9356|  16.5k|      0x1e01b, 0x1e01c, 0x1e01d, 0x1e01e, 0x1e01f, 0x1e020, 0x1e021, 0x1e023,
 9357|  16.5k|      0x1e024, 0x1e026, 0x1e027, 0x1e028, 0x1e029, 0x1e02a, 0x1e130, 0x1e131,
 9358|  16.5k|      0x1e132, 0x1e133, 0x1e134, 0x1e135, 0x1e136, 0x1e2ec, 0x1e2ed, 0x1e2ee,
 9359|  16.5k|      0x1e2ef, 0x1e8d0, 0x1e8d1, 0x1e8d2, 0x1e8d3, 0x1e8d4, 0x1e8d5, 0x1e8d6,
 9360|  16.5k|      0x1e944, 0x1e945, 0x1e946, 0x1e947, 0x1e948, 0x1e949, 0x1e94a, 0xe0100,
 9361|  16.5k|      0xe0101, 0xe0102, 0xe0103, 0xe0104, 0xe0105, 0xe0106, 0xe0107, 0xe0108,
 9362|  16.5k|      0xe0109, 0xe010a, 0xe010b, 0xe010c, 0xe010d, 0xe010e, 0xe010f, 0xe0110,
 9363|  16.5k|      0xe0111, 0xe0112, 0xe0113, 0xe0114, 0xe0115, 0xe0116, 0xe0117, 0xe0118,
 9364|  16.5k|      0xe0119, 0xe011a, 0xe011b, 0xe011c, 0xe011d, 0xe011e, 0xe011f, 0xe0120,
 9365|  16.5k|      0xe0121, 0xe0122, 0xe0123, 0xe0124, 0xe0125, 0xe0126, 0xe0127, 0xe0128,
 9366|  16.5k|      0xe0129, 0xe012a, 0xe012b, 0xe012c, 0xe012d, 0xe012e, 0xe012f, 0xe0130,
 9367|  16.5k|      0xe0131, 0xe0132, 0xe0133, 0xe0134, 0xe0135, 0xe0136, 0xe0137, 0xe0138,
 9368|  16.5k|      0xe0139, 0xe013a, 0xe013b, 0xe013c, 0xe013d, 0xe013e, 0xe013f, 0xe0140,
 9369|  16.5k|      0xe0141, 0xe0142, 0xe0143, 0xe0144, 0xe0145, 0xe0146, 0xe0147, 0xe0148,
 9370|  16.5k|      0xe0149, 0xe014a, 0xe014b, 0xe014c, 0xe014d, 0xe014e, 0xe014f, 0xe0150,
 9371|  16.5k|      0xe0151, 0xe0152, 0xe0153, 0xe0154, 0xe0155, 0xe0156, 0xe0157, 0xe0158,
 9372|  16.5k|      0xe0159, 0xe015a, 0xe015b, 0xe015c, 0xe015d, 0xe015e, 0xe015f, 0xe0160,
 9373|  16.5k|      0xe0161, 0xe0162, 0xe0163, 0xe0164, 0xe0165, 0xe0166, 0xe0167, 0xe0168,
 9374|  16.5k|      0xe0169, 0xe016a, 0xe016b, 0xe016c, 0xe016d, 0xe016e, 0xe016f, 0xe0170,
 9375|  16.5k|      0xe0171, 0xe0172, 0xe0173, 0xe0174, 0xe0175, 0xe0176, 0xe0177, 0xe0178,
 9376|  16.5k|      0xe0179, 0xe017a, 0xe017b, 0xe017c, 0xe017d, 0xe017e, 0xe017f, 0xe0180,
 9377|  16.5k|      0xe0181, 0xe0182, 0xe0183, 0xe0184, 0xe0185, 0xe0186, 0xe0187, 0xe0188,
 9378|  16.5k|      0xe0189, 0xe018a, 0xe018b, 0xe018c, 0xe018d, 0xe018e, 0xe018f, 0xe0190,
 9379|  16.5k|      0xe0191, 0xe0192, 0xe0193, 0xe0194, 0xe0195, 0xe0196, 0xe0197, 0xe0198,
 9380|  16.5k|      0xe0199, 0xe019a, 0xe019b, 0xe019c, 0xe019d, 0xe019e, 0xe019f, 0xe01a0,
 9381|  16.5k|      0xe01a1, 0xe01a2, 0xe01a3, 0xe01a4, 0xe01a5, 0xe01a6, 0xe01a7, 0xe01a8,
 9382|  16.5k|      0xe01a9, 0xe01aa, 0xe01ab, 0xe01ac, 0xe01ad, 0xe01ae, 0xe01af, 0xe01b0,
 9383|  16.5k|      0xe01b1, 0xe01b2, 0xe01b3, 0xe01b4, 0xe01b5, 0xe01b6, 0xe01b7, 0xe01b8,
 9384|  16.5k|      0xe01b9, 0xe01ba, 0xe01bb, 0xe01bc, 0xe01bd, 0xe01be, 0xe01bf, 0xe01c0,
 9385|  16.5k|      0xe01c1, 0xe01c2, 0xe01c3, 0xe01c4, 0xe01c5, 0xe01c6, 0xe01c7, 0xe01c8,
 9386|  16.5k|      0xe01c9, 0xe01ca, 0xe01cb, 0xe01cc, 0xe01cd, 0xe01ce, 0xe01cf, 0xe01d0,
 9387|  16.5k|      0xe01d1, 0xe01d2, 0xe01d3, 0xe01d4, 0xe01d5, 0xe01d6, 0xe01d7, 0xe01d8,
 9388|  16.5k|      0xe01d9, 0xe01da, 0xe01db, 0xe01dc, 0xe01dd, 0xe01de, 0xe01df, 0xe01e0,
 9389|  16.5k|      0xe01e1, 0xe01e2, 0xe01e3, 0xe01e4, 0xe01e5, 0xe01e6, 0xe01e7, 0xe01e8,
 9390|  16.5k|      0xe01e9, 0xe01ea, 0xe01eb, 0xe01ec, 0xe01ed, 0xe01ee, 0xe01ef};
 9391|  16.5k|  if (std::binary_search(std::begin(combining), std::end(combining),
  ------------------
  |  Branch (9391:7): [True: 61, False: 16.4k]
  ------------------
 9392|  16.5k|                         label.front())) {
 9393|     61|    return false;
 9394|     61|  }
 9395|       |  // We verify this next step as part of the mapping:
 9396|       |  // ---------------------------------------------
 9397|       |  // Each code point in the label must only have certain status values
 9398|       |  // according to Section 5, IDNA Mapping Table:
 9399|       |  // - For Transitional Processing, each value must be valid.
 9400|       |  // - For Nontransitional Processing, each value must be either valid or
 9401|       |  // deviation.
 9402|       |
 9403|       |  // If CheckJoiners, the label must satisfy the ContextJ rules from Appendix
 9404|       |  // A, in The Unicode Code Points and Internationalized Domain Names for
 9405|       |  // Applications (IDNA) [IDNA2008].
 9406|  16.4k|  constexpr static uint32_t virama[] = {
 9407|  16.4k|      0x094D,  0x09CD,  0x0A4D,  0x0ACD,  0x0B4D,  0x0BCD,  0x0C4D,  0x0CCD,
 9408|  16.4k|      0x0D3B,  0x0D3C,  0x0D4D,  0x0DCA,  0x0E3A,  0x0EBA,  0x0F84,  0x1039,
 9409|  16.4k|      0x103A,  0x1714,  0x1734,  0x17D2,  0x1A60,  0x1B44,  0x1BAA,  0x1BAB,
 9410|  16.4k|      0x1BF2,  0x1BF3,  0x2D7F,  0xA806,  0xA82C,  0xA8C4,  0xA953,  0xA9C0,
 9411|  16.4k|      0xAAF6,  0xABED,  0x10A3F, 0x11046, 0x1107F, 0x110B9, 0x11133, 0x11134,
 9412|  16.4k|      0x111C0, 0x11235, 0x112EA, 0x1134D, 0x11442, 0x114C2, 0x115BF, 0x1163F,
 9413|  16.4k|      0x116B6, 0x1172B, 0x11839, 0x1193D, 0x1193E, 0x119E0, 0x11A34, 0x11A47,
 9414|  16.4k|      0x11A99, 0x11C3F, 0x11D44, 0x11D45, 0x11D97};
 9415|  16.4k|  constexpr static uint32_t R[] = {
 9416|  16.4k|      0x622, 0x623, 0x624, 0x625, 0x627, 0x629, 0x62f, 0x630, 0x631,
 9417|  16.4k|      0x632, 0x648, 0x671, 0x672, 0x673, 0x675, 0x676, 0x677, 0x688,
 9418|  16.4k|      0x689, 0x68a, 0x68b, 0x68c, 0x68d, 0x68e, 0x68f, 0x690, 0x691,
 9419|  16.4k|      0x692, 0x693, 0x694, 0x695, 0x696, 0x697, 0x698, 0x699, 0x6c0,
 9420|  16.4k|      0x6c3, 0x6c4, 0x6c5, 0x6c6, 0x6c7, 0x6c8, 0x6c9, 0x6ca, 0x6cb,
 9421|  16.4k|      0x6cd, 0x6cf, 0x6d2, 0x6d3, 0x6d5, 0x6ee, 0x6ef, 0x710, 0x715,
 9422|  16.4k|      0x716, 0x717, 0x718, 0x719, 0x71e, 0x728, 0x72a, 0x72c, 0x72f,
 9423|  16.4k|      0x74d, 0x759, 0x75a, 0x75b, 0x854, 0x8aa, 0x8ab, 0x8ac};
 9424|  16.4k|  constexpr static uint32_t L[] = {0xa872};
 9425|  16.4k|  constexpr static uint32_t D[] = {
 9426|  16.4k|      0x620,  0x626,  0x628,  0x62a,  0x62b,  0x62c,  0x62d,  0x62e,  0x633,
 9427|  16.4k|      0x634,  0x635,  0x636,  0x637,  0x638,  0x639,  0x63a,  0x63b,  0x63c,
 9428|  16.4k|      0x63d,  0x63e,  0x63f,  0x641,  0x642,  0x643,  0x644,  0x645,  0x646,
 9429|  16.4k|      0x647,  0x649,  0x64a,  0x66e,  0x66f,  0x678,  0x679,  0x67a,  0x67b,
 9430|  16.4k|      0x67c,  0x67d,  0x67e,  0x67f,  0x680,  0x681,  0x682,  0x683,  0x684,
 9431|  16.4k|      0x685,  0x686,  0x687,  0x69a,  0x69b,  0x69c,  0x69d,  0x69e,  0x69f,
 9432|  16.4k|      0x6a0,  0x6a1,  0x6a2,  0x6a3,  0x6a4,  0x6a5,  0x6a6,  0x6a7,  0x6a8,
 9433|  16.4k|      0x6a9,  0x6aa,  0x6ab,  0x6ac,  0x6ad,  0x6ae,  0x6af,  0x6b0,  0x6b1,
 9434|  16.4k|      0x6b2,  0x6b3,  0x6b4,  0x6b5,  0x6b6,  0x6b7,  0x6b8,  0x6b9,  0x6ba,
 9435|  16.4k|      0x6bb,  0x6bc,  0x6bd,  0x6be,  0x6bf,  0x6c1,  0x6c2,  0x6cc,  0x6ce,
 9436|  16.4k|      0x6d0,  0x6d1,  0x6fa,  0x6fb,  0x6fc,  0x6ff,  0x712,  0x713,  0x714,
 9437|  16.4k|      0x71a,  0x71b,  0x71c,  0x71d,  0x71f,  0x720,  0x721,  0x722,  0x723,
 9438|  16.4k|      0x724,  0x725,  0x726,  0x727,  0x729,  0x72b,  0x72d,  0x72e,  0x74e,
 9439|  16.4k|      0x74f,  0x750,  0x751,  0x752,  0x753,  0x754,  0x755,  0x756,  0x757,
 9440|  16.4k|      0x758,  0x75c,  0x75d,  0x75e,  0x75f,  0x760,  0x761,  0x762,  0x763,
 9441|  16.4k|      0x764,  0x765,  0x766,  0x850,  0x851,  0x852,  0x853,  0x855,  0x8a0,
 9442|  16.4k|      0x8a2,  0x8a3,  0x8a4,  0x8a5,  0x8a6,  0x8a7,  0x8a8,  0x8a9,  0x1807,
 9443|  16.4k|      0x1820, 0x1821, 0x1822, 0x1823, 0x1824, 0x1825, 0x1826, 0x1827, 0x1828,
 9444|  16.4k|      0x1829, 0x182a, 0x182b, 0x182c, 0x182d, 0x182e, 0x182f, 0x1830, 0x1831,
 9445|  16.4k|      0x1832, 0x1833, 0x1834, 0x1835, 0x1836, 0x1837, 0x1838, 0x1839, 0x183a,
 9446|  16.4k|      0x183b, 0x183c, 0x183d, 0x183e, 0x183f, 0x1840, 0x1841, 0x1842, 0x1843,
 9447|  16.4k|      0x1844, 0x1845, 0x1846, 0x1847, 0x1848, 0x1849, 0x184a, 0x184b, 0x184c,
 9448|  16.4k|      0x184d, 0x184e, 0x184f, 0x1850, 0x1851, 0x1852, 0x1853, 0x1854, 0x1855,
 9449|  16.4k|      0x1856, 0x1857, 0x1858, 0x1859, 0x185a, 0x185b, 0x185c, 0x185d, 0x185e,
 9450|  16.4k|      0x185f, 0x1860, 0x1861, 0x1862, 0x1863, 0x1864, 0x1865, 0x1866, 0x1867,
 9451|  16.4k|      0x1868, 0x1869, 0x186a, 0x186b, 0x186c, 0x186d, 0x186e, 0x186f, 0x1870,
 9452|  16.4k|      0x1871, 0x1872, 0x1873, 0x1874, 0x1875, 0x1876, 0x1877, 0x1887, 0x1888,
 9453|  16.4k|      0x1889, 0x188a, 0x188b, 0x188c, 0x188d, 0x188e, 0x188f, 0x1890, 0x1891,
 9454|  16.4k|      0x1892, 0x1893, 0x1894, 0x1895, 0x1896, 0x1897, 0x1898, 0x1899, 0x189a,
 9455|  16.4k|      0x189b, 0x189c, 0x189d, 0x189e, 0x189f, 0x18a0, 0x18a1, 0x18a2, 0x18a3,
 9456|  16.4k|      0x18a4, 0x18a5, 0x18a6, 0x18a7, 0x18a8, 0x18aa, 0xa840, 0xa841, 0xa842,
 9457|  16.4k|      0xa843, 0xa844, 0xa845, 0xa846, 0xa847, 0xa848, 0xa849, 0xa84a, 0xa84b,
 9458|  16.4k|      0xa84c, 0xa84d, 0xa84e, 0xa84f, 0xa850, 0xa851, 0xa852, 0xa853, 0xa854,
 9459|  16.4k|      0xa855, 0xa856, 0xa857, 0xa858, 0xa859, 0xa85a, 0xa85b, 0xa85c, 0xa85d,
 9460|  16.4k|      0xa85e, 0xa85f, 0xa860, 0xa861, 0xa862, 0xa863, 0xa864, 0xa865, 0xa866,
 9461|  16.4k|      0xa867, 0xa868, 0xa869, 0xa86a, 0xa86b, 0xa86c, 0xa86d, 0xa86e, 0xa86f,
 9462|  16.4k|      0xa870, 0xa871};
 9463|       |
 9464|   168k|  for (size_t i = 0; i < label.size(); i++) {
  ------------------
  |  Branch (9464:22): [True: 153k, False: 14.3k]
  ------------------
 9465|   153k|    uint32_t c = label[i];
 9466|   153k|    if (c == 0x200c) {
  ------------------
  |  Branch (9466:9): [True: 1.64k, False: 151k]
  ------------------
 9467|  1.64k|      if (i > 0) {
  ------------------
  |  Branch (9467:11): [True: 1.63k, False: 6]
  ------------------
 9468|  1.63k|        if (std::binary_search(std::begin(virama), std::end(virama),
  ------------------
  |  Branch (9468:13): [True: 256, False: 1.38k]
  ------------------
 9469|  1.63k|                               label[i - 1])) {
 9470|    256|          return true;
 9471|    256|        }
 9472|  1.63k|      }
 9473|  1.38k|      if ((i == 0) || (i + 1 >= label.size())) {
  ------------------
  |  Branch (9473:11): [True: 6, False: 1.38k]
  |  Branch (9473:23): [True: 69, False: 1.31k]
  ------------------
 9474|     75|        return false;
 9475|     75|      }
 9476|       |      // we go backward looking for L or D
 9477|  1.31k|      auto is_l_or_d = [](uint32_t code) {
 9478|  1.31k|        return std::binary_search(std::begin(L), std::end(L), code) ||
 9479|  1.31k|               std::binary_search(std::begin(D), std::end(D), code);
 9480|  1.31k|      };
 9481|  1.31k|      auto is_r_or_d = [](uint32_t code) {
 9482|  1.31k|        return std::binary_search(std::begin(R), std::end(R), code) ||
 9483|  1.31k|               std::binary_search(std::begin(D), std::end(D), code);
 9484|  1.31k|      };
 9485|  1.31k|      std::u32string_view before = label.substr(0, i);
 9486|  1.31k|      std::u32string_view after = label.substr(i + 1);
 9487|  1.31k|      return (std::find_if(before.begin(), before.end(), is_l_or_d) !=
  ------------------
  |  Branch (9487:14): [True: 1.25k, False: 60]
  ------------------
 9488|  1.31k|              before.end()) &&
 9489|  1.25k|             (std::find_if(after.begin(), after.end(), is_r_or_d) !=
  ------------------
  |  Branch (9489:14): [True: 1.15k, False: 99]
  ------------------
 9490|  1.25k|              after.end());
 9491|   151k|    } else if (c == 0x200d) {
  ------------------
  |  Branch (9491:16): [True: 426, False: 151k]
  ------------------
 9492|    426|      if (i > 0) {
  ------------------
  |  Branch (9492:11): [True: 423, False: 3]
  ------------------
 9493|    423|        if (std::binary_search(std::begin(virama), std::end(virama),
  ------------------
  |  Branch (9493:13): [True: 361, False: 62]
  ------------------
 9494|    423|                               label[i - 1])) {
 9495|    361|          return true;
 9496|    361|        }
 9497|    423|      }
 9498|     65|      return false;
 9499|    426|    }
 9500|   153k|  }
 9501|       |
 9502|       |  // If CheckBidi, and if the domain name is a  Bidi domain name, then the label
 9503|       |  // must satisfy all six of the numbered conditions in [IDNA2008] RFC 5893,
 9504|       |  // Section 2.
 9505|       |
 9506|       |  // The following rule, consisting of six conditions, applies to labels
 9507|       |  // in Bidi domain names.  The requirements that this rule satisfies are
 9508|       |  // described in Section 3.  All of the conditions must be satisfied for
 9509|       |  // the rule to be satisfied.
 9510|       |  //
 9511|       |  //  1.  The first character must be a character with Bidi property L, R,
 9512|       |  //     or AL.  If it has the R or AL property, it is an RTL label; if it
 9513|       |  //     has the L property, it is an LTR label.
 9514|       |  //
 9515|       |  //  2.  In an RTL label, only characters with the Bidi properties R, AL,
 9516|       |  //      AN, EN, ES, CS, ET, ON, BN, or NSM are allowed.
 9517|       |  //
 9518|       |  //   3.  In an RTL label, the end of the label must be a character with
 9519|       |  //       Bidi property R, AL, EN, or AN, followed by zero or more
 9520|       |  //       characters with Bidi property NSM.
 9521|       |  //
 9522|       |  //   4.  In an RTL label, if an EN is present, no AN may be present, and
 9523|       |  //       vice versa.
 9524|       |  //
 9525|       |  //  5.  In an LTR label, only characters with the Bidi properties L, EN,
 9526|       |  //       ES, CS, ET, ON, BN, or NSM are allowed.
 9527|       |  //
 9528|       |  //   6.  In an LTR label, the end of the label must be a character with
 9529|       |  //       Bidi property L or EN, followed by zero or more characters with
 9530|       |  //       Bidi property NSM.
 9531|       |
 9532|  14.3k|  size_t last_non_nsm_char = find_last_not_of_nsm(label);
 9533|  14.3k|  if (last_non_nsm_char == std::u32string_view::npos) {
  ------------------
  |  Branch (9533:7): [True: 0, False: 14.3k]
  ------------------
 9534|      0|    return false;
 9535|      0|  }
 9536|       |
 9537|       |  // A "Bidi domain name" is a domain name that contains at least one RTL label.
 9538|       |  // The following rule, consisting of six conditions, applies to labels in Bidi
 9539|       |  // domain names.
 9540|  14.3k|  if (is_rtl_label(label)) {
  ------------------
  |  Branch (9540:7): [True: 2.99k, False: 11.3k]
  ------------------
 9541|       |    // The first character must be a character with Bidi property L, R,
 9542|       |    // or AL. If it has the R or AL property, it is an RTL label; if it
 9543|       |    // has the L property, it is an LTR label.
 9544|       |
 9545|  2.99k|    if (find_direction(label[0]) == direction::L) {
  ------------------
  |  Branch (9545:9): [True: 206, False: 2.78k]
  ------------------
 9546|       |      // Eval as LTR
 9547|       |
 9548|       |      // In an LTR label, only characters with the Bidi properties L, EN,
 9549|       |      // ES, CS, ET, ON, BN, or NSM are allowed.
 9550|  3.05k|      for (size_t i = 0; i <= last_non_nsm_char; i++) {
  ------------------
  |  Branch (9550:26): [True: 3.05k, False: 0]
  ------------------
 9551|  3.05k|        const direction d = find_direction(label[i]);
 9552|  3.05k|        if (!(d == direction::L || d == direction::EN || d == direction::ES ||
  ------------------
  |  Branch (9552:15): [True: 923, False: 2.12k]
  |  Branch (9552:36): [True: 220, False: 1.90k]
  |  Branch (9552:58): [True: 386, False: 1.52k]
  ------------------
 9553|  1.52k|              d == direction::CS || d == direction::ET || d == direction::ON ||
  ------------------
  |  Branch (9553:15): [True: 274, False: 1.24k]
  |  Branch (9553:37): [True: 222, False: 1.02k]
  |  Branch (9553:59): [True: 218, False: 809]
  ------------------
 9554|    809|              d == direction::BN || d == direction::NSM)) {
  ------------------
  |  Branch (9554:15): [True: 405, False: 404]
  |  Branch (9554:37): [True: 198, False: 206]
  ------------------
 9555|    206|          return false;
 9556|    206|        }
 9557|  3.05k|      }
 9558|       |
 9559|      0|      const direction last_dir = find_direction(label[last_non_nsm_char]);
 9560|      0|      if (!(last_dir == direction::L || last_dir == direction::EN)) {
  ------------------
  |  Branch (9560:13): [True: 0, False: 0]
  |  Branch (9560:41): [True: 0, False: 0]
  ------------------
 9561|      0|        return false;
 9562|      0|      }
 9563|       |
 9564|      0|      return true;
 9565|       |
 9566|  2.78k|    } else {
 9567|       |      // Eval as RTL
 9568|       |
 9569|  2.78k|      bool has_an = false;
 9570|  2.78k|      bool has_en = false;
 9571|  13.6k|      for (size_t i = 0; i <= last_non_nsm_char; i++) {
  ------------------
  |  Branch (9571:26): [True: 10.9k, False: 2.62k]
  ------------------
 9572|  10.9k|        const direction d = find_direction(label[i]);
 9573|       |
 9574|       |        // In an RTL label, if an EN is present, no AN may be present, and vice
 9575|       |        // versa.
 9576|  10.9k|        if ((d == direction::EN && ((has_en = true) && has_an)) ||
  ------------------
  |  Branch (9576:14): [True: 1.10k, False: 9.88k]
  |  Branch (9576:37): [True: 1.10k, False: 0]
  |  Branch (9576:56): [True: 1, False: 1.10k]
  ------------------
 9577|  10.9k|            (d == direction::AN && ((has_an = true) && has_en))) {
  ------------------
  |  Branch (9577:14): [True: 1.18k, False: 9.80k]
  |  Branch (9577:37): [True: 1.18k, False: 0]
  |  Branch (9577:56): [True: 2, False: 1.18k]
  ------------------
 9578|      3|          return false;
 9579|      3|        }
 9580|       |
 9581|  10.9k|        if (!(d == direction::R || d == direction::AL || d == direction::AN ||
  ------------------
  |  Branch (9581:15): [True: 1.53k, False: 9.45k]
  |  Branch (9581:36): [True: 3.06k, False: 6.39k]
  |  Branch (9581:58): [True: 1.18k, False: 5.20k]
  ------------------
 9582|  5.20k|              d == direction::EN || d == direction::ES || d == direction::CS ||
  ------------------
  |  Branch (9582:15): [True: 1.10k, False: 4.10k]
  |  Branch (9582:37): [True: 779, False: 3.32k]
  |  Branch (9582:59): [True: 360, False: 2.96k]
  ------------------
 9583|  2.96k|              d == direction::ET || d == direction::ON || d == direction::BN ||
  ------------------
  |  Branch (9583:15): [True: 665, False: 2.30k]
  |  Branch (9583:37): [True: 1.11k, False: 1.18k]
  |  Branch (9583:59): [True: 586, False: 600]
  ------------------
 9584|    600|              d == direction::NSM)) {
  ------------------
  |  Branch (9584:15): [True: 470, False: 130]
  ------------------
 9585|    130|          return false;
 9586|    130|        }
 9587|       |
 9588|  10.8k|        if (i == last_non_nsm_char &&
  ------------------
  |  Branch (9588:13): [True: 2.65k, False: 8.19k]
  ------------------
 9589|  2.65k|            !(d == direction::R || d == direction::AL || d == direction::AN ||
  ------------------
  |  Branch (9589:15): [True: 793, False: 1.86k]
  |  Branch (9589:36): [True: 1.06k, False: 795]
  |  Branch (9589:58): [True: 548, False: 247]
  ------------------
 9590|    247|              d == direction::EN)) {
  ------------------
  |  Branch (9590:15): [True: 220, False: 27]
  ------------------
 9591|     27|          return false;
 9592|     27|        }
 9593|  10.8k|      }
 9594|       |
 9595|  2.62k|      return true;
 9596|  2.78k|    }
 9597|  2.99k|  }
 9598|       |
 9599|  11.3k|  return true;
 9600|  14.3k|}
_ZN3ada4idna36contains_forbidden_domain_code_pointENSt3__117basic_string_viewIcNS1_11char_traitsIcEEEE:
 9654|  3.69k|bool contains_forbidden_domain_code_point(std::string_view view) {
 9655|  3.69k|  return std::ranges::any_of(view, is_forbidden_domain_code_point);
 9656|  3.69k|}
_ZN3ada4idna8to_asciiENSt3__117basic_string_viewIcNS1_11char_traitsIcEEEE:
 9726|  9.07k|std::string to_ascii(std::string_view ut8_string) {
 9727|  9.07k|  if (is_ascii(ut8_string)) {
  ------------------
  |  Branch (9727:7): [True: 6.57k, False: 2.49k]
  ------------------
 9728|  6.57k|    return from_ascii_to_ascii(ut8_string);
 9729|  6.57k|  }
 9730|  2.49k|  static const std::string error = "";
 9731|       |  // We convert to UTF-32
 9732|       |
 9733|       |#ifdef ADA_USE_SIMDUTF
 9734|       |  size_t utf32_length =
 9735|       |      simdutf::utf32_length_from_utf8(ut8_string.data(), ut8_string.size());
 9736|       |  std::u32string utf32(utf32_length, '\0');
 9737|       |  size_t actual_utf32_length = simdutf::convert_utf8_to_utf32(
 9738|       |      ut8_string.data(), ut8_string.size(), utf32.data());
 9739|       |#else
 9740|  2.49k|  size_t utf32_length =
 9741|  2.49k|      ada::idna::utf32_length_from_utf8(ut8_string.data(), ut8_string.size());
 9742|  2.49k|  std::u32string utf32(utf32_length, '\0');
 9743|  2.49k|  size_t actual_utf32_length = ada::idna::utf8_to_utf32(
 9744|  2.49k|      ut8_string.data(), ut8_string.size(), utf32.data());
 9745|  2.49k|#endif
 9746|  2.49k|  if (actual_utf32_length == 0) {
  ------------------
  |  Branch (9746:7): [True: 195, False: 2.30k]
  ------------------
 9747|    195|    return error;
 9748|    195|  }
 9749|       |  // mapping: use the two-argument overload to avoid an extra heap allocation
 9750|       |  // that the single-argument overload (which returns by value) would incur.
 9751|  2.30k|  std::u32string tmp_buffer;
 9752|  2.30k|  std::u32string post_map;
 9753|  2.30k|  if (!ada::idna::map(utf32, tmp_buffer)) {
  ------------------
  |  Branch (9753:7): [True: 25, False: 2.27k]
  ------------------
 9754|     25|    return error;
 9755|     25|  }
 9756|  2.27k|  utf32 = std::move(tmp_buffer);
 9757|  2.27k|  normalize(utf32);
 9758|  2.27k|  std::string out;
 9759|  2.27k|  out.reserve(ut8_string.size());
 9760|  2.27k|  size_t label_start = 0;
 9761|       |
 9762|  8.16k|  while (label_start != utf32.size()) {
  ------------------
  |  Branch (9762:10): [True: 6.90k, False: 1.26k]
  ------------------
 9763|  6.90k|    size_t loc_dot = utf32.find('.', label_start);
 9764|  6.90k|    bool is_last_label = (loc_dot == std::string_view::npos);
 9765|  6.90k|    size_t label_size =
 9766|  6.90k|        is_last_label ? utf32.size() - label_start : loc_dot - label_start;
  ------------------
  |  Branch (9766:9): [True: 2.16k, False: 4.73k]
  ------------------
 9767|  6.90k|    size_t label_size_with_dot = is_last_label ? label_size : label_size + 1;
  ------------------
  |  Branch (9767:34): [True: 2.16k, False: 4.73k]
  ------------------
 9768|  6.90k|    std::u32string_view label_view(utf32.data() + label_start, label_size);
 9769|  6.90k|    label_start += label_size_with_dot;
 9770|  6.90k|    if (label_size == 0) {
  ------------------
  |  Branch (9770:9): [True: 926, False: 5.97k]
  ------------------
 9771|       |      // empty label? Nothing to do.
 9772|  5.97k|    } else if (label_view.starts_with(U"xn--")) {
  ------------------
  |  Branch (9772:16): [True: 1.41k, False: 4.55k]
  ------------------
 9773|       |      // we do not need to check, e.g., Xn-- because mapping goes to lower case
 9774|       |      // Validate first, then bulk-copy with a single resize to avoid per-char
 9775|       |      // capacity checks in operator+=.
 9776|  28.5k|      for (char32_t c : label_view) {
  ------------------
  |  Branch (9776:23): [True: 28.5k, False: 1.39k]
  ------------------
 9777|  28.5k|        if (c >= 0x80) {
  ------------------
  |  Branch (9777:13): [True: 22, False: 28.5k]
  ------------------
 9778|     22|          return error;
 9779|     22|        }
 9780|  28.5k|      }
 9781|  1.39k|      size_t label_out_start = out.size();
 9782|  1.39k|      out.resize(label_out_start + label_size);
 9783|  1.39k|      char* dest = out.data() + label_out_start;
 9784|  28.4k|      for (char32_t c : label_view) {
  ------------------
  |  Branch (9784:23): [True: 28.4k, False: 1.39k]
  ------------------
 9785|  28.4k|        *dest++ = static_cast<char>(c);
 9786|  28.4k|      }
 9787|  1.39k|      std::string_view puny_segment_ascii(out.data() + label_out_start + 4,
 9788|  1.39k|                                          label_size - 4);
 9789|  1.39k|      tmp_buffer.clear();
 9790|  1.39k|      bool is_ok = ada::idna::punycode_to_utf32(puny_segment_ascii, tmp_buffer);
 9791|  1.39k|      if (!is_ok) {
  ------------------
  |  Branch (9791:11): [True: 24, False: 1.37k]
  ------------------
 9792|     24|        return error;
 9793|     24|      }
 9794|       |      // If the input is just ASCII, it should not have been encoded
 9795|       |      // as punycode.
 9796|       |      // https://github.com/whatwg/url/issues/760
 9797|  1.37k|      if (is_ascii(tmp_buffer)) {
  ------------------
  |  Branch (9797:11): [True: 66, False: 1.30k]
  ------------------
 9798|     66|        return error;
 9799|     66|      }
 9800|  1.30k|      if (!ada::idna::map(tmp_buffer, post_map)) {
  ------------------
  |  Branch (9800:11): [True: 73, False: 1.23k]
  ------------------
 9801|     73|        return error;
 9802|     73|      }
 9803|  1.23k|      if (tmp_buffer != post_map) {
  ------------------
  |  Branch (9803:11): [True: 105, False: 1.12k]
  ------------------
 9804|    105|        return error;
 9805|    105|      }
 9806|  1.12k|      normalize(post_map);
 9807|  1.12k|      if (post_map != tmp_buffer) {
  ------------------
  |  Branch (9807:11): [True: 48, False: 1.07k]
  ------------------
 9808|     48|        return error;
 9809|     48|      }
 9810|  1.07k|      if (post_map.empty()) {
  ------------------
  |  Branch (9810:11): [True: 0, False: 1.07k]
  ------------------
 9811|      0|        return error;
 9812|      0|      }
 9813|  1.07k|      if (!is_label_valid(post_map)) {
  ------------------
  |  Branch (9813:11): [True: 13, False: 1.06k]
  ------------------
 9814|     13|        return error;
 9815|     13|      }
 9816|  4.55k|    } else {
 9817|       |      // The fast path here is an ascii label.
 9818|  4.55k|      if (is_ascii(label_view)) {
  ------------------
  |  Branch (9818:11): [True: 387, False: 4.17k]
  ------------------
 9819|       |        // no validation needed; bulk-copy with single resize.
 9820|    387|        size_t old_size = out.size();
 9821|    387|        out.resize(old_size + label_size);
 9822|    387|        char* dest = out.data() + old_size;
 9823|  1.58k|        for (char32_t c : label_view) {
  ------------------
  |  Branch (9823:25): [True: 1.58k, False: 387]
  ------------------
 9824|  1.58k|          *dest++ = static_cast<char>(c);
 9825|  1.58k|        }
 9826|  4.17k|      } else {
 9827|       |        // slow path.
 9828|       |        // first check validity.
 9829|  4.17k|        if (!is_label_valid(label_view)) {
  ------------------
  |  Branch (9829:13): [True: 659, False: 3.51k]
  ------------------
 9830|    659|          return error;
 9831|    659|        }
 9832|       |        // It is valid! So now we must encode it as punycode...
 9833|  3.51k|        out.append("xn--");
 9834|  3.51k|        bool is_ok = ada::idna::utf32_to_punycode(label_view, out);
 9835|  3.51k|        if (!is_ok) {
  ------------------
  |  Branch (9835:13): [True: 0, False: 3.51k]
  ------------------
 9836|      0|          return error;
 9837|      0|        }
 9838|  3.51k|      }
 9839|  4.55k|    }
 9840|  5.89k|    if (!is_last_label) {
  ------------------
  |  Branch (9840:9): [True: 4.68k, False: 1.20k]
  ------------------
 9841|  4.68k|      out.push_back('.');
 9842|  4.68k|    }
 9843|  5.89k|  }
 9844|  1.26k|  return out;
 9845|  2.27k|}
_ZN3ada4idna10to_unicodeENSt3__117basic_string_viewIcNS1_11char_traitsIcEEEE:
 9859|  9.05k|std::string to_unicode(std::string_view input) {
 9860|  9.05k|  std::string output;
 9861|  9.05k|  output.reserve(input.size());
 9862|       |
 9863|  9.05k|  size_t label_start = 0;
 9864|  9.05k|  std::u32string tmp_buffer;
 9865|  9.05k|  std::u32string post_map;
 9866|  43.8k|  while (label_start < input.size()) {
  ------------------
  |  Branch (9866:10): [True: 34.8k, False: 9.05k]
  ------------------
 9867|  34.8k|    size_t loc_dot = input.find('.', label_start);
 9868|  34.8k|    bool is_last_label = (loc_dot == std::string_view::npos);
 9869|  34.8k|    size_t label_size =
 9870|  34.8k|        is_last_label ? input.size() - label_start : loc_dot - label_start;
  ------------------
  |  Branch (9870:9): [True: 8.64k, False: 26.1k]
  ------------------
 9871|  34.8k|    auto label_view = std::string_view(input.data() + label_start, label_size);
 9872|       |
 9873|  34.8k|    if (label_view.starts_with("xn--") && ada::idna::is_ascii(label_view)) {
  ------------------
  |  Branch (9873:9): [True: 10.9k, False: 23.8k]
  |  Branch (9873:43): [True: 9.56k, False: 1.41k]
  ------------------
 9874|  9.56k|      label_view.remove_prefix(4);
 9875|  9.56k|      tmp_buffer.clear();
 9876|  9.56k|      if (ada::idna::punycode_to_utf32(label_view, tmp_buffer)) {
  ------------------
  |  Branch (9876:11): [True: 7.81k, False: 1.75k]
  ------------------
 9877|       |        // Per UTS #46, the decoded label must be re-validated. Reject decodings
 9878|       |        // that are pure ASCII (xn-- encoding of an ASCII-only label), or whose
 9879|       |        // mapping/normalization is not stable, or that fail label validity.
 9880|  7.81k|        bool accept_decoded = true;
 9881|  7.81k|        if (ada::idna::is_ascii(tmp_buffer)) {
  ------------------
  |  Branch (9881:13): [True: 936, False: 6.88k]
  ------------------
 9882|    936|          accept_decoded = false;
 9883|  6.88k|        } else {
 9884|  6.88k|          post_map.clear();
 9885|  6.88k|          if (!ada::idna::map(tmp_buffer, post_map) || post_map != tmp_buffer) {
  ------------------
  |  Branch (9885:15): [True: 952, False: 5.92k]
  |  Branch (9885:56): [True: 164, False: 5.76k]
  ------------------
 9886|  1.11k|            accept_decoded = false;
 9887|  5.76k|          } else {
 9888|  5.76k|            ada::idna::normalize(post_map);
 9889|  5.76k|            if (post_map != tmp_buffer || post_map.empty() ||
  ------------------
  |  Branch (9889:17): [True: 62, False: 5.70k]
  |  Branch (9889:43): [True: 0, False: 5.70k]
  ------------------
 9890|  5.70k|                !ada::idna::is_label_valid(post_map)) {
  ------------------
  |  Branch (9890:17): [True: 36, False: 5.66k]
  ------------------
 9891|     98|              accept_decoded = false;
 9892|     98|            }
 9893|  5.76k|          }
 9894|  6.88k|        }
 9895|       |
 9896|  7.81k|        if (accept_decoded) {
  ------------------
  |  Branch (9896:13): [True: 5.66k, False: 2.15k]
  ------------------
 9897|       |#ifdef ADA_USE_SIMDUTF
 9898|       |          auto utf8_size = simdutf::utf8_length_from_utf32(tmp_buffer.data(),
 9899|       |                                                           tmp_buffer.size());
 9900|       |          size_t old_size = output.size();
 9901|       |          output.resize(old_size + utf8_size);
 9902|       |          simdutf::convert_utf32_to_utf8(tmp_buffer.data(), tmp_buffer.size(),
 9903|       |                                         output.data() + old_size);
 9904|       |#else
 9905|  5.66k|          auto utf8_size = ada::idna::utf8_length_from_utf32(tmp_buffer.data(),
 9906|  5.66k|                                                             tmp_buffer.size());
 9907|  5.66k|          size_t old_size = output.size();
 9908|  5.66k|          output.resize(old_size + utf8_size);
 9909|  5.66k|          ada::idna::utf32_to_utf8(tmp_buffer.data(), tmp_buffer.size(),
 9910|  5.66k|                                   output.data() + old_size);
 9911|  5.66k|#endif
 9912|  5.66k|        } else {
 9913|       |          // ToUnicode never fails. If any step fails, return the original
 9914|       |          // input sequence for the label.
 9915|  2.15k|          output.append(
 9916|  2.15k|              std::string_view(input.data() + label_start, label_size));
 9917|  2.15k|        }
 9918|  7.81k|      } else {
 9919|       |        // ToUnicode never fails.  If any step fails, then the original input
 9920|       |        // sequence is returned immediately in that step.
 9921|  1.75k|        output.append(std::string_view(input.data() + label_start, label_size));
 9922|  1.75k|      }
 9923|  25.2k|    } else {
 9924|  25.2k|      output.append(label_view);
 9925|  25.2k|    }
 9926|       |
 9927|  34.8k|    if (!is_last_label) {
  ------------------
  |  Branch (9927:9): [True: 26.1k, False: 8.64k]
  ------------------
 9928|  26.1k|      output.push_back('.');
 9929|  26.1k|    }
 9930|       |
 9931|  34.8k|    label_start += label_size + 1;
 9932|  34.8k|  }
 9933|       |
 9934|  9.05k|  return output;
 9935|  9.05k|}
idna.cc:_ZZN3ada4idna22utf32_length_from_utf8EPKcmENK3$_0clEa:
  263|   469k|  return std::count_if(p, std::next(p, len), [](int8_t c) {
  264|       |    // -65 is 0b10111111, anything larger in two-complement's
  265|       |    // should start a new code point.
  266|   469k|    return c > -65;
  267|   469k|  });
idna.cc:_ZZN3ada4idna9ascii_mapEPcmENK3$_0clEh:
 2838|  37.0k|  auto broadcast = [](uint8_t v) -> uint64_t {
 2839|  37.0k|    return 0x101010101010101ull * v;
 2840|  37.0k|  };
idna.cc:_ZN3ada4idnaL11idna_lookupEj:
 2786|   315k|static uint16_t idna_lookup(uint32_t cp) noexcept {
 2787|       |  // -- Two-level table covers the full active code-point range ---------------
 2788|   315k|  if (cp < IDNA_LOW_RANGE_END) {
  ------------------
  |  Branch (2788:7): [True: 314k, False: 588]
  ------------------
 2789|   314k|    uint16_t ref = idna_stage1[cp >> IDNA_BLOCK_BITS];
 2790|   314k|    if (ref & IDNA_BOOL_FLAG) {
  ------------------
  |  Branch (2790:9): [True: 143k, False: 170k]
  ------------------
 2791|       |      // Boolean block: one bit per code point, 1 = VALID, 0 = DISALLOWED.
 2792|   143k|      uint32_t bit_idx =
 2793|   143k|          static_cast<uint32_t>(ref & ~IDNA_BOOL_FLAG) * IDNA_BLOCK_SIZE +
 2794|   143k|          (cp & IDNA_BLOCK_MASK);
 2795|   143k|      bool is_valid = (idna_bool_blocks[bit_idx >> 6] >> (bit_idx & 63u)) & 1u;
 2796|   143k|      return is_valid ? IDNA_VALID : IDNA_DISALLOWED;
  ------------------
  |  Branch (2796:14): [True: 143k, False: 228]
  ------------------
 2797|   143k|    }
 2798|   170k|    return idna_stage2[ref + (cp & IDNA_BLOCK_MASK)];
 2799|   314k|  }
 2800|       |
 2801|       |  // -- Variation selectors supplement (U+E0100-U+E01EF): all ignored ---------
 2802|       |  // Everything else above IDNA_LOW_RANGE_END is disallowed.
 2803|    588|  if (cp >= IDNA_HIGH_IGNORED_START && cp < IDNA_HIGH_IGNORED_END) {
  ------------------
  |  Branch (2803:7): [True: 529, False: 59]
  |  Branch (2803:40): [True: 0, False: 529]
  ------------------
 2804|      0|    return IDNA_IGNORED;
 2805|      0|  }
 2806|       |
 2807|    588|  return IDNA_DISALLOWED;
 2808|    588|}
idna.cc:_ZN3ada4idnaL9utf8_nextERPKh:
 2813|   297k|static char32_t utf8_next(const uint8_t*& ptr) noexcept {
 2814|   297k|  uint8_t b0 = *ptr++;
 2815|   297k|  if (b0 < 0x80u) return static_cast<char32_t>(b0);
  ------------------
  |  Branch (2815:7): [True: 81.7k, False: 215k]
  ------------------
 2816|   215k|  if (b0 < 0xE0u) {
  ------------------
  |  Branch (2816:7): [True: 198k, False: 17.0k]
  ------------------
 2817|   198k|    uint32_t cp = (b0 & 0x1Fu) << 6;
 2818|   198k|    cp |= (*ptr++ & 0x3Fu);
 2819|   198k|    return static_cast<char32_t>(cp);
 2820|   198k|  }
 2821|  17.0k|  if (b0 < 0xF0u) {
  ------------------
  |  Branch (2821:7): [True: 16.1k, False: 906]
  ------------------
 2822|  16.1k|    uint32_t cp = (b0 & 0x0Fu) << 12;
 2823|  16.1k|    cp |= ((*ptr++ & 0x3Fu) << 6);
 2824|  16.1k|    cp |= (*ptr++ & 0x3Fu);
 2825|  16.1k|    return static_cast<char32_t>(cp);
 2826|  16.1k|  }
 2827|       |  // 4-byte sequence
 2828|    906|  uint32_t cp = (b0 & 0x07u) << 18;
 2829|    906|  cp |= ((*ptr++ & 0x3Fu) << 12);
 2830|    906|  cp |= ((*ptr++ & 0x3Fu) << 6);
 2831|    906|  cp |= (*ptr++ & 0x3Fu);
 2832|    906|  return static_cast<char32_t>(cp);
 2833|  17.0k|}
idna.cc:_ZN3ada4idnaL19char_to_digit_valueEc:
 8040|   260k|static constexpr int32_t char_to_digit_value(char value) {
 8041|   260k|  if (value >= 'a' && value <= 'z') return value - 'a';
  ------------------
  |  Branch (8041:7): [True: 214k, False: 46.1k]
  |  Branch (8041:23): [True: 214k, False: 228]
  ------------------
 8042|  46.3k|  if (value >= '0' && value <= '9') return value - '0' + 26;
  ------------------
  |  Branch (8042:7): [True: 41.9k, False: 4.47k]
  |  Branch (8042:23): [True: 39.9k, False: 1.92k]
  ------------------
 8043|  6.39k|  return -1;
 8044|  46.3k|}
idna.cc:_ZN3ada4idnaL5adaptEiib:
 8050|   242k|static constexpr int32_t adapt(int32_t d, int32_t n, bool firsttime) {
 8051|   242k|  if (firsttime) {
  ------------------
  |  Branch (8051:7): [True: 20.4k, False: 222k]
  ------------------
 8052|  20.4k|    d = d / damp;
 8053|   222k|  } else {
 8054|   222k|    d = d / 2;
 8055|   222k|  }
 8056|   242k|  d += d / n;
 8057|   242k|  int32_t k = 0;
 8058|   267k|  while (d > ((base - tmin) * tmax) / 2) {
  ------------------
  |  Branch (8058:10): [True: 24.6k, False: 242k]
  ------------------
 8059|  24.6k|    d /= base - tmin;
 8060|  24.6k|    k += base;
 8061|  24.6k|  }
 8062|   242k|  return k + (((base - tmin + 1) * d) / (d + skew));
 8063|   242k|}
idna.cc:_ZN3ada4idnaL13digit_to_charEi:
 8046|  86.9k|static constexpr char digit_to_char(int32_t digit) {
 8047|  86.9k|  return digit < 26 ? char(digit + 97) : char(digit + 22);
  ------------------
  |  Branch (8047:10): [True: 74.2k, False: 12.7k]
  ------------------
 8048|  86.9k|}
idna.cc:_ZZN3ada4idna14is_label_validENSt3__117basic_string_viewIDiNS1_11char_traitsIDiEEEEENK3$_0clEj:
 9477|  2.68k|      auto is_l_or_d = [](uint32_t code) {
 9478|  2.68k|        return std::binary_search(std::begin(L), std::end(L), code) ||
  ------------------
  |  Branch (9478:16): [True: 34, False: 2.65k]
  ------------------
 9479|  2.65k|               std::binary_search(std::begin(D), std::end(D), code);
  ------------------
  |  Branch (9479:16): [True: 1.22k, False: 1.43k]
  ------------------
 9480|  2.68k|      };
idna.cc:_ZZN3ada4idna14is_label_validENSt3__117basic_string_viewIDiNS1_11char_traitsIDiEEEEENK3$_1clEj:
 9481|  2.59k|      auto is_r_or_d = [](uint32_t code) {
 9482|  2.59k|        return std::binary_search(std::begin(R), std::end(R), code) ||
  ------------------
  |  Branch (9482:16): [True: 398, False: 2.19k]
  ------------------
 9483|  2.19k|               std::binary_search(std::begin(D), std::end(D), code);
  ------------------
  |  Branch (9483:16): [True: 757, False: 1.43k]
  ------------------
 9484|  2.59k|      };
idna.cc:_ZN3ada4idnaL20find_last_not_of_nsmENSt3__117basic_string_viewIDiNS1_11char_traitsIDiEEEE:
 9057|  14.3k|    const std::u32string_view label) noexcept {
 9058|  17.4k|  for (int i = static_cast<int>(label.size() - 1); i >= 0; i--)
  ------------------
  |  Branch (9058:52): [True: 17.4k, False: 0]
  ------------------
 9059|  17.4k|    if (find_direction(label[i]) != direction::NSM) return i;
  ------------------
  |  Branch (9059:9): [True: 14.3k, False: 3.10k]
  ------------------
 9060|       |
 9061|      0|  return std::u32string_view::npos;
 9062|  14.3k|}
idna.cc:_ZN3ada4idnaL12is_rtl_labelENSt3__117basic_string_viewIDiNS1_11char_traitsIDiEEEE:
 9066|  14.3k|inline static bool is_rtl_label(const std::u32string_view label) noexcept {
 9067|  14.3k|  const size_t mask =
 9068|  14.3k|      (1u << direction::R) | (1u << direction::AL) | (1u << direction::AN);
 9069|       |
 9070|  14.3k|  size_t directions = 0;
 9071|   121k|  for (size_t i = 0; i < label.size(); i++) {
  ------------------
  |  Branch (9071:22): [True: 106k, False: 14.3k]
  ------------------
 9072|   106k|    directions |= 1u << find_direction(label[i]);
 9073|   106k|  }
 9074|  14.3k|  return (directions & mask) != 0;
 9075|  14.3k|}
idna.cc:_ZN3ada4idnaL14find_directionEj:
 9040|   141k|inline static direction find_direction(uint32_t code_point) noexcept {
 9041|   141k|  auto it = std::lower_bound(
 9042|   141k|      std::begin(dir_table), std::end(dir_table), code_point,
 9043|   141k|      [](const directions& d, uint32_t c) { return d.final_code < c; });
 9044|       |
 9045|       |  // next check is almost surely in vain, but we use it for safety.
 9046|   141k|  if (it == std::end(dir_table)) {
  ------------------
  |  Branch (9046:7): [True: 622, False: 140k]
  ------------------
 9047|    622|    return direction::NONE;
 9048|    622|  }
 9049|       |  // We have that d.final_code >= c.
 9050|   140k|  if (code_point >= it->start_code) {
  ------------------
  |  Branch (9050:7): [True: 136k, False: 4.54k]
  ------------------
 9051|   136k|    return it->direct;
 9052|   136k|  }
 9053|  4.54k|  return direction::NONE;
 9054|   140k|}
idna.cc:_ZZN3ada4idnaL14find_directionEjENKUlRKNS0_10directionsEjE_clES3_j:
 9043|  1.48M|      [](const directions& d, uint32_t c) { return d.final_code < c; });
_ZN3ada4idna30is_forbidden_domain_code_pointEc:
 9650|  44.2k|inline bool is_forbidden_domain_code_point(const char c) noexcept {
 9651|  44.2k|  return is_forbidden_domain_code_point_table[uint8_t(c)];
 9652|  44.2k|}
_ZN3ada4idna8is_asciiENSt3__117basic_string_viewIcNS1_11char_traitsIcEEEE:
 9626|  23.7k|bool constexpr is_ascii(std::string_view view) {
 9627|   450k|  for (uint8_t c : view) {
  ------------------
  |  Branch (9627:18): [True: 450k, False: 17.3k]
  ------------------
 9628|   450k|    if (c >= 0x80) {
  ------------------
  |  Branch (9628:9): [True: 6.38k, False: 444k]
  ------------------
 9629|  6.38k|      return false;
 9630|  6.38k|    }
 9631|   450k|  }
 9632|  17.3k|  return true;
 9633|  23.7k|}
idna.cc:_ZN3ada4idnaL19from_ascii_to_asciiENSt3__117basic_string_viewIcNS1_11char_traitsIcEEEE:
 9659|  6.57k|static std::string from_ascii_to_ascii(std::string_view ut8_string) {
 9660|  6.57k|  static const std::string error = "";
 9661|  6.57k|  std::string out;
 9662|  6.57k|  out.reserve(ut8_string.size());
 9663|  6.57k|  std::u32string tmp_buffer;
 9664|  6.57k|  std::u32string post_map;
 9665|  6.57k|  size_t label_start = 0;
 9666|       |
 9667|  19.1k|  while (label_start != ut8_string.size()) {
  ------------------
  |  Branch (9667:10): [True: 13.3k, False: 5.79k]
  ------------------
 9668|  13.3k|    size_t loc_dot = ut8_string.find('.', label_start);
 9669|  13.3k|    bool is_last_label = (loc_dot == std::string_view::npos);
 9670|  13.3k|    size_t label_size =
 9671|  13.3k|        is_last_label ? ut8_string.size() - label_start : loc_dot - label_start;
  ------------------
  |  Branch (9671:9): [True: 2.62k, False: 10.7k]
  ------------------
 9672|  13.3k|    size_t label_size_with_dot = is_last_label ? label_size : label_size + 1;
  ------------------
  |  Branch (9672:34): [True: 2.62k, False: 10.7k]
  ------------------
 9673|  13.3k|    std::string_view label_view(ut8_string.data() + label_start, label_size);
 9674|  13.3k|    label_start += label_size_with_dot;
 9675|  13.3k|    if (label_size == 0) {
  ------------------
  |  Branch (9675:9): [True: 4.71k, False: 8.65k]
  ------------------
 9676|       |      // empty label? Nothing to do.
 9677|  8.65k|    } else {
 9678|       |      // Append the label to out and lowercase it in-place, avoiding a separate
 9679|       |      // copy of the entire input string.
 9680|  8.65k|      size_t label_out_start = out.size();
 9681|  8.65k|      out.append(label_view);
 9682|  8.65k|      ascii_map(out.data() + label_out_start, label_size);
 9683|  8.65k|      std::string_view mapped_label(out.data() + label_out_start, label_size);
 9684|  8.65k|      if (mapped_label.starts_with("xn--")) {
  ------------------
  |  Branch (9684:11): [True: 6.27k, False: 2.37k]
  ------------------
 9685|       |        // The xn-- part is the expensive game.
 9686|  6.27k|        std::string_view puny_segment_ascii(out.data() + label_out_start + 4,
 9687|  6.27k|                                            label_size - 4);
 9688|  6.27k|        tmp_buffer.clear();
 9689|  6.27k|        bool is_ok =
 9690|  6.27k|            ada::idna::punycode_to_utf32(puny_segment_ascii, tmp_buffer);
 9691|  6.27k|        if (!is_ok) {
  ------------------
  |  Branch (9691:13): [True: 186, False: 6.08k]
  ------------------
 9692|    186|          return error;
 9693|    186|        }
 9694|       |        // If the input is just ASCII, it should not have been encoded
 9695|       |        // as punycode.
 9696|       |        // https://github.com/whatwg/url/issues/760
 9697|  6.08k|        if (is_ascii(tmp_buffer)) {
  ------------------
  |  Branch (9697:13): [True: 108, False: 5.98k]
  ------------------
 9698|    108|          return error;
 9699|    108|        }
 9700|  5.98k|        if (!ada::idna::map(tmp_buffer, post_map)) {
  ------------------
  |  Branch (9700:13): [True: 318, False: 5.66k]
  ------------------
 9701|    318|          return error;
 9702|    318|        }
 9703|  5.66k|        if (tmp_buffer != post_map) {
  ------------------
  |  Branch (9703:13): [True: 88, False: 5.57k]
  ------------------
 9704|     88|          return error;
 9705|     88|        }
 9706|  5.57k|        normalize(post_map);
 9707|  5.57k|        if (post_map != tmp_buffer) {
  ------------------
  |  Branch (9707:13): [True: 58, False: 5.51k]
  ------------------
 9708|     58|          return error;
 9709|     58|        }
 9710|  5.51k|        if (post_map.empty()) {
  ------------------
  |  Branch (9710:13): [True: 0, False: 5.51k]
  ------------------
 9711|      0|          return error;
 9712|      0|        }
 9713|  5.51k|        if (!is_label_valid(post_map)) {
  ------------------
  |  Branch (9713:13): [True: 18, False: 5.49k]
  ------------------
 9714|     18|          return error;
 9715|     18|        }
 9716|  5.51k|      }
 9717|  8.65k|    }
 9718|  12.5k|    if (!is_last_label) {
  ------------------
  |  Branch (9718:9): [True: 10.6k, False: 1.96k]
  ------------------
 9719|  10.6k|      out.push_back('.');
 9720|  10.6k|    }
 9721|  12.5k|  }
 9722|  5.79k|  return out;
 9723|  6.57k|}
_ZN3ada4idna8is_asciiENSt3__117basic_string_viewIDiNS1_11char_traitsIDiEEEE:
 9617|  19.8k|bool constexpr is_ascii(std::u32string_view view) {
 9618|  34.5k|  for (uint32_t c : view) {
  ------------------
  |  Branch (9618:19): [True: 34.5k, False: 1.49k]
  ------------------
 9619|  34.5k|    if (c >= 0x80) {
  ------------------
  |  Branch (9619:9): [True: 18.3k, False: 16.1k]
  ------------------
 9620|  18.3k|      return false;
 9621|  18.3k|    }
 9622|  34.5k|  }
 9623|  1.49k|  return true;
 9624|  19.8k|}
_ZN3ada8checkers17verify_dns_lengthENSt3__117basic_string_viewIcNS1_11char_traitsIcEEEE:
  112|  3.70k|    std::string_view input) noexcept {
  113|  3.70k|  if (input.empty()) return false;
  ------------------
  |  Branch (113:7): [True: 3.65k, False: 55]
  ------------------
  114|     55|  if (input.back() == '.') {
  ------------------
  |  Branch (114:7): [True: 1, False: 54]
  ------------------
  115|      1|    if (input.size() > 254) return false;
  ------------------
  |  Branch (115:9): [True: 1, False: 0]
  ------------------
  116|     54|  } else if (input.size() > 253)
  ------------------
  |  Branch (116:14): [True: 30, False: 24]
  ------------------
  117|     30|    return false;
  118|       |
  119|     24|  size_t start = 0;
  120|     44|  while (start < input.size()) {
  ------------------
  |  Branch (120:10): [True: 30, False: 14]
  ------------------
  121|     30|    auto dot_location = input.find('.', start);
  122|       |    // If not found, it's likely the end of the domain
  123|     30|    if (dot_location == std::string_view::npos) dot_location = input.size();
  ------------------
  |  Branch (123:9): [True: 22, False: 8]
  ------------------
  124|       |
  125|     30|    auto label_size = dot_location - start;
  126|     30|    if (label_size > 63 || label_size == 0) return false;
  ------------------
  |  Branch (126:9): [True: 10, False: 20]
  |  Branch (126:28): [True: 0, False: 20]
  ------------------
  127|       |
  128|     20|    start = dot_location + 1;
  129|     20|  }
  130|       |
  131|     14|  return true;
  132|     24|}

_ZN3ada37url_pattern_compile_component_optionsC2ENSt3__18optionalIcEES3_:
 5559|      6|      : delimiter(new_delimiter), prefix(new_prefix) {}

LLVMFuzzerTestOneInput:
    9|  3.69k|extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
   10|  3.69k|  FuzzedDataProvider fdp(data, size);
   11|  3.69k|  std::string source = fdp.ConsumeRandomLengthString(256);
   12|  3.69k|  std::string source2 = fdp.ConsumeRandomLengthString(64);
   13|       |
   14|       |  /**
   15|       |   * High-level IDNA API
   16|       |   */
   17|  3.69k|  std::string ascii_result = ada::idna::to_ascii(source);
   18|  3.69k|  std::string unicode_result = ada::idna::to_unicode(source);
   19|       |
   20|       |  // Avoid dead-code elimination
   21|  3.69k|  volatile size_t length = 0;
   22|  3.69k|  length += ascii_result.size();
   23|  3.69k|  length += unicode_result.size();
   24|       |
   25|       |  /**
   26|       |   * Round-trip property: to_unicode(to_ascii(x)) should not crash.
   27|       |   * We don't assert equality because IDNA may normalize/reject inputs.
   28|       |   */
   29|  3.69k|  if (!ascii_result.empty()) {
  ------------------
  |  Branch (29:7): [True: 1.69k, False: 2.00k]
  ------------------
   30|  1.69k|    std::string roundtrip = ada::idna::to_unicode(ascii_result);
   31|  1.69k|    length += roundtrip.size();
   32|  1.69k|  }
   33|       |
   34|       |  /**
   35|       |   * Punycode functions
   36|       |   */
   37|  3.69k|  {
   38|  3.69k|    std::u32string utf32_out;
   39|       |    // punycode_to_utf32: source can be any string (it's a punycode label)
   40|  3.69k|    bool punycode_ok = ada::idna::punycode_to_utf32(source, utf32_out);
   41|  3.69k|    length += utf32_out.size();
   42|       |
   43|       |    // verify_punycode: checks if source is valid punycode
   44|  3.69k|    volatile bool is_valid_punycode = ada::idna::verify_punycode(source);
   45|  3.69k|    (void)is_valid_punycode;
   46|       |
   47|       |    // utf32_to_punycode: round-trip if punycode_to_utf32 succeeded
   48|  3.69k|    if (punycode_ok && !utf32_out.empty()) {
  ------------------
  |  Branch (48:9): [True: 578, False: 3.11k]
  |  Branch (48:24): [True: 563, False: 15]
  ------------------
   49|    563|      std::string punycode_back;
   50|    563|      volatile bool encode_ok =
   51|    563|          ada::idna::utf32_to_punycode(utf32_out, punycode_back);
   52|    563|      length += punycode_back.size();
   53|    563|      (void)encode_ok;
   54|    563|    }
   55|  3.69k|  }
   56|       |
   57|       |  /**
   58|       |   * Unicode transcoding
   59|       |   */
   60|  3.69k|  {
   61|       |    // UTF-8 to UTF-32 conversion
   62|  3.69k|    size_t utf32_len =
   63|  3.69k|        ada::idna::utf32_length_from_utf8(source.data(), source.size());
   64|  3.69k|    if (utf32_len > 0 && utf32_len < 1024) {
  ------------------
  |  Branch (64:9): [True: 3.65k, False: 33]
  |  Branch (64:26): [True: 3.65k, False: 0]
  ------------------
   65|  3.65k|      std::vector<char32_t> utf32_buf(utf32_len + 1, 0);
   66|  3.65k|      size_t actual = ada::idna::utf8_to_utf32(source.data(), source.size(),
   67|  3.65k|                                               utf32_buf.data());
   68|  3.65k|      length += actual;
   69|       |
   70|       |      // UTF-32 to UTF-8 round-trip
   71|  3.65k|      if (actual > 0) {
  ------------------
  |  Branch (71:11): [True: 3.50k, False: 154]
  ------------------
   72|  3.50k|        size_t utf8_len =
   73|  3.50k|            ada::idna::utf8_length_from_utf32(utf32_buf.data(), actual);
   74|  3.50k|        if (utf8_len > 0 && utf8_len < 4096) {
  ------------------
  |  Branch (74:13): [True: 3.50k, False: 0]
  |  Branch (74:29): [True: 3.50k, False: 0]
  ------------------
   75|  3.50k|          std::string utf8_back(utf8_len, '\0');
   76|  3.50k|          size_t written = ada::idna::utf32_to_utf8(utf32_buf.data(), actual,
   77|  3.50k|                                                    utf8_back.data());
   78|  3.50k|          length += written;
   79|  3.50k|        }
   80|  3.50k|      }
   81|  3.65k|    }
   82|  3.69k|  }
   83|       |
   84|       |  /**
   85|       |   * IDNA label validation
   86|       |   */
   87|  3.69k|  {
   88|       |    // is_label_valid requires a UTF-32 string
   89|  3.69k|    std::u32string utf32_label;
   90|  3.69k|    bool ok = ada::idna::punycode_to_utf32(source2, utf32_label);
   91|  3.69k|    if (ok && !utf32_label.empty()) {
  ------------------
  |  Branch (91:9): [True: 3.64k, False: 47]
  |  Branch (91:15): [True: 3, False: 3.64k]
  ------------------
   92|      3|      volatile bool label_valid = ada::idna::is_label_valid(utf32_label);
   93|      3|      (void)label_valid;
   94|      3|    }
   95|       |
   96|       |    // Also test is_label_valid with direct ASCII-to-UTF32 conversion
   97|  3.69k|    std::u32string ascii_label(source2.begin(), source2.end());
   98|  3.69k|    if (!ascii_label.empty()) {
  ------------------
  |  Branch (98:9): [True: 50, False: 3.64k]
  ------------------
   99|     50|      volatile bool ascii_label_valid = ada::idna::is_label_valid(ascii_label);
  100|     50|      (void)ascii_label_valid;
  101|     50|    }
  102|  3.69k|  }
  103|       |
  104|       |  /**
  105|       |   * IDNA mapping
  106|       |   */
  107|  3.69k|  {
  108|       |    // ASCII mapping: just lowercases ASCII characters
  109|  3.69k|    std::string ascii_copy = source;
  110|  3.69k|    ada::idna::ascii_map(ascii_copy.data(), ascii_copy.size());
  111|  3.69k|    length += ascii_copy.size();
  112|       |
  113|       |    // Unicode mapping: maps UTF-32 characters according to IDNA
  114|  3.69k|    size_t utf32_len =
  115|  3.69k|        ada::idna::utf32_length_from_utf8(source.data(), source.size());
  116|  3.69k|    if (utf32_len > 0 && utf32_len < 256) {
  ------------------
  |  Branch (116:9): [True: 3.65k, False: 33]
  |  Branch (116:26): [True: 3.64k, False: 11]
  ------------------
  117|  3.64k|      std::u32string utf32_input(utf32_len, 0);
  118|  3.64k|      size_t actual = ada::idna::utf8_to_utf32(source.data(), source.size(),
  119|  3.64k|                                               utf32_input.data());
  120|  3.64k|      if (actual > 0) {
  ------------------
  |  Branch (120:11): [True: 3.49k, False: 150]
  ------------------
  121|  3.49k|        utf32_input.resize(actual);
  122|  3.49k|        std::u32string mapped = ada::idna::map(utf32_input);
  123|  3.49k|        length += mapped.size();
  124|  3.49k|      }
  125|  3.64k|    }
  126|  3.69k|  }
  127|       |
  128|       |  /**
  129|       |   * Domain code point validation
  130|       |   */
  131|  3.69k|  {
  132|  3.69k|    volatile bool has_forbidden =
  133|  3.69k|        ada::idna::contains_forbidden_domain_code_point(source);
  134|  3.69k|    (void)has_forbidden;
  135|       |
  136|       |    // is_ascii checks
  137|  3.69k|    volatile bool is_ascii_str =
  138|  3.69k|        ada::idna::is_ascii(std::string_view(source.data(), source.size()));
  139|  3.69k|    (void)is_ascii_str;
  140|  3.69k|  }
  141|       |
  142|       |  /**
  143|       |   * Normalization
  144|       |   */
  145|  3.69k|  {
  146|  3.69k|    size_t utf32_len =
  147|  3.69k|        ada::idna::utf32_length_from_utf8(source.data(), source.size());
  148|  3.69k|    if (utf32_len > 0 && utf32_len < 256) {
  ------------------
  |  Branch (148:9): [True: 3.65k, False: 33]
  |  Branch (148:26): [True: 3.64k, False: 11]
  ------------------
  149|  3.64k|      std::u32string utf32_input(utf32_len, 0);
  150|  3.64k|      size_t actual = ada::idna::utf8_to_utf32(source.data(), source.size(),
  151|  3.64k|                                               utf32_input.data());
  152|  3.64k|      if (actual > 0) {
  ------------------
  |  Branch (152:11): [True: 3.49k, False: 150]
  ------------------
  153|  3.49k|        utf32_input.resize(actual);
  154|  3.49k|        ada::idna::normalize(utf32_input);
  155|  3.49k|        length += utf32_input.size();
  156|  3.49k|      }
  157|  3.64k|    }
  158|  3.69k|  }
  159|       |
  160|       |  /**
  161|       |   * IDNA stability property.
  162|       |   *
  163|       |   * Applying to_ascii twice must be idempotent: if to_ascii(x) produces a
  164|       |   * non-empty result, then to_ascii(to_ascii(x)) must equal to_ascii(x).
  165|       |   * A correctly normalised ACE label is already its own fixed point.
  166|       |   *
  167|       |   * We allow the second call to return an empty string only if the first
  168|       |   * result was itself not a valid IDNA domain (some implementations return
  169|       |   * empty on failure). If the first result is non-empty and looks like a
  170|       |   * valid domain the second application must match.
  171|       |   */
  172|  3.69k|  {
  173|  3.69k|    if (!ascii_result.empty()) {
  ------------------
  |  Branch (173:9): [True: 1.69k, False: 2.00k]
  ------------------
  174|  1.69k|      std::string ascii_result2 = ada::idna::to_ascii(ascii_result);
  175|  1.69k|      if (!ascii_result2.empty() && ascii_result2 != ascii_result) {
  ------------------
  |  Branch (175:11): [True: 1.69k, False: 0]
  |  Branch (175:37): [True: 0, False: 1.69k]
  ------------------
  176|      0|        printf(
  177|      0|            "IDNA to_ascii not idempotent!\n"
  178|      0|            "  input:   %s\n  first:   %s\n  second:  %s\n",
  179|      0|            source.c_str(), ascii_result.c_str(), ascii_result2.c_str());
  180|      0|        abort();
  181|      0|      }
  182|  1.69k|    }
  183|  3.69k|  }
  184|       |
  185|       |  /**
  186|       |   * to_unicode stability.
  187|       |   *
  188|       |   * Applying to_unicode twice should also be idempotent: once a domain is in
  189|       |   * its Unicode presentation form, converting again should give the same
  190|       |   * result.
  191|       |   */
  192|  3.69k|  {
  193|  3.69k|    if (!unicode_result.empty()) {
  ------------------
  |  Branch (193:9): [True: 3.67k, False: 14]
  ------------------
  194|  3.67k|      std::string unicode_result2 = ada::idna::to_unicode(unicode_result);
  195|  3.67k|      if (!unicode_result2.empty() && unicode_result2 != unicode_result) {
  ------------------
  |  Branch (195:11): [True: 3.67k, False: 0]
  |  Branch (195:39): [True: 0, False: 3.67k]
  ------------------
  196|      0|        printf(
  197|      0|            "IDNA to_unicode not idempotent!\n"
  198|      0|            "  input:   %s\n  first:   %s\n  second:  %s\n",
  199|      0|            source.c_str(), unicode_result.c_str(), unicode_result2.c_str());
  200|      0|        abort();
  201|      0|      }
  202|  3.67k|    }
  203|  3.69k|  }
  204|       |
  205|       |  /**
  206|       |   * Long domain names near the DNS length limit (253 characters).
  207|       |   *
  208|       |   * The IDNA and DNS-length checking code has special handling for domains
  209|       |   * close to or exceeding 253/255 characters and 63-character labels. Feed
  210|       |   * the fuzzer inputs of a controlled length to maximise coverage of those
  211|       |   * boundary checks.
  212|       |   */
  213|  3.69k|  {
  214|  3.69k|    std::string long_domain = fdp.ConsumeRandomLengthString(270);
  215|  3.69k|    std::string long_ascii = ada::idna::to_ascii(long_domain);
  216|  3.69k|    length += long_ascii.size();
  217|       |
  218|       |    // verify_dns_length on the long input (already called for `source` above,
  219|       |    // but we want to exercise the boundary cases separately).
  220|  3.69k|    volatile bool long_dns_ok = ada::checkers::verify_dns_length(long_domain);
  221|  3.69k|    (void)long_dns_ok;
  222|       |
  223|  3.69k|    if (!long_ascii.empty()) {
  ------------------
  |  Branch (223:9): [True: 15, False: 3.67k]
  ------------------
  224|     15|      volatile bool long_ascii_dns_ok =
  225|     15|          ada::checkers::verify_dns_length(long_ascii);
  226|     15|      (void)long_ascii_dns_ok;
  227|     15|    }
  228|  3.69k|  }
  229|       |
  230|       |  /**
  231|       |   * Punycode round-trip on arbitrary binary blobs.
  232|       |   *
  233|       |   * Feed random bytes directly into punycode_to_utf32, then if that succeeds
  234|       |   * encode the result back with utf32_to_punycode and verify the round-trip.
  235|       |   */
  236|  3.69k|  {
  237|  3.69k|    std::string blob = fdp.ConsumeRandomLengthString(128);
  238|  3.69k|    std::u32string decoded;
  239|  3.69k|    bool ok = ada::idna::punycode_to_utf32(blob, decoded);
  240|  3.69k|    if (ok && !decoded.empty()) {
  ------------------
  |  Branch (240:9): [True: 3.65k, False: 32]
  |  Branch (240:15): [True: 5, False: 3.65k]
  ------------------
  241|      5|      std::string reencoded;
  242|      5|      bool enc_ok = ada::idna::utf32_to_punycode(decoded, reencoded);
  243|      5|      (void)enc_ok;
  244|      5|      length += reencoded.size();
  245|       |
  246|       |      // Re-decode the re-encoded form; it must match the first decoded form.
  247|      5|      if (enc_ok && !reencoded.empty()) {
  ------------------
  |  Branch (247:11): [True: 5, False: 0]
  |  Branch (247:21): [True: 5, False: 0]
  ------------------
  248|      5|        std::u32string redecoded;
  249|      5|        bool redec_ok = ada::idna::punycode_to_utf32(reencoded, redecoded);
  250|      5|        if (redec_ok && redecoded != decoded) {
  ------------------
  |  Branch (250:13): [True: 5, False: 0]
  |  Branch (250:25): [True: 0, False: 5]
  ------------------
  251|      0|          printf("Punycode round-trip mismatch!\n");
  252|      0|          abort();
  253|      0|        }
  254|      5|      }
  255|      5|    }
  256|  3.69k|  }
  257|       |
  258|  3.69k|  return 0;
  259|  3.69k|}

