Coverage Report

Created: 2026-08-31 06:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ada-url/build/singleheader/ada.cpp
Line
Count
Source
1
/* auto-generated on 2026-08-30 21:03:19 -0400. Do not edit! */
2
/* begin file src/ada.cpp */
3
#include "ada.h"
4
/* begin file src/checkers.cpp */
5
6
#include <algorithm>
7
#include <array>
8
#include <string_view>
9
10
namespace ada::checkers {
11
12
0
ada_really_inline constexpr bool is_ipv4(std::string_view view) noexcept {
13
  // The string is not empty and does not contain upper case ASCII characters.
14
0
  if (!last_label_may_be_a_number(view)) {
15
0
    return false;
16
0
  }
17
  // If the address ends with a dot, we need to prune it (special case).
18
0
  if (view.ends_with('.')) {
19
0
    view.remove_suffix(1);
20
0
  }
21
  // From the last character, find the last dot.
22
0
  size_t last_dot = view.rfind('.');
23
0
  if (last_dot != std::string_view::npos) {
24
    // We have at least one dot.
25
0
    view.remove_prefix(last_dot + 1);
26
0
  }
27
  /** Optimization opportunity: we have basically identified the last number of
28
     the ipv4 if we return true here. We might as well parse it and have at
29
     least one number parsed when we get to parse_ipv4. */
30
0
  if (std::ranges::all_of(view, ada::checkers::is_digit)) {
31
0
    return true;
32
0
  }
33
  // It could be hex (0x), but not if there is a single character.
34
0
  if (view.size() == 1) {
35
0
    return false;
36
0
  }
37
  // It must start with 0x.
38
0
  if (!view.starts_with("0x")) {
39
0
    return false;
40
0
  }
41
  // We must allow "0x".
42
0
  if (view.size() == 2) {
43
0
    return true;
44
0
  }
45
  // We have 0x followed by some characters, we need to check that they are
46
  // hexadecimals.
47
0
  view.remove_prefix(2);
48
0
  return std::ranges::all_of(view, ada::unicode::is_lowercase_hex);
49
0
}
50
51
// for use with path_signature, we include all characters that need percent
52
// encoding.
53
static constexpr std::array<uint8_t, 256> path_signature_table =
54
    []() consteval {
55
      std::array<uint8_t, 256> result{};
56
      for (size_t i = 0; i < 256; i++) {
57
        if (i <= 0x20 || i == 0x22 || i == 0x23 || i == 0x3c || i == 0x3e ||
58
            i == 0x3f || i == 0x5e || i == 0x60 || i == 0x7b || i == 0x7d ||
59
            i > 0x7e) {
60
          result[i] = 1;
61
        } else if (i == 0x25) {
62
          result[i] = 8;
63
        } else if (i == 0x2e) {
64
          result[i] = 4;
65
        } else if (i == 0x5c) {
66
          result[i] = 2;
67
        } else {
68
          result[i] = 0;
69
        }
70
      }
71
      return result;
72
    }();
73
74
ada_really_inline constexpr uint8_t path_signature(
75
0
    std::string_view input) noexcept {
76
  // The path percent-encode set is the query percent-encode set and U+003F (?),
77
  // U+0060 (`), U+007B ({), and U+007D (}). The query percent-encode set is the
78
  // C0 control percent-encode set and U+0020 SPACE, U+0022 ("), U+0023 (#),
79
  // U+003C (<), and U+003E (>). The C0 control percent-encode set are the C0
80
  // controls and all code points greater than U+007E (~).
81
0
  size_t i = 0;
82
0
  uint8_t accumulator{};
83
0
  for (; i + 7 < input.size(); i += 8) {
84
0
    accumulator |= uint8_t(path_signature_table[uint8_t(input[i])] |
85
0
                           path_signature_table[uint8_t(input[i + 1])] |
86
0
                           path_signature_table[uint8_t(input[i + 2])] |
87
0
                           path_signature_table[uint8_t(input[i + 3])] |
88
0
                           path_signature_table[uint8_t(input[i + 4])] |
89
0
                           path_signature_table[uint8_t(input[i + 5])] |
90
0
                           path_signature_table[uint8_t(input[i + 6])] |
91
0
                           path_signature_table[uint8_t(input[i + 7])]);
92
0
  }
93
0
  for (; i < input.size(); i++) {
94
0
    accumulator |= uint8_t(path_signature_table[uint8_t(input[i])]);
95
0
  }
96
0
  return accumulator;
97
0
}
98
99
ada_really_inline constexpr bool verify_dns_length(
100
4.73k
    std::string_view input) noexcept {
101
4.73k
  if (input.empty()) return false;
102
569
  if (input.back() == '.') {
103
65
    if (input.size() > 254) return false;
104
504
  } else if (input.size() > 253)
105
73
    return false;
106
107
486
  size_t start = 0;
108
1.92k
  while (start < input.size()) {
109
1.50k
    auto dot_location = input.find('.', start);
110
    // If not found, it's likely the end of the domain
111
1.50k
    if (dot_location == std::string_view::npos) dot_location = input.size();
112
113
1.50k
    auto label_size = dot_location - start;
114
1.50k
    if (label_size > 63 || label_size == 0) return false;
115
116
1.43k
    start = dot_location + 1;
117
1.43k
  }
118
119
415
  return true;
120
486
}
121
122
}  // namespace ada::checkers
123
/* end file src/checkers.cpp */
124
/* begin file src/unicode.cpp */
125
126
127
ADA_PUSH_DISABLE_ALL_WARNINGS
128
/* begin file src/ada_idna.cpp */
129
/* auto-generated on 2026-07-12 20:34:08 -0400. Do not edit! */
130
/* begin file src/idna.cpp */
131
/* begin file src/unicode_transcoding.cpp */
132
/* begin file include/ada/idna/unicode_transcoding.h */
133
#ifndef ADA_IDNA_UNICODE_TRANSCODING_H
134
#define ADA_IDNA_UNICODE_TRANSCODING_H
135
136
#include <string>
137
#include <string_view>
138
139
namespace ada::idna {
140
141
size_t utf8_to_utf32(const char* buf, size_t len, char32_t* utf32_output);
142
143
size_t utf8_length_from_utf32(const char32_t* buf, size_t len);
144
145
size_t utf32_length_from_utf8(const char* buf, size_t len);
146
147
size_t utf32_to_utf8(const char32_t* buf, size_t len, char* utf8_output);
148
149
}  // namespace ada::idna
150
151
#endif  // ADA_IDNA_UNICODE_TRANSCODING_H
152
/* end file include/ada/idna/unicode_transcoding.h */
153
154
#include <algorithm>
155
#include <cstdint>
156
#include <cstring>
157
158
namespace ada::idna {
159
160
14.8k
size_t utf8_to_utf32(const char* buf, size_t len, char32_t* utf32_output) {
161
14.8k
  const uint8_t* data = reinterpret_cast<const uint8_t*>(buf);
162
14.8k
  size_t pos = 0;
163
14.8k
  const char32_t* start{utf32_output};
164
132k
  while (pos < len) {
165
    // try to convert the next block of 16 ASCII bytes
166
118k
    if (pos + 16 <= len) {  // if it is safe to read 16 more
167
                            // bytes, check that they are ascii
168
51.0k
      uint64_t v1;
169
51.0k
      std::memcpy(&v1, data + pos, sizeof(uint64_t));
170
51.0k
      uint64_t v2;
171
51.0k
      std::memcpy(&v2, data + pos + sizeof(uint64_t), sizeof(uint64_t));
172
51.0k
      uint64_t v{v1 | v2};
173
51.0k
      if ((v & 0x8080808080808080) == 0) {
174
9.95k
        size_t final_pos = pos + 16;
175
169k
        while (pos < final_pos) {
176
159k
          *utf32_output++ = char32_t(buf[pos]);
177
159k
          pos++;
178
159k
        }
179
9.95k
        continue;
180
9.95k
      }
181
51.0k
    }
182
109k
    uint8_t leading_byte = data[pos];  // leading byte
183
109k
    if (leading_byte < 0b10000000) {
184
      // converting one ASCII byte !!!
185
60.0k
      *utf32_output++ = char32_t(leading_byte);
186
60.0k
      pos++;
187
60.0k
    } else if ((leading_byte & 0b11100000) == 0b11000000) {
188
      // We have a two-byte UTF-8
189
15.3k
      if (pos + 1 >= len) {
190
58
        return 0;
191
58
      }  // minimal bound checking
192
15.2k
      if ((data[pos + 1] & 0b11000000) != 0b10000000) {
193
107
        return 0;
194
107
      }
195
      // range check
196
15.1k
      uint32_t code_point =
197
15.1k
          (leading_byte & 0b00011111) << 6 | (data[pos + 1] & 0b00111111);
198
15.1k
      if (code_point < 0x80 || 0x7ff < code_point) {
199
12
        return 0;
200
12
      }
201
15.1k
      *utf32_output++ = char32_t(code_point);
202
15.1k
      pos += 2;
203
33.6k
    } else if ((leading_byte & 0b11110000) == 0b11100000) {
204
      // We have a three-byte UTF-8
205
31.2k
      if (pos + 2 >= len) {
206
44
        return 0;
207
44
      }  // minimal bound checking
208
209
31.1k
      if ((data[pos + 1] & 0b11000000) != 0b10000000) {
210
64
        return 0;
211
64
      }
212
31.1k
      if ((data[pos + 2] & 0b11000000) != 0b10000000) {
213
17
        return 0;
214
17
      }
215
      // range check
216
31.0k
      uint32_t code_point = (leading_byte & 0b00001111) << 12 |
217
31.0k
                            (data[pos + 1] & 0b00111111) << 6 |
218
31.0k
                            (data[pos + 2] & 0b00111111);
219
31.0k
      if (code_point < 0x800 || 0xffff < code_point ||
220
31.0k
          (0xd7ff < code_point && code_point < 0xe000)) {
221
22
        return 0;
222
22
      }
223
31.0k
      *utf32_output++ = char32_t(code_point);
224
31.0k
      pos += 3;
225
31.0k
    } else if ((leading_byte & 0b11111000) == 0b11110000) {  // 0b11110000
226
      // we have a 4-byte UTF-8 word.
227
2.03k
      if (pos + 3 >= len) {
228
44
        return 0;
229
44
      }  // minimal bound checking
230
1.99k
      if ((data[pos + 1] & 0b11000000) != 0b10000000) {
231
45
        return 0;
232
45
      }
233
1.95k
      if ((data[pos + 2] & 0b11000000) != 0b10000000) {
234
7
        return 0;
235
7
      }
236
1.94k
      if ((data[pos + 3] & 0b11000000) != 0b10000000) {
237
20
        return 0;
238
20
      }
239
240
      // range check
241
1.92k
      uint32_t code_point = (leading_byte & 0b00000111) << 18 |
242
1.92k
                            (data[pos + 1] & 0b00111111) << 12 |
243
1.92k
                            (data[pos + 2] & 0b00111111) << 6 |
244
1.92k
                            (data[pos + 3] & 0b00111111);
245
1.92k
      if (code_point <= 0xffff || 0x10ffff < code_point) {
246
31
        return 0;
247
31
      }
248
1.89k
      *utf32_output++ = char32_t(code_point);
249
1.89k
      pos += 4;
250
1.89k
    } else {
251
372
      return 0;
252
372
    }
253
109k
  }
254
13.9k
  return utf32_output - start;
255
14.8k
}
256
257
8.64k
size_t utf8_length_from_utf32(const char32_t* buf, size_t len) {
258
  // We are not BOM aware.
259
8.64k
  const uint32_t* p = reinterpret_cast<const uint32_t*>(buf);
260
8.64k
  size_t counter{0};
261
162k
  for (size_t i = 0; i != len; ++i) {
262
154k
    ++counter;                                      // ASCII
263
154k
    counter += static_cast<size_t>(p[i] > 0x7F);    // two-byte
264
154k
    counter += static_cast<size_t>(p[i] > 0x7FF);   // three-byte
265
154k
    counter += static_cast<size_t>(p[i] > 0xFFFF);  // four-bytes
266
154k
  }
267
8.64k
  return counter;
268
8.64k
}
269
270
16.6k
size_t utf32_length_from_utf8(const char* buf, size_t len) {
271
16.6k
  const int8_t* p = reinterpret_cast<const int8_t*>(buf);
272
400k
  return std::count_if(p, std::next(p, len), [](int8_t c) {
273
    // -65 is 0b10111111, anything larger in two-complement's
274
    // should start a new code point.
275
400k
    return c > -65;
276
400k
  });
277
16.6k
}
278
279
8.64k
size_t utf32_to_utf8(const char32_t* buf, size_t len, char* utf8_output) {
280
8.64k
  const uint32_t* data = reinterpret_cast<const uint32_t*>(buf);
281
8.64k
  size_t pos = 0;
282
8.64k
  const char* start{utf8_output};
283
130k
  while (pos < len) {
284
    // try to convert the next block of 2 ASCII characters
285
121k
    if (pos + 2 <= len) {  // if it is safe to read 8 more
286
                           // bytes, check that they are ascii
287
113k
      uint64_t v;
288
113k
      std::memcpy(&v, data + pos, sizeof(uint64_t));
289
113k
      if ((v & 0xFFFFFF80FFFFFF80) == 0) {
290
32.7k
        *utf8_output++ = char(buf[pos]);
291
32.7k
        *utf8_output++ = char(buf[pos + 1]);
292
32.7k
        pos += 2;
293
32.7k
        continue;
294
32.7k
      }
295
113k
    }
296
88.6k
    uint32_t word = data[pos];
297
88.6k
    if ((word & 0xFFFFFF80) == 0) {
298
      // will generate one UTF-8 bytes
299
13.9k
      *utf8_output++ = char(word);
300
13.9k
      pos++;
301
74.6k
    } else if ((word & 0xFFFFF800) == 0) {
302
      // will generate two UTF-8 bytes
303
      // we have 0b110XXXXX 0b10XXXXXX
304
56.2k
      *utf8_output++ = char((word >> 6) | 0b11000000);
305
56.2k
      *utf8_output++ = char((word & 0b111111) | 0b10000000);
306
56.2k
      pos++;
307
56.2k
    } else if ((word & 0xFFFF0000) == 0) {
308
      // will generate three UTF-8 bytes
309
      // we have 0b1110XXXX 0b10XXXXXX 0b10XXXXXX
310
15.2k
      if (word >= 0xD800 && word <= 0xDFFF) {
311
0
        return 0;
312
0
      }
313
15.2k
      *utf8_output++ = char((word >> 12) | 0b11100000);
314
15.2k
      *utf8_output++ = char(((word >> 6) & 0b111111) | 0b10000000);
315
15.2k
      *utf8_output++ = char((word & 0b111111) | 0b10000000);
316
15.2k
      pos++;
317
15.2k
    } else {
318
      // will generate four UTF-8 bytes
319
      // we have 0b11110XXX 0b10XXXXXX 0b10XXXXXX
320
      // 0b10XXXXXX
321
3.09k
      if (word > 0x10FFFF) {
322
0
        return 0;
323
0
      }
324
3.09k
      *utf8_output++ = char((word >> 18) | 0b11110000);
325
3.09k
      *utf8_output++ = char(((word >> 12) & 0b111111) | 0b10000000);
326
3.09k
      *utf8_output++ = char(((word >> 6) & 0b111111) | 0b10000000);
327
3.09k
      *utf8_output++ = char((word & 0b111111) | 0b10000000);
328
3.09k
      pos++;
329
3.09k
    }
330
88.6k
  }
331
8.64k
  return utf8_output - start;
332
8.64k
}
333
}  // namespace ada::idna
334
/* end file src/unicode_transcoding.cpp */
335
/* begin file src/mapping.cpp */
336
/* begin file include/ada/idna/mapping.h */
337
#ifndef ADA_IDNA_MAPPING_H
338
#define ADA_IDNA_MAPPING_H
339
340
#include <string>
341
#include <string_view>
342
343
namespace ada::idna {
344
345
// If the input is ascii, then the mapping is just -> lower case.
346
void ascii_map(char* input, size_t length);
347
// Map the characters according to IDNA, returning the empty string on error.
348
std::u32string map(std::u32string_view input);
349
// Map into an existing buffer (cleared on entry). Returns false if any code
350
// point is disallowed. Reusing the buffer avoids repeated heap allocations
351
// when called in a loop over multiple labels.
352
bool map(std::u32string_view input, std::u32string& out);
353
354
}  // namespace ada::idna
355
356
#endif
357
/* end file include/ada/idna/mapping.h */
358
359
#include <array>
360
#include <cstring>
361
#include <cstdint>
362
#include <string>
363
364
/* begin file src/table_store.hpp */
365
// Runtime store for compressed Unicode/IDNA tables.
366
// Large tables are DEFLATE-compressed (read-only) and expanded once on first
367
// use into a heap buffer so the working set does not bloat the on-disk binary.
368
// Hot-path lookups use the same O(1) multi-stage layout as the pre-compression
369
// code; compression only affects on-disk size and one-time init.
370
//
371
// Thread-safe without mutex: atomic CAS + spin-wait. ensure_tables() returns
372
// false if initialization fails (OOM, corrupt blob); callers must treat that
373
// as a hard error and not touch table pointers.
374
375
/* begin file src/raw_inflate.hpp */
376
// Minimal raw DEFLATE inflater (RFC 1951), enough for zlib raw streams.
377
// Returns number of output bytes written, or 0 on failure.
378
#include <cstdint>
379
#include <cstring>
380
381
namespace ada::idna::deflate {
382
383
struct BitReader {
384
  const uint8_t* p;
385
  const uint8_t* end;
386
  uint32_t acc = 0;
387
  int bits = 0;
388
389
  explicit BitReader(const uint8_t* data, size_t len)
390
1
      : p(data), end(data + len) {}
391
392
457k
  bool ensure(int n) {
393
520k
    while (bits < n) {
394
62.3k
      if (p >= end) return false;
395
62.3k
      acc |= uint32_t(*p++) << bits;
396
62.3k
      bits += 8;
397
62.3k
    }
398
457k
    return true;
399
457k
  }
400
  // Keep this symbol in the shared library. A larger translation unit can
401
  // otherwise inline it away and trip the ABI check (removed BitReader::get).
402
#if defined(__GNUC__)
403
  __attribute__((used))
404
#endif
405
457k
  uint32_t get(int n) {
406
457k
    if (!ensure(n)) return UINT32_MAX;
407
457k
    uint32_t v = acc & ((1u << n) - 1);
408
457k
    acc >>= n;
409
457k
    bits -= n;
410
457k
    return v;
411
457k
  }
412
0
  void align_byte() {
413
0
    acc >>= (bits & 7);
414
0
    bits -= (bits & 7);
415
0
  }
416
};
417
418
struct Huff {
419
  // canonical codes: for each length, list of symbols
420
  // Fast path: table for codes up to max_bits
421
  static constexpr int MAXBITS = 15;
422
  uint8_t lengths[288]{};
423
  int counts[MAXBITS + 1]{};
424
  int first_code[MAXBITS + 1]{};
425
  int16_t symbols[288]{};
426
  int nsymbols = 0;
427
  int max_bits = 0;
428
429
  // Base index into symbols[] for each code length (used by decode).
430
  int base_idx[MAXBITS + 1]{};
431
432
16
  bool build(const uint8_t* lens, int n) {
433
16
    std::memset(counts, 0, sizeof(counts));
434
16
    std::memset(first_code, 0, sizeof(first_code));
435
16
    std::memset(base_idx, 0, sizeof(base_idx));
436
16
    nsymbols = n;
437
16
    max_bits = 0;
438
1.98k
    for (int i = 0; i < n; i++) {
439
1.96k
      lengths[i] = lens[i];
440
1.96k
      if (lens[i]) {
441
1.91k
        counts[lens[i]]++;
442
1.91k
        if (lens[i] > max_bits) max_bits = lens[i];
443
1.91k
      }
444
1.96k
    }
445
    // Canonical first code for each bit length (RFC 1951).
446
16
    int code = 0;
447
256
    for (int bits = 1; bits <= MAXBITS; bits++) {
448
240
      code = (code + counts[bits - 1]) << 1;
449
240
      first_code[bits] = code;
450
240
    }
451
16
    int idx = 0;
452
158
    for (int bits = 1; bits <= max_bits; bits++) {
453
142
      base_idx[bits] = idx;
454
      // assign symbols in symbol order for codes of this length
455
21.6k
      for (int sym = 0; sym < n; sym++) {
456
21.5k
        if (lengths[sym] == bits) {
457
1.91k
          symbols[idx++] = static_cast<int16_t>(sym);
458
1.91k
        }
459
21.5k
      }
460
142
    }
461
16
    return true;
462
16
  }
463
464
68.3k
  int decode(BitReader& br) const {
465
68.3k
    if (max_bits == 0) return -1;
466
68.3k
    int code = 0;
467
427k
    for (int len = 1; len <= max_bits; len++) {
468
427k
      uint32_t b = br.get(1);
469
427k
      if (b == UINT32_MAX) return -1;
470
427k
      code = (code << 1) | int(b);
471
427k
      int first = first_code[len];
472
427k
      int cnt = counts[len];
473
427k
      if (cnt && code - first < cnt) {
474
68.3k
        return symbols[base_idx[len] + (code - first)];
475
68.3k
      }
476
427k
    }
477
0
    return -1;
478
68.3k
  }
479
};
480
481
// Fixed Huffman tables are built once at dynamic initialization (before main /
482
// single-threaded), so concurrent first-use of inflate cannot race.
483
2
inline Huff make_fixed_litlen_huff() {
484
2
  Huff h;
485
2
  uint8_t lens[288];
486
  // Fixed Huffman: 0-143:8, 144-255:9, 256-279:7, 280-287:8
487
290
  for (int i = 0; i <= 143; i++) lens[i] = 8;
488
226
  for (int i = 144; i <= 255; i++) lens[i] = 9;
489
50
  for (int i = 256; i <= 279; i++) lens[i] = 7;
490
18
  for (int i = 280; i <= 287; i++) lens[i] = 8;
491
2
  h.build(lens, 288);
492
2
  return h;
493
2
}
494
495
2
inline Huff make_fixed_dist_huff() {
496
2
  Huff h;
497
2
  uint8_t lens[32];
498
66
  for (int i = 0; i < 32; i++) lens[i] = 5;
499
2
  h.build(lens, 32);
500
2
  return h;
501
2
}
502
503
// NOLINTNEXTLINE(cert-err58-cpp) -- intentional process-lifetime tables
504
inline const Huff kFixedLitLenHuff = make_fixed_litlen_huff();
505
// NOLINTNEXTLINE(cert-err58-cpp)
506
inline const Huff kFixedDistHuff = make_fixed_dist_huff();
507
508
0
inline int fixed_litlen(BitReader& br) { return kFixedLitLenHuff.decode(br); }
509
510
0
inline int fixed_dist(BitReader& br) { return kFixedDistHuff.decode(br); }
511
512
// length and distance base tables
513
static const uint16_t len_base[29] = {
514
    3,  4,  5,  6,  7,  8,  9,  10, 11,  13,  15,  17,  19,  23, 27,
515
    31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258};
516
static const uint8_t len_extra[29] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
517
                                      1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
518
                                      4, 4, 4, 4, 5, 5, 5, 5, 0};
519
static const uint16_t dist_base[30] = {
520
    1,    2,    3,    4,    5,    7,    9,    13,    17,    25,
521
    33,   49,   65,   97,   129,  193,  257,  385,   513,   769,
522
    1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577};
523
static const uint8_t dist_extra[30] = {0, 0, 0,  0,  1,  1,  2,  2,  3,  3,
524
                                       4, 4, 5,  5,  6,  6,  7,  7,  8,  8,
525
                                       9, 9, 10, 10, 11, 11, 12, 12, 13, 13};
526
527
inline size_t inflate_raw(const uint8_t* src, size_t src_len, uint8_t* dst,
528
1
                          size_t dst_cap) {
529
1
  BitReader br(src, src_len);
530
1
  size_t out = 0;
531
4
  for (;;) {
532
4
    uint32_t bfinal = br.get(1);
533
4
    uint32_t btype = br.get(2);
534
4
    if (bfinal == UINT32_MAX || btype == UINT32_MAX) return 0;
535
4
    if (btype == 0) {
536
      // stored
537
0
      br.align_byte();
538
0
      if (!br.ensure(16)) return 0;
539
      // read 16+16 from bit buffer awkwardly - use byte path
540
      // Align: bits is multiple of 8
541
      // Get len from remaining bits then bytes
542
0
      uint32_t len = br.get(16);
543
0
      uint32_t nlen = br.get(16);
544
0
      if (len == UINT32_MAX || nlen == UINT32_MAX) return 0;
545
0
      if ((len ^ 0xFFFF) != nlen) return 0;
546
      // After get, may have bits in acc from previous - for stored, should be
547
      // byte aligned Copy len bytes from p
548
0
      if (br.bits != 0) {
549
        // leftover bits should be 0 if aligned
550
0
      }
551
0
      if (size_t(br.end - br.p) < len) return 0;
552
0
      if (out + len > dst_cap) return 0;
553
0
      std::memcpy(dst + out, br.p, len);
554
0
      br.p += len;
555
0
      out += len;
556
4
    } else if (btype == 1 || btype == 2) {
557
4
      Huff lit, dist;
558
4
      if (btype == 1) {
559
        // use fixed via functions
560
4
      } else {
561
        // dynamic
562
4
        uint32_t hlit = br.get(5);
563
4
        if (hlit == UINT32_MAX) return 0;
564
4
        hlit += 257;
565
4
        uint32_t hdist = br.get(5);
566
4
        if (hdist == UINT32_MAX) return 0;
567
4
        hdist += 1;
568
4
        uint32_t hclen = br.get(4);
569
4
        if (hclen == UINT32_MAX) return 0;
570
4
        hclen += 4;
571
4
        static const int order[19] = {16, 17, 18, 0, 8,  7, 9,  6, 10, 5,
572
4
                                      11, 4,  12, 3, 13, 2, 14, 1, 15};
573
4
        uint8_t clen[19]{};
574
69
        for (uint32_t i = 0; i < hclen; i++) {
575
65
          uint32_t v = br.get(3);
576
65
          if (v == UINT32_MAX) return 0;
577
65
          clen[order[i]] = uint8_t(v);
578
65
        }
579
4
        Huff cl;
580
4
        if (!cl.build(clen, 19)) return 0;
581
4
        uint8_t lens[288 + 32]{};
582
4
        uint32_t n = hlit + hdist;
583
1.09k
        for (uint32_t i = 0; i < n;) {
584
1.08k
          int sym = cl.decode(br);
585
1.08k
          if (sym < 0) return 0;
586
1.08k
          if (sym < 16) {
587
1.03k
            lens[i++] = uint8_t(sym);
588
1.03k
          } else if (sym == 16) {
589
49
            uint32_t rep = br.get(2);
590
49
            if (rep == UINT32_MAX) return 0;
591
49
            rep += 3;
592
49
            if (i == 0) return 0;
593
49
            uint8_t v = lens[i - 1];
594
263
            while (rep--) lens[i++] = v;
595
49
          } else if (sym == 17) {
596
0
            uint32_t rep = br.get(3);
597
0
            if (rep == UINT32_MAX) return 0;
598
0
            rep += 3;
599
0
            while (rep--) lens[i++] = 0;
600
0
          } else if (sym == 18) {
601
0
            uint32_t rep = br.get(7);
602
0
            if (rep == UINT32_MAX) return 0;
603
0
            rep += 11;
604
0
            while (rep--) lens[i++] = 0;
605
0
          } else
606
0
            return 0;
607
1.08k
        }
608
4
        if (!lit.build(lens, int(hlit))) return 0;
609
4
        if (!dist.build(lens + hlit, int(hdist))) return 0;
610
4
      }
611
52.2k
      for (;;) {
612
52.2k
        int sym;
613
52.2k
        if (btype == 1)
614
0
          sym = fixed_litlen(br);
615
52.2k
        else
616
52.2k
          sym = lit.decode(br);
617
52.2k
        if (sym < 0) return 0;
618
52.2k
        if (sym < 256) {
619
37.2k
          if (out >= dst_cap) return 0;
620
37.2k
          dst[out++] = uint8_t(sym);
621
37.2k
        } else if (sym == 256) {
622
4
          break;
623
14.9k
        } else {
624
14.9k
          int len_code = sym - 257;
625
14.9k
          if (len_code < 0 || len_code > 28) return 0;
626
14.9k
          uint32_t extra = br.get(len_extra[len_code]);
627
14.9k
          if (len_extra[len_code] && extra == UINT32_MAX) return 0;
628
14.9k
          uint32_t length =
629
14.9k
              len_base[len_code] + (len_extra[len_code] ? extra : 0);
630
14.9k
          int dsym;
631
14.9k
          if (btype == 1)
632
0
            dsym = fixed_dist(br);
633
14.9k
          else
634
14.9k
            dsym = dist.decode(br);
635
14.9k
          if (dsym < 0 || dsym > 29) return 0;
636
14.9k
          uint32_t dextra = br.get(dist_extra[dsym]);
637
14.9k
          if (dist_extra[dsym] && dextra == UINT32_MAX) return 0;
638
14.9k
          uint32_t distance = dist_base[dsym] + (dist_extra[dsym] ? dextra : 0);
639
14.9k
          if (distance > out || out + length > dst_cap) return 0;
640
202k
          for (uint32_t k = 0; k < length; k++) {
641
187k
            dst[out] = dst[out - distance];
642
187k
            out++;
643
187k
          }
644
14.9k
        }
645
52.2k
      }
646
4
    } else {
647
0
      return 0;  // reserved
648
0
    }
649
4
    if (bfinal) break;
650
4
  }
651
1
  return out;
652
1
}
653
654
}  // namespace ada::idna::deflate
655
/* end file src/raw_inflate.hpp */
656
/* begin file src/table_blob.inc */
657
// Auto-generated by scripts/pack_tables.py - do not edit.
658
// Compressed Unicode/IDNA tables (raw DEFLATE).
659
// clang-format off
660
#ifndef ADA_IDNA_TABLE_BLOB_H
661
#define ADA_IDNA_TABLE_BLOB_H
662
#include <cstdint>
663
#include <cstddef>
664
namespace ada::idna::table_blob {
665
constexpr size_t uncompressed_size = 224608;
666
constexpr size_t compressed_size = 62377;
667
constexpr uint32_t uncompressed_crc32 = 0x6F4A6B2Eu;
668
constexpr size_t decomposition_block_rows = 67;
669
constexpr size_t decomposition_block_cols = 257;
670
constexpr size_t ccc_block_rows = 67;
671
constexpr size_t ccc_block_cols = 256;
672
constexpr size_t composition_block_rows = 67;
673
constexpr size_t composition_block_cols = 257;
674
constexpr size_t id_continue_count = 1418;
675
constexpr size_t id_start_count = 776;
676
constexpr size_t dir_table_count = 1449;
677
constexpr size_t combining_range_count = 290;
678
// Offsets into the decompressed buffer:
679
constexpr size_t off_idna_stage1 = 0;
680
constexpr size_t count_idna_stage1 = 3282;
681
constexpr size_t off_idna_stage2 = 6564;
682
constexpr size_t count_idna_stage2 = 11456;
683
constexpr size_t off_idna_bool_blocks = 29480;
684
constexpr size_t count_idna_bool_blocks = 225;
685
constexpr size_t off_idna_utf8_mappings = 31280;
686
constexpr size_t count_idna_utf8_mappings = 17383;
687
constexpr size_t off_decomposition_index = 48663;
688
constexpr size_t count_decomposition_index = 4352;
689
constexpr size_t off_decomposition_block = 53016;
690
constexpr size_t count_decomposition_block = 17219;
691
constexpr size_t off_decomposition_data = 87456;
692
constexpr size_t count_decomposition_data = 9102;
693
constexpr size_t off_ccc_index = 123864;
694
constexpr size_t count_ccc_index = 4352;
695
constexpr size_t off_ccc_block = 128216;
696
constexpr size_t count_ccc_block = 17152;
697
constexpr size_t off_composition_index = 145368;
698
constexpr size_t count_composition_index = 4352;
699
constexpr size_t off_composition_block = 149720;
700
constexpr size_t count_composition_block = 17219;
701
constexpr size_t off_composition_data = 184160;
702
constexpr size_t count_composition_data = 1883;
703
constexpr size_t off_id_continue_flat = 191692;
704
constexpr size_t count_id_continue_flat = 2836;
705
constexpr size_t off_id_start_flat = 203036;
706
constexpr size_t count_id_start_flat = 1552;
707
constexpr size_t off_dir_start = 209244;
708
constexpr size_t count_dir_start = 1449;
709
constexpr size_t off_dir_final = 215040;
710
constexpr size_t count_dir_final = 1449;
711
constexpr size_t off_dir_value = 220836;
712
constexpr size_t count_dir_value = 1449;
713
constexpr size_t off_combining_flat = 222288;
714
constexpr size_t count_combining_flat = 580;
715
alignas(8) inline constexpr uint8_t compressed[] = {
716
0xec,0x9c,0x09,0x40,0x53,0xc7,0xda,0xfe,0x5f,0x08,0x98,0x28,0x4b,0x4c,0xc2,0x12,
717
0x14,0x09,0x12,0x42,0x12,0x76,0x12,0x20,0xec,0x09,0xd0,0xdd,0x56,0xdb,0xda,0xdd,
718
0x5b,0x5b,0x97,0x6a,0xdd,0xad,0xb6,0xda,0xc5,0x96,0x23,0xbb,0xa2,0xe0,0xbe,0xb0,
719
0x8a,0xa8,0xa8,0x88,0x08,0xa8,0xec,0xcb,0x2d,0x2a,0x62,0xad,0x88,0xa8,0xdd,0xeb,
720
0x56,0x36,0x6d,0x6b,0x5b,0xdb,0xda,0xd6,0x96,0xfc,0x9f,0x73,0x12,0xd4,0xb6,0xf6,
721
0xb6,0xb7,0xcb,0xfd,0xbe,0xfb,0xfd,0x9b,0xe1,0x37,0x33,0xe7,0x9c,0x99,0x79,0xde,
722
0x79,0xcf,0x9c,0x73,0x66,0x4e,0x00,0x62,0x88,0x0c,0xc4,0x50,0x33,0x91,0x85,0xc1,
723
0x82,0xb1,0x68,0xb6,0x20,0x4b,0x83,0x25,0x63,0x49,0x4c,0xb3,0x25,0xf1,0x0c,0x3c,
724
0x86,0xd7,0xcc,0x23,0x2b,0x83,0x15,0x63,0xd5,0x6c,0x45,0xd6,0x16,0x8c,0x25,0x63,
725
0xb0,0x26,0x86,0xc7,0x58,0x31,0xd6,0xcc,0x20,0x86,0xcf,0x08,0x98,0xc1,0xcc,0x10,
726
0xc6,0x86,0x21,0x86,0xb1,0xb6,0x65,0x9a,0xad,0x69,0x90,0x61,0x90,0x1d,0x63,0xcf,
727
0x08,0x19,0x66,0xd0,0x50,0x46,0xc4,0x88,0x19,0x09,0xe3,0xc0,0x38,0x32,0x4e,0x8c,
728
0x33,0x23,0x65,0x5c,0x98,0xe6,0x41,0xc3,0x18,0xe2,0x1b,0xf8,0x0c,0xbf,0x99,0x4f,
729
0x82,0xe1,0xa8,0x47,0x8c,0x41,0xc0,0x08,0xa0,0x27,0x20,0x6e,0xcb,0x95,0x19,0xc1,
730
0xb8,0x31,0x32,0xc6,0x9d,0x19,0xc9,0xd0,0x60,0xd3,0xbe,0x1f,0x07,0x0f,0x46,0xce,
731
0x78,0x32,0x0a,0xc6,0x30,0xd8,0x8b,0x61,0x06,0xcb,0x19,0x25,0xa3,0x62,0xd4,0x8c,
732
0x37,0xe3,0xc3,0xf8,0x32,0x7e,0x8c,0x3f,0x13,0xc0,0x04,0xa2,0x54,0x10,0xd0,0x30,
733
0x5a,0x26,0x98,0x69,0x1e,0x1c,0xc2,0xd0,0x10,0xc3,0x10,0x66,0x08,0x54,0x86,0x90,
734
0x8d,0xc1,0x86,0xb1,0x69,0xb6,0x21,0x5b,0x83,0x2d,0x63,0xdb,0x6c,0x4b,0x76,0x06,
735
0xbb,0x50,0x86,0xb1,0x6b,0xb6,0x23,0x7b,0xd8,0x62,0x6f,0xd2,0x60,0xcc,0xa9,0x8e,
736
0x69,0xb6,0x27,0xa1,0x41,0x78,0x2b,0x3b,0x6e,0x15,0x18,0x61,0x33,0x5b,0x76,0x28,
737
0x31,0x61,0xa6,0xbe,0x0d,0x65,0x86,0x36,0x0f,0x25,0x51,0x38,0x63,0x10,0x45,0x30,
738
0x91,0xd8,0x13,0xc5,0x30,0xa2,0x66,0x11,0x89,0x0d,0x62,0x46,0xdc,0x2c,0x26,0x49,
739
0x34,0x63,0x90,0x30,0x92,0x66,0x09,0x39,0x18,0x1c,0x62,0x18,0xc6,0xa1,0xd9,0x81,
740
0x1c,0x0d,0x8e,0x8c,0x63,0xb3,0x23,0x39,0x19,0x9c,0x7e,0xab,0xee,0xdf,0xe1,0xef,
741
0xf0,0x77,0xf8,0x6b,0x82,0x9e,0x31,0x5c,0xcf,0xc7,0x32,0x8c,0x53,0xb3,0x53,0x1c,
742
0x43,0xce,0x06,0x67,0xc6,0xb9,0xd9,0x39,0x9e,0x41,0x9e,0xb9,0x0d,0xdc,0x0e,0xee,
743
0x60,0xee,0x64,0xee,0x42,0x7a,0x37,0x73,0x0f,0x43,0x52,0x83,0x74,0xd4,0xdf,0xde,
744
0xfb,0x0b,0xc3,0xbd,0xcc,0x7d,0xcc,0xe8,0xbf,0x03,0x17,0x18,0x69,0xb3,0x94,0x5c,
745
0x0c,0x2e,0x8c,0x4b,0xb3,0x0b,0x0d,0x33,0x0c,0x63,0x86,0x35,0x0f,0xa3,0xe1,0x86,
746
0xe1,0xcc,0xf0,0xe6,0xe1,0xe4,0x6a,0x70,0x65,0x5c,0x9b,0x5d,0x69,0x84,0x61,0x04,
747
0x33,0xa2,0x79,0x04,0xb9,0x19,0xdc,0x18,0xb7,0x66,0x37,0x92,0x19,0x64,0x63,0x98,
748
0xfb,0xe1,0xc9,0x07,0x98,0x07,0x11,0x8f,0x65,0x1e,0xe2,0xda,0x7a,0x98,0x79,0x84,
749
0x79,0x94,0x79,0x8c,0x79,0x9c,0x79,0x82,0x61,0x64,0x78,0x66,0xca,0xc8,0x7d,0x1c,
750
0x63,0x70,0x67,0xdc,0xff,0x71,0xdd,0xf7,0x77,0x32,0x4f,0x32,0xcd,0xee,0xa3,0x99,
751
0xf1,0xcc,0x53,0xcc,0xd3,0xcc,0x04,0x66,0x22,0x33,0x89,0x99,0xcc,0x3c,0xc3,0x4c,
752
0x61,0xa6,0x32,0xcf,0x32,0xd3,0x98,0xe9,0xcc,0x0c,0x66,0x26,0xda,0x22,0x66,0x16,
753
0x43,0x23,0x67,0x33,0x73,0x18,0xc3,0xc8,0xb9,0x5c,0xeb,0xcf,0x31,0xf3,0x98,0xf9,
754
0xcc,0x38,0xe6,0x79,0xe6,0x05,0x66,0x01,0x8e,0x2f,0x64,0x5e,0x64,0x5e,0x62,0x5e,
755
0x66,0x5e,0x41,0x7e,0x11,0xf3,0x2a,0xf3,0x1a,0x93,0xc0,0x30,0xcc,0x62,0x26,0x91,
756
0x49,0x62,0x92,0xb1,0x2f,0x05,0xa4,0x72,0x35,0xd3,0xf0,0xec,0x24,0x26,0x9d,0x59,
757
0xc2,0x2c,0x65,0x32,0x98,0x65,0xdc,0xbe,0xe5,0x6c,0xdf,0x47,0x66,0x32,0x59,0xcc,
758
0x0a,0x66,0x25,0xb3,0x0a,0xc7,0x57,0x33,0x6b,0x30,0x3f,0x58,0xcb,0xac,0xc3,0x91,
759
0xf5,0xcc,0x06,0x66,0x23,0x93,0x8d,0x5c,0x0e,0x93,0xcb,0xe4,0x31,0xf9,0x66,0x6f,
760
0x15,0x30,0x9b,0x98,0x42,0x66,0x33,0x53,0xf4,0x2f,0xc7,0xd7,0x24,0xce,0xfe,0x2d,
761
0xe6,0xad,0xad,0x7f,0xfa,0x39,0xdb,0xc6,0x14,0xff,0xea,0x18,0xdf,0xce,0xec,0xf8,
762
0x1f,0xbc,0xc2,0x1e,0xb8,0xc5,0xbe,0x65,0xff,0x27,0xaf,0x9f,0x25,0xbf,0xb3,0xde,
763
0x4f,0xbd,0x23,0x67,0x76,0x32,0x25,0xcc,0x2e,0xe4,0x4a,0x99,0xdd,0xb7,0x54,0x68,
764
0x1e,0x49,0x1e,0x65,0x38,0xbe,0x87,0x29,0x67,0x2a,0xfe,0x3f,0xb9,0x53,0x57,0x32,
765
0x7b,0x39,0x5f,0x15,0xff,0x7d,0xa7,0xfe,0x51,0xd8,0x77,0xdd,0x43,0xfb,0x99,0xaa,
766
0x9b,0xfc,0xb5,0xfc,0x4f,0x53,0x20,0xa6,0x9a,0x31,0x78,0xfc,0xcf,0xf5,0xd0,0xbc,
767
0x2a,0xf2,0xb8,0x79,0x34,0xd4,0x30,0xb5,0x4c,0x1d,0x37,0xa7,0xda,0x6a,0xde,0xa3,
768
0x62,0xea,0x99,0x66,0x0f,0x92,0x1b,0xe4,0xc4,0x34,0xa0,0x56,0x23,0xf6,0x35,0x99,
769
0x9e,0x6b,0xf2,0x66,0x39,0x79,0x1a,0x3c,0x19,0xcf,0x66,0x4f,0x52,0x18,0x14,0x8c,
770
0xa2,0x59,0x41,0x5e,0x06,0x2f,0xc6,0xab,0xd9,0x8b,0x94,0x06,0xe5,0xad,0x46,0x5b,
771
0xf3,0x6f,0xb0,0xeb,0x9f,0x03,0xcf,0x4d,0x65,0xb3,0xf2,0x75,0xa4,0x2d,0xcc,0x81,
772
0xeb,0xc7,0x0e,0x32,0x87,0x7e,0x52,0xba,0xd5,0x9c,0x1e,0x36,0xa7,0x6d,0xe6,0xf4,
773
0x88,0x59,0xf1,0x0d,0x86,0x54,0x47,0x7f,0x41,0xe9,0x4d,0xe6,0x18,0xe2,0x76,0xf3,
774
0x96,0x41,0xc5,0xa8,0x9a,0x55,0xc7,0xaf,0x1f,0xf5,0x41,0xed,0x0e,0xe6,0x04,0x43,
775
0x6a,0x83,0x9a,0x51,0x77,0x32,0xcd,0x6a,0xf2,0xbe,0xd5,0x7d,0xe5,0xc7,0xe1,0xa4,
776
0x39,0x3d,0xc5,0x9c,0x66,0xde,0x62,0xde,0x66,0xde,0xb9,0xe9,0xd8,0xbb,0xcc,0x7b,
777
0xcc,0xfb,0x5c,0xee,0x03,0xc6,0xe0,0xfd,0xef,0xde,0xbf,0xfe,0x0e,0x7f,0x87,0xbf,
778
0xc3,0xdf,0xe1,0xef,0xf0,0xaf,0xc2,0xb3,0xff,0x6b,0x2c,0xf9,0xf0,0xbf,0xd0,0x7b,
779
0x75,0xff,0xdf,0x8c,0x93,0x33,0xb7,0xd8,0x17,0xf5,0xe7,0xae,0xfb,0xbd,0x9b,0xbd,
780
0xc9,0xc7,0xe0,0xc3,0xf8,0x34,0xfb,0x90,0xaf,0xc1,0x97,0xf1,0xfd,0x63,0xeb,0x97,
781
0xff,0x3d,0xe1,0xec,0xdf,0xf7,0x19,0x2e,0x2c,0x61,0x8c,0x46,0x0b,0xe2,0x91,0x35,
782
0xf1,0x69,0x30,0xd9,0x90,0x1d,0x09,0x49,0x44,0x12,0x72,0x24,0x67,0x72,0xa1,0xe1,
783
0x34,0x82,0x64,0x34,0x92,0xe4,0xa4,0x20,0x25,0xa9,0xc9,0x87,0xfc,0x28,0x80,0x82,
784
0x48,0x4b,0xc6,0x3f,0xed,0xd3,0xff,0x07,0x43,0xc8,0x4f,0x6c,0xd1,0x11,0xdb,0x23,
785
0x36,0x47,0x88,0x23,0xb9,0x9c,0x9e,0x62,0x29,0x9e,0xee,0xe4,0xf2,0xf7,0xd0,0x68,
786
0xf4,0xca,0x68,0xbc,0x9f,0x1e,0xa1,0x7f,0x20,0x9d,0x48,0xcf,0xd0,0xb3,0x34,0x83,
787
0x66,0xd3,0x73,0xf4,0x3c,0x2d,0xa4,0x97,0xe9,0x55,0x38,0x26,0x89,0x52,0x69,0x09,
788
0x2d,0xa3,0x2c,0x5a,0x45,0x6b,0x69,0x03,0xe5,0x50,0x3e,0x15,0xd2,0x16,0x94,0x2f,
789
0xa6,0x9d,0x54,0x4a,0x7b,0xa8,0x92,0xf6,0x53,0xcd,0x9f,0xe0,0x87,0x7a,0xb4,0xd1,
790
0x04,0x5e,0x07,0x07,0xc1,0x61,0xf0,0x06,0x38,0x06,0x3a,0xc0,0x49,0xf0,0x16,0x78,
791
0x17,0x7c,0x00,0xce,0x82,0x0b,0xa0,0x1b,0xf4,0x81,0x8f,0xc1,0x65,0xf0,0x05,0xf8,
792
0x0a,0x7c,0x03,0xae,0x81,0x7e,0xd6,0x0f,0x16,0x46,0xa3,0x15,0x10,0x58,0x08,0x2c,
793
0x6c,0x90,0xda,0x5b,0xb0,0x8a,0x22,0xc4,0x0e,0xc0,0x19,0x0c,0xb3,0x18,0x66,0xe1,
794
0x86,0x74,0x24,0xf0,0x04,0x4a,0xe0,0x6d,0xe1,0x8f,0x38,0x08,0x04,0x03,0x1d,0x88,
795
0x00,0xd1,0xc0,0x00,0xe2,0xc1,0x1d,0xe0,0x6e,0x70,0x2f,0x18,0x03,0x1e,0x04,0x0f,
796
0x83,0xc7,0xc0,0x38,0x30,0x1e,0x4c,0x00,0x93,0xc1,0x54,0x30,0x1d,0xcc,0x02,0x73,
797
0xc1,0x7c,0x8b,0x05,0x88,0x5f,0x02,0x8b,0x80,0x02,0x56,0x26,0x58,0x24,0x22,0x97,
798
0x02,0xd2,0x2d,0x32,0x10,0x67,0x5a,0xac,0xb4,0x58,0xc3,0x59,0xba,0xde,0x22,0xdb,
799
0x22,0xcf,0x62,0x13,0xf2,0x45,0x16,0xdb,0x10,0xef,0xb0,0xd8,0x65,0x51,0x66,0x61,
800
0xf2,0x5b,0x85,0xc5,0x3e,0xe4,0xaa,0x2d,0xea,0x10,0x37,0x82,0x7f,0x82,0x03,0x16,
801
0xad,0x88,0x8f,0x70,0x25,0xde,0x44,0x7c,0xdc,0xa2,0x13,0xf1,0x69,0x8b,0x77,0x2c,
802
0xde,0x47,0x7a,0x06,0x9c,0xb7,0xe8,0x32,0xd7,0xef,0xb5,0xf8,0xf1,0x79,0xb8,0x64,
803
0xc1,0x86,0xcb,0x5c,0xf8,0x82,0x0b,0x5f,0xa1,0xc4,0x37,0xe0,0x1a,0xe8,0x07,0x16,
804
0x96,0xf0,0x26,0xe0,0x83,0x21,0x96,0x6c,0x1d,0x3b,0xc4,0x43,0x81,0x04,0x38,0x01,
805
0x17,0xe0,0x0a,0x64,0xc0,0x03,0x28,0xb8,0x52,0x2a,0x4b,0x36,0xf8,0x20,0xef,0x6f,
806
0x19,0x64,0x19,0x8c,0x54,0x07,0x22,0x40,0x34,0x30,0x80,0x78,0x70,0x07,0xb8,0x1b,
807
0xdc,0x0b,0xc6,0x80,0x07,0xc1,0xc3,0xe0,0x31,0x30,0x0e,0x8c,0x07,0x13,0xc0,0x64,
808
0x30,0x15,0x4c,0x07,0xb3,0xc0,0x5c,0x30,0x1f,0x2c,0x00,0x2f,0x81,0x45,0x20,0x01,
809
0x24,0x82,0x14,0x90,0x0e,0x32,0x2c,0x7f,0xdc,0xd7,0x4c,0xcb,0x55,0xd8,0xb3,0xd6,
810
0x72,0x03,0xb7,0x3f,0x17,0x71,0x81,0xe5,0x66,0xcb,0xad,0x96,0xdb,0x91,0x2b,0x01,
811
0xbb,0x41,0x39,0xd8,0x6b,0x69,0xfc,0xaf,0xff,0x08,0xa9,0xca,0x52,0x82,0x3b,0x58,
812
0xad,0x65,0x83,0x65,0xb3,0xa5,0x1f,0xee,0x5e,0x7f,0xac,0xbd,0x16,0xcb,0x56,0xcb,
813
0x37,0x2c,0xdb,0x2d,0x3b,0x2d,0xdf,0xe2,0xbc,0xb3,0xcd,0xc2,0x19,0x77,0xc7,0x00,
814
0x7a,0xef,0x77,0xfa,0xea,0x43,0xcb,0x73,0xa8,0xf9,0x91,0x65,0x8f,0xe5,0xc7,0xb7,
815
0x68,0x81,0xfe,0xf0,0x1d,0xe6,0x32,0x5a,0xfd,0x02,0x7c,0x05,0xbe,0xb1,0x34,0xdd,
816
0x6f,0xaf,0x0d,0x28,0x59,0x5a,0xf0,0x06,0xee,0xa3,0xf1,0x64,0xc5,0x1b,0xc2,0xb3,
817
0xe3,0x0d,0xe5,0x49,0x78,0x4e,0xd8,0xeb,0x02,0x5c,0x79,0x32,0x1e,0x46,0x32,0x4f,
818
0xc1,0x53,0xf1,0x7c,0x78,0xfe,0xbc,0x20,0x5e,0x30,0x4f,0xc7,0xfb,0xd8,0x32,0x82,
819
0x17,0xcd,0xbb,0x93,0x0c,0xbc,0x78,0xde,0x1d,0xbc,0xbb,0x79,0xf7,0xa2,0xe4,0x18,
820
0xde,0x83,0xbc,0x87,0x79,0x8f,0xf1,0xc6,0xf1,0xc6,0xf3,0x26,0xf0,0x26,0xf3,0xa6,
821
0xf2,0xfe,0x9c,0xb3,0x37,0x1d,0xda,0x3a,0xb4,0xec,0x8a,0x16,0x1f,0x83,0x16,0xc6,
822
0x3c,0x98,0x0b,0xe6,0x83,0x05,0xe0,0x25,0xb0,0x08,0x24,0x80,0x44,0x90,0x02,0xd2,
823
0x41,0x06,0xc8,0x04,0x11,0xb0,0x6f,0x0c,0x52,0x1d,0xec,0x37,0x1a,0x57,0x82,0x31,
824
0xbc,0x35,0x9c,0x75,0xeb,0x79,0xd9,0xbc,0x3c,0xde,0x26,0x5e,0x11,0x6f,0x1b,0x6f,
825
0x07,0x6f,0x17,0xaf,0x8c,0x57,0xc1,0xdb,0xc7,0xab,0xe6,0xd5,0xf1,0x1a,0x79,0xff,
826
0xe4,0x1d,0xe0,0xb5,0xf2,0x8e,0xf0,0xde,0xe4,0x1d,0xe7,0x75,0xf2,0x4e,0xf3,0xde,
827
0xe1,0xbd,0xcf,0x3b,0xc3,0x3b,0xcf,0xeb,0xe2,0xf5,0xf2,0x2e,0xf1,0x3e,0xe5,0x7d,
828
0xce,0xfb,0x92,0x77,0x95,0xf7,0x1d,0xef,0x07,0x1e,0xdc,0x66,0x35,0xc8,0x6a,0xb0,
829
0x95,0xad,0x95,0xd0,0x4a,0x6c,0xe5,0x68,0x25,0xb5,0x1a,0x6e,0xe5,0x66,0x35,0xd2,
830
0xca,0xd3,0x4a,0x69,0xe5,0x6d,0xe5,0x67,0xf5,0x57,0x8f,0xef,0x40,0x28,0x68,0x41,
831
0x28,0x08,0x07,0x51,0x40,0x0f,0xe2,0xc0,0xed,0xe0,0x2e,0x30,0x0a,0x8c,0x06,0x0f,
832
0x80,0x87,0xc0,0xa3,0xe0,0x09,0xf0,0x24,0x78,0xfa,0x16,0x16,0x4e,0xc2,0xbe,0x29,
833
0x60,0x1a,0x98,0x09,0xe6,0x80,0x79,0xe0,0x05,0xf0,0x22,0x78,0x05,0xbc,0x06,0x16,
834
0x83,0x64,0x90,0x06,0x96,0x82,0xe5,0x60,0x05,0x58,0x0d,0xd6,0x81,0x8d,0x20,0x17,
835
0x14,0x80,0xcd,0x60,0x2b,0xd8,0x0e,0x4a,0xc0,0x6e,0x50,0x0e,0xf6,0x5a,0x55,0x21,
836
0xae,0x05,0x0d,0xa0,0x19,0xb4,0x80,0x43,0xa0,0x8d,0xb3,0xec,0x28,0xe2,0x76,0x70,
837
0x02,0x9c,0x02,0x6f,0x83,0xf7,0xc0,0x87,0xe0,0x1c,0xf8,0x08,0xf4,0x80,0x8b,0xe0,
838
0x13,0xf0,0x19,0xb8,0x02,0xbe,0x06,0xdf,0x82,0xef,0xd9,0x56,0x80,0xa5,0xb5,0xd1,
839
0x68,0x0d,0x04,0xc0,0x06,0xd8,0x03,0x11,0x70,0x00,0xce,0x60,0x18,0x18,0x01,0xdc,
840
0x81,0x1c,0x78,0x01,0x35,0xf0,0x05,0x01,0x40,0x03,0x42,0x40,0x18,0x88,0x04,0x31,
841
0x20,0x16,0xdc,0x06,0xee,0x04,0xf7,0x80,0xfb,0xc0,0xfd,0x60,0x2c,0x78,0x04,0x3c,
842
0x6e,0xcd,0x5e,0x6f,0xff,0xb0,0x7e,0xca,0x7a,0xa2,0xf5,0x33,0xd6,0xcf,0x5a,0xcf,
843
0xb0,0x9e,0x6d,0xfd,0x9c,0xf5,0xf3,0xd6,0x0b,0xad,0x5f,0xb6,0x7e,0xd5,0x9a,0xb1,
844
0x4e,0xb2,0x4e,0xb5,0x5e,0x62,0xbd,0xcc,0x3a,0xcb,0x7a,0x95,0xf5,0x5a,0xeb,0x0d,
845
0xd6,0x39,0xd6,0xf9,0xd6,0x85,0xd6,0x5b,0xac,0x8b,0xad,0x77,0x5a,0x97,0x5a,0xef,
846
0xb1,0xae,0xb4,0xde,0x6f,0x5d,0x63,0x5d,0x6f,0xdd,0x64,0xfd,0xba,0xf5,0x41,0xeb,
847
0xc3,0xd6,0x6f,0x58,0xb3,0x57,0xea,0x5f,0xf9,0x39,0x66,0x7d,0x63,0x56,0x36,0x90,
848
0xfb,0xbf,0xf2,0xe9,0xb4,0x7e,0xdb,0xfa,0x03,0xeb,0xf3,0xd6,0x7f,0xac,0x95,0x1e,
849
0xeb,0x4f,0xad,0xbf,0xb2,0xfe,0xde,0x9a,0x37,0x68,0xc8,0x20,0xd1,0x20,0xe9,0xa0,
850
0x3f,0x77,0x26,0xfc,0x63,0xdf,0xff,0x7c,0x76,0x7c,0x63,0x8f,0x6c,0x90,0xd7,0xa0,
851
0x7e,0xa3,0xdf,0xa0,0x9f,0xd6,0xfe,0x7d,0x9a,0x3f,0x3d,0xcf,0x37,0xf4,0xfe,0xfd,
852
0x96,0xfb,0x6f,0xb1,0x1d,0x3c,0x88,0x8d,0x23,0x07,0xdd,0xdc,0x62,0xff,0xaf,0xea,
853
0xfd,0xb4,0xcf,0xa6,0x10,0x37,0xe8,0xee,0x41,0xf7,0x0f,0x62,0xf7,0x3e,0x3a,0xe8,
854
0xa7,0xde,0xf9,0xf7,0x57,0x1b,0xff,0xca,0xff,0xb7,0x2a,0x39,0xb0,0x35,0x7e,0xd0,
855
0x33,0x83,0xfa,0x6f,0xe9,0xc9,0xdf,0x6f,0xc1,0x5f,0xf7,0x99,0x39,0xc8,0xf8,0x0b,
856
0xe7,0xb7,0xff,0xfa,0x39,0xea,0xff,0x17,0xe7,0xf0,0xb7,0x9d,0xf5,0x5f,0xae,0x35,
857
0x7f,0xd0,0xbf,0x1e,0x7d,0xbf,0xd4,0x42,0xff,0x2f,0xfa,0xf0,0xe5,0x41,0x8b,0x07,
858
0xfd,0x19,0xeb,0xc7,0x5f,0xfa,0xa4,0x0f,0xfa,0x4f,0xde,0x9b,0x96,0x0d,0xfa,0x79,
859
0x8f,0x57,0x5f,0xdf,0x97,0x7d,0x3d,0x57,0x78,0x3d,0xb7,0xfd,0x17,0xed,0x2b,0x1b,
860
0xf4,0xf3,0x6b,0x6a,0x3f,0xf6,0x35,0x0c,0x3a,0x30,0xe8,0x8d,0x41,0xa7,0x06,0xbd,
861
0xff,0x93,0x9a,0xdd,0xbf,0xa1,0xa7,0x9f,0xdc,0xc2,0xbe,0x2f,0xaf,0xef,0xbb,0x76,
862
0x3d,0x67,0xc9,0x1f,0xc8,0x0d,0xe6,0xff,0x52,0x5b,0x43,0xf9,0x7f,0xe6,0x93,0xc5,
863
0x99,0x3f,0x9c,0x2f,0xe3,0xcb,0xf9,0x4a,0xbe,0x0f,0x3f,0x80,0xaf,0xe5,0xeb,0xf8,
864
0x91,0x7c,0x3d,0x3f,0x9e,0x7f,0x27,0x7f,0x14,0x7f,0x0c,0x7f,0x2c,0xff,0x51,0xfe,
865
0x38,0xfe,0x53,0xfc,0x49,0xfc,0xa9,0xfc,0x19,0xfc,0x39,0xfc,0xf9,0xfc,0x85,0xfc,
866
0x57,0xf8,0x09,0xfc,0x24,0x7e,0x1a,0x3f,0x83,0x9f,0xc5,0x5f,0xcd,0x5f,0xcf,0xcf,
867
0xe1,0x17,0xf0,0x8b,0xf8,0xc5,0xfc,0x12,0x7e,0xbf,0xb1,0x8c,0x7f,0x63,0x64,0x54,
868
0xf2,0xff,0xca,0xab,0xb3,0x8a,0xff,0x67,0xb4,0x42,0x44,0x64,0xfc,0xaf,0xf9,0xb0,
869
0xfe,0xac,0xe3,0x37,0xf1,0x5b,0xf8,0xad,0xfc,0x37,0xf8,0xed,0xfc,0xfe,0xff,0xe0,
870
0xec,0xe2,0xdf,0xf3,0x14,0x5d,0xff,0xfc,0xda,0x3d,0xfc,0x8f,0x7e,0x4e,0x63,0x65,
871
0xf1,0x1d,0x8f,0x5d,0x43,0x0c,0xc2,0xba,0x41,0x6b,0xd5,0xc9,0x7f,0x8b,0x7f,0xb3,
872
0xc2,0x7b,0xfc,0x33,0xfc,0x0b,0xfc,0x1e,0xfe,0x25,0xfe,0x65,0xfe,0x15,0xfe,0x55,
873
0xfe,0x35,0xbe,0x91,0xcf,0x13,0xf0,0x05,0x55,0x7c,0x1b,0x81,0x50,0x20,0x11,0x38,
874
0x0b,0x86,0x0b,0x64,0x02,0xb9,0x40,0x29,0xf0,0x11,0x04,0x08,0xb4,0x02,0x9d,0x20,
875
0x52,0xa0,0x17,0xc4,0x0b,0xee,0x14,0x8c,0x12,0x8c,0x11,0x8c,0x15,0x3c,0x2a,0x18,
876
0x27,0x78,0x4a,0x30,0x49,0x30,0x55,0x30,0x43,0x30,0x47,0x30,0x5f,0xb0,0x50,0xf0,
877
0x8a,0x20,0x41,0xc0,0xb6,0x9c,0x24,0x48,0x13,0x64,0x08,0xfe,0x2a,0x7f,0x5b,0xd0,
878
0xf3,0xc4,0x83,0xf7,0xd8,0xf7,0x8a,0xeb,0x2d,0x7e,0xfa,0x5e,0x11,0x73,0x6d,0x9a,
879
0x6f,0x29,0xc3,0xba,0x9c,0x7d,0xaf,0xe8,0x47,0x16,0x94,0x25,0x58,0x25,0x58,0x2b,
880
0xe0,0x71,0xef,0x21,0xd9,0xb7,0x3e,0x1b,0x05,0x76,0x28,0xe5,0x88,0xd2,0xfe,0x16,
881
0x23,0x28,0xdd,0x22,0x57,0xb0,0x49,0x20,0xe3,0x4a,0x6f,0x11,0x54,0x58,0xf8,0xd0,
882
0x76,0x81,0x69,0x55,0xca,0xae,0x39,0x45,0x68,0x87,0x7d,0x3b,0xc9,0xee,0xb9,0x97,
883
0xdb,0xf3,0xcb,0x76,0x5d,0xfd,0x53,0x56,0xa6,0xbb,0x04,0xd6,0x54,0x26,0x58,0x45,
884
0x1b,0x05,0x36,0x54,0x21,0xd8,0x27,0xa8,0x16,0xec,0xb2,0xd8,0x61,0x51,0x27,0x68,
885
0x14,0xbc,0x2e,0x38,0x28,0x38,0x2c,0x38,0x2a,0x68,0x17,0x9c,0x10,0xec,0xb3,0x38,
886
0x25,0x78,0x5b,0x50,0x6d,0xf1,0x9e,0xe0,0x43,0xc1,0x11,0x8b,0x73,0x82,0xcd,0x96,
887
0xa7,0x2d,0x3e,0x12,0xbc,0x63,0xb1,0xd5,0x52,0x4b,0xbd,0x82,0x4b,0x82,0xf3,0x16,
888
0x3a,0xde,0xa7,0x38,0x03,0x5f,0x80,0xaf,0xc1,0x77,0xa0,0x1f,0x58,0x0e,0x36,0x1a,
889
0x07,0x81,0x21,0xc0,0x1e,0x88,0x81,0x13,0x18,0x06,0xdc,0x80,0x07,0xf0,0x02,0xde,
890
0xc0,0x1f,0x68,0x40,0x28,0x88,0x00,0x31,0x20,0x0e,0xdc,0x01,0xee,0x01,0xa3,0xc1,
891
0x83,0xe0,0x11,0xf0,0x04,0x18,0x0f,0x26,0x82,0x29,0x60,0x3a,0x98,0x0d,0xe6,0x81,
892
0x05,0xe0,0x65,0xf0,0x1a,0x48,0x04,0xa9,0x60,0x29,0xc8,0x04,0xab,0xc0,0x3a,0x90,
893
0x0d,0xf2,0xc1,0x66,0xb0,0x0d,0xec,0x04,0xbb,0x41,0x05,0xd8,0x0f,0x6a,0x41,0x23,
894
0x78,0x1d,0x1c,0x02,0x47,0xc0,0x31,0x70,0x02,0x9c,0x06,0xef,0x82,0x0f,0xc1,0x79,
895
0xd0,0x0d,0x2e,0x82,0x4f,0xc1,0x17,0xe0,0x6b,0xf0,0x1d,0xe8,0x07,0x96,0x43,0xd0,
896
0x7f,0x30,0x04,0xd8,0x03,0x31,0x70,0x1a,0x72,0xc3,0xfb,0xc3,0x86,0xb0,0xaa,0xf0,
897
0x05,0xf6,0x8d,0x04,0x0a,0xa0,0x06,0x7e,0x20,0x08,0x84,0x80,0x70,0x10,0x0d,0x62,
898
0xc1,0xed,0xe0,0x6e,0x70,0x1f,0x78,0x00,0x3c,0x0c,0x1e,0x07,0x4f,0x82,0x09,0xe0,
899
0x19,0x30,0x0d,0xcc,0x02,0xcf,0x81,0x17,0xc0,0x4b,0xe0,0x55,0xb0,0x18,0xa4,0x80,
900
0x25,0x60,0x39,0x58,0x09,0xd6,0x82,0x8d,0x20,0x0f,0x14,0x82,0xad,0x60,0x07,0x28,
901
0x05,0xe5,0x60,0x1f,0xa8,0x01,0x0d,0xe0,0x9f,0xe0,0x20,0x68,0x03,0x6f,0x82,0x0e,
902
0x70,0x0a,0xbc,0x03,0x3e,0x18,0xf2,0xf3,0x91,0x75,0x6e,0x48,0xd7,0x90,0xbe,0x21,
903
0x9f,0x0c,0xf9,0x7c,0xc8,0x57,0x43,0xbe,0x1d,0xf2,0xc3,0x90,0x9f,0xde,0x77,0x2c,
904
0x6c,0xac,0x6d,0x06,0xdb,0xd8,0xd9,0x88,0x6c,0x1c,0x6d,0x6e,0x75,0xff,0x71,0xb1,
905
0x19,0x61,0x33,0xd2,0x46,0x61,0xa3,0xb6,0xf1,0xb3,0x09,0xb2,0x09,0xb1,0xf9,0xe9,
906
0xf1,0x70,0x9b,0x68,0x9b,0x58,0x9b,0xdb,0x6d,0xee,0xb6,0xb9,0xcf,0xe6,0x01,0x9b,
907
0x87,0x6d,0x7e,0xda,0xfe,0xe3,0x36,0x4f,0xda,0x4c,0xb0,0x79,0xc6,0x66,0x9a,0xcd,
908
0xac,0x5b,0xb6,0xdf,0x6f,0x7c,0x0e,0xfb,0x5f,0x00,0x2f,0x81,0x57,0x7f,0xd6,0xfe,
909
0x62,0x9b,0x14,0x9b,0x25,0x36,0xcb,0x6d,0x56,0xda,0xac,0xb5,0xd9,0x68,0x93,0x87,
910
0xe3,0x43,0x70,0xc5,0x0d,0x05,0x12,0xe0,0x04,0x5c,0x80,0x2b,0x90,0x71,0xef,0x9e,
911
0x0a,0x6d,0x8a,0x6d,0x4a,0x6d,0x2a,0x6d,0x6a,0x6c,0x9a,0x6c,0x0e,0xda,0xbc,0x61,
912
0xf3,0xd3,0xed,0x0e,0x9b,0xb7,0x6c,0x3e,0xb0,0xb9,0x60,0xd3,0x67,0x73,0xd9,0xe6,
913
0x2b,0x9b,0x6b,0x3f,0xdb,0xb6,0xb0,0xe5,0xdb,0xda,0xd9,0x4a,0x6c,0x5d,0x6c,0x65,
914
0xb6,0x0a,0x5b,0x1f,0xdb,0x9f,0x6e,0xb3,0x36,0x05,0xd9,0xea,0x6c,0xa3,0x6c,0xd9,
915
0xbe,0xc4,0xda,0xde,0x69,0x3b,0xca,0x76,0x8c,0xed,0x10,0x9e,0xce,0x76,0xac,0xed,
916
0xc7,0x96,0x63,0x6d,0x1f,0xb5,0x1d,0x67,0x3b,0xc1,0x76,0xaa,0xed,0x4c,0xee,0xf8,
917
0x73,0xb6,0x0b,0x6d,0x87,0xf2,0x5e,0xb1,0x95,0xf0,0xa6,0xda,0x26,0xd8,0xa6,0xd8,
918
0x66,0xd8,0x9a,0x7a,0xb5,0xd2,0x76,0xc0,0x17,0x6b,0x6c,0x37,0xd8,0xe6,0xda,0xb2,
919
0x6f,0xc8,0x36,0xd9,0x6e,0xb3,0xdd,0x65,0x3e,0x5e,0x61,0x3b,0xd0,0xff,0x7d,0xb6,
920
0x35,0xb6,0x0d,0xb6,0xae,0xbc,0x7f,0xda,0x1e,0xb4,0xb5,0xe2,0xbd,0xc1,0xd5,0x7b,
921
0xd3,0xb6,0xd3,0xf6,0x6d,0xae,0xfd,0x0f,0x6c,0x2f,0xd8,0xba,0xf0,0x7a,0x6c,0x65,
922
0xbc,0x4e,0xdb,0x78,0xba,0x64,0xcb,0x7e,0x7f,0x71,0xab,0x60,0x7a,0xee,0x98,0x34,
923
0x2f,0xdb,0xde,0xf0,0xee,0x15,0xdb,0x7f,0xbd,0xae,0x30,0xfe,0xc2,0xb7,0x23,0x57,
924
0x6d,0xfb,0x51,0x53,0x60,0x27,0xb4,0xbb,0x3e,0x4e,0x90,0x73,0xb5,0xfb,0x69,0x2b,
925
0xee,0x76,0x72,0x3b,0x2f,0xbb,0x5f,0xbe,0xef,0xa9,0x7f,0x72,0x2c,0xe4,0xc6,0x83,
926
0x92,0x6e,0xa8,0xde,0xb4,0x93,0x42,0xed,0x44,0xdc,0x91,0x30,0xbb,0x08,0xbb,0x28,
927
0xbb,0x18,0x3b,0x83,0x5d,0x9c,0xdd,0x6d,0x76,0x77,0xd8,0xdd,0x63,0x77,0xaf,0xdd,
928
0x68,0xbb,0xe1,0x38,0x3e,0x9a,0xd8,0xef,0x67,0x6e,0x7d,0x1c,0xe3,0x1d,0xcf,0x83,
929
0x11,0x14,0x80,0x67,0x82,0xf0,0xfa,0xd3,0x43,0xc6,0x7d,0x1f,0x75,0xeb,0xe7,0xef,
930
0xfd,0x76,0xff,0xde,0x9d,0x7c,0xac,0xdd,0xa3,0x76,0xd6,0x34,0x0e,0xb5,0x9e,0xb2,
931
0x9b,0x64,0x97,0xc7,0x7e,0x63,0x61,0xc7,0x3e,0xad,0x4c,0xe1,0x2b,0x3c,0xb5,0x44,
932
0x50,0x75,0x86,0x1f,0x87,0xd3,0x0c,0xae,0x6d,0xd3,0x37,0x62,0x6c,0x60,0xb7,0x66,
933
0xdb,0x3d,0x67,0xf7,0x02,0xf6,0xb3,0xdf,0x89,0x4d,0xe0,0x99,0x52,0x47,0x7a,0x8e,
934
0xfb,0x4e,0x0d,0xb3,0x60,0xee,0x5b,0xb5,0x17,0xed,0x5c,0xd0,0x87,0x45,0x76,0x09,
935
0x76,0x89,0x76,0x29,0xf0,0x07,0x56,0x17,0x76,0x77,0xe3,0x59,0xa5,0xe2,0xdd,0xcd,
936
0x5b,0x76,0xdd,0x5e,0x3e,0xf7,0xec,0x63,0x9f,0x92,0x37,0xdb,0xb7,0xc2,0x6e,0x9d,
937
0x5d,0xae,0x5d,0x91,0xdd,0x0e,0xbb,0x32,0xbb,0x7d,0x76,0x75,0x76,0xff,0xb4,0x6b,
938
0xb5,0x7b,0xd3,0xae,0xd3,0xee,0x1d,0xbb,0x33,0x76,0x5d,0x76,0x97,0xd0,0xda,0x67,
939
0x76,0x57,0xec,0xae,0xda,0xf9,0xd0,0x77,0x76,0x3f,0xd8,0x59,0xd8,0x0f,0xb2,0x0f,
940
0xa0,0xc1,0xf6,0xb6,0xf6,0xce,0xdc,0x77,0x7a,0x2e,0xf4,0x6b,0xc7,0xcd,0x73,0x72,
941
0xfb,0x1b,0x8a,0x0e,0xf6,0x3f,0x5d,0x3d,0xfc,0x37,0x7e,0x86,0xd9,0x8f,0x44,0x3f,
942
0x7c,0xec,0x35,0xf6,0xff,0x69,0xe5,0x28,0x7b,0xc3,0x1f,0xd6,0xfc,0xed,0xeb,0xd7,
943
0x5b,0x5c,0x3d,0xf6,0x77,0xda,0xdf,0x63,0x7f,0x9f,0xfd,0xfd,0xf6,0x63,0xed,0x1f,
944
0xb1,0x7f,0xdc,0xfe,0x1f,0xf6,0x4f,0xd9,0x4f,0xb4,0x7f,0xc6,0x7e,0x9a,0xfd,0x2c,
945
0xfb,0xe7,0xec,0x5f,0xb0,0x7f,0xc9,0xfe,0x55,0xfb,0xc5,0xf6,0x29,0xf6,0x4b,0xec,
946
0x33,0xed,0x57,0xdb,0x6f,0xb0,0xcf,0xb3,0xdf,0x6c,0x5f,0x6c,0xbf,0xcb,0xbe,0xdc,
947
0x7e,0xbf,0x7d,0x9d,0xfd,0x6f,0xd5,0x6d,0xb6,0x3f,0x60,0x7f,0xd8,0xfe,0xa8,0xfd,
948
0x71,0xfb,0x93,0xf6,0x6f,0xdb,0xbf,0x6f,0x7f,0xd6,0xfe,0x23,0xfb,0x5e,0xfb,0x8f,
949
0xed,0x3f,0xb3,0xff,0xd2,0xfe,0x1b,0xfb,0xef,0xed,0x49,0x68,0x25,0x14,0x08,0x6d,
950
0x85,0x43,0x85,0x0e,0x42,0xa9,0xd0,0x55,0xe8,0x2e,0xf4,0x14,0xfe,0x9e,0x6f,0x9a,
951
0x7f,0x4f,0x9d,0x50,0xbb,0x3f,0x7e,0x16,0x55,0x42,0xe3,0xff,0xa9,0x4f,0x88,0x30,
952
0x5c,0x18,0xf5,0x27,0xf6,0xc9,0xf0,0x27,0xb5,0x75,0x87,0xf0,0x1e,0xe1,0x68,0xe1,
953
0x83,0xc2,0x47,0x84,0x4f,0x08,0xc7,0x0b,0x27,0x0a,0xa7,0x08,0xa7,0x0b,0x67,0x0b,
954
0xe7,0x09,0x17,0x08,0x5f,0x16,0xbe,0x26,0x4c,0x14,0xa6,0x0a,0x97,0x0a,0x33,0x85,
955
0xab,0x84,0xeb,0x84,0xd9,0xc2,0x7c,0xe1,0x66,0xe1,0x36,0xe1,0x4e,0xe1,0x6e,0x61,
956
0x85,0x70,0xbf,0xb0,0x56,0xd8,0x28,0x7c,0x5d,0x78,0x48,0x78,0x44,0x78,0x4c,0x78,
957
0x42,0x78,0x5a,0xf8,0xae,0xf0,0x43,0xe1,0x79,0x61,0xb7,0xf0,0xa2,0xf0,0x53,0xe1,
958
0x17,0xc2,0xaf,0x85,0xdf,0x09,0xfb,0x85,0x96,0x43,0xff,0x6a,0xbf,0x0e,0x82,0xc2,
959
0x90,0xa1,0x76,0x43,0x45,0x9c,0x92,0x03,0x62,0x29,0x70,0x05,0xab,0xb0,0x06,0xc8,
960
0x12,0xec,0xc2,0x7c,0xde,0x9d,0x3b,0xe6,0xf9,0x23,0x5b,0x24,0x18,0xaf,0xaa,0xa1,
961
0x3e,0x43,0xfd,0xb1,0x57,0x03,0x42,0x41,0x04,0x88,0x01,0x71,0xe0,0x0e,0x70,0x0f,
962
0x18,0x0d,0x1e,0x04,0x8f,0x80,0x27,0xc0,0x78,0x30,0x11,0x4c,0x01,0xd3,0xc1,0x6c,
963
0x30,0x0f,0x2c,0x00,0x2f,0x83,0xd7,0x40,0x22,0x48,0x05,0x4b,0x41,0x26,0x6b,0x09,
964
0x58,0x07,0xb2,0x41,0x3e,0xd8,0x0c,0xb6,0x81,0x9d,0x60,0x37,0xa8,0x00,0xfb,0x41,
965
0x2d,0x68,0x04,0xaf,0x83,0x43,0xe0,0x08,0x38,0x06,0x4e,0x80,0xd3,0xe0,0x5d,0xf0,
966
0x21,0x38,0x0f,0xba,0xc1,0x45,0xf0,0x29,0xf8,0xe2,0x67,0x5e,0xfe,0x1a,0x7b,0xbe,
967
0xbb,0xbe,0xb7,0x7f,0xa8,0xf1,0x3f,0xf6,0xbe,0xf3,0xc7,0x77,0x29,0x4b,0x91,0xf1,
968
0x77,0xbd,0xfd,0xfb,0xad,0x6f,0xb8,0x07,0x89,0xfe,0x3b,0xae,0xfe,0x21,0xa2,0x5f,
969
0xf2,0x80,0xbd,0x48,0x2c,0x72,0x12,0x0d,0x13,0xb9,0x89,0x3c,0x44,0x5e,0x22,0x6f,
970
0x91,0xbf,0x48,0x23,0x0a,0x15,0x45,0x88,0x62,0x44,0x71,0xa2,0x3b,0x44,0xf7,0x88,
971
0x46,0x8b,0x1e,0x14,0x3d,0x22,0x7a,0x42,0x34,0x5e,0x34,0x51,0x34,0x45,0x34,0x5d,
972
0x34,0x5b,0x34,0x4f,0xb4,0x40,0xf4,0xb2,0xe8,0x35,0x51,0xa2,0x28,0x55,0xb4,0x54,
973
0x94,0x29,0x5a,0x25,0x5a,0x27,0xca,0x16,0xe5,0x8b,0x36,0x8b,0xb6,0x89,0x76,0x8a,
974
0x76,0x8b,0x2a,0x44,0xfb,0x45,0xb5,0xa2,0x46,0xd1,0xeb,0xa2,0x43,0xa2,0x23,0xa2,
975
0x63,0xa2,0x13,0xa2,0xd3,0xa2,0x77,0x45,0x1f,0x8a,0xce,0x8b,0xba,0x45,0x17,0x45,
976
0x9f,0x8a,0xbe,0x10,0x7d,0x2d,0xfa,0x4e,0xd4,0x2f,0xb2,0x14,0x0f,0x12,0x0f,0x11,
977
0xdb,0x8b,0xc5,0x62,0x27,0xf1,0x30,0xb1,0x9b,0xd8,0x43,0xec,0x25,0xf6,0x16,0xfb,
978
0x8b,0x35,0xe2,0x50,0x71,0x84,0x38,0x46,0x1c,0x27,0xbe,0x43,0x7c,0x8f,0x78,0xb4,
979
0xf8,0x41,0xf1,0x23,0xe2,0x27,0xc4,0xe3,0xc5,0x13,0xc5,0x53,0xc4,0xd3,0xc5,0xb3,
980
0xc5,0xf3,0xc4,0x0b,0xc4,0x2f,0x8b,0x5f,0x13,0x27,0x8a,0x53,0xc5,0x4b,0xc5,0x99,
981
0xe2,0x55,0xe2,0x75,0xe2,0x6c,0x71,0xbe,0x78,0xb3,0x78,0x9b,0x78,0xa7,0x78,0xb7,
982
0xb8,0x42,0xbc,0x5f,0x5c,0x2b,0x6e,0x14,0xbf,0x2e,0x3e,0x24,0x3e,0x22,0x3e,0x26,
983
0x3e,0x21,0x3e,0x2d,0x7e,0x57,0xfc,0xa1,0xf8,0xbc,0xb8,0x5b,0x7c,0x51,0xfc,0xa9,
984
0xf8,0x0b,0xf1,0xd7,0xe2,0xef,0xc4,0xfd,0x62,0x4b,0xc9,0x20,0xc9,0x10,0x89,0xbd,
985
0x44,0x2c,0x71,0x92,0x0c,0x93,0xb8,0x49,0x3c,0x24,0x5e,0x12,0x6f,0x89,0xbf,0x44,
986
0x23,0x09,0x95,0x44,0x48,0x62,0x24,0x71,0x92,0x3b,0x24,0xf7,0x48,0x46,0x4b,0x1e,
987
0x94,0x3c,0x22,0x79,0x42,0x32,0x5e,0x32,0x51,0x32,0x45,0x32,0x5d,0x32,0x5b,0x32,
988
0x4f,0xb2,0x40,0xf2,0xb2,0xe4,0x35,0x49,0xa2,0x24,0x55,0xb2,0x54,0x92,0x29,0x59,
989
0x25,0x59,0x27,0xc9,0x96,0xe4,0x4b,0x36,0x4b,0xb6,0x49,0x76,0x4a,0x76,0x4b,0x2a,
990
0x24,0xfb,0x25,0xb5,0x92,0x46,0xc9,0xeb,0x92,0x43,0x92,0x23,0x92,0x63,0x92,0x13,
991
0x92,0xd3,0x92,0x77,0x25,0x1f,0x4a,0xce,0x4b,0xba,0x25,0x17,0x25,0x9f,0x4a,0xbe,
992
0x90,0x7c,0x2d,0xf9,0x4e,0xd2,0x2f,0xb1,0x74,0x18,0xe4,0x30,0xc4,0xc1,0xde,0x41,
993
0xec,0xe0,0xe4,0x30,0xcc,0xc1,0xcd,0xc1,0xc3,0xc1,0xcb,0xc1,0xdb,0xc1,0xdf,0x41,
994
0xe3,0x10,0xea,0x10,0xe1,0x10,0xe3,0x10,0xe7,0x70,0x87,0xc3,0x3d,0x0e,0xa3,0x1d,
995
0x1e,0x74,0x78,0xc4,0xe1,0x09,0x87,0xf1,0x0e,0x13,0x1d,0xfa,0x8d,0x7f,0x7e,0x60,
996
0x57,0x08,0x53,0x1c,0xfe,0x33,0xa3,0xf0,0x59,0xe8,0x4c,0x17,0xcd,0x74,0x98,0xeb,
997
0xf0,0x47,0xae,0x6e,0xf6,0xf3,0xbc,0xc3,0x4b,0x5c,0x1b,0xaf,0x39,0xfc,0x77,0x3f,
998
0x95,0x53,0x1c,0xfe,0xea,0xfb,0x62,0xbf,0x71,0x99,0xc3,0x0a,0x87,0x35,0x0e,0x1b,
999
0x1c,0x72,0x1d,0x36,0x39,0x6c,0x71,0xd8,0xee,0xb0,0xcb,0x61,0x8f,0xc3,0x5e,0x87,
1000
0x6a,0x87,0x7a,0x87,0x66,0x87,0x03,0x0e,0x87,0x1d,0x8e,0x3a,0x1c,0x77,0x38,0xe9,
1001
0xf0,0xb6,0xc3,0xfb,0x0e,0x67,0x1d,0x3e,0x72,0xe8,0x75,0xf8,0xd8,0xe1,0x33,0x87,
1002
0x2f,0x1d,0xbe,0x71,0xf8,0xde,0x81,0x1c,0xad,0x1c,0x05,0x8e,0xb6,0x8e,0x43,0x1d,
1003
0x1d,0x1c,0xa5,0x8e,0xae,0x8e,0xee,0x8e,0x9e,0x8e,0x2a,0x47,0x5f,0xc7,0x40,0xc7,
1004
0x60,0xc7,0x30,0xc7,0x28,0x47,0x83,0xe3,0x6d,0x8e,0x77,0x39,0xde,0xeb,0x78,0xbf,
1005
0xe3,0x43,0x8e,0x44,0x8f,0x39,0xfe,0xc3,0xf1,0x69,0xc7,0xc9,0x8e,0xcf,0x3a,0xce,
1006
0x74,0x9c,0xeb,0xf8,0xbc,0xe3,0x8b,0x8e,0x8b,0x1c,0x19,0xc7,0x64,0xc7,0x74,0xc7,
1007
0x65,0x8e,0x2b,0x1c,0xd7,0x38,0x6e,0x70,0xcc,0x75,0xdc,0xe4,0xb8,0xc5,0x71,0xbb,
1008
0xe3,0x2e,0xc7,0x3d,0x8e,0x7b,0x1d,0xab,0x1d,0xeb,0x1d,0x9b,0x1d,0x0f,0x38,0x1e,
1009
0x76,0x3c,0xea,0x78,0xdc,0xf1,0xa4,0xe3,0xdb,0x8e,0xef,0x3b,0x9e,0x75,0xfc,0xc8,
1010
0xb1,0xd7,0xf1,0x63,0xc7,0xcf,0x1c,0xbf,0x74,0xfc,0xc6,0xf1,0x7b,0x47,0x93,0x57,
1011
0xec,0x71,0x67,0x22,0x27,0x2b,0x27,0x81,0x93,0xad,0xd3,0x50,0x27,0x07,0x27,0x37,
1012
0x91,0xd4,0xc9,0xd5,0xc9,0xdd,0xc9,0xd3,0xc9,0xff,0x0f,0xdf,0x7f,0x55,0x4e,0xfe,
1013
0x4e,0xc1,0x4e,0x11,0x4e,0x06,0xa7,0x3b,0x9c,0xee,0x75,0x7a,0xd0,0xe9,0x31,0xa7,
1014
0xf1,0x4e,0x93,0x9d,0xa6,0x3b,0xcd,0x75,0x5a,0xe0,0xb4,0xc8,0x29,0xd1,0x29,0xdd,
1015
0x29,0xd3,0x69,0x8d,0x53,0xb6,0xd3,0x26,0xa7,0x6d,0x4e,0xbb,0x9c,0x2a,0x9c,0xaa,
1016
0x9d,0x1a,0x9d,0x0e,0x38,0x1d,0x71,0x3a,0xee,0x74,0xda,0xe9,0x8c,0x53,0xbf,0xb1,
1017
0xd7,0xe9,0x53,0xa7,0x2f,0x9d,0xbe,0x73,0x22,0xe7,0x41,0xce,0xb6,0xce,0x62,0x67,
1018
0xa9,0xb3,0x9b,0xb3,0xa7,0xb3,0xb7,0x73,0xa0,0x73,0xa8,0x73,0x94,0x73,0x9c,0xf3,
1019
0x5d,0xce,0xa3,0x9d,0x1f,0x72,0x7e,0xc2,0xf9,0x69,0xe7,0x29,0xce,0x33,0x9d,0xe7,
1020
0x39,0xbf,0xe8,0xfc,0x9a,0x73,0xb2,0xf3,0x52,0xe7,0x15,0xce,0xeb,0x9c,0x73,0x9d,
1021
0x37,0x3b,0x6f,0x77,0xde,0xed,0xbc,0xd7,0xb9,0xd6,0xb9,0xd9,0xf9,0x80,0xb3,0x93,
1022
0xf8,0xb0,0xf3,0x4f,0xed,0x3b,0xea,0x7c,0xdc,0xb9,0xd3,0xf9,0xb4,0xf3,0x3b,0xce,
1023
0xef,0x3b,0x9f,0x71,0x3e,0xef,0xdc,0xe5,0xdc,0xeb,0x7c,0xc9,0xf9,0x53,0xe7,0xcf,
1024
0x9d,0xbf,0x74,0xbe,0xea,0xfc,0x9d,0xf3,0x32,0x9c,0xd9,0x2d,0x38,0xa7,0xec,0x59,
1025
0x7c,0x9f,0x3b,0x7f,0x37,0xce,0xde,0x0f,0xce,0x16,0x52,0x6b,0xe9,0x60,0xa9,0x9d,
1026
0x54,0x24,0x75,0x94,0xba,0x48,0x47,0x48,0x47,0x4a,0x15,0x52,0xb5,0xd4,0x4f,0x1a,
1027
0x24,0x0d,0x91,0x46,0x49,0xe3,0xa5,0x37,0x7c,0x7b,0xa7,0x74,0x94,0x74,0x8c,0x34,
1028
0x42,0x34,0x56,0x3a,0x5d,0xa4,0xc1,0xbd,0x76,0x3c,0xee,0xc2,0xdb,0x24,0x4b,0x45,
1029
0xde,0xe2,0x47,0xa5,0xe3,0xa4,0x4f,0x49,0x27,0x49,0xa7,0x4a,0x67,0x48,0xe7,0x48,
1030
0xe7,0x4b,0x17,0x4a,0x5f,0x91,0x6e,0x16,0x25,0x48,0x93,0xa4,0x69,0xd2,0x0c,0x69,
1031
0x96,0x74,0xb5,0x74,0xbd,0x34,0x47,0x6a,0x3a,0x37,0x05,0xd2,0x22,0x69,0xb1,0xb4,
1032
0x44,0x5a,0x26,0xad,0x94,0x56,0x49,0xeb,0xa4,0x4d,0xd2,0x16,0x69,0xab,0xf4,0x88,
1033
0xf4,0x4d,0xe9,0x71,0x69,0xa7,0xf4,0xb4,0xf4,0x1d,0xe9,0xfb,0xd2,0x33,0xd2,0xf3,
1034
0xd2,0x2e,0x69,0xaf,0xf4,0x92,0xf4,0x53,0xe9,0xe7,0xd2,0x2f,0xa5,0xdf,0x4a,0xfb,
1035
0xa5,0x3c,0x17,0x81,0x8b,0x9d,0x8b,0xd8,0xc5,0xd9,0xc5,0xd5,0x65,0xa4,0x8b,0xd2,
1036
0xc5,0xcf,0x45,0xeb,0x12,0xea,0x12,0xe1,0x12,0xed,0x12,0xeb,0x72,0xbb,0xcb,0xdd,
1037
0x2e,0xf7,0xb9,0x3c,0xe0,0xf2,0xb0,0xcb,0xe3,0x2e,0x4f,0xba,0x4c,0x70,0x79,0xc6,
1038
0x65,0x9a,0xcb,0x2c,0x97,0xe7,0x5c,0x5e,0x70,0x79,0xc9,0xe5,0x55,0x97,0xc5,0x2e,
1039
0x29,0x2e,0x4b,0x5c,0x96,0xbb,0xac,0x74,0x59,0xeb,0xb2,0xd1,0x25,0xcf,0xa5,0xd0,
1040
0x65,0xab,0xcb,0x0e,0x97,0x52,0x97,0x72,0x97,0x7d,0x2e,0x35,0x2e,0x0d,0x2e,0xff,
1041
0x74,0x39,0xe8,0xd2,0xe6,0xf2,0xa6,0x4b,0x87,0xcb,0x29,0x97,0x77,0x5c,0x3e,0x70,
1042
0x39,0xe7,0xd2,0xe5,0xd2,0xe7,0xf2,0x89,0xcb,0xe7,0x2e,0x5f,0xb9,0x7c,0xeb,0xf2,
1043
0x83,0x8b,0xd5,0x30,0xd1,0x30,0xb7,0x61,0x3e,0xc3,0x42,0x86,0xc5,0x0d,0xbb,0x77,
1044
0xd8,0x23,0xc3,0xa6,0x0c,0x9b,0x3f,0xec,0xd5,0x61,0x69,0xc3,0x56,0x0e,0xcb,0x1f,
1045
0x56,0x32,0x6c,0xdf,0xb0,0xa6,0x61,0x87,0x86,0x1d,0x1f,0xf6,0xc1,0xb0,0x8b,0xc3,
1046
0x3e,0x1f,0x66,0x31,0xdc,0x61,0xb8,0xe7,0x70,0xff,0xe1,0x31,0xc3,0x47,0x0f,0x1f,
1047
0x37,0xfc,0x99,0xe1,0x73,0x86,0xbf,0x34,0x3c,0x75,0xf8,0xba,0xe1,0x45,0xc3,0x4b,
1048
0x87,0x57,0x0d,0xff,0xe7,0xf0,0xc3,0xc3,0xdb,0x87,0x9f,0x1e,0xfe,0xc1,0xf0,0x9e,
1049
0xe1,0x9f,0x0f,0xb7,0x70,0xb5,0x71,0x95,0xba,0xaa,0x5c,0x35,0xae,0xe1,0xae,0x06,
1050
0xd7,0xfb,0x5d,0x9f,0x74,0x9d,0xe5,0xba,0xd0,0x35,0xcd,0x35,0xd3,0x75,0x83,0xeb,
1051
0x66,0xd7,0x5d,0xae,0xfb,0x5d,0x9b,0x5d,0xdf,0x74,0x7d,0xcb,0xf5,0x43,0xd7,0x5e,
1052
0xd7,0x2f,0x5c,0xbf,0x77,0x1d,0x3c,0x42,0x32,0x62,0xc4,0x08,0xe5,0x08,0xdd,0x88,
1053
0xdb,0x46,0x8c,0x1a,0x31,0x6e,0xc4,0xc4,0x11,0x73,0x46,0x2c,0x1a,0x91,0x3a,0x62,
1054
0xc5,0x88,0xec,0x11,0xc5,0x23,0x76,0x8f,0xa8,0x1e,0x71,0x70,0xc4,0xd1,0x11,0xef,
1055
0x8f,0xe8,0x1e,0x71,0x69,0xc4,0x67,0x23,0xbe,0x1a,0xf1,0xdd,0x08,0xe3,0x08,0x2b,
1056
0xb7,0xc1,0x6e,0xf6,0x6e,0x12,0x37,0xa9,0x9b,0x9b,0x9b,0xa7,0x9b,0xb7,0x5b,0xa0,
1057
0x5b,0xa8,0x5b,0x94,0x5b,0x9c,0xdb,0x5d,0x6e,0xa3,0xdd,0x1e,0x72,0x7b,0xc2,0xed,
1058
0x69,0xb7,0x29,0x6e,0x33,0xdd,0xe6,0xb9,0x2d,0x70,0x7b,0xc9,0x6d,0x91,0x1b,0xe3,
1059
0x96,0xe4,0x96,0xea,0xb6,0xc4,0x6d,0xb9,0xdb,0x4a,0xb7,0x35,0x6e,0x39,0x6e,0x9b,
1060
0xdd,0x76,0xb8,0xed,0x71,0x6b,0x70,0x6b,0x76,0x6b,0x71,0x6b,0x75,0x3b,0xe2,0xf6,
1061
0xa6,0xdb,0x71,0xb7,0x4e,0xb7,0xd3,0x6e,0xef,0xba,0x9d,0x71,0x3b,0xef,0xd6,0xe5,
1062
0xd6,0xe7,0xf6,0x89,0xdb,0x67,0x6e,0x57,0xdc,0xbe,0x76,0xfb,0xce,0xad,0xdf,0xcd,
1063
0x52,0x36,0x48,0x36,0x44,0x66,0x27,0x1b,0x2a,0x93,0xc8,0x9c,0x64,0x2e,0xb2,0x11,
1064
0x32,0x77,0x99,0x5c,0xe6,0x25,0xf3,0x96,0xf9,0xcb,0x82,0x64,0x21,0xb2,0x70,0x59,
1065
0xb4,0xcc,0x20,0xbb,0x4d,0x76,0x8f,0xac,0xc1,0xed,0x01,0xd9,0xc3,0xb2,0xc7,0x65,
1066
0x4f,0xca,0x26,0xc8,0xa6,0xc9,0xe6,0xc9,0x5e,0x90,0xbd,0x28,0x5b,0x24,0x4b,0x90,
1067
0x25,0xca,0x52,0x64,0x4b,0x64,0xcb,0x40,0x96,0x6c,0x95,0x6c,0xad,0x6c,0xa3,0x2c,
1068
0x17,0x14,0xc8,0x8a,0x64,0xfd,0xc6,0x62,0xd9,0x4e,0x59,0xa9,0x6c,0x0f,0x72,0x55,
1069
0xb2,0x5a,0x59,0x83,0xac,0x59,0xd6,0x22,0x3b,0x84,0xf6,0xdb,0x64,0x47,0x65,0xed,
1070
0xb2,0x13,0xb2,0xd3,0xb2,0xe3,0x6e,0xef,0xc8,0x3e,0x90,0x9d,0x43,0x89,0x8f,0x64,
1071
0xbd,0xb2,0x4b,0xb2,0x4f,0x65,0x9f,0xcb,0xbe,0x94,0x7d,0x27,0x23,0x77,0x6b,0xf7,
1072
0x21,0xee,0x42,0x77,0x07,0x77,0x17,0x77,0x37,0x77,0xb9,0xbb,0xca,0xdd,0xcf,0x5d,
1073
0xeb,0x1e,0xee,0xae,0x77,0xbf,0xdd,0x7d,0x94,0xfb,0x03,0xee,0x8f,0xba,0x3f,0xe9,
1074
0x3e,0xc9,0x7d,0x9a,0xfb,0x1c,0xf7,0x17,0xdc,0x5f,0x71,0x5f,0xec,0x9e,0xe6,0xbe,
1075
0xdc,0x7d,0xb5,0xfb,0x46,0xf7,0x02,0xf7,0xad,0xee,0x25,0xee,0xe5,0xee,0xfb,0xdc,
1076
0x8d,0xc6,0x1a,0xd0,0x00,0xfe,0x09,0x0e,0x82,0x4e,0xbe,0xd1,0xd8,0x86,0xf4,0x4d,
1077
0xd0,0x01,0x4e,0x81,0x77,0xc0,0x07,0xe0,0x1c,0xe8,0x02,0x7d,0xe0,0x13,0xf0,0x39,
1078
0xf8,0x0a,0x7c,0x0b,0x7e,0x00,0x16,0x23,0x8d,0x46,0x6b,0x30,0x78,0xe4,0x6f,0xbb,
1079
0xff,0xd8,0xa1,0x9c,0x08,0x38,0x02,0x17,0x30,0x02,0x8c,0x04,0x0a,0xa0,0x06,0x7e,
1080
0x20,0x08,0x84,0x80,0x70,0x10,0x0d,0x62,0x81,0x9b,0x95,0xa7,0xd5,0xff,0x96,0xa7,
1081
0xd8,0xed,0xb0,0xe7,0x6e,0x70,0x1f,0x78,0x00,0x3c,0x0c,0x1e,0x07,0x4f,0x9a,0x7d,
1082
0x30,0x01,0xe9,0x33,0x60,0x1a,0x98,0x05,0x9e,0x03,0x2f,0x80,0x97,0xc0,0xab,0x60,
1083
0x31,0x48,0x01,0x4b,0xc0,0x72,0xb0,0x12,0xac,0x05,0x1b,0x41,0x1e,0x28,0x04,0x5b,
1084
0xc1,0x0e,0x50,0x0a,0xca,0xc1,0x3e,0x50,0x03,0x1a,0xc0,0x3f,0xc1,0x41,0xd0,0x06,
1085
0xde,0x04,0x1d,0xe0,0x14,0x78,0xc7,0xcc,0x8f,0x3f,0x1f,0x60,0xcf,0x39,0xd0,0x35,
1086
0xb2,0x0f,0xf1,0x27,0xe0,0x73,0xf0,0x15,0xf8,0xf6,0x7a,0xd9,0x1f,0x90,0xab,0xe6,
1087
0xbe,0x1b,0xb3,0xf0,0xc0,0xf9,0xf4,0x30,0x7f,0xa7,0x8d,0xd4,0x0e,0x88,0x80,0x23,
1088
0x70,0x01,0x23,0xc0,0x48,0xa0,0x00,0x6a,0xe0,0x07,0xaa,0x2c,0x37,0x0a,0xf6,0x09,
1089
0x82,0x3c,0xea,0xd0,0x42,0xb0,0x87,0xce,0xe3,0x75,0x41,0x84,0x47,0x0c,0xf6,0xc7,
1090
0x81,0x3b,0xc0,0x3d,0x60,0x34,0x78,0x10,0x3c,0x02,0x9e,0x00,0xe3,0x3d,0x3e,0x14,
1091
0x4c,0xf4,0x98,0x82,0xdc,0x74,0x30,0xdb,0xe3,0x39,0xc4,0x2f,0x80,0x97,0xc0,0xab,
1092
0x60,0x31,0x48,0x01,0x4b,0xc0,0x72,0xb0,0xd2,0xe3,0xb7,0xce,0xf0,0x14,0x64,0x4d,
1093
0x36,0x34,0x92,0xd6,0x70,0xbd,0xf8,0x8a,0x22,0x2c,0xfe,0x8c,0x73,0x7e,0xdf,0xc8,
1094
0x0d,0x1e,0x43,0x86,0xe6,0x7a,0xfc,0xfc,0xc8,0x26,0x8f,0x9b,0xd7,0x61,0x45,0x1e,
1095
0xc5,0x1e,0x25,0x1e,0x65,0x1e,0x95,0x1e,0x55,0x1e,0x75,0x1e,0x4d,0x1e,0x2d,0x1e,
1096
0xad,0x1e,0x6f,0x78,0xb4,0x7b,0x74,0x7a,0xbc,0xe5,0xf1,0x9e,0xc7,0x19,0x8f,0x0b,
1097
0x1e,0x3d,0x1e,0x97,0x3c,0x2e,0x7b,0x5c,0xf1,0xb8,0xea,0x71,0xcd,0xc3,0xe8,0xc1,
1098
0x93,0xf3,0xe5,0x36,0x72,0xa1,0x5c,0x22,0x77,0x96,0x0f,0x97,0xcb,0xe4,0x72,0xb9,
1099
0x52,0xee,0x23,0x0f,0x90,0x6b,0xe5,0x3a,0x79,0xa4,0x5c,0x2f,0x8f,0x97,0xdf,0x29,
1100
0x1f,0x25,0x1f,0x23,0x1f,0x2b,0x7f,0x54,0x3e,0x4e,0xfe,0x94,0x7c,0x92,0x7c,0xaa,
1101
0x7c,0x86,0x7c,0x8e,0x7c,0xbe,0x7c,0xa1,0xfc,0x15,0x79,0x82,0x3c,0x49,0x9e,0x26,
1102
0xcf,0x90,0x67,0xc9,0x57,0xcb,0xd7,0xcb,0x73,0xe4,0x05,0xf2,0x22,0x79,0xb1,0xbc,
1103
0x44,0x5e,0x26,0xaf,0x94,0x57,0xc9,0xeb,0xe4,0x4d,0xf2,0x16,0x79,0xab,0xfc,0x0d,
1104
0x79,0xbb,0xbc,0x53,0xfe,0x96,0xfc,0x3d,0xf9,0x19,0xf9,0x05,0x79,0x8f,0x3c,0x55,
1105
0x72,0x49,0x7e,0x59,0x7e,0x45,0x7e,0x55,0x3e,0x1e,0xf3,0xec,0x6b,0xf2,0x6d,0x12,
1106
0xa3,0x9c,0xe7,0xc9,0xf7,0xb4,0xf1,0x14,0x7a,0x4a,0x3c,0x9d,0x3d,0x87,0x7b,0xca,
1107
0x3c,0xe5,0x9e,0x4a,0x4f,0x1f,0xcf,0x00,0x4f,0xad,0xa7,0xce,0x33,0xd2,0x53,0xef,
1108
0x19,0xef,0x79,0xa7,0xe7,0x28,0xcf,0x31,0x9e,0x63,0x3d,0x1f,0xf5,0x1c,0xe7,0xf9,
1109
0x94,0xe7,0x24,0xcf,0xa9,0x9e,0x33,0x3c,0xe7,0x78,0xce,0xf7,0x5c,0xe8,0xf9,0x8a,
1110
0x67,0x82,0x67,0x92,0x67,0x9a,0x67,0x86,0x67,0x96,0xe7,0x6a,0xcf,0xf5,0x9e,0x39,
1111
0x9e,0x05,0x9e,0xfd,0xe2,0x22,0xcf,0x62,0xcf,0x12,0xcf,0x32,0xcf,0x4a,0xcf,0x2a,
1112
0xcf,0x3a,0xcf,0x26,0xcf,0x16,0xcf,0x56,0xcf,0x37,0x3c,0x3d,0x1c,0xda,0x3d,0x3b,
1113
0x3d,0xdf,0xf2,0x7c,0xcf,0xf3,0x8c,0xe7,0x05,0xcf,0x1e,0xcf,0x4b,0x9e,0x97,0x3d,
1114
0xaf,0x78,0x5e,0xf5,0xbc,0xe6,0x69,0xf4,0xe4,0x29,0xf8,0x0a,0x1b,0x85,0x50,0x21,
1115
0x51,0x38,0x2b,0x86,0x2b,0x64,0x0a,0xb9,0x42,0xa9,0xf0,0x51,0x04,0x28,0xb4,0x0a,
1116
0x9d,0x42,0xee,0x19,0xa9,0xd0,0x2b,0xe2,0x15,0x77,0x2a,0x46,0x29,0xc6,0x28,0xc6,
1117
0x2a,0x1e,0x55,0x8c,0x53,0x3c,0xa5,0x98,0xa4,0x98,0xaa,0x98,0xa1,0x98,0xa3,0x98,
1118
0xaf,0x58,0xa8,0x78,0x45,0x91,0xa0,0x48,0x52,0xa4,0x29,0x32,0x25,0x19,0x8a,0x2c,
1119
0xc5,0x6a,0xc5,0x7a,0x45,0x8e,0xa2,0x40,0x51,0xa4,0x28,0x56,0x94,0x28,0xca,0x14,
1120
0x95,0x8a,0x2a,0x45,0x9d,0xa2,0x49,0xd1,0xa2,0xd8,0x2c,0x6a,0x55,0xbc,0xa1,0x68,
1121
0x57,0x74,0x2a,0xde,0x52,0xbc,0xa7,0x38,0xa3,0xb8,0xa0,0x78,0x44,0xd4,0xa3,0xb8,
1122
0xa4,0xb8,0xac,0xb8,0xa2,0xb8,0xaa,0xb8,0xa6,0x30,0x2a,0x78,0x5e,0x7c,0x2f,0x1b,
1123
0x2f,0xa1,0x97,0xc4,0xcb,0xd9,0x6b,0xb8,0x97,0xcc,0x4b,0xee,0xa5,0xf4,0xf2,0xf1,
1124
0x0a,0xf0,0xd2,0x7a,0xe9,0xbc,0x22,0xbd,0x92,0x14,0x7a,0xaf,0x78,0xaf,0x3b,0xbd,
1125
0x46,0x79,0x8d,0xf1,0x1a,0xeb,0xf5,0xa8,0xd7,0x38,0xaf,0x78,0xc5,0x53,0x5e,0x93,
1126
0xbc,0xa6,0x7a,0xcd,0xf0,0x9a,0xe3,0x35,0xdf,0x6b,0xa1,0xd7,0x2b,0x5e,0x09,0x5e,
1127
0x49,0x5e,0x69,0x5e,0x19,0x5e,0x59,0x5e,0xab,0xbd,0xd6,0x7b,0xe5,0x78,0x15,0x78,
1128
0x15,0x79,0x15,0x7b,0x95,0x78,0xc9,0x3d,0xcb,0xbc,0x2a,0xbd,0xaa,0xbc,0xea,0xbc,
1129
0x9e,0x70,0x68,0xf2,0x6a,0xf1,0x6a,0xf5,0x7a,0xc3,0xab,0xdd,0xab,0xd3,0xeb,0x2d,
1130
0xaf,0xf7,0xbc,0xce,0x78,0x5d,0xf0,0xea,0xf1,0xba,0xe4,0x35,0x4a,0x7a,0xd9,0xeb,
1131
0x8a,0xd7,0x55,0xaf,0x6b,0x5e,0x46,0x2f,0x9e,0x92,0xaf,0xb4,0x51,0x0a,0x95,0xa3,
1132
0x14,0x12,0xa5,0xb3,0x72,0xb8,0x52,0xa6,0x94,0x2b,0x95,0x4a,0x1f,0x65,0x80,0x52,
1133
0xab,0xd4,0x29,0x23,0x95,0x7a,0x65,0xbc,0x72,0xb3,0xe4,0x4e,0xe5,0x28,0xe5,0x18,
1134
0xe5,0x58,0xe5,0xa3,0xca,0x71,0xca,0xa7,0x94,0x93,0x94,0x53,0x95,0x33,0x94,0x73,
1135
0x94,0xf3,0x95,0x0b,0x95,0x1f,0x8a,0x5f,0x51,0x26,0x28,0x93,0x94,0x69,0xca,0x0c,
1136
0x65,0x96,0x72,0xb5,0x72,0xbd,0x32,0x47,0x59,0xa0,0x2c,0x52,0x16,0x2b,0x4b,0x94,
1137
0x65,0xca,0x4a,0x65,0x95,0xf2,0x1e,0x49,0x9d,0xf2,0x11,0x49,0x93,0xb2,0x45,0xd9,
1138
0xaa,0x64,0xc7,0xf1,0x1b,0x88,0xdb,0xb9,0x5c,0xa7,0xf2,0x2d,0xe5,0x7b,0xca,0x33,
1139
0xca,0x0b,0xca,0x1e,0xe5,0x25,0xe5,0x65,0xe5,0x15,0xe5,0x77,0x62,0xa3,0xf1,0x2a,
1140
0x8e,0x5d,0xe3,0x8e,0x1b,0x95,0x3c,0x95,0xf9,0x4d,0xbe,0xca,0x46,0x25,0x54,0x49,
1141
0x54,0xce,0xaa,0xe1,0x2a,0x99,0x4a,0xae,0x52,0xaa,0x7c,0x54,0x01,0x2a,0xad,0x4a,
1142
0xa7,0x8a,0x54,0xe9,0x55,0xf1,0xaa,0x3b,0x55,0xa3,0x54,0x8d,0xa2,0x31,0xaa,0xb1,
1143
0xaa,0x47,0x55,0xe3,0x54,0x4f,0xa9,0x26,0xa9,0xa6,0xaa,0x66,0xa8,0xe6,0xa8,0xe6,
1144
0xab,0x16,0xaa,0x5e,0x51,0x25,0xa8,0x92,0x54,0x69,0xaa,0xa7,0xa4,0x19,0xaa,0x2c,
1145
0xd5,0x6a,0xd5,0x7a,0xd5,0x1c,0x69,0x8e,0xaa,0x40,0x55,0xa4,0x2a,0x56,0x95,0xa8,
1146
0x24,0x5e,0x65,0xaa,0x4a,0x55,0x95,0xaa,0x4e,0xd5,0xa4,0x6a,0x41,0x68,0x55,0xbd,
1147
0xa1,0x6a,0x57,0x75,0xaa,0xde,0x52,0xbd,0xa7,0x3a,0xa3,0xba,0xa0,0x32,0x2a,0x7b,
1148
0x54,0x97,0x54,0x97,0x55,0x57,0x54,0x57,0x55,0xdf,0xab,0xb8,0xef,0x62,0xd4,0x56,
1149
0x6a,0x81,0xda,0x56,0x3d,0x54,0xed,0xa0,0x96,0xaa,0x5d,0xd5,0x3a,0x95,0xbb,0xda,
1150
0x53,0xad,0x52,0xbf,0xa1,0xf4,0x55,0x07,0xaa,0x83,0xd5,0x61,0xea,0x28,0xb5,0x41,
1151
0x7d,0x9b,0xfa,0x2e,0xf5,0xbd,0xea,0xfb,0xd5,0x0f,0xa9,0x1f,0x53,0x3f,0xaa,0xfa,
1152
0x87,0x7a,0x9c,0xea,0x69,0xf5,0x64,0xf5,0xb3,0xea,0x99,0xea,0xb9,0xea,0x76,0xe5,
1153
0x42,0xcf,0xe7,0xd5,0x2f,0xaa,0xe3,0xc4,0x69,0x8a,0x4e,0xaf,0x45,0x6a,0x46,0xbd,
1154
0x50,0x95,0xac,0x7e,0x45,0x95,0xae,0x5e,0xa6,0x5e,0xa1,0x7e,0x4b,0xb9,0x46,0xbd,
1155
0x41,0x9d,0xab,0xde,0xa4,0xde,0xa2,0x7e,0x4f,0xb9,0x5d,0xbd,0x4b,0xbd,0x47,0xbd,
1156
0x57,0x5d,0xad,0xae,0x57,0x97,0xa8,0x9a,0xd5,0x07,0xd4,0x12,0xaf,0xc3,0xea,0x3a,
1157
0xd5,0x51,0xf5,0x71,0xf5,0x49,0xf5,0xdb,0xea,0xf7,0xd5,0xed,0xaa,0xb3,0xea,0x6b,
1158
0xca,0x8f,0xd4,0x9d,0xaa,0x48,0x45,0xaf,0xfa,0x2d,0xd5,0xc7,0xea,0x33,0xaa,0xcf,
1159
0xd4,0x5f,0xaa,0xbf,0x51,0x7f,0xaf,0x26,0xef,0x1e,0xd5,0x65,0xa5,0x95,0xf7,0x25,
1160
0x95,0xc0,0xfb,0xb2,0xca,0xd6,0x7b,0xbc,0xc3,0x50,0x6f,0x47,0xef,0x61,0xde,0x32,
1161
0x6f,0xb9,0xb7,0xd2,0xdb,0xc7,0x3b,0xd0,0x3b,0xc4,0x3b,0xc2,0x3b,0xc6,0xfb,0xcf,
1162
0x5c,0xff,0xc6,0x79,0xdf,0xee,0x7d,0x97,0xf7,0x28,0xef,0x31,0xde,0x63,0x11,0x7e,
1163
0xa9,0xd4,0x23,0xde,0xe3,0xbc,0x9f,0xf6,0x7e,0xc6,0x7b,0xfa,0x4d,0x25,0xe6,0x78,
1164
0x63,0x1d,0xea,0xfd,0x92,0xf7,0x22,0xbb,0x14,0xbb,0x45,0xde,0x09,0xde,0x89,0xde,
1165
0x29,0xde,0xe9,0xde,0x19,0xde,0xb7,0xd9,0x65,0x7a,0xaf,0xf6,0xde,0xe0,0x5d,0xe0,
1166
0xbd,0xcd,0xbb,0xc4,0x7b,0x8f,0xf7,0x3e,0xef,0x5a,0xef,0x26,0xef,0x03,0xde,0x6d,
1167
0xde,0xc7,0x50,0xbb,0xd3,0xfb,0x6d,0xef,0x0f,0xbc,0xcf,0x7b,0xf7,0x20,0xff,0x31,
1168
0xf8,0xdc,0xfb,0x6b,0xc4,0xd7,0xbc,0xc9,0xa7,0xdf,0x68,0xed,0x33,0xc4,0x47,0xe8,
1169
0xe3,0xe0,0xe3,0xe2,0xe3,0xe6,0x23,0xf7,0x51,0xf9,0xf8,0xf9,0x68,0x7c,0x74,0x08,
1170
0x11,0xe6,0x10,0x6d,0x0e,0x06,0x73,0x88,0x37,0x87,0x3b,0xcc,0xe1,0x6e,0x73,0xb8,
1171
0xd7,0x1c,0xc6,0x98,0xc3,0x83,0xe6,0xf0,0xb0,0x39,0x3c,0x66,0x0e,0xe3,0xcc,0x61,
1172
0x3c,0xc2,0x04,0x84,0xc9,0x08,0x53,0x11,0xa6,0x23,0xcc,0x42,0x98,0x6b,0x0e,0xf3,
1173
0xcd,0x61,0x81,0x39,0xbc,0x64,0x0e,0x8b,0x10,0x12,0xcc,0x21,0x11,0x21,0xc5,0x1c,
1174
0xd2,0xcd,0x21,0x03,0x21,0x13,0xe1,0x8f,0x3f,0x6d,0x56,0xfa,0x98,0xc2,0x1a,0x84,
1175
0xf5,0x08,0xd9,0x08,0x1f,0x58,0xe7,0xf9,0xe4,0xf9,0x6c,0x42,0x28,0x42,0xd8,0x66,
1176
0x0e,0x3b,0x10,0x76,0x21,0x94,0x23,0xec,0x47,0xa8,0x43,0x68,0x46,0x38,0x88,0x70,
1177
0x84,0x0b,0xed,0x5c,0x38,0x69,0x0e,0x6f,0xf9,0xbc,0xef,0x73,0x0e,0xdb,0xdd,0x3e,
1178
0x97,0x7c,0x3e,0xf3,0xf9,0xca,0xe7,0x3b,0x1f,0xa3,0x8f,0x95,0xef,0x60,0x5f,0x7b,
1179
0x5f,0x89,0xaf,0xd4,0x77,0x84,0xaf,0x87,0xaf,0xd2,0xd7,0xd7,0x37,0xc8,0x37,0xd4,
1180
0x37,0xd2,0xd7,0xe0,0x7b,0xbb,0xef,0x3d,0xbe,0x63,0x7c,0x1f,0xf2,0x7d,0xdc,0x77,
1181
0xbc,0xef,0x24,0xdf,0x67,0x7d,0x67,0xf9,0xce,0xf3,0x5d,0xe8,0xbb,0xc8,0x77,0xb1,
1182
0x6f,0xaa,0x6f,0x86,0xef,0x0a,0xdf,0xb5,0xbe,0xd9,0xbe,0x05,0xbe,0x5b,0x7c,0x77,
1183
0xf8,0xee,0xf6,0xad,0xf4,0xad,0xf6,0x6d,0xf0,0x7d,0xdd,0xb7,0xd5,0xf7,0xa8,0x6f,
1184
0x87,0xef,0x69,0xdf,0xf7,0x7c,0xcf,0xfa,0x76,0xf9,0x5e,0xf4,0xbd,0xec,0xfb,0xa5,
1185
0xef,0xb7,0xbe,0xfd,0xbe,0x3c,0x3f,0x81,0x9f,0x9d,0x9f,0xd8,0xcf,0xd9,0xcf,0xd5,
1186
0x6f,0xa4,0x9f,0x97,0x9f,0x8f,0x5f,0xa0,0x5f,0x88,0x5f,0x84,0x9f,0xde,0xef,0x36,
1187
0xbf,0xbb,0xfd,0x46,0xfb,0x8d,0xf5,0x7b,0xcc,0xef,0x49,0xbf,0x89,0x7e,0x53,0xfd,
1188
0x66,0xfa,0x3d,0xe7,0xb7,0xc0,0xef,0x15,0x3f,0xc6,0x2f,0xc5,0x6f,0xa9,0x5f,0x96,
1189
0xdf,0x1a,0xbf,0x8d,0x7e,0xf9,0x7e,0x45,0x7e,0xdb,0xfd,0x76,0xfb,0xed,0xf5,0xab,
1190
0xf5,0x6b,0xf6,0x3b,0xe4,0x77,0xd4,0xaf,0xc3,0xef,0x9c,0xcf,0x69,0x3f,0xb6,0x27,
1191
0xef,0xf9,0x9d,0xf5,0xfb,0xce,0xa7,0xcb,0x8f,0xed,0xc9,0x45,0xbf,0xcb,0x7e,0x52,
1192
0xdf,0x2f,0xfd,0xd8,0x9e,0x7c,0xeb,0xd7,0xef,0xe7,0xeb,0xcb,0xf3,0x67,0x7b,0xc3,
1193
0x5a,0x65,0xb2,0x68,0xc0,0x16,0x93,0x15,0x02,0xff,0x08,0x3f,0x3b,0x7f,0xb1,0xff,
1194
0x63,0x7e,0xce,0xfe,0xac,0x7a,0x91,0x9f,0xab,0xff,0x48,0xff,0xa5,0x7e,0x5e,0xfe,
1195
0xac,0x2e,0xeb,0x2d,0x1f,0xff,0x73,0x3e,0x81,0xfe,0x03,0xde,0x0a,0xf1,0x1f,0xf0,
1196
0x55,0x84,0xbf,0xef,0x4d,0x3e,0xba,0xd9,0x43,0x7a,0xff,0x9b,0x7d,0xf4,0x73,0x0f,
1197
0xb1,0xde,0xb9,0xe1,0x97,0x01,0x9f,0xdc,0xe6,0x3f,0xe0,0x91,0x01,0x6f,0xdc,0xed,
1198
0xcf,0xfa,0x62,0xb4,0xff,0x80,0x27,0xc6,0x72,0x96,0xb0,0x36,0x98,0xd4,0x1f,0xf3,
1199
0x9f,0xe5,0xfb,0xa4,0xff,0x44,0xff,0xa9,0xfe,0x6c,0x3b,0xae,0x5c,0x0d,0xb6,0xd4,
1200
0x4c,0xff,0xf9,0xfe,0x2f,0xfb,0x2f,0xf6,0x4f,0xf5,0xcf,0xf0,0x5f,0xe1,0xbf,0xd6,
1201
0x3f,0xdb,0xbf,0xc0,0x7f,0x8b,0xff,0x0e,0xff,0xdd,0xfe,0x95,0xfe,0xd5,0xfe,0x0d,
1202
0xfe,0xaf,0xfb,0xb7,0xfa,0x1f,0xf5,0xef,0xf0,0x3f,0xed,0xff,0x9e,0xff,0x59,0xff,
1203
0x2e,0xff,0x8b,0xfe,0x97,0xd1,0xca,0x97,0xfe,0xdf,0xfa,0xf7,0xfb,0xf3,0x02,0x7e,
1204
0x6f,0xbd,0x81,0xed,0x27,0x61,0xcf,0x5a,0xb3,0x37,0x4c,0xfb,0xd8,0x51,0x22,0x08,
1205
0x10,0x04,0xfc,0xa6,0xf5,0x41,0x80,0x03,0xc2,0xf0,0x00,0x8f,0x00,0x75,0x40,0x60,
1206
0x80,0x2e,0x20,0x06,0xe1,0xf6,0x80,0x7b,0x03,0xc6,0x06,0x3c,0x11,0x30,0x21,0xe0,
1207
0x59,0x84,0x39,0x01,0x0b,0x10,0x5e,0x45,0x48,0x0e,0xc8,0x40,0x58,0x15,0xb0,0x11,
1208
0x61,0x13,0x42,0x71,0xc0,0x6e,0x84,0x7d,0x08,0xf5,0x01,0x2d,0x01,0x47,0x02,0x3a,
1209
0x10,0xde,0x0e,0x38,0x13,0xd0,0x1d,0xf0,0x49,0xc0,0x97,0x08,0xd7,0x02,0x2c,0x03,
1210
0x07,0x07,0x0e,0x0d,0x74,0x0e,0xc4,0xd2,0x31,0x50,0x81,0xe0,0x8b,0xa0,0x0d,0x8c,
1211
0x08,0x8c,0x0d,0xbc,0x2b,0x70,0x4c,0xe0,0x23,0x81,0x4f,0x06,0xb2,0x36,0x4c,0x0e,
1212
0x9c,0x11,0x38,0x2f,0xf0,0xa5,0x40,0x26,0x30,0x0d,0x21,0x33,0x70,0x6d,0x60,0x6e,
1213
0x60,0x11,0xc2,0xce,0xc0,0xf2,0xc0,0xea,0xc0,0xa6,0xc0,0x43,0x81,0x6f,0x06,0x9e,
1214
0x0c,0x7c,0x2f,0xf0,0x7c,0x60,0x5f,0xe0,0x67,0x81,0x57,0x03,0xfb,0x03,0xad,0x83,
1215
0x6c,0x83,0x24,0x41,0xc3,0x82,0x46,0x06,0xa9,0x82,0x02,0x82,0x42,0x83,0xa2,0x83,
1216
0xae,0x05,0x0c,0x0e,0xbc,0x2d,0x68,0x54,0xd0,0x83,0x41,0x8f,0x07,0x3d,0x1d,0x34,
1217
0x15,0x3c,0x18,0x34,0x3b,0xe8,0x85,0xa0,0x45,0x41,0x49,0x41,0x4b,0xb1,0x7d,0x04,
1218
0xd6,0xaf,0x0c,0xda,0x10,0xf4,0xfb,0xbf,0x09,0xbd,0x75,0x28,0x08,0xda,0x16,0x54,
1219
0x1a,0xb4,0x3f,0xa8,0x29,0xe8,0x70,0x50,0x47,0xd0,0xbb,0x41,0x17,0x82,0x3e,0x0e,
1220
0xba,0x12,0xe4,0xa8,0x51,0x68,0x7e,0xfa,0x9b,0x7e,0xb7,0xfe,0xf8,0x6b,0x02,0x35,
1221
0xfd,0xc6,0x60,0x8d,0xd1,0x32,0x54,0x13,0xa6,0x89,0xd0,0xc4,0x68,0xfe,0xbd,0x6f,
1222
0x10,0xf0,0x84,0xd1,0xdc,0xa1,0xb9,0x07,0x81,0xfd,0x7d,0x86,0x7b,0x35,0xa3,0x35,
1223
0xf7,0x6b,0x1e,0xd2,0x3c,0xa6,0xf9,0x87,0xe6,0x69,0xcd,0x64,0x0d,0xfb,0x5d,0xf1,
1224
0xb3,0x9a,0x99,0x9a,0xb9,0x9a,0xe7,0x39,0x7b,0x5e,0xd4,0xbc,0xac,0x71,0xb5,0x33,
1225
0x85,0x7b,0xb8,0x5a,0x26,0x7d,0xe8,0x58,0x06,0x43,0x3f,0x54,0x13,0xf7,0xa3,0x76,
1226
0x16,0x69,0x5e,0xd3,0x30,0x9a,0xdb,0xec,0x12,0x35,0xc9,0x9a,0x54,0xcd,0x3d,0x76,
1227
0xfd,0xc6,0x74,0xcd,0x52,0xcd,0x32,0x4d,0xe6,0x75,0x2b,0x57,0x68,0xd6,0x68,0x36,
1228
0xa2,0xed,0x3c,0xec,0x29,0xd4,0x6c,0xd5,0xec,0xd4,0xec,0xd6,0x54,0x6a,0xaa,0x34,
1229
0xf5,0x9a,0x66,0xcd,0x41,0x4d,0x9b,0xe6,0x98,0xa6,0x03,0xe1,0x24,0xc2,0x5b,0x08,
1230
0xef,0x22,0x7c,0x60,0x0e,0x67,0x11,0x2e,0x98,0x43,0x37,0x42,0x9f,0x39,0x7c,0x6c,
1231
0x0e,0x97,0xcd,0xe1,0x0b,0x73,0xf8,0xca,0x1c,0xbe,0x41,0xb8,0x86,0xd0,0x8f,0x60,
1232
0xa1,0xb5,0xd0,0x5a,0x99,0x03,0xdf,0x1c,0x86,0x98,0x83,0x9d,0x39,0x0c,0x35,0x07,
1233
0x89,0x39,0x38,0x99,0x83,0x8b,0x39,0xb8,0x9a,0x83,0xcc,0x1c,0x3c,0xcc,0x41,0x61,
1234
0x0e,0x2a,0x73,0xf0,0x31,0x07,0x7f,0x73,0x08,0x42,0x60,0x9f,0x06,0xc1,0x5a,0x53,
1235
0xd0,0x21,0x44,0x21,0xc4,0x22,0xdc,0x81,0x60,0xfa,0x4d,0x95,0x7e,0x63,0xa8,0x66,
1236
0x94,0x76,0x11,0xe7,0xb5,0xd7,0x34,0xf7,0x69,0x59,0xef,0xb2,0x1e,0xf5,0xd7,0x24,
1237
0x6a,0xa6,0x38,0x8c,0xd1,0xde,0xea,0xf7,0x53,0xd8,0xd1,0x90,0x0c,0x6f,0xa7,0xe2,
1238
0x8c,0x64,0x6a,0x7e,0xcf,0x37,0xd4,0x2f,0x6a,0xd2,0x71,0xa6,0x1f,0xd0,0xde,0xa3,
1239
0x79,0xc3,0xf6,0xf7,0xd4,0xbf,0x57,0x33,0x56,0x3b,0x5a,0xf3,0xb0,0xf6,0x51,0xed,
1240
0x38,0xed,0x14,0x07,0x76,0x04,0x05,0x6a,0x9e,0xd2,0x7e,0xeb,0x32,0x49,0x3b,0x55,
1241
0x3b,0x43,0x3b,0x47,0x3b,0x5f,0xbb,0x50,0xfb,0x8a,0x36,0x41,0x9b,0xa4,0x4d,0xd3,
1242
0xfe,0x55,0x6f,0xd0,0x32,0xb4,0x59,0xda,0xd5,0x5a,0xa2,0x3f,0xf2,0x7e,0xd9,0x34,
1243
0x46,0x6f,0x7e,0xcb,0xcc,0x6e,0xdf,0xfc,0xa6,0x99,0xdd,0xbe,0xf9,0x6d,0x33,0xbb,
1244
0x6d,0x7a,0xe3,0x6c,0xaa,0xbb,0x5e,0x9b,0xad,0xcd,0xd3,0x46,0xd2,0x26,0x6d,0x91,
1245
0x76,0x1b,0xce,0xe9,0x4e,0xed,0x6e,0x6d,0x85,0x76,0xbf,0xb6,0x56,0xdb,0xa8,0x7d,
1246
0x5d,0xfb,0xeb,0xf7,0x87,0x43,0xda,0x37,0xb4,0xc7,0xb5,0xa7,0xb4,0xef,0x6a,0xcf,
1247
0x68,0x3f,0xd2,0xf6,0x69,0x3f,0xd5,0x5e,0xd1,0x7e,0xa3,0xfd,0x41,0x6b,0x19,0xcc,
1248
0x0f,0xb6,0x0d,0x16,0x05,0x3b,0x05,0x0f,0x0f,0x76,0x0f,0x56,0x04,0x7b,0x07,0x07,
1249
0x04,0x07,0x07,0x87,0x07,0xc7,0x04,0xc7,0x07,0xdf,0x15,0x7c,0x5f,0xf0,0x83,0xc1,
1250
0x8f,0x06,0xff,0x23,0x78,0x42,0xf0,0x94,0xe0,0x19,0xc1,0x73,0x83,0x5f,0x08,0x7e,
1251
0x39,0x38,0x21,0x38,0x39,0x78,0x49,0xf0,0x7f,0xfa,0xf7,0xa9,0x7f,0xed,0x3b,0xd0,
1252
0xcc,0xe0,0xd5,0xc1,0x1b,0x82,0xf3,0x82,0x37,0x07,0x17,0x07,0xef,0x0a,0x2e,0x0f,
1253
0xde,0x1f,0x5c,0x17,0xdc,0x1c,0x7c,0x30,0xf8,0x48,0x70,0x7b,0xf0,0xc9,0xe0,0x77,
1254
0x82,0x3f,0x0c,0xbe,0x10,0xdc,0x1b,0xfc,0x49,0xf0,0x17,0xc1,0x57,0x83,0xbf,0x0f,
1255
0xb6,0x08,0x19,0x14,0x62,0x13,0x32,0x34,0xc4,0x31,0x64,0x58,0x88,0x2c,0xc4,0x33,
1256
0x44,0x1d,0xe2,0x1f,0xa2,0x0d,0x09,0x0b,0x89,0x0e,0xf9,0xb3,0xbf,0xa5,0xf8,0xab,
1257
0xda,0xfb,0xe9,0xdd,0x39,0x2e,0xe4,0xce,0x90,0x7b,0x43,0x1e,0x08,0x79,0x24,0x64,
1258
0x5c,0xc8,0xd3,0x21,0xcf,0x84,0x4c,0x0f,0x99,0x13,0xf2,0x3c,0x7a,0xf3,0x52,0xc8,
1259
0x6b,0x21,0x49,0x21,0xe9,0x21,0xcb,0x43,0x56,0x85,0xac,0x0f,0xc9,0x0d,0x29,0x0c,
1260
0xd9,0x16,0x52,0x12,0xb2,0x27,0x64,0x5f,0x48,0x6d,0x48,0x13,0x8e,0x1f,0x08,0x69,
1261
0x0b,0x39,0x16,0xd2,0x19,0xf2,0x76,0xc8,0x07,0x21,0xe7,0xb1,0xdd,0x13,0xf2,0x71,
1262
0x48,0xff,0xaf,0x7e,0x1f,0xfc,0xdb,0x8e,0xf7,0xff,0xe8,0x37,0xf6,0x3e,0x0f,0xf9,
1263
0x32,0xe4,0x79,0xba,0x1a,0x92,0x60,0xd1,0x6f,0xfc,0x2e,0xe4,0x87,0x10,0x8b,0x50,
1264
0xab,0x50,0xf6,0x6f,0xe0,0xf9,0xa1,0x36,0xa1,0xf6,0xa1,0xa2,0xd0,0xd9,0x1e,0x0e,
1265
0xa1,0x45,0x16,0xce,0xa1,0x5f,0xd1,0xb0,0xd0,0x11,0xa1,0xee,0xa1,0xf2,0x50,0xaf,
1266
0xd0,0x20,0x0f,0x75,0xa8,0x7f,0xa8,0x26,0x34,0x24,0x34,0x22,0x34,0x3a,0xb4,0x98,
1267
0xe2,0x42,0x6f,0x0f,0x1d,0x49,0x77,0x85,0x8e,0x0a,0x15,0x0d,0xbd,0x3f,0xf4,0x80,
1268
0xc5,0xd8,0xd0,0x47,0x42,0x1f,0x0f,0x7d,0x32,0xf4,0xb8,0xc5,0xd3,0xa1,0xfd,0xc6,
1269
0xc9,0xa1,0x53,0x43,0xa7,0x87,0xce,0x0a,0x9d,0x1b,0x3a,0x3f,0x74,0x41,0xe8,0x4b,
1270
0xa1,0xaf,0x85,0xde,0xf0,0x50,0x52,0x68,0x7a,0xe8,0xf2,0xd0,0x55,0xa1,0xeb,0x43,
1271
0x73,0x43,0x0b,0x43,0xb7,0x85,0x96,0x84,0xee,0x09,0xdd,0x17,0x5a,0x1b,0xda,0x14,
1272
0x7a,0x20,0xb4,0x2d,0xf4,0x58,0x68,0x67,0xe8,0xdb,0xa1,0x1f,0x84,0x9e,0x0f,0xed,
1273
0x09,0xfd,0x38,0xf4,0xf3,0xd0,0xaf,0x43,0xaf,0x85,0x92,0xce,0x5a,0x37,0x44,0x27,
1274
0xd4,0x39,0xe8,0x5c,0x74,0x6e,0x3a,0xb9,0x4e,0xa5,0xf3,0xd3,0x69,0x74,0x3a,0x5d,
1275
0x94,0x2e,0x56,0x77,0x87,0x6e,0x94,0xee,0x7e,0xdd,0xc3,0xba,0x27,0x74,0x4f,0xe9,
1276
0x26,0xeb,0xa6,0xe9,0x66,0xeb,0xe6,0xeb,0x5e,0xd4,0xbd,0xaa,0xfb,0xfd,0xdf,0xc0,
1277
0x27,0xea,0xd2,0x74,0xcb,0x74,0x2b,0x75,0xeb,0x74,0x39,0xba,0x4d,0xba,0xad,0xba,
1278
0x9d,0xba,0x32,0xdd,0x5e,0x5d,0x8d,0xae,0x51,0xd7,0xa2,0x3b,0xac,0x7b,0x53,0x77,
1279
0x42,0xf7,0x96,0xee,0x7d,0xdd,0x39,0x5d,0xb7,0xee,0x92,0xee,0xf7,0x8c,0xa8,0x3f,
1280
0x3a,0xbf,0xf8,0x4c,0xf7,0x95,0xee,0x3b,0x9d,0x51,0x67,0x15,0x36,0x38,0xcc,0x3e,
1281
0x4c,0x12,0x26,0x0d,0x1b,0x11,0xe6,0x11,0xa6,0x0c,0xf3,0x0d,0x0b,0x0a,0x0b,0x0d,
1282
0x8b,0x0c,0x33,0x84,0xdd,0x1e,0x76,0x4f,0xd8,0x98,0xb0,0x87,0xc2,0x1e,0x0f,0x1b,
1283
0x1f,0x36,0x29,0xec,0xd9,0xb0,0x59,0x61,0xf3,0xc2,0x16,0x86,0x2d,0x0a,0x5b,0x1c,
1284
0x96,0x1a,0x96,0x11,0xb6,0x22,0x6c,0x6d,0x58,0x76,0x58,0x41,0xd8,0x96,0xb0,0x1d,
1285
0x61,0xbb,0xc3,0x2a,0xc3,0xaa,0xc3,0x1a,0xc2,0x5e,0x0f,0x6b,0x0d,0x3b,0x1a,0xd6,
1286
0x11,0x76,0x3a,0xec,0xbd,0xb0,0xb3,0x61,0x5d,0x61,0x17,0xc3,0x2e,0x87,0x7d,0x19,
1287
0xf6,0x6d,0x58,0x7f,0x18,0x2f,0x5c,0x10,0x6e,0x17,0x2e,0x0e,0x77,0x0e,0x77,0x0d,
1288
0x1f,0x19,0xee,0x15,0xee,0x13,0xfe,0x3f,0xf7,0x97,0x1c,0xa6,0x10,0x18,0x1e,0x12,
1289
0x1e,0x11,0xae,0x0f,0xbf,0x2d,0xfc,0xee,0xf0,0xd1,0xe1,0x63,0xc3,0x1f,0x0b,0x7f,
1290
0x32,0x7c,0x62,0xf8,0xd4,0xf0,0x99,0xe1,0xcf,0x85,0x2f,0x08,0x7f,0x25,0x9c,0x09,
1291
0x4f,0x09,0x5f,0x1a,0x9e,0x15,0xbe,0x26,0x7c,0x63,0x78,0x7e,0x78,0x51,0xf8,0xf6,
1292
0xf0,0x5f,0x3b,0x47,0xbf,0x3e,0x3e,0x6e,0xde,0xff,0xf3,0xdf,0x3e,0xfd,0x73,0xfe,
1293
0xfe,0xeb,0xd6,0x7f,0xd3,0xf0,0x7b,0x7e,0x17,0xed,0xe7,0xf3,0x87,0x1f,0xff,0xc6,
1294
0xee,0xef,0xff,0x94,0x86,0xef,0x0f,0x6f,0x0a,0x3f,0x1a,0xfe,0x4e,0x78,0x77,0xf8,
1295
0x95,0xf0,0xdf,0xf6,0xf7,0x2c,0xbf,0xfc,0x57,0x2d,0xff,0xc9,0x0f,0x45,0x0c,0x8e,
1296
0x10,0x47,0xc8,0x22,0x7c,0x23,0xc2,0x23,0xfe,0xfa,0xdf,0x02,0xfa,0x57,0xe1,0x3f,
1297
0xf5,0x3b,0x89,0x7f,0xbc,0x4e,0xbf,0xf1,0x7f,0x97,0x6d,0xfd,0x46,0xb6,0x0e,0xeb,
1298
0x43,0x3b,0x2e,0x66,0xeb,0xb0,0xe9,0x40,0x1d,0xf6,0x9b,0x87,0x5b,0xeb,0xf4,0x1b,
1299
0x6d,0xc0,0x8f,0x75,0xfa,0x8d,0xff,0xf3,0xbe,0xee,0x37,0xde,0xf0,0xb5,0xa9,0x3f,
1300
0x37,0xd7,0xf9,0x69,0x7f,0x7e,0xff,0xd8,0xb9,0x59,0xe7,0x46,0x9d,0x7e,0xe3,0x08,
1301
0x1a,0xf8,0xc6,0xe6,0xcf,0xd1,0xf9,0xbb,0xce,0xdf,0x75,0xfe,0x53,0x75,0xee,0x88,
1302
0xb8,0x3b,0x82,0x1d,0xbb,0xbf,0xfe,0xdf,0x62,0x74,0xbc,0x1f,0xff,0xb7,0x98,0x7b,
1303
0x23,0x7e,0xbd,0xce,0x98,0x9f,0xd4,0xb9,0x3f,0xc2,0x1f,0xe5,0x22,0xb0,0x7d,0x2f,
1304
0x8e,0xff,0xad,0xf9,0x7f,0x4b,0x73,0x3e,0x02,0x3b,0x96,0x6e,0x35,0x77,0xfa,0xb3,
1305
0xf7,0xfd,0x7b,0x2b,0xb9,0x5b,0xaf,0xba,0xfb,0x7f,0x56,0xf7,0xc6,0xfc,0xe2,0xe7,
1306
0xff,0x3f,0xc8,0xf4,0xdf,0x83,0x6e,0xfd,0xbf,0x83,0x46,0x72,0xff,0x35,0x68,0xc4,
1307
0xc8,0xb7,0xad,0x2a,0x78,0xd5,0xbc,0xcf,0xac,0x36,0x5a,0xed,0xb5,0xba,0x75,0x0b,
1308
0x6c,0x7d,0xde,0x8f,0xea,0xb2,0xff,0x75,0x68,0x26,0xea,0x95,0xf1,0xde,0xe4,0xad,
1309
0xb6,0xea,0x70,0xcf,0xb5,0xfa,0x2d,0xf3,0x9f,0x87,0x22,0x1e,0x8f,0x18,0x1f,0x31,
1310
0x29,0xe2,0xd9,0x88,0x59,0x11,0xf3,0x22,0x16,0x46,0x2c,0x8a,0x58,0x1c,0x91,0x1a,
1311
0x91,0x11,0xb1,0x22,0x62,0x6d,0x44,0x76,0x44,0x41,0xc4,0x96,0x88,0x1d,0x11,0xbb,
1312
0x23,0x2a,0x23,0xaa,0x23,0x1a,0x22,0x5e,0x8f,0x68,0x8d,0x38,0x1a,0xd1,0x11,0x71,
1313
0x3a,0xe2,0xbd,0x88,0xb3,0x11,0x5d,0x11,0x17,0x23,0x2e,0x47,0x7c,0x19,0xf1,0xed,
1314
0x1f,0x9a,0xc1,0xb1,0xef,0x18,0x2f,0x6b,0xbe,0xd1,0xf4,0x1b,0x83,0xb4,0x16,0xda,
1315
0x2f,0x34,0x43,0xb5,0xc1,0xdc,0xbb,0x3d,0xf6,0x7d,0x9e,0x95,0xd6,0x49,0xeb,0xaa,
1316
0x1d,0xa2,0x95,0x69,0xfb,0x35,0x7c,0x2d,0xfb,0xe6,0xf1,0x2b,0xcd,0x35,0x8d,0x9d,
1317
0x56,0xa2,0x75,0xd1,0xf6,0x47,0x2c,0xf2,0xb1,0x88,0xb4,0x8a,0xec,0x37,0xb2,0xf5,
1318
0xfb,0x8d,0xfe,0xdc,0xbb,0x9e,0x2f,0xd8,0x77,0xb5,0xb7,0xaa,0x6f,0x1c,0xa8,0x8f,
1319
0xd9,0x0a,0xb6,0x5c,0x7e,0xf4,0x66,0xe8,0xf2,0xf5,0xb7,0xa5,0xa6,0xfa,0x78,0x02,
1320
0x03,0x53,0xfd,0x7e,0xe3,0x40,0x7d,0xf6,0xf8,0xcd,0xf5,0x17,0xf9,0xf4,0x1b,0x7f,
1321
0xae,0x6f,0xb2,0xbf,0xdf,0xf8,0xaf,0xf4,0x4d,0xf6,0xe3,0xb9,0x8e,0xda,0x03,0xfd,
1322
0x67,0xdf,0x57,0x0e,0xf4,0x9f,0xd5,0xff,0xd5,0xfe,0x5f,0xb7,0xfe,0xe7,0xfe,0xfb,
1323
0xf7,0xea,0xf3,0x23,0x87,0x44,0xda,0x45,0x0e,0x8d,0x94,0x44,0x3a,0x45,0xba,0x44,
1324
0xba,0x46,0xca,0x22,0x3d,0x22,0x6f,0x9c,0x9f,0xdf,0xf3,0x77,0x3e,0x8a,0x48,0x6b,
1325
0x3c,0x21,0x4a,0x65,0x7e,0x91,0xbf,0x6f,0xcd,0x14,0x18,0xb9,0x44,0xa6,0x8d,0x0c,
1326
0x8d,0x0c,0x8f,0x8c,0x8e,0xfc,0x5d,0x7f,0x9b,0x12,0x19,0x1f,0x79,0x47,0xe4,0x9f,
1327
0xb3,0x92,0xb8,0x3b,0xf2,0xaf,0x5d,0x85,0xdc,0x1b,0x39,0x36,0x72,0x9a,0xcb,0x2f,
1328
0x1f,0x1f,0x22,0x7e,0x22,0x72,0x7c,0xe4,0xc4,0x48,0x2f,0xd1,0x94,0xc8,0xe9,0x91,
1329
0xee,0x4e,0xb3,0x23,0xe7,0x45,0x2e,0x88,0x2c,0xf1,0x7a,0x39,0xf2,0xb5,0xc8,0xc4,
1330
0xc8,0xd4,0xc8,0xa5,0x91,0x99,0x91,0xd9,0xe2,0x55,0x91,0xeb,0x22,0xb3,0x23,0xf3,
1331
0x23,0x37,0x47,0x6e,0x8b,0xb4,0x17,0x91,0xd3,0xce,0xc8,0x02,0xa9,0xad,0x53,0x91,
1332
0x74,0x77,0xe4,0xcb,0x92,0x8a,0xc8,0xfd,0x91,0xb5,0x91,0x8d,0x91,0xaf,0x47,0x8e,
1333
0x93,0x6a,0xc4,0x87,0x22,0x8f,0x44,0x1e,0x8b,0x3c,0x11,0x39,0xd0,0xfe,0xe9,0xc8,
1334
0xb3,0x91,0x17,0x23,0xbf,0x8c,0xec,0x8f,0x14,0x44,0x89,0xa3,0x5c,0xa3,0xbc,0xa2,
1335
0x7e,0xac,0x1f,0x18,0x15,0x1c,0xf5,0x5b,0xd7,0xcf,0x7f,0xf5,0xfa,0xfb,0xf7,0x7c,
1336
0x6e,0x7d,0xcf,0xbf,0xa1,0x1f,0x16,0x15,0x15,0x65,0x88,0xba,0x2d,0xea,0xee,0x28,
1337
0x99,0xea,0xbe,0xa8,0x07,0xa2,0x1e,0x8e,0x7a,0x3c,0x4a,0xae,0x7a,0x32,0x6a,0x42,
1338
0xd4,0x33,0x51,0x4a,0xd5,0xf4,0xa8,0xd9,0x51,0xf3,0xa2,0x16,0x44,0xbd,0x12,0x95,
1339
0x10,0x95,0x18,0x99,0x14,0x95,0x1e,0xb5,0x2c,0x6a,0x45,0xd4,0x9a,0x28,0x2b,0xf5,
1340
0x86,0xa8,0xd1,0xa2,0xbc,0xa8,0xc2,0xa8,0xad,0x51,0x3b,0xa2,0x8e,0x44,0x96,0x46,
1341
0x95,0x47,0x49,0xd5,0xec,0x6f,0x79,0xb8,0xaa,0xf7,0x45,0xd5,0x44,0x8d,0x55,0x34,
1342
0x44,0x69,0x55,0xff,0x8c,0x3a,0x18,0xd5,0x16,0xf5,0x26,0x17,0x3a,0xa2,0x4e,0x47,
1343
0xbd,0x1b,0xf5,0x61,0xd4,0xf9,0xa8,0x9e,0xa8,0x4b,0x51,0x97,0xa3,0xae,0x44,0x5d,
1344
0x8d,0xba,0x16,0x65,0x8c,0xe2,0x45,0xf3,0xa3,0x6d,0xa2,0x85,0xd1,0x92,0x68,0x67,
1345
0x04,0x4f,0xf5,0xf0,0x68,0x59,0xb4,0x3c,0x5a,0x19,0x1d,0xa9,0xf2,0x89,0x0e,0x88,
1346
0xd6,0x46,0xe7,0x28,0x75,0xd1,0x91,0xd1,0xfa,0xe8,0xf8,0xe8,0x3b,0xa3,0x47,0x45,
1347
0x8f,0x89,0x1e,0x1b,0xfd,0x68,0xf4,0x3f,0xa2,0x9f,0x8e,0x9e,0x1c,0x3d,0x25,0xf2,
1348
0xd9,0xe8,0x99,0xd1,0x73,0xa3,0x5f,0x88,0x7e,0x39,0xfa,0xb5,0xe8,0xc4,0xe8,0xd4,
1349
0xe8,0xa5,0xd1,0x99,0xd1,0xab,0xa2,0xd7,0x45,0x67,0x23,0xe4,0x47,0x17,0x45,0x17,
1350
0x47,0xc7,0x2b,0x4a,0xa2,0xcb,0xa2,0xf7,0x46,0x57,0x47,0xd7,0x47,0xef,0x17,0x35,
1351
0x47,0x1f,0x88,0x6e,0x14,0x1d,0x8e,0x3e,0x1a,0x7d,0x3c,0xfa,0x54,0xf4,0x3b,0xd1,
1352
0x1f,0x46,0x9f,0x8f,0xee,0x8e,0xbe,0x18,0xfd,0x69,0xf4,0x17,0xd1,0x5f,0x47,0x7f,
1353
0x17,0xdd,0x1f,0x6d,0x19,0x33,0x28,0x66,0x48,0x8c,0x30,0x46,0x12,0xe3,0x1c,0x33,
1354
0x3c,0x66,0xbe,0xa7,0x2c,0xa6,0x5b,0xe4,0x19,0xe3,0x19,0xa3,0x8e,0xf1,0x43,0x08,
1355
0x8a,0x09,0x89,0x89,0x88,0xd1,0xc7,0xc4,0xc7,0xdc,0x19,0x33,0x2a,0x66,0x4c,0xcc,
1356
0xd8,0x98,0x47,0x63,0xc6,0xc5,0x3c,0x15,0x33,0x29,0x66,0x8c,0x6a,0x6a,0xcc,0xcc,
1357
0x98,0xb9,0x31,0xcf,0xc7,0x3c,0xa4,0x7e,0x3e,0xe6,0xc5,0x98,0x47,0x55,0x8b,0x62,
1358
0x98,0x98,0xe4,0x98,0xf4,0x98,0x71,0x2a,0xbe,0xe7,0xb2,0x98,0x15,0x31,0x6b,0x62,
1359
0x36,0xc4,0xe4,0xc6,0x6c,0x8a,0xd9,0x12,0xb3,0x23,0xa6,0x34,0xa6,0x3c,0x66,0x5f,
1360
0x4c,0x4d,0x4c,0x43,0xcc,0xeb,0x31,0x87,0x62,0x8e,0xc4,0x1c,0x8b,0x39,0x11,0x73,
1361
0x3a,0xe6,0xdd,0x98,0x0f,0x63,0xce,0xc7,0x3c,0xa5,0xea,0x8e,0xb9,0x18,0x73,0x39,
1362
0xe6,0x4a,0xcc,0xd5,0x98,0x6b,0x31,0x53,0x55,0xc6,0x18,0x9e,0x9e,0xaf,0xb7,0xd1,
1363
0x0b,0xf5,0x12,0xbd,0xb3,0x7e,0xb8,0x9e,0xfd,0x5d,0x14,0x99,0x5e,0xae,0x57,0xea,
1364
0x7d,0xf4,0x81,0xfa,0x60,0x7d,0x98,0x3e,0x4a,0x3f,0x43,0x65,0xd0,0xdf,0xae,0xbf,
1365
0x5b,0x7f,0x9f,0x5e,0xe6,0xfd,0x80,0xfe,0x61,0xfd,0xe3,0xfa,0x27,0xf5,0x13,0xf4,
1366
0x53,0xf4,0xd3,0xf5,0xb3,0xf5,0xf3,0xf4,0x0b,0xf5,0xaf,0xe8,0x13,0xf4,0x49,0xfa,
1367
0x34,0x45,0x9a,0x3e,0x43,0xbf,0x42,0xbf,0x56,0x9f,0xad,0xcf,0xd7,0x17,0xe9,0x8b,
1368
0xf5,0x25,0xfa,0x32,0x7d,0xa5,0x7e,0x8e,0xaa,0xd3,0xab,0x4a,0x5f,0xa7,0x6f,0xd2,
1369
0xb7,0xe8,0x0f,0xeb,0x8f,0xea,0x8f,0xeb,0x4f,0xea,0x19,0xf5,0xdb,0xfa,0xf7,0xf5,
1370
0xe7,0xf4,0x5d,0xfa,0x3e,0xfd,0xa7,0xfa,0x2b,0xfa,0xab,0xfa,0x64,0xf5,0x35,0xbd,
1371
0x51,0xcf,0x33,0xf0,0x0d,0x36,0x06,0xa1,0x41,0x62,0x90,0x1a,0x5c,0x0d,0x23,0x0d,
1372
0x0a,0x83,0xb7,0x61,0x99,0xda,0xdf,0xa0,0x31,0xe8,0x0c,0x91,0x06,0xbd,0xe1,0x36,
1373
0xc3,0xdd,0x86,0xfb,0x0c,0x0f,0x18,0x1e,0x36,0x3c,0x8e,0xf0,0xa4,0x61,0x82,0x61,
1374
0x8d,0xfa,0x19,0xc3,0x34,0xc3,0x2c,0xc3,0x73,0x86,0x17,0x0c,0x2f,0x1b,0x5e,0x33,
1375
0x8c,0x51,0x24,0x19,0xd2,0x0d,0xcb,0x0c,0x2b,0x0d,0xeb,0x0c,0x39,0x86,0x02,0xc3,
1376
0x2e,0x75,0x91,0x61,0xbb,0xa1,0xd4,0x50,0x61,0xa8,0x32,0xd4,0x21,0xec,0x51,0x2b,
1377
0xbd,0x9b,0x0c,0x2d,0x86,0x56,0xc3,0x1b,0x86,0xe3,0x86,0x3a,0xcf,0x6a,0xf5,0x49,
1378
0xc3,0xdb,0x86,0xf5,0xaa,0x0f,0x0c,0xe7,0x0d,0x97,0x94,0x3d,0x86,0x4b,0x86,0x22,
1379
0xd5,0x65,0xc3,0x15,0xc3,0x55,0xc3,0xf7,0x08,0x16,0xb1,0xd6,0xb1,0x83,0x63,0xed,
1380
0x63,0xc5,0xb1,0x4e,0xb1,0xc3,0x62,0x65,0xb1,0xf2,0x58,0x65,0xac,0x4f,0x6c,0x40,
1381
0xac,0x36,0x36,0x2c,0x36,0x2a,0xd6,0x10,0x7b,0x5b,0xec,0x5d,0xb1,0xf7,0xc6,0xde,
1382
0x1f,0xfb,0x70,0xec,0x13,0xb1,0xe3,0x63,0x27,0xc5,0x4e,0x8d,0x9d,0x19,0x3b,0x37,
1383
0xb6,0x4e,0xf5,0x7c,0xec,0x4b,0xb1,0xaf,0xc5,0x26,0xc6,0xa6,0xc5,0x66,0xc4,0xae,
1384
0x88,0x5d,0x13,0xbb,0x21,0x36,0x37,0x76,0x53,0xec,0x96,0xd8,0xed,0xb1,0xa5,0xb1,
1385
0x15,0xb1,0x55,0xb1,0xea,0x98,0xfa,0xd8,0xe6,0xd8,0x03,0xb1,0x87,0x63,0x8f,0xc6,
1386
0x1e,0x8f,0x3d,0x19,0xfb,0x76,0xec,0xfb,0xb1,0x67,0x63,0x3f,0x8a,0xed,0x8d,0x5d,
1387
0xad,0xf8,0x24,0xf6,0xf3,0xd8,0xaf,0x62,0xbf,0x8d,0xfd,0x21,0xd6,0x22,0xae,0x55,
1388
0x65,0x1d,0x37,0x38,0xce,0x2e,0x4e,0x14,0xe7,0x18,0x37,0x2c,0x4e,0x16,0xe7,0x19,
1389
0xa7,0x8a,0xf3,0x8d,0x0b,0x8c,0x0b,0x8e,0x0b,0x8f,0x8b,0x8e,0x8b,0x8b,0xbb,0x23,
1390
0xee,0x9e,0xb8,0x31,0x71,0x0f,0xc5,0x3d,0x16,0x57,0xec,0xf9,0x8f,0xb8,0xa7,0xe3,
1391
0x26,0xc7,0x3d,0x1b,0x37,0x33,0x6e,0x6e,0xdc,0x49,0xf5,0xf3,0x71,0x2f,0xc6,0x2d,
1392
0x8a,0x63,0xe2,0x92,0xe3,0xd2,0xe3,0x96,0xc5,0xad,0x88,0x1b,0x2d,0x59,0x13,0xb7,
1393
0x31,0x2e,0x2f,0xae,0x30,0x6e,0x6b,0xdc,0x8e,0xb8,0xd2,0xb8,0x8a,0xb8,0xaa,0xb8,
1394
0xba,0xb8,0xa6,0xb8,0x5e,0xf5,0xc7,0xea,0xe9,0x92,0x96,0xb8,0xc3,0x71,0x47,0xe3,
1395
0x8e,0xc7,0x9d,0x8c,0x7b,0x3b,0xee,0x83,0xb8,0xf3,0x71,0xdd,0x71,0x17,0xe3,0x3e,
1396
0x8d,0xbb,0x12,0xf7,0x99,0xfa,0x6a,0xdc,0xf7,0x71,0x16,0xf1,0xd6,0xf1,0x83,0xe3,
1397
0xed,0xe2,0xc5,0xf1,0x4e,0xf1,0xc3,0xe2,0xdd,0xe2,0x3d,0xe2,0xbd,0xe2,0xbd,0xe3,
1398
0xfd,0xe3,0xb5,0xf1,0xba,0xf8,0xc8,0x78,0x7d,0xfc,0x6d,0xf1,0x77,0xc5,0xdf,0x1b,
1399
0x7f,0x7f,0xfc,0x43,0xf1,0x8f,0xc7,0x8f,0x8f,0x9f,0x18,0x3f,0x25,0x7e,0x7a,0xfc,
1400
0x9c,0xf8,0xf9,0xf1,0x02,0x6f,0x81,0xf7,0x8b,0xf1,0x8b,0xe2,0x17,0xc7,0xa7,0xc4,
1401
0x2f,0x89,0x5f,0x1e,0xbf,0x32,0x7e,0x6d,0xfc,0xc6,0xf8,0xbc,0x78,0x5b,0xef,0xcd,
1402
0xf1,0xdb,0xe2,0x77,0xc6,0xef,0x8e,0xaf,0x88,0xdf,0x1f,0x5f,0x17,0xdf,0x14,0x7f,
1403
0x20,0xbe,0x2d,0xde,0xdb,0xe1,0x58,0x7c,0x84,0xc3,0x89,0xf8,0xd3,0xf1,0xef,0xc6,
1404
0x7f,0x18,0x3f,0xda,0xe1,0x7c,0xfc,0x9f,0xf1,0xfb,0x47,0x3f,0x7a,0x1b,0xc7,0xe6,
1405
0xd2,0x64,0xd4,0x6c,0x34,0x5e,0x36,0xef,0x39,0xc3,0xc5,0x7a,0xf3,0x56,0xcf,0xcd,
1406
0x77,0x36,0x1e,0xfd,0x68,0xaf,0xde,0x98,0x80,0x78,0x8c,0x91,0xfb,0xbf,0x42,0xcc,
1407
0xf5,0x52,0xd7,0xd8,0xff,0x20,0x50,0xf0,0xad,0xd1,0xf8,0xc3,0xc1,0x2b,0x9f,0x36,
1408
0x61,0xeb,0x87,0x4f,0xae,0x34,0x45,0x5a,0x50,0xbb,0x91,0xd7,0xff,0x29,0xb7,0xff,
1409
0x93,0x2b,0x1f,0xb7,0x46,0x9f,0x96,0xb6,0x1a,0x5b,0x5a,0xa3,0x17,0xb3,0xda,0x7c,
1410
0xe3,0x99,0x1f,0xb0,0xdf,0x78,0xe5,0x4c,0xf4,0xd3,0xba,0x76,0xb6,0x2d,0x6e,0xfb,
1411
0x32,0xbb,0x3d,0xb7,0xdd,0x68,0x4f,0xdc,0x36,0x6b,0xdc,0x0f,0x9f,0x19,0xdb,0x91,
1412
0x7e,0x6a,0x4c,0xf8,0x1e,0x4a,0x01,0x09,0xc9,0x4f,0x19,0x9b,0x8d,0xae,0xac,0x5d,
1413
0x42,0xae,0x5f,0x67,0x8c,0x7c,0x2e,0x8d,0x4e,0x88,0xe6,0x2a,0x70,0x31,0xbb,0x91,
1414
0x60,0xb6,0x2e,0xda,0x78,0x53,0x1f,0x64,0x6c,0xa7,0xcc,0x33,0x69,0xd9,0xcd,0xaf,
1415
0x5d,0xd1,0x39,0x18,0x91,0x40,0x6c,0xb3,0xc6,0x33,0xec,0xff,0x85,0x41,0x6f,0x79,
1416
0xa6,0xb2,0xc6,0xeb,0xff,0x47,0x49,0xcf,0xee,0x4f,0x30,0x0a,0x8d,0xc2,0xcf,0xb9,
1417
0x4d,0x99,0xc9,0x3f,0x42,0xae,0xd5,0x56,0x73,0xa1,0x76,0x73,0xca,0x1a,0x50,0xc0,
1418
0xb5,0xa1,0x37,0x7b,0x4f,0xc8,0xd9,0x7b,0xd3,0x47,0xf8,0x99,0x39,0xf3,0x8d,0xf1,
1419
0xc2,0x4d,0xe7,0x07,0x8a,0x26,0xcf,0x9b,0xfe,0xcb,0x34,0x4e,0x03,0xdd,0xdc,0x74,
1420
0x93,0x3b,0xd7,0x3c,0x25,0x98,0x3f,0xd7,0x8d,0xe3,0xde,0x51,0xdf,0xf8,0x70,0xd6,
1421
0x9a,0x7b,0x99,0x70,0xf3,0xfb,0x58,0xe1,0xf5,0xf1,0x60,0x4a,0x65,0x46,0x9e,0xbe,
1422
0xd9,0xdc,0x57,0xa3,0x90,0xe1,0xf6,0x34,0x19,0x5b,0xcc,0x7d,0x30,0xd5,0xd6,0x1b,
1423
0xaf,0x98,0xfe,0x83,0x00,0x7d,0xc3,0x6e,0xbf,0xf6,0xda,0x6b,0x74,0x43,0xd9,0x54,
1424
0x57,0xc8,0xfe,0xa7,0xe5,0x6f,0x06,0x14,0xcc,0x6f,0x81,0x2f,0x73,0x8d,0x54,0xa1,
1425
0x8c,0xfe,0xa6,0x71,0xc8,0x4f,0xe3,0x92,0x2c,0xf6,0xa0,0xcc,0xe2,0xc6,0xfb,0x62,
1426
0xfd,0x0d,0x8b,0xb9,0xbe,0x73,0x7f,0x01,0x2c,0x3c,0x7b,0xfd,0x1c,0xb0,0x71,0x93,
1427
0xc9,0xe5,0xfa,0x1b,0xb5,0xe8,0x46,0xc7,0xb8,0x5e,0x63,0xbf,0x9e,0x1b,0x3e,0x4d,
1428
0x2b,0xcd,0xc5,0xb9,0x4e,0x30,0xc6,0x81,0x37,0xd3,0xba,0x6f,0x4c,0xe2,0xc6,0x24,
1429
0x93,0x77,0xaf,0xdb,0x85,0xf3,0xf1,0x3d,0x97,0x99,0xf3,0xd9,0x65,0xb8,0x52,0x9f,
1430
0x86,0x91,0x61,0x71,0xf3,0x1b,0x6e,0xae,0xa1,0x6f,0x06,0xbc,0xa9,0xef,0x37,0x99,
1431
0xcc,0x9a,0xc5,0x73,0xa3,0x7e,0x1c,0xb7,0xb8,0xf9,0xed,0x37,0xff,0x7b,0xb3,0x7d,
1432
0xf0,0xef,0x8f,0xde,0x8c,0x9b,0x3c,0x17,0xc9,0xa3,0xef,0x4d,0x35,0xbe,0xbf,0x7e,
1433
0x96,0x07,0xac,0xe1,0xce,0x11,0xeb,0x77,0xf6,0x90,0x7e,0xe0,0x62,0x3b,0xc3,0x27,
1434
0x6e,0xb4,0xf2,0xae,0x5f,0xba,0x74,0xe3,0xec,0xb2,0xef,0x37,0x4d,0x57,0xa3,0xb9,
1435
0x19,0x7c,0x12,0x1a,0xe0,0x80,0x81,0xff,0x47,0xc4,0x37,0xf2,0x4c,0xd7,0xe9,0x27,
1436
0xd7,0x0a,0xc2,0x17,0x9f,0x6d,0x97,0xa1,0xfc,0x28,0xce,0x4f,0xc6,0xad,0x57,0x9b,
1437
0x2c,0x06,0x99,0x94,0x2f,0xb3,0x75,0x59,0x9b,0x6f,0xf4,0x43,0xcf,0xb6,0xcc,0x43,
1438
0x34,0xe0,0x27,0xee,0xca,0x10,0x9a,0x8e,0xf7,0xb0,0x67,0x29,0xe1,0xc7,0x6f,0xfd,
1439
0xcd,0x7f,0xb9,0xcd,0x67,0x12,0xbe,0x98,0xc3,0xb6,0xff,0x6d,0x02,0x5d,0x37,0x89,
1440
0xcc,0x2e,0xfe,0x5e,0x66,0xd2,0x31,0xde,0xf8,0xef,0x14,0x37,0x19,0xce,0x1d,0x33,
1441
0xb5,0xc7,0x63,0xb5,0x7f,0x30,0x5d,0x52,0x37,0xc6,0x34,0x1a,0xe9,0xc7,0x35,0xc0,
1442
0x75,0x37,0x61,0x2f,0x6b,0x6f,0x13,0x5b,0x26,0xe1,0xda,0x80,0x77,0x84,0x03,0x6d,
1443
0x99,0xae,0x6f,0xae,0x81,0x56,0xd3,0x10,0x1e,0xf8,0x98,0xaf,0x2f,0x23,0xcf,0xe4,
1444
0xdf,0x04,0x19,0x09,0x6f,0xf9,0xfd,0x05,0x9f,0x06,0x46,0x80,0xf9,0xaa,0x32,0x19,
1445
0xd3,0x72,0xbd,0x40,0x02,0xa7,0xa9,0xd7,0x63,0x1e,0x68,0xbc,0x06,0x93,0xce,0x1a,
1446
0xaf,0x8f,0x35,0x53,0x8b,0xc6,0x34,0x73,0x49,0xe6,0xc6,0x37,0x25,0x32,0x4a,0x20,
1447
0xf3,0x65,0xcb,0x18,0x6f,0xb8,0x10,0x9f,0xcb,0x73,0x4c,0xaa,0x56,0xc8,0x2b,0xe9,
1448
0xb3,0xeb,0x57,0xcd,0xc0,0xb5,0x21,0xfc,0xde,0x74,0x7d,0x58,0xd0,0xcd,0xf7,0xee,
1449
0x84,0x7e,0x73,0x6b,0x66,0x5d,0xf3,0x15,0x69,0xea,0xbf,0x90,0xbe,0xe9,0x37,0xfd,
1450
0xaf,0xe7,0x84,0xb3,0xac,0x07,0x98,0x9b,0x7a,0x29,0x43,0x0b,0x2d,0x37,0x8f,0xce,
1451
0xeb,0xbd,0x4f,0xa2,0x1f,0xdf,0x81,0xd2,0x4c,0x63,0xd7,0x34,0x9a,0x13,0xe6,0x18,
1452
0x13,0x0a,0xcc,0x66,0xc3,0xdb,0x2d,0x37,0xff,0x9f,0x16,0xd3,0x47,0x36,0x90,0x33,
1453
0x9b,0xc5,0x33,0xd9,0x94,0x30,0x30,0x2f,0x37,0xed,0x6e,0x36,0x95,0xf9,0x1c,0x76,
1454
0x98,0xee,0xcf,0x42,0x0b,0x1a,0x18,0x41,0xec,0x79,0xbd,0x7e,0x8d,0xe3,0x0e,0xca,
1455
0x33,0x5f,0x61,0xdc,0x1e,0x0c,0xcb,0x81,0xbb,0x6e,0xc2,0x39,0xdc,0x6b,0xd9,0xab,
1456
0xd5,0x78,0xf5,0xfa,0xed,0xef,0xc6,0x77,0x6a,0x37,0xee,0xe1,0x34,0x81,0x26,0xd2,
1457
0x24,0x9a,0x4c,0xcf,0xd0,0x14,0x9a,0x4a,0xcf,0xd2,0x34,0x9a,0x4e,0x33,0x68,0x26,
1458
0xcd,0xa2,0xd9,0x34,0x87,0xe6,0xd2,0x73,0x34,0x8f,0xe6,0xd3,0xf3,0xf4,0x02,0x2d,
1459
0xa0,0x85,0xf4,0x22,0xbd,0x44,0x2f,0x93,0x3b,0xb9,0x1f,0x4d,0x07,0xc9,0xa4,0xc1,
1460
0xd2,0xd1,0xfd,0xe8,0x62,0x3a,0x56,0x8f,0xa4,0x18,0x2b,0xc9,0xa0,0xf3,0x8b,0x93,
1461
0x83,0xb9,0x18,0x87,0xb8,0x7c,0xcb,0x26,0x6a,0x29,0xa4,0x96,0xcd,0xd4,0x52,0x44,
1462
0x2d,0x5b,0xa8,0x65,0x2b,0xb5,0x6c,0xa3,0x96,0x62,0x6a,0xd9,0x4e,0x2d,0x3b,0xa8,
1463
0x65,0x27,0xb5,0x94,0x50,0xcb,0x2e,0x6a,0x29,0xa5,0x96,0xdd,0xd4,0x52,0x46,0x2d,
1464
0x7b,0xa8,0xa5,0x9c,0x5a,0x2a,0xa8,0xa5,0x92,0x5a,0xf6,0x52,0xcb,0x3e,0x6a,0xd9,
1465
0x4f,0x2d,0xd5,0xd4,0x52,0x43,0x2d,0xb5,0xd4,0x52,0x47,0x2d,0xf5,0xd4,0xd2,0x40,
1466
0x2d,0x8d,0x74,0x60,0x31,0x1d,0x48,0xa2,0x03,0x29,0x74,0x20,0x8d,0x0e,0x2c,0xa1,
1467
0x03,0x19,0x74,0x60,0x39,0x1d,0xc8,0xa2,0x03,0x2b,0xe9,0xc0,0x6a,0x3a,0xb0,0x96,
1468
0x0e,0xac,0xa7,0x03,0x1b,0xe9,0x40,0x0e,0x1d,0xc8,0xa3,0x03,0x05,0x74,0xa0,0x90,
1469
0x0e,0x14,0xd1,0x81,0xad,0x74,0xa0,0x98,0x0e,0xec,0xa0,0x03,0x25,0x74,0xa0,0x94,
1470
0x0e,0x94,0xd1,0xb4,0xa3,0x69,0x34,0x6d,0x3a,0x1d,0xd8,0x47,0x07,0xaa,0xe8,0x40,
1471
0x2d,0x1d,0xa8,0xa7,0x03,0x8d,0x34,0xf3,0xf5,0x2a,0x3a,0x98,0x48,0x07,0x93,0xe9,
1472
0x60,0x2a,0x1d,0x4c,0xa7,0x23,0xf5,0xb3,0xe9,0x60,0x06,0x1d,0x5c,0x4e,0x07,0xb3,
1473
0xe8,0xe0,0x4a,0x3a,0xb8,0x9a,0x0e,0xae,0xa5,0x83,0xeb,0xe9,0xe0,0x46,0x3a,0x98,
1474
0x43,0x07,0xf3,0xe8,0x60,0x01,0x1d,0x2c,0xa4,0x83,0x45,0x74,0x70,0x2b,0x1d,0x2c,
1475
0xa6,0x83,0x3b,0xe8,0x60,0x09,0x1d,0x2c,0xa5,0x83,0x65,0x74,0xb0,0x9c,0x0e,0x56,
1476
0xd2,0xc1,0x7d,0x74,0xb0,0x8a,0x5a,0x9a,0xe8,0x60,0x2d,0x1d,0xac,0xa7,0x83,0x8d,
1477
0xd4,0xb6,0x9a,0x0e,0x25,0xd1,0xa1,0x14,0x6a,0x5b,0x43,0x87,0xd2,0xa9,0x6d,0x1d,
1478
0xb5,0xad,0xa7,0x43,0xcb,0xa8,0x35,0x8f,0xda,0x36,0x52,0x5b,0x0e,0x1d,0x5a,0x45,
1479
0x6d,0x9b,0xa8,0xad,0x88,0xda,0x76,0x50,0xdb,0x76,0x3a,0x84,0x9d,0x65,0xd4,0x56,
1480
0x41,0x6d,0xfb,0xe8,0x50,0x21,0x1d,0x2a,0xa2,0x43,0x5b,0xe9,0x08,0x43,0x87,0xb6,
1481
0xd3,0x11,0xb4,0x53,0x4a,0x47,0xd2,0xe9,0xd0,0x1e,0x3a,0xb2,0x94,0x8e,0x64,0xd0,
1482
0xa1,0xbd,0x74,0x68,0x3f,0x1d,0x59,0x45,0x87,0x6a,0xe8,0x50,0x03,0x4d,0x86,0xde,
1483
0xcc,0xe9,0x34,0x7b,0x3a,0xb5,0x66,0x52,0xeb,0x0a,0x6a,0x5d,0x45,0xad,0x6b,0xa8,
1484
0x75,0x1d,0xb5,0x6e,0xa0,0xd6,0x6c,0x6a,0xcd,0xa5,0xd6,0x02,0x6a,0x2d,0xa4,0xd6,
1485
0x22,0x6a,0xdd,0x4a,0xad,0xc5,0xd4,0xba,0x83,0x5a,0x4b,0xa8,0xb5,0x94,0x5a,0xcb,
1486
0x68,0xf2,0xcb,0xd4,0x0a,0xc9,0xb5,0x74,0xa8,0x89,0x5a,0x6b,0xa8,0xb5,0x8e,0x5a,
1487
0x1b,0xa8,0xb5,0x89,0x0e,0x2f,0xa6,0xc3,0x49,0x74,0x38,0x85,0x0e,0xa7,0xd1,0xe1,
1488
0x25,0x74,0x38,0x83,0x0e,0x2f,0xa7,0xc3,0x59,0x74,0x78,0x25,0x1d,0x5e,0x4d,0x87,
1489
0xd7,0xd2,0xe1,0xf5,0x74,0x78,0x23,0x1d,0xce,0xa1,0xc3,0x79,0x74,0xb8,0x80,0x0e,
1490
0xe5,0xd3,0xe1,0x22,0x3a,0xbc,0x95,0x0e,0x17,0xd3,0xe1,0x1d,0x74,0xb8,0x84,0x0e,
1491
0x97,0xd2,0xe1,0x32,0x3a,0x5c,0x4e,0x87,0x2b,0xe9,0x7c,0x39,0x0e,0xd4,0xd3,0xa1,
1492
0x6c,0xe4,0xb6,0x51,0x5b,0x22,0x1d,0x62,0xe8,0xc8,0x12,0x3a,0xb2,0x8c,0xda,0xd2,
1493
0xa8,0x6d,0x09,0xb5,0x65,0x50,0xdb,0x72,0x6a,0xcb,0xa2,0x36,0x1c,0xad,0xa1,0xb6,
1494
0x3a,0x3a,0xb2,0x18,0x03,0x2f,0x15,0xa4,0x81,0xa5,0x60,0x3b,0x48,0x02,0x19,0x74,
1495
0x64,0x2d,0x1d,0x65,0x08,0x83,0xf3,0xe8,0x6a,0x3a,0x9a,0xce,0x0e,0xd2,0x1a,0x7a,
1496
0xb3,0x9c,0xde,0xac,0xa4,0x23,0xc8,0x54,0x91,0x3b,0xb6,0x23,0xa9,0xbd,0x92,0x1d,
1497
0xcc,0xec,0xd1,0x5d,0x84,0x33,0x7e,0xac,0x94,0x8e,0xed,0xa6,0x63,0x65,0xd4,0xbe,
1498
0x8c,0xda,0x97,0x53,0x7b,0x26,0x1d,0x2b,0xa7,0x63,0x15,0x74,0xac,0x92,0x8e,0xed,
1499
0xa5,0x63,0xfb,0xe8,0xd8,0x7e,0x3a,0x86,0x62,0xd5,0x74,0xac,0x96,0x8e,0xd5,0xd1,
1500
0xb1,0x06,0x3a,0xd6,0x48,0xc7,0x9a,0xa8,0x9d,0xa1,0xf6,0xc5,0xd4,0x9e,0x44,0xed,
1501
0xc9,0xd4,0x9e,0x42,0xed,0xa9,0xd4,0x9e,0x46,0xed,0xe9,0xd4,0xbe,0x84,0xda,0x97,
1502
0x52,0x7b,0x06,0xb5,0xaf,0xa7,0xf6,0x8d,0xd4,0x9e,0x43,0xed,0x79,0xd4,0x5e,0x40,
1503
0xed,0x85,0xd4,0x5e,0x44,0xed,0x5b,0xa9,0xbd,0x98,0xda,0x77,0x50,0x7b,0x09,0xb5,
1504
0x97,0x52,0x3b,0x74,0xab,0xa9,0xbd,0x8e,0xde,0xc4,0x4f,0x3d,0xbd,0xd9,0x40,0x1d,
1505
0x2b,0xa8,0x63,0x25,0x75,0xac,0xa2,0x8e,0xd5,0xd4,0xb1,0x86,0x3a,0xd6,0x52,0xc7,
1506
0x3a,0xea,0x58,0x4f,0x1d,0x1b,0xa8,0x63,0x23,0x75,0x64,0x53,0x47,0x0e,0x75,0xe4,
1507
0x52,0x47,0x1e,0x75,0xe4,0x53,0x47,0x01,0x1d,0xdf,0x43,0xc7,0xcb,0xe9,0x78,0x05,
1508
0x1d,0xaf,0xa4,0xe3,0x7b,0xe9,0xf8,0x3e,0x3a,0xbe,0x9f,0x8e,0x57,0xd1,0xf1,0x6a,
1509
0x3a,0x5e,0x43,0xc7,0x6b,0xe9,0x78,0x1d,0x1d,0xaf,0xa7,0xe3,0x0d,0x74,0xbc,0x91,
1510
0x8e,0x37,0x51,0x07,0x43,0x1d,0x8b,0xa9,0x23,0x91,0x3a,0x92,0xa8,0x23,0x99,0x3a,
1511
0x52,0xa8,0x23,0x95,0x3a,0xd2,0xa8,0x23,0x9d,0x3a,0x96,0x50,0xc7,0x52,0xea,0xc8,
1512
0xa0,0x8e,0x65,0xd4,0xb1,0x9c,0x3a,0x32,0xa9,0x23,0x8b,0x3a,0x0a,0xa9,0xa3,0x88,
1513
0x3a,0xb6,0x52,0x47,0x31,0x75,0xec,0xa0,0x8e,0x12,0xea,0x28,0xa5,0x8e,0x32,0xea,
1514
0x28,0xa7,0x8e,0x4a,0xea,0xd8,0x47,0x1d,0x55,0xd4,0x51,0x43,0x1d,0x75,0xd4,0x01,
1515
0xe3,0x9b,0xe8,0xc4,0x62,0x3a,0x91,0x41,0x27,0x96,0xd3,0x89,0x2c,0x3a,0xb1,0x92,
1516
0x4e,0xac,0xa6,0x13,0x6b,0xe9,0xc4,0x7a,0x3a,0xb1,0x91,0x4e,0xe4,0xd0,0x89,0x3c,
1517
0x3a,0x51,0x40,0x27,0x0a,0xe9,0x44,0x11,0x9d,0xd8,0x4a,0x27,0x8a,0xe9,0xc4,0x0e,
1518
0x3a,0x51,0x42,0x27,0x4a,0xe9,0x44,0x19,0x9d,0x28,0xa7,0x13,0x95,0x74,0x62,0x1f,
1519
0x9d,0xa8,0xa2,0x13,0x35,0x74,0xa2,0x8e,0x4e,0x34,0xd0,0x89,0x26,0xea,0xcc,0xa2,
1520
0xce,0x44,0xea,0x4c,0xa6,0xce,0x54,0xea,0x4c,0xa7,0xce,0xa5,0xd4,0xb9,0x8c,0x3a,
1521
0x33,0xa9,0x73,0x25,0x75,0xae,0xa6,0xce,0xb5,0xd4,0xb9,0x9e,0x3a,0x37,0x52,0x67,
1522
0x0e,0x75,0xe6,0x51,0x67,0x01,0x75,0x16,0x52,0x67,0x11,0x75,0x6e,0xa5,0xce,0x62,
1523
0xea,0xdc,0x41,0x9d,0x25,0xd4,0x59,0x4a,0x9d,0x65,0xd4,0x59,0x4e,0x9d,0x95,0xd4,
1524
0xb9,0x8f,0x3a,0xab,0xa8,0xb3,0x86,0x3a,0xeb,0xa8,0xb3,0x81,0x3a,0x9b,0xe8,0xe4,
1525
0x62,0x3a,0x99,0x44,0x27,0x53,0xe8,0x64,0x1a,0x9d,0x5c,0x42,0x27,0x33,0xe8,0xe4,
1526
0x72,0x3a,0x99,0x45,0x27,0x57,0xd2,0xc9,0xd5,0x74,0x72,0x2d,0x9d,0x5c,0x4f,0x27,
1527
0x37,0xd2,0xc9,0x1c,0x3a,0x99,0x47,0x27,0x0b,0xe8,0x64,0x21,0x9d,0x2c,0xa2,0x93,
1528
0x5b,0xe9,0x64,0x31,0x9d,0xdc,0x41,0x27,0x4b,0xe8,0x64,0x29,0x9d,0x2c,0xa3,0x53,
1529
0x85,0x74,0x6a,0x33,0x9d,0x2a,0xa2,0x53,0x5b,0xe8,0xd4,0x56,0x3a,0xb5,0x8d,0x4e,
1530
0x15,0xd3,0xa9,0xed,0x74,0x6a,0x07,0x9d,0xda,0x49,0xa7,0x4a,0xe8,0xd4,0x2e,0x3a,
1531
0x55,0x4a,0xa7,0x76,0xd3,0x29,0x14,0xde,0x43,0xa7,0xca,0xe9,0x54,0x05,0x9d,0xaa,
1532
0xa4,0x53,0x7b,0xe9,0xd4,0x3e,0x3a,0xb5,0x9f,0x4e,0x55,0xd1,0xa9,0x6a,0x3a,0x55,
1533
0x43,0xa7,0x6a,0xe9,0x54,0x1d,0x9d,0xaa,0xa7,0x53,0x0d,0x74,0xaa,0x91,0x4e,0x35,
1534
0xd1,0x69,0x86,0x4e,0x2f,0xa6,0xd3,0x89,0x74,0x3a,0x89,0x4e,0x27,0xd3,0xe9,0x14,
1535
0x3a,0x9d,0x0a,0x15,0xec,0x78,0xbb,0xf8,0x9d,0xbd,0xf4,0x4e,0x3a,0xa2,0xf7,0xd2,
1536
0xd8,0xdc,0x52,0x44,0x67,0xb7,0xac,0x3d,0xbb,0xa5,0x1e,0xc9,0x3a,0x53,0xb2,0xde,
1537
0x94,0xe4,0x9a,0x92,0x42,0x53,0xb2,0xd9,0x94,0x94,0x98,0x92,0x32,0x2e,0xd9,0x56,
1538
0x78,0x76,0x1b,0x9b,0x6c,0x36,0x25,0x65,0x5c,0xb2,0xbd,0xe2,0xec,0x76,0x36,0xa9,
1539
0x36,0x25,0xeb,0x4c,0xc9,0x7a,0x53,0x92,0x6b,0x4a,0x4a,0xb8,0x64,0x57,0xe1,0xd9,
1540
0x5d,0x6c,0xb2,0x99,0x4b,0x6a,0x96,0x9f,0xad,0xae,0xa0,0xb3,0x75,0xcb,0xcf,0xd6,
1541
0x22,0xa9,0x2d,0x39,0x5b,0xbb,0xd1,0x94,0x14,0xd2,0xd9,0xfa,0x0c,0x3a,0xdb,0x90,
1542
0x78,0xb6,0xb1,0x0a,0xc9,0x32,0x53,0xb2,0xd2,0x94,0xac,0x33,0x25,0x39,0xa6,0x84,
1543
0x39,0xdb,0xb8,0x0f,0x49,0xf9,0xd9,0x86,0x0a,0x53,0x82,0xce,0x35,0x56,0x9c,0x6d,
1544
0x64,0xb8,0x04,0x3b,0xb8,0x5c,0xe5,0x40,0x62,0xde,0x31,0xb0,0x7f,0x15,0xd7,0x48,
1545
0x63,0xae,0x29,0x29,0x34,0x25,0xdb,0x4c,0x49,0x89,0x29,0x59,0xc1,0x0a,0x9c,0xdf,
1546
0xcb,0x80,0xc5,0x20,0x11,0x24,0x81,0x64,0x90,0x02,0x52,0x41,0x1a,0x48,0x07,0x4b,
1547
0xc0,0x52,0x90,0x01,0x96,0x81,0xe5,0x20,0x13,0x64,0x81,0x15,0x60,0x25,0x58,0x05,
1548
0x56,0x83,0x35,0x60,0x2d,0x58,0x07,0xd6,0x83,0x0d,0x60,0x23,0xc0,0xad,0x6e,0x6f,
1549
0x0e,0xc8,0x05,0x79,0x20,0x1f,0x14,0x80,0x4d,0xa0,0x10,0x6c,0x06,0x45,0x60,0x0b,
1550
0xd8,0x0a,0x8a,0x41,0x29,0x9d,0x4b,0xca,0xa5,0x73,0x59,0x7b,0x40,0x39,0xa8,0x00,
1551
0x95,0x60,0x2f,0xd8,0x47,0x17,0x37,0x66,0xd0,0xb9,0x8a,0xa5,0x28,0xb3,0x02,0xac,
1552
0x04,0xab,0xc0,0x6a,0xb0,0x06,0xac,0x05,0xeb,0xc0,0x7a,0xb0,0x01,0x6c,0x04,0xd9,
1553
0x20,0x07,0xe4,0x81,0x7c,0x50,0x00,0x36,0x81,0x42,0xb0,0x19,0x14,0x81,0x2d,0x60,
1554
0x2b,0xd8,0x06,0x8a,0xc1,0x76,0xb0,0x03,0xec,0x04,0x25,0x60,0x17,0x60,0xed,0xda,
1555
0x0d,0xca,0x00,0x6c,0x4b,0x82,0x6d,0x49,0xb0,0x2d,0x09,0xb6,0x25,0xc1,0xb6,0xa4,
1556
0x7d,0x60,0x3f,0xa8,0x02,0xd5,0xa0,0x06,0xd4,0x82,0x06,0xd0,0x08,0x9a,0xa8,0x6d,
1557
0x05,0xb5,0xc1,0x62,0x78,0xbd,0x0d,0x1d,0x84,0xb3,0xce,0xc1,0x59,0xe7,0xe0,0x98,
1558
0x73,0xe8,0x7c,0x1b,0x9e,0x85,0x6b,0xa9,0xad,0x80,0xda,0x0a,0xa9,0x0d,0x9b,0x90,
1559
0xde,0x87,0x27,0x00,0x1e,0x95,0x10,0xde,0x9f,0x42,0x47,0x70,0xa4,0x9c,0xda,0xf6,
1560
0x50,0x5b,0x25,0xb5,0xed,0xa5,0xb6,0x6a,0x3a,0x82,0x27,0x08,0x8c,0x83,0x73,0x8f,
1561
0xac,0xa0,0x23,0x68,0xb8,0x7a,0x31,0x48,0x02,0x29,0x20,0x0d,0x2c,0x01,0x70,0x57,
1562
0xf5,0x72,0x90,0x05,0xd8,0x32,0x70,0x55,0x35,0xdc,0x54,0x0d,0xe5,0x6a,0xb8,0xa7,
1563
0x1a,0xae,0xa9,0x86,0x05,0xd5,0x70,0x4b,0x35,0x5c,0x52,0x0d,0x77,0x54,0xc3,0x15,
1564
0xd5,0x70,0x43,0x35,0x5c,0x50,0x0d,0x85,0x6a,0x58,0x50,0x8d,0x6e,0x57,0xa3,0xcb,
1565
0xd5,0xe8,0x6e,0x35,0xba,0x5a,0x8d,0x6e,0x56,0xa3,0x8b,0xd5,0x75,0x00,0x5d,0xac,
1566
0x6e,0xa2,0x73,0x35,0xd0,0xaf,0x81,0x7e,0x0d,0xf4,0x6b,0xa0,0x5f,0x03,0xfd,0x1a,
1567
0xe8,0xd7,0x40,0xbf,0x06,0xfa,0x35,0xd0,0xaf,0x81,0x7e,0x0d,0xf4,0x6b,0xa0,0x5f,
1568
0x03,0xfd,0x1a,0xe8,0xd7,0x40,0xbf,0x06,0xfa,0x35,0xd0,0xaf,0x81,0x7e,0x0d,0xf4,
1569
0x6b,0xa0,0x5f,0x03,0xfd,0x1a,0xe8,0xd7,0x40,0xbf,0x06,0xfa,0x35,0xd0,0xaf,0x81,
1570
0x7e,0x0d,0xf4,0x6b,0xa0,0x5f,0x03,0xfd,0x1a,0xe8,0xd7,0x40,0xbf,0x06,0xfa,0xb5,
1571
0xd0,0xaf,0x85,0x7e,0x2d,0xf4,0x6b,0xa1,0x5f,0x0b,0xfd,0x5a,0xe8,0xd7,0x42,0xbf,
1572
0x16,0xfa,0xb5,0xd0,0xaf,0x85,0x7e,0xed,0x5a,0x9a,0x70,0xa4,0x91,0x5a,0x20,0x89,
1573
0x8b,0xf3,0x5c,0x2d,0x24,0x6b,0x21,0x59,0x0b,0xc9,0x5a,0x48,0xd6,0x42,0xb2,0x16,
1574
0x92,0xb5,0x90,0xac,0x85,0x64,0x2d,0x24,0x6b,0x21,0x59,0x0b,0xc9,0x5a,0x48,0xd6,
1575
0x42,0xb2,0x16,0x92,0xb5,0x90,0xac,0x83,0x64,0x1d,0x24,0xeb,0x20,0x59,0x07,0xc9,
1576
0x3a,0x48,0xd6,0x41,0xb2,0x0e,0x92,0x75,0x90,0xac,0x83,0x64,0x1d,0x24,0xeb,0xd0,
1577
0xe5,0x3a,0x74,0xb9,0x0e,0x5d,0xae,0x43,0x97,0xeb,0xd0,0xe5,0x3a,0xe8,0xd7,0x41,
1578
0xbf,0x0e,0xfa,0x75,0xd0,0xaf,0x83,0x7e,0x1d,0xf4,0xeb,0xa0,0x5f,0x07,0xfd,0x3a,
1579
0xe8,0xd7,0x41,0xbf,0x0e,0xfa,0x75,0xd0,0xaf,0x83,0x7e,0x1d,0xf4,0xeb,0xa0,0x5f,
1580
0x07,0xfd,0x3a,0xe8,0xd7,0x33,0x00,0x36,0xd4,0x27,0x02,0xd8,0x51,0x9f,0x0c,0x60,
1581
0x4b,0x7d,0x2a,0x80,0x3d,0xf5,0xb8,0x4a,0xea,0x61,0x43,0x3d,0xae,0x92,0x7a,0xd8,
1582
0x51,0x8f,0xab,0xa4,0x1e,0xb6,0xd4,0xe3,0x0a,0xa8,0x87,0x76,0x3d,0xae,0x80,0x7a,
1583
0xe8,0xd7,0xe3,0x0a,0xa8,0x87,0x0d,0xf5,0xb8,0x02,0xea,0x61,0x47,0x3d,0x46,0x78,
1584
0x3d,0xb4,0xeb,0x31,0xc2,0xeb,0xa1,0x5f,0x8f,0x11,0x5e,0x0f,0x1b,0xea,0x31,0xc2,
1585
0xeb,0x61,0x47,0x03,0x74,0x1b,0xa0,0xdb,0x00,0xdd,0x06,0xe8,0x36,0x40,0xb7,0x01,
1586
0xba,0x0d,0xd0,0x6a,0x80,0x4e,0x03,0x34,0x1a,0xd0,0xdf,0x06,0xe8,0x34,0x40,0xa7,
1587
0x01,0x3a,0x0d,0xd0,0x69,0x80,0x4e,0x03,0x74,0x1a,0xa0,0xd3,0xc0,0xea,0x30,0x98,
1588
0xa7,0xa0,0x07,0x5c,0x9c,0xc8,0xc5,0x49,0x5c,0x9c,0xcc,0xc5,0x29,0x5c,0x9c,0xca,
1589
0xc5,0x69,0x5c,0xbc,0x89,0x8b,0x0b,0xb9,0x78,0x33,0x17,0x17,0x71,0xf1,0x16,0x2e,
1590
0xde,0xca,0xc5,0xdb,0xb8,0xb8,0x98,0x8d,0x1b,0xb8,0xf2,0x0d,0x5c,0xf9,0x06,0xae,
1591
0x7c,0x03,0x57,0xbe,0x81,0x2b,0xdf,0xc0,0x95,0x6f,0xe0,0xca,0x37,0x98,0xca,0xef,
1592
0x41,0x7c,0xac,0x9c,0x8d,0x76,0xb1,0xdb,0x8d,0xfb,0xb9,0x18,0xde,0x68,0x2c,0x67,
1593
0x8f,0x62,0x3a,0xb5,0x9a,0xdc,0xdf,0x4c,0x64,0xa7,0x55,0x6f,0xb2,0x7d,0xdf,0xcb,
1594
0x16,0xad,0x62,0xa3,0xdd,0x6c,0xc9,0x26,0xce,0x56,0xdc,0xbd,0x71,0x84,0x2d,0x8b,
1595
0x39,0x1a,0x1b,0xb3,0xf3,0xb8,0xd5,0x28,0x7f,0x0c,0xa7,0xa3,0x89,0x85,0x75,0xd3,
1596
0x7e,0xec,0x5c,0xc3,0x15,0x58,0xc3,0x15,0x58,0xc3,0x16,0x80,0x52,0x13,0x7c,0xd6,
1597
0xc4,0xfa,0x0c,0x77,0x8f,0xa6,0xad,0xdc,0x04,0x8e,0xa1,0xa7,0xb1,0x5d,0x8f,0xb6,
1598
0xdb,0x97,0xb0,0x51,0x26,0xa7,0xc5,0xd9,0xd6,0x50,0xcd,0x1e,0x61,0xab,0xd3,0x79,
1599
0x66,0x05,0x52,0x4c,0x34,0x99,0x0a,0xfc,0x98,0x13,0x53,0x6e,0x1f,0x7e,0xcc,0x09,
1600
0x9b,0x1b,0x39,0x12,0x05,0x53,0x88,0x5d,0xc2,0x8e,0xa4,0x91,0xfa,0x1b,0x45,0xd9,
1601
0xd2,0x81,0x14,0x4c,0x21,0x14,0x4a,0x3a,0x0a,0xa3,0x70,0xf2,0xa1,0xf3,0xe9,0xab,
1602
0x28,0x9a,0x54,0xa4,0xa6,0x79,0xf3,0x69,0x42,0xc0,0x24,0x30,0x9f,0x5e,0xdf,0x33,
1603
0x89,0x26,0x05,0xcc,0x01,0x2f,0x20,0x3f,0x85,0x66,0xcf,0xa1,0xf9,0xb3,0xe8,0xf9,
1604
0x67,0x66,0xd2,0xf3,0xb3,0xe8,0x7c,0x4a,0x26,0xbd,0xb5,0x82,0xde,0x5a,0x49,0x6f,
1605
0xad,0xa2,0xb7,0x56,0xd3,0x94,0x09,0x2f,0xa2,0x95,0x95,0xdc,0xca,0x49,0xc7,0xc5,
1606
0xe1,0x5c,0x1c,0x14,0xc8,0x25,0x5a,0xd2,0x70,0x31,0x9b,0x0f,0xe1,0xf2,0x21,0xdc,
1607
0xf2,0x2a,0x84,0x82,0xb9,0x98,0xdd,0x1f,0x4a,0x21,0x5c,0xcc,0xe6,0xc3,0xb8,0xa3,
1608
0x61,0xdc,0x9e,0x30,0xd2,0x71,0x31,0xbb,0x9f,0xa6,0x4d,0xc3,0x0f,0x58,0x40,0x0b,
1609
0xa6,0xe1,0x87,0x03,0x9b,0x2f,0xd2,0x8b,0xd3,0xf0,0x33,0x8d,0xce,0xa7,0x26,0x53,
1610
0x20,0x27,0x75,0x3e,0xbd,0x04,0x3f,0xe6,0xc4,0x94,0xdb,0x8d,0x1f,0x73,0xc2,0xe6,
1611
0x2e,0x30,0xe9,0x60,0x09,0xb1,0x36,0x62,0xe5,0xa7,0xa1,0x20,0x18,0x88,0xc5,0x1f,
1612
0xcc,0x81,0x15,0xe8,0x05,0x34,0xc3,0x49,0x13,0x48,0xaa,0x20,0x35,0xa9,0x34,0x40,
1613
0x0b,0x82,0x41,0x08,0x08,0x05,0x3a,0x10,0x06,0xc2,0x41,0x50,0x20,0x1b,0xb1,0x25,
1614
0x83,0xd8,0xa2,0x41,0x6c,0xd9,0x20,0xb6,0x70,0x10,0x5b,0x3a,0x88,0x2d,0x1e,0xc4,
1615
0x96,0x0f,0x62,0x2b,0x04,0xb1,0x35,0x34,0x6c,0x8d,0x09,0x60,0x22,0x98,0x04,0x26,
1616
0x83,0x67,0xc0,0x14,0x30,0x15,0x3c,0x0b,0xa6,0x81,0xe9,0x60,0x06,0x98,0x09,0x66,
1617
0x81,0xd9,0x60,0x0e,0x98,0x0b,0x9e,0x03,0xf3,0xc0,0x7c,0xf0,0x3c,0x78,0x01,0x2c,
1618
0x00,0x0b,0xc1,0x8b,0xe0,0x25,0xf0,0xb2,0xfa,0x86,0x1b,0x58,0x4f,0x44,0x44,0x44,
1619
0x53,0x34,0xfb,0x13,0x4d,0xe7,0x4b,0xf2,0x8e,0x56,0xd3,0xf9,0x3d,0x7b,0x40,0x39,
1620
0xc0,0x48,0xda,0x83,0xe1,0xb5,0x67,0x2f,0xc0,0x70,0xda,0xb3,0x1f,0x54,0x01,0xb6,
1621
0x4c,0x0d,0xa8,0x05,0x75,0xa0,0x1e,0x34,0x80,0x46,0xd0,0x84,0xd5,0x0e,0xa6,0x1b,
1622
0xe5,0x98,0x6e,0x94,0x63,0xba,0x51,0x8e,0xe9,0x46,0x39,0xa6,0x1b,0xe5,0x98,0x6e,
1623
0x94,0x63,0xba,0x51,0x8e,0xe9,0x46,0x39,0xa6,0x1b,0xe5,0x98,0x6e,0x94,0x63,0xba,
1624
0x51,0x8e,0xe9,0x46,0x39,0xa6,0x1b,0xe5,0x98,0x6e,0x94,0x63,0xba,0x51,0x8e,0xe9,
1625
0x46,0x39,0xa6,0x1b,0xe5,0x98,0x6e,0x94,0x63,0xba,0x51,0x8e,0xe9,0x46,0x39,0x86,
1626
0x7a,0x39,0xa6,0x1b,0xe5,0x98,0x6e,0x94,0x63,0xba,0x51,0x8e,0xe9,0x46,0x39,0xa6,
1627
0x1b,0xe5,0xec,0xca,0x0a,0xd3,0x8d,0x72,0x4c,0x37,0xca,0x31,0xdd,0x28,0xc7,0x74,
1628
0xa3,0x1c,0xd3,0x8d,0x72,0x3c,0x51,0x71,0x4f,0xdd,0xd7,0x40,0x6d,0xb0,0xaa,0x7c,
1629
0x3b,0xd8,0x09,0x76,0x01,0x76,0x55,0xb6,0x9f,0x0e,0xe3,0xd9,0x0c,0x1b,0x2b,0x60,
1630
0x63,0x05,0xec,0xab,0x80,0x6d,0x15,0xb0,0xab,0x02,0x36,0x55,0xc0,0x9e,0x0a,0xd8,
1631
0x52,0x01,0x3b,0x2a,0x60,0x43,0x05,0xf4,0x2b,0xa0,0x5d,0x01,0xdd,0x0a,0x68,0x56,
1632
0x40,0xaf,0x02,0x5a,0x15,0xd0,0xa9,0xc0,0x94,0xa6,0x02,0xd3,0x99,0x0a,0x4c,0x65,
1633
0x2a,0x30,0x95,0xa9,0xd8,0x01,0x30,0xb4,0x2a,0x4a,0x41,0x19,0x80,0x0f,0x2b,0xa0,
1634
0x58,0x01,0xdf,0x55,0xc0,0x6f,0x15,0xf0,0x59,0x05,0xfc,0x55,0x01,0xab,0x2a,0xe0,
1635
0xa7,0x4a,0xe8,0x57,0x42,0xbf,0x12,0xfa,0x95,0xd0,0xaf,0x84,0x7e,0x25,0xf4,0x2b,
1636
0xa1,0x5f,0x09,0xfd,0x4a,0xe8,0x57,0x42,0xbf,0x12,0xfa,0x95,0xd0,0xaf,0x84,0x7e,
1637
0x25,0xf4,0x2b,0xa1,0x5f,0x09,0xfd,0x4a,0xe8,0x57,0x42,0xbf,0x12,0x3d,0xab,0xc4,
1638
0x58,0xae,0x84,0xd6,0xbe,0x42,0xea,0x2e,0x5b,0x4e,0x7d,0x8d,0x05,0xf4,0x51,0x35,
1639
0x03,0xb6,0x83,0xfd,0xa0,0x89,0x3e,0xc2,0xf3,0xf7,0x23,0x3c,0x2b,0x3f,0xaa,0x5d,
1640
0x06,0x36,0x81,0x5a,0xea,0x4a,0x6e,0xa2,0xae,0x94,0xad,0xa0,0x84,0xba,0x52,0x13,
1641
0xc1,0x3a,0x80,0x7c,0xda,0x26,0xb0,0x8f,0xba,0xd2,0x19,0xea,0x5a,0x9a,0x43,0x5d,
1642
0x19,0x35,0xd4,0xb5,0x6c,0x2d,0xc8,0x06,0xd5,0xd4,0xb5,0x7c,0x31,0xc8,0x05,0x3b,
1643
0xa8,0x2b,0x13,0xf5,0x32,0xf7,0x53,0x57,0x56,0x3a,0x28,0xa2,0xae,0x9c,0xf5,0xd4,
1644
0x95,0x5b,0x40,0x5d,0x45,0x68,0x67,0x0b,0x8e,0x6d,0x59,0x0a,0x50,0x77,0x4b,0x31,
1645
0x75,0x6d,0xad,0xa4,0xae,0xd2,0x15,0xd4,0xb5,0x1b,0xed,0x96,0xa1,0x9d,0x3d,0x59,
1646
0x60,0x33,0x40,0xbe,0x7c,0x37,0x28,0xa7,0xae,0x2a,0xe8,0x55,0xc1,0xa6,0x2a,0x36,
1647
0xdf,0x48,0x5d,0x35,0x15,0x00,0xb6,0xe2,0x99,0xdf,0x55,0xb7,0x17,0x60,0x1f,0x66,
1648
0xd8,0x5d,0x78,0xc0,0x75,0x35,0xa0,0x2d,0x3c,0x70,0xba,0x1a,0xd0,0x6e,0x53,0x12,
1649
0x75,0xa7,0xa7,0x83,0xfd,0xd4,0xbd,0x24,0x83,0xba,0xd7,0x94,0x81,0xbd,0xd4,0xbd,
1650
0x2e,0x0d,0xac,0x07,0x5b,0x40,0x0d,0x75,0xaf,0xdf,0x04,0xb6,0x52,0x77,0xce,0x1e,
1651
0xea,0xce,0x45,0xf9,0xdc,0xed,0xd4,0xbd,0x0b,0xfb,0x4a,0x37,0x03,0x1c,0xdf,0x5d,
1652
0x09,0x1f,0xa2,0x7e,0xd9,0x1a,0x90,0x43,0xdd,0xb0,0xb1,0x7b,0x0f,0xf2,0xb8,0x0e,
1653
0x7a,0x16,0x97,0x50,0x4f,0xfa,0x4e,0xb0,0x1f,0xd4,0x81,0x26,0xea,0x59,0x92,0x06,
1654
0x36,0x82,0x1c,0xea,0x59,0xba,0x8b,0x7a,0x32,0x93,0xc1,0x12,0xea,0x59,0x9d,0x0b,
1655
0xb6,0x51,0xcf,0x9a,0x0d,0xa0,0x00,0x6c,0x07,0x7b,0xa8,0x67,0x5d,0x06,0x58,0x45,
1656
0x3d,0x1b,0xd1,0xc6,0xc6,0x06,0xea,0xc9,0xde,0x0d,0xd0,0x4e,0x0e,0xd2,0x02,0xb4,
1657
0x51,0xb0,0x19,0x54,0x52,0xcf,0x96,0x5a,0xea,0xd9,0x56,0x0d,0x1a,0xa9,0x67,0x07,
1658
0xb4,0x4b,0x50,0xaf,0xa4,0x86,0x7a,0x30,0x8a,0x7b,0x2a,0xb1,0x1f,0x0f,0xe7,0x1e,
1659
0x3c,0x80,0x7b,0x1a,0x97,0x82,0x06,0xea,0x65,0x16,0x83,0x65,0x60,0x15,0xa8,0xa4,
1660
0xde,0xc5,0x4d,0xd4,0x9b,0xb8,0x84,0x7a,0xd3,0x8a,0xc0,0x4e,0x80,0x7d,0x69,0xf5,
1661
0xd4,0x9b,0x8e,0x32,0xe9,0x39,0xa0,0x80,0x7a,0x97,0xec,0x06,0x15,0xa0,0x9a,0x7a,
1662
0x37,0x2e,0x07,0x25,0xd4,0x5b,0xc8,0x00,0x94,0x29,0x44,0xbd,0xad,0x8d,0xd4,0xbb,
1663
0x2d,0x83,0x7a,0x8b,0xd1,0xe6,0x76,0xec,0xc7,0xf5,0xdf,0x8b,0xeb,0xb8,0x17,0xd7,
1664
0x63,0x6f,0x39,0xea,0xe0,0x5a,0xe8,0xdd,0xb7,0x05,0xec,0xa1,0xde,0xfd,0x68,0x1f,
1665
0x93,0xa9,0xde,0xba,0xa5,0xd4,0xdb,0x88,0xf6,0xf1,0x18,0xed,0xc5,0xf2,0xa3,0x2f,
1666
0x71,0x25,0xf5,0xa5,0x2c,0xa1,0xbe,0xb4,0x54,0xb0,0x0c,0x60,0x7b,0x6d,0x15,0xf5,
1667
0xad,0x63,0xa8,0x6f,0x43,0x2e,0xf5,0x65,0xef,0x07,0x35,0xd4,0x97,0xb3,0x9d,0xfa,
1668
0xf2,0x70,0x2c,0x2f,0x1f,0x6c,0x06,0x3b,0xa8,0xaf,0x20,0x03,0x94,0x82,0x4a,0xea,
1669
0xdb,0xb4,0x98,0xfa,0x36,0xa3,0x4c,0x51,0x0e,0x28,0xa0,0xbe,0x6d,0xeb,0xc0,0x46,
1670
0xb0,0x8b,0xfa,0x76,0x62,0x7f,0xc9,0x06,0x80,0xfd,0xbb,0xb6,0x82,0x32,0x50,0x01,
1671
0xea,0xa9,0xaf,0x34,0x9b,0xfa,0x2a,0xb1,0x0f,0xf3,0xc8,0x3e,0x8c,0xa1,0x3e,0x4c,
1672
0xfe,0xfa,0x30,0xa9,0xeb,0xc3,0x44,0xae,0x0f,0x13,0xb7,0x3e,0x4c,0xda,0xfa,0x30,
1673
0xd1,0xea,0xc3,0x24,0xab,0xaf,0x3e,0x13,0xac,0x06,0x9b,0x00,0xca,0x34,0x2c,0x05,
1674
0xab,0x70,0x3d,0xb1,0xd7,0x14,0x6c,0x6d,0xdc,0x44,0xfe,0x78,0x4e,0xac,0xc2,0xc8,
1675
0x4f,0x06,0x29,0xe4,0x7e,0x21,0x71,0x23,0x1b,0x65,0xd3,0x85,0xc4,0xf4,0x0b,0x89,
1676
0x4b,0x91,0x54,0x5e,0x48,0x4a,0xa7,0x73,0xc9,0x98,0x32,0x25,0x63,0xca,0x94,0x8a,
1677
0x99,0x7d,0x32,0xa6,0x0e,0xa9,0x58,0x54,0xa4,0x62,0x9a,0x97,0x8c,0xe9,0x53,0x32,
1678
0xa6,0x4f,0xc9,0x98,0x3e,0xa5,0xe2,0xf1,0x9f,0x8a,0x89,0x46,0x2a,0x26,0x10,0xa9,
1679
0x98,0x76,0xa5,0x62,0xda,0x95,0x8a,0x69,0x57,0x32,0x16,0x31,0xc9,0x98,0xd2,0x25,
1680
0x63,0x4a,0x97,0xcc,0xb6,0x85,0xe9,0x41,0x32,0xa6,0x9a,0xc9,0x58,0x08,0x25,0x63,
1681
0xba,0x99,0xbc,0x0c,0x60,0xca,0x99,0x9c,0x09,0x30,0xed,0x4c,0xc6,0x1c,0x23,0x19,
1682
0x73,0x8c,0x64,0x4c,0xfb,0x52,0x50,0x36,0x05,0xd3,0xaf,0x14,0x4c,0xbf,0x52,0x30,
1683
0xfd,0xc2,0xd5,0x7d,0x2e,0x05,0xd3,0xaf,0x14,0x4c,0xbf,0x52,0xb0,0xd0,0x49,0xc1,
1684
0x94,0x33,0x05,0x36,0xe1,0x8a,0x3f,0x97,0x02,0x9b,0x52,0x60,0x53,0x0a,0x16,0x3a,
1685
0x29,0x98,0x7e,0xa6,0xc0,0x9e,0x14,0xd8,0x93,0x02,0x7b,0x52,0x60,0x4f,0x0a,0xec,
1686
0x49,0x61,0xed,0xc1,0x34,0x32,0x19,0x53,0xbc,0x34,0xd8,0x93,0x06,0x7b,0x70,0x16,
1687
0xcf,0xa5,0x41,0x3b,0x0d,0x53,0xbf,0x34,0x4c,0xfb,0xd2,0x30,0xcd,0x4d,0xc6,0x1a,
1688
0x27,0x0d,0xd3,0xdc,0x34,0x4c,0x73,0x93,0x91,0x26,0x63,0xf1,0x95,0x8c,0xa9,0x4d,
1689
0x32,0x6c,0x49,0x86,0x2d,0xc9,0xd0,0x4f,0x86,0x76,0x32,0x74,0x93,0xa1,0x9b,0xcc,
1690
0xfa,0x02,0xba,0xc9,0xd0,0x4d,0x86,0x5e,0x32,0xa6,0x9a,0x29,0xf0,0x59,0x0a,0x34,
1691
0x52,0xd8,0xf6,0x61,0x47,0x1a,0x6b,0x07,0xda,0x4f,0xc1,0xe2,0x2e,0x05,0x1a,0x78,
1692
0x9e,0x9f,0x4b,0x65,0xfd,0x06,0x1b,0x52,0xd1,0xdf,0x54,0xf4,0x37,0x15,0xb6,0xa5,
1693
0x42,0x2b,0xb5,0x10,0x77,0xb9,0x25,0xb8,0xfb,0xe4,0x20,0x5d,0x0a,0x4a,0x01,0xae,
1694
0x98,0x35,0x15,0x48,0x71,0xe7,0xc3,0x6a,0xa9,0x6b,0x0b,0xee,0x56,0xb9,0x7b,0x48,
1695
0x85,0x93,0xa3,0x66,0xe3,0x44,0x2e,0x4e,0xe2,0xe2,0x14,0x2e,0x4e,0xe5,0xe2,0x34,
1696
0x2e,0x5e,0xc2,0xc5,0x19,0x5c,0xbc,0x8c,0x8b,0x33,0xb9,0x38,0x8b,0x8b,0x57,0x70,
1697
0xf1,0x4a,0x2e,0x5e,0x85,0xf8,0xe2,0x1e,0xb6,0xcd,0x4b,0x89,0x1b,0xd8,0x38,0x63,
1698
0x0b,0x1b,0xe7,0xd5,0xb3,0x71,0x71,0x3a,0x1b,0xef,0x59,0x83,0xf8,0xe3,0xc4,0x5d,
1699
0x6c,0xbc,0x36,0x99,0x8d,0xf3,0xd9,0x16,0x3e,0xde,0xb3,0x9d,0x8d,0x6b,0xf6,0x22,
1700
0xfe,0x24,0x89,0x6d,0xe1,0x93,0x65,0xac,0xd6,0x27,0x6b,0xd9,0x76,0x3e,0x2e,0x62,
1701
0x5b,0xf8,0x78,0xc3,0x96,0x8f,0x37,0x25,0x9b,0x32,0x9f,0xe4,0xb0,0x19,0xdc,0xda,
1702
0xd9,0xb8,0x76,0x19,0x97,0x67,0xed,0x44,0xb7,0xb9,0x3d,0xac,0x4a,0x57,0x4a,0x29,
1703
0xb7,0x3f,0x89,0xcb,0x97,0xb0,0xf9,0x9a,0x3c,0x36,0xbf,0x7c,0x31,0x62,0xdc,0xf2,
1704
0x10,0xe3,0x46,0xc6,0xe6,0xf7,0xec,0xe5,0xf6,0xb0,0x36,0xe0,0xb2,0x64,0xcb,0xe4,
1705
0x16,0xb0,0x7b,0xd6,0x6f,0x65,0xe3,0x4d,0x3b,0xb9,0xa3,0x6c,0xfb,0x3d,0x5b,0x1a,
1706
0xd9,0xa3,0x2b,0x96,0xb3,0xf9,0x25,0x35,0x88,0x7b,0x2b,0x0a,0xd9,0xfc,0x56,0xae,
1707
0xe5,0xa5,0x6c,0x3b,0x1f,0xd5,0x15,0xb1,0xf9,0x95,0xac,0xcd,0x5d,0xa5,0xdb,0xd8,
1708
0xa3,0x39,0xec,0x9e,0x8f,0xea,0x59,0xdd,0xde,0xca,0x34,0xce,0x86,0x35,0x5c,0x2d,
1709
0xce,0xc2,0x7a,0x56,0x11,0xb7,0x26,0x2e,0xae,0x54,0x53,0xd7,0x5a,0x3c,0x0d,0x6a,
1710
0xea,0xa9,0x67,0x77,0x16,0xcd,0x7d,0xfe,0x19,0xd2,0x04,0x91,0x46,0x43,0x1a,0xcc,
1711
0x17,0x83,0x49,0x83,0x99,0x62,0x28,0x69,0x74,0xa4,0x09,0x23,0x4d,0x38,0x69,0x03,
1712
0x49,0x1b,0x44,0x5a,0x0d,0x69,0xb5,0xa4,0x0d,0x26,0x6d,0x08,0xc1,0xff,0x04,0xef,
1713
0x13,0x7c,0x4f,0xf0,0x3c,0xc1,0xef,0x04,0xaf,0x13,0x7c,0x4e,0xf0,0x38,0xc1,0xdf,
1714
0x04,0x6f,0x13,0x7c,0x4d,0xf0,0x34,0xc1,0xcf,0x04,0x2f,0x63,0x5f,0xf5,0xc5,0xca,
1715
0x4d,0x04,0x57,0x7f,0x9c,0x87,0xad,0xec,0x3d,0x78,0x30,0xae,0xc1,0x03,0x91,0x1d,
1716
0x3e,0x49,0x78,0x68,0xe6,0x11,0xfc,0x80,0x87,0x04,0x6e,0xe8,0x5b,0xf0,0xe0,0x59,
1717
0xb1,0x1c,0x37,0xfa,0x1a,0xdc,0xf8,0x0a,0x09,0x7d,0xc7,0xc3,0x11,0x37,0xe6,0x62,
1718
0xf6,0x06,0x8f,0x1b,0xda,0x62,0x0c,0xaf,0xe4,0x9d,0xb8,0x2d,0xe0,0xc1,0x52,0x89,
1719
0x1b,0xd2,0x26,0x3c,0x6c,0xb1,0x1a,0xeb,0x4a,0xdd,0x88,0x07,0x0b,0x1e,0x8c,0x55,
1720
0xdb,0xf0,0x80,0xc4,0x83,0x6a,0x59,0x1d,0x1e,0x80,0x78,0x48,0x96,0xe2,0xe1,0x90,
1721
0x53,0x84,0x32,0xb8,0x71,0x63,0x02,0x00,0xdf,0x60,0x88,0xe6,0x92,0x36,0x94,0xb4,
1722
0x3a,0xd2,0x62,0xda,0x1b,0x4e,0xc1,0x98,0x9d,0x07,0x51,0xb0,0x86,0x82,0xb5,0x14,
1723
0x1c,0x4c,0xc1,0x98,0x23,0x87,0x52,0xb0,0x8e,0x82,0xc3,0x28,0x38,0x9c,0x42,0x30,
1724
0x59,0x65,0x1f,0x61,0x1a,0x36,0xd2,0xb2,0x51,0x30,0x1b,0x85,0xb0,0x51,0x28,0x1b,
1725
0xe9,0xd8,0x28,0x8c,0x8d,0xc2,0xd9,0x28,0x28,0x90,0x8b,0xb9,0x3a,0x41,0x5c,0xa5,
1726
0x67,0xa7,0xd2,0x33,0xf3,0xc0,0x02,0x9a,0xf9,0xfc,0x64,0xdc,0xbb,0x36,0x83,0x2d,
1727
0x60,0x1b,0xd8,0x0e,0x76,0x82,0x12,0x50,0x0a,0xca,0x40,0x39,0x7b,0x7f,0x03,0xfb,
1728
0x40,0x15,0xa8,0x01,0x75,0xa0,0x01,0x34,0xd1,0x85,0xa4,0xc5,0x20,0x19,0xa4,0x12,
1729
0x7b,0x13,0xbc,0x90,0x84,0xfb,0x61,0x52,0x06,0x58,0x06,0x96,0x83,0x4c,0x90,0x05,
1730
0x56,0x81,0xb5,0x60,0x03,0xc8,0x01,0xf9,0xa0,0x00,0x6c,0x02,0x85,0x00,0x76,0x24,
1731
0xc1,0x8e,0x24,0xd8,0x91,0x04,0x3b,0x92,0x76,0x00,0xd8,0x92,0x04,0x5b,0x92,0x76,
1732
0x01,0xd8,0x93,0x04,0x7b,0x92,0xf6,0x00,0xd8,0x94,0x84,0x8b,0xbc,0x6e,0x4b,0xd7,
1733
0xaa,0x65,0x6c,0x17,0x2e,0x24,0xad,0xbc,0x90,0x54,0xcf,0xe9,0xb3,0x1b,0x25,0x50,
1734
0xba,0x90,0x58,0x68,0xda,0xc0,0xbd,0x39,0xdb,0xd4,0xcb,0xcd,0x5c,0x19,0xb6,0x6f,
1735
0x5b,0x60,0x22,0x7b,0x24,0x71,0x8f,0x69,0xa3,0x92,0xeb,0x46,0xe2,0xb6,0x0b,0x89,
1736
0x3b,0xb0,0xc1,0x3a,0x02,0xfd,0x44,0xf7,0xb9,0x0a,0x4b,0xb8,0x6d,0xe4,0x12,0xd1,
1737
0x6e,0x3d,0xeb,0x21,0xae,0x6a,0x8d,0x29,0x57,0xcf,0xf5,0x00,0x87,0xd8,0x76,0x38,
1738
0xdf,0xc1,0xf4,0x0b,0x49,0x49,0x26,0x63,0xb0,0x51,0x8a,0xdd,0xa6,0x7a,0xbb,0xb8,
1739
0x8d,0x4a,0x53,0xae,0x92,0xf3,0x40,0xe2,0x6e,0x6c,0x70,0x09,0x6b,0x10,0x5b,0x08,
1740
0x25,0xb6,0x5e,0xaf,0xb1,0x9b,0xeb,0x0b,0x73,0xfd,0x48,0xa9,0x39,0x81,0xe1,0x9c,
1741
0xca,0xa6,0x81,0xed,0xa4,0x42,0x53,0xff,0x4d,0xdd,0x33,0xed,0x2a,0xbb,0x6e,0xc5,
1742
0x8d,0xc2,0xe6,0x1c,0x57,0x92,0x35,0xa4,0x8c,0x15,0x48,0xac,0xe7,0x8c,0x2f,0x35,
1743
0x6d,0x97,0x72,0x2d,0x2d,0x67,0xcf,0x3c,0xd7,0xe9,0x1a,0xd3,0xf3,0xad,0x84,0x3b,
1744
0xb3,0x6c,0x0e,0x47,0xf3,0xd8,0xf1,0xc0,0x56,0xe2,0x1a,0xe0,0x36,0x38,0x1f,0x5e,
1745
0x77,0x47,0x15,0xd7,0x05,0xb3,0x83,0xeb,0xae,0x3b,0xd8,0x94,0x63,0x47,0x09,0x33,
1746
0xd0,0x76,0x52,0x1a,0x37,0xac,0x92,0x96,0x98,0xce,0xb4,0xc9,0xae,0xa4,0xa5,0xa6,
1747
0x71,0x93,0x39,0xd0,0x85,0xa4,0x2c,0xce,0x44,0x76,0x9c,0x71,0x67,0xfa,0xa6,0x96,
1748
0x4c,0x67,0x9e,0x3d,0xb2,0x82,0xcb,0xed,0x32,0x35,0xb4,0x86,0x3d,0xdf,0x38,0x89,
1749
0x66,0x9f,0xb0,0xdb,0x65,0xd7,0x73,0xac,0xc4,0x6a,0xd3,0x16,0x3b,0x50,0x06,0xce,
1750
0xd8,0x12,0xd3,0x76,0xd1,0xc0,0x58,0x4a,0x5a,0xc7,0xee,0x46,0x67,0x12,0x8b,0x07,
1751
0x0a,0x27,0x99,0x06,0x48,0xd2,0x06,0xb6,0xb9,0xc4,0xa6,0x81,0x11,0xc5,0x0e,0xb1,
1752
0x06,0x2e,0x61,0xcf,0xe3,0x2a,0xae,0x00,0xeb,0xb2,0x64,0xd3,0x3e,0xd3,0x70,0x61,
1753
0x73,0x30,0xbd,0x1a,0xb9,0x8d,0x5c,0x8e,0xbd,0x7c,0xf2,0x06,0x06,0x20,0xab,0x97,
1754
0xcb,0x55,0x62,0x73,0x39,0x26,0x99,0x3c,0xee,0xd0,0x12,0xd3,0x0e,0xb3,0x94,0x29,
1755
0xc7,0x1e,0xcd,0x1f,0x38,0x05,0xa5,0x03,0x1b,0x5c,0x81,0x7c,0xae,0x33,0x59,0xa6,
1756
0x5c,0x09,0x77,0x15,0xb3,0xb9,0x4a,0xee,0xb4,0x14,0x9b,0xaa,0x16,0x0c,0x9c,0x6b,
1757
0xd3,0x06,0x77,0xa5,0x15,0x70,0x27,0x6d,0xc5,0x75,0xa1,0x42,0x6e,0x6c,0x72,0xc9,
1758
0xf5,0x13,0x73,0xf3,0x38,0x4b,0xda,0x32,0x70,0x7d,0x98,0x73,0xec,0xbe,0x6d,0xa6,
1759
0x8b,0x8e,0xb8,0xb6,0x92,0xae,0x17,0xdd,0x69,0xba,0xa0,0x4b,0x58,0xf7,0xb3,0xa3,
1760
0x99,0xcd,0xd5,0x73,0x0e,0xe6,0xae,0x6f,0xd3,0x6d,0xc0,0x74,0x59,0x60,0x4e,0x55,
1761
0x61,0x6a,0x61,0x60,0x04,0x07,0xf6,0xc0,0x7d,0x41,0x6c,0xa4,0x61,0x23,0x2d,0x1b,
1762
0x05,0xb3,0x51,0x08,0x1b,0x85,0xb2,0x91,0x8e,0x8d,0xc2,0xd8,0x28,0x9c,0x2b,0x6c,
1763
0xaa,0xc2,0xd5,0x09,0xe2,0x2a,0x05,0x71,0xb5,0x82,0xb8,0x6a,0x41,0x5c,0xbd,0x20,
1764
0xae,0x62,0x10,0x57,0x33,0x88,0xab,0x1a,0xc4,0xd5,0xd5,0x70,0x75,0x35,0x26,0x3d,
1765
0xae,0xae,0x86,0xab,0xab,0xe1,0xea,0x3e,0x3b,0x77,0x02,0x4d,0x9e,0x40,0x13,0x5e,
1766
0xa0,0x89,0x13,0xe6,0xd1,0x9c,0x05,0x34,0x77,0x12,0x4d,0x9e,0x85,0x1f,0x0d,0xd0,
1767
0xd2,0xb4,0x17,0xf0,0x3c,0xab,0xec,0x4e,0x5f,0x41,0xdd,0x1b,0x4a,0xd9,0xbb,0x13,
1768
0xd6,0x40,0xec,0x93,0xa0,0x7b,0x43,0x66,0x37,0x56,0x82,0x78,0xb0,0x74,0xd5,0x67,
1769
0x7d,0x54,0x9f,0xcd,0x3e,0x59,0xd0,0xd2,0xec,0x09,0x74,0xac,0x7e,0x02,0xcd,0x9a,
1770
0x40,0x33,0xf0,0x33,0x91,0x66,0x4d,0xa4,0xa9,0x13,0x69,0xd2,0x84,0x99,0x34,0x83,
1771
0x8d,0xe6,0x4e,0xa1,0xd9,0x53,0x50,0x82,0x65,0x2a,0xcd,0x9a,0x4a,0x33,0xa6,0xd2,
1772
0xb3,0x2f,0xd3,0x0c,0x30,0x0b,0x4c,0x05,0xcf,0x83,0x63,0xf5,0x33,0x69,0xd6,0x4c,
1773
0x9a,0x8c,0x5a,0x33,0x69,0xca,0x2c,0x9a,0x3d,0x0b,0xbb,0x66,0xd1,0xac,0x59,0x34,
1774
0x69,0x16,0xcd,0x60,0x33,0x1a,0xe4,0x34,0x84,0x9f,0x19,0x6c,0x02,0x3b,0x27,0x01,
1775
0xfc,0xcc,0x60,0x93,0xf3,0xe9,0x6b,0xe7,0x9b,0x62,0x1c,0x87,0x51,0xb3,0xc0,0x54,
1776
0x30,0x6f,0xc2,0x64,0x16,0xee,0xb0,0x39,0xd5,0xd0,0xdc,0xf9,0x34,0x7b,0x3e,0x9a,
1777
0x47,0x8d,0xf9,0x34,0x77,0x01,0xcd,0x5e,0x80,0x8d,0x05,0x34,0x6b,0x01,0xcd,0x80,
1778
0x2f,0x16,0xd2,0xec,0x85,0xd8,0x5e,0x48,0xb3,0x16,0xd2,0x0c,0xfc,0xb4,0x2f,0xa1,
1779
0x59,0x60,0xe2,0x73,0x34,0x69,0x12,0x4d,0x9a,0x4c,0x93,0xd0,0x08,0xfa,0x30,0x19,
1780
0xdd,0x7c,0x89,0x9e,0x9d,0x00,0x6f,0xd2,0xb4,0xd9,0x34,0x63,0x06,0xcd,0x78,0x9e,
1781
0x66,0xce,0xa2,0x99,0xb3,0x69,0xe6,0x9c,0xa9,0x34,0xf3,0x45,0x9a,0x35,0x0d,0x5d,
1782
0x9a,0x03,0x0f,0x3c,0x4b,0x73,0xe7,0xce,0xa2,0xb9,0xf3,0x68,0x3e,0x7e,0x16,0xd0,
1783
0xc2,0x89,0xb4,0x00,0x6d,0xcc,0xa2,0x09,0x5c,0x1c,0xc4,0x2e,0xeb,0x34,0x6c,0xa4,
1784
0x65,0xa3,0x60,0x36,0x0a,0x61,0xa3,0x50,0x36,0xd2,0xb1,0x51,0x18,0x1b,0x85,0xb3,
1785
0x11,0x9e,0x85,0x6c,0xcc,0xd5,0x09,0xe2,0x2a,0x05,0x71,0xb5,0x82,0xb8,0x6a,0x41,
1786
0x5c,0xbd,0x20,0xae,0x62,0x10,0x57,0x33,0x88,0xab,0x1a,0xc4,0xd5,0xd5,0x70,0x75,
1787
0x35,0x26,0x3d,0xae,0xae,0x86,0xab,0xab,0xe1,0xea,0x6a,0xb8,0xba,0x1a,0xae,0xae,
1788
0x86,0xab,0xab,0xe1,0xea,0x6a,0xb8,0xba,0x5a,0xae,0xae,0x96,0xab,0x3b,0x15,0x67,
1789
0xf5,0xe2,0xc6,0xc5,0x20,0x09,0xa4,0x80,0x34,0xb0,0x04,0x2c,0x07,0x59,0x60,0x25,
1790
0x58,0x0d,0xd6,0x82,0xf5,0x60,0x23,0xc8,0x01,0x79,0xa0,0x00,0x14,0x82,0x22,0xb0,
1791
0x15,0x14,0x83,0x1d,0xa0,0x04,0x94,0xd2,0xc5,0x6c,0xb4,0x9b,0x8d,0x76,0xb3,0xd1,
1792
0x6e,0x36,0xda,0xcd,0x46,0xbb,0xd9,0x19,0x00,0x6d,0x67,0xa3,0xed,0x6c,0xb4,0x9d,
1793
0x8d,0xb6,0xb3,0xd1,0x76,0x36,0xda,0xce,0x46,0xdb,0xd9,0x68,0x3b,0x17,0xed,0xe5,
1794
0xa2,0xbd,0x5c,0xb4,0x97,0x8b,0xf6,0x72,0xd1,0x5e,0x2e,0xda,0xcb,0x2d,0x03,0x95,
1795
0x60,0x1f,0xa8,0x02,0x35,0xa0,0x0e,0x34,0x80,0x26,0xba,0x98,0x07,0xbd,0x3c,0xe8,
1796
0xe5,0x41,0x2f,0x0f,0x7a,0x79,0xd0,0xcb,0x83,0x5e,0x1e,0xf4,0xf2,0xa0,0x87,0xa5,
1797
0xdd,0xc5,0x3c,0xe8,0xe5,0x41,0x2f,0x0f,0x7a,0x79,0xd0,0xcb,0x83,0x5e,0x1e,0xfa,
1798
0x92,0x87,0xbe,0xe4,0xa1,0x2f,0x79,0xd0,0xce,0x83,0x76,0x1e,0xb4,0xb1,0xfc,0xbb,
1799
0x98,0x07,0xed,0x3c,0x68,0xe7,0x41,0x3b,0xaf,0x16,0xd4,0xd3,0xb9,0x7d,0xd0,0xcd,
1800
0x83,0x5e,0x3e,0xf4,0xf2,0xa1,0x97,0x0f,0xbd,0x7c,0xe8,0xe5,0x2f,0x03,0xd0,0xc8,
1801
0x87,0x46,0x3e,0xda,0xcf,0x47,0xfb,0xf9,0x68,0x3f,0x1f,0xed,0xe7,0xa3,0xfd,0x7c,
1802
0xb4,0x9f,0x8f,0xf6,0xf3,0xd1,0x7e,0x3e,0xda,0xcf,0xdf,0x41,0x6d,0xbb,0xe8,0x48,
1803
0x3e,0x1d,0x41,0xe5,0x52,0xb6,0x12,0x3a,0x96,0x8f,0x8e,0xe5,0x43,0x20,0x1f,0x1d,
1804
0xcb,0x47,0xc7,0xf2,0x21,0x54,0x00,0xa1,0x02,0x56,0x08,0x2b,0x8d,0xfd,0x99,0xc8,
1805
0xa7,0x83,0xa5,0xd4,0xb6,0x05,0x09,0xfa,0x56,0x80,0xbe,0x15,0x40,0xb7,0x00,0x4d,
1806
0x14,0xa0,0x6f,0x05,0xd0,0x2e,0x80,0x36,0x96,0xf2,0x87,0x20,0x5f,0xb0,0x9f,0x2e,
1807
0xee,0x42,0xab,0xa5,0xab,0xe8,0x08,0x96,0x6c,0x99,0x58,0x12,0x65,0x62,0x89,0x96,
1808
0x89,0x65,0x51,0x26,0x96,0x45,0x99,0x58,0xa2,0x65,0x62,0x89,0x96,0x89,0x25,0x5a,
1809
0x26,0x96,0x48,0x99,0x58,0xa2,0x65,0x62,0x99,0x94,0x89,0x25,0x5a,0x26,0x96,0x4a,
1810
0x99,0x58,0x2a,0x65,0x62,0xa9,0x94,0x89,0xa5,0x52,0x26,0x96,0x4a,0x99,0x58,0xa2,
1811
0x65,0x62,0x69,0x94,0x89,0xa5,0x51,0x26,0x96,0x68,0x99,0x58,0xa2,0x65,0x62,0x89,
1812
0x96,0x89,0xe5,0x53,0x66,0x15,0xa8,0x06,0x35,0xa0,0x16,0xd4,0x01,0x78,0x2c,0xb3,
1813
0x01,0x34,0x82,0x26,0x3a,0x97,0x85,0x25,0x56,0x16,0x96,0xa5,0x59,0x58,0x92,0x66,
1814
0x61,0x29,0x9a,0x85,0x25,0x55,0x16,0x96,0x54,0x59,0x58,0x6e,0x66,0x61,0xe9,0x95,
1815
0x85,0xa5,0x55,0x16,0x96,0x9a,0x59,0x58,0x6a,0x66,0x61,0xa9,0x99,0x85,0xa5,0x58,
1816
0x16,0xec,0xce,0xc2,0x72,0x2f,0x0b,0x4b,0xcd,0x2c,0x2c,0x35,0xb3,0xb0,0xf4,0xca,
1817
0xc2,0xd2,0x2b,0x0b,0xcb,0xbf,0x2c,0x38,0x25,0x0b,0x4b,0xc3,0xac,0x75,0x00,0x4b,
1818
0xb5,0x2c,0x2c,0xd5,0xb2,0xb0,0x54,0xcb,0xc2,0x12,0x36,0x2b,0x07,0xb0,0xdf,0xed,
1819
0x61,0x39,0x98,0x85,0x25,0x5a,0x16,0x96,0x86,0x59,0xe8,0x7f,0x16,0xfa,0x9f,0x85,
1820
0xfe,0x67,0xa1,0xff,0x59,0xe8,0x7f,0x16,0xfa,0x9f,0x85,0xfe,0x67,0xa1,0xff,0x59,
1821
0xe8,0x7f,0x16,0xfa,0x9f,0x85,0xfe,0x67,0xa1,0xff,0x59,0xe8,0x7f,0x16,0xfa,0x9f,
1822
0x85,0xfe,0x67,0x95,0x51,0x6f,0x79,0x3a,0x75,0xe7,0xec,0xc5,0x7c,0x19,0x29,0x16,
1823
0xee,0x1f,0x55,0x57,0x60,0x4e,0xbd,0x95,0xba,0xb6,0x62,0x9e,0xbd,0x0e,0x73,0xe8,
1824
0xad,0xd8,0x9f,0xc6,0xbe,0x58,0xd9,0x41,0x3d,0x8d,0x29,0xd4,0xbb,0xa1,0x89,0x7a,
1825
0xf3,0x6b,0xa9,0xb7,0xa8,0x9a,0xfa,0x12,0xb3,0xa8,0x7b,0x7b,0x22,0x75,0xef,0xcd,
1826
0xa1,0x9e,0xa4,0x8d,0xd4,0x03,0x9b,0x7a,0x57,0x60,0xd1,0x8f,0xe5,0x70,0x5f,0x71,
1827
0x39,0xe6,0xfd,0x89,0x98,0x83,0xef,0xa3,0xee,0x5d,0xc9,0xd4,0xc3,0xbe,0x20,0xd9,
1828
0x50,0x4a,0x7d,0xd5,0xf9,0xd4,0xb5,0x0f,0xf7,0xef,0xa6,0x12,0xea,0x5d,0xbf,0x9c,
1829
0x7a,0xb7,0x6e,0xa1,0xee,0x0c,0xf6,0xa5,0xca,0x06,0xea,0xdd,0x54,0x40,0x5d,0x75,
1830
0x4b,0xb1,0x36,0x58,0x4f,0xdd,0xfb,0x76,0x52,0x4f,0x46,0x3d,0xf5,0x61,0xa6,0xf2,
1831
0x51,0x63,0x2a,0xe6,0xfc,0x55,0xd4,0x95,0x91,0x4f,0xdd,0xab,0x93,0xa9,0xbb,0x64,
1832
0x35,0xda,0x5b,0x81,0xb9,0x7e,0x31,0xda,0x4c,0xa5,0xde,0x8d,0xb9,0xd4,0x5b,0x55,
1833
0x46,0x7d,0xb9,0x15,0xd4,0x57,0x8a,0xb4,0xaa,0x96,0x7a,0x36,0x2f,0xc3,0x7a,0xa2,
1834
0x89,0x7a,0xf6,0x6f,0xa2,0x5e,0xf8,0xbf,0x6f,0x59,0x32,0xf5,0x96,0xac,0xa3,0xae,
1835
0x22,0x68,0xd4,0xc3,0x9e,0x72,0xec,0x5f,0xdc,0x88,0xb5,0xc7,0x66,0xea,0x29,0x5a,
1836
0x8a,0xfe,0x27,0x52,0x5f,0x0e,0x34,0x8a,0x36,0x50,0x57,0xf9,0x66,0xf4,0x6b,0x35,
1837
0x75,0x57,0x65,0x53,0x77,0x7d,0x16,0xf5,0xec,0x2d,0xa3,0x9e,0x6a,0xac,0x47,0x36,
1838
0x66,0xc0,0x86,0x55,0xd4,0x9b,0x88,0x34,0x2d,0x17,0x40,0x63,0x7b,0x2e,0x34,0x1a,
1839
0xa1,0x51,0x8e,0xe3,0xfb,0xa8,0x77,0x37,0x83,0xfe,0x64,0x41,0xab,0x11,0xbe,0xac,
1840
0xa1,0xae,0xb2,0x62,0xea,0x66,0x56,0x51,0x4f,0x66,0x1a,0xf5,0xac,0xdd,0x83,0xb5,
1841
0xca,0x7a,0xe8,0xd5,0xa1,0x4f,0x4d,0xd4,0xd5,0xb8,0x03,0x65,0x96,0x63,0x6d,0xb3,
1842
0x8c,0xba,0xd7,0x56,0x43,0x67,0x33,0x7c,0x9f,0x44,0x5d,0x85,0xf9,0xd4,0x93,0x8b,
1843
0x35,0xcc,0x4a,0xf8,0x65,0x27,0xd6,0x4a,0xbb,0x6b,0xa9,0xbb,0x02,0xe7,0x21,0x03,
1844
0x3a,0x19,0x5b,0xa9,0x1b,0x63,0xbe,0x67,0xed,0x56,0xf8,0x77,0x37,0xd6,0x55,0x58,
1845
0x23,0xa5,0x2d,0xa1,0xee,0xcd,0x8b,0xa9,0xa7,0x12,0xfe,0x58,0x82,0x73,0x5a,0xb2,
1846
0x8a,0xfa,0xd2,0xb0,0xf4,0xcb,0xd8,0x47,0x5d,0x2b,0x71,0x0e,0xea,0x76,0x51,0xf7,
1847
0xfa,0x14,0xf8,0x1c,0xfd,0xdd,0x82,0x73,0xb3,0x0e,0xe7,0x61,0x07,0xd2,0xda,0xf5,
1848
0xd4,0x57,0x97,0x89,0xf3,0x9f,0x8a,0xf5,0x54,0x15,0xf5,0x36,0x40,0x1f,0xab,0xb9,
1849
0xee,0x54,0x9c,0x9f,0x74,0xf4,0x63,0x15,0xdb,0xff,0x22,0xea,0x49,0xc1,0x5a,0x6d,
1850
0x15,0x28,0x5e,0x4a,0x3d,0x55,0x18,0x2b,0x8b,0xa1,0x51,0xbf,0x8d,0x7a,0x57,0xef,
1851
0xa6,0x3e,0xa6,0x88,0xfa,0x96,0x2f,0xa5,0xae,0x74,0xac,0xbf,0x96,0x62,0x4d,0xb6,
1852
0xaa,0x01,0x63,0x21,0x1d,0xe3,0x83,0xd5,0x5d,0x42,0x5d,0x4d,0x38,0xff,0xcb,0xf1,
1853
0x68,0xde,0xbd,0x9b,0x7a,0xf6,0x40,0x1f,0xe3,0x01,0x2b,0x0b,0xea,0xca,0x81,0x6f,
1854
0xf6,0xa3,0x5f,0x0c,0xfc,0x87,0x6b,0xaf,0x67,0x25,0x3b,0xbe,0xb2,0xd1,0x76,0x2a,
1855
0xf5,0xa5,0xef,0xc5,0xb9,0xd8,0x4f,0x7d,0x79,0xe9,0x58,0xf3,0x6d,0x80,0xaf,0x32,
1856
0xa8,0x67,0x1b,0xb4,0x52,0xb1,0x3f,0xbb,0x9a,0xba,0xb1,0xa2,0xf9,0xa8,0x16,0x63,
1857
0x22,0x29,0x1b,0xfe,0x85,0x0f,0xf6,0x34,0x51,0xf7,0x3a,0x8c,0xbf,0xb4,0x4c,0x8c,
1858
0xd3,0x44,0xd8,0x85,0x71,0xb3,0xb8,0x9e,0xba,0xb3,0x51,0x7f,0x03,0x8e,0x2f,0x85,
1859
0x7f,0xf2,0x60,0x43,0x41,0x25,0xc6,0xd5,0x62,0xea,0xae,0x85,0xe6,0x0a,0xf4,0x67,
1860
0x2d,0xea,0x14,0x96,0xc0,0xef,0x2b,0xa8,0x0f,0x3e,0xef,0x4e,0x87,0xc6,0xc6,0x6a,
1861
0xea,0x62,0x4a,0xa8,0x6b,0x2f,0xd6,0x98,0x55,0x3b,0xd1,0x4f,0xac,0x3f,0xa1,0xdf,
1862
0x9d,0x82,0x71,0xb7,0x09,0xfe,0xca,0x86,0x6e,0x3a,0x7c,0xbe,0x02,0xfe,0x2d,0xc7,
1863
0xb9,0xd8,0x80,0x71,0x92,0x07,0x1f,0x6e,0xde,0x8e,0xf3,0xb8,0x15,0xed,0xa6,0x52,
1864
0xcf,0x7a,0x8c,0xa9,0x06,0xac,0x69,0x8b,0x30,0x0e,0x8a,0x0a,0xd1,0x17,0xf8,0x75,
1865
0x19,0x6c,0x64,0x5f,0x10,0xaf,0xc8,0x83,0x9d,0x18,0xbb,0xab,0x30,0xde,0xd7,0xd7,
1866
0xfe,0x3f,0xf6,0xde,0x06,0xa8,0xa9,0x6b,0xed,0xfb,0x5e,0x51,0x50,0xa2,0x50,0x82,
1867
0x82,0x82,0x82,0x05,0x25,0x0a,0x96,0x40,0x52,0x93,0x96,0x20,0xb4,0xa0,0xa0,0x04,
1868
0x12,0xbe,0xa3,0x44,0x41,0xa1,0x05,0x4c,0x20,0x91,0x04,0x12,0x20,0x90,0x40,0x02,
1869
0x49,0x48,0x42,0x62,0x49,0x05,0x0a,0x2d,0xb4,0xa0,0xa0,0x60,0xc1,0x8a,0x10,0x05,
1870
0x0b,0x56,0xee,0x91,0xe7,0x96,0x3e,0x32,0x23,0x33,0x72,0x17,0x5a,0x79,0x47,0x4e,
1871
0x09,0xc2,0x3d,0xf2,0x0e,0xcc,0xc8,0x8c,0xcc,0xc8,0xcc,0xbb,0x56,0xd8,0xf6,0xf5,
1872
0x9c,0xe7,0x9c,0xfb,0x7c,0xf5,0x9c,0xe7,0x7c,0x90,0x5f,0xd7,0x7f,0xed,0xf5,0xb1,
1873
0xf7,0x5e,0xeb,0xba,0xae,0xb5,0xf6,0x8e,0x61,0xa6,0xf0,0x7a,0xd0,0x7e,0xdd,0xf0,
1874
0xba,0x77,0xbe,0x02,0xb3,0x70,0x97,0x9d,0xbd,0x5d,0x05,0xd7,0x42,0x3b,0x78,0xd6,
1875
0x09,0x7d,0x7c,0x13,0xc6,0x4d,0x95,0x02,0x3c,0x2b,0x6f,0x00,0x73,0x5d,0xd0,0x0e,
1876
0xdf,0x2a,0xc0,0x9c,0xe1,0x16,0xbc,0x3f,0xbc,0x8e,0x16,0xae,0xcd,0x3b,0x57,0x60,
1877
0x4c,0xc0,0xb5,0xd0,0x03,0xe3,0xfa,0x3a,0xf4,0x6f,0x2f,0x9c,0xc3,0xe7,0xd0,0x3f,
1878
0xe8,0x1f,0xda,0xe0,0x13,0xcf,0xf2,0xed,0x45,0x18,0x1f,0x0a,0x60,0xf9,0x0c,0xa6,
1879
0x16,0xe8,0xcb,0x86,0x5e,0x18,0x2b,0x30,0xb6,0x0c,0x70,0x6d,0x7d,0x01,0x7d,0xd9,
1880
0x3a,0x00,0xd7,0x08,0x2c,0xb7,0xc1,0x71,0x5f,0xf9,0x04,0xda,0xbb,0x0e,0xde,0x13,
1881
0xc6,0x58,0x3d,0x8c,0xf1,0xaf,0xe1,0xfa,0x56,0xc0,0x54,0x01,0xd7,0xf3,0x65,0xb8,
1882
0xa6,0x2e,0x43,0x9b,0xb6,0xc2,0xef,0xe0,0xb7,0xa0,0x0f,0xe0,0x77,0xab,0xf9,0xcf,
1883
0x6f,0x43,0xbf,0x40,0xdb,0x56,0x5c,0x85,0xf7,0x80,0xf7,0x82,0x6b,0xd8,0x52,0x05,
1884
0xfd,0x6a,0x44,0xfb,0x06,0xfc,0x1e,0x0f,0xd7,0xa5,0xa5,0xa1,0x1d,0xde,0x17,0xde,
1885
0x1b,0xda,0xc6,0xd2,0x0d,0xd7,0x79,0x79,0x0d,0xb4,0x23,0xb4,0x93,0x06,0xda,0xab,
1886
0xf2,0x26,0x8c,0x79,0xb8,0x7f,0x40,0x5b,0xcd,0xc2,0x27,0xe7,0xec,0x25,0x38,0x7e,
1887
0xf3,0x6d,0x30,0xdb,0x87,0x62,0x0e,0xda,0x4f,0x0d,0xe3,0x45,0x0b,0x7d,0x53,0x0d,
1888
0x8f,0x2f,0x99,0xe0,0x18,0xa1,0xbf,0xe0,0x5e,0xf4,0xac,0x0d,0xda,0xae,0x0d,0x8e,
1889
0xf3,0x8a,0x11,0x26,0xe8,0xef,0x0e,0x68,0x9f,0x6b,0x30,0xf6,0xbf,0x81,0x79,0x1f,
1890
0xec,0xd3,0x0f,0x8f,0x07,0x6f,0x82,0x39,0x05,0xdc,0xab,0x2a,0xbb,0xe0,0x7a,0x80,
1891
0x7e,0x30,0x7d,0x06,0xe6,0x5a,0xab,0xc1,0xdc,0x95,0x3a,0x30,0xd7,0x09,0xd7,0x55,
1892
0x27,0xac,0xeb,0xb9,0x08,0xe6,0x7a,0x61,0x9c,0xde,0x85,0x71,0xf6,0x05,0xf4,0xc1,
1893
0x57,0xdf,0xc1,0x58,0x83,0x31,0xa2,0x34,0x83,0xc5,0xd6,0xaa,0xeb,0x60,0x4e,0x0b,
1894
0x0d,0xde,0x77,0x05,0x6e,0x3c,0x70,0x11,0xc1,0x41,0xcf,0xdc,0x85,0x13,0x51,0xab,
1895
0x61,0x19,0xe6,0x55,0xd0,0xf8,0x55,0xd0,0x09,0xb5,0xb5,0x70,0xb2,0x0d,0xd0,0xc0,
1896
0xd0,0xc1,0x97,0x7a,0xe0,0x66,0xa9,0x82,0xa9,0x06,0x58,0x3a,0x60,0xb9,0x13,0x4e,
1897
0xfa,0xdb,0x4f,0x61,0x82,0xed,0x83,0x30,0x60,0xee,0x76,0xc1,0xc0,0xad,0x87,0x06,
1898
0x80,0x93,0x57,0xc1,0xc5,0xac,0x6e,0x86,0x01,0x07,0x17,0x1b,0x7c,0x60,0xcc,0x56,
1899
0x37,0x82,0x59,0xd3,0xa7,0xd0,0x20,0x75,0x70,0xf3,0xfb,0x02,0x06,0x14,0xcc,0xbf,
1900
0x85,0xf9,0xb7,0x30,0xf0,0x15,0xd0,0x41,0xf0,0xf1,0xfa,0x4c,0x6b,0x06,0xcf,0xf4,
1901
0x70,0x23,0x32,0x75,0x83,0x67,0x35,0x30,0xc8,0x6a,0xbe,0x05,0xcf,0xea,0x61,0x30,
1902
0xd5,0x7f,0x05,0x9d,0x09,0x37,0x60,0xb8,0x89,0x3f,0x6b,0x82,0x4e,0x6d,0x82,0x86,
1903
0xb8,0x0c,0x37,0xa6,0x6b,0xb0,0x5f,0x37,0xec,0x63,0x86,0x6d,0x03,0xd0,0xa9,0x46,
1904
0xe8,0x54,0xb4,0xe1,0x37,0xc1,0xc9,0xb7,0x41,0x23,0x5c,0x81,0x1b,0xe7,0x35,0xb8,
1905
0x99,0x7f,0x0d,0x03,0xee,0x6b,0x68,0xa8,0xeb,0x70,0x13,0x1c,0x80,0x0e,0x57,0xc2,
1906
0x4d,0x54,0xd3,0x00,0xe6,0x75,0xd0,0x30,0x0d,0xd0,0xe9,0xf0,0xb1,0x3b,0xdf,0x5c,
1907
0x05,0xe6,0x3b,0x3f,0x05,0x8b,0x97,0x5a,0xf4,0x48,0x54,0x60,0xf1,0x32,0x7c,0x46,
1908
0xfd,0x7c,0xbd,0x09,0xcc,0x28,0xa0,0x99,0x14,0xfd,0x60,0xb1,0x4d,0xa7,0x83,0xd2,
1909
0x53,0x0d,0x16,0xaf,0xc2,0xb0,0x9b,0x1f,0xac,0x00,0xf3,0x77,0x2f,0x80,0xac,0x2c,
1910
0x90,0xc5,0x03,0x59,0xf0,0xbd,0x19,0x65,0x30,0xcf,0x17,0x83,0xf1,0x5e,0xf4,0xc7,
1911
0x4b,0xbd,0xe8,0x8f,0x9e,0x7a,0xd1,0xdf,0x39,0xdd,0x5d,0x2b,0x76,0x81,0x1f,0x1a,
1912
0xfe,0xab,0x17,0xfc,0x70,0xf3,0xbf,0x6e,0x83,0x1f,0x2e,0x81,0x1f,0x6a,0xc0,0x0f,
1913
0x5f,0x80,0x1f,0x1a,0xc1,0x0f,0x4d,0xe0,0x87,0x76,0xf0,0xc3,0x35,0xf0,0x43,0xc7,
1914
0x0f,0x4a,0x24,0xe5,0x50,0xfe,0x6b,0xc0,0x7a,0x0c,0x33,0x58,0xaa,0x46,0x67,0x54,
1915
0xff,0x57,0x1f,0x92,0x01,0xf0,0x83,0x09,0xc9,0xa7,0x48,0x2e,0x22,0xa9,0x41,0x52,
1916
0x8b,0xa4,0x0e,0x49,0x3d,0x92,0x06,0x24,0x9f,0x23,0xf9,0x02,0x49,0x23,0x92,0x2f,
1917
0x91,0x34,0x23,0x69,0x41,0x72,0x19,0x49,0x2b,0x92,0x2b,0x48,0xae,0x22,0x69,0x47,
1918
0xd2,0x81,0xe4,0xda,0xda,0x45,0xfb,0xd1,0xdd,0xbe,0x43,0x57,0xf9,0x0e,0x75,0x86,
1919
0x52,0x0d,0x47,0x3c,0xd9,0x0d,0x26,0xbf,0x05,0x93,0x77,0xc1,0x8f,0x0a,0x30,0x79,
1920
0x07,0x4c,0x7e,0x07,0x26,0xfb,0xc1,0x8f,0xad,0xe0,0xc7,0x2b,0xe0,0x47,0x15,0xf8,
1921
0xb1,0x02,0xfc,0xa8,0x01,0x3f,0x56,0x82,0x1f,0x8d,0xe0,0x47,0x03,0xf8,0xf1,0x02,
1922
0xf8,0x51,0x0b,0x7e,0xac,0x07,0x3f,0x9a,0xc0,0x8f,0x1d,0xe0,0xc7,0x6f,0xc0,0x8f,
1923
0x3d,0xe0,0xc7,0x6e,0xf0,0xe3,0x1d,0xf0,0xe3,0xb7,0xe0,0x27,0x05,0xf8,0x49,0x09,
1924
0x7e,0xbc,0x0b,0x7e,0xfa,0x14,0xfc,0x74,0x11,0xfc,0xd8,0x05,0x7e,0xaa,0x04,0x3f,
1925
0x69,0xc0,0x4f,0x5a,0xf0,0x53,0x15,0xf8,0x49,0x0d,0x7e,0xd2,0x81,0x9f,0xaa,0xc1,
1926
0xa4,0x0e,0x4c,0x5c,0x99,0xb8,0x0a,0xe5,0xa7,0x5a,0x28,0x93,0x5a,0x74,0x54,0x89,
1927
0x44,0x83,0xc4,0x5a,0xac,0x46,0x0d,0xb0,0xb7,0x01,0x75,0xed,0x44,0xd2,0x85,0x6a,
1928
0xd4,0x48,0xf4,0x60,0xa2,0x1d,0xd5,0xb5,0xa3,0xba,0xf6,0x89,0xeb,0x50,0x50,0x43,
1929
0x3b,0xba,0x6e,0x3b,0x6a,0xbd,0x86,0x5a,0xaf,0xa1,0xd6,0x6b,0xa8,0xf5,0x1a,0x6a,
1930
0xbd,0x86,0x5a,0xaf,0xa1,0xd6,0xaf,0x51,0xeb,0xd7,0xa8,0xee,0x6b,0x54,0xf7,0x35,
1931
0xaa,0xeb,0x44,0x9d,0x3b,0x51,0x5d,0x17,0x6a,0xed,0x42,0x47,0xd7,0xd1,0xd1,0x75,
1932
0xd4,0x70,0x1d,0x15,0x7b,0x50,0xb1,0x07,0x15,0x7b,0xd0,0x45,0x7b,0x50,0x9d,0x19,
1933
0x15,0xcd,0xe8,0xe8,0x16,0x6a,0xbd,0x85,0x8a,0xb7,0x50,0xeb,0x2d,0x54,0x77,0x1b,
1934
0x15,0x6f,0xa3,0xa3,0x3e,0x24,0xfd,0xa8,0x4b,0x3f,0x3a,0xba,0x83,0x8e,0xee,0xc0,
1935
0xa3,0x49,0x25,0x3c,0x82,0xd2,0x85,0xe4,0x3a,0x14,0x6b,0x1d,0x1c,0x15,0x14,0x3d,
1936
0x98,0x2c,0x47,0x0d,0xe5,0xa8,0xae,0x1c,0xd5,0x95,0xa3,0xba,0x0a,0x68,0x38,0x28,
1937
0x9d,0x48,0xba,0x90,0xc0,0xd3,0x2a,0x26,0x55,0x48,0xd4,0x48,0x74,0x48,0x60,0x3f,
1938
0x15,0xea,0xa2,0x42,0x5d,0x54,0xa8,0x8b,0x0a,0xb5,0xaa,0x50,0xab,0x0a,0xb5,0xaa,
1939
0x51,0xab,0x1a,0xb5,0xaa,0x51,0xab,0x1a,0xb5,0xaa,0x51,0xab,0x1a,0xb5,0x6a,0x50,
1940
0xab,0x06,0xb5,0x6a,0x50,0xab,0x06,0xb5,0x6a,0x50,0xab,0x06,0xb5,0x56,0xa2,0xd6,
1941
0x4a,0x54,0x57,0x89,0xea,0x2a,0x51,0x9d,0x1e,0xd5,0xe9,0xd1,0x19,0x7a,0x74,0x86,
1942
0x1e,0xb5,0xea,0x51,0xab,0x1e,0x59,0xf7,0xc6,0xe4,0x0d,0x30,0xd1,0x0d,0x65,0x52,
1943
0x07,0xc5,0x73,0xd2,0x30,0x69,0x82,0x6a,0xb4,0xea,0x05,0xab,0x7e,0x62,0xd5,0x6a,
1944
0xab,0x9a,0x50,0xef,0x2b,0x13,0xdd,0x48,0x6e,0x22,0x7f,0x6b,0x90,0x97,0xbb,0x91,
1945
0xdc,0x44,0x0e,0xd6,0x20,0xb7,0x76,0x23,0xb9,0x89,0x3c,0xaa,0x41,0x1e,0xed,0x46,
1946
0x72,0x13,0x39,0x53,0x83,0xa6,0x74,0x15,0x8d,0xbc,0x1b,0xc9,0x4d,0x34,0x68,0x0d,
1947
0x1a,0x56,0x37,0x92,0x9b,0x68,0x44,0x28,0xca,0x90,0x93,0xae,0x4c,0x56,0xa2,0xeb,
1948
0x55,0xa2,0xab,0x54,0x22,0x67,0x5a,0xed,0x54,0x89,0xce,0xa8,0x44,0xf3,0xba,0x81,
1949
0x3a,0x57,0xa2,0x8b,0x56,0x22,0x7f,0x43,0xe9,0x45,0xde,0xeb,0x45,0xad,0x0a,0xeb,
1950
0xc0,0x61,0xf6,0xc9,0x5a,0x86,0x86,0x0e,0x7d,0xad,0x43,0xa2,0x47,0x6e,0xd6,0x21,
1951
0xd1,0x23,0x37,0xeb,0x90,0xe8,0xd1,0x15,0x74,0x48,0xf4,0xe8,0x0a,0x3a,0x24,0x7a,
1952
0x14,0x68,0x3a,0x24,0x28,0x02,0xd1,0x51,0x27,0x3a,0xba,0x8e,0x8e,0xae,0xa3,0x23,
1953
0x33,0x3a,0x32,0xa3,0xa3,0x5b,0xe8,0xe8,0x96,0xf5,0x5c,0x14,0x3b,0xbd,0x28,0xb2,
1954
0x7a,0xd1,0x1c,0x7a,0xd1,0xd4,0x7b,0x90,0x98,0x91,0xdc,0x42,0x72,0x75,0xb2,0xca,
1955
0xba,0x06,0xac,0x61,0xbf,0x16,0xd0,0xd7,0xd6,0x42,0xfa,0xda,0x5a,0x28,0x5f,0xb3,
1956
0xfa,0xdf,0x9a,0x75,0xad,0x65,0xd7,0xad,0xd1,0x8f,0x4a,0x5d,0xd6,0x10,0xb0,0x66,
1957
0x3a,0x6b,0xbc,0xaf,0x85,0x7d,0xe7,0x5a,0xe0,0x77,0xae,0xcd,0xc1,0xda,0xb3,0x67,
1958
0xed,0x2a,0x3d,0xd6,0xe8,0x41,0x4b,0x01,0x5b,0x0c,0x56,0x1b,0xad,0xdd,0xaf,0x77,
1959
0x6d,0x46,0xbd,0x6b,0x77,0xe8,0x5d,0x6b,0xbb,0xb5,0x36,0xeb,0x5b,0x6b,0x63,0xb9,
1960
0xbd,0x76,0xb1,0xdb,0x6b,0x6d,0xb7,0xd7,0xee,0xde,0xbf,0x36,0xf8,0xfe,0xb5,0xca,
1961
0xfe,0xb5,0xb1,0xdc,0x59,0x2b,0xdd,0x59,0xeb,0x72,0x67,0x2d,0x5e,0x95,0xd6,0xab,
1962
0xa0,0x45,0x82,0xad,0x15,0x6b,0x9c,0x5b,0xef,0x6e,0xcd,0xf4,0x6b,0x99,0xce,0xba,
1963
0x20,0xd6,0x96,0xc4,0xf5,0xb5,0xa5,0x80,0x45,0x7f,0x17,0xb6,0x12,0xac,0x2b,0x60,
1964
0xed,0x04,0xb5,0x75,0xb6,0x28,0x5b,0xab,0xbc,0xbe,0xd6,0xe5,0xfa,0x5a,0xa9,0x13,
1965
0x85,0x49,0xe5,0xda,0x0a,0xaa,0x5c,0xbb,0x9f,0x66,0xed,0x74,0xcd,0xda,0x8d,0x34,
1966
0x6b,0xe7,0x69,0xac,0xc6,0x42,0x8b,0xc7,0xba,0xa4,0xd6,0x86,0xab,0x5f,0x9b,0x43,
1967
0xfb,0x9a,0x7f,0xaf,0xad,0x99,0xe7,0xda,0x9a,0x59,0xaf,0xbd,0xae,0xbc,0xbe,0xb6,
1968
0x55,0x59,0xa7,0x79,0x6d,0x6d,0xee,0x9d,0x6b,0xa5,0xce,0x35,0xd3,0x75,0xbe,0x76,
1969
0x8e,0xb5,0xa7,0x79,0x2d,0x80,0x7a,0xd7,0xb2,0x5b,0xaf,0x27,0xdd,0x69,0xcd,0xd6,
1970
0xee,0xae,0x5f,0xab,0xd4,0xaf,0x55,0xea,0xd7,0x2a,0xd5,0x6b,0x59,0xf9,0xeb,0x35,
1971
0xdf,0xb5,0x16,0xb8,0xd6,0x52,0xc5,0x2f,0x1b,0x01,0xb6,0x47,0xbc,0xbe,0xa6,0x7a,
1972
0xad,0x4d,0xbd,0x36,0x16,0xbd,0x75,0xbf,0xc4,0x6c,0x86,0x32,0xe5,0xda,0x38,0xdb,
1973
0xd7,0xda,0x7a,0xd6,0xce,0xd3,0xac,0x4d,0xd3,0x3c,0xa9,0x82,0xcf,0x05,0x78,0x3f,
1974
0x94,0xc1,0x20,0x55,0x59,0x17,0x1b,0x3c,0xa8,0xb0,0x2e,0xef,0x35,0x27,0x4c,0x7c,
1975
0x63,0xed,0xb8,0xb6,0x4f,0x76,0xc3,0xe0,0xd2,0xc2,0xbd,0x0d,0x96,0x54,0xd6,0xa5,
1976
0x38,0xa9,0x85,0x35,0x2a,0x6b,0xb8,0x59,0x37,0xb3,0xb5,0xcc,0xf3,0xf5,0xc5,0x3c,
1977
0x5f,0x77,0xf4,0xfc,0xff,0x3b,0x76,0x4e,0xaa,0x3c,0x91,0x58,0xfb,0xc0,0xdb,0x75,
1978
0xff,0x64,0x40,0x87,0xc0,0x0f,0xfc,0xac,0x50,0x82,0x20,0xe0,0x05,0x3e,0x84,0x47,
1979
0x75,0x30,0x7d,0x06,0x7e,0xa3,0x40,0x7f,0x56,0x75,0x11,0x9c,0x05,0x25,0x40,0x0e,
1980
0x6b,0x6a,0x60,0x82,0x2f,0x0e,0x8a,0x6a,0x98,0x4c,0x30,0xe9,0x61,0xaa,0x82,0xc9,
1981
0x00,0x93,0x11,0xa6,0x0b,0x30,0x7d,0x02,0x4e,0x83,0x54,0xb0,0x0f,0xec,0x07,0x07,
1982
0x01,0x09,0x04,0x83,0x0f,0x40,0x0a,0xf0,0x06,0x44,0x10,0x0a,0x77,0xb2,0x2a,0xb4,
1983
0x33,0x54,0xa1,0x0d,0x0f,0x6d,0x77,0x68,0xb3,0xb3,0x6e,0x1c,0x68,0xbf,0xb3,0x6e,
1984
0x1d,0x68,0xcb,0xb3,0x6e,0x1e,0x68,0xd7,0x43,0x07,0x68,0xfb,0xfb,0x14,0x1d,0x40,
1985
0x03,0xb5,0x80,0x89,0x4b,0x60,0xe2,0x32,0x98,0x68,0x05,0x13,0x6d,0x70,0xb3,0x02,
1986
0xe8,0x89,0xd9,0x0e,0x26,0x3a,0x60,0x50,0xc0,0x3d,0x09,0x58,0x9f,0x53,0x00,0xad,
1987
0x2b,0x68,0x32,0xb4,0xbf,0x02,0xb4,0x01,0xf6,0xc0,0x40,0x80,0x66,0x81,0x71,0x00,
1988
0x17,0x13,0x7c,0xf0,0x40,0xdb,0xc1,0xb5,0x02,0x1d,0x03,0x0d,0x0f,0x5d,0x07,0xd0,
1989
0x93,0x02,0x05,0x27,0xb0,0x5a,0x13,0xac,0xb9,0xf5,0x12,0x92,0xcb,0x48,0xda,0x90,
1990
0x5c,0x05,0x7b,0xc1,0x01,0x10,0x00,0xce,0x00,0x19,0x28,0x05,0xbf,0xb9,0xa2,0x86,
1991
0x09,0xfd,0xa2,0x83,0x7e,0xe9,0x41,0x3f,0xa4,0x5c,0x86,0xa9,0x0d,0xa6,0xab,0x30,
1992
0xa1,0x7f,0xc8,0x85,0xe5,0x0a,0x58,0x86,0xef,0xd6,0x3f,0x57,0x54,0x80,0xb5,0x7f,
1993
0xd2,0x45,0x3f,0x28,0x34,0x00,0xf4,0xc3,0xf8,0x7f,0x5c,0x02,0xff,0x71,0x19,0xfc,
1994
0x47,0x27,0xf8,0x8f,0x2b,0xe0,0x3f,0xda,0xc0,0x6f,0xe0,0x29,0xbf,0xa9,0x29,0x07,
1995
0xbf,0x81,0x5f,0xdb,0x7e,0xa3,0x31,0xc1,0xf4,0x29,0x4c,0x17,0xc1,0x6f,0xea,0x9a,
1996
0xc1,0x6f,0x3e,0xab,0x02,0x8b,0xd5,0xd5,0xed,0x48,0x3a,0x90,0x5c,0x43,0xf2,0x35,
1997
0x92,0x4e,0x24,0x5d,0x48,0xae,0x23,0xf9,0x06,0xc9,0x0d,0x24,0xdd,0x48,0x6e,0x22,
1998
0xe9,0x41,0xd2,0x8b,0xc4,0x8c,0xe4,0x16,0x92,0xdb,0x48,0xfa,0x90,0xf4,0x23,0xb9,
1999
0x83,0xe4,0x5b,0x24,0x03,0x48,0x06,0x91,0xdc,0x45,0xf2,0x1d,0x14,0x93,0x02,0x89,
2000
0x12,0x49,0x39,0x92,0x0a,0x24,0x2a,0x24,0x6a,0x24,0x1a,0x24,0x95,0x48,0xb4,0x48,
2001
0x74,0x48,0xf4,0x48,0xd0,0x98,0x4d,0x06,0x24,0x46,0x24,0x17,0x90,0x7c,0x02,0xe5,
2002
0x62,0x3d,0x92,0x06,0x24,0x9f,0x23,0xf9,0x02,0x49,0x23,0x92,0x26,0x24,0x5f,0x22,
2003
0xf9,0x0a,0x49,0x33,0x92,0x16,0x24,0x97,0x90,0x5c,0x46,0xd2,0x8a,0xa4,0x0d,0xc9,
2004
0x15,0x24,0x57,0x91,0x20,0xbb,0x5c,0x44,0x76,0xb9,0x88,0xec,0x72,0x11,0xd9,0xe5,
2005
0x22,0xb2,0xcb,0x45,0x64,0x97,0x8b,0xc8,0x2e,0x17,0x91,0x5d,0x2e,0x22,0xbb,0x5c,
2006
0x44,0x76,0xb9,0x88,0xec,0x72,0x11,0xd9,0xe5,0x22,0xb2,0xcb,0x45,0x64,0x97,0x8b,
2007
0xc8,0x2e,0x17,0x91,0x5d,0x2e,0x22,0xbb,0x5c,0x44,0x76,0xb9,0x88,0xec,0x72,0x11,
2008
0xd9,0xa5,0xee,0x33,0x24,0x68,0xe0,0x75,0x68,0xe0,0x75,0x68,0xe0,0x75,0x68,0xe0,
2009
0x75,0x68,0xe0,0x75,0x68,0xe0,0x75,0x68,0xe0,0x75,0x68,0xe0,0x75,0x68,0xe0,0x75,
2010
0x68,0xe0,0x75,0x68,0xcc,0x75,0x68,0xcc,0x75,0x68,0xcc,0x75,0x68,0xcc,0x75,0x68,
2011
0xcc,0x75,0x68,0xcc,0x75,0x68,0xcc,0x75,0x68,0xcc,0x75,0x68,0xcc,0x75,0x68,0xcc,
2012
0x75,0x68,0xcc,0x75,0x68,0xcc,0x75,0x68,0xcc,0x75,0x68,0xcc,0x75,0x68,0xcc,0x75,
2013
0x68,0xb8,0x75,0x68,0xb8,0x75,0x68,0xb8,0x75,0x68,0xb8,0x75,0x68,0xb8,0x75,0x68,
2014
0xb8,0x75,0x68,0xb8,0x75,0xd6,0x91,0x0e,0x80,0xff,0x5d,0x0d,0xfe,0xb7,0x09,0x7c,
2015
0xdf,0x00,0xbe,0xbf,0x0c,0xfe,0xbb,0xeb,0x0a,0xf8,0xbe,0x0d,0x7c,0xdf,0x0a,0xa6,
2016
0x6f,0x99,0xc0,0x48,0x3d,0x18,0xf9,0x12,0x7c,0xdf,0x01,0x46,0x2e,0x81,0xef,0xbf,
2017
0x00,0xdf,0x37,0x82,0x91,0xab,0xe0,0x7b,0x15,0xf8,0xfe,0x1a,0xf8,0x1e,0x0e,0xa1,
2018
0x69,0x40,0x05,0xfe,0xfb,0xcb,0x0b,0x60,0xe4,0x3a,0x3a,0x56,0x83,0xef,0x2f,0xa0,
2019
0x5c,0x03,0x46,0x6e,0x81,0x91,0xdb,0x60,0xe4,0x0e,0x2a,0x69,0xc1,0xc8,0x5d,0xf0,
2020
0x7d,0x3b,0xf8,0xfe,0x0a,0xbc,0x36,0x3c,0xf9,0x2a,0xf8,0x4d,0x77,0x37,0xf8,0xfe,
2021
0x13,0xf0,0x7d,0x0b,0xf8,0x1e,0x5e,0xb5,0x1e,0xfc,0xa7,0x02,0xfc,0xa7,0x12,0xfc,
2022
0x67,0x39,0xea,0xad,0x47,0x82,0x0c,0xd3,0x83,0x82,0xa8,0x07,0x05,0x51,0x0f,0x0a,
2023
0xa2,0x1e,0x14,0x44,0x3d,0x28,0x88,0x7a,0x50,0x10,0xf5,0xa0,0x20,0xea,0x41,0x41,
2024
0xd4,0x83,0x82,0xa8,0x07,0x05,0x51,0x0f,0x0a,0xa2,0x1e,0x14,0x44,0x3d,0x28,0x88,
2025
0x7a,0x50,0x10,0xf5,0xa0,0x20,0xea,0x41,0x41,0x84,0xbe,0xa2,0x54,0xf7,0x98,0x90,
2026
0x7c,0x8a,0xe4,0x22,0x92,0x1a,0x24,0xb5,0x48,0xea,0x90,0x20,0x9f,0xf5,0x20,0x9f,
2027
0xf5,0x20,0x9f,0xf5,0x20,0x9f,0xf5,0x20,0x9f,0xf5,0x20,0x9f,0xf5,0x20,0x9f,0xf5,
2028
0x58,0x87,0x86,0x7c,0xd6,0x83,0x7c,0xd6,0x83,0x7c,0xd6,0x83,0x82,0xad,0x07,0x39,
2029
0xae,0x07,0x39,0xae,0x07,0x39,0xae,0x07,0x39,0xae,0x07,0x39,0xae,0x07,0x39,0xae,
2030
0x07,0x39,0xae,0x07,0x39,0xae,0x07,0x39,0xae,0x07,0x39,0xae,0x07,0x39,0xae,0x07,
2031
0x39,0xae,0x07,0x39,0xae,0x07,0x39,0xae,0x07,0x39,0xae,0x07,0x05,0x9b,0x19,0x15,
2032
0xcd,0xa8,0x68,0xb6,0x16,0x91,0x33,0xcd,0xc8,0x99,0x66,0xe4,0x4c,0x33,0x72,0xa6,
2033
0x19,0x39,0xd3,0x8c,0x9c,0x69,0x46,0xce,0x34,0xa3,0xd8,0x33,0x23,0x8f,0x9a,0xd1,
2034
0x9a,0x34,0xa3,0x35,0x69,0x46,0x6b,0xd2,0x8c,0xd6,0xe4,0x2d,0x64,0xce,0x5b,0xc8,
2035
0x9c,0xb7,0x90,0x39,0x6f,0x21,0x73,0xde,0x42,0xe6,0xbc,0x05,0xcd,0x69,0xba,0xac,
2036
0x40,0xa2,0x44,0x52,0x8e,0xa4,0x02,0x89,0x0a,0x89,0xb5,0x55,0x83,0xa4,0x12,0x89,
2037
0x16,0x89,0x0e,0x89,0x1e,0x49,0x15,0x12,0x03,0x12,0x23,0x92,0x0b,0x48,0x3e,0x41,
2038
0x52,0x8d,0xc4,0x84,0xe4,0x53,0x24,0x17,0x91,0xd4,0x20,0xa9,0x45,0x52,0x87,0xe4,
2039
0x33,0x24,0xf5,0x48,0x1a,0x90,0x7c,0x8e,0xe4,0x0b,0x24,0x8d,0x48,0x9a,0x90,0x7c,
2040
0x89,0x04,0x1a,0xbb,0xae,0xbf,0x19,0x49,0x0b,0x92,0x4b,0x48,0x2e,0x23,0x69,0x45,
2041
0xd2,0x86,0xe4,0x0a,0x92,0xab,0x48,0xda,0x91,0x74,0x20,0xb9,0x86,0xe4,0x6b,0x24,
2042
0x9d,0x48,0xba,0x90,0x5c,0x47,0xf2,0x0d,0x92,0x1b,0x48,0xba,0x91,0xdc,0x44,0xd2,
2043
0x83,0xa4,0x17,0x89,0x19,0xc9,0x2d,0x24,0xb7,0x91,0xf4,0x21,0xe9,0x47,0x72,0x07,
2044
0xc9,0xb7,0x48,0x06,0x90,0x0c,0x22,0xb9,0x8b,0x04,0x5a,0xb7,0xee,0x0e,0x6a,0xb8,
2045
0x83,0x1a,0xee,0xa0,0x86,0x3b,0xa8,0xe1,0x0e,0x6a,0xf8,0x56,0x81,0x44,0x89,0xa4,
2046
0x1c,0x49,0x05,0x12,0x15,0x12,0x35,0x12,0x0d,0x92,0x4a,0x24,0x5a,0x24,0x3a,0x24,
2047
0x7a,0x24,0x55,0x48,0x0c,0x48,0x8c,0x48,0x2e,0x20,0xf9,0x04,0x49,0x35,0x12,0x13,
2048
0x92,0x4f,0x91,0x40,0xc3,0x36,0xa9,0x3f,0x83,0xa9,0x0d,0x1d,0xd4,0xff,0xd6,0x01,
2049
0x4c,0xd7,0xdf,0x2c,0x7c,0xf3,0x66,0xe1,0xc6,0x9b,0x85,0xee,0x37,0x0b,0xd0,0x20,
2050
0x4d,0x9a,0x7e,0xec,0x4a,0x9a,0x3b,0xaf,0x0f,0xfa,0xdf,0xb8,0xe4,0x5a,0xed,0xeb,
2051
0x42,0xff,0x1b,0xd7,0xff,0xa5,0xe5,0x1b,0x70,0xbf,0x1b,0x3c,0xb8,0x0d,0x7e,0xa3,
2052
0xad,0x84,0x09,0xce,0xfd,0xcb,0xd6,0x4b,0x48,0x2e,0x23,0x69,0x45,0xd2,0x86,0xe4,
2053
0x0a,0x92,0xab,0x48,0xda,0x91,0x74,0x20,0xb9,0x86,0xe4,0x6b,0x24,0x9d,0x48,0xba,
2054
0x90,0x5c,0x47,0xf2,0x0d,0x92,0x1b,0x48,0xba,0x91,0xdc,0x44,0xd2,0x83,0xa4,0x17,
2055
0x89,0x19,0xc9,0x2d,0x24,0xb7,0x91,0xf4,0x21,0xe9,0x47,0x72,0x07,0xc9,0xb7,0x48,
2056
0x06,0x90,0x0c,0x22,0xb9,0x8b,0x04,0x3a,0xe8,0xcb,0x36,0x05,0x12,0x25,0x12,0x34,
2057
0xc8,0x36,0xf8,0x60,0xbf,0x0e,0x7e,0x6c,0x01,0x93,0xdf,0x00,0xb2,0x1f,0xa0,0xf8,
2058
0x81,0x77,0xfd,0xc0,0x21,0x3f,0x40,0xf5,0x03,0x34,0x3f,0xf0,0x9e,0x1f,0x78,0xdf,
2059
0x0f,0x04,0xfa,0x01,0x3a,0x7a,0xe9,0xa9,0xc9,0x47,0x2f,0x35,0x85,0xc5,0x80,0x5b,
2060
0x00,0xf2,0x33,0x40,0x7e,0x3e,0x10,0x0a,0x0b,0x40,0xe1,0xc7,0x40,0x00,0xff,0xcb,
2061
0x00,0x82,0x3c,0x90,0x91,0x0d,0x7e,0x56,0x7e,0xfb,0xb3,0xb2,0xca,0xfa,0x1b,0x7f,
2062
0x39,0xfa,0x9b,0xcd,0xcf,0x80,0xe5,0x13,0xf4,0x47,0x1c,0x95,0xc0,0xd2,0xfa,0x39,
2063
0x98,0xbb,0x7a,0x19,0xcc,0xdc,0x69,0x05,0xb3,0xf5,0xcd,0xe0,0x99,0xaa,0x05,0x58,
2064
0x74,0x46,0x60,0xb9,0x6b,0x00,0x16,0x8d,0x11,0xcc,0xc2,0xad,0xdc,0xa2,0x6d,0x02,
2065
0xcf,0xcc,0xe5,0x60,0xee,0x66,0x07,0xb0,0x5c,0x86,0x65,0xf8,0xf4,0x9d,0x1d,0xa8,
2066
0x01,0xb3,0xfa,0x5a,0x30,0x6b,0xac,0x05,0xf3,0x4a,0x3d,0x98,0x35,0x54,0x82,0x59,
2067
0xdd,0x45,0xf0,0xec,0x8a,0x12,0x3c,0xeb,0x40,0xff,0xd4,0xa8,0x05,0xb3,0x77,0x14,
2068
0xe0,0x59,0x0d,0xbc,0x9f,0xee,0x26,0xb0,0xc0,0x9d,0x7f,0x5e,0x8d,0xde,0xb2,0x6a,
2069
0x66,0x1b,0x3b,0xd7,0xde,0xc3,0x6a,0x66,0xfa,0x74,0xaf,0x8f,0xee,0x18,0xb0,0x23,
2070
0xcb,0xf5,0xd7,0x75,0xcf,0xca,0xfb,0xb1,0x23,0x78,0xe1,0xd7,0x75,0x5f,0x7c,0xf6,
2071
0xba,0x5f,0x55,0xd3,0xeb,0xd6,0x5a,0x6b,0x9d,0xe5,0x2e,0x9a,0xd5,0x37,0x60,0xa6,
2072
0x6f,0x10,0xa6,0x3e,0x30,0xd3,0x0f,0xed,0xd9,0xac,0xba,0x04,0x66,0x06,0x9b,0xc1,
2073
0xcc,0xdd,0x6f,0x81,0x45,0x51,0x0e,0x2c,0x4a,0x38,0x34,0xf8,0x26,0x63,0x41,0xbf,
2074
0xa1,0x7f,0x0a,0x57,0x76,0x73,0x3d,0xac,0x50,0xa3,0x3f,0x11,0x6a,0x85,0x09,0xfa,
2075
0xac,0xb9,0xa6,0x11,0xb6,0xf4,0xc3,0x02,0x0c,0x88,0xe6,0xda,0x2a,0x68,0x05,0x78,
2076
0x5d,0x4d,0x2b,0x98,0xf9,0x16,0x59,0x04,0x06,0x43,0x47,0xe5,0x57,0xd0,0x24,0xf0,
2077
0xcd,0xe8,0x22,0xca,0xe1,0x75,0x75,0x1a,0x98,0x6e,0x83,0x9f,0x6b,0xd0,0x9f,0xd4,
2078
0xaa,0x61,0x82,0x65,0xa3,0x0e,0xa6,0xcf,0x61,0x82,0xd3,0x37,0x0e,0xc2,0x04,0xdd,
2079
0xdc,0xdc,0xde,0x09,0x9e,0x29,0xa1,0xfd,0x3e,0xd1,0xc3,0x04,0x77,0x94,0x66,0xf4,
2080
0x77,0x44,0x9f,0x7c,0x0d,0x53,0x37,0x34,0x18,0x3c,0x0b,0x8e,0xc8,0x02,0xdf,0x6f,
2081
0x2c,0xf0,0x9d,0xc4,0x62,0x6a,0x87,0xe5,0x4b,0xc0,0x02,0x9f,0xf0,0x96,0x9a,0x6a,
2082
0x60,0xa9,0xbd,0x08,0x13,0xec,0x5f,0xa7,0x82,0x09,0x9e,0x03,0x9f,0xac,0x96,0xcf,
2083
0xe0,0x8c,0x1a,0xeb,0x60,0x82,0x43,0x6c,0x30,0xc1,0xd4,0x0b,0x1d,0x74,0x1d,0x58,
2084
0xbe,0xba,0x00,0x13,0x3c,0x6e,0x86,0x8e,0xfc,0x12,0x4e,0xa1,0x19,0x3a,0xa0,0x19,
2085
0xde,0xe3,0x12,0x1c,0x7e,0x0b,0x7c,0x19,0xb1,0x5c,0x86,0x15,0x97,0x6f,0x43,0xef,
2086
0xc3,0x9b,0xc2,0x25,0x61,0x69,0x83,0xcb,0xa2,0xe5,0x73,0x18,0xfd,0x2d,0x5f,0x5c,
2087
0x03,0x96,0xab,0x9d,0xc0,0xd2,0xfe,0x05,0x4c,0x57,0xe1,0x71,0x3d,0xb0,0x74,0x5c,
2088
0x01,0x3f,0x7f,0x71,0x1d,0xa6,0x01,0x60,0xe9,0x84,0x43,0xeb,0x84,0x81,0xdb,0x72,
2089
0x15,0x1e,0x7c,0x53,0x01,0x13,0xec,0xf0,0x0d,0x5c,0x00,0x2d,0x9d,0xe8,0xe0,0x3b,
2090
0x60,0xb9,0x01,0xaf,0x39,0x78,0x11,0xfc,0xfc,0xa5,0x12,0x58,0xba,0x9b,0x81,0x05,
2091
0x3e,0x43,0x2d,0x37,0xe1,0x06,0xd2,0x72,0x1b,0xde,0xd8,0x5c,0x81,0x0e,0xae,0xc0,
2092
0x03,0x38,0x4c,0x33,0x9c,0x06,0x7c,0x4c,0x58,0x6e,0xc3,0x98,0xbb,0x7d,0x09,0xfc,
2093
0xdc,0xfc,0x0d,0xcc,0xa1,0xb1,0xfa,0xe0,0xd4,0xa1,0x17,0x2d,0x70,0x0f,0xfd,0xb9,
2094
0x05,0x8e,0xec,0x92,0x06,0x5a,0xbb,0x05,0x76,0xbc,0x03,0x8d,0x77,0x07,0xce,0xfb,
2095
0x0e,0x5c,0x61,0xd7,0x2e,0xa0,0x7f,0x13,0x34,0x74,0x83,0x39,0x2d,0xbc,0xd1,0x00,
2096
0x3c,0x1d,0x3d,0x1c,0x2e,0xeb,0xe1,0x92,0xbb,0x52,0x09,0x2d,0x8f,0x7e,0x4f,0x18,
2097
0xfc,0x1a,0xd6,0x42,0x9b,0xdd,0x85,0xe5,0xef,0xa0,0x2d,0xbe,0x83,0x76,0xfa,0x0e,
2098
0x06,0x6f,0xb9,0x12,0xfc,0x0c,0x57,0xe4,0xcf,0xad,0x70,0x97,0xbf,0xf4,0x05,0x8c,
2099
0x64,0xb8,0x12,0x66,0xd5,0xe8,0xdf,0x45,0x0d,0x30,0xdd,0x01,0xb3,0x9a,0x9b,0x30,
2100
0xc1,0x15,0xa1,0xf9,0x06,0xcc,0x56,0xa2,0x7f,0x9c,0x47,0x3f,0x4a,0x7c,0x01,0x23,
2101
0xbc,0x09,0x46,0x7d,0x37,0x98,0xad,0x82,0xe7,0x18,0xe1,0x2e,0x78,0xa9,0x13,0x9e,
2102
0x60,0x18,0x84,0x15,0x03,0xb0,0xa2,0x1d,0xcc,0x5e,0xa8,0x00,0xb3,0x9f,0xc0,0x9d,
2103
0xe5,0xd2,0x37,0xb0,0x57,0xf5,0x25,0x58,0x50,0xc3,0x4a,0x38,0x8f,0xf6,0xeb,0x60,
2104
0xd6,0xd4,0x01,0xd3,0x5d,0x30,0xfb,0x29,0xbc,0x8a,0x09,0x06,0x4c,0x47,0x27,0x98,
2105
0xad,0x85,0x2e,0xb9,0x0c,0xbf,0x8a,0xcc,0x7e,0x76,0x19,0xcc,0x7e,0xd1,0x07,0x66,
2106
0x1b,0x74,0xe0,0xe7,0x4e,0xf8,0xae,0x0d,0x0d,0xfd,0xf3,0xd7,0xd0,0x62,0xf0,0x85,
2107
0xda,0xa2,0x81,0x0b,0xad,0x51,0x01,0x66,0x3f,0x6f,0x04,0x73,0xe5,0x5d,0x60,0xe6,
2108
0x93,0x06,0x58,0x6e,0x01,0xb3,0x4d,0x70,0x68,0x4d,0x17,0xd1,0x3f,0x88,0x42,0x03,
2109
0x75,0xe9,0xc0,0xec,0x57,0x70,0xec,0x5f,0xc2,0x3b,0xb6,0x40,0xdb,0x5c,0x36,0x75,
2110
0x81,0xd9,0x4b,0x17,0xc0,0x6c,0xf3,0x57,0x60,0xb6,0x15,0x0e,0x18,0xee,0x2d,0xb3,
2111
0x57,0xe0,0x5d,0xae,0x5e,0x03,0xb3,0xd7,0xa0,0xaf,0x2f,0x7f,0x0e,0x0b,0x5f,0x7f,
2112
0x01,0x7e,0xbe,0x51,0x0f,0x66,0x3b,0xe1,0x73,0xed,0xf2,0xa5,0xab,0x60,0xb6,0x0b,
2113
0x7e,0x4d,0xea,0x86,0x67,0x75,0x41,0x13,0x5c,0x87,0x67,0x5e,0x87,0x9b,0xd6,0xe5,
2114
0x6b,0xc8,0x7f,0xbd,0xf0,0x79,0x70,0xf9,0x6b,0x78,0x07,0xd8,0xbc,0x78,0xf9,0x26,
2115
0x9c,0xf1,0xcd,0xef,0xc0,0x2c,0x7c,0xc3,0x99,0xed,0x86,0xe7,0xf5,0xd6,0xc1,0x04,
2116
0x27,0x67,0x86,0x93,0x84,0xef,0x03,0xb3,0xe8,0x91,0x7e,0x19,0xfd,0x28,0xd0,0xdb,
2117
0x0b,0x66,0xfb,0xa0,0x1d,0xe1,0x83,0xef,0xe7,0xde,0x1e,0x30,0x8b,0x1e,0x35,0x97,
2118
0xe1,0xd3,0x63,0xf6,0x36,0xf4,0xc4,0x20,0xdc,0x53,0x2f,0x0f,0xc2,0x85,0x78,0xf9,
2119
0x2e,0xbc,0xe7,0x77,0x1a,0xf0,0x4c,0xd1,0x0f,0x13,0x1c,0xd4,0xad,0x3a,0xb8,0x58,
2120
0xf4,0x30,0x0d,0xc2,0x74,0x1b,0x3c,0x83,0xf3,0x86,0x8b,0xb3,0x0d,0x3c,0x53,0xc3,
2121
0x0b,0xb7,0xea,0x2e,0x83,0x67,0x1a,0xe8,0xbd,0xd6,0x0b,0xe8,0x6f,0xb8,0xdb,0xc1,
2122
0x33,0x1d,0xf4,0x46,0x6b,0xbd,0x16,0x3c,0xd3,0xc3,0x4d,0x07,0x6e,0x4c,0x8b,0xad,
2123
0x8d,0xe8,0x1f,0xd3,0x9b,0x6b,0xc0,0x33,0xe3,0x1d,0xf0,0xec,0x02,0xdc,0xfd,0xee,
2124
0xa0,0x3f,0xe7,0x86,0xdf,0x6c,0xee,0xf4,0x81,0x67,0xf0,0xd5,0xff,0x99,0xa9,0x11,
2125
0x3c,0xfb,0x54,0x0d,0x9e,0x5d,0x84,0x5f,0x04,0x07,0xbe,0x80,0x5b,0x15,0xf4,0x5b,
2126
0xeb,0x8d,0x5b,0xf0,0x00,0xc6,0x77,0xeb,0x4d,0x14,0x5e,0x9a,0xaf,0xc0,0xb3,0x7a,
2127
0x74,0xe5,0xbb,0x2d,0x48,0x60,0x6c,0xb5,0x29,0x55,0xe0,0xe7,0xef,0x06,0xc0,0x8c,
2128
0x02,0x3e,0x2c,0xdb,0xe0,0x17,0x23,0x28,0xf0,0x19,0xd0,0xa6,0x6a,0x40,0xd2,0x03,
2129
0x9e,0x35,0xa2,0xdf,0xcf,0xe0,0x69,0x70,0xdd,0xcd,0x28,0x35,0x60,0xa6,0x1c,0xbe,
2130
0x67,0xb4,0xa1,0x1f,0x5e,0x5a,0x2e,0x80,0x19,0xf8,0xe5,0x6a,0xb1,0xad,0x1e,0x3e,
2131
0x6f,0xda,0x3e,0x87,0xaf,0x1a,0x6d,0x5f,0xc0,0xbb,0x5f,0xfd,0x1a,0xcc,0xa8,0xbe,
2132
0x81,0x9b,0x26,0x9c,0x6b,0x07,0x7c,0xba,0xb6,0xb5,0xc1,0x07,0x44,0xdb,0xb5,0xab,
2133
0xe0,0xd9,0xd7,0xd7,0xc1,0x0c,0x7a,0x68,0xb5,0x5d,0x87,0x73,0xfc,0x06,0x9a,0xe6,
2134
0x1b,0x1d,0xac,0x80,0xdb,0x52,0xdb,0x4d,0x38,0x47,0xf8,0x02,0x39,0xa3,0x87,0x1b,
2135
0x36,0x7c,0xb5,0x7b,0x06,0xdf,0xfb,0x9e,0xf5,0xc2,0x67,0x48,0xdb,0x5d,0xd8,0xcb,
2136
0x0c,0x77,0x73,0x03,0xdc,0x85,0x6f,0xc3,0x29,0xf6,0x95,0x83,0x67,0xfd,0x6a,0x58,
2137
0x86,0x0f,0xa7,0x2b,0xd0,0x4c,0x8b,0x57,0x74,0x95,0x60,0xc6,0x08,0xc7,0x7a,0xa5,
2138
0xaa,0x01,0x3c,0x1b,0x84,0x4f,0xa5,0x2b,0x86,0xbb,0xe0,0xd9,0xdd,0x5a,0xf0,0xec,
2139
0x3b,0x54,0x40,0xdf,0x6d,0xae,0xd4,0x5c,0x06,0x73,0x4a,0xf8,0xb2,0x73,0x05,0xbe,
2140
0xef,0xcf,0xc1,0x0d,0x6b,0xf1,0xb2,0xf1,0x2b,0x18,0x74,0xb5,0x30,0xf8,0x6e,0x82,
2141
0x39,0x55,0x05,0x98,0xa9,0xae,0x82,0xf9,0x5d,0x60,0xb9,0x06,0x6d,0x7c,0xe5,0xcb,
2142
0xab,0x48,0xe0,0xd1,0xe5,0x0b,0x28,0x16,0x2f,0xc0,0x20,0xd5,0xaa,0xc0,0xdc,0xdd,
2143
0x2f,0xc1,0x8c,0xe9,0x6b,0x30,0xa7,0x37,0xc1,0x04,0xfb,0xeb,0xd1,0x1f,0x58,0xf6,
2144
0xc0,0x1c,0x2e,0x59,0x6b,0x3e,0x08,0xe6,0xaa,0xa0,0x29,0xae,0x74,0x0e,0x80,0x39,
2145
0x43,0x13,0x98,0x33,0xc2,0xdb,0x5e,0xe8,0x82,0xc7,0x28,0x87,0x8d,0x9f,0x5c,0x85,
2146
0x75,0x17,0x61,0xae,0x87,0xc9,0x00,0x13,0xf4,0xf7,0x15,0xe8,0x9f,0xc5,0x2b,0x70,
2147
0xe3,0x58,0xbc,0x02,0x5f,0x99,0x67,0x6a,0xe0,0xf5,0xe1,0x77,0xa3,0x39,0xf8,0xad,
2148
0x68,0xae,0x06,0x1a,0xfa,0x2a,0xea,0x5b,0x0b,0xfd,0x78,0x65,0xa0,0x13,0xcc,0xd4,
2149
0x36,0xc1,0x04,0x1d,0x77,0xe5,0x2e,0x7c,0x54,0x5f,0xad,0x80,0x06,0xab,0x85,0xfd,
2150
0x1b,0xaa,0x61,0x82,0x97,0x6e,0xe8,0x00,0x73,0x9f,0xa3,0xa4,0x05,0x73,0x8d,0x17,
2151
0xc0,0xdc,0x17,0x97,0x60,0x0e,0x27,0xdc,0x04,0xfb,0x7c,0x09,0x1d,0xf7,0xd9,0x67,
2152
0x60,0xee,0xab,0x16,0x30,0xd7,0xac,0x84,0xc7,0xfd,0x60,0xae,0x05,0x5a,0xe4,0x2a,
2153
0x3a,0x11,0xbe,0x34,0xce,0xc1,0xb7,0xc2,0x99,0x7a,0x33,0xcc,0xe1,0x2e,0xf2,0x29,
2154
0x5c,0x21,0x57,0x2f,0xc1,0x40,0xbe,0xda,0x76,0x05,0xcc,0x7c,0x7e,0x17,0xcc,0x7c,
2155
0x51,0x09,0xe6,0xae,0xa1,0xee,0x37,0xe1,0xf5,0x6e,0xc2,0xeb,0xc1,0xaf,0x10,0x73,
2156
0xbd,0x5f,0x80,0x39,0xf4,0xb6,0x7c,0x75,0x00,0xbe,0x42,0x34,0x37,0x43,0x0b,0xa1,
2157
0x9f,0xdb,0x6e,0xc1,0xc9,0xdf,0x86,0x26,0x6e,0x86,0x57,0x9c,0xfb,0x16,0xbe,0x9d,
2158
0xb6,0x7f,0xf6,0x29,0x92,0x2e,0x30,0x5f,0x5e,0x03,0xe6,0x2b,0xba,0xc1,0xbc,0x0a,
2159
0xbe,0x69,0xb5,0x37,0x5e,0x87,0x07,0x5f,0x80,0x79,0x6d,0x1f,0x98,0xaf,0xfa,0x0c,
2160
0xa6,0x7a,0x30,0xaf,0x1b,0x00,0xf3,0x9f,0xf4,0x83,0xf9,0x6a,0x18,0xee,0xed,0xdf,
2161
0xdc,0x01,0xf3,0x75,0x30,0xe6,0xae,0xc0,0x07,0x32,0xfa,0x86,0xd5,0x0e,0xef,0x35,
2162
0x73,0xf5,0x0a,0x98,0xff,0x02,0x6e,0xd2,0xb7,0x6e,0x82,0xf9,0x46,0x18,0x7b,0x1d,
2163
0x68,0xf1,0x74,0x68,0x3f,0x07,0x33,0x1d,0x30,0xb8,0x3a,0xe0,0x33,0xf9,0x2b,0x38,
2164
0xcc,0x8e,0x6a,0x3d,0x98,0xb9,0x06,0xa3,0xb8,0xe3,0xd3,0x3a,0x30,0xdf,0x0c,0xdf,
2165
0x7f,0x3a,0xd0,0xe3,0xfa,0x32,0x7c,0x76,0x76,0xf6,0x80,0x79,0xf8,0x42,0x34,0x7f,
2166
0xe5,0x2a,0x98,0xbf,0x5a,0x0e,0x13,0x9c,0xdd,0x37,0x70,0xf9,0x77,0x74,0xde,0x00,
2167
0xf3,0xdd,0x0a,0x30,0xdf,0x03,0x9f,0xb6,0xf0,0xfb,0xcd,0x0c,0xfc,0x22,0x31,0x6f,
2168
0x86,0x81,0x70,0x0d,0xfd,0x66,0xde,0x03,0x17,0xca,0x35,0x15,0xbc,0xd5,0x35,0x2d,
2169
0xec,0x7b,0x0d,0x46,0xc0,0x8c,0x19,0x5e,0xf9,0xdb,0xbb,0x60,0x1e,0x7e,0x3f,0x9b,
2170
0x1f,0xf8,0x04,0x26,0xe8,0xad,0x6b,0xf5,0x0a,0x00,0x70,0x1b,0x36,0xda,0xd8,0x6e,
2171
0xda,0xbc,0xd9,0x0e,0xbf,0x65,0xab,0xbd,0xc3,0x5b,0x8e,0x9b,0x7f,0xf9,0x10,0x36,
2172
0x3b,0x6d,0xdb,0xee,0xec,0xb2,0x63,0xa7,0xab,0xb5,0xe8,0xb6,0x79,0xd7,0x6e,0x77,
2173
0x8f,0x3d,0x6f,0x7b,0x7a,0x6d,0xfe,0xbb,0x7f,0xf6,0xee,0x83,0xe2,0xfd,0xab,0x5e,
2174
0x92,0xb8,0xff,0x80,0x8f,0xef,0xc1,0x77,0xb0,0x92,0xdf,0xeb,0x6a,0x92,0xff,0xe6,
2175
0x00,0x32,0x05,0x1e,0xbc,0xbb,0xf9,0x9f,0xf3,0x73,0x68,0x33,0x95,0xf6,0xde,0xfb,
2176
0x81,0xaf,0x8b,0xf4,0x37,0xdb,0x82,0x0e,0x6f,0x0e,0x0e,0xf9,0xe0,0x75,0xe9,0xc3,
2177
0xcd,0xff,0xc6,0x9f,0xd0,0xb0,0x23,0x9b,0xd7,0x3f,0xeb,0x9f,0xf5,0xcf,0xfa,0x67,
2178
0xfd,0xb3,0xfe,0x59,0xff,0xac,0x7f,0xd6,0x3f,0xeb,0x9f,0xf5,0xcf,0xfa,0x67,0xfd,
2179
0xf3,0xef,0xf3,0x01,0x36,0xeb,0xfc,0x55,0xd8,0x02,0xbb,0xdf,0x02,0x0f,0x08,0xc0,
2180
0x09,0x38,0x63,0xb8,0x00,0x77,0x88,0x07,0xf0,0x02,0x44,0x40,0x02,0x64,0x08,0x05,
2181
0xd0,0x41,0x08,0x08,0x05,0x61,0x80,0x05,0x38,0x20,0x03,0xc2,0x07,0x62,0x20,0x03,
2182
0x2a,0x60,0x00,0x35,0x90,0x46,0xd0,0x0a,0x3a,0x41,0x2f,0x18,0x00,0xf7,0xc1,0x43,
2183
0xf0,0x18,0x3c,0x81,0xcc,0x80,0xe7,0xe0,0x05,0x78,0x05,0x6c,0x70,0xf6,0x56,0x9c,
2184
0x71,0xee,0x38,0x6f,0x9c,0x1f,0x8e,0x6a,0x25,0x18,0x17,0x8e,0x63,0xe2,0x92,0x70,
2185
0x29,0xb8,0x0c,0x08,0x1f,0x27,0xc6,0xc9,0x70,0x2a,0x9c,0x01,0x57,0x83,0x6b,0xc4,
2186
0xb5,0xe2,0x3a,0x21,0xbd,0xb8,0x01,0xdc,0x7d,0xdc,0x43,0xdc,0x63,0xdc,0x13,0x2b,
2187
0x33,0xb8,0xe7,0xb8,0x17,0xb8,0x57,0x38,0x9b,0x0d,0x36,0x1b,0xec,0x21,0xce,0x1b,
2188
0xdc,0x37,0x78,0x6f,0xf0,0xdb,0x40,0xdd,0x10,0xbc,0x21,0x7c,0x03,0x73,0x43,0xd2,
2189
0x86,0x94,0x0d,0x19,0x1b,0xf8,0x1b,0xc4,0x1b,0x64,0x1b,0x54,0x1b,0x0c,0x56,0x6a,
2190
0x36,0x34,0x6e,0x68,0xdd,0xd0,0xb9,0xa1,0x77,0xc3,0xc0,0x86,0xfb,0x1b,0x1e,0x6e,
2191
0x78,0xbc,0xe1,0xc9,0x86,0x99,0x0d,0xcf,0x37,0xbc,0xd8,0xf0,0x6a,0x83,0xcd,0x46,
2192
0xfb,0x8d,0xce,0x1b,0xdd,0x37,0x7a,0x6f,0xf4,0xb3,0x42,0xdd,0x18,0xbc,0x31,0x7c,
2193
0x23,0x73,0x63,0xd2,0xc6,0x94,0x8d,0x19,0x1b,0xf9,0x1b,0xc5,0x1b,0x25,0x1b,0xe5,
2194
0x1b,0x55,0x1b,0x0d,0x1b,0x6b,0x36,0x36,0x6e,0x6c,0x85,0x74,0x6e,0xec,0xdd,0x38,
2195
0xb0,0xf1,0xfe,0xc6,0x87,0x1b,0xc7,0x37,0x4e,0x6d,0x9c,0xb1,0xf2,0x7c,0xe3,0x8b,
2196
0x8d,0xaf,0x36,0xda,0xd8,0xd8,0xdb,0xb8,0xd8,0xb8,0x5b,0xf1,0xb6,0xf1,0xb3,0xa1,
2197
0xda,0x04,0xdb,0x84,0xdb,0x30,0xad,0x24,0xd9,0xa4,0xd8,0x64,0xd8,0xf0,0x6d,0xc4,
2198
0x36,0x32,0x1b,0x95,0x8d,0xc1,0xa6,0xc6,0xa6,0xd1,0xa6,0xd5,0xa6,0xd3,0xa6,0xd7,
2199
0x66,0xc0,0xe6,0xbe,0xcd,0x43,0x9b,0xc7,0x36,0x4f,0xac,0xcc,0xd8,0x3c,0xb7,0x79,
2200
0x61,0xf3,0xca,0xc6,0xc6,0xd6,0xde,0xd6,0xd9,0xd6,0xdd,0xd6,0xdb,0xd6,0xcf,0x96,
2201
0x6a,0x1b,0x6c,0x1b,0x6e,0xcb,0xb4,0x4d,0xb2,0x4d,0xb1,0xcd,0xb0,0xe5,0xdb,0x8a,
2202
0x6d,0x65,0xb6,0x2a,0x5b,0x83,0x6d,0xad,0x6d,0xfd,0x5f,0x4d,0xb3,0x6d,0xfb,0xff,
2203
0xc0,0x0d,0xdb,0xbe,0x3f,0x89,0x7e,0xdb,0x61,0xdb,0x31,0xdb,0x29,0x5b,0x8b,0xed,
2204
0x82,0xed,0xb2,0xed,0xaa,0xad,0xed,0x26,0xfb,0x4d,0xce,0x9b,0xdc,0x37,0x79,0x6f,
2205
0xf2,0xdb,0x44,0xdd,0x14,0xbc,0x29,0x7c,0x13,0x73,0x53,0xf2,0xa6,0x8c,0x4d,0xc2,
2206
0x4d,0xb2,0x4d,0xda,0x4d,0x35,0x9b,0x9a,0x37,0x75,0x42,0xfa,0x36,0xdd,0xdf,0xf4,
2207
0x68,0xd3,0x93,0x4d,0x33,0x9b,0x9e,0x5b,0x79,0xb1,0xe9,0xd5,0x26,0x9b,0xcd,0xf6,
2208
0x9b,0x9d,0x37,0xbb,0x6f,0xf6,0xd9,0x4c,0xdd,0x1c,0xbc,0x39,0x7c,0x33,0x6b,0x33,
2209
0x7b,0x73,0xea,0xe6,0x8c,0xcd,0xfc,0xcd,0x62,0x2b,0xb2,0xcd,0xaa,0xcd,0xd5,0x9b,
2210
0x1b,0x37,0xb7,0x6e,0xee,0xdc,0xdc,0xbb,0x79,0x00,0x72,0x7f,0xf3,0xc3,0xcd,0x8f,
2211
0x37,0x3f,0xd9,0x3c,0xb3,0xf9,0xf9,0xe6,0x17,0x9b,0x5f,0x6d,0xb6,0xb1,0xb3,0xb7,
2212
0x73,0xb6,0x73,0xb7,0xf3,0xb6,0xf3,0xb3,0xa3,0xda,0x05,0xdb,0x85,0xdb,0x31,0xed,
2213
0x92,0xec,0x52,0xec,0x32,0xec,0xf8,0x76,0x62,0x3b,0x99,0x9d,0xca,0xce,0x60,0x57,
2214
0x63,0xd7,0x68,0xa5,0xd5,0xae,0xf3,0xb7,0xe8,0xb5,0x1b,0xb0,0xbb,0x6f,0xf7,0xd0,
2215
0x6e,0xc2,0x6e,0xc6,0x6e,0xd1,0xee,0x95,0x9d,0x0d,0xde,0x1e,0xef,0x8a,0xf7,0xc6,
2216
0xfb,0xe1,0xa9,0xff,0xa6,0xd0,0xf0,0x74,0x7c,0x08,0x3e,0x0c,0x1f,0x81,0x67,0xe0,
2217
0x59,0xf8,0x78,0x3c,0x1b,0x9f,0xfc,0x57,0xc1,0xc1,0xa7,0xe3,0x79,0x78,0x11,0x5e,
2218
0x8a,0x57,0xe2,0xb5,0x10,0x1d,0xde,0x88,0x37,0xe1,0x6b,0xf1,0x0d,0xf8,0xc6,0x7f,
2219
0x5a,0x9a,0xf1,0xad,0x90,0x76,0xfc,0x8d,0xbf,0x31,0xbd,0xbf,0x60,0xc6,0x0f,0x60,
2220
0xdc,0xfb,0x85,0x21,0xfc,0xf7,0xf8,0x47,0xf8,0x09,0xfc,0x13,0xfc,0x0c,0xfe,0x39,
2221
0xfe,0x05,0xe4,0x15,0xc4,0x66,0x8b,0xfd,0x16,0xd7,0xbf,0x00,0xcf,0x2d,0x3e,0x5b,
2222
0xc8,0x5b,0x02,0xb7,0x84,0x6e,0x89,0xdc,0x92,0xf4,0x17,0x90,0xb2,0x25,0x63,0x0b,
2223
0x7f,0x8b,0x78,0x8b,0x6c,0x8b,0x7c,0x8b,0x72,0x8b,0x7a,0x8b,0x7e,0xcb,0xa7,0x5b,
2224
0x1a,0xb6,0x34,0x6d,0x69,0xfe,0xb3,0x69,0xd9,0xd2,0xb6,0xa5,0x63,0x4b,0xe7,0x96,
2225
0xae,0x2d,0xdd,0x5b,0x7a,0xad,0x98,0xb7,0xf4,0xfd,0x0e,0xf7,0xb6,0x3c,0x80,0x3c,
2226
0xc2,0x98,0xf8,0x85,0xa7,0x5b,0xe6,0xb6,0x2c,0xfe,0x5e,0x5e,0xfe,0x95,0x80,0xad,
2227
0x7f,0x0e,0x76,0x5b,0x09,0x10,0x57,0x0c,0xcf,0x5f,0xf0,0xd9,0x4a,0xde,0x1a,0xf8,
2228
0x67,0x12,0xba,0x35,0xf2,0x1f,0x90,0xb8,0xad,0xc9,0xff,0x03,0x69,0x5b,0xb9,0x5b,
2229
0x85,0x5b,0x8b,0xac,0x28,0xb6,0x6a,0xad,0x54,0x6f,0xad,0xdf,0xda,0xbc,0xb5,0x7d,
2230
0xeb,0x8d,0xad,0x7d,0x56,0xee,0x6d,0x7d,0xb0,0xf5,0xd1,0xd6,0x89,0xad,0x4f,0xb7,
2231
0xce,0x59,0x59,0xdc,0xfa,0x72,0x2b,0xb0,0xb7,0xb3,0x27,0xd8,0xbb,0xda,0x7b,0xda,
2232
0xfb,0xd8,0x93,0xed,0x03,0xed,0x43,0xed,0x23,0xad,0xc4,0xd9,0x27,0xaf,0xf3,0x07,
2233
0xe1,0xd8,0xa7,0xad,0xf3,0x17,0xc1,0xb5,0x17,0xda,0x17,0xd9,0x2b,0xec,0xb5,0xff,
2234
0xc0,0xe8,0xec,0x4d,0xf6,0x0d,0xf6,0x2d,0xf6,0xed,0xff,0x60,0xdc,0x80,0xf4,0xfd,
2235
0x51,0xee,0xfd,0xcd,0x00,0xeb,0x9f,0x7f,0xf3,0xcf,0xdf,0x22,0xaa,0x1e,0xfc,0x0e,
2236
0x8f,0xac,0x4c,0xfc,0x4a,0x3c,0xb5,0x9f,0xb3,0x5f,0xb4,0x7f,0x69,0x0f,0x1c,0xec,
2237
0x1c,0x08,0x0e,0xae,0xff,0xa2,0x78,0x3a,0xf8,0xfc,0x11,0xc8,0x0e,0x81,0x90,0xd0,
2238
0x7f,0x1a,0x22,0xad,0xc4,0xfd,0x2a,0x24,0x3b,0xa4,0x39,0x70,0xad,0x08,0xd7,0xf9,
2239
0x17,0xa4,0xc8,0x8a,0xc2,0x41,0xfb,0x47,0xa8,0x76,0xa8,0xff,0xbb,0xd2,0xfc,0x77,
2240
0xa4,0xdd,0xe1,0x86,0x43,0xdf,0xbf,0x2d,0xf7,0xfe,0xcd,0x78,0xf0,0x5b,0x3c,0x72,
2241
0x98,0x80,0x3c,0x75,0x78,0xfe,0x6f,0xce,0x0b,0x87,0x57,0x0e,0x36,0x6f,0xad,0xf3,
2242
0x87,0xb0,0x87,0x38,0xbf,0xe5,0xf9,0x96,0xcf,0x3f,0x0d,0xbe,0x6f,0x91,0xff,0xad,
2243
0xa1,0xbc,0x15,0xf8,0x2b,0x43,0x7f,0x2b,0xec,0xad,0xc8,0xbf,0x29,0x8c,0xb7,0x98,
2244
0x7f,0x57,0x92,0x7e,0x0f,0x29,0xbf,0x90,0xf1,0x0b,0xfc,0x5f,0x10,0xff,0x41,0x64,
2245
0xbf,0x07,0x15,0xc4,0xf0,0x56,0xed,0x5b,0xcd,0x6f,0x75,0xbc,0xd5,0xfb,0x3b,0x0c,
2246
0xfc,0x09,0xdc,0xff,0x3d,0x3c,0xfc,0x85,0xc7,0xbf,0xf0,0xe4,0x17,0x66,0xfe,0x20,
2247
0xcf,0xff,0x85,0x79,0xb1,0xce,0x3f,0x09,0xcb,0x6f,0xbd,0xfc,0xbd,0x00,0x47,0xe0,
2248
0x68,0x07,0x21,0x40,0x5c,0x21,0x9e,0x18,0x3e,0xbf,0x3a,0x64,0x48,0xa0,0x95,0x50,
2249
0xc7,0x48,0x48,0xdc,0x3a,0xff,0x62,0xc4,0x3b,0xb2,0x1d,0x39,0x8e,0x29,0x8e,0xa9,
2250
0x8e,0xe9,0x8e,0x99,0x8e,0x3c,0x47,0x81,0xa3,0xc8,0x51,0xe2,0x28,0x75,0x94,0x3b,
2251
0x2a,0x1d,0xd5,0x8e,0x5a,0x47,0x9d,0xa3,0xd1,0xd1,0xe4,0x58,0xeb,0xd8,0xe0,0xd8,
2252
0xe4,0xd8,0xe2,0xd8,0xe6,0xd8,0xe1,0xd8,0xe5,0xd8,0xed,0x68,0x76,0xec,0x77,0x1c,
2253
0x74,0x1c,0x72,0x1c,0x76,0x1c,0x71,0x1c,0x75,0x7c,0xe4,0x38,0xe6,0x38,0xee,0x38,
2254
0xe9,0x38,0xe5,0x38,0xed,0x68,0x71,0x9c,0x77,0x5c,0x70,0x5c,0x72,0x5c,0x76,0x5c,
2255
0x71,0x5c,0x75,0xc4,0x11,0x6c,0x09,0x78,0x82,0x03,0xc1,0x89,0xe0,0x42,0x70,0x23,
2256
0x78,0x10,0xbc,0x08,0x44,0x82,0x2f,0x81,0x44,0xa0,0x10,0x68,0x04,0x3a,0x21,0x84,
2257
0x10,0xfa,0x07,0x09,0x23,0x84,0xff,0x0a,0x44,0x10,0x18,0x04,0x16,0x21,0x9e,0xc0,
2258
0x26,0x70,0x08,0xa9,0x84,0x74,0x42,0x26,0x81,0x47,0x10,0x10,0x44,0x04,0x09,0x41,
2259
0x4a,0x90,0x13,0x94,0x04,0x35,0x41,0x47,0x30,0x12,0x4c,0x84,0x5a,0x42,0x03,0xa1,
2260
0x89,0xd0,0x42,0x68,0x23,0x74,0x10,0xba,0x08,0xdd,0x04,0x33,0xa1,0x9f,0x30,0x48,
2261
0x18,0x22,0x0c,0x13,0x46,0x08,0xa3,0x84,0x31,0xc2,0x38,0x61,0xe2,0x1f,0x80,0xa7,
2262
0x84,0x39,0xc2,0x22,0xe1,0x25,0x01,0x38,0xd9,0x39,0x11,0x9c,0x5c,0x9d,0xbc,0x9d,
2263
0xc8,0x4e,0x81,0x4e,0xa1,0x4e,0x91,0x4e,0x71,0x4e,0xc9,0x4e,0x69,0x4e,0x5c,0x27,
2264
0xa1,0x53,0x91,0x93,0xc2,0xc9,0xe0,0x54,0xef,0xd4,0xea,0x74,0xc3,0xa9,0xcf,0xe9,
2265
0x9e,0xd3,0x03,0xa7,0x47,0x4e,0x4f,0x9c,0xe6,0x9c,0x16,0x9d,0x5e,0x3a,0x81,0x6d,
2266
0x76,0xdb,0x08,0xdb,0x5c,0xb7,0x79,0x6e,0xf3,0xd9,0x46,0xde,0x16,0xb8,0x2d,0x74,
2267
0x5b,0xe4,0xb6,0xb8,0x6d,0xc9,0xdb,0xd2,0xb6,0x71,0xb7,0x89,0xb7,0x29,0xb6,0x69,
2268
0xb7,0x55,0x6f,0xab,0xdf,0xd6,0xbc,0xad,0x7d,0xdb,0x8d,0x6d,0x7d,0xdb,0xee,0x6d,
2269
0x7b,0xb8,0x6d,0x62,0xdb,0xd3,0x6d,0x73,0xdb,0x16,0xb7,0xbd,0xdc,0x06,0xb6,0xdb,
2270
0x6d,0x27,0x6c,0x77,0xdd,0xee,0xb9,0xdd,0x67,0x3b,0x79,0x7b,0xe0,0xf6,0xd0,0xed,
2271
0x91,0xdb,0xe3,0xb6,0x27,0x6f,0x4f,0xdb,0xce,0xdd,0x2e,0xde,0xae,0xd8,0x6e,0xd8,
2272
0x5e,0xbf,0xbd,0x75,0xfb,0x8d,0xed,0x03,0xdb,0x1f,0x6c,0x7f,0xb4,0x7d,0x62,0xfb,
2273
0xd3,0xed,0x73,0xdb,0x17,0xb7,0xbf,0xdc,0x0e,0x9c,0xed,0x9c,0x9d,0x9d,0x3d,0x9d,
2274
0x7d,0x9c,0xc9,0xce,0x81,0xce,0xa1,0xce,0x91,0xce,0x71,0xce,0x29,0xce,0x5c,0x67,
2275
0xb1,0xb3,0xc2,0xd9,0xe0,0x5c,0xef,0xdc,0xec,0xdc,0xee,0x7c,0xc3,0xb9,0xcf,0xf9,
2276
0x9e,0xf3,0x03,0xe7,0x47,0xce,0x13,0xce,0x4f,0x9d,0xe7,0x9c,0x17,0x9d,0x5f,0x3a,
2277
0x03,0x17,0x3b,0x17,0x67,0x17,0x4f,0x17,0x3f,0x97,0x40,0x97,0x50,0x97,0x48,0x97,
2278
0x38,0x97,0x64,0x97,0x34,0x17,0xae,0x8b,0xd0,0xa5,0xc8,0x45,0xe1,0xa2,0x75,0xa9,
2279
0x76,0xa9,0x77,0x69,0x76,0x69,0x77,0xb9,0xe1,0xd2,0xe7,0x72,0xcf,0xe5,0x81,0xcb,
2280
0x23,0x97,0x09,0x97,0xa7,0x2e,0x73,0x2e,0x8b,0x2e,0x2f,0x5d,0xc0,0x0e,0xbb,0x1d,
2281
0x84,0x1d,0xae,0x3b,0x3c,0x77,0xf8,0xee,0x78,0x77,0x47,0xe0,0x2f,0x84,0xee,0x88,
2282
0xdc,0x11,0xb7,0x23,0x79,0x47,0xc6,0x0e,0xe1,0x0e,0xd9,0x0e,0xed,0x8e,0x9a,0x1d,
2283
0xcd,0x3b,0x3a,0x77,0xf4,0xed,0xb8,0xbf,0xe3,0xd1,0x8e,0x27,0x3b,0xe6,0x76,0xbc,
2284
0xd8,0x01,0x76,0xda,0xef,0x74,0xdd,0xe9,0xbd,0x93,0xbc,0x33,0x78,0x67,0xe4,0xce,
2285
0xb8,0x9d,0xc9,0x3b,0xd3,0x76,0x72,0x77,0x0a,0x77,0x16,0xed,0x54,0xed,0xac,0xde,
2286
0xd9,0xb8,0xb3,0x7d,0x67,0xef,0xce,0x7b,0x3b,0x1f,0xee,0x9c,0xd8,0x39,0xb3,0x73,
2287
0x71,0xe7,0xcb,0x9d,0xc0,0xd5,0xce,0x95,0xe0,0xea,0xea,0xea,0xe9,0xea,0xe3,0x4a,
2288
0x76,0x0d,0x76,0x8d,0x74,0x4d,0x72,0x4d,0x73,0xe5,0xbb,0x16,0xb9,0xaa,0x5c,0xab,
2289
0x5d,0x1b,0x5d,0xdb,0x5d,0x7b,0x5d,0xef,0xb9,0x3e,0x74,0x9d,0x70,0x9d,0x71,0x5d,
2290
0x74,0x7d,0xe5,0x6a,0xe7,0xe6,0xec,0xe6,0xe9,0xe6,0xe3,0x46,0x76,0x0b,0x74,0x0b,
2291
0x75,0x63,0xba,0x25,0xbb,0x65,0xb8,0x09,0xdd,0x64,0x6e,0x5a,0xb7,0x1a,0xb7,0x66,
2292
0xb7,0x4e,0xb7,0x3e,0xb7,0x7b,0x6e,0x0f,0xdc,0x1e,0xb9,0x4d,0xb8,0x3d,0x75,0x9b,
2293
0x73,0x5b,0x74,0x7b,0xf9,0x3b,0x80,0x5d,0x76,0xbb,0x9c,0x77,0x79,0xee,0xf2,0xdb,
2294
0x15,0xb8,0x2b,0x7c,0x57,0xdc,0xae,0xe4,0x5d,0x69,0xbb,0xf8,0xbb,0x8a,0x76,0xa9,
2295
0x76,0x55,0xef,0x6a,0xdc,0xd5,0xbe,0xeb,0xc6,0xae,0xbe,0x5d,0xf7,0x77,0x3d,0xda,
2296
0xf5,0x64,0xd7,0x9c,0x95,0xc5,0x5d,0x2f,0x77,0xd9,0xec,0x26,0xec,0x76,0xdf,0xed,
2297
0x63,0x85,0xbc,0x3b,0x70,0x77,0xf8,0xee,0xb8,0xdd,0x29,0xbb,0xb9,0xbb,0xc5,0xbb,
2298
0x15,0xbb,0xb5,0xbb,0xab,0x77,0x37,0xee,0x6e,0xdf,0xdd,0xbb,0xfb,0xde,0xee,0x87,
2299
0xbb,0x27,0x76,0x3f,0xdd,0x3d,0xb7,0xfb,0xc5,0x6e,0xe0,0x6e,0xef,0xee,0xea,0xee,
2300
0xed,0x4e,0x76,0x0f,0x74,0x0f,0x75,0x67,0xba,0x27,0xbb,0x67,0xb8,0x0b,0xdd,0x65,
2301
0xee,0x5a,0xf7,0x6a,0xf7,0x7a,0xf7,0x56,0xf7,0x1b,0xee,0x03,0xee,0x0f,0xac,0x3c,
2302
0x72,0x9f,0x70,0x9f,0x71,0x5f,0x74,0x7f,0xe5,0x6e,0xe7,0x81,0x20,0x78,0xb8,0x7a,
2303
0x78,0x7b,0x90,0x3d,0x82,0x3d,0x22,0x3d,0x92,0x3c,0xd2,0x20,0x5c,0x88,0x18,0xa2,
2304
0x80,0x18,0x3c,0x6a,0x3c,0x1a,0x3d,0xda,0x3d,0x7a,0x3d,0xee,0x79,0x3c,0xf4,0x98,
2305
0xf0,0x98,0xf1,0x78,0xee,0xf1,0xc2,0x03,0xec,0xb1,0xdf,0xe3,0xba,0xc7,0x7b,0x0f,
2306
0x79,0x4f,0xf0,0x9e,0xf0,0x3d,0xcc,0x3d,0x49,0x7b,0x52,0xf6,0x64,0xec,0xe1,0xef,
2307
0x11,0xef,0x91,0xed,0x51,0xed,0x31,0xec,0xa9,0xd9,0xd3,0xb8,0xa7,0x75,0x4f,0xa7,
2308
0x95,0xbe,0x3d,0xf7,0xf7,0x3c,0xde,0x33,0xb3,0xe7,0xc5,0x1e,0x9b,0xb7,0x9d,0xdf,
2309
0xf6,0x7e,0x9b,0xfc,0x76,0xf0,0xdb,0xcc,0xb7,0x53,0xde,0xe6,0xbf,0x2d,0x7b,0xdb,
2310
0xf0,0x76,0xe3,0xdb,0xed,0x6f,0xf7,0xbe,0x7d,0xff,0xed,0xc7,0x6f,0xcf,0xbc,0xfd,
2311
0xe2,0x6d,0x1b,0x4f,0x67,0x4f,0x4f,0x4f,0x3f,0xcf,0x60,0x4f,0xa6,0x67,0x8a,0x27,
2312
0xdf,0x53,0xe6,0x69,0xf0,0xac,0xf7,0x6c,0xf5,0xec,0xf5,0xbc,0xef,0xf9,0xd8,0x73,
2313
0xc6,0xf3,0x85,0xa7,0x8d,0x17,0xc1,0xcb,0xdd,0xcb,0xcf,0x2b,0xd8,0x8b,0xe9,0x95,
2314
0xe2,0xc5,0xf7,0x92,0x79,0xa9,0xbc,0x0c,0x5e,0xf5,0x5e,0xcd,0x5e,0x9d,0x90,0x5e,
2315
0xaf,0x7b,0x5e,0x0f,0xbc,0x1e,0x79,0x4d,0x78,0x3d,0xf5,0x9a,0xf7,0x5a,0xf4,0x5a,
2316
0xf6,0x5a,0xf5,0xda,0xb4,0xd7,0x7e,0xaf,0xeb,0x5e,0xcf,0xbd,0x7e,0x10,0xea,0xde,
2317
0xd0,0xbd,0x91,0x7b,0xe3,0xf6,0x26,0xef,0x4d,0xdb,0x9b,0xbd,0x37,0x6f,0x6f,0xf1,
2318
0x5e,0xc5,0x5e,0xed,0xde,0xea,0xbd,0x8d,0x7b,0xdb,0xad,0xdc,0xd8,0x3b,0xb0,0xf7,
2319
0xfe,0xde,0x87,0x7b,0x1f,0xef,0x7d,0xb2,0xf7,0xff,0xd9,0x3b,0xbb,0xf7,0xff,0xdd,
2320
0xfb,0x62,0xef,0xab,0xbd,0x36,0xfb,0x08,0xfb,0xdc,0xf7,0x79,0xef,0xf3,0xdb,0x47,
2321
0xdd,0x17,0xba,0x2f,0x72,0x5f,0xdc,0xbe,0xe4,0x7d,0x69,0xfb,0xb2,0xf7,0xe5,0xed,
2322
0x2b,0xda,0x27,0xb3,0xa2,0xdd,0x57,0xbd,0xaf,0x11,0xd2,0xba,0xef,0xc6,0xbe,0xbe,
2323
0x7d,0xf7,0xf6,0x3d,0xd8,0xf7,0x68,0xdf,0x8f,0xfb,0xa6,0xf6,0xcd,0xec,0x9b,0x85,
2324
0xfc,0xf7,0xbe,0x85,0x7d,0x4b,0xfb,0x96,0xf7,0xad,0xec,0x5b,0xdd,0x87,0xf3,0xb6,
2325
0xf5,0xc6,0x7b,0x3b,0x78,0x13,0xde,0xc0,0xc9,0xdb,0xf9,0x17,0x5c,0xbc,0xdd,0xff,
2326
0x00,0x1e,0xde,0x5e,0xde,0xbe,0xde,0xd4,0xdf,0x81,0xe6,0x1d,0x68,0x85,0xee,0x1d,
2327
0xe6,0xcd,0xf4,0x66,0x79,0xb3,0xbd,0xd3,0x30,0xd2,0xbd,0xb9,0xde,0x3c,0x6f,0xe1,
2328
0xef,0x20,0xf2,0x96,0x7a,0x2b,0xbd,0xb5,0x7f,0x10,0x9d,0x77,0xfd,0x6f,0xd1,0xe0,
2329
0xdd,0xf8,0x47,0x68,0xf2,0x6e,0xf1,0x6e,0x85,0xb4,0x79,0x77,0x78,0x77,0x79,0x77,
2330
0x7b,0x9b,0xbd,0xfb,0xbd,0x07,0xbd,0x87,0xbc,0x87,0xbd,0x47,0xbc,0x47,0xbd,0xc7,
2331
0xbc,0xc7,0xbd,0x27,0xbd,0xa7,0xbc,0xa7,0xbd,0x2d,0xde,0xf3,0xde,0x0b,0xde,0x4b,
2332
0xde,0xcb,0xde,0x2b,0xde,0xab,0xde,0x38,0xa2,0x2d,0x11,0x4f,0x74,0x20,0x12,0x88,
2333
0x4e,0x44,0x17,0xa2,0x1b,0xd1,0x83,0xe8,0x45,0x24,0x12,0x7d,0x89,0x24,0x22,0x85,
2334
0x48,0x23,0xd2,0x89,0x21,0xc4,0x30,0x62,0xf8,0xef,0x25,0x82,0xc8,0xfc,0xa7,0x82,
2335
0x05,0xe1,0x10,0x33,0x89,0x3c,0xa2,0x90,0x28,0x22,0xca,0x89,0x3a,0xa2,0x81,0x68,
2336
0x24,0xd6,0x12,0x1b,0x88,0x4d,0xc4,0x16,0x62,0x1b,0xb1,0x83,0xd8,0x45,0xec,0x26,
2337
0x9a,0x89,0xfd,0xc4,0x01,0xe2,0x20,0x71,0x88,0xf8,0x00,0x32,0x42,0x1c,0x25,0x8e,
2338
0x11,0xc7,0x89,0x93,0xc4,0x27,0x90,0x29,0xa2,0x85,0xb8,0x44,0x7c,0x49,0x5c,0x21,
2339
0xbe,0x82,0x80,0xfd,0xb8,0xfd,0x36,0x10,0xbb,0xfd,0x4e,0xfb,0x5d,0xf6,0xbb,0xee,
2340
0x77,0xdb,0xef,0xb1,0xdf,0x6b,0xbf,0xf7,0x7e,0xe2,0x7e,0xdf,0xfd,0xa4,0xfd,0x94,
2341
0xfd,0xb4,0xfd,0xf4,0xfd,0x21,0xfb,0x43,0xf7,0x87,0xed,0x67,0xed,0x8f,0xdf,0xcf,
2342
0xde,0xcf,0xd9,0x9f,0xba,0x3f,0x0d,0x23,0x7d,0x7f,0xe6,0x7e,0xde,0x7e,0xc1,0x7e,
2343
0xd1,0x7e,0xf1,0x1b,0x48,0xf6,0x2b,0xf7,0x1b,0xf7,0x37,0xed,0xef,0xd8,0x6f,0xde,
2344
0x3f,0xb4,0x7f,0x74,0xff,0xe4,0x7e,0xcb,0xfe,0xa5,0xfd,0xab,0xfb,0xf1,0x07,0x5c,
2345
0x0e,0x78,0x1d,0x20,0x1d,0xa0,0x1d,0xa0,0x1f,0x08,0x3b,0xc0,0x3a,0xc0,0x3e,0xc0,
2346
0x39,0x90,0x7e,0x40,0x70,0x40,0x7e,0x40,0x7d,0x40,0x77,0xc0,0x74,0xa0,0xe9,0x40,
2347
0xcb,0x81,0xb6,0x03,0x1d,0x07,0xba,0x0e,0x74,0x1f,0xe8,0x3f,0x30,0x7c,0x60,0xf4,
2348
0xc0,0xd8,0x81,0xc9,0x03,0x96,0x03,0xcb,0x07,0x56,0x0f,0xe0,0x7c,0xf0,0x3e,0x2e,
2349
0x3e,0x6e,0x3e,0x1e,0x3e,0x5e,0x3e,0xde,0xff,0x07,0x44,0x1f,0xf2,0x1f,0x25,0xd0,
2350
0x27,0xf4,0x4f,0x22,0xf2,0xaf,0x22,0xce,0x27,0xd9,0x27,0xed,0xef,0x08,0xf7,0x17,
2351
0x84,0x56,0x8a,0xfe,0x4c,0x14,0x10,0xed,0x2f,0xe8,0x7c,0x4c,0x3e,0x8d,0x3e,0x4d,
2352
0x3e,0x6d,0x3e,0x37,0xfe,0x28,0x7d,0x56,0xee,0x59,0x79,0x00,0x79,0xf4,0x67,0x31,
2353
0x01,0x79,0xfa,0x7b,0x99,0xf3,0x59,0xf4,0x79,0xe9,0x03,0x7c,0xed,0xac,0x10,0x7c,
2354
0x5d,0xad,0x78,0xfa,0xfa,0xfc,0x16,0x64,0xdf,0x40,0x2b,0xa1,0xbe,0x91,0x56,0xe2,
2355
0x7c,0x93,0x7f,0x15,0xd2,0x7c,0xb9,0xbe,0x42,0xdf,0xa2,0xbf,0x39,0x0a,0x5f,0xad,
2356
0x6f,0xb5,0x6f,0xfd,0x6f,0xd1,0xec,0xdb,0xee,0x7b,0xc3,0xb7,0xef,0xff,0x1a,0x03,
2357
0xbe,0xf7,0xd6,0x59,0xe7,0xef,0xc4,0x90,0xef,0xb0,0xef,0x88,0xef,0xa8,0xef,0x98,
2358
0xef,0xb8,0xef,0xa4,0xef,0x94,0xef,0xb4,0xaf,0xc5,0x77,0xc1,0x77,0xd9,0x77,0xd5,
2359
0xd7,0xf6,0xa0,0xc3,0x41,0x97,0x83,0x1e,0x07,0x89,0x07,0x49,0x07,0x69,0x07,0x43,
2360
0x0e,0x32,0x0e,0xb2,0x0f,0xa6,0x1f,0x14,0x1c,0x94,0x1e,0x54,0x1f,0x34,0x1d,0x6c,
2361
0x3a,0xd8,0x71,0xb0,0xff,0xe0,0xc8,0xc1,0xc9,0x83,0xf3,0x07,0x57,0x0e,0xe2,0xdf,
2362
0x71,0x7b,0xc7,0xf7,0x1d,0xfa,0x3b,0x8c,0x77,0x38,0xef,0xa4,0xbf,0xc3,0x7b,0x47,
2363
0xf4,0x8e,0xf4,0x1d,0xe5,0x3b,0xba,0x77,0x4c,0xef,0x34,0xbc,0xd3,0xf2,0x4e,0xd7,
2364
0x3b,0xfd,0xef,0x0c,0xbf,0x33,0xf6,0xce,0xd4,0x3b,0xf3,0xef,0x2c,0xbf,0x83,0xf3,
2365
0x73,0xf0,0x73,0xf3,0x23,0xfa,0x51,0xfc,0x42,0xfc,0x18,0x7e,0x6c,0xbf,0x74,0x3f,
2366
0x81,0x9f,0xd4,0x4f,0xed,0x67,0xf2,0x6b,0xf2,0xeb,0xf0,0x33,0xfb,0x0d,0xf9,0x8d,
2367
0xfa,0x4d,0xfa,0x59,0xfc,0x96,0xfc,0x56,0xfd,0xf0,0x24,0x17,0x92,0x17,0x89,0x44,
2368
0xa2,0x93,0x22,0x48,0xf1,0xa4,0x54,0x52,0x3a,0x29,0x93,0xc4,0x23,0x09,0x48,0x22,
2369
0x92,0x84,0x24,0x25,0xc9,0x49,0x4a,0x92,0x9a,0xa4,0x23,0x19,0x49,0x26,0x52,0x2d,
2370
0xa9,0x81,0xd4,0x44,0x6a,0x21,0xb5,0x91,0x3a,0x48,0x5d,0xa4,0x6e,0x92,0x99,0xd4,
2371
0x4f,0x1a,0x24,0x0d,0x91,0x86,0x49,0x23,0xa4,0x51,0xd2,0x18,0x69,0x9c,0x34,0x49,
2372
0x9a,0x22,0x4d,0x93,0x2c,0xa4,0x79,0xd2,0x02,0x69,0x89,0xb4,0x4c,0x5a,0x21,0xad,
2373
0x92,0x70,0xfe,0xb6,0xfe,0x78,0x7f,0x07,0x7f,0x27,0x7f,0x17,0x7f,0x37,0x7f,0x0f,
2374
0x7f,0x2f,0x7f,0xa2,0xbf,0xaf,0x3f,0xc9,0x9f,0xfc,0x2b,0x40,0xf1,0x0f,0xfd,0x97,
2375
0x22,0xcc,0x9f,0xe5,0xcf,0xf6,0x4f,0xfb,0x17,0x82,0xbb,0xce,0x5f,0x05,0xcf,0x5f,
2376
0xe0,0x2f,0x5c,0xe7,0x5f,0x1e,0x91,0xbf,0x78,0x9d,0x75,0xfe,0x86,0x48,0xfc,0x8b,
2377
0xfe,0x29,0x90,0xfa,0xcb,0xfe,0x00,0x72,0x88,0xd2,0x5f,0xed,0xaf,0xf3,0x37,0xfa,
2378
0x9b,0xfc,0x6b,0xfd,0x1b,0xfc,0x9b,0xfc,0x5b,0xfc,0xdb,0xfc,0x3b,0xfc,0xbb,0xfc,
2379
0xbb,0xfd,0xcd,0xfe,0xfd,0xfe,0x83,0xfe,0x43,0xfe,0xc3,0xfe,0x23,0xfe,0xa3,0xfe,
2380
0x63,0xfe,0xe3,0xfe,0x93,0xfe,0x53,0xfe,0xd3,0xfe,0x16,0xff,0x79,0xff,0x05,0xff,
2381
0x25,0xff,0x65,0xff,0x15,0xff,0x55,0x7f,0x5c,0x80,0x6d,0x00,0x3e,0xc0,0x21,0xc0,
2382
0x29,0xc0,0x25,0xc0,0x2d,0xc0,0x23,0xc0,0x2b,0x80,0x18,0xe0,0x1b,0x40,0x0a,0xa0,
2383
0x04,0xd0,0x02,0xe8,0x01,0x21,0x01,0x61,0x01,0x11,0x01,0x8c,0x00,0x56,0x40,0x7c,
2384
0x00,0x3b,0x80,0x13,0x90,0x1a,0x90,0x1e,0x90,0x19,0xc0,0x0b,0x10,0x04,0x88,0x02,
2385
0x24,0x01,0xd2,0x00,0x79,0x80,0x32,0x40,0x1d,0xa0,0x0b,0x30,0x06,0x98,0x02,0x6a,
2386
0x03,0x1a,0x02,0x9a,0x02,0x5a,0x02,0xda,0x02,0x3a,0x02,0xba,0x02,0xba,0x03,0xcc,
2387
0x01,0xfd,0x01,0x83,0x01,0x43,0x01,0xc3,0x01,0x23,0x01,0xa3,0x01,0x63,0x01,0xe3,
2388
0x01,0x93,0x01,0x53,0x01,0xd3,0x01,0x96,0x80,0xf9,0x80,0x85,0x80,0xa5,0x80,0xe5,
2389
0x80,0x95,0x80,0xd5,0x00,0x1c,0xd9,0x96,0x8c,0x27,0x3b,0x90,0x9d,0xc8,0x2e,0x64,
2390
0x37,0xb2,0x07,0xd9,0x8b,0x4c,0x24,0xfb,0x92,0x49,0x64,0x0a,0x99,0x46,0xa6,0x93,
2391
0x43,0xc8,0x61,0xe4,0x08,0x32,0x83,0xcc,0x22,0xc7,0x93,0xd9,0x64,0x0e,0x39,0x95,
2392
0x9c,0x4e,0xce,0x24,0xf3,0xc8,0x02,0xb2,0x88,0x2c,0x21,0x4b,0xc9,0x72,0xb2,0x92,
2393
0xac,0x26,0xeb,0xc8,0x46,0xb2,0x89,0x5c,0x4b,0x6e,0x20,0x37,0x91,0x5b,0xc8,0x6d,
2394
0xe4,0x0e,0x72,0x17,0xb9,0x9b,0x6c,0x26,0xf7,0x93,0x07,0xc9,0x43,0xe4,0x61,0xf2,
2395
0x08,0x79,0x94,0x3c,0x46,0x1e,0x27,0x4f,0x92,0xa7,0xc8,0xd3,0x64,0x0b,0x79,0x9e,
2396
0xbc,0x40,0x5e,0x22,0x2f,0x93,0x57,0xc8,0xab,0x64,0x1c,0xc5,0x96,0x82,0xa7,0x38,
2397
0x50,0x9c,0x28,0x2e,0x14,0x37,0x8a,0x07,0xc5,0x8b,0x42,0xa4,0xf8,0x52,0x48,0x14,
2398
0x0a,0x85,0x46,0xa1,0x53,0x42,0x28,0x61,0x94,0x08,0x0a,0x83,0xc2,0xa2,0xc4,0x53,
2399
0xd8,0x14,0x0e,0x25,0x95,0x92,0x4e,0xc9,0xa4,0xf0,0x28,0x02,0x8a,0x88,0x22,0xa1,
2400
0x48,0x29,0x72,0x8a,0x92,0xa2,0xa6,0xe8,0x28,0x46,0x8a,0x89,0x52,0x4b,0x69,0xa0,
2401
0x34,0x51,0x5a,0x28,0x6d,0x94,0x0e,0x4a,0x17,0xa5,0x9b,0x62,0xa6,0xf4,0x53,0x06,
2402
0x29,0x43,0x94,0x61,0xca,0x08,0x65,0x94,0x32,0x46,0x79,0xfc,0x37,0x60,0x1c,0x32,
2403
0xf1,0x77,0x63,0x92,0xf2,0x84,0x32,0x45,0x99,0xa6,0x58,0x28,0x73,0x7f,0x02,0x8b,
2404
0x90,0x97,0x10,0xf0,0x2e,0x78,0xd7,0x0e,0x42,0x80,0xb8,0x42,0x3c,0x21,0x3e,0x10,
2405
0x32,0x24,0x10,0x12,0x0a,0x89,0xb4,0x12,0x07,0x49,0x86,0xa4,0xfd,0x16,0xdc,0x77,
2406
0x85,0x90,0xa2,0x77,0x15,0x10,0xed,0xbb,0xd5,0x90,0xfa,0x77,0x9b,0x21,0xed,0xef,
2407
0xde,0xf8,0xb3,0xe8,0x7b,0x83,0xfe,0x77,0x87,0xde,0x7d,0x00,0x19,0x7b,0x77,0xe2,
2408
0x0f,0xf2,0x14,0x32,0x07,0x59,0x84,0xbc,0x84,0x80,0x43,0xe0,0x90,0x1d,0x84,0x00,
2409
0x71,0x85,0x78,0x42,0x7c,0x20,0x64,0x48,0xa0,0x95,0x50,0x48,0x24,0x24,0xee,0xb7,
2410
0x48,0x3e,0x94,0x06,0xe1,0x1e,0x12,0x42,0x8a,0x0e,0x29,0x20,0xda,0x43,0xd5,0x90,
2411
0xfa,0x43,0xcd,0x7f,0x16,0xed,0x56,0x6e,0x1c,0xea,0x3b,0x74,0xef,0xd0,0x03,0x8c,
2412
0xb1,0x43,0x13,0x7f,0x07,0x26,0x0f,0x4d,0x1d,0x9a,0x3e,0x64,0x39,0x34,0x7f,0x68,
2413
0xe1,0xd0,0xd2,0xa1,0xe5,0x43,0x2b,0x87,0x56,0x0f,0xe1,0xa8,0xb6,0x54,0x3c,0xd5,
2414
0x81,0xea,0x44,0x75,0xa1,0xba,0x51,0x3d,0xa8,0x5e,0x54,0x22,0xd5,0x97,0x4a,0xa2,
2415
0x52,0xa8,0x34,0x2a,0x9d,0x1a,0x42,0x0d,0xa3,0x46,0x50,0x19,0x54,0x16,0x35,0x9e,
2416
0xca,0xa6,0x72,0xa8,0xa9,0xd4,0x74,0x6a,0x26,0x95,0x47,0x15,0x50,0x45,0x54,0x09,
2417
0x55,0x4a,0x95,0x53,0x95,0x54,0x35,0x55,0x47,0x35,0x52,0x4d,0xd4,0x5a,0x6a,0x03,
2418
0xb5,0x89,0xda,0x42,0x6d,0xa3,0x76,0x50,0xbb,0xa8,0xdd,0x54,0x33,0xb5,0x9f,0x3a,
2419
0x48,0x1d,0xa2,0x0e,0x53,0x47,0xa8,0xa3,0xd4,0x31,0xea,0x38,0x75,0x92,0x3a,0x45,
2420
0x9d,0xa6,0x5a,0xa8,0xf3,0xd4,0x05,0xea,0x12,0x75,0x99,0xba,0x42,0x5d,0xa5,0xe2,
2421
0x68,0xb6,0x34,0x3c,0xcd,0x81,0xe6,0x44,0x73,0xa1,0xb9,0xd1,0x3c,0x68,0x5e,0x34,
2422
0x22,0xcd,0x97,0x46,0xa2,0x51,0x68,0x34,0x1a,0x9d,0x16,0x42,0x0b,0xa3,0x45,0xd0,
2423
0x18,0x34,0x16,0x2d,0xce,0x4a,0x3c,0x8d,0x4d,0xe3,0xd0,0x52,0x69,0xe9,0xb4,0x4c,
2424
0x1a,0x8f,0x26,0xa0,0x89,0x68,0x12,0x9a,0x94,0x26,0xa7,0x29,0x69,0x6a,0x9a,0xf6,
2425
0x9f,0x1c,0x1d,0xa4,0x96,0xd6,0x42,0xeb,0xa2,0xf5,0xd3,0x86,0x69,0x63,0xb4,0x29,
2426
0xda,0x3c,0x6d,0x99,0x86,0x7b,0xcf,0xe1,0x3d,0xb7,0xf7,0x88,0xef,0x51,0xde,0x0b,
2427
0x7b,0x2f,0xfe,0xbd,0xf4,0xf7,0x44,0xef,0x29,0xdf,0x33,0xbd,0xd7,0xf2,0x5e,0xf7,
2428
0x7b,0x43,0xef,0x8d,0xbd,0x37,0xfd,0xde,0xd2,0x7b,0xb8,0xf7,0x9d,0xde,0xf7,0x7a,
2429
0x3f,0xe4,0xfd,0xa4,0xf7,0xd9,0xef,0xa7,0xbf,0x2f,0x78,0x5f,0xfa,0xbe,0xfa,0x7d,
2430
0xd3,0xfb,0x4d,0xef,0x77,0xbc,0x6f,0x7e,0x7f,0xe8,0xfd,0xd1,0xf7,0x27,0xdf,0xb7,
2431
0xbc,0xbf,0xf4,0xfe,0xea,0xfb,0xf8,0x40,0x97,0x40,0xaf,0x40,0x52,0x20,0x3d,0x30,
2432
0x22,0x30,0x3e,0x30,0x35,0x90,0x17,0x28,0x09,0x54,0x06,0x1a,0x03,0x1b,0x02,0xdb,
2433
0x02,0xbb,0x03,0x07,0x03,0x47,0x02,0xc7,0x03,0xa7,0x03,0x17,0x02,0x57,0x02,0x6d,
2434
0xe9,0x78,0xba,0x03,0xdd,0x89,0xee,0xfc,0x3b,0xb8,0xd0,0xbd,0xe8,0xbe,0x74,0x0a,
2435
0x9d,0x4e,0x0f,0xa3,0x33,0xe8,0xf1,0x74,0x0e,0x3d,0x9d,0xce,0xa3,0x8b,0xe8,0x52,
2436
0xba,0x92,0xae,0xa3,0x9b,0xe8,0x0d,0xf4,0x26,0x7a,0x0b,0xbd,0x8d,0xde,0x41,0xef,
2437
0xa2,0x77,0xd3,0xcd,0xf4,0x7e,0xfa,0x20,0x7d,0x88,0x3e,0x4c,0x1f,0xa1,0x8f,0xd2,
2438
0xc7,0xe8,0x93,0xf4,0x69,0xfa,0x3c,0x7d,0x89,0xbe,0x42,0xc7,0x05,0xe1,0x83,0x9c,
2439
0x82,0xdc,0x82,0xbc,0x82,0x7c,0x83,0x28,0x41,0xf4,0xa0,0xb0,0x20,0x76,0x50,0x66,
2440
0x10,0x3f,0x48,0x10,0x24,0x0a,0x92,0x04,0x49,0x83,0xe4,0x41,0xca,0x20,0x75,0x90,
2441
0x2e,0xc8,0x18,0x64,0x0a,0xaa,0x0d,0x6a,0x08,0x6a,0x0a,0x6a,0x09,0x6a,0x0b,0xea,
2442
0x08,0xea,0x0a,0xea,0x0e,0x32,0x07,0xf5,0x07,0x0d,0x06,0x0d,0x05,0x0d,0x07,0x8d,
2443
0x04,0x8d,0x06,0x8d,0x05,0x8d,0x07,0x4d,0x06,0x4d,0x05,0x4d,0x07,0x59,0x82,0xe6,
2444
0x83,0x16,0x82,0x96,0x82,0x96,0x83,0x56,0x82,0x56,0x83,0x70,0x87,0x6d,0x0f,0xe3,
2445
0x0f,0x3b,0x1c,0x76,0x3a,0xec,0x72,0xd8,0xed,0xb0,0xc7,0x61,0xaf,0xc3,0xc4,0xc3,
2446
0xbe,0x87,0x49,0x87,0x29,0x87,0xe9,0x87,0xc3,0x0e,0x33,0x0e,0xc7,0x1f,0xe6,0x1c,
2447
0x4e,0x3f,0xcc,0x3b,0x2c,0x3a,0x2c,0x3d,0xac,0x3c,0xac,0x3b,0x6c,0x3a,0xdc,0x70,
2448
0xb8,0xe5,0x70,0xc7,0xe1,0xee,0xc3,0xfd,0x87,0x87,0x0e,0x8f,0x1c,0x1e,0x3b,0x3c,
2449
0x79,0x78,0xfa,0xf0,0xfc,0xe1,0xa5,0xc3,0xab,0x87,0xf1,0xc1,0x2e,0xc1,0x1e,0xc1,
2450
0xbe,0xc1,0x94,0xe0,0x90,0xe0,0xb0,0xe0,0x88,0x60,0x46,0x30,0x2b,0x38,0x3e,0x98,
2451
0x1d,0xcc,0x09,0x4e,0x0d,0x4e,0x0f,0xce,0x0c,0xe6,0x05,0x0b,0x82,0x45,0xc1,0x92,
2452
0x60,0x69,0xb0,0x3c,0x58,0x19,0xac,0x0e,0xd6,0x05,0x1b,0x83,0x4d,0xc1,0xb5,0xc1,
2453
0x0d,0xc1,0x4d,0xc1,0x2d,0xc1,0x6d,0xc1,0x1d,0xc1,0x5d,0xc1,0xdd,0xc1,0xe6,0xe0,
2454
0xfe,0xe0,0xc1,0xe0,0xa1,0xe0,0xe1,0xe0,0x91,0xe0,0xd1,0xe0,0xb1,0xe0,0xf1,0xe0,
2455
0xc9,0xe0,0xa9,0xe0,0xe9,0x60,0x4b,0xf0,0x7c,0xf0,0x42,0xf0,0x52,0xf0,0x72,0xf0,
2456
0x4a,0x30,0x2e,0x04,0x17,0xe2,0x12,0x42,0x0c,0xa1,0x87,0x44,0x84,0x70,0x42,0x32,
2457
0x43,0x44,0x21,0xba,0x90,0x86,0x90,0xb6,0x90,0xee,0x90,0xc1,0x90,0xd1,0x90,0xa9,
2458
0x90,0x85,0x90,0xd5,0x10,0x87,0x0f,0x3c,0x3e,0x20,0x7d,0x10,0xf1,0x01,0xeb,0x83,
2459
0xcc,0x0f,0xe4,0x1f,0x98,0x3e,0x68,0xf9,0xa0,0xff,0x83,0xb1,0x0f,0xa6,0x3f,0x58,
2460
0xf8,0x60,0xe5,0x03,0xfc,0x87,0x6e,0x1f,0x92,0x3e,0x0c,0xfb,0x90,0xf5,0x21,0xe7,
2461
0x43,0xde,0x87,0x92,0x0f,0x95,0x1f,0xea,0x3e,0x34,0x7d,0xd8,0xf4,0x61,0xc7,0x87,
2462
0x43,0x1f,0x8e,0x7d,0x68,0xf9,0x70,0xf5,0x43,0x87,0x50,0xb7,0x50,0x62,0x68,0x48,
2463
0x28,0x2b,0x34,0x33,0x54,0x14,0xaa,0x0e,0x35,0x85,0xb6,0x84,0x76,0x85,0x0e,0x86,
2464
0x8e,0x85,0x4e,0x87,0x2e,0x87,0xda,0x86,0x39,0x84,0x79,0x85,0x91,0xc2,0xe8,0x61,
2465
0x8c,0x30,0x76,0x58,0x7a,0x98,0x20,0x4c,0x19,0x66,0x0a,0x6b,0x08,0xeb,0x0e,0x1b,
2466
0x0c,0x1b,0x0b,0x9b,0x0e,0x5b,0x0a,0x5b,0x0d,0xc3,0x1f,0x71,0x3b,0xe2,0x75,0x84,
2467
0x72,0x24,0xe2,0x08,0xeb,0x48,0xe6,0x11,0xd1,0x11,0xe9,0x11,0xe5,0x11,0xdd,0x11,
2468
0xd3,0x91,0x86,0x23,0x2d,0x47,0x3a,0x8e,0x74,0x1f,0xe9,0x3f,0x32,0x74,0x64,0xf4,
2469
0xc8,0xe4,0x11,0xcb,0x91,0xa5,0x23,0xab,0x47,0xf0,0x47,0x5d,0x8e,0x7a,0x1d,0x25,
2470
0x1d,0xa5,0x1f,0x8d,0x38,0x1a,0x7f,0x34,0xf5,0x28,0xef,0xa8,0xe4,0xa8,0xf2,0xa8,
2471
0xee,0xa8,0xe9,0x68,0xd3,0xd1,0xb6,0xa3,0x5d,0x47,0xcd,0x47,0x87,0x8e,0x8e,0x1e,
2472
0x1d,0x3f,0x3a,0x75,0xd4,0x72,0x74,0xe1,0xe8,0xf2,0x51,0xdb,0x70,0x87,0x70,0x97,
2473
0x70,0x8f,0x70,0x62,0x38,0x29,0x9c,0x16,0x1e,0x12,0x1e,0x11,0x1e,0x1f,0x9e,0x1e,
2474
0xce,0x0b,0x17,0x85,0x4b,0xc3,0x95,0xe1,0xba,0x70,0x53,0x78,0x43,0x78,0x5b,0x78,
2475
0x77,0xf8,0x60,0xf8,0x48,0xf8,0x58,0xf8,0x64,0xf8,0x74,0xf8,0x7c,0xf8,0x52,0xf8,
2476
0x4a,0x38,0x2e,0x02,0x1f,0xe1,0x14,0xe1,0x16,0x41,0x8c,0xa0,0x44,0xd0,0x23,0x22,
2477
0x22,0xe2,0x23,0x52,0x23,0x32,0x23,0x44,0x11,0xf2,0x08,0x63,0x44,0x6d,0x44,0x4b,
2478
0x44,0x57,0x44,0x7f,0xc4,0x70,0xc4,0x64,0xc4,0x52,0xc4,0x4a,0x04,0xee,0x18,0xfe,
2479
0x98,0xd3,0x31,0xb7,0x63,0x5e,0xc7,0x7c,0x8f,0x51,0x8e,0xd1,0x8f,0x85,0x1d,0x63,
2480
0x1c,0x8b,0x3f,0xc6,0x39,0x96,0x7e,0x8c,0x77,0x4c,0x74,0x4c,0x7a,0x4c,0x79,0xcc,
2481
0x74,0xac,0xe1,0x58,0xcb,0xb1,0x8e,0x63,0xfd,0xc7,0x86,0x8f,0x8d,0x1e,0x1b,0x3f,
2482
0x36,0x75,0xcc,0x72,0x6c,0xe1,0xd8,0xf2,0xb1,0xd5,0x63,0xb6,0xc7,0x1d,0x8e,0xbb,
2483
0x1c,0xf7,0x3a,0xee,0x7b,0x9c,0x72,0x3c,0xe4,0x38,0xe3,0x78,0xfc,0xf1,0xf4,0xe3,
2484
0x82,0xe3,0x92,0xe3,0xf2,0xe3,0xea,0xe3,0xc6,0xe3,0x0d,0xc7,0xdb,0x8e,0x77,0x1d,
2485
0x37,0x1f,0x1f,0x3c,0x3e,0x7c,0x7c,0xf4,0xf8,0xf8,0xf1,0xa9,0xe3,0x96,0xe3,0x0b,
2486
0xc7,0x57,0x8e,0xdb,0x46,0x3a,0x45,0x7a,0x44,0xfa,0x46,0xd2,0x22,0xc3,0x22,0x59,
2487
0x91,0x9c,0xc8,0xcc,0x48,0x51,0xa4,0x3c,0x52,0x17,0x59,0x1b,0xd9,0x12,0xd9,0x15,
2488
0xd9,0x1f,0x39,0x1c,0x39,0x16,0x39,0x15,0x39,0x1f,0xb9,0x1c,0x09,0x18,0xeb,0xfc,
2489
0x65,0xe0,0x18,0xb6,0x0c,0xbb,0x75,0xfe,0x09,0xc0,0x33,0xec,0xff,0xed,0x71,0x60,
2490
0x38,0x31,0x5c,0x18,0xae,0x56,0xdc,0x18,0x1e,0x0c,0xcf,0x7f,0x09,0xbc,0x18,0x44,
2491
0x86,0x2f,0x83,0xc4,0x20,0xff,0x1f,0x50,0x18,0xd4,0x75,0xfe,0x2c,0x02,0x19,0xc1,
2492
0x8c,0x50,0x46,0x38,0x23,0x92,0xc1,0x64,0xc4,0x31,0x92,0x18,0xc9,0x8c,0x14,0x46,
2493
0x1a,0x23,0x83,0xc1,0x65,0xf0,0x19,0x42,0x86,0x98,0x51,0xc4,0x90,0x31,0x14,0x0c,
2494
0x15,0x43,0xcb,0x30,0x30,0xaa,0x19,0x35,0x8c,0x7a,0x46,0x23,0xa3,0x99,0xd1,0xca,
2495
0x68,0x67,0x74,0x32,0x6e,0x30,0x7a,0x19,0x7d,0x8c,0x01,0xc6,0x3d,0xc6,0x7d,0xc6,
2496
0x03,0xc6,0x43,0xc6,0x23,0xc6,0x63,0xc6,0x04,0xe3,0x09,0xe3,0x29,0x63,0x86,0x31,
2497
0xc7,0x78,0xce,0x58,0x64,0xbc,0x60,0xbc,0x64,0xbc,0x62,0x80,0x28,0x9b,0x28,0xbb,
2498
0x28,0xfb,0x28,0x42,0x94,0x73,0x94,0x6b,0x94,0x7b,0x94,0x67,0x94,0x77,0x94,0x4f,
2499
0x94,0x5f,0x14,0x39,0x8a,0x1a,0x15,0x18,0x15,0x1c,0x15,0x1a,0x15,0x1e,0x15,0x19,
2500
0xc5,0x8c,0x8a,0x8b,0x4a,0x8a,0x4a,0x8e,0x4a,0x89,0x4a,0x8b,0xca,0x88,0xe2,0x46,
2501
0xf1,0xa3,0x84,0x51,0xe2,0xa8,0xa2,0x28,0x59,0x94,0x22,0x4a,0x15,0xa5,0x8d,0x32,
2502
0x44,0x55,0x47,0xd5,0x44,0xd5,0x47,0x35,0x46,0x35,0x47,0xb5,0x46,0xb5,0x47,0x75,
2503
0x46,0xdd,0x88,0xea,0x8d,0xea,0x8b,0x1a,0x88,0xba,0x17,0x75,0x3f,0xea,0x41,0xd4,
2504
0xc3,0xa8,0x47,0x51,0x8f,0xa3,0x26,0xa2,0x9e,0x44,0x3d,0x8d,0x9a,0x89,0x9a,0x8b,
2505
0x7a,0x1e,0xb5,0x18,0xf5,0x22,0xea,0x65,0xd4,0xab,0x28,0x10,0x6d,0x13,0x6d,0x17,
2506
0x6d,0x1f,0x4d,0x88,0x76,0x8e,0x76,0x8d,0x76,0x8f,0xf6,0x8c,0xf6,0x8e,0xf6,0x89,
2507
0xf6,0x8b,0x26,0x47,0x53,0xa3,0x03,0xa3,0x83,0xa3,0x43,0xa3,0xc3,0xa3,0x23,0xa3,
2508
0x99,0xd1,0x71,0xd1,0x49,0xd1,0xc9,0xd1,0x29,0xd1,0x69,0xd1,0x19,0xd1,0xdc,0x68,
2509
0x7e,0xb4,0x30,0x5a,0x1c,0x5d,0x14,0x2d,0x8b,0x56,0x44,0xab,0xa2,0xb5,0xd1,0x86,
2510
0xe8,0xea,0xe8,0x9a,0xe8,0xfa,0xe8,0xc6,0xe8,0xe6,0xe8,0xd6,0xe8,0xf6,0xe8,0xce,
2511
0xe8,0x1b,0xd1,0xbd,0xd1,0x7d,0xd1,0x03,0xd1,0xf7,0xa2,0xef,0x47,0x3f,0x88,0x7e,
2512
0x18,0xfd,0x28,0xfa,0x71,0xf4,0x44,0xf4,0x93,0xe8,0xa7,0xd1,0x33,0xd1,0x73,0xd1,
2513
0xcf,0xa3,0x17,0xa3,0x5f,0x44,0xbf,0x8c,0x7e,0x15,0x0d,0x98,0x36,0x4c,0x3b,0xa6,
2514
0x3d,0x93,0xc0,0x74,0x66,0xba,0x32,0xdd,0x99,0x9e,0x4c,0x6f,0xa6,0x0f,0xd3,0x8f,
2515
0x49,0x66,0x52,0x99,0x81,0xcc,0x60,0x66,0x28,0x33,0x9c,0x19,0xc9,0x64,0x32,0xe3,
2516
0x98,0x49,0xcc,0x64,0x66,0x0a,0x33,0x8d,0x99,0xc1,0xe4,0x32,0xf9,0x4c,0x21,0x53,
2517
0xcc,0x2c,0x62,0xca,0x98,0x0a,0xa6,0x8a,0xa9,0x65,0x1a,0x98,0xd5,0xcc,0x1a,0x66,
2518
0x3d,0xb3,0x91,0xd9,0xcc,0x6c,0x65,0xb6,0x33,0x3b,0x99,0x37,0x98,0xbd,0xcc,0x3e,
2519
0xe6,0x00,0xf3,0x1e,0xf3,0x3e,0xf3,0x01,0xf3,0x21,0xf3,0x11,0xf3,0x31,0x73,0x82,
2520
0xf9,0x84,0xf9,0x94,0x39,0xc3,0x9c,0x63,0x3e,0x67,0x2e,0x32,0x5f,0x30,0x5f,0x32,
2521
0x5f,0x31,0x01,0xcb,0x86,0x65,0xc7,0xb2,0x67,0x11,0x58,0xce,0x2c,0x57,0x96,0x3b,
2522
0xcb,0x93,0xe5,0xcd,0xf2,0x61,0xf9,0xb1,0xc8,0x2c,0xf8,0x85,0x8b,0x15,0xc8,0x0a,
2523
0x66,0x85,0xb2,0xc2,0x59,0x91,0x2c,0x26,0x2b,0x8e,0x95,0xc4,0x4a,0x66,0xa5,0xb0,
2524
0xd2,0x58,0x19,0x2c,0x2e,0x8b,0x6f,0x45,0x08,0x11,0x5b,0x29,0x62,0xc9,0x58,0x0a,
2525
0x96,0x8a,0xa5,0x65,0x19,0x58,0xd5,0xac,0x1a,0x56,0x3d,0xab,0x11,0xd2,0x0c,0x69,
2526
0xb5,0xd2,0xce,0xea,0xc4,0xb8,0xc1,0xea,0x65,0xf5,0xb1,0x06,0x58,0xf7,0x58,0xf7,
2527
0x59,0x0f,0x58,0x0f,0x59,0x8f,0x58,0x8f,0x59,0x13,0xac,0x27,0xac,0xa7,0xac,0x19,
2528
0xd6,0x1c,0xeb,0x39,0x6b,0x91,0xf5,0x82,0xf5,0x92,0xf5,0x8a,0x05,0x62,0x6c,0x62,
2529
0xec,0x62,0xec,0x63,0x08,0x31,0xce,0x31,0xae,0x31,0xee,0x31,0x9e,0x31,0xde,0x31,
2530
0x3e,0x31,0x7e,0x31,0xe4,0x18,0x6a,0x4c,0x60,0x4c,0x70,0x4c,0x68,0x4c,0x78,0x4c,
2531
0x64,0x0c,0x33,0x26,0x2e,0x26,0x29,0x26,0x39,0x26,0x25,0x26,0x2d,0x26,0x23,0x86,
2532
0x1b,0xc3,0x8f,0x11,0xc6,0x88,0x63,0x8a,0x62,0x64,0x31,0x8a,0x18,0x55,0x8c,0x36,
2533
0xc6,0x10,0x53,0x1d,0x53,0x13,0x53,0x1f,0xd3,0x18,0xd3,0x1c,0xd3,0x1a,0xd3,0x1e,
2534
0xd3,0x19,0x73,0x23,0xa6,0x37,0xa6,0x2f,0x66,0xc0,0xca,0xbd,0x98,0xfb,0x31,0x0f,
2535
0x62,0x1e,0xc6,0x3c,0x8a,0x79,0x1c,0x33,0x11,0xf3,0x24,0xe6,0x69,0xcc,0x4c,0xcc,
2536
0x5c,0xcc,0xf3,0x98,0xc5,0x98,0x17,0x31,0x2f,0x63,0x5e,0xc5,0x80,0x58,0x9b,0x58,
2537
0xbb,0x58,0xfb,0x58,0x42,0xac,0x73,0xac,0x6b,0xac,0x7b,0xac,0x67,0xac,0x77,0xac,
2538
0x4f,0xac,0x5f,0x2c,0x39,0x96,0x1a,0x1b,0x18,0x1b,0x1c,0x1b,0x1a,0x1b,0x1e,0x1b,
2539
0x19,0xcb,0x8c,0x8d,0x8b,0x4d,0x8a,0x4d,0x8e,0x4d,0x89,0x4d,0x8b,0xcd,0x88,0xe5,
2540
0xc6,0xf2,0x63,0x85,0xb1,0xe2,0xd8,0xa2,0x58,0x59,0xac,0x22,0x56,0x15,0xab,0x8d,
2541
0x35,0xc4,0x56,0xc7,0xd6,0xc4,0xd6,0xc7,0x36,0xc6,0x36,0xc7,0xb6,0xc6,0xb6,0xc7,
2542
0x76,0xc6,0xde,0x88,0xed,0x8d,0xed,0x8b,0x1d,0x88,0xbd,0x17,0x7b,0x3f,0xf6,0x41,
2543
0xec,0xc3,0xd8,0x47,0xb1,0x8f,0x63,0x27,0x62,0x9f,0xc4,0x3e,0x8d,0x9d,0x89,0x9d,
2544
0x8b,0x7d,0x1e,0xbb,0x18,0xfb,0x22,0xf6,0x65,0xec,0xab,0x58,0x10,0x67,0x13,0x67,
2545
0x17,0x67,0x1f,0x47,0x88,0x73,0x8e,0x73,0x8d,0x73,0x8f,0xf3,0x8c,0xf3,0x8e,0xf3,
2546
0x89,0xf3,0x8b,0x23,0xc7,0x51,0xe3,0x02,0xe3,0x82,0xe3,0x42,0xe3,0xc2,0xe3,0x22,
2547
0xe3,0x98,0x71,0x71,0x71,0x49,0x71,0xc9,0x71,0x29,0x71,0x69,0x71,0x19,0xbf,0x22,
2548
0x99,0x10,0x41,0x9c,0x24,0x4e,0x1e,0xa7,0x8b,0xab,0x8d,0x6b,0x8a,0x6b,0xfd,0x03,
2549
0xb4,0xc5,0x75,0xc5,0x99,0xe3,0x06,0xe3,0x86,0xe3,0x1e,0xbe,0xc1,0x63,0xc8,0x54,
2550
0xdc,0x74,0x9c,0x25,0x6e,0x3e,0x6e,0x21,0x6e,0x29,0x6e,0x39,0x6e,0x25,0x6e,0x35,
2551
0x0e,0x17,0x6f,0x13,0x6f,0x1f,0xef,0x1c,0xef,0x19,0xef,0x17,0x4f,0x8d,0x0f,0x8e,
2552
0x0f,0x8f,0x67,0xc6,0x27,0xc5,0xa7,0xc4,0x67,0xc4,0xf3,0xe3,0xc5,0x10,0x59,0xbc,
2553
0x2a,0xde,0x10,0x5f,0x13,0xdf,0x08,0x69,0x85,0x74,0xc6,0xf7,0x42,0x06,0xe2,0xef,
2554
0x43,0x1e,0xc6,0x3f,0x8e,0x7f,0x12,0x3f,0x13,0xff,0x3c,0xfe,0x45,0xfc,0xab,0x78,
2555
0x9b,0x04,0x87,0x04,0x97,0x04,0xb7,0x04,0x8f,0x04,0xaf,0x04,0x62,0x82,0x6f,0x02,
2556
0x29,0x81,0x92,0x40,0x4b,0xa0,0x27,0x84,0x24,0x84,0x25,0x44,0x24,0x30,0x12,0x58,
2557
0x09,0xf1,0x09,0xec,0x04,0x4e,0x42,0x6a,0x42,0x7a,0x42,0x66,0x02,0x2f,0x41,0x90,
2558
0x20,0x4a,0x90,0x24,0x48,0x13,0xe4,0x09,0xca,0x04,0x75,0x82,0x2e,0xc1,0x98,0x60,
2559
0x4a,0xa8,0x4d,0x68,0x48,0x68,0x4a,0x68,0x49,0x68,0x4b,0xe8,0x48,0xe8,0x4a,0xe8,
2560
0x4e,0x30,0x27,0xf4,0x27,0x0c,0x26,0x0c,0x25,0x0c,0x27,0x8c,0x24,0x8c,0x26,0x8c,
2561
0x25,0x8c,0x27,0x4c,0x26,0x4c,0x25,0x4c,0x27,0x58,0x12,0xe6,0x13,0x16,0x12,0x96,
2562
0x12,0x96,0x13,0x56,0x12,0x56,0x13,0x70,0x89,0xb6,0x89,0xf8,0x44,0x87,0x44,0xa7,
2563
0x44,0x97,0x44,0xb7,0x44,0x8f,0x44,0xaf,0x44,0x62,0xa2,0x6f,0x22,0x29,0x91,0x92,
2564
0x48,0x4b,0xa4,0x27,0x86,0x24,0x86,0x25,0x46,0x24,0x32,0x12,0x59,0x89,0xf1,0x89,
2565
0xec,0x44,0x4e,0x62,0x6a,0x62,0x7a,0x62,0x66,0xa2,0x20,0x51,0x92,0x28,0x4d,0x94,
2566
0x27,0x2a,0x13,0xd5,0x89,0xba,0x44,0x63,0xa2,0x29,0xb1,0x36,0xb1,0x21,0xb1,0x29,
2567
0xb1,0x2d,0xb1,0xf3,0xaf,0xa6,0x2b,0xb1,0x3b,0xd1,0x9c,0xd8,0x9f,0x38,0x98,0x38,
2568
0x94,0x38,0x9c,0x38,0x92,0x38,0x9a,0x38,0x96,0x38,0x9e,0x38,0x95,0x38,0x9d,0x68,
2569
0x49,0x9c,0x4f,0x5c,0x48,0x5c,0x4a,0x5c,0x4e,0x5c,0x49,0x5c,0x4d,0xc4,0x25,0xd9,
2570
0x26,0xe1,0x93,0x1c,0x92,0xdc,0x92,0x88,0x49,0x94,0xa4,0x90,0x24,0x46,0x12,0x3b,
2571
0x29,0x3d,0x49,0x90,0x24,0x4d,0x52,0x27,0x99,0x92,0x9a,0x92,0x3a,0x92,0xcc,0x49,
2572
0x43,0x49,0xa3,0x49,0x93,0x49,0x96,0xa4,0xf9,0xa4,0x85,0xa4,0xa5,0xa4,0x65,0x08,
2573
0x8e,0xed,0xc0,0x76,0x63,0x13,0xd9,0x14,0x36,0x9d,0x1d,0xc6,0x66,0xb0,0xe3,0xd9,
2574
0x1c,0x76,0x3a,0x9b,0xc7,0x16,0xb1,0xa5,0x6c,0x25,0x5b,0xc7,0x36,0xb1,0x1b,0xd8,
2575
0x2d,0xec,0x0e,0x76,0x37,0xbb,0x9f,0x3d,0xc4,0x1e,0x61,0x8f,0xb1,0x27,0xd9,0xd3,
2576
0xec,0x79,0xf6,0x12,0x7b,0x85,0x8d,0x3b,0x81,0x3f,0xe1,0x74,0xc2,0xed,0x84,0xd7,
2577
0x09,0xdf,0x13,0x94,0x13,0xf4,0x13,0x61,0x27,0x18,0x27,0xe2,0x4f,0x70,0x4e,0xa4,
2578
0x9f,0xe0,0x9d,0x10,0x9d,0x90,0x9e,0x50,0x9e,0xd0,0x9d,0x30,0x9d,0x68,0x38,0xd1,
2579
0x72,0xa2,0xe3,0x44,0xf7,0x89,0xfe,0x13,0x43,0x27,0x46,0x4e,0x8c,0x9d,0x98,0x3c,
2580
0x31,0x7d,0x62,0xfe,0xc4,0xd2,0x89,0x95,0x13,0xb8,0x93,0xf8,0x93,0x4e,0x27,0xdd,
2581
0x4e,0x7a,0x9d,0xf4,0x3d,0x49,0x39,0x49,0x3f,0x19,0x76,0x92,0x71,0x32,0xfe,0x24,
2582
0xe7,0x64,0xfa,0x49,0xde,0x49,0xd1,0x49,0xe9,0x49,0xe5,0x49,0xdd,0x49,0xd3,0xc9,
2583
0x86,0x93,0x2d,0x27,0x3b,0x4e,0x76,0x9f,0xec,0x3f,0x39,0x74,0x72,0xe4,0xe4,0xd8,
2584
0xc9,0xc9,0x93,0xd3,0x27,0xe7,0x4f,0x2e,0x9d,0x5c,0x39,0x69,0x9b,0xec,0x94,0xec,
2585
0x91,0xec,0x9b,0x4c,0x4b,0x0e,0x4b,0x66,0x25,0x73,0x92,0x33,0x93,0x45,0xc9,0xf2,
2586
0x64,0x5d,0xb2,0x29,0xb9,0x21,0xb9,0x25,0xb9,0x23,0xb9,0x3b,0xb9,0x3f,0x79,0x28,
2587
0x79,0x24,0x79,0x2c,0x79,0x32,0x79,0x3a,0x79,0x3e,0x79,0x29,0x79,0x25,0x19,0xc7,
2588
0xc1,0x73,0x9c,0x38,0x6e,0x1c,0x2f,0x8e,0x2f,0x87,0xc2,0xa1,0x73,0xc2,0x38,0x0c,
2589
0x4e,0x3c,0x87,0xc3,0x49,0xe7,0xf0,0x38,0x22,0x8e,0x94,0xa3,0xe4,0xe8,0x38,0x26,
2590
0x4e,0x03,0xa7,0x85,0xd3,0xc1,0xe9,0xe6,0xf4,0x73,0x86,0x38,0x23,0x9c,0x31,0xce,
2591
0x24,0x67,0x9a,0x33,0xcf,0x59,0xe2,0xac,0x72,0xf0,0xa7,0x5c,0x4e,0x79,0x9d,0x22,
2592
0x9d,0xa2,0x9d,0x0a,0x39,0x15,0x71,0x8a,0x75,0x8a,0x7d,0x2a,0xf5,0x54,0xe6,0x29,
2593
0xc1,0x29,0xc9,0x29,0xf9,0x29,0xf5,0x29,0xe3,0xa9,0xda,0x53,0x4d,0xa7,0xda,0x4e,
2594
0x75,0x9d,0x32,0x9f,0x1a,0x3c,0x35,0x7c,0x6a,0xf4,0xd4,0xf8,0xa9,0xa9,0x53,0x96,
2595
0x53,0x0b,0xa7,0x96,0x4f,0xad,0x9e,0xb2,0x3d,0xed,0x70,0xda,0xe5,0xb4,0xc7,0x69,
2596
0xe2,0x69,0xd2,0x69,0xda,0xe9,0x90,0xd3,0x11,0xa7,0x59,0xa7,0xd9,0xa7,0x53,0x4f,
2597
0x67,0x9e,0x16,0x9c,0x96,0x9c,0x96,0x9f,0x56,0x9f,0x36,0x9e,0xae,0x3d,0xdd,0x74,
2598
0xba,0xed,0x74,0xd7,0x69,0xf3,0xe9,0xc1,0xd3,0xc3,0xa7,0x47,0x4f,0x8f,0x9f,0x9e,
2599
0x3a,0x6d,0x39,0xbd,0x70,0x7a,0xf9,0xf4,0xea,0x69,0xdb,0x14,0x87,0x14,0x97,0x14,
2600
0x8f,0x14,0x62,0x0a,0x29,0x85,0x96,0x12,0x92,0x12,0x91,0x12,0x9f,0x92,0x9a,0x92,
2601
0x99,0x22,0x48,0x91,0xa4,0xc8,0x53,0xd4,0x29,0xc6,0x94,0xda,0x94,0xa6,0x94,0xb6,
2602
0x94,0xae,0x14,0x73,0xca,0x60,0xca,0x70,0xca,0x68,0xca,0x78,0xca,0x54,0x8a,0x25,
2603
0x65,0x29,0x65,0x35,0x05,0x9f,0xea,0x94,0xea,0x96,0xea,0x95,0xea,0x9b,0x4a,0x49,
2604
0xa5,0xa7,0x86,0xa5,0x32,0x52,0xe3,0x53,0x39,0xa9,0xe9,0x10,0x5e,0xaa,0x28,0x55,
2605
0x9a,0xaa,0x4c,0xd5,0xa5,0x9a,0x52,0x1b,0x52,0x5b,0x52,0x3b,0x52,0xbb,0x53,0xfb,
2606
0x53,0x87,0x52,0x47,0x52,0xc7,0x52,0x27,0x53,0xa7,0x53,0xe7,0x53,0x97,0x52,0x57,
2607
0x52,0x71,0x67,0xf0,0x67,0x9c,0xce,0xb8,0x9d,0xf1,0x3a,0xe3,0x7b,0x86,0x72,0x86,
2608
0x7e,0x26,0xec,0x0c,0xe3,0x4c,0xfc,0x19,0xce,0x99,0xf4,0x33,0xbc,0x33,0xa2,0x33,
2609
0xd2,0x33,0xca,0x33,0xba,0x33,0xa6,0x33,0x0d,0x67,0x5a,0xce,0x74,0x9c,0xe9,0x3e,
2610
0xd3,0x7f,0x66,0xe8,0xcc,0xc8,0x99,0xb1,0x33,0x93,0x67,0xa6,0xcf,0xcc,0x9f,0x59,
2611
0x3a,0xb3,0x72,0x06,0x77,0x16,0x7f,0xd6,0xe9,0xac,0xdb,0x59,0xaf,0xb3,0xbe,0x67,
2612
0x29,0x67,0xe9,0x67,0xc3,0xce,0x32,0xce,0xc6,0xfd,0x09,0xc4,0x9f,0x4d,0x3d,0xcb,
2613
0x3b,0x2b,0x39,0xab,0x3c,0x6b,0x3c,0xdb,0x70,0xb6,0xed,0x6c,0xf7,0xd9,0xc1,0xb3,
2614
0x23,0x67,0xc7,0xcf,0x4e,0x9f,0x5d,0x38,0xbb,0x72,0xd6,0x36,0xcd,0x29,0xcd,0x23,
2615
0xcd,0x37,0x8d,0x96,0x16,0x96,0xc6,0x4a,0xe3,0xa4,0x65,0xa6,0x89,0xd2,0xe4,0x69,
2616
0xba,0xb4,0xda,0xb4,0x96,0xb4,0xae,0xb4,0xfe,0xb4,0xe1,0xb4,0xb1,0xb4,0xa9,0xb4,
2617
0xf9,0xb4,0xe5,0x34,0x5c,0xba,0x43,0xba,0x5b,0x3a,0x31,0x9d,0x92,0x1e,0x92,0xce,
2618
0x48,0x67,0xa7,0xa7,0xa7,0x0b,0xd2,0xa5,0xe9,0xea,0x74,0x53,0x7a,0x53,0x7a,0x47,
2619
0xba,0x39,0x7d,0x28,0x7d,0x34,0x7d,0x32,0xdd,0x92,0xbe,0x94,0xbe,0x9a,0x8e,0xff,
2620
0xc8,0xe5,0x23,0xaf,0x8f,0x48,0x1f,0xd1,0x3f,0x8a,0xf8,0x28,0x0e,0x12,0xff,0x51,
2621
0xea,0x47,0xbc,0x8f,0x24,0x1f,0x29,0x3f,0x32,0x7e,0xd4,0xf0,0x51,0xdb,0x47,0xdd,
2622
0x1f,0x0d,0x7e,0x34,0xf2,0xd1,0xf8,0x47,0xd3,0x1f,0x2d,0x7c,0xb4,0xf2,0x91,0xed,
2623
0xc7,0x4e,0x1f,0x7b,0x7c,0xec,0xfb,0x31,0xed,0xe3,0xb0,0x8f,0x59,0x1f,0x73,0x3e,
2624
0xce,0xfc,0x58,0xf4,0xb1,0xfc,0x63,0xdd,0xc7,0xb5,0x1f,0xb7,0x7c,0xdc,0xf5,0x71,
2625
0xff,0xc7,0xc3,0x1f,0x8f,0x7d,0x3c,0xf5,0xf1,0xfc,0xc7,0xcb,0x1f,0xe3,0x32,0x1c,
2626
0x32,0xdc,0x32,0x88,0x19,0x94,0x8c,0x90,0x0c,0x46,0x06,0x3b,0x23,0x3d,0x43,0x90,
2627
0x21,0xcd,0x50,0x67,0x98,0x32,0x9a,0x32,0x3a,0x32,0xcc,0x19,0x43,0x19,0xa3,0x19,
2628
0x13,0xbf,0x32,0x93,0x19,0x96,0x8c,0xa5,0x0c,0x5c,0xa6,0x53,0xa6,0x57,0x26,0x25,
2629
0x33,0x2c,0x33,0x3e,0x33,0x3d,0x53,0x90,0x69,0xce,0x1c,0xcf,0x9c,0xf9,0x13,0xb1,
2630
0x64,0xce,0x67,0x2e,0x64,0x2e,0x65,0x2e,0x67,0xae,0x64,0xae,0x66,0xe2,0xb2,0x6c,
2631
0xb3,0xf0,0x59,0xce,0x7f,0x06,0x2e,0x59,0x1e,0x59,0x5e,0x59,0xc4,0x2c,0xdf,0x2c,
2632
0x52,0x16,0x25,0x8b,0x96,0x45,0xcf,0x0a,0xc9,0x0a,0xcb,0x8a,0xc8,0x62,0x64,0xb1,
2633
0xb2,0xe2,0xb3,0xd8,0x59,0x9c,0xac,0xd4,0xac,0xf4,0xac,0xcc,0x2c,0x5e,0x16,0x1f,
2634
0x22,0xc8,0x12,0x65,0x49,0xb2,0xe4,0x59,0xea,0x2c,0x63,0x56,0x6d,0x56,0x43,0x56,
2635
0x53,0x56,0x4b,0x56,0x5b,0x56,0x47,0x56,0x67,0x56,0x57,0x56,0x77,0x96,0x39,0xab,
2636
0x3f,0x6b,0x30,0x6b,0x28,0x6b,0x38,0x6b,0x24,0x6b,0x34,0x6b,0x2c,0x6b,0x3c,0x6b,
2637
0x32,0x6b,0x2a,0x6b,0x3a,0xcb,0x92,0x35,0x9f,0xb5,0x90,0xb5,0x94,0xb5,0x9c,0xf5,
2638
0x32,0x6b,0x25,0x6b,0x35,0x0b,0x77,0xce,0xf6,0x9c,0x1d,0x06,0xfe,0x9c,0xd3,0x39,
2639
0xb7,0x73,0x9e,0xe7,0xbc,0xce,0xf9,0x9c,0xf3,0x3d,0x47,0x39,0x47,0x3f,0x17,0x76,
2640
0x8e,0x71,0x2e,0xfe,0x1c,0xe7,0x5c,0xfa,0x39,0xde,0x39,0xd1,0x39,0xe9,0x39,0xf9,
2641
0x39,0xf5,0x39,0xe3,0xb9,0xda,0x73,0x4d,0xe7,0xda,0xce,0x75,0x9d,0x33,0x9f,0x1b,
2642
0x3c,0x37,0x7c,0x6e,0xf4,0xdc,0xf8,0xb9,0xa9,0x73,0xd3,0xe7,0x2c,0xe7,0xe6,0xcf,
2643
0x2d,0x9c,0x5b,0x3a,0xb7,0x7c,0x6e,0xe5,0xdc,0xea,0x39,0x1c,0xd7,0x96,0x8b,0xe7,
2644
0x3a,0x70,0x9d,0xb8,0x2e,0x5c,0x37,0xae,0x07,0xd7,0x8b,0x4b,0xe4,0xfa,0x72,0x49,
2645
0x5c,0x0a,0x97,0xc6,0xa5,0x73,0x43,0xb8,0x61,0xdc,0x08,0x2e,0x83,0xcb,0xe2,0xc6,
2646
0x73,0xd9,0x5c,0x0e,0x37,0x95,0x9b,0xce,0xcd,0xe4,0xf2,0xb8,0x02,0xae,0x88,0x2b,
2647
0xe1,0x4a,0xb9,0x72,0xae,0x92,0xab,0xe6,0xea,0xb8,0x46,0xae,0x89,0x5b,0xcb,0x6d,
2648
0xe0,0x36,0x71,0x5b,0xb8,0x6d,0xdc,0x0e,0x6e,0x17,0xb7,0x9b,0x6b,0xe6,0xf6,0x73,
2649
0x07,0xb9,0x43,0xdc,0x61,0xee,0x08,0x77,0x94,0x3b,0xc6,0x1d,0xe7,0x4e,0x72,0xa7,
2650
0xb8,0xd3,0x5c,0x0b,0x77,0x9e,0xbb,0xc0,0x5d,0xe2,0x2e,0x73,0x57,0xb8,0xab,0x5c,
2651
0x1c,0xcf,0x96,0x87,0xe7,0x39,0xf0,0x9c,0x78,0x2e,0x3c,0x37,0x9e,0x07,0xcf,0x8b,
2652
0x47,0xe4,0xf9,0xf2,0x48,0x3c,0x0a,0x8f,0xc6,0xa3,0xf3,0x42,0x78,0x61,0xbc,0x08,
2653
0x1e,0x83,0xc7,0xe2,0xc5,0xf3,0xd8,0x3c,0x0e,0x2f,0x95,0x97,0xce,0xcb,0xe4,0xf1,
2654
0x78,0x02,0x9e,0x88,0x27,0xe1,0x49,0x79,0x72,0x9e,0x8e,0x57,0xcb,0x6b,0xe1,0x75,
2655
0xf1,0xfa,0x79,0xc3,0xbc,0x51,0xde,0xe3,0x5f,0x18,0xe7,0x4d,0xf2,0xa6,0x78,0xd3,
2656
0x3c,0x0b,0x6f,0x9e,0xb7,0xc0,0x5b,0xe2,0x2d,0xf3,0x56,0x78,0xab,0x3c,0x5c,0xb6,
2657
0x6d,0x36,0x3e,0xdb,0x21,0xdb,0x29,0xdb,0x25,0xdb,0x2d,0xdb,0x23,0xdb,0x2b,0x9b,
2658
0x98,0xed,0x9b,0x4d,0xca,0xa6,0x64,0xd3,0xb2,0xe9,0xd9,0x21,0xd9,0x61,0xd9,0x11,
2659
0xd9,0x8c,0x6c,0x56,0x76,0x7c,0x36,0x3b,0x9b,0x93,0x9d,0x9a,0x9d,0x9e,0x9d,0x99,
2660
0xcd,0xcb,0x16,0x64,0x8b,0xb2,0x25,0xd9,0xd2,0x6c,0x79,0xb6,0x32,0x5b,0x9d,0xad,
2661
0xcb,0x36,0x66,0x9b,0xb2,0x6b,0xb3,0x1b,0xb2,0x9b,0xb2,0x5b,0xb2,0xdb,0xb2,0x3b,
2662
0xb2,0xbb,0xb2,0xbb,0xb3,0xcd,0xd9,0xfd,0xd9,0x83,0xd9,0x43,0xd9,0xc3,0xd9,0x23,
2663
0xd9,0xa3,0xd9,0x63,0xd9,0xe3,0xd9,0x93,0xd9,0x53,0xd9,0xd3,0xd9,0x96,0xec,0xf9,
2664
0xec,0x85,0xec,0xa5,0xec,0xe5,0xec,0x95,0xec,0xd5,0x6c,0x5c,0x8e,0x6d,0x0e,0x3e,
2665
0xc7,0x21,0xc7,0x29,0xc7,0x25,0xc7,0x2d,0xc7,0x23,0xc7,0x2b,0x87,0x98,0xe3,0x9b,
2666
0x43,0xca,0xa1,0xe4,0xd0,0x72,0xe8,0x39,0x21,0x39,0x61,0x39,0x11,0x39,0x8c,0x1c,
2667
0x56,0x4e,0x7c,0x0e,0x3b,0x87,0x93,0x93,0x9a,0x93,0x9e,0x93,0x99,0xc3,0xcb,0x11,
2668
0xe4,0x88,0x72,0x24,0x39,0xd2,0x1c,0x79,0x8e,0x32,0x47,0x9d,0xa3,0xcb,0x31,0xe6,
2669
0x98,0x72,0x6a,0x73,0x1a,0x72,0x9a,0x72,0x5a,0x72,0xda,0x72,0x3a,0x72,0xba,0x72,
2670
0xba,0x73,0xcc,0x39,0xfd,0x39,0x83,0x39,0x43,0x39,0xc3,0x39,0x23,0x39,0xa3,0x39,
2671
0x63,0x39,0xe3,0x39,0x93,0x39,0x53,0x39,0xd3,0x39,0x96,0x9c,0xf9,0x9c,0x85,0x9c,
2672
0xa5,0x9c,0xe5,0x9c,0x95,0x9c,0xd5,0x1c,0x1c,0xdf,0x96,0x8f,0xe7,0x3b,0xf0,0x9d,
2673
0xf8,0x2e,0x7c,0x37,0xbe,0x07,0xdf,0x8b,0x4f,0xe4,0xfb,0xf2,0x49,0x7c,0x0a,0x9f,
2674
0xc6,0xa7,0xf3,0x43,0xf8,0x61,0xfc,0x08,0x3e,0x03,0xbe,0x28,0xc7,0xf3,0xd9,0x7c,
2675
0x0e,0x3f,0x95,0x9f,0xce,0xcf,0xe4,0xf3,0xf8,0x02,0xbe,0x88,0x2f,0xe1,0x4b,0xf9,
2676
0x72,0xbe,0x92,0xaf,0xe6,0xeb,0xf8,0x46,0xbe,0x89,0x5f,0xcb,0x6f,0xe0,0x37,0xf1,
2677
0x5b,0xf8,0x6d,0xfc,0x0e,0x7e,0x17,0xbf,0x9b,0x6f,0xe6,0xf7,0xf3,0x07,0xf9,0x43,
2678
0xfc,0x61,0xfe,0x08,0xff,0xa1,0x95,0x51,0xfe,0x18,0x7f,0x9c,0x3f,0xc9,0x9f,0xe2,
2679
0x4f,0xf3,0x67,0x20,0x16,0xfe,0x3c,0x7f,0x81,0xbf,0xc4,0x5f,0xe6,0xaf,0xf0,0x5f,
2680
0x41,0x56,0xf9,0x38,0x81,0xad,0x00,0x2f,0x70,0x10,0x38,0x09,0x9c,0x21,0x2e,0x02,
2681
0x37,0x81,0x87,0xc0,0xd3,0x8a,0x97,0x80,0x28,0xf0,0x15,0x90,0x04,0x34,0x01,0x5d,
2682
0x10,0x22,0x08,0x15,0x84,0x09,0x22,0x04,0x0c,0x01,0x4b,0x10,0x2f,0x60,0x0b,0x38,
2683
0x82,0x94,0x75,0xfe,0x04,0x52,0x05,0xe9,0x82,0x4c,0x01,0x4f,0x20,0x10,0x08,0x05,
2684
0x22,0x81,0x44,0x20,0x15,0xc8,0x05,0x4a,0x81,0x5a,0xa0,0x13,0x18,0x05,0x26,0x41,
2685
0xad,0xa0,0x41,0xd0,0x24,0x68,0x11,0xb4,0x09,0x3a,0x04,0x5d,0x82,0x6e,0x81,0x59,
2686
0xd0,0x2f,0x18,0x14,0x0c,0x09,0x86,0x05,0x23,0x82,0x51,0xc1,0x98,0x60,0x5c,0x30,
2687
0x29,0x98,0x12,0x4c,0x0b,0x2c,0x82,0x79,0xc1,0x82,0x60,0x49,0xb0,0x2c,0x58,0x11,
2688
0xac,0x0a,0x70,0xe7,0x6d,0xcf,0xe3,0xcf,0x3b,0x9c,0x77,0x3a,0xef,0x72,0xde,0xf5,
2689
0xbc,0xdb,0x79,0x8f,0xf3,0x5e,0xe7,0x89,0xe7,0x7d,0xcf,0x93,0xce,0x53,0xce,0xd3,
2690
0xce,0xd3,0xcf,0x07,0xaf,0xf3,0x4f,0x4e,0x38,0x84,0xf9,0x3f,0x92,0xb4,0x8e,0x95,
2691
0x94,0xf3,0x19,0xeb,0xac,0xf3,0x17,0xc1,0x3f,0x2f,0x5e,0x67,0x9d,0x7f,0x61,0x64,
2692
0xe7,0x55,0x10,0xc3,0x3a,0xff,0xa6,0xd4,0x9c,0x6f,0xfc,0x37,0xa6,0x75,0x9d,0x75,
2693
0x7e,0x35,0x3a,0xcf,0xf7,0x9e,0xbf,0x77,0xfe,0xe1,0xf9,0x89,0xf3,0x33,0xe7,0x17,
2694
0xff,0xa9,0x78,0x79,0x1e,0xe4,0xda,0xe7,0xba,0xe6,0x7a,0xe7,0x92,0xd7,0x59,0xe7,
2695
0xff,0x22,0x14,0x08,0x2d,0x97,0x9e,0x1b,0x92,0x1b,0x96,0x1b,0x91,0xcb,0xc8,0x65,
2696
0xe5,0xc6,0xe7,0xb2,0x73,0x39,0xb9,0xa9,0xb9,0xe9,0xb9,0x99,0xb9,0xbc,0x5c,0x41,
2697
0xae,0x28,0x57,0x92,0x2b,0xcd,0x95,0xe7,0x2a,0x73,0xd5,0xb9,0xba,0x5c,0x63,0xae,
2698
0x29,0xb7,0x36,0xb7,0x21,0xb7,0x29,0xb7,0x25,0xb7,0x2d,0xb7,0x23,0xb7,0x2b,0xb7,
2699
0x3b,0xd7,0x9c,0xdb,0x9f,0x3b,0x98,0x3b,0x94,0x3b,0x9c,0x3b,0x92,0x3b,0x9a,0x3b,
2700
0x96,0x3b,0x9e,0x3b,0x99,0x3b,0x95,0x3b,0x9d,0x6b,0xc9,0x9d,0xcf,0x5d,0xc8,0x5d,
2701
0xca,0x5d,0xce,0x5d,0xc9,0x5d,0xcd,0xc5,0x09,0x6d,0x85,0x78,0xa1,0x83,0xd0,0x49,
2702
0xe8,0x22,0x74,0x13,0x7a,0x08,0xbd,0x84,0x44,0xa1,0xaf,0x90,0x24,0xa4,0x08,0x69,
2703
0x42,0xba,0x30,0x44,0x18,0x26,0x8c,0x10,0x32,0x84,0x2c,0x61,0xbc,0x90,0x2d,0xe4,
2704
0x08,0x53,0x85,0xe9,0xc2,0x4c,0x21,0x4f,0x28,0x10,0x8a,0x84,0x12,0xa1,0x54,0x28,
2705
0x17,0x2a,0x85,0x2a,0xa1,0x5a,0xa8,0x13,0x1a,0x85,0x26,0x61,0xad,0xb0,0x41,0xd8,
2706
0x24,0x6c,0x11,0xb6,0x09,0x3b,0x84,0x5d,0xc2,0x6e,0xa1,0x59,0xd8,0x2f,0x1c,0x14,
2707
0x0e,0x09,0x87,0x85,0x23,0xc2,0x51,0xe1,0x98,0x70,0x5c,0x38,0x29,0x9c,0x12,0x4e,
2708
0x0b,0x2d,0xc2,0x79,0xe1,0x82,0x70,0x49,0xb8,0x2c,0x5c,0x11,0xae,0x0a,0x71,0x22,
2709
0x5b,0x11,0x5e,0xe4,0x20,0x72,0x12,0xb9,0x88,0xdc,0x44,0x1e,0x22,0x2f,0x11,0x51,
2710
0xe4,0x2b,0x22,0x89,0x28,0x22,0x9a,0x88,0x2e,0x0a,0x11,0x85,0x89,0x22,0x44,0x0c,
2711
0x11,0x4b,0x14,0x2f,0x62,0x8b,0x38,0xa2,0x54,0x51,0xba,0x28,0x53,0xc4,0x13,0x09,
2712
0x44,0x22,0x91,0x44,0x24,0x15,0xc9,0x45,0x4a,0x91,0x5a,0xa4,0x13,0x19,0x45,0x26,
2713
0x51,0xad,0xa8,0x41,0xd4,0x24,0x6a,0x16,0xb5,0x88,0xda,0x44,0xed,0x90,0x0e,0x51,
2714
0x27,0xa4,0x4b,0xd4,0x2d,0xea,0x85,0x98,0x45,0xfd,0xa2,0x41,0xd1,0x90,0xe8,0xbe,
2715
0x68,0x58,0x34,0x22,0x1a,0x15,0x8d,0x89,0xc6,0x45,0x93,0xa2,0x29,0xd1,0xb4,0xc8,
2716
0x22,0x9a,0x17,0x2d,0x88,0x96,0x44,0x2f,0x44,0xcb,0xa2,0x97,0xa2,0x15,0xd1,0xaa,
2717
0x08,0x97,0x67,0x9b,0x87,0xcf,0x73,0xc8,0x73,0xca,0x73,0xce,0x73,0xc9,0x73,0xcb,
2718
0xf3,0xc8,0xf3,0xca,0x23,0xe6,0xf9,0xe6,0x91,0xf2,0x28,0x79,0xb4,0x3c,0x7a,0x5e,
2719
0x48,0x5e,0x58,0x5e,0x44,0x1e,0x23,0x8f,0x95,0x17,0x9f,0xc7,0xce,0xe3,0xe4,0xa5,
2720
0xe6,0xa5,0xe7,0x65,0xe6,0xf1,0xf2,0x04,0x79,0xa2,0x3c,0x49,0x9e,0x34,0x4f,0x9e,
2721
0xa7,0xcc,0x53,0xe7,0xe9,0xf2,0x8c,0x79,0xa6,0xbc,0xda,0xbc,0x86,0xbc,0xa6,0xbc,
2722
0x96,0xbc,0xb6,0xbc,0x8e,0xbc,0xae,0xbc,0xee,0x3c,0x73,0x5e,0x7f,0xde,0x60,0xde,
2723
0x50,0xde,0x70,0xde,0x48,0xde,0x68,0xde,0x58,0xde,0x78,0xde,0x64,0xde,0x54,0xde,
2724
0x74,0x9e,0x25,0x6f,0x3e,0x6f,0x21,0x6f,0x29,0x6f,0x39,0x6f,0x25,0x6f,0x35,0x0f,
2725
0x97,0x8f,0xcb,0xb7,0xcd,0xc7,0xe7,0x3b,0xe4,0x3b,0xe5,0xbb,0xe4,0xbb,0xe6,0xbb,
2726
0xe5,0x7b,0xe4,0x7b,0xe5,0x13,0xf3,0x7d,0x20,0xbe,0xf9,0xa4,0x7c,0x4a,0x3e,0x2d,
2727
0x9f,0x9e,0x1f,0x92,0x1f,0x96,0x1f,0x91,0x1f,0x99,0xcf,0xc8,0x67,0xe5,0xc7,0xe7,
2728
0xb3,0xf3,0x39,0xf9,0xa9,0xf9,0xe9,0xf9,0x19,0xf9,0x99,0xf9,0xbc,0x7c,0x41,0xbe,
2729
0x28,0x5f,0x92,0x2f,0xcd,0x97,0xe7,0x2b,0xf3,0xd5,0xf9,0xba,0x7c,0x63,0xbe,0x29,
2730
0xbf,0x36,0xbf,0x21,0xbf,0x29,0xbf,0x25,0xbf,0x2d,0xbf,0x23,0xbf,0x2b,0xbf,0x3b,
2731
0xdf,0x9c,0xdf,0x9f,0x3f,0x98,0x3f,0x94,0x3f,0x9c,0x3f,0x92,0x3f,0x9a,0x3f,0x96,
2732
0xff,0x38,0x7f,0x3c,0x7f,0x32,0x7f,0x2a,0x7f,0x3a,0x7f,0x26,0xdf,0x92,0x3f,0x9f,
2733
0xbf,0x90,0xbf,0x94,0xbf,0x9c,0xff,0x32,0x7f,0x25,0xff,0x95,0x95,0xd5,0x7c,0x9c,
2734
0xd8,0x56,0x8c,0x17,0x3b,0x88,0x9d,0xc4,0x2e,0x62,0x57,0xb1,0x9b,0xd8,0x43,0xec,
2735
0x25,0x26,0x8a,0x7d,0xc5,0x24,0x31,0x45,0x4c,0x13,0xd3,0xc5,0x21,0xe2,0x30,0x71,
2736
0x84,0x98,0x21,0x66,0x89,0xe3,0xc5,0x6c,0x31,0x47,0x9c,0x2a,0x4e,0x17,0x67,0x8a,
2737
0x79,0x62,0x81,0x58,0x24,0x96,0x88,0xa5,0x62,0xb9,0x58,0x29,0x56,0x8b,0x75,0x62,
2738
0xa3,0xd8,0x24,0xae,0x15,0x37,0x88,0x9b,0xc4,0x2d,0xe2,0x36,0x71,0x87,0xb8,0x4b,
2739
0xdc,0x2d,0x36,0x8b,0xfb,0xc5,0x83,0xe2,0x21,0xf1,0xb0,0x78,0x44,0x3c,0x2a,0x1e,
2740
0x13,0x8f,0x8b,0x27,0xc5,0x53,0xe2,0x69,0xb1,0x45,0x3c,0x2f,0x5e,0x10,0x2f,0x89,
2741
0x97,0xc5,0x2b,0xe2,0x55,0x31,0x4e,0x62,0x2b,0xc1,0x4b,0x1c,0x24,0x4e,0x12,0x17,
2742
0x89,0x9b,0xc4,0x43,0xe2,0x25,0x21,0x4a,0x7c,0x25,0x24,0x09,0x45,0x42,0x93,0xd0,
2743
0x25,0x21,0x92,0x30,0x49,0x84,0x84,0x21,0x61,0x49,0xe2,0x25,0x6c,0x09,0x47,0x92,
2744
0x2a,0x49,0x97,0x64,0x4a,0x78,0x12,0x81,0x44,0x24,0x91,0x48,0xa4,0x12,0xb9,0x44,
2745
0x29,0x51,0x4b,0x74,0x12,0xa3,0xc4,0x24,0xa9,0x95,0x34,0x48,0x9a,0x24,0x2d,0x92,
2746
0x36,0x49,0x87,0xa4,0x4b,0xd2,0x2d,0x31,0x4b,0xfa,0x25,0x83,0x92,0x21,0xc9,0xb0,
2747
0x64,0x44,0x32,0x2a,0x19,0x93,0x8c,0x4b,0x26,0x25,0x53,0x92,0x69,0x89,0x45,0x32,
2748
0x2f,0x59,0x90,0x2c,0x49,0x96,0x25,0x2b,0x92,0x55,0x09,0xae,0xc0,0xb6,0x00,0x5f,
2749
0xe0,0x50,0xe0,0x54,0xe0,0x52,0xe0,0x56,0xe0,0x51,0xe0,0x55,0x40,0x2c,0xf0,0x2d,
2750
0x20,0x15,0x50,0x0a,0x68,0x05,0xf4,0x82,0x90,0x82,0xb0,0x82,0x88,0x02,0x46,0x01,
2751
0xab,0x20,0xbe,0x80,0x5d,0xc0,0x29,0x48,0x2d,0x48,0x2f,0xc8,0x2c,0xe0,0x15,0x08,
2752
0x0a,0x44,0x05,0x92,0x02,0x69,0x81,0xbc,0x40,0x59,0xa0,0x2e,0xd0,0x15,0x18,0x0b,
2753
0x4c,0x05,0xb5,0x05,0x0d,0x05,0x4d,0x05,0x2d,0x05,0x6d,0x05,0x1d,0x05,0x5d,0x05,
2754
0xdd,0x05,0xe6,0x82,0xfe,0x82,0xc1,0x82,0xa1,0x82,0xe1,0x82,0x91,0x82,0xd1,0x82,
2755
0x31,0xc8,0x78,0xc1,0x64,0xc1,0x54,0xc1,0x74,0x81,0xa5,0x60,0xbe,0x60,0xa1,0x60,
2756
0xa9,0x60,0xb9,0x60,0xa5,0x60,0xb5,0x00,0x57,0x68,0x5b,0x88,0x2f,0x74,0x28,0x74,
2757
0x2a,0x74,0x29,0x74,0x2b,0xf4,0x28,0xf4,0x2a,0x24,0x16,0xfa,0x16,0x92,0x0a,0x29,
2758
0x85,0xb4,0x42,0x7a,0x61,0x48,0x61,0x58,0x61,0x44,0x21,0xa3,0x90,0x55,0x18,0x5f,
2759
0xc8,0x2e,0xe4,0x14,0xa6,0x16,0xa6,0x17,0x66,0x16,0xf2,0x0a,0x05,0x85,0xa2,0x42,
2760
0x49,0xa1,0xb4,0x50,0x5e,0xa8,0x2c,0x54,0x17,0xea,0x0a,0x8d,0x85,0xa6,0xc2,0xda,
2761
0xc2,0x86,0xc2,0xa6,0xc2,0x96,0xc2,0xb6,0xc2,0x8e,0xc2,0xae,0xc2,0xee,0x42,0x73,
2762
0x61,0x7f,0xe1,0x60,0xe1,0x50,0xe1,0x70,0xe1,0x48,0xe1,0x68,0xe1,0x58,0xe1,0x78,
2763
0xe1,0x64,0xe1,0x54,0xe1,0x74,0xa1,0xa5,0x70,0xbe,0x70,0xa1,0x70,0xa9,0x70,0xb9,
2764
0x70,0xa5,0x70,0xb5,0x10,0x57,0x64,0x5b,0x84,0x2f,0x72,0x28,0x72,0x2a,0x72,0x29,
2765
0x72,0x2b,0xf2,0x28,0xf2,0x2a,0x22,0x16,0xf9,0x16,0x91,0x8a,0x28,0x45,0xb4,0x22,
2766
0x7a,0x51,0x48,0x51,0x58,0x51,0x44,0x11,0xa3,0x88,0x55,0x14,0x5f,0xc4,0x2e,0xe2,
2767
0x14,0xa5,0x16,0xa5,0x17,0x65,0x16,0xf1,0x8a,0x04,0x45,0xa2,0x22,0x49,0x91,0xb4,
2768
0x48,0x5e,0xa4,0x2c,0x52,0x17,0xe9,0x8a,0x8c,0x45,0xa6,0xa2,0xda,0xa2,0x86,0xa2,
2769
0xa6,0xa2,0x96,0xa2,0xb6,0xa2,0x8e,0xa2,0xae,0xa2,0xee,0x22,0x73,0x51,0x7f,0xd1,
2770
0x60,0xd1,0x50,0xd1,0x70,0xd1,0x48,0xd1,0x68,0xd1,0x58,0xd1,0x78,0xd1,0x64,0xd1,
2771
0x54,0xd1,0x74,0x91,0xa5,0x68,0xbe,0x68,0xa1,0x68,0xa9,0x68,0xb9,0x68,0xa5,0x68,
2772
0xb5,0x08,0x27,0xb5,0x95,0xe2,0xa5,0x0e,0x52,0x27,0xa9,0x8b,0xd4,0x4d,0xea,0x21,
2773
0xf5,0x92,0x12,0xa5,0xbe,0x52,0x92,0x94,0x22,0xa5,0x49,0xe9,0xd2,0x10,0x69,0x98,
2774
0x34,0x42,0xca,0x90,0xb2,0xa4,0xf1,0x52,0xb6,0x94,0x23,0x4d,0x95,0xa6,0x4b,0x33,
2775
0xa5,0x5c,0x08,0x4f,0x2a,0x90,0x8a,0xa4,0x12,0xa9,0x54,0x2a,0x97,0x2a,0xa5,0x6a,
2776
0xa9,0x4e,0x6a,0x94,0x9a,0xa4,0xb5,0xd2,0x06,0x69,0x93,0xb4,0x45,0xda,0x26,0xed,
2777
0x90,0x76,0x49,0xbb,0xa5,0x66,0x69,0xbf,0x74,0x50,0x3a,0x24,0x1d,0x96,0x8e,0x48,
2778
0x47,0xa5,0x63,0xd2,0x71,0xe9,0xa4,0x74,0x4a,0x3a,0x2d,0xb5,0x48,0xe7,0xa5,0x0b,
2779
0xd2,0x25,0xe9,0xb2,0x74,0x45,0xba,0x2a,0xc5,0x15,0xdb,0x16,0xe3,0x8b,0x1d,0x8a,
2780
0x9d,0x8a,0x5d,0x8a,0xdd,0x8a,0x3d,0x8a,0xbd,0x8a,0x89,0xc5,0xbe,0xc5,0xa4,0x62,
2781
0x4a,0x31,0xad,0x98,0x5e,0x1c,0x52,0x1c,0x56,0x1c,0x51,0xcc,0x28,0x66,0x15,0xc7,
2782
0x17,0xb3,0x8b,0x39,0xc5,0xa9,0xc5,0xe9,0xc5,0x99,0xc5,0xbc,0x62,0x41,0xb1,0xa8,
2783
0x58,0x52,0x2c,0x2d,0x96,0x17,0x2b,0x8b,0xd5,0xc5,0xba,0x62,0x63,0xb1,0xa9,0xb8,
2784
0xb6,0xb8,0xa1,0xb8,0xa9,0xb8,0xa5,0xb8,0xad,0xb8,0xa3,0xb8,0xab,0xb8,0xbb,0xd8,
2785
0x5c,0xdc,0x5f,0x3c,0x58,0x3c,0x54,0x3c,0x5c,0x3c,0x02,0x19,0x2d,0x1e,0x2b,0x1e,
2786
0x2f,0x9e,0x2c,0x9e,0x2a,0x9e,0x2e,0xb6,0x14,0xcf,0x17,0x2f,0x14,0x2f,0x15,0x2f,
2787
0x17,0xaf,0x14,0xaf,0x16,0xe3,0x4a,0x6c,0x4b,0xf0,0x25,0x0e,0x25,0x4e,0x25,0x2e,
2788
0x25,0x6e,0x25,0x1e,0x25,0x5e,0x25,0xc4,0x12,0xdf,0x12,0x52,0x09,0xa5,0x84,0x56,
2789
0x42,0x2f,0x09,0x29,0x09,0x2b,0x89,0x28,0x61,0x94,0xb0,0x4a,0xe2,0x4b,0xd8,0x25,
2790
0x9c,0x92,0xd4,0x92,0xf4,0x92,0xcc,0x12,0x5e,0x89,0xa0,0x44,0x54,0x22,0x29,0x91,
2791
0x96,0xc8,0x4b,0x94,0x25,0xea,0x12,0x5d,0x89,0xb1,0xc4,0x54,0x52,0x5b,0xd2,0x50,
2792
0xd2,0x54,0xd2,0x52,0xd2,0x56,0xd2,0x51,0xd2,0x55,0xd2,0x5d,0x62,0x2e,0xe9,0x2f,
2793
0x19,0x2c,0x19,0x2a,0x19,0x2e,0x19,0x29,0x19,0x2d,0x19,0x2b,0x19,0x2f,0x99,0x2c,
2794
0x99,0x2a,0x99,0x2e,0xb1,0x94,0xcc,0x97,0x2c,0x94,0x2c,0x95,0x2c,0x97,0xac,0x94,
2795
0xac,0x96,0xe0,0x64,0xb6,0x32,0xbc,0xcc,0x41,0xe6,0x24,0x73,0x91,0xb9,0xc9,0x3c,
2796
0x64,0x5e,0x32,0xa2,0xcc,0x57,0x46,0x92,0x51,0x64,0x34,0x19,0x5d,0x16,0x22,0x0b,
2797
0x93,0x45,0xc8,0x18,0x32,0x96,0x2c,0x5e,0xc6,0x96,0x71,0x64,0xa9,0xb2,0x74,0x59,
2798
0xa6,0x8c,0x27,0x13,0xc8,0x44,0x32,0x89,0x4c,0x2a,0x93,0xcb,0x94,0x32,0xb5,0x4c,
2799
0x27,0x33,0xca,0x4c,0xb2,0x5a,0x59,0x83,0xac,0x49,0xd6,0x22,0x6b,0x93,0x75,0xc8,
2800
0xba,0x64,0xdd,0x32,0xb3,0xac,0x5f,0x36,0x28,0x1b,0x92,0x0d,0xcb,0x46,0x64,0xa3,
2801
0xb2,0x31,0xd9,0xb8,0x6c,0x52,0x36,0x25,0x9b,0x96,0x59,0x64,0xf3,0xb2,0x05,0xd9,
2802
0x92,0x6c,0x59,0xb6,0x22,0x5b,0x95,0xe1,0xe4,0xb6,0x72,0xbc,0xdc,0x41,0xee,0x24,
2803
0x77,0x91,0xbb,0xc9,0x3d,0xe4,0x5e,0x72,0xa2,0xdc,0x57,0x4e,0x92,0x53,0xe4,0x34,
2804
0x39,0x5d,0x1e,0x22,0x0f,0x93,0x47,0xc8,0x19,0x72,0x96,0x3c,0x5e,0xce,0x96,0x73,
2805
0xe4,0xa9,0xf2,0x74,0x79,0xa6,0x9c,0x27,0x17,0xc8,0x45,0x72,0x89,0x5c,0x2a,0x97,
2806
0xcb,0x95,0x72,0xb5,0x5c,0x27,0x37,0xca,0x4d,0xf2,0x5a,0x79,0x83,0xbc,0x49,0xde,
2807
0x22,0x6f,0x93,0x77,0xc8,0xbb,0xe4,0xdd,0x72,0xb3,0xbc,0x5f,0x3e,0x28,0x1f,0x92,
2808
0x0f,0xcb,0x47,0xe4,0xa3,0xf2,0x31,0xf9,0xb8,0x7c,0x52,0x3e,0x25,0x9f,0x96,0x5b,
2809
0xe4,0xf3,0xf2,0x05,0xf9,0x92,0x7c,0x59,0xfe,0x12,0xb2,0x22,0x5f,0x95,0xe3,0x4a,
2810
0x6d,0x4b,0xf1,0xa5,0x0e,0xa5,0x4e,0xa5,0x2e,0xa5,0x6e,0xa5,0x1e,0xa5,0x5e,0xa5,
2811
0xc4,0x52,0xdf,0x52,0x52,0x29,0xa5,0x94,0x56,0x4a,0x2f,0x0d,0x29,0x0d,0x2b,0x8d,
2812
0x28,0x65,0x94,0xb2,0x4a,0xe3,0x4b,0xd9,0xa5,0x9c,0xd2,0xd4,0xd2,0xf4,0xd2,0xcc,
2813
0x52,0x5e,0xa9,0xa0,0x54,0x54,0x2a,0x29,0x95,0x96,0xca,0x4b,0x95,0xa5,0xea,0x52,
2814
0x5d,0xa9,0xb1,0xd4,0x54,0x5a,0x5b,0xda,0x50,0xda,0x54,0xda,0x52,0xda,0x56,0xda,
2815
0x51,0xda,0x55,0xda,0x5d,0x6a,0x2e,0xed,0x2f,0x1d,0x2c,0xbd,0xf7,0x37,0x67,0xa8,
2816
0x74,0xb8,0x74,0xa4,0x74,0xb4,0x74,0xac,0x74,0xbc,0x74,0xb2,0x74,0xaa,0x74,0xba,
2817
0xd4,0x52,0x3a,0x5f,0xba,0x50,0xba,0x54,0xba,0x5c,0xba,0x52,0xba,0x5a,0x8a,0x2b,
2818
0xb3,0x2d,0xc3,0x97,0x39,0x94,0x39,0x95,0xb9,0x94,0xb9,0x95,0x79,0x94,0x79,0x95,
2819
0x11,0xcb,0x7c,0xcb,0x48,0x65,0x94,0x32,0x5a,0x19,0xbd,0x2c,0xa4,0x2c,0xac,0x2c,
2820
0xa2,0x8c,0x51,0xc6,0x2a,0x8b,0x2f,0x63,0x97,0x71,0xca,0x52,0xcb,0xd2,0xcb,0x32,
2821
0xcb,0x78,0x65,0x82,0x32,0x51,0x99,0xa4,0x4c,0x5a,0x26,0x2f,0x53,0x96,0xa9,0xcb,
2822
0x74,0x65,0xc6,0x32,0x53,0x59,0x6d,0x59,0x43,0x59,0x53,0x59,0x4b,0x59,0x5b,0x59,
2823
0x47,0x59,0x57,0x59,0x77,0x99,0xb9,0xac,0x6f,0x9d,0x75,0xd6,0xf9,0x23,0xf4,0x43,
2824
0x06,0xcb,0x86,0xca,0x86,0xcb,0x1e,0x94,0x8d,0x94,0x8d,0x96,0x8d,0x95,0x8d,0x97,
2825
0x4d,0x96,0x4d,0x95,0x4d,0x97,0x59,0xca,0xe6,0xcb,0x16,0xca,0x96,0xca,0x96,0xcb,
2826
0x56,0xca,0x56,0xcb,0x70,0x0a,0x5b,0x05,0x5e,0xe1,0xa0,0x70,0x52,0xb8,0x28,0xdc,
2827
0x14,0x1e,0x0a,0x2f,0x05,0x51,0xe1,0xab,0x20,0x29,0x28,0x0a,0xaa,0x82,0xa6,0xa0,
2828
0x2b,0x82,0x15,0x21,0x8a,0x50,0x48,0x98,0x22,0x5c,0x11,0xa1,0x60,0x28,0x58,0x8a,
2829
0x78,0x05,0x5b,0xc1,0x51,0xa4,0x2a,0xd2,0x15,0x99,0x0a,0x9e,0x82,0xaf,0x10,0x28,
2830
0x44,0x0a,0x89,0x42,0xaa,0x90,0x29,0xe4,0x0a,0x85,0x42,0xa9,0x50,0xbd,0x81,0x5a,
2831
0xa1,0xc5,0xd0,0x29,0x0c,0x0a,0xa3,0xa2,0x5a,0x61,0x52,0xd4,0x28,0x6a,0x15,0x0d,
2832
0x8a,0x26,0x45,0xb3,0xa2,0x45,0xd1,0xa6,0x68,0x57,0x74,0x28,0x3a,0x21,0x5d,0x8a,
2833
0x1b,0x8a,0x6e,0x45,0xaf,0xc2,0xac,0xe8,0x53,0xf4,0x2b,0x06,0x14,0x83,0x8a,0x7b,
2834
0x8a,0x21,0xc5,0xb0,0xe2,0x81,0x62,0x44,0xf1,0x10,0x32,0xaa,0x18,0x53,0x8c,0x2b,
2835
0x26,0x15,0x4f,0x14,0x53,0x8a,0x69,0x85,0x45,0x31,0xaf,0x58,0x50,0x2c,0x29,0x96,
2836
0x15,0x2f,0x15,0x2b,0x8a,0x55,0x05,0x4e,0x69,0xab,0xb4,0x53,0xe2,0x95,0x0e,0x4a,
2837
0x27,0xa5,0x8b,0xd2,0x55,0xe9,0xa6,0x74,0x57,0x7a,0x28,0xbd,0x94,0x44,0xa5,0xaf,
2838
0x92,0xa4,0xa4,0x28,0x69,0x4a,0xba,0x32,0x44,0x19,0xa6,0x0c,0x57,0x46,0x28,0x19,
2839
0x4a,0x96,0x32,0x5e,0xc9,0x56,0x72,0x94,0xa9,0xca,0x74,0x65,0xa6,0x92,0xa7,0x14,
2840
0x28,0x45,0x4a,0x89,0x52,0xaa,0x94,0x2b,0x95,0x4a,0xb5,0x52,0xfb,0x0b,0x3a,0xa5,
2841
0x51,0x69,0x52,0xd6,0x28,0x6b,0x95,0x0d,0xca,0x26,0x65,0x8b,0xb2,0x4d,0xd9,0xae,
2842
0xec,0x50,0x76,0x29,0xbb,0x95,0x66,0x65,0xbf,0x72,0x50,0x39,0xa4,0x1c,0x56,0x8e,
2843
0x28,0x47,0x95,0x63,0xca,0x71,0xe5,0xa4,0x72,0x4a,0x39,0xad,0xb4,0x28,0xe7,0x95,
2844
0xcf,0xd7,0x59,0xe7,0x1f,0x82,0x05,0xc8,0xb2,0x72,0x55,0x69,0x5b,0xee,0x50,0xee,
2845
0x52,0xee,0x51,0x4e,0x2c,0x27,0x95,0xd3,0xca,0x43,0xca,0xc3,0x7f,0x21,0xa2,0x3c,
2846
0xbe,0x3c,0xb5,0x9c,0x57,0x2e,0x29,0x57,0x96,0x1b,0xcb,0x1b,0xca,0xdb,0xca,0xbb,
2847
0xcb,0x07,0xcb,0x47,0xca,0xc7,0xcb,0xa7,0xcb,0x17,0xca,0x57,0xca,0x6d,0x2b,0x9c,
2848
0x2a,0x3c,0x2a,0x7c,0x2b,0x68,0x15,0x61,0x15,0xac,0x0a,0x4e,0x45,0x66,0x85,0xa8,
2849
0x42,0x5e,0xa1,0xab,0x30,0x56,0x98,0x2a,0x1a,0x2a,0x9a,0x2b,0x5a,0x2a,0xda,0x2a,
2850
0x3a,0x2a,0xba,0x2a,0xba,0x2b,0xcc,0x15,0xfd,0x15,0x83,0x15,0x43,0x15,0xc3,0x15,
2851
0x23,0x15,0xa3,0x15,0x63,0x15,0xe3,0x15,0x93,0x15,0x53,0x15,0xd3,0x15,0x96,0x8a,
2852
0xf9,0x8a,0x85,0x8a,0xa5,0x8a,0xe5,0x8a,0x95,0x8a,0xd5,0x0a,0x9c,0xca,0x56,0x85,
2853
0x57,0x39,0xa9,0xdc,0x54,0x5e,0x2a,0x5f,0x15,0x4d,0x15,0xfc,0x17,0x10,0xa2,0x8a,
2854
0x50,0xb1,0x54,0x49,0xbf,0x0a,0x6c,0x55,0xca,0xbf,0x34,0xa9,0x90,0x4c,0x95,0x40,
2855
0x25,0xfc,0x83,0x88,0x54,0x12,0x95,0x54,0x25,0x57,0xa9,0x55,0x3a,0x95,0x51,0x65,
2856
0x52,0xd5,0xaa,0x1a,0x54,0x4d,0xaa,0x16,0x55,0x9b,0xaa,0x43,0xd5,0xa5,0xea,0x56,
2857
0x99,0x55,0xfd,0xaa,0x41,0xd5,0x90,0x6a,0x58,0x35,0xa2,0x1a,0x55,0x8d,0xa9,0xc6,
2858
0x55,0x93,0xaa,0x29,0xd5,0xb4,0xca,0xa2,0x9a,0x57,0x2d,0xa8,0x96,0x54,0xcb,0xaa,
2859
0x15,0xd5,0xaa,0x0a,0xa7,0xb6,0x55,0xe3,0xd5,0x0e,0x6a,0x27,0xb5,0x8b,0xda,0x4d,
2860
0xed,0xa1,0xf6,0x52,0x7b,0x63,0x10,0xd5,0x14,0x75,0x88,0x9a,0xa1,0x66,0xab,0xd3,
2861
0xd5,0x02,0xb5,0x54,0xad,0x56,0x57,0xff,0x16,0x26,0x75,0xad,0xba,0x7e,0x9d,0x75,
2862
0xd6,0xf9,0x0b,0x69,0x50,0x37,0xa9,0x5b,0xd4,0x6d,0xea,0x0e,0x75,0x97,0xba,0x5b,
2863
0x6d,0x56,0xf7,0xab,0x07,0xd5,0xf7,0x7e,0x87,0xfb,0xea,0x07,0xea,0x87,0xea,0x47,
2864
0xea,0xc7,0xea,0x09,0xf5,0x13,0xf5,0x53,0xf5,0x8c,0x7a,0x4e,0xfd,0x5c,0xbd,0xa8,
2865
0x7e,0xa1,0x7e,0xa9,0x7e,0xa5,0x06,0x1a,0x1b,0x8d,0x9d,0xc6,0x5e,0x43,0xd0,0x38,
2866
0x6b,0x5c,0x35,0xee,0x1a,0x4f,0x8d,0xb7,0xc6,0x47,0xe3,0xa7,0x21,0x6b,0xa8,0x9a,
2867
0x40,0x4d,0xb0,0x26,0x54,0x13,0xae,0x89,0xd4,0x30,0x35,0x71,0x9a,0x24,0x4d,0xb2,
2868
0x26,0x45,0x93,0xa6,0xc9,0xd0,0x70,0x35,0x7c,0x8d,0x50,0x23,0xd6,0x14,0x69,0x64,
2869
0x1a,0x85,0x46,0xa5,0xd1,0x6a,0x0c,0x9a,0x6a,0x4d,0x8d,0xa6,0x5e,0xd3,0xa8,0x69,
2870
0xd6,0xb4,0x6a,0xda,0x35,0x9d,0x9a,0x1b,0x9a,0x5e,0x4d,0x9f,0x66,0x40,0x73,0x4f,
2871
0x73,0x5f,0xf3,0x40,0xf3,0x50,0xf3,0x48,0xf3,0x58,0x33,0xa1,0x79,0xa2,0x79,0xaa,
2872
0x99,0xd1,0xcc,0x69,0x9e,0x6b,0x16,0x35,0x2f,0x34,0x2f,0x35,0xaf,0x34,0xa0,0xd2,
2873
0xa6,0xd2,0xae,0xd2,0xbe,0x92,0x50,0xe9,0x5c,0xe9,0x5a,0xe9,0x5e,0xe9,0x59,0xe9,
2874
0x5d,0xe9,0x53,0xe9,0x57,0x49,0xae,0xa4,0x56,0x06,0x56,0x06,0x57,0x86,0x56,0x86,
2875
0x57,0x46,0x56,0x32,0x2b,0xe3,0x2a,0x93,0x2a,0x93,0x2b,0x53,0x2a,0xd3,0x2a,0x33,
2876
0x2a,0xb9,0x95,0xfc,0x4a,0x61,0xa5,0xb8,0xb2,0xa8,0x52,0x56,0xa9,0xa8,0x54,0x55,
2877
0x6a,0x2b,0x0d,0x95,0xd5,0x95,0x35,0x95,0xf5,0x95,0x8d,0x95,0xcd,0x95,0xad,0x95,
2878
0xed,0x95,0x9d,0x95,0x37,0x2a,0x7b,0x2b,0xfb,0x2a,0x07,0x2a,0xef,0x55,0xde,0xaf,
2879
0x7c,0x50,0xf9,0xb0,0xf2,0x51,0xe5,0xe3,0xca,0x89,0xca,0x27,0x95,0x4f,0x2b,0x67,
2880
0x2a,0xe7,0x2a,0x9f,0x57,0x2e,0x56,0xbe,0xa8,0x7c,0x59,0xf9,0xaa,0x12,0x68,0x6d,
2881
0xb4,0x76,0x5a,0x7b,0x2d,0x41,0xeb,0xac,0x75,0xd5,0xba,0x6b,0x3d,0xb5,0xde,0x5a,
2882
0x1f,0xad,0x9f,0x96,0xac,0xa5,0x6a,0x03,0xb5,0xc1,0xda,0x50,0x6d,0xb8,0x36,0x52,
2883
0xcb,0xd4,0xc6,0x69,0x93,0xb4,0xc9,0xda,0x14,0x6d,0x9a,0x36,0x43,0xcb,0xd5,0xf2,
2884
0xb5,0x42,0xad,0x58,0x5b,0xa4,0x95,0xc1,0xd7,0x5b,0x95,0x56,0xab,0x35,0x68,0xab,
2885
0xb5,0x35,0xda,0x7a,0x6d,0xa3,0xb6,0x59,0xdb,0xaa,0x6d,0xd7,0x76,0x6a,0x6f,0x68,
2886
0x7b,0xb5,0x7d,0xda,0x01,0xed,0x3d,0xed,0x7d,0xed,0x03,0xed,0x43,0xed,0x23,0xed,
2887
0x63,0xed,0x84,0xf6,0x89,0xf6,0xa9,0x76,0x46,0x3b,0xa7,0x7d,0xae,0x5d,0xd4,0xbe,
2888
0xd0,0xbe,0xd4,0xbe,0xd2,0x02,0x9d,0x8d,0xce,0x4e,0x67,0xaf,0x23,0xe8,0x9c,0x75,
2889
0xae,0x3a,0x77,0x9d,0xa7,0xce,0x5b,0xe7,0xa3,0xf3,0xd3,0x91,0x75,0x54,0x5d,0xa0,
2890
0x2e,0x58,0x17,0xaa,0x0b,0xd7,0x45,0xea,0x98,0xba,0x38,0x5d,0x92,0x2e,0x59,0x97,
2891
0xa2,0x4b,0xd3,0x65,0xe8,0xb8,0x3a,0xbe,0x4e,0xa8,0x13,0xeb,0x8a,0x74,0x32,0x9d,
2892
0x42,0xa7,0xd2,0x69,0x75,0x06,0x5d,0xb5,0xae,0x46,0x57,0xaf,0x6b,0xd4,0x35,0xeb,
2893
0x5a,0x75,0xed,0xba,0x4e,0xdd,0x0d,0x5d,0xaf,0xae,0x4f,0x37,0xa0,0xbb,0x07,0xb9,
2894
0xaf,0x7b,0xa0,0x7b,0xa8,0x7b,0xa4,0x7b,0xac,0x9b,0xd0,0x3d,0xd1,0x3d,0xd5,0xcd,
2895
0xe8,0xe6,0x74,0xcf,0x75,0x8b,0xba,0x17,0xba,0x97,0xba,0x57,0x3a,0xa0,0xb7,0xd1,
2896
0xdb,0xe9,0xed,0xf5,0x04,0xbd,0xb3,0xde,0x55,0xef,0xae,0xf7,0xd4,0x7b,0xeb,0x7d,
2897
0xf4,0x7e,0x7a,0xb2,0x9e,0xaa,0x0f,0xd4,0x07,0xeb,0x43,0xf5,0xe1,0xfa,0x48,0x3d,
2898
0x53,0x1f,0xa7,0x4f,0xd2,0x27,0xeb,0x53,0xf4,0x69,0xfa,0x0c,0x3d,0x57,0xcf,0xd7,
2899
0x0b,0xf5,0x62,0x7d,0x91,0x5e,0xa6,0x57,0xe8,0x55,0x7a,0xad,0xde,0xa0,0xaf,0xd6,
2900
0xd7,0xe8,0xeb,0xf5,0x8d,0xfa,0x66,0x7d,0xab,0xbe,0x5d,0xdf,0xa9,0xbf,0xa1,0xef,
2901
0xd5,0xf7,0xe9,0x07,0xf4,0xf7,0xf4,0xf7,0xf5,0x0f,0xf4,0x0f,0xf5,0x8f,0xf4,0x8f,
2902
0xf5,0x13,0xfa,0x27,0xfa,0xa7,0xfa,0x19,0xfd,0x9c,0xfe,0xb9,0x7e,0x51,0xff,0x42,
2903
0xff,0x52,0xff,0x4a,0x0f,0xaa,0x6c,0xaa,0xec,0xaa,0xec,0xab,0x08,0x55,0xce,0x55,
2904
0xae,0x55,0xee,0x55,0x9e,0x55,0xde,0x55,0x3e,0x55,0x7e,0x55,0xe4,0x2a,0x6a,0x55,
2905
0x60,0x55,0x70,0x55,0x68,0x55,0x78,0x55,0x64,0x15,0xb3,0x2a,0xae,0x2a,0xa9,0x2a,
2906
0xb9,0x2a,0xa5,0x2a,0xad,0x2a,0xa3,0x8a,0x5b,0xc5,0xaf,0x12,0x56,0x89,0xab,0x8a,
2907
0xaa,0x64,0x55,0x8a,0x2a,0x55,0x95,0xb6,0xca,0x50,0x55,0x5d,0x55,0x53,0x55,0x5f,
2908
0xd5,0x58,0xd5,0x5c,0xd5,0x5a,0xd5,0x5e,0xd5,0x59,0x75,0xa3,0xaa,0xb7,0xaa,0xaf,
2909
0x6a,0xa0,0xea,0x5e,0xd5,0xfd,0xaa,0x07,0x55,0x0f,0xab,0x1e,0x55,0x3d,0xae,0x9a,
2910
0xa8,0x7a,0x52,0xf5,0xb4,0x6a,0xa6,0x6a,0xae,0xea,0x79,0xd5,0x62,0xd5,0x8b,0xaa,
2911
0x97,0x55,0xaf,0xaa,0x80,0xc1,0xc6,0x60,0x67,0xb0,0x37,0x10,0x0c,0xce,0x06,0x57,
2912
0x83,0xbb,0xc1,0xd3,0xe0,0x6d,0xf0,0x31,0xf8,0x19,0xc8,0x06,0xaa,0x21,0xd0,0x10,
2913
0x6c,0x08,0x35,0x84,0x1b,0x22,0x0d,0x4c,0x43,0x9c,0x21,0xc9,0x90,0x6c,0x48,0x31,
2914
0xa4,0x19,0x32,0x0c,0x5c,0x03,0xdf,0x20,0x34,0x88,0x0d,0x45,0x06,0x99,0x41,0x61,
2915
0x50,0x19,0xb4,0x06,0x83,0xa1,0xda,0x50,0x63,0xa8,0x37,0x34,0x1a,0x9a,0x0d,0xad,
2916
0x86,0x76,0x43,0xa7,0xe1,0x86,0xa1,0xd7,0xd0,0x67,0x18,0x30,0xdc,0x33,0xdc,0x37,
2917
0x3c,0x30,0x3c,0x34,0x3c,0x32,0x3c,0x36,0x4c,0x18,0x9e,0x18,0x9e,0x1a,0x66,0x0c,
2918
0x73,0x86,0xe7,0x86,0x45,0xc3,0x0b,0xc3,0x4b,0xc3,0x2b,0x03,0x30,0xda,0x18,0xed,
2919
0x8c,0xf6,0x46,0x82,0xd1,0xd9,0xe8,0x6a,0x74,0x37,0x7a,0x1a,0xbd,0x8d,0x3e,0x46,
2920
0x3f,0x23,0xd9,0x48,0x35,0x06,0x1a,0x83,0x8d,0xa1,0xc6,0x70,0x63,0xa4,0x91,0x69,
2921
0x8c,0x33,0x26,0x19,0x93,0x8d,0x29,0xc6,0x34,0x63,0x86,0x91,0x6b,0xe4,0x1b,0x85,
2922
0x46,0xb1,0xb1,0xc8,0x28,0x33,0x2a,0x8c,0x2a,0xa3,0xd6,0x68,0x30,0x56,0x1b,0x6b,
2923
0x8c,0xf5,0xc6,0x46,0x63,0xb3,0xb1,0xd5,0xd8,0x6e,0xec,0x34,0xde,0x30,0xf6,0x1a,
2924
0xfb,0x8c,0x03,0xc6,0x7b,0x90,0xfb,0xc6,0x07,0xc6,0x87,0xc6,0x47,0xc6,0xc7,0xc6,
2925
0x09,0xe3,0x13,0xe3,0x53,0xe3,0x8c,0x71,0xce,0xf8,0xdc,0xb8,0x68,0x7c,0x61,0x7c,
2926
0x69,0x7c,0x65,0x04,0x17,0x6c,0x2e,0xd8,0x5d,0xb0,0xbf,0x40,0xb8,0xe0,0x7c,0xc1,
2927
0xf5,0x82,0xfb,0x05,0xcf,0x0b,0xde,0x17,0x7c,0x2e,0xf8,0x5d,0x20,0x5f,0xa0,0x5e,
2928
0x08,0x5c,0xe7,0x5f,0x80,0xb5,0xff,0xf7,0xac,0x27,0x96,0xec,0x36,0x02,0x90,0x8e,
2929
0x1d,0xdb,0xc0,0xe3,0x77,0x61,0x7e,0x08,0x2b,0xe3,0x60,0x79,0x60,0xe3,0xda,0xf1,
2930
0x01,0x98,0x53,0x60,0x9e,0x0b,0xd6,0xf2,0x70,0x58,0x49,0x7d,0xe3,0xf8,0xf5,0x79,
2931
0xaf,0xeb,0xc3,0xd0,0x4d,0x36,0xae,0xe5,0x38,0x2c,0xdf,0x80,0xe5,0x1b,0xb1,0xdc,
2932
0x0e,0xcb,0xb7,0xc0,0xfc,0x28,0x76,0x8f,0x08,0xec,0xbc,0x08,0xec,0xbc,0x08,0xec,
2933
0xbc,0x08,0xac,0x3f,0x03,0x6b,0x67,0x60,0xed,0x0c,0xac,0x9d,0x81,0xb5,0xc7,0x60,
2934
0xd7,0x8f,0xc5,0xfa,0xc5,0x62,0xfd,0x62,0xb1,0x7e,0xb1,0x6f,0xb4,0xa3,0xfe,0x6c,
2935
0xac,0x1f,0x1b,0xeb,0xc7,0xc6,0xfa,0xb1,0xb1,0x76,0x0e,0x56,0x9f,0x8e,0xf5,0x4b,
2936
0x7f,0xa3,0xbc,0x01,0xcb,0x37,0x62,0xf9,0x6b,0x5b,0xa2,0xf9,0x7c,0x8c,0xcd,0x27,
2937
0x13,0x3b,0x2f,0x13,0x3b,0x2f,0x13,0x3b,0x2f,0x13,0xeb,0xcf,0xc3,0xda,0x79,0x58,
2938
0x3b,0x0f,0x6b,0xe7,0x61,0xed,0xe7,0xb1,0xeb,0xe7,0x62,0xfd,0x72,0xb1,0x7e,0xb9,
2939
0x58,0xbf,0xdc,0x37,0xda,0x51,0x7f,0x09,0xd6,0x4f,0x82,0xf5,0x93,0x60,0xfd,0x24,
2940
0x58,0xbb,0x14,0xab,0x97,0xbe,0x61,0x7f,0x1b,0x6c,0xdc,0x36,0x58,0x79,0x13,0x56,
2941
0xde,0x84,0x95,0x7d,0xb0,0xb2,0x0f,0xe6,0x27,0x1c,0x36,0x3f,0x1c,0x56,0xde,0x80,
2942
0x95,0x37,0x60,0xe5,0xcd,0x58,0x79,0x33,0x56,0xb6,0xc7,0xca,0x28,0x0f,0xc7,0xf2,
2943
0x0c,0x2c,0x8f,0xc0,0xee,0x9b,0x89,0xe5,0x11,0xd8,0x7d,0x33,0xb1,0x3c,0x02,0xbb,
2944
0x4e,0x26,0x96,0x47,0x60,0xe3,0xc8,0xc4,0xf2,0x08,0xec,0x3a,0x99,0x58,0x7e,0x1c,
2945
0x1b,0xc7,0x39,0x2c,0x3f,0x8e,0x5d,0xe7,0x1c,0x96,0x1f,0xc7,0xae,0x73,0x0e,0xcb,
2946
0x8f,0x63,0x7e,0x3a,0x87,0xe5,0x91,0xd8,0x79,0xdc,0x37,0xe2,0x6a,0x23,0xe6,0x8f,
2947
0x8d,0x58,0xd9,0x06,0x2b,0xdb,0x60,0xe5,0x4d,0x58,0x79,0x13,0x56,0xf6,0xc1,0xca,
2948
0x3e,0x58,0x79,0x33,0x96,0x47,0x81,0xb5,0xfa,0x6c,0xec,0x18,0x5d,0x3f,0x1b,0xcb,
2949
0xa3,0xb1,0xfb,0xe7,0x60,0x39,0x13,0xb3,0x2f,0x1f,0xcb,0x99,0x58,0x3d,0xff,0x8d,
2950
0x76,0x7b,0xac,0x6c,0x8f,0x95,0x6f,0x83,0xb5,0x32,0xca,0x63,0xb0,0xf3,0xce,0x63,
2951
0x79,0x0c,0x76,0xde,0x79,0x2c,0x8f,0xc1,0xce,0x3b,0x8f,0xe5,0x03,0x1b,0xd6,0x8e,
2952
0x63,0xb1,0x79,0xe5,0x62,0x79,0x2c,0x36,0xaf,0x5c,0x2c,0x47,0xe5,0xad,0x58,0x19,
2953
0xe5,0x09,0xd8,0xf5,0xf3,0xb0,0x3c,0x01,0xbb,0x7e,0x1e,0x96,0x27,0x60,0xd7,0xcf,
2954
0xc3,0xf2,0x44,0xac,0x5f,0x3e,0x96,0x27,0x62,0xf3,0xcf,0xc7,0xf2,0x44,0xec,0xbc,
2955
0x7c,0x2c,0x4f,0xc4,0xce,0xcb,0xc7,0xf2,0x24,0xac,0x5e,0x8c,0xe5,0x49,0x58,0xbd,
2956
0x18,0xcb,0xd9,0x98,0x9f,0x24,0x58,0xce,0xc6,0xe6,0x21,0xc1,0x72,0x36,0x36,0x0f,
2957
0x09,0x96,0xb3,0xb1,0xf5,0x2a,0xc1,0x72,0x36,0x36,0x2f,0x09,0x96,0xb3,0x31,0x3f,
2958
0x4a,0xb0,0xfc,0x24,0x36,0xce,0x42,0x2c,0xe7,0x60,0xb9,0xf4,0x8d,0x32,0x5a,0x57,
2959
0xa7,0xb0,0xf9,0x15,0x63,0xf9,0x29,0x2c,0x0e,0x8a,0xb1,0xfc,0x14,0x36,0xde,0xe2,
2960
0x37,0xe6,0x87,0x6c,0xbb,0x1b,0xb3,0xed,0x6e,0xec,0xde,0xbb,0xb1,0x7b,0xef,0xc6,
2961
0xd6,0xce,0xa9,0x37,0xd6,0x51,0xf1,0x1b,0x6b,0xa9,0xf8,0x8d,0x38,0x40,0xb1,0xc5,
2962
0xc4,0xe2,0x8c,0x8f,0xe5,0x31,0x58,0x7d,0x0c,0x56,0x3e,0x8f,0xe5,0x61,0xd8,0x79,
2963
0xe9,0x58,0xce,0xc0,0x72,0x1e,0x96,0xc7,0x62,0x79,0xee,0x1b,0xf6,0xb5,0xc7,0xc6,
2964
0x64,0xff,0xc6,0x3e,0x69,0xf3,0xc6,0x1e,0x63,0xf3,0x46,0x3d,0xee,0x8d,0x7a,0xdc,
2965
0x1b,0xf5,0xf6,0x6f,0xd4,0xbf,0x79,0x1d,0xf0,0x46,0x3d,0x78,0xe3,0x39,0x61,0xf3,
2966
0xc6,0x1e,0xfb,0x7a,0x9f,0xda,0xfc,0x46,0xfd,0xeb,0xe3,0xff,0x85,0xf9,0x79,0x16,
2967
0xcb,0x8f,0x63,0xe3,0x3c,0x87,0xe5,0xd1,0x58,0x9e,0xf3,0xc6,0xfc,0x7c,0xb0,0xf9,
2968
0xf9,0xbc,0x51,0xb6,0x79,0xa3,0x0e,0x1d,0xdf,0xc6,0xad,0xf5,0xff,0x74,0xc3,0x5a,
2969
0x9e,0xfd,0x86,0x1f,0x90,0x4f,0x5e,0xfb,0xe3,0xb5,0x2f,0x8e,0x63,0x7e,0x3f,0xf7,
2970
0xc6,0xfa,0x03,0xd8,0x7a,0x03,0x6f,0x3c,0xf7,0x70,0x6f,0x3c,0x33,0x70,0xd8,0xf8,
2971
0x71,0xd8,0xf8,0x51,0x3e,0x81,0xe5,0x2f,0xff,0x3f,0xf6,0xce,0x04,0x40,0xc7,0xe2,
2972
0xf1,0xe3,0xcf,0xfb,0xee,0xbe,0xbb,0xd6,0x7d,0x76,0x29,0xd7,0x16,0xc2,0xae,0xbd,
2973
0x59,0xe7,0x5a,0xd6,0x99,0x90,0x90,0x54,0xae,0x90,0x5c,0xeb,0x08,0x95,0xca,0x91,
2974
0xd2,0x49,0x87,0x4a,0x27,0x9d,0xa4,0x72,0x25,0x54,0xce,0x0a,0x91,0x12,0x15,0x65,
2975
0x8b,0x90,0x44,0x42,0xba,0x48,0xf5,0xff,0xcc,0x3e,0xdf,0x27,0xe3,0xf9,0xdb,0x1f,
2976
0xaa,0x5f,0xbf,0x8e,0xf7,0x19,0x1f,0xdf,0x99,0x79,0xe6,0x99,0x67,0x66,0x9e,0x99,
2977
0x79,0x9e,0xf7,0x99,0x79,0x66,0xad,0xfb,0x68,0x11,0x1d,0x53,0x44,0xee,0x62,0x72,
2978
0x17,0x53,0x7f,0x58,0x44,0xfd,0x61,0x11,0xb9,0x8b,0xc9,0x5d,0x4c,0xd7,0xb7,0x88,
2979
0xae,0x6f,0x11,0xb9,0x8b,0xc9,0x5d,0x4c,0xf9,0x2f,0xa2,0xbc,0x17,0x91,0xbb,0x98,
2980
0xdc,0xc5,0xd4,0x9e,0x8b,0xa8,0x3d,0x17,0x91,0xbb,0x98,0xdc,0xc5,0x74,0x1d,0x8b,
2981
0xe8,0x1a,0x16,0x91,0xbb,0x98,0xdc,0xc5,0xd4,0x9e,0x2b,0xaa,0xbe,0x57,0x54,0xfb,
2982
0xad,0xa8,0xf6,0x5b,0x51,0xfd,0x6f,0x41,0xf5,0xbf,0x05,0xad,0xeb,0xdc,0xd5,0xea,
2983
0xff,0xbd,0xfb,0x6a,0x25,0xeb,0x3e,0x1e,0x69,0xdd,0x03,0x23,0xad,0xfb,0x7c,0xa4,
2984
0x75,0x8f,0xf4,0xfc,0xa3,0xe5,0x17,0x6d,0xb9,0x23,0x2d,0xbf,0x48,0xb5,0xe3,0x48,
2985
0xb5,0xeb,0x48,0xa5,0xa7,0x67,0xd0,0xbd,0xee,0x26,0xaf,0x57,0x63,0xbf,0x16,0x46,
2986
0x05,0xdd,0xbe,0xe0,0x6a,0x3d,0x33,0x45,0xe9,0x79,0x29,0x5a,0x9a,0x5f,0x5a,0x59,
2987
0x1a,0x21,0x35,0x7d,0x4b,0xf7,0xa0,0xdb,0x3e,0x4d,0x59,0x0c,0x87,0x89,0x41,0xb7,
2988
0x6e,0x98,0xeb,0x5c,0x22,0xe2,0x48,0x9b,0x59,0x10,0x74,0x8f,0xc9,0xc2,0x5e,0xdb,
2989
0x7a,0x36,0x9b,0x2a,0xbd,0x4b,0xe1,0x4c,0xbf,0x3f,0x51,0xf6,0xfb,0xa5,0x93,0xa4,
2990
0x8f,0x49,0x9f,0x92,0x4e,0xf3,0xe2,0xb6,0xce,0x33,0x49,0xf6,0xa7,0xa4,0xb3,0xe4,
2991
0x3f,0xd7,0x8b,0xdf,0x3a,0xc6,0xe8,0x1b,0x76,0x1a,0x65,0xf7,0xfc,0x16,0x5b,0x61,
2992
0x8c,0xbe,0x29,0x9d,0x0d,0xf3,0x75,0x8e,0x75,0xf2,0x5b,0xa7,0x63,0x96,0xc3,0x12,
2993
0x78,0x19,0x96,0xc2,0x32,0x78,0x40,0xe7,0x7f,0x02,0x4a,0x45,0xba,0xe5,0x63,0xd4,
2994
0x84,0x2f,0x11,0xe9,0x1e,0x1f,0x25,0xf7,0x19,0x72,0x9f,0xa6,0x70,0xb1,0x91,0xee,
2995
0xf5,0x38,0x4d,0x5a,0x53,0x9a,0xaa,0xfd,0xa9,0x3a,0x2e,0x59,0xc7,0xb5,0x97,0xbb,
2996
0x96,0xdc,0x35,0x15,0xae,0xa1,0x8e,0x1b,0x12,0xa9,0xba,0x2d,0x3d,0x45,0xfe,0x69,
2997
0xd2,0xa2,0xd2,0x04,0xcb,0x9d,0x4f,0xee,0x7c,0x4a,0xb7,0x77,0x7e,0xa3,0x1b,0xe5,
2998
0xff,0xa1,0xf4,0x14,0x69,0x9a,0xf4,0x54,0x69,0x0d,0xa9,0xc9,0x47,0xa4,0xd2,0x15,
2999
0x29,0x77,0x3e,0xb9,0x8d,0x96,0x91,0xd6,0x93,0xee,0x94,0x7e,0x21,0x8d,0x93,0xb6,
3000
0x94,0xc6,0x2a,0x9e,0x86,0xd2,0x58,0xf9,0x37,0xb4,0xf6,0x17,0x90,0xdb,0x68,0x25,
3001
0xf9,0x37,0x91,0x56,0x95,0xb6,0x90,0xf6,0x08,0x39,0xce,0x68,0xa8,0x14,0x45,0x3b,
3002
0x8f,0x72,0xf5,0x42,0x68,0x2a,0x35,0xee,0x76,0xd0,0xdc,0x72,0x0f,0xd1,0x7e,0xa3,
3003
0x2b,0xa4,0xcd,0xa5,0xef,0x2b,0xdc,0x52,0xe9,0x3a,0x69,0xe5,0x18,0xc7,0xa9,0x03,
3004
0x09,0xd2,0x64,0x69,0x29,0xe9,0x29,0xd2,0x53,0xa5,0x67,0x4a,0xcb,0x4b,0x2b,0x48,
3005
0xab,0x4a,0xab,0x4b,0x57,0xc0,0x22,0xe9,0x06,0x98,0x02,0xaf,0xc2,0xe3,0xd2,0x19,
3006
0xd2,0xa4,0xfc,0x84,0x87,0x9a,0xd2,0x53,0xa4,0xa7,0x4a,0xcf,0x94,0x56,0x95,0x36,
3007
0x29,0x40,0xdd,0x2a,0xe0,0x6a,0x3d,0x69,0x07,0x28,0x0f,0x75,0xa0,0x82,0xf4,0x6e,
3008
0xd8,0x00,0xcb,0x61,0x11,0xac,0x90,0x2e,0x97,0x7f,0xe3,0x82,0xc4,0x03,0x8b,0xe1,
3009
0x7d,0x58,0x6e,0xe9,0x07,0xd2,0x65,0x96,0x9a,0x7d,0x8d,0x0b,0x71,0x4e,0x68,0x22,
3010
0x35,0xee,0x0e,0xf0,0x21,0xac,0x92,0xbe,0x63,0xa9,0xe7,0xb7,0x19,0x5a,0x16,0x26,
3011
0xaf,0xb0,0x06,0x66,0xc3,0x74,0x98,0x24,0x9d,0x02,0x05,0x8a,0x38,0x4e,0x26,0xcc,
3012
0x83,0xf3,0xa4,0x6d,0xa4,0xed,0xa5,0x9d,0xa4,0x19,0x30,0x17,0x06,0xc2,0x20,0xe9,
3013
0x10,0x98,0x0d,0x23,0xa5,0x03,0x65,0x9f,0x63,0xa9,0xe7,0xe7,0xe9,0xdd,0x8a,0xef,
3014
0x61,0xe9,0x14,0xe9,0xd3,0xd2,0xe9,0xd2,0x09,0x3a,0xdf,0x39,0x45,0x1d,0x27,0x1e,
3015
0x72,0x20,0x54,0x9a,0xb6,0x07,0xd1,0xd2,0x18,0x69,0x01,0x69,0x21,0x69,0x31,0x69,
3016
0x2d,0x69,0x1d,0x69,0x3d,0x69,0x7d,0x69,0xa6,0xd4,0xdc,0xa3,0xcc,0x7d,0x3b,0x53,
3017
0xcf,0x01,0xe6,0x1e,0x75,0x67,0xc0,0x7d,0x06,0x30,0xf7,0x33,0xef,0xd9,0xbf,0x85,
3018
0x9e,0xcb,0x5a,0xea,0x39,0xcc,0xdc,0x7b,0x2a,0xd0,0xb7,0xb7,0x76,0xdc,0xfb,0xa8,
3019
0xb9,0x17,0x9a,0xfb,0xa5,0x79,0xc6,0x34,0xf7,0xbb,0xd6,0xec,0x6b,0x03,0xc1,0xb3,
3020
0x1c,0xa7,0x9b,0x9e,0x2d,0xcc,0x7d,0xaf,0x23,0x7e,0x9d,0xe0,0x92,0xa0,0xfb,0x7c,
3021
0x61,0x9e,0x65,0xfa,0x99,0xf8,0x03,0xee,0x3d,0xec,0x42,0xfc,0x4f,0xe1,0x98,0x53,
3022
0x21,0xdb,0x71,0xef,0xad,0xe6,0xfe,0x7b,0x16,0xee,0x01,0xec,0x1b,0x8a,0xfd,0x9c,
3023
0xb3,0xdc,0xbe,0x78,0x0e,0xbc,0xa8,0xbe,0x77,0x85,0x9e,0x03,0x06,0x29,0xbc,0x09,
3024
0xe7,0x85,0x59,0x6a,0x85,0xa9,0x4b,0x7b,0xbf,0x20,0xe8,0xfe,0xa6,0x6b,0x87,0xee,
3025
0x73,0xdc,0xb4,0xf4,0x44,0x3b,0xa3,0x5d,0xa1,0x07,0x5c,0x01,0xbd,0xcd,0x3d,0xd3,
3026
0xdc,0x2b,0x39,0xdf,0x23,0x68,0x3f,0x18,0x8b,0xfd,0x31,0x74,0x20,0x64,0xc3,0x20,
3027
0x18,0x0c,0x43,0xe0,0x2a,0x18,0x0e,0xa3,0x61,0x0c,0x4c,0x27,0x4f,0xb7,0xa0,0xb7,
3028
0xc2,0x99,0x1c,0x77,0x1b,0x7a,0x7b,0xd0,0x7d,0xc6,0x9a,0x80,0xde,0x15,0x74,0x9f,
3029
0xc9,0xe6,0xeb,0x59,0xe1,0x1c,0x3d,0x2b,0x18,0xcd,0xd4,0x7d,0xb8,0x9b,0xd4,0xb8,
3030
0x63,0xe5,0x8e,0x95,0x3b,0x51,0xee,0x44,0xeb,0x1d,0x44,0xc0,0xfa,0xfd,0x1e,0xd0,
3031
0x33,0x5e,0xb4,0x9e,0xb3,0xa3,0xe5,0x8e,0x95,0x3b,0x56,0xee,0x44,0xb9,0x13,0xe5,
3032
0xae,0x24,0x77,0x25,0xb9,0xe3,0xe4,0x8e,0xb3,0x7e,0xf3,0x3a,0xd6,0xef,0x5e,0xc7,
3033
0xf2,0x0f,0x58,0xfe,0xde,0x3b,0x90,0x38,0xf9,0x79,0xc7,0x27,0xc8,0x9d,0x60,0x3d,
3034
0x13,0x45,0x59,0xcf,0x45,0xc6,0xde,0x58,0xe9,0xed,0x69,0xfd,0xd6,0x8d,0xd4,0x33,
3035
0x69,0xa4,0x9e,0xb5,0xa2,0xf5,0x6c,0x13,0x2d,0x77,0xac,0xdc,0xb1,0x72,0xe7,0x93,
3036
0x3b,0x9f,0xdc,0x95,0xe4,0xf6,0x7e,0x2b,0xc7,0xcb,0x1d,0xaf,0x67,0xc9,0x04,0xd5,
3037
0xa1,0x04,0xeb,0x9d,0x4c,0xc0,0x7a,0x9f,0x11,0xd0,0x33,0x78,0x40,0xcf,0xe0,0x9e,
3038
0x3b,0x56,0xee,0x58,0xb9,0x13,0xe5,0x4e,0xd4,0x6f,0x9a,0x58,0xfd,0xd6,0x8d,0xb5,
3039
0xdc,0x91,0x96,0x5f,0xa4,0xfc,0x13,0xe5,0xe7,0x1d,0x17,0x27,0xb7,0xd1,0x96,0x3a,
3040
0x5f,0x3f,0x69,0x4b,0xe5,0xbb,0x9f,0xb4,0xa5,0xe2,0xea,0x27,0x3d,0x5f,0xfe,0xfd,
3041
0xa5,0xe7,0xcb,0xbf,0xbf,0xb5,0x3f,0x51,0xee,0x44,0xb9,0xe3,0xe4,0x8e,0xb3,0x9e,
3042
0x41,0x03,0xd6,0x33,0x68,0xc0,0xf2,0xcf,0x67,0xf9,0xe7,0x8b,0x38,0xf2,0xdb,0xdb,
3043
0xb1,0x7e,0x7f,0x3b,0x96,0x7f,0xc0,0xf2,0x37,0xf6,0xd6,0xca,0x47,0xb6,0x73,0xc4,
3044
0x1d,0x2d,0x77,0xb4,0x9e,0xcd,0xa3,0xf5,0x6c,0xee,0xb9,0x63,0xe5,0x8e,0xb5,0xdc,
3045
0x91,0x96,0x5f,0xa4,0xfc,0x13,0xe5,0x97,0xa8,0x67,0xf6,0x68,0x3d,0xb3,0x47,0xcb,
3046
0x1d,0x2b,0x77,0xac,0xf5,0x9b,0x3e,0xda,0xfa,0x5d,0x1f,0x6d,0xfd,0x76,0x8f,0xb6,
3047
0x7e,0xbf,0xdb,0xc7,0x47,0x5b,0x71,0x44,0xeb,0xb7,0x40,0xb4,0x7e,0x0b,0x78,0xee,
3048
0x58,0xb9,0x63,0xe5,0x4e,0x94,0x3b,0x51,0xee,0x38,0xb9,0xe3,0xf4,0x5b,0xe3,0x6c,
3049
0xfd,0xd6,0x38,0x5b,0xee,0x04,0xb9,0x13,0xe4,0x8e,0x93,0x3b,0xce,0x7a,0x57,0x10,
3050
0xb0,0xde,0x17,0x04,0xac,0x77,0x06,0xf9,0xac,0xf7,0x06,0xc6,0xde,0x5e,0x61,0x86,
3051
0x4a,0xdb,0x2b,0x5d,0x43,0xa5,0x1d,0xf4,0xdb,0x6e,0x98,0xb4,0x83,0xca,0x62,0x98,
3052
0xb4,0x83,0xda,0xc0,0x30,0x69,0x07,0xe5,0x73,0x98,0xb4,0x83,0xe2,0x19,0x26,0xbd,
3053
0x48,0xfe,0xc3,0xa5,0x17,0xe9,0xb8,0xe1,0xd6,0xbb,0xc9,0x68,0xfd,0x46,0xf1,0xde,
3054
0x29,0x04,0xf5,0x4e,0x21,0x28,0x77,0xac,0xdc,0xb1,0x72,0x27,0xca,0x9d,0xa8,0x76,
3055
0xeb,0x95,0xa7,0x97,0xae,0xfc,0x8a,0x2f,0xbf,0xfa,0xd1,0x45,0xf4,0xad,0x37,0x04,
3056
0xdc,0xf8,0x1b,0x28,0x9e,0xae,0x52,0xe3,0x8e,0x91,0x3b,0xc6,0x7a,0xc7,0x6b,0xbf,
3057
0x1f,0xb5,0xdf,0xfd,0x3a,0x96,0xbf,0x63,0xf9,0xc7,0x58,0xfe,0x76,0x3c,0x11,0x96,
3058
0x7f,0x84,0x75,0xfe,0xa0,0x95,0x86,0xa0,0xf5,0xce,0x32,0x60,0xbd,0xb7,0x0c,0x58,
3059
0xfe,0x8e,0xe5,0xef,0x58,0xfe,0x31,0x96,0x7f,0x8c,0xe5,0x1f,0x61,0xf9,0xdb,0xe7,
3060
0x8d,0xb2,0xce,0xeb,0xbd,0x9b,0x8c,0x55,0x9f,0x1b,0x2b,0x77,0x8c,0xdc,0x31,0x72,
3061
0x47,0xc8,0x1d,0x61,0xbd,0xcb,0xb6,0xdf,0x03,0xdb,0xef,0xb8,0x1d,0xcb,0xdf,0xb1,
3062
0xfc,0x63,0x2c,0xff,0x18,0xcb,0x3f,0xc2,0xf2,0x8f,0xb0,0xd2,0x13,0xb4,0xd2,0xe4,
3063
0xbd,0xc3,0x8c,0x51,0x1f,0x1c,0x23,0x77,0xac,0xdc,0xb1,0xea,0x5f,0x62,0xd5,0xb7,
3064
0x78,0xee,0x18,0xb9,0x63,0xac,0x77,0xe7,0xf6,0x7b,0x67,0xfb,0x9d,0xba,0x63,0xf9,
3065
0x3b,0x96,0x7f,0x8c,0xe5,0x6f,0xc7,0x13,0x61,0xf9,0x47,0x58,0xe7,0x0f,0x5a,0x69,
3066
0xf0,0xde,0xd5,0x97,0xb6,0xce,0x5b,0xda,0x3a,0x6f,0x69,0xeb,0xbc,0xa5,0xad,0xf3,
3067
0x96,0xb6,0xce,0x5b,0xda,0x3a,0x6f,0x69,0xeb,0xbc,0xa5,0xad,0xf3,0x1a,0x7b,0xac,
3068
0xe5,0x1f,0xab,0xf6,0x1f,0xab,0xb6,0xef,0xb9,0x63,0xe4,0x8e,0xb1,0xde,0xcb,0x05,
3069
0xac,0x77,0x73,0x01,0xcb,0xdf,0xb1,0xfc,0x1d,0xcb,0x3f,0xc6,0xf2,0xb7,0xe3,0x89,
3070
0xb0,0xfc,0x23,0x2c,0xff,0x58,0xcb,0x3f,0x56,0xed,0xdd,0x51,0xfb,0x74,0xe4,0x8e,
3071
0x95,0xdb,0xdb,0x1f,0x23,0x77,0x8c,0xdc,0x11,0x72,0x47,0xe8,0xf7,0x7c,0x09,0x69,
3072
0x49,0xcb,0xed,0x58,0x7e,0x8e,0xe5,0x1f,0xb0,0xfc,0x03,0x96,0x7f,0xa6,0xe5,0x9f,
3073
0xa9,0xf7,0x0f,0x25,0xa4,0x25,0x2d,0xb7,0x63,0xf9,0x39,0x96,0x7f,0xc0,0xf2,0x0f,
3074
0x58,0xfe,0x99,0x96,0x7f,0xa6,0x7e,0xf7,0x97,0x90,0x96,0xb4,0xdc,0x8e,0xe5,0xe7,
3075
0x58,0xfe,0x01,0xcb,0xdf,0xd8,0x27,0xca,0x7f,0xa2,0xfc,0x26,0x5a,0xc7,0x4f,0xb4,
3076
0x8e,0x9f,0x68,0x1d,0x3f,0xd1,0x3a,0x7e,0x9e,0xfc,0xe7,0xc9,0x6f,0x9e,0x75,0xfc,
3077
0x3c,0xeb,0xf8,0x79,0xd6,0xf1,0xf3,0x8e,0x71,0x7c,0xa6,0xe5,0x9f,0xa9,0x77,0x33,
3078
0x25,0xa4,0x25,0x2d,0xb7,0x63,0xf9,0x39,0x96,0x7f,0xc0,0xf2,0x0f,0x58,0xfe,0x99,
3079
0x96,0x7f,0xa6,0xde,0xc1,0x94,0x90,0x96,0xb4,0xdc,0x8e,0xe5,0xe7,0x58,0xfe,0x01,
3080
0xcb,0x3f,0x60,0xf9,0x67,0x5a,0xfe,0x99,0x7a,0x2f,0x54,0x42,0x5a,0xd2,0x72,0x3b,
3081
0x96,0x9f,0x63,0xf9,0x07,0x2c,0xff,0x80,0xe5,0x9f,0x69,0xf9,0x67,0xea,0x1d,0x51,
3082
0x09,0x69,0x49,0xcb,0xed,0x58,0x7e,0x8e,0xe5,0x1f,0xb0,0xfc,0xbd,0x77,0x5a,0x25,
3083
0xa4,0x25,0x2d,0xb7,0x63,0xf9,0x39,0x96,0x7f,0xc0,0xf2,0xf7,0xde,0x4d,0x95,0x90,
3084
0x96,0xb4,0xdc,0x8e,0xe5,0xe7,0x58,0xfe,0x01,0xcb,0xdf,0x3e,0x3e,0xd3,0xf2,0xcf,
3085
0xd4,0xbb,0xad,0x92,0x96,0x3a,0x96,0x3d,0x60,0xd9,0x33,0xf5,0x5e,0xac,0x84,0xb4,
3086
0xa4,0xe5,0x76,0x2c,0x3f,0xc7,0xf2,0x0f,0x58,0xfe,0x01,0xcb,0x3f,0xd3,0xf2,0xcf,
3087
0xd4,0xfb,0xbd,0x12,0xd2,0x92,0x96,0xdb,0xb1,0xfc,0x1c,0xcb,0x3f,0x60,0xf9,0x07,
3088
0x2c,0xff,0x4c,0xcb,0xdf,0x6b,0xf7,0x8e,0xef,0xdd,0xa0,0xe3,0x7b,0x47,0xe8,0xf8,
3089
0xde,0x15,0x3a,0xd6,0x3b,0xc3,0xc5,0xd6,0x35,0xf5,0xca,0xd0,0xf1,0xbd,0x27,0x74,
3090
0xac,0xf7,0x85,0x5e,0x9f,0x93,0x65,0xf5,0x39,0x59,0xbe,0xbe,0x2b,0xcb,0xd7,0x7f,
3091
0x65,0xf9,0xfa,0xb0,0x2c,0x5f,0x3f,0x96,0xe5,0xeb,0xcb,0xb2,0x7c,0xfd,0x59,0x96,
3092
0xd5,0x27,0x65,0x59,0x7d,0x52,0x96,0xaf,0x6f,0xcb,0xf2,0xf5,0x6f,0x59,0xbe,0x3e,
3093
0x2e,0xcb,0xd7,0xcf,0x65,0xf9,0xfa,0xba,0x2c,0x5f,0x7f,0x97,0x65,0xf5,0x19,0x59,
3094
0x56,0x9f,0x91,0xe5,0xeb,0x7b,0xb2,0x7c,0xfd,0x4f,0x96,0xaf,0x0f,0xca,0xf2,0xf5,
3095
0x43,0x59,0xbe,0xbe,0x28,0xcb,0xd7,0x1f,0x65,0x59,0x7d,0x4a,0x96,0xd5,0xa7,0x64,
3096
0xf9,0xfa,0xa6,0x2c,0x5f,0xff,0x94,0xe5,0xeb,0xa3,0xb2,0x7c,0xfd,0x54,0x96,0xaf,
3097
0xaf,0xca,0xf2,0xf5,0x57,0x59,0x56,0xfd,0xcd,0xb2,0xea,0x6f,0x96,0xaf,0x1d,0x64,
3098
0xf9,0xda,0x42,0x96,0xaf,0x3d,0x64,0xf9,0xda,0x44,0x96,0xaf,0x5d,0x64,0xf9,0xda,
3099
0x46,0x96,0x55,0xbf,0xb3,0xac,0xfa,0x9d,0xe5,0x6b,0x27,0x59,0xbe,0xb6,0x92,0xe5,
3100
0x6b,0x2f,0x59,0xbe,0x36,0x93,0xe5,0x6b,0x37,0x59,0xbe,0xb6,0xe3,0xd5,0xb3,0x28,
3101
0x69,0xa4,0xd5,0x9e,0xbc,0x7d,0x59,0x56,0xdb,0xf2,0xec,0x99,0x96,0x7a,0x75,0x26,
3102
0x4a,0x1a,0x29,0x75,0xac,0x71,0x80,0xbb,0x14,0xce,0x8c,0x13,0x78,0xf7,0x03,0xcf,
3103
0x6e,0x34,0x53,0x63,0x07,0x99,0x56,0x7b,0xf5,0xea,0x44,0x96,0xd5,0x76,0x3d,0x7b,
3104
0xa6,0xa5,0x59,0xba,0x47,0x7a,0xf7,0x4d,0xef,0x7e,0xe4,0x58,0x63,0x0e,0xf7,0x2b,
3105
0xdc,0xe2,0xb2,0x6a,0xeb,0x65,0xd5,0xf6,0xcb,0x1e,0xb9,0xb7,0x44,0x49,0x23,0xad,
3106
0xb1,0x03,0xc7,0x37,0x1e,0xb1,0xc0,0xba,0x17,0xe5,0xb3,0xee,0x1f,0x51,0xd2,0x48,
3107
0xa9,0x63,0x8d,0x73,0xfc,0xac,0x73,0xfe,0x5c,0xf6,0x88,0xdb,0xeb,0x9f,0xa3,0xa4,
3108
0x91,0xd6,0x38,0x85,0xe3,0x1b,0xc7,0x58,0xaa,0xeb,0xb7,0xd4,0xba,0x27,0x64,0x5a,
3109
0x61,0xbc,0xfe,0x3d,0x4a,0x1a,0x29,0x75,0xac,0xb1,0x95,0x29,0x3a,0x76,0xaa,0x9e,
3110
0xd3,0xbc,0x71,0x9a,0x2e,0xce,0x91,0xfe,0xcd,0xab,0x93,0x59,0x56,0x5f,0xe7,0xd9,
3111
0x33,0x2d,0xcd,0xd2,0x3d,0xcb,0xb1,0xc6,0x70,0xa6,0x59,0x7d,0xb7,0xe7,0x36,0xe1,
3112
0x5e,0xd4,0xd8,0x90,0x39,0x77,0x10,0x4b,0x44,0xb9,0x23,0xf3,0x7c,0xfe,0x13,0x45,
3113
0x15,0x2e,0x99,0xe3,0xe2,0x9d,0x63,0x63,0xf6,0x27,0x95,0xfb,0xff,0xa4,0x1e,0x83,
3114
0xf2,0x8e,0x8b,0x39,0x26,0x44,0x9c,0xf5,0x9d,0x23,0x78,0xfb,0xea,0x1f,0x23,0x3e,
3115
0x13,0x3e,0x41,0x73,0x24,0xcc,0x1c,0xa2,0x54,0x48,0x83,0x1a,0x50,0x13,0xd2,0xa1,
3116
0x2a,0x14,0xaf,0xe0,0x38,0x75,0xcd,0x98,0x1a,0x9c,0xab,0xb1,0xec,0x04,0xcd,0x45,
3117
0xf2,0xe6,0x21,0x9d,0xcc,0xf1,0x5d,0xf5,0x5e,0x75,0x80,0xc6,0xe1,0xcc,0xfb,0xd5,
3118
0x2b,0xf4,0x5e,0xb5,0xaf,0xde,0xad,0x9a,0x73,0x64,0x6b,0xac,0x6e,0x88,0xde,0xd7,
3119
0x0e,0xd6,0xb1,0xd5,0x1d,0xf7,0x7d,0xa1,0x67,0x37,0xfe,0xe6,0x5d,0xe2,0x4c,0x69,
3120
0x77,0xf9,0x0f,0xb0,0xec,0xe6,0xb9,0x7e,0x42,0xc0,0x0d,0x63,0xde,0xd3,0xf5,0xd2,
3121
0xbb,0x62,0x8f,0xdc,0x77,0x6c,0x01,0xf7,0xb7,0x5a,0x33,0xbd,0x37,0xee,0xab,0xf7,
3122
0xc6,0xe7,0x2b,0x2e,0xf3,0xbe,0xa7,0x8d,0xd2,0xe2,0xd1,0x56,0xef,0x97,0x2f,0xd4,
3123
0x7b,0xe8,0xf3,0x64,0x6f,0xa9,0x71,0xea,0x69,0x7a,0x0f,0xd0,0xc2,0x39,0x32,0x06,
3124
0x9d,0xa9,0x74,0xf6,0xd0,0x31,0x8d,0x15,0xde,0x9c,0x63,0x6d,0xc8,0x71,0xde,0x85,
3125
0x75,0xb0,0x3e,0xe4,0x5e,0x9b,0xc6,0x3a,0xd6,0xbc,0x8f,0x58,0xa2,0xf7,0xc3,0xf7,
3126
0xc0,0x64,0x28,0x56,0xc1,0x7d,0xdf,0xe9,0xbd,0xab,0xf6,0xe6,0xbb,0x78,0xf3,0xc4,
3127
0x6a,0x58,0xf6,0x74,0xcb,0x9e,0x68,0x5d,0x43,0xe3,0x4e,0xd6,0xb5,0xf4,0xec,0x9e,
3128
0x7f,0xaa,0xe5,0x9f,0x6a,0xcd,0x39,0x4b,0xd5,0x35,0xf7,0xec,0x5e,0xf8,0x34,0xd5,
3129
0x03,0xcf,0xee,0xf9,0xd7,0xb4,0x8e,0xad,0x69,0x85,0xa9,0xa9,0xfa,0xe2,0xd9,0xbd,
3130
0xf0,0xde,0x75,0x38,0x16,0xed,0x2d,0x9a,0x59,0xea,0xb7,0x7b,0x5c,0x64,0xd1,0xcc,
3131
0x52,0xef,0x3a,0x37,0xd4,0x38,0x42,0x4b,0x95,0x5f,0x5e,0x0c,0xb5,0xe8,0x6d,0xa9,
3132
0xdf,0xee,0x31,0xdc,0xa2,0xb7,0xa5,0xbd,0x55,0xb7,0xba,0xeb,0xba,0xf5,0xd3,0xb5,
3133
0xf0,0xca,0x7e,0x02,0x0d,0xb6,0xa6,0x99,0xfb,0x20,0xbd,0x57,0xba,0x56,0xfa,0x9e,
3134
0x74,0x9d,0x34,0xa2,0x82,0xab,0xf9,0xa4,0x05,0xa4,0xb1,0xd2,0x73,0xa4,0x55,0x2b,
3135
0xfc,0x7f,0xe2,0x8f,0x41,0x1d,0x85,0x6f,0x28,0xcd,0x92,0x36,0x95,0x9a,0xb6,0x6c,
3136
0xb4,0xab,0xdc,0x2d,0xa5,0x75,0xe4,0x5f,0x4f,0x7a,0xb9,0xfc,0x7b,0x48,0x07,0x49,
3137
0x07,0x4b,0x87,0x4a,0x87,0x49,0xaf,0x91,0x5e,0x2b,0x1d,0x2d,0x1d,0x23,0xbd,0x49,
3138
0x7a,0xb3,0xf4,0x71,0xe9,0x54,0xe9,0x34,0xe9,0x74,0xe9,0x08,0xe9,0x75,0xd2,0xbb,
3139
0xa4,0x77,0x4b,0x67,0x4b,0xe7,0x48,0x5f,0x94,0xce,0xf5,0xca,0x93,0x8b,0x12,0x93,
3140
0x70,0x62,0xfd,0x9c,0xdd,0x9e,0x12,0xad,0xbe,0x31,0xd1,0x39,0xd2,0x9e,0xbc,0xf9,
3141
0x9b,0x5e,0x7b,0xf1,0xda,0x87,0xd7,0x46,0xbd,0xfa,0x9f,0xae,0x63,0x13,0xd4,0x67,
3142
0x26,0xaa,0xdf,0xac,0x2c,0x7f,0xcf,0x9e,0x6c,0xd9,0x53,0x2c,0x7b,0xaa,0x65,0x4f,
3143
0xb3,0xec,0x35,0x2c,0x7b,0x4d,0xcb,0x9e,0x6e,0xd9,0xbd,0x7c,0xd8,0xee,0x44,0x9f,
3144
0x3b,0xc9,0xe7,0x4e,0xf6,0xb9,0x53,0x7c,0xee,0x54,0x9f,0x3b,0xcd,0xe7,0xae,0xe1,
3145
0x73,0xd7,0xf4,0xb9,0xd3,0x7d,0xf9,0xf7,0xd2,0x97,0xa8,0x7b,0x65,0x92,0x34,0x59,
3146
0x9a,0x22,0x4d,0x95,0xa6,0x49,0x6b,0x48,0x6b,0x4a,0xd3,0xa5,0x5e,0x9e,0xe3,0xad,
3147
0xfc,0xc6,0x5b,0x79,0x8d,0xb7,0xf2,0x19,0x6f,0xe5,0x31,0xde,0xca,0x5f,0xbc,0x95,
3148
0xb7,0x78,0x2b,0x5f,0xf1,0x56,0x9e,0xe2,0xad,0xfc,0xc4,0x5b,0x79,0x89,0x57,0xde,
3149
0xba,0x5a,0xf9,0xec,0x66,0xd9,0xbb,0x5b,0xf6,0xcb,0x2d,0x7b,0x0f,0xcb,0xde,0xd3,
3150
0xb2,0xf7,0xb2,0xec,0x57,0x58,0xf6,0xde,0x96,0xfd,0x4a,0xcb,0xde,0xc7,0xb2,0xf7,
3151
0xb5,0xec,0xfd,0x2c,0x7b,0x7f,0xcb,0x3e,0xc0,0xb2,0x67,0x5b,0xf6,0x81,0x96,0x7d,
3152
0x90,0x65,0x1f,0x6c,0xd9,0x87,0x58,0xf6,0xab,0x2c,0xfb,0x50,0xcb,0x3e,0xcc,0xb2,
3153
0x0f,0xb7,0xec,0x57,0x5b,0xf6,0x6b,0x64,0x6f,0xe0,0x1c,0xb9,0x9f,0x36,0xb2,0xee,
3154
0xa7,0x27,0x32,0x16,0x6c,0xdf,0xcf,0xdb,0x5a,0xe3,0xc1,0xed,0x35,0x26,0x6c,0xee,
3155
0x13,0x1d,0x75,0x1f,0xef,0xaa,0x6b,0xd2,0xdd,0xba,0xd7,0xf6,0x54,0x59,0x5f,0x61,
3156
0xdd,0x77,0xfd,0xcf,0x30,0x03,0x54,0x46,0x03,0x55,0x26,0x83,0xad,0xf1,0xe1,0xa1,
3157
0xca,0xeb,0x70,0xe5,0xed,0x1a,0xd5,0x07,0x7f,0x1f,0x5d,0xcb,0x71,0xa9,0x9b,0x07,
3158
0x1f,0x57,0x71,0xfb,0xab,0x2b,0x95,0xf6,0xae,0x71,0x8e,0xb3,0x86,0x84,0x3c,0xf6,
3159
0x98,0x9b,0xd9,0xca,0x90,0x06,0xf5,0xa1,0x23,0x8c,0x85,0xdb,0x61,0x32,0xbc,0x6c,
3160
0xfc,0x29,0x84,0x1e,0xd0,0x07,0x46,0xc3,0x7d,0x30,0x1d,0xb6,0xc0,0xb7,0x2a,0xa0,
3161
0x87,0xe0,0x20,0x94,0xa2,0xa0,0xce,0x80,0x9a,0xd0,0x00,0x2e,0x81,0xde,0x30,0x1a,
3162
0x5e,0x82,0x95,0xb0,0x0d,0x36,0x90,0x90,0xb2,0x14,0xe2,0x6e,0x0a,0x31,0x48,0x21,
3163
0xe6,0x87,0x52,0x50,0x09,0x06,0x43,0xeb,0x4e,0x8e,0x33,0x12,0x7e,0x80,0x22,0x97,
3164
0x38,0x4e,0x05,0xa8,0x09,0xfd,0x61,0x20,0x6c,0xba,0xd4,0x71,0x3e,0x83,0xfd,0xf0,
3165
0x33,0x0c,0xba,0x8c,0xf2,0x81,0x1b,0xe0,0x1b,0xf8,0x19,0x0a,0x74,0xe6,0xb7,0x03,
3166
0xb4,0x86,0xae,0x30,0x18,0x5e,0x83,0x7c,0x5c,0xa8,0x34,0x68,0x01,0xd5,0xb9,0x50,
3167
0x29,0x70,0x33,0xdc,0x0f,0x4f,0xc2,0x02,0xd8,0x02,0x9f,0xc1,0x3e,0x2e,0x62,0x3e,
3168
0x2e,0x62,0x65,0x28,0x47,0x99,0x75,0x83,0xab,0x61,0x0e,0xac,0x86,0xf7,0x60,0x13,
3169
0x14,0xe1,0xa2,0x96,0x84,0x14,0xe8,0xc3,0x05,0xad,0xc2,0xc5,0x4c,0x83,0xda,0x50,
3170
0x1f,0x9a,0x40,0x47,0xe8,0x04,0xcf,0xc1,0x8d,0x5c,0xe8,0x5b,0x20,0x87,0x8b,0xbd,
3171
0x03,0x4e,0xe3,0x82,0x97,0x85,0xca,0x90,0x00,0xb7,0xc1,0xdd,0x30,0x94,0x4a,0x70,
3172
0x1d,0xbc,0x00,0x8b,0xe1,0x2b,0xd8,0x44,0xa5,0xd8,0x0a,0x07,0xa0,0x16,0x15,0x63,
3173
0x3e,0x2c,0x82,0x21,0x54,0x90,0xd5,0x70,0x10,0x06,0x8f,0xa0,0xec,0x20,0xed,0x06,
3174
0xea,0x30,0xdc,0x0a,0x0b,0x21,0x30,0xd2,0x71,0x0a,0x42,0x71,0x48,0x86,0x1b,0xe0,
3175
0x16,0xd8,0x36,0xca,0x71,0x76,0xc1,0x01,0x38,0x0c,0x05,0x47,0x3b,0x4e,0x69,0x28,
3176
0x0b,0xfd,0x61,0x10,0x0c,0x87,0x96,0x37,0x91,0x3f,0xc8,0x18,0x47,0x7b,0x81,0xee,
3177
0x70,0xfd,0x2d,0xa4,0x17,0xd6,0x81,0x73,0x2b,0xfd,0xda,0xed,0xb4,0x31,0x68,0x07,
3178
0xc3,0xe1,0x11,0xb8,0xfc,0x0e,0xea,0x39,0xcc,0x81,0xe9,0x77,0x3a,0xce,0x2a,0x78,
3179
0x68,0x3c,0xcf,0xdb,0x30,0x17,0xee,0x9a,0x40,0x5b,0xbc,0xcb,0x71,0x96,0xc3,0x5b,
3180
0xf0,0x2e,0x0c,0x9b,0x48,0x1d,0x80,0x33,0xef,0xa3,0xee,0xc0,0x02,0xd8,0x09,0x6d,
3181
0xee,0x77,0x9c,0xcb,0xa0,0x1b,0xf4,0x86,0xd5,0xb0,0x07,0x0e,0x40,0xe0,0x01,0xee,
3182
0xf7,0xb0,0x09,0x36,0xc3,0x7d,0x93,0xf8,0x2d,0x0a,0xcf,0xc1,0xd4,0x07,0x1d,0x67,
3183
0x23,0x6c,0x86,0x73,0x1e,0xe2,0xda,0x43,0x12,0xd4,0x81,0x8b,0xe1,0xb3,0x87,0x69,
3184
0x77,0x8f,0x52,0x26,0xf0,0x14,0xbc,0x02,0xaf,0xc1,0x1a,0x78,0x17,0x0e,0xc2,0x4f,
3185
0x50,0x98,0x76,0x53,0x02,0xca,0x41,0x6d,0x68,0x0e,0x17,0xc0,0x1d,0xf0,0x30,0x4c,
3186
0x7e,0xcc,0xfd,0xed,0x54,0x3c,0xc1,0x6d,0x03,0x8d,0x20,0x0b,0x5a,0xe0,0x9e,0x04,
3187
0x2d,0xa5,0xad,0xa4,0x6d,0xa4,0x6d,0xa5,0xed,0xa4,0x1d,0xa4,0x1d,0xa5,0x9d,0xa4,
3188
0x97,0x4a,0x3b,0x4b,0xbb,0x4a,0x2f,0x97,0xf6,0x94,0x5e,0x21,0x1d,0x60,0xe9,0x83,
3189
0x30,0x48,0xee,0x41,0x72,0x5f,0x25,0xf7,0x55,0x72,0x0f,0x97,0x7b,0xb8,0xdc,0xd7,
3190
0xca,0x7d,0xad,0xdc,0x8d,0xe5,0x36,0x79,0xf4,0xd4,0xf8,0x3f,0x22,0xff,0x71,0x70,
3191
0x2b,0x4c,0x97,0xfb,0x79,0xe9,0x0c,0xe9,0x2c,0xe9,0x1c,0xe9,0x5c,0xe9,0x3c,0xe9,
3192
0x02,0xe9,0x2b,0xd2,0x85,0xd2,0xc5,0xd2,0xa5,0xd2,0xd7,0xa5,0xcb,0xa5,0x2b,0xa5,
3193
0xef,0x58,0x6a,0xd2,0xb5,0x4e,0xee,0x75,0x72,0xbf,0x2f,0xf7,0xfb,0x72,0x6f,0x94,
3194
0x7b,0xa3,0xdc,0x9b,0xe4,0xde,0x24,0xf7,0xd3,0x72,0xef,0x95,0xee,0x93,0xee,0x97,
3195
0x7e,0x2d,0xfd,0xc9,0xca,0x97,0x49,0x8b,0x53,0x8c,0xfa,0x08,0xcf,0x42,0x10,0x9e,
3196
0x83,0xe7,0x21,0x02,0x22,0x21,0x04,0x33,0x61,0x16,0xcc,0x86,0x39,0xf0,0x22,0xcc,
3197
0x85,0x33,0x20,0x0a,0xa2,0x21,0x1f,0x94,0x87,0x18,0xc8,0x0f,0x05,0xa0,0x20,0x14,
3198
0x82,0xc2,0x50,0x04,0x8a,0x42,0x31,0x28,0x0e,0x5d,0xa1,0x1b,0x74,0x87,0xcb,0xa1,
3199
0x07,0xf4,0x84,0x5e,0x70,0x05,0xf4,0x86,0x2b,0xa1,0x0f,0xf4,0x85,0x7e,0xd0,0x1f,
3200
0x06,0x40,0x36,0x0c,0x84,0x41,0x30,0x18,0x86,0xc0,0x55,0xd0,0x05,0x4a,0x42,0x29,
3201
0x58,0x01,0x2b,0xe1,0x2d,0x78,0x1b,0xd6,0xc3,0x06,0xf8,0x10,0xce,0x84,0x8f,0x61,
3202
0x33,0x9c,0x05,0x65,0xa0,0x1c,0x54,0x80,0x58,0xa8,0x04,0xe7,0x42,0x55,0xa8,0x06,
3203
0x71,0x10,0x0f,0xd5,0x21,0x09,0xd2,0x20,0x03,0x9a,0xc0,0x79,0xb0,0x1f,0xbe,0x86,
3204
0x0e,0x70,0x11,0x74,0x84,0x1b,0x61,0x2c,0x8c,0x83,0xbb,0xe0,0x6e,0xb8,0x17,0x1e,
3205
0x85,0x29,0xc5,0xdc,0x7b,0x9a,0xb9,0x7f,0xc5,0xc0,0x26,0xee,0x33,0xf9,0xd1,0x38,
3206
0x28,0x00,0x49,0x57,0xb9,0xf7,0xb8,0xd3,0x21,0x00,0xe7,0x72,0xaf,0x49,0xe8,0xe0,
3207
0xde,0xe7,0xcc,0x73,0x83,0xb9,0x66,0xde,0x33,0x44,0xd0,0xb2,0x47,0x58,0xf6,0x90,
3208
0x65,0x8f,0xb2,0xec,0xd1,0x96,0x3d,0xc6,0xb2,0x17,0xb0,0xec,0x05,0x2d,0x7b,0x61,
3209
0xcb,0x5e,0xc4,0xb2,0x17,0xb5,0xec,0xc5,0x2c,0x7b,0x71,0xcb,0xee,0xe8,0x3a,0xdb,
3210
0x69,0xed,0xea,0x4b,0x6f,0x57,0x5f,0x9a,0xbb,0xfa,0xd2,0xdd,0xd5,0x97,0xf6,0xae,
3211
0xbe,0xf4,0x77,0xf5,0xe5,0xa1,0xab,0x2f,0x1f,0x5d,0x7d,0x79,0xe9,0xea,0xcb,0x4f,
3212
0x57,0x5f,0x9e,0xba,0xfa,0xf2,0xd5,0xd5,0x97,0x37,0x7f,0xfc,0xfd,0x7d,0xe7,0xef,
3213
0xad,0x7a,0x6f,0xea,0xf3,0xf4,0x63,0xec,0x2b,0xee,0x3b,0xc6,0xd4,0x03,0xcf,0x7e,
3214
0xbb,0x65,0x8f,0xb1,0xec,0xa6,0x7e,0x78,0xf6,0x7b,0x2d,0xff,0x7e,0x6d,0xac,0xb2,
3215
0xb4,0xfc,0xfb,0x58,0xfe,0x97,0x5a,0xfe,0xa6,0x9f,0xf7,0xec,0xe6,0x79,0xe1,0xd7,
3216
0xf0,0xd9,0xd6,0x6f,0xb0,0xbe,0x47,0xec,0x95,0xad,0x30,0xe6,0x5e,0xe7,0xd9,0xcd,
3217
0x33,0x91,0x67,0x37,0xcf,0x1f,0x9e,0xbd,0xca,0x15,0x56,0xfa,0xad,0x63,0xeb,0x5d,
3218
0x7d,0xc4,0x5e,0xe8,0x42,0xeb,0x59,0x78,0xd0,0x11,0xfb,0x94,0xdb,0xad,0x34,0x5b,
3219
0xe1,0x5f,0xbc,0xe0,0x88,0x7d,0x9b,0x95,0x97,0x11,0x56,0x3c,0x3d,0x3b,0x59,0x61,
3220
0x86,0x1e,0xb1,0x07,0x5a,0x1d,0xb1,0xaf,0xb0,0xe2,0xbf,0xd0,0x2a,0x87,0x7e,0xd6,
3221
0xb9,0x8a,0x59,0xe1,0xcd,0x73,0x86,0x67,0x3f,0x20,0x7b,0x2b,0x1e,0xac,0x47,0x5c,
3222
0xe6,0x3e,0x87,0x8d,0xbf,0xd6,0x7d,0xf6,0xf6,0xde,0x99,0x25,0x59,0xbf,0xb5,0x92,
3223
0xac,0xdf,0xda,0x49,0xfa,0x9d,0x95,0xe4,0x1c,0x79,0x0f,0x95,0x26,0xad,0x21,0xad,
3224
0x29,0x4d,0xd7,0x31,0x09,0xd6,0xef,0xed,0x64,0x2b,0xae,0x64,0xeb,0xf7,0x7b,0xb2,
3225
0xe2,0x73,0xd4,0x6f,0x47,0xa8,0xaf,0xf6,0xfa,0xe3,0x18,0xab,0x0f,0x3e,0x56,0xff,
3226
0xeb,0xb5,0x4d,0xaf,0x4d,0x7a,0x6d,0xd1,0x6b,0x83,0x5e,0xdb,0xf3,0xda,0x9c,0xd7,
3227
0xd6,0xbc,0x36,0xe6,0xb5,0x2d,0xaf,0x4d,0x79,0x6d,0xc9,0x6b,0x43,0x5e,0xdb,0x29,
3228
0xee,0x0b,0x37,0x4f,0xe7,0xf6,0xda,0x49,0x7f,0xc5,0x39,0x44,0xda,0xff,0x18,0x7d,
3229
0xa3,0xa9,0xf3,0xa6,0xae,0x9b,0x3a,0x6e,0xea,0xb6,0xa9,0xd3,0xa6,0x2e,0x9b,0x3a,
3230
0x6c,0xea,0xae,0xa9,0xb3,0xa6,0xae,0x9a,0x3a,0x6a,0xea,0xa6,0xa9,0x93,0xa6,0x2e,
3231
0x9a,0x3a,0x68,0xea,0x9e,0xa9,0x73,0xa6,0xae,0x99,0x3a,0x66,0xea,0x96,0xa9,0x53,
3232
0x1b,0xd1,0x1a,0x57,0xb9,0xcf,0xf1,0xbd,0x79,0xae,0xab,0x42,0xbc,0xd9,0xc4,0xb9,
3233
0x93,0xb8,0x42,0x0f,0xb8,0x75,0x61,0x12,0x7e,0xdd,0xfb,0x1c,0xdd,0x37,0xef,0xe0,
3234
0x39,0xfe,0x00,0xe1,0x6a,0xc3,0xfd,0x9d,0xdc,0xba,0x67,0xea,0x9c,0xa9,0x6b,0xa6,
3235
0x8e,0x99,0xba,0x75,0x66,0x47,0xf7,0xfa,0xa4,0xe9,0x3a,0xd5,0x90,0x7a,0xef,0x0f,
3236
0xd3,0x75,0x0d,0x13,0xac,0xf7,0x29,0x29,0x56,0x5d,0xf1,0xae,0x71,0x8a,0xf5,0xae,
3237
0x26,0x45,0xf1,0xa5,0x28,0xbe,0x14,0xc5,0x97,0xa2,0xf8,0x52,0xad,0x77,0x37,0xa6,
3238
0x5c,0x92,0xa4,0xc9,0xd2,0x14,0x69,0xaa,0x34,0x4d,0x5a,0x43,0x5a,0x53,0x9a,0x2e,
3239
0xf5,0xde,0x27,0x78,0xf6,0x44,0xcb,0xee,0xc5,0xdd,0x54,0xbf,0x1d,0x7b,0xe8,0x77,
3240
0xa1,0x67,0x6f,0x6f,0xbd,0x43,0x36,0xbf,0x67,0x1f,0x27,0xa2,0x27,0xf5,0x8c,0x32,
3241
0x15,0x9e,0xd5,0x73,0xd7,0xf3,0x7a,0xde,0x9a,0xa5,0xe7,0x91,0xb9,0x7a,0xbe,0x5a,
3242
0xa0,0xe7,0xaa,0x85,0x7a,0x9e,0x5a,0xaa,0xe7,0xa8,0xe5,0x7a,0x66,0x59,0x05,0xab,
3243
0xe1,0x2d,0x58,0x03,0x6f,0xeb,0x39,0x6a,0x9d,0x9e,0x97,0x36,0xea,0xb9,0xe8,0x13,
3244
0xd8,0x0c,0x5b,0xe0,0x53,0xd8,0x0a,0xdb,0x61,0x07,0xec,0x84,0x2f,0x60,0x17,0xec,
3245
0x86,0x2f,0x61,0x8f,0x9e,0x9f,0xf6,0xe9,0xb9,0xc9,0x3c,0x33,0x6d,0x37,0x75,0xf1,
3246
0x42,0x37,0x0f,0xde,0xb3,0xda,0x61,0xa5,0xe3,0x71,0x1d,0x6b,0xce,0x39,0x45,0xee,
3247
0x03,0xd6,0x33,0xda,0xe3,0xe2,0xb0,0xc2,0x3d,0xa9,0x74,0x1f,0xb0,0x9e,0x33,0x9f,
3248
0x94,0x7b,0xa9,0xca,0x67,0x9a,0xdc,0x53,0x55,0x0e,0x33,0xac,0xf3,0x4d,0x92,0xff,
3249
0x61,0x95,0xdf,0x61,0x95,0xe5,0x01,0x85,0x7d,0x56,0x7e,0x5b,0xb4,0xff,0x49,0xe5,
3250
0x6f,0xba,0xf2,0xfa,0x9a,0xe2,0x99,0xae,0xbc,0xee,0xb2,0xe2,0x9a,0x24,0xbf,0x03,
3251
0x96,0xfb,0x80,0xca,0xd0,0x7b,0x36,0xf6,0x3f,0x2b,0xaf,0xd6,0xf1,0xc6,0xfd,0x99,
3252
0x15,0x9f,0xb7,0x7f,0xb7,0xf5,0x3c,0xec,0xf9,0xef,0xb1,0xd4,0x2b,0x83,0x2f,0x94,
3253
0x66,0xcf,0xff,0x53,0x2b,0xcf,0xbb,0x2d,0xff,0xbd,0x56,0x1e,0xfc,0xc7,0xfa,0xdd,
3254
0x2b,0xad,0x72,0xde,0x6d,0x3d,0xa7,0x3f,0x69,0x9d,0x7b,0x8f,0xce,0xb3,0x46,0x75,
3255
0xf0,0xb0,0xca,0x71,0x8e,0x8e,0x59,0x25,0xfb,0x61,0xeb,0x39,0x7b,0xae,0xe2,0xf0,
3256
0xe2,0x9d,0x6b,0x5d,0x3f,0xaf,0xec,0xe7,0xa9,0x2c,0xec,0xeb,0xfc,0x8a,0x15,0xce,
3257
0xb3,0xaf,0xf4,0x95,0xcf,0x02,0xeb,0x77,0xc2,0x3c,0xeb,0x9a,0xef,0xb6,0xf2,0xb3,
3258
0x4a,0xf5,0xfd,0x6d,0xab,0x2c,0xde,0x51,0x9a,0x5e,0xf7,0xd5,0x51,0xfb,0x3c,0xb6,
3259
0xff,0xeb,0xd6,0xef,0x8f,0xc3,0xaa,0xfb,0xbb,0xad,0xdf,0x1e,0x8f,0x2b,0x2d,0x2b,
3260
0x7d,0xfe,0x33,0x7c,0xee,0x39,0xd6,0xef,0x16,0xbb,0x1d,0xd8,0x75,0xcd,0xfb,0x0d,
3261
0xf3,0x84,0x75,0x4d,0xbd,0xdf,0x36,0xaf,0x29,0x9f,0xcf,0x58,0xc7,0x7f,0x61,0xb5,
3262
0xa1,0x19,0x2a,0x1f,0xaf,0xfd,0x78,0xed,0x6a,0xa1,0x65,0x5f,0xad,0x34,0x6c,0x54,
3263
0x98,0xd7,0xad,0x7d,0x5e,0xbb,0xd8,0x68,0xe5,0x7d,0x9e,0xf5,0x3b,0xca,0xcb,0xff,
3264
0x62,0xeb,0xfa,0x3e,0x69,0x95,0xd9,0x26,0x5f,0xf9,0x6f,0xd2,0xbe,0x4d,0x56,0xfc,
3265
0x2b,0xad,0xdf,0x61,0x5e,0x3a,0x3d,0xbb,0xd7,0x7e,0x9e,0xb4,0xea,0x9b,0xe7,0xde,
3266
0x2d,0xfb,0x6b,0xba,0x16,0x9f,0xc8,0x6f,0x86,0xec,0x07,0x94,0xd6,0xcf,0x65,0xdf,
3267
0x6c,0xc5,0xe1,0xb9,0x77,0x59,0x6a,0x5f,0xcf,0xdd,0x6a,0x43,0x5e,0x7b,0xb5,0xed,
3268
0x5e,0x3d,0xf2,0xb7,0xb1,0xed,0xbe,0x7e,0x66,0xbb,0x15,0xd7,0x0e,0xab,0x6f,0xdb,
3269
0x65,0x5d,0xdb,0xdd,0x72,0x7f,0xe1,0xab,0x17,0xde,0x71,0x87,0xad,0x6b,0xed,0xf5,
3270
0xb1,0x5b,0xa4,0x5e,0xd9,0xcd,0xb2,0xfa,0x1a,0xbb,0x7d,0x9b,0x7b,0xcf,0x82,0x6c,
3271
0xf7,0x7e,0x63,0x34,0x49,0x9a,0x2c,0x4d,0x91,0xa6,0x4a,0xd3,0xa4,0x35,0xa4,0x35,
3272
0xa5,0xe9,0x56,0x3c,0x76,0x9c,0x89,0x96,0x3d,0xc9,0xb2,0x27,0x5b,0xf6,0x14,0xcb,
3273
0x9e,0x6a,0xd9,0xd3,0x2c,0x7b,0x0d,0xcb,0x5e,0xd3,0xb2,0xa7,0x5b,0xe9,0x4e,0xb0,
3274
0xec,0x76,0x7e,0x92,0x2c,0x7b,0xb2,0x65,0xf7,0xce,0x7b,0x85,0xde,0xef,0x76,0xd5,
3275
0xfb,0xda,0xae,0x7a,0x57,0xdc,0x4e,0xef,0x71,0xbb,0xea,0xbe,0x3b,0x40,0xf7,0xdc,
3276
0x6c,0xdf,0x78,0x9c,0xa7,0x49,0x96,0x3d,0x59,0xef,0x93,0x4d,0x1c,0x83,0x79,0x96,
3277
0x2d,0x4a,0x44,0x71,0x3d,0xdd,0x7b,0x9c,0x79,0xaf,0x69,0x9e,0x77,0x0a,0xe3,0x7e,
3278
0xa5,0xaf,0xfb,0x0c,0x55,0xa4,0x33,0xbf,0xf3,0x5b,0xb9,0xcf,0x51,0xd9,0x3a,0x7f,
3279
0x7f,0xe9,0xab,0x9a,0xe7,0xdc,0x4f,0xee,0x3e,0xd2,0x16,0x7a,0x9f,0xdd,0x52,0xda,
3280
0x44,0xea,0x8d,0x77,0xf7,0x55,0x58,0xdb,0x9d,0xad,0x77,0xde,0xfd,0xa5,0xaf,0x46,
3281
0x1c,0xd1,0x5e,0x3a,0x87,0xf7,0xdd,0x92,0x37,0xee,0x7d,0x8d,0xdc,0x9e,0xbd,0xa5,
3282
0x65,0x6f,0x62,0xd9,0x2f,0xb4,0xec,0xaf,0x46,0x1c,0x79,0xb7,0xdd,0x57,0xe5,0xd2,
3283
0xd7,0x7a,0xe7,0xdd,0xd3,0x7a,0xef,0xdd,0x4f,0xe1,0xfb,0x39,0x47,0xe8,0x2e,0xed,
3284
0xe3,0x1c,0xed,0x9f,0x64,0xed,0x4b,0xb2,0xb4,0x8f,0xcf,0xcf,0xbb,0x06,0xdd,0x2d,
3285
0xbb,0xa7,0x7d,0x7c,0x7e,0xa5,0x2a,0xb8,0xef,0xda,0x6d,0x7b,0x92,0x55,0x27,0xfa,
3286
0x58,0xf6,0x96,0x96,0xbd,0x89,0x65,0x1f,0x64,0xd5,0x1f,0xdb,0xee,0xc5,0x77,0x2c,
3287
0xbf,0x24,0x6b,0xde,0x42,0x7f,0xe9,0xab,0x11,0x47,0xd2,0x32,0x58,0xfb,0xdb,0x6b,
3288
0x7f,0x7b,0xed,0x6f,0xaf,0xfd,0xed,0x95,0xb6,0xf6,0x4a,0x97,0x57,0x37,0x3b,0x28,
3289
0x7c,0x07,0x85,0xef,0xa0,0xf0,0x1d,0x14,0xbe,0x83,0xc2,0x7b,0xee,0x69,0xfa,0xbe,
3290
0x66,0x9a,0xe6,0xd0,0xc7,0x2b,0x7c,0xbc,0xea,0xd3,0x40,0x95,0x63,0x77,0xab,0xde,
3291
0x37,0x54,0x3e,0xbc,0x7a,0xd2,0x50,0xed,0x23,0x5e,0xfb,0xbd,0xfa,0x78,0xb5,0xc6,
3292
0x3c,0xba,0xaa,0x6e,0xb4,0xd6,0xf8,0x47,0x7f,0xd5,0x5f,0x8f,0x96,0x4a,0xcb,0x10,
3293
0xe7,0xe8,0x7a,0xd3,0x5f,0x3a,0x40,0xe7,0xe9,0xab,0x31,0x90,0x7e,0x6a,0x9b,0xfd,
3294
0xac,0x31,0xf2,0x7e,0x0a,0xd7,0x57,0xe7,0x69,0xaa,0xf2,0xb0,0xf3,0xd3,0x5a,0x78,
3295
0xd7,0xd1,0x9b,0x2b,0x32,0x48,0xe3,0x3a,0x43,0x55,0x2e,0xdd,0x54,0x9e,0x26,0x8f,
3296
0x5e,0xbb,0xf3,0xec,0x89,0xfa,0x3d,0x9e,0x24,0x4d,0x96,0xa6,0x48,0x53,0xa5,0x69,
3297
0xd2,0x1a,0xd2,0x9a,0xd2,0x74,0xa9,0xd7,0x57,0x7a,0xf6,0x44,0xcb,0x9e,0x64,0xd9,
3298
0x93,0x2d,0x7b,0x8a,0x65,0x4f,0xb5,0xec,0x69,0x96,0xbd,0x86,0x65,0xaf,0x69,0xd9,
3299
0xd3,0xad,0x74,0x27,0x58,0x76,0x3b,0x3f,0x49,0x96,0x3d,0xd9,0xb2,0xa7,0x58,0xf6,
3300
0x54,0xcb,0x9e,0x66,0xd9,0x6b,0x58,0xf6,0x9a,0x96,0x3d,0xdd,0x2a,0xa7,0x04,0xcb,
3301
0xee,0x9d,0xb7,0x97,0xd5,0x3f,0x35,0x8f,0xe4,0x37,0x0d,0x0c,0x78,0xc6,0xad,0x53,
3302
0x8d,0x35,0xee,0x56,0x31,0xc0,0xf5,0x81,0x4a,0xf8,0xd7,0x98,0x4e,0x5d,0x09,0x72,
3303
0xed,0xd0,0x3b,0xd0,0xa6,0xfc,0x1e,0xfc,0xa6,0xa7,0x3b,0x8e,0xb0,0x12,0xfb,0xbb,
3304
0x54,0x9a,0x24,0x7e,0x4f,0x7c,0xd6,0xd6,0x7d,0x07,0x6f,0x68,0xd3,0xd1,0xfd,0xdd,
3305
0x7a,0x33,0x1d,0x72,0x53,0xec,0xdf,0x71,0xc2,0xde,0x5c,0xec,0xb1,0x37,0x38,0x4e,
3306
0xfd,0x9b,0x1c,0xe7,0xe5,0x9b,0x1d,0xe7,0x87,0x71,0x8e,0x33,0x9e,0xdf,0xa8,0xc1,
3307
0x2b,0x1d,0xa7,0x34,0x17,0xfa,0x43,0x2a,0xcf,0x27,0x54,0x8e,0xba,0x37,0x3a,0xce,
3308
0x95,0x1c,0xbb,0x7f,0x92,0xe3,0x8c,0x26,0xde,0xab,0x88,0x37,0x92,0xca,0x5a,0x9a,
3309
0x4a,0x13,0xc7,0xb1,0x65,0x1e,0xa5,0x2e,0xf1,0x7b,0x75,0x37,0x95,0x6f,0xcd,0x58,
3310
0xea,0xff,0x2d,0x8e,0xf3,0x26,0x15,0x68,0xe3,0x28,0x7e,0x27,0x13,0xe7,0x2a,0xfa,
3311
0xff,0x53,0xc9,0xe4,0x95,0xc4,0x79,0x98,0x63,0xde,0xe6,0x1c,0x37,0xd1,0xd7,0xcf,
3312
0x23,0x63,0x9f,0x50,0x01,0x5f,0xa7,0xc1,0xac,0xe7,0x9c,0x45,0xd9,0xf7,0xf9,0x50,
3313
0x77,0x5c,0x26,0x8a,0x78,0x2f,0x81,0xbd,0x77,0x90,0x97,0xfb,0x29,0x8f,0x87,0x1c,
3314
0xe7,0xd0,0x23,0xdc,0x3f,0xa8,0xfc,0x37,0xd0,0xa8,0x26,0x5f,0xc7,0x39,0xc6,0x90,
3315
0x8e,0x7b,0xdc,0x31,0x8a,0x0f,0x6e,0xe5,0x19,0xe5,0x22,0xdc,0xdc,0x47,0xba,0x8c,
3316
0x70,0x9c,0xeb,0x89,0xa3,0x1b,0xf1,0xad,0x22,0xfc,0x32,0xca,0xe4,0xfb,0xfb,0x48,
3317
0x0f,0xfb,0xbb,0x5d,0xe2,0x38,0x25,0x38,0xd7,0x47,0xa4,0xa5,0x08,0xe9,0xad,0x4e,
3318
0x3c,0x35,0xae,0xa7,0x0d,0xb2,0x7f,0x1d,0x69,0xb9,0x8d,0xe3,0x72,0x48,0xd7,0x5b,
3319
0x70,0x26,0x1d,0xf9,0x22,0xf6,0xef,0xe7,0x3c,0x57,0xb1,0x7f,0xe4,0x6d,0x3c,0xff,
3320
0x74,0x73,0xcb,0xe7,0x67,0xce,0x97,0x4e,0x59,0x7c,0xce,0xef,0xf2,0xe2,0x5d,0x28,
3321
0x57,0xca,0x29,0x9b,0xdf,0xf9,0xa7,0x52,0x36,0x3f,0x72,0xce,0xc5,0xe4,0x6f,0x1a,
3322
0x69,0x29,0x44,0x98,0xb7,0xb8,0xb0,0xc3,0xb9,0xce,0x15,0x88,0xeb,0x35,0xf6,0x5f,
3323
0x46,0x3a,0x02,0xc3,0xb8,0x3f,0x52,0xae,0xcf,0x12,0xcf,0xcb,0x7d,0xdc,0xb1,0x9f,
3324
0x71,0x84,0xfb,0x99,0xf8,0x3f,0x1b,0x4d,0xfe,0xe8,0x68,0x7a,0x10,0xdf,0x0b,0x1c,
3325
0xdf,0x9b,0xb4,0xbc,0x09,0xa3,0xe8,0x48,0x3e,0x27,0x6f,0x03,0xd8,0xbf,0x8e,0xe3,
3326
0xde,0xe1,0x9a,0x7c,0x4b,0x9a,0x33,0x2f,0x74,0xdf,0x2f,0x7c,0x49,0x39,0xbf,0xc1,
3327
0x79,0x7e,0x26,0x5f,0x55,0x28,0xa3,0xe7,0x27,0x52,0xe6,0x0f,0x3a,0xce,0xfd,0x94,
3328
0xcf,0xdb,0x8f,0xba,0xe3,0x92,0xcb,0xa9,0x27,0xc3,0xcc,0xd8,0x1d,0xe7,0x1b,0x42,
3329
0xf8,0x09,0x1a,0xac,0x7d,0x90,0x6b,0x10,0xcb,0x71,0xcd,0xe8,0xec,0x6e,0xa1,0x13,
3330
0x5a,0xc5,0xf1,0xdf,0x90,0xde,0x01,0x94,0x47,0x45,0xc2,0x7e,0x45,0x5a,0x63,0xb9,
3331
0x6e,0xcd,0x29,0xef,0x53,0x89,0xe7,0x09,0x58,0xc8,0x79,0x57,0x52,0x47,0x96,0x8d,
3332
0x73,0xf3,0xf1,0x26,0xf1,0x7d,0x4b,0x9e,0xaf,0x25,0xed,0x2f,0x70,0x8e,0x7a,0xa4,
3333
0xf5,0xaa,0xc1,0xee,0x6f,0xdb,0x83,0xed,0xdd,0xb2,0x7a,0x99,0x7a,0x72,0x26,0xe5,
3334
0x35,0x1b,0xff,0xde,0x9c,0xe7,0x41,0xea,0x5f,0x63,0xce,0x91,0x72,0x37,0x75,0x92,
3335
0x32,0x6e,0xca,0xb5,0x3e,0xed,0x01,0xae,0x03,0xe5,0xf7,0x82,0x79,0x87,0x42,0x1e,
3336
0xe7,0xe3,0xff,0x29,0xc7,0xdc,0x44,0x3c,0x1f,0xd1,0x69,0x7d,0x45,0x3c,0xf5,0xb9,
3337
0x8e,0x93,0x7a,0xb8,0xd7,0xe2,0x6d,0xd2,0x9c,0x49,0xbd,0x39,0x4c,0x1a,0x47,0x4c,
3338
0x70,0xc7,0x9e,0xc6,0x91,0xcf,0x78,0x8e,0xbb,0x85,0x74,0x5e,0x4b,0xdd,0x3b,0x00,
3339
0x0d,0xb8,0xe6,0x0f,0xd3,0x36,0x62,0x38,0x6f,0x47,0xca,0xb6,0x0f,0xd7,0xa9,0x28,
3340
0x79,0xbc,0xec,0x01,0xf7,0xbd,0x4f,0x3c,0xe5,0x30,0x9c,0x63,0xaa,0x72,0x8e,0xd3,
3341
0x49,0xe7,0x2e,0xc2,0x57,0x21,0xef,0xb7,0x91,0xa7,0x46,0x94,0xd3,0xa9,0x57,0xb8,
3342
0xd7,0xf9,0x26,0xc2,0x9c,0x4b,0xbc,0x45,0xc8,0x7f,0x0f,0x53,0x9f,0x38,0xd7,0xf9,
3343
0xc4,0x3f,0x95,0xfd,0x9f,0x71,0x0d,0xa3,0x88,0x7f,0x2b,0xf1,0x5f,0x4d,0xde,0xde,
3344
0xa1,0x6c,0x3e,0x1d,0xe7,0x8e,0xe3,0x6d,0xe5,0xb8,0xfa,0x5c,0xff,0x97,0x49,0xc3,
3345
0x59,0x1c,0xbb,0x96,0x74,0x3f,0x40,0xd8,0x43,0xb4,0x99,0x27,0xd8,0xd7,0xe1,0x61,
3346
0xc7,0x79,0x8c,0xeb,0x74,0x3f,0x71,0xad,0xe6,0xdc,0x3b,0x47,0xb9,0x63,0x98,0xe5,
3347
0xae,0x75,0x9c,0xbb,0x29,0xcb,0x25,0xd4,0xe7,0x49,0x94,0xf7,0x45,0xd4,0xc3,0x25,
3348
0x66,0x9c,0x9a,0x7a,0x59,0x8b,0x74,0x44,0xc3,0xd3,0x94,0xfd,0x7a,0xd2,0xff,0x01,
3349
0xe1,0xc6,0x52,0x3e,0x65,0x38,0xfe,0x45,0xd2,0x55,0x7b,0xbc,0x3b,0x36,0xd9,0xf2,
3350
0x3e,0x77,0x5c,0x72,0x3d,0xe1,0x32,0xc8,0xeb,0x12,0xfa,0x81,0x8b,0xa9,0x87,0x43,
3351
0x08,0xf3,0x09,0xee,0x2a,0xe4,0x6b,0x15,0x65,0x58,0x87,0x32,0xbf,0x0c,0x7a,0xc0,
3352
0x78,0x68,0xcf,0xf5,0x58,0x34,0xc2,0x1d,0x2f,0x2d,0x4e,0x7b,0xfc,0x81,0xeb,0x5c,
3353
0x93,0x32,0xfe,0x09,0xf6,0x52,0x6e,0x87,0xa1,0x32,0xfd,0xc2,0x8b,0xb4,0xcd,0x4f,
3354
0xf0,0x9b,0xc7,0x79,0x5e,0xe0,0xda,0x7d,0x4e,0x19,0xb6,0x34,0xf5,0x96,0xb4,0x6d,
3355
0x87,0x36,0xe4,0xfb,0x11,0xce,0x19,0x45,0x3d,0xb8,0x02,0x32,0x38,0xf7,0x54,0xb8,
3356
0x5c,0xe3,0xd8,0xf7,0x72,0x7d,0xaf,0xa0,0x8c,0xef,0x84,0xaf,0xa1,0x15,0xd7,0x76,
3357
0x2b,0xdc,0x45,0xfa,0xc6,0x52,0xae,0xc3,0xc8,0xcf,0x19,0x94,0x5b,0x05,0xea,0x68,
3358
0x7f,0xca,0xad,0x2a,0x65,0x51,0x81,0xb2,0xbb,0x6b,0xb8,0xfb,0xcc,0xd8,0x0c,0x9a,
3359
0x42,0x6b,0x93,0xe6,0xab,0xdd,0xf7,0x6f,0x77,0xc0,0x9d,0x90,0x41,0x19,0x8e,0x82,
3360
0x25,0xd7,0xba,0x75,0x3a,0x86,0xf6,0xde,0x00,0x06,0x91,0xa7,0x10,0x75,0x6f,0x0f,
3361
0xe5,0x7c,0xf5,0x68,0x97,0x0e,0xd4,0xa1,0xa2,0x94,0xd3,0x7d,0x10,0xa0,0x9c,0xd3,
3362
0x61,0x3d,0xfd,0x47,0x3e,0xfa,0xa1,0x97,0xc6,0xbb,0x79,0xdf,0x46,0x1e,0x7f,0xa1,
3363
0x5c,0x6a,0x93,0xf7,0xab,0x48,0xf7,0x57,0x99,0x41,0xe7,0x34,0x8e,0xad,0xc8,0x35,
3364
0x99,0x4b,0x9e,0xaf,0x80,0x91,0x94,0x41,0x96,0x51,0x58,0x41,0xfe,0x0f,0x5d,0xe0,
3365
0xe6,0xbf,0x1d,0x4c,0x82,0xad,0x2a,0xff,0x39,0xd0,0x88,0xb6,0x7b,0x21,0x74,0xbb,
3366
0x98,0xb2,0xe4,0xda,0xad,0xe3,0x1a,0x7d,0x08,0xbd,0xa9,0x77,0xcf,0xc3,0x46,0xce,
3367
0x71,0x3e,0x65,0x92,0x4f,0xe5,0xd3,0x45,0x65,0x94,0xc2,0xf5,0x7e,0x9d,0xb6,0x76,
3368
0x26,0x6d,0xf7,0x02,0x68,0xdf,0xc3,0xbd,0x9e,0xa6,0xaf,0x2d,0x0d,0xed,0x7b,0xb9,
3369
0xe3,0xf3,0xa6,0x7f,0x31,0x75,0x7f,0x13,0xe5,0xb7,0x5a,0x65,0x58,0x26,0xdb,0x2d,
3370
0xc7,0x67,0xe8,0x87,0x52,0x29,0xcb,0x19,0x83,0xdc,0x3a,0x30,0x90,0x32,0x8d,0xa2,
3371
0xee,0xd6,0x86,0xb3,0xa8,0x0f,0x65,0x87,0xba,0xf5,0x62,0x13,0x7c,0x03,0xcd,0x09,
3372
0x9f,0x01,0x6f,0x51,0xee,0xb3,0x54,0xa6,0xd7,0x52,0x3f,0x3a,0x5d,0xe7,0x96,0x6d,
3373
0x3d,0x95,0xe9,0x05,0xd4,0xcd,0xbd,0x70,0x35,0xf7,0x95,0x06,0x94,0xe5,0x4d,0x2a,
3374
0xd3,0xc5,0xb7,0xba,0x75,0x68,0xf5,0xad,0x6e,0xf9,0x9a,0x7e,0x74,0xcf,0xad,0x6e,
3375
0x39,0xdf,0x7a,0x9b,0x5b,0xce,0x35,0x29,0xe7,0x41,0x94,0xf3,0x24,0xda,0xcc,0x50,
3376
0xfa,0x85,0x11,0xf7,0xb9,0x65,0x6e,0xea,0xe2,0xa6,0xfb,0xdd,0xb2,0x2f,0xf0,0x80,
3377
0x5b,0xfe,0xc5,0x1f,0x72,0xef,0x6f,0xcd,0x2b,0x07,0x9d,0x46,0xf0,0x7e,0x72,0xd0,
3378
0x79,0xa4,0x36,0x7d,0x48,0x06,0x71,0x42,0xb3,0x0b,0x82,0xce,0xda,0x4b,0x82,0xce,
3379
0xfa,0xeb,0x83,0x4e,0x43,0xc2,0xdd,0xf9,0x98,0xfb,0xec,0xed,0xd1,0x5b,0xda,0xf7,
3380
0x18,0x7e,0x9e,0xbf,0x37,0x0f,0xc5,0xd3,0x21,0x21,0xd2,0x15,0x72,0xb5,0x87,0xb4,
3381
0x0f,0x5c,0x6f,0xf9,0xf7,0x83,0x0f,0xe1,0x45,0xf8,0x1a,0xe6,0xc1,0xd6,0x90,0x3b,
3382
0x67,0xd5,0xcc,0x55,0x7d,0x0f,0x36,0x41,0x0e,0x7c,0x0c,0x3b,0x61,0x57,0xc8,0x9d,
3383
0x03,0xfc,0x05,0xba,0x34,0xe4,0xea,0x32,0xe9,0xab,0x96,0xdf,0xab,0xf2,0x5f,0xab,
3384
0x78,0x8d,0xce,0x97,0xbe,0xaa,0x39,0xb1,0xaf,0x6a,0x5e,0xec,0xab,0x3a,0xdf,0xab,
3385
0x3a,0xa7,0xd1,0xf7,0xa5,0x1f,0x48,0x37,0x4a,0x3f,0x94,0x7e,0x24,0xdd,0x24,0xcd,
3386
0x91,0x7e,0x22,0xdd,0x22,0xfd,0x54,0xba,0x4d,0xba,0x5d,0xba,0x43,0xfa,0xb9,0x74,
3387
0xa7,0xd4,0x4b,0xfb,0x2e,0x2b,0x1d,0x0b,0x94,0xde,0xc5,0x3a,0xdf,0x62,0xc5,0xb3,
3388
0x58,0xf9,0x31,0xe7,0x1e,0x18,0xe5,0x72,0xad,0x8f,0xeb,0x7d,0x8c,0xf4,0x71,0x8d,
3389
0x8f,0x1b,0x7c,0x5c,0xed,0xe3,0x49,0x1f,0x4f,0xfb,0xb8,0xd1,0xc7,0x18,0x1f,0x37,
3390
0xf9,0xb8,0xd9,0xc7,0x1d,0xe2,0x76,0x71,0xa7,0x18,0x27,0x1e,0x10,0x77,0x89,0x69,
3391
0x3e,0x66,0xf8,0x98,0xe3,0x63,0x96,0x8f,0x97,0xc5,0x2b,0x3e,0xbc,0xb5,0x6b,0xec,
3392
0x35,0x6c,0x6c,0x16,0xf9,0x58,0x67,0x61,0xaf,0x75,0xf3,0xbc,0x8f,0x15,0x62,0xb9,
3393
0x58,0x29,0xbc,0xb5,0x73,0x56,0x8b,0x37,0xc4,0x9b,0x62,0xad,0x8f,0x66,0xc2,0x5e,
3394
0x8b,0xe7,0x58,0xf6,0xf7,0xf3,0xb0,0x37,0xcd,0xc3,0xbe,0x22,0x0f,0xfb,0xf2,0x3c,
3395
0xec,0x2b,0xf3,0xb0,0xaf,0x3d,0x01,0x7b,0xb3,0xff,0x60,0x7f,0xcb,0x87,0xb7,0xaf,
3396
0x9a,0x65,0x8f,0xb3,0xec,0x59,0x79,0xc4,0x65,0xb4,0xb2,0x8e,0xab,0xac,0x63,0x8c,
3397
0xc6,0x4b,0xb3,0xa4,0xcd,0xa4,0x26,0x7c,0x15,0x85,0xaf,0xa2,0xf0,0x55,0x14,0xbe,
3398
0x8a,0xc2,0x57,0x51,0xf8,0x2a,0x0a,0x5f,0x55,0xe1,0xab,0x6a,0x7f,0x55,0xed,0xaf,
3399
0xaa,0xfd,0xd5,0x14,0x4f,0x35,0xed,0x8f,0xb3,0xfc,0xb2,0x14,0x77,0x35,0x69,0x9c,
3400
0xd4,0xf8,0x27,0xcb,0x3f,0x59,0xfe,0xc9,0xda,0x97,0xac,0xfd,0xa9,0xf2,0x4f,0x95,
3401
0x3b,0x4d,0xe1,0xd3,0xe4,0x9f,0xa6,0xf0,0x69,0xda,0x5f,0x43,0xfe,0x35,0xe4,0xae,
3402
0x29,0x4d,0xd7,0x71,0xe9,0x72,0xd7,0x92,0xbb,0x96,0xdc,0x0d,0xe4,0x6e,0xa0,0xe3,
3403
0x1b,0x28,0xde,0x06,0xd6,0xfe,0x66,0x52,0x93,0xdf,0x4c,0x85,0xcb,0xd4,0xfe,0x4c,
3404
0xed,0xcf,0xd4,0xfe,0x86,0xaa,0xa3,0x0d,0x15,0x6f,0x43,0x85,0x6f,0xa8,0x78,0x8d,
3405
0x36,0x92,0x66,0x49,0x9b,0x49,0x9b,0x6b,0x5f,0x35,0x69,0x9c,0x34,0x5e,0x9a,0x25,
3406
0x6d,0x26,0x6d,0x2e,0x3f,0xbb,0xec,0xb3,0xac,0x32,0xf6,0x68,0x66,0xd5,0xa1,0xc6,
3407
0x0a,0xdf,0x58,0xe1,0x1b,0x2b,0x7c,0x63,0x85,0x69,0xac,0xf0,0x8d,0x15,0xbe,0x89,
3408
0xc2,0x37,0xd1,0xfe,0x26,0xda,0xdf,0x44,0xfb,0x9b,0x5b,0xf5,0xd6,0xab,0xb3,0xf1,
3409
0x56,0xda,0x9a,0x5b,0x75,0xd6,0x90,0x00,0xd9,0x90,0x28,0x6d,0x26,0x35,0xf3,0xa6,
3410
0xce,0x43,0xdb,0xc8,0xde,0xd2,0xb2,0x9f,0x6f,0xd9,0x5b,0x59,0xf6,0xd6,0x96,0xbd,
3411
0x8d,0xe2,0xf1,0xda,0x46,0xa2,0x65,0x4f,0xca,0xa3,0x2d,0x35,0x3e,0x4e,0xbb,0x4a,
3412
0x94,0x26,0xf9,0xda,0x53,0xe3,0x3c,0xda,0x55,0xa2,0x34,0xc9,0xd7,0x9e,0x1a,0xe7,
3413
0xd1,0xae,0x12,0xa5,0x49,0xbe,0xf6,0xd5,0xf8,0x18,0xed,0xec,0x58,0xf5,0x30,0xaf,
3414
0x7a,0x77,0xbc,0xfa,0x95,0x57,0x3d,0xaa,0x64,0xd5,0x99,0xc6,0x4a,0x5f,0x63,0xa5,
3415
0xcf,0xae,0x1f,0x8d,0x8f,0x51,0x4f,0x9a,0x59,0xe5,0xef,0x95,0x7d,0x92,0xaf,0x1e,
3416
0x34,0x3e,0x46,0x7d,0x38,0x5e,0xdf,0x17,0x9f,0xc7,0xb5,0x6b,0x72,0x82,0x7d,0x5f,
3417
0x93,0x13,0xec,0xf3,0x9a,0x58,0xd7,0xe0,0x64,0xfa,0xb4,0x93,0xed,0xcb,0xe2,0x7f,
3418
0x43,0x9f,0xf6,0x47,0xf5,0x65,0xfe,0xbe,0xeb,0x44,0xfb,0xa8,0x13,0xe9,0x93,0x9a,
3419
0x9c,0x40,0x5f,0x74,0x22,0x7d,0x4f,0x93,0x3c,0xfa,0x9c,0xec,0x13,0xec,0x6b,0x9a,
3420
0x1c,0xa7,0xbe,0xf8,0xeb,0xc5,0xb1,0xae,0x7f,0x55,0xb9,0x93,0xad,0xeb,0x6b,0xdc,
3421
0x29,0x72,0xa7,0xc8,0x7d,0xac,0x72,0xca,0x3a,0x46,0x7e,0xfc,0xe9,0xcb,0x88,0x3a,
3422
0xd2,0xa7,0x19,0x7b,0x2b,0xcb,0xee,0xf5,0x69,0x35,0xd4,0x4e,0x6a,0xe8,0xb8,0x74,
3423
0xb9,0xd3,0xe5,0xae,0x25,0x77,0x2d,0xb9,0x93,0xe5,0x4e,0x96,0x3b,0x45,0xee,0x14,
3424
0xab,0xbc,0x9a,0x59,0xe5,0x56,0x4d,0xee,0x6a,0x56,0x39,0x36,0xb3,0xca,0x33,0x55,
3425
0xee,0x54,0xb9,0xd3,0xe4,0x4e,0xb3,0xe2,0xaf,0x26,0x8d,0x93,0xc6,0xfb,0xca,0x28,
3426
0x51,0xe9,0x49,0x54,0x3c,0x89,0x3a,0x3e,0xf1,0x5f,0x90,0xbf,0xe3,0x1d,0x6f,0xd7,
3427
0xa9,0x26,0xd6,0x73,0x4b,0x5e,0x7d,0x49,0x5e,0xf1,0xf9,0x9f,0x77,0x4c,0x1f,0xde,
3428
0xc2,0xd2,0x2a,0x56,0x9b,0xac,0x62,0xf5,0x65,0xc7,0xb2,0x67,0x59,0x7d,0x63,0x96,
3429
0xd5,0x3e,0xaa,0x59,0xf6,0x38,0xcb,0x1e,0x7f,0x8c,0x3e,0xd2,0xb3,0xc7,0x59,0x75,
3430
0x3e,0xce,0x7a,0x0e,0x49,0xb6,0xc2,0x26,0x5b,0xfd,0x6a,0xb2,0x75,0xcd,0x92,0xad,
3431
0x78,0x8e,0x65,0xaf,0x66,0xd9,0xb3,0x7c,0xf6,0x54,0xeb,0xfc,0x7e,0x7b,0x96,0x75,
3432
0xed,0xe2,0xf2,0xb0,0x57,0xb3,0xae,0x7f,0x96,0xef,0x9a,0xd9,0xf6,0x2c,0x9f,0x3d,
3433
0xcd,0xaa,0x83,0x69,0x56,0x19,0xda,0xf6,0x1a,0x56,0x5e,0x8e,0x65,0xb7,0xc3,0x34,
3434
0xb7,0xfa,0xfb,0x2c,0xab,0xcf,0xcf,0xcb,0xde,0xcc,0xba,0x0f,0x64,0x59,0xf6,0xe6,
3435
0x96,0xbd,0x99,0x75,0x4f,0xc8,0xf2,0xd9,0x33,0xad,0xf4,0x64,0x5a,0xf1,0x34,0xb2,
3436
0xca,0xa7,0x91,0xd5,0xbe,0x1a,0x59,0xf9,0xf5,0xee,0x0f,0xd5,0x8e,0x61,0x8f,0xb7,
3437
0x8e,0x8d,0xf7,0xf5,0x93,0x71,0x3e,0xfb,0xb1,0xea,0x51,0x96,0x65,0x6f,0xee,0xbb,
3438
0x3f,0xdb,0xf7,0x1b,0x7f,0x7d,0xb4,0xef,0x3b,0xde,0xbd,0xda,0xbe,0x47,0x35,0xf1,
3439
0xdd,0x97,0xe2,0x7c,0xf6,0x66,0xd6,0xfd,0x2a,0x2b,0x0f,0x7b,0x33,0xab,0xaf,0x6f,
3440
0x6e,0xd9,0x9b,0x59,0x69,0xcd,0xf2,0xd9,0x2b,0x5b,0x7d,0x50,0x15,0xab,0xbe,0x55,
3441
0xb1,0xe2,0xac,0xe2,0x0b,0x13,0x6f,0xf9,0x67,0x59,0xfe,0x59,0x56,0x1f,0x97,0xe5,
3442
0xfb,0x3d,0x66,0xfb,0x37,0xb3,0xfa,0x91,0x66,0x56,0xbb,0x68,0x6e,0xd5,0xff,0xe6,
3443
0x56,0x1d,0xb6,0x7f,0x87,0xd8,0xcf,0x8c,0xcd,0x7d,0xf7,0x5e,0xfb,0x7e,0xdc,0xfc,
3444
0x18,0x79,0x6d,0x6e,0xd5,0xa5,0xe6,0x56,0xd9,0x36,0xf7,0xd5,0x37,0xbb,0x8e,0xa5,
3445
0x5b,0xe1,0x1b,0x1e,0xe3,0x77,0x8b,0xfd,0x5c,0x61,0xa7,0x33,0xcb,0x0a,0x9f,0xe5,
3446
0xf3,0x6f,0xec,0x7b,0xa6,0x8b,0xb3,0xf2,0x51,0xcd,0x57,0xaf,0x9a,0x5b,0xcf,0x4b,
3447
0xcd,0xad,0x67,0xcb,0xe6,0xbe,0xf8,0xed,0xb6,0x99,0xea,0xeb,0x8b,0xe2,0x7d,0x69,
3448
0xf6,0xee,0x37,0x8d,0xf4,0xee,0x24,0xd3,0xb2,0x57,0x92,0xdd,0x7b,0x86,0xf2,0x9e,
3449
0xe1,0xbd,0xdf,0x1f,0x76,0x3b,0xa8,0x6e,0xc5,0xe3,0x95,0x93,0x77,0x0f,0x6a,0x6a,
3450
0xf9,0x37,0xb2,0x9e,0x35,0x9a,0x6a,0x7f,0x23,0x2b,0xad,0x8d,0xac,0x7a,0xe0,0xd9,
3451
0x73,0xff,0x8e,0x8a,0x2f,0x2d,0xc6,0xcf,0x1f,0x9f,0xf1,0xf3,0xc7,0xe9,0xb5,0x75,
3452
0xb3,0xcf,0xb3,0x57,0xb2,0xe2,0x49,0xd4,0x7b,0x0e,0xcf,0xaf,0x9a,0x99,0x33,0x9d,
3453
0xe0,0x38,0xc1,0x04,0xf7,0x5b,0xbd,0xda,0xd6,0xba,0x0b,0xa7,0xe0,0x77,0x6a,0xc2,
3454
0xb1,0xd7,0x79,0x28,0xc9,0x09,0x4a,0x40,0x67,0xc7,0xc5,0x5b,0x23,0xe1,0x5a,0xb8,
3455
0xce,0xec,0xe7,0xb8,0x52,0x50,0x14,0x8a,0x41,0x7e,0x28,0x90,0x70,0xe4,0xdb,0xe4,
3456
0x82,0x50,0x08,0x0a,0x43,0x11,0xf3,0x0d,0x91,0x99,0x03,0x6e,0xad,0x05,0x91,0x97,
3457
0x7a,0xe7,0x33,0x78,0x69,0x8f,0x57,0xba,0x6b,0x59,0x6b,0x47,0x98,0xf4,0xe5,0x95,
3458
0xa6,0x58,0x33,0x86,0x6b,0xe6,0xae,0x6b,0x9d,0x87,0x38,0xc7,0xfd,0x06,0xbc,0x9e,
3459
0xbe,0x4b,0xbc,0xc4,0xac,0x0b,0x69,0xd6,0x86,0x85,0x0c,0xa5,0xa9,0x85,0x9e,0x09,
3460
0x5b,0x58,0xbf,0x8f,0xbd,0xdf,0xc6,0xde,0xef,0x62,0xef,0x59,0xd2,0xfb,0x6d,0xec,
3461
0x3d,0x4f,0x7a,0xbf,0x8f,0xbd,0x67,0x4a,0xef,0x37,0x72,0x86,0xf5,0x9b,0xf9,0x02,
3462
0xb9,0x8d,0x96,0x8f,0x3a,0x7a,0x6d,0x6c,0x7b,0x8d,0x6c,0xff,0x5a,0xd9,0xfe,0x35,
3463
0xb3,0xfd,0x6b,0x67,0xe7,0xa5,0x95,0x44,0x65,0x1f,0xe7,0x8a,0x2a,0x3e,0xaa,0xfa,
3464
0xa8,0xe6,0x23,0xce,0x47,0xbc,0x8f,0xea,0x22,0x41,0x24,0x8a,0x24,0x91,0xec,0x23,
3465
0xc5,0x47,0xaa,0x8f,0x34,0x1f,0x35,0x7c,0xd4,0xf4,0x91,0xee,0xa3,0x96,0x8f,0x06,
3466
0x3e,0x32,0x7d,0x34,0xf4,0xd1,0xc8,0x47,0x96,0x8f,0xc6,0x3e,0x9a,0xf8,0x68,0x2a,
3467
0x9a,0x1d,0xe3,0x37,0x78,0x73,0xab,0xdd,0xb6,0xcd,0xc3,0x7e,0x61,0x1e,0xf6,0x76,
3468
0x79,0xd8,0x3d,0x35,0x6d,0xa3,0x82,0xe3,0xb6,0x01,0xaf,0x8e,0x9b,0xb6,0x50,0xc9,
3469
0x6a,0xc3,0x5e,0xbb,0xa8,0xa6,0xb6,0x11,0xaf,0xb5,0x48,0x4e,0x74,0xed,0x14,0xaf,
3470
0x1f,0xa9,0xa3,0xf6,0x54,0x4f,0xed,0x32,0xe3,0x4f,0xfc,0xee,0xb9,0x93,0xda,0xb1,
3471
0xe9,0x53,0x2e,0x53,0x7f,0xd1,0xe5,0x4f,0xfc,0x1e,0xda,0xf4,0x39,0x23,0xd4,0xef,
3472
0x5c,0x0f,0x63,0x29,0xd8,0x9b,0xce,0x75,0xfb,0x59,0xaf,0xef,0x33,0x7d,0xd7,0x8f,
3473
0x9a,0x73,0x3e,0x45,0xf3,0x65,0x9f,0xd2,0xdc,0x58,0x33,0x27,0x7c,0x9b,0xe6,0x58,
3474
0x7f,0xae,0x39,0x92,0x87,0x13,0xfe,0x7e,0xf3,0xea,0x0f,0x68,0xae,0xa7,0x99,0x23,
3475
0xda,0xa5,0xd8,0x3f,0xeb,0xdb,0xc3,0xc7,0xc9,0xce,0x13,0xf0,0x9c,0xf5,0x77,0xd1,
3476
0x9e,0x46,0x9f,0x32,0xf3,0xd7,0xf0,0x08,0x9e,0xe3,0xae,0x89,0x72,0x57,0x79,0x77,
3477
0x4d,0x94,0x7b,0x60,0x32,0x7e,0xab,0x61,0x6d,0xd0,0x71,0xde,0x0d,0xba,0x7f,0xbf,
3478
0x65,0x12,0xda,0x16,0x9e,0x30,0x6b,0xa3,0x4f,0xe7,0x78,0xf4,0x49,0x68,0x0f,0x1d,
3479
0xcc,0xda,0xe5,0x67,0x51,0xb7,0xd1,0xcb,0x60,0x1a,0x5c,0x0e,0xdd,0xa0,0x0b,0x3c,
3480
0x14,0x74,0xd7,0xff,0x79,0xd8,0xac,0xf1,0x0e,0x37,0xc2,0xb3,0x66,0x3d,0x74,0xf3,
3481
0x37,0x43,0x20,0x72,0x73,0xc0,0xb9,0xf3,0x19,0xf2,0x82,0x3d,0x64,0xec,0x68,0x14,
3482
0x6a,0xfe,0x4e,0xcc,0x50,0xf3,0x37,0x49,0x82,0x6e,0x9d,0xbe,0x06,0xcd,0x87,0xff,
3483
0x75,0xe8,0xf5,0x30,0x12,0xa6,0xc2,0xd3,0x26,0x5e,0xd2,0xf4,0x0c,0x3a,0xce,0x84,
3484
0xa5,0x53,0x18,0x8f,0x4e,0x81,0xc7,0xe1,0x01,0x58,0xc2,0xf9,0x97,0xc2,0x32,0xc8,
3485
0x4f,0x1c,0x65,0x60,0x52,0xd1,0x80,0xf3,0x32,0x3c,0x24,0x7d,0x4a,0x9a,0x58,0x2c,
3486
0xe0,0x54,0x82,0x24,0x69,0x93,0x12,0x01,0xa7,0x5e,0x09,0x57,0x3b,0xc0,0x82,0x92,
3487
0x84,0x2b,0xe9,0xea,0x4c,0xe9,0x42,0x98,0x5f,0x2a,0xe0,0xcc,0x80,0x05,0xd2,0xd4,
3488
0xd3,0x03,0x4e,0x02,0x74,0x78,0x37,0xe0,0xf4,0x80,0x8b,0x7c,0xda,0xdf,0xb2,0x0f,
3489
0xb0,0xec,0xd9,0x96,0x7d,0xa0,0x65,0x1f,0x04,0x0b,0x64,0x7f,0x59,0xba,0xc0,0x8a,
3490
0xeb,0x65,0xcb,0xbe,0xc0,0x8a,0xf7,0x65,0xcb,0xfe,0x4f,0x5b,0xd3,0xe1,0xaf,0x90,
3491
0x9f,0x7f,0x52,0x5e,0xfe,0xe8,0x6b,0xe3,0xe5,0xa5,0x89,0x95,0x76,0x7f,0x9a,0x4f,
3492
0x36,0xbd,0x3d,0x8f,0x93,0xce,0x7f,0x7b,0x99,0x67,0x1e,0x23,0x2f,0xc7,0xcb,0xc3,
3493
0x7f,0x4a,0xff,0xff,0x3a,0xed,0xc7,0xba,0x06,0xad,0xfe,0x62,0x69,0x0e,0xf7,0xa7,
3494
0xe1,0xfc,0x84,0xf3,0x13,0xce,0xcf,0x3f,0x2d,0x3f,0x89,0x3c,0x2f,0xd7,0x08,0xba,
3495
0xeb,0xf0,0xde,0xad,0xb5,0x31,0xef,0xd5,0x7a,0xb9,0xf7,0x69,0x7d,0xdc,0x07,0xb4,
3496
0x66,0xed,0x83,0xf0,0x10,0x3c,0x0c,0x8f,0xc0,0xa3,0x5a,0xe7,0x75,0xb2,0xd6,0x91,
3497
0x7d,0x40,0x7f,0xfb,0xee,0x49,0xad,0x2f,0xfb,0x34,0x3c,0x63,0xd6,0x18,0xd4,0xba,
3498
0xaf,0xd1,0x15,0xdc,0xb5,0x81,0xed,0xbf,0xe5,0x64,0xd6,0xe2,0x7e,0x49,0x6b,0xf6,
3499
0xce,0xd7,0xfa,0xb9,0xe6,0x6f,0xea,0xbd,0xa2,0xbf,0xe7,0xbc,0x10,0x16,0x69,0x0d,
3500
0xee,0x25,0xd6,0xdf,0xda,0x7b,0x0d,0x5e,0xd7,0x5a,0xb7,0xde,0xdf,0x7a,0x5a,0xa9,
3501
0xb5,0x68,0x83,0x15,0xdc,0x78,0xe7,0x2b,0xae,0xe5,0x3a,0x6e,0x49,0x44,0x38,0x9f,
3502
0xe1,0x7c,0x86,0xf3,0xf9,0x57,0xce,0x67,0x0e,0x7c,0x1c,0x71,0xe2,0xef,0xf9,0xfe,
3503
0xf2,0xe1,0x22,0x09,0x07,0x49,0x91,0xee,0xdf,0xee,0x4c,0x89,0x74,0xff,0xa6,0xa6,
3504
0xf9,0xbb,0x99,0xe6,0x6f,0x65,0x9a,0xbf,0x87,0x69,0xfe,0x86,0x67,0x6d,0xa8,0x13,
3505
0xe9,0xfe,0x3d,0xcc,0xfa,0x90,0x01,0x0d,0x20,0x33,0xd2,0xfd,0x9b,0x96,0x8d,0x20,
3506
0x0b,0x1a,0x47,0xba,0x7f,0xd3,0xb2,0x69,0xa4,0xfb,0xb7,0x2c,0xcd,0xdf,0xc7,0x3c,
3507
0x1f,0x6e,0x79,0xda,0xfd,0xdb,0x9c,0xe6,0xef,0x82,0x5e,0x14,0xe9,0xfe,0x1d,0xcd,
3508
0x19,0xf0,0x4e,0xe4,0xc9,0xa5,0xc1,0x3b,0x7f,0x83,0xff,0x70,0xde,0xe6,0x3a,0xf7,
3509
0x5d,0x3a,0x5f,0x3b,0xe8,0x0c,0xd3,0xa1,0x0d,0xe9,0x98,0x15,0x79,0xe4,0xbd,0x7e,
3510
0x35,0xbd,0x73,0x6f,0xaa,0x77,0xec,0x71,0xd6,0x1c,0x8f,0x86,0xbe,0x39,0x32,0xc9,
3511
0x7a,0x2f,0xde,0x40,0xef,0xd7,0x33,0xad,0xb9,0x13,0xde,0xfb,0xff,0x78,0xbd,0xbb,
3512
0x4f,0xd3,0x3b,0x75,0xf3,0xde,0xbc,0xbf,0xe6,0x35,0x4f,0x81,0x01,0xd6,0x79,0x9b,
3513
0xf8,0xc6,0xea,0x8e,0x77,0x2e,0xff,0x79,0xd2,0xac,0x39,0x55,0xf6,0x38,0xa8,0x7d,
3514
0xbc,0x7d,0xac,0x7d,0xcc,0xcb,0x79,0xa4,0xa5,0x86,0x6f,0xec,0xf0,0x64,0xd2,0x62,
3515
0xe7,0x77,0x4a,0xd4,0xff,0x2f,0xe3,0x26,0x79,0x94,0xf3,0x1f,0x51,0xc6,0xc7,0xbb,
3516
0x96,0x7f,0xc4,0x39,0xbc,0xf5,0x5c,0x13,0xf4,0xde,0x3f,0x51,0x9a,0x24,0x4d,0x96,
3517
0xa6,0x48,0x53,0xa5,0x69,0xd2,0x1a,0xd2,0x9a,0xd2,0x74,0x69,0x65,0x3d,0xb7,0x79,
3518
0xeb,0x2a,0x65,0x5a,0xf6,0x86,0x96,0xbd,0x91,0x65,0xcf,0xb2,0xec,0x8d,0x2d,0x7b,
3519
0x13,0xcb,0xde,0xd4,0xb2,0x37,0xb3,0xec,0xcd,0x2d,0x7b,0x0b,0xcb,0x7e,0x9e,0x65,
3520
0x6f,0x69,0xd9,0xcf,0xb7,0xec,0xad,0x2c,0x7b,0x6b,0xcb,0xde,0xc6,0xb2,0x5f,0x60,
3521
0xd9,0xdb,0x5a,0xf6,0x0b,0x2d,0x7b,0x3b,0xcb,0xde,0xde,0xb2,0x77,0xb0,0xec,0x17,
3522
0x59,0xf6,0x8e,0x96,0xfd,0x62,0xd9,0xcd,0x58,0xa5,0x89,0xdf,0x8c,0x57,0x36,0xd4,
3523
0x79,0xbd,0xe7,0xde,0x0e,0x0a,0xf7,0x67,0x3d,0x0f,0x37,0xf5,0x7d,0xd7,0xdd,0x56,
3524
0xe7,0x6b,0x2b,0xbc,0xef,0x98,0xbd,0x63,0x1b,0x2a,0xac,0xa7,0xde,0x1a,0xe5,0x17,
3525
0xc8,0x6e,0xd2,0x64,0xd6,0x6c,0x6c,0xa1,0xb1,0x0a,0x6f,0xbc,0xc2,0xac,0x7b,0xda,
3526
0xa1,0x93,0xe3,0xbc,0xd5,0xf6,0xc8,0x9a,0x28,0x66,0x4d,0xa8,0x33,0x48,0xc8,0xb6,
3527
0x5b,0xdc,0x35,0xf1,0x9e,0xc4,0x5d,0x8e,0x87,0xf1,0xf2,0x03,0xdd,0x6f,0x0e,0x5b,
3528
0x12,0xe9,0xed,0x9d,0x1d,0xe7,0x0e,0x32,0x33,0x13,0xf7,0x59,0xe6,0x1b,0xcc,0xeb,
3529
0xdc,0x35,0x4b,0xa7,0xdd,0xee,0x38,0xfb,0xc8,0x48,0x3a,0x99,0x2b,0xc9,0xc3,0xf9,
3530
0x44,0xe2,0x6f,0xd7,0xdd,0x2d,0x04,0xb3,0xce,0x54,0xf3,0x09,0xee,0xda,0x4e,0x66,
3531
0x9d,0x27,0xb3,0xbe,0x53,0x74,0x77,0x77,0x2d,0xd0,0xb6,0x84,0x1b,0xc5,0x43,0xfa,
3532
0x35,0x3c,0xa4,0xe7,0xe3,0xd8,0x91,0xfd,0xdd,0x75,0xa5,0x72,0xd7,0x56,0x22,0xde,
3533
0x41,0x9c,0xe3,0x25,0x0a,0xab,0xe5,0x5d,0xee,0x75,0xaa,0xd6,0xcb,0xbd,0x4e,0xc6,
3534
0x6e,0xe2,0xf5,0xec,0xb7,0x5b,0xf6,0x5b,0x3a,0x1d,0xb1,0x9b,0x75,0x1e,0x3c,0xbb,
3535
0x39,0x97,0x67,0xdf,0x30,0xf4,0x88,0xfd,0xe3,0x0b,0x8e,0xd8,0x3b,0xf4,0x70,0xed,
3536
0xf7,0x93,0xcf,0xbd,0x6d,0x4f,0xfc,0xfe,0x57,0x97,0xf3,0xd7,0x34,0xeb,0x66,0x41,
3537
0x85,0x40,0xd0,0xe9,0xd2,0xca,0xfd,0x1e,0xf0,0x15,0x08,0x72,0xc1,0xae,0x81,0x49,
3538
0xad,0xdd,0xef,0x03,0xdf,0x81,0x47,0x53,0x4c,0x5f,0x10,0xcc,0xfd,0x56,0xf0,0x42,
3539
0xb8,0x1c,0x86,0x99,0x6f,0x6f,0x43,0x41,0x67,0x01,0xfb,0x7a,0xb5,0x71,0xcb,0xb9,
3540
0x05,0xee,0xfb,0xd1,0x27,0xcd,0xb7,0xb9,0xc4,0xfd,0x5c,0x1b,0xf7,0x5b,0xbb,0xcd,
3541
0x77,0x05,0x73,0xd7,0xdd,0x8d,0x20,0xed,0x9b,0x09,0x5f,0x1b,0x6d,0x7c,0x81,0x5b,
3542
0x5e,0xc3,0x4c,0x7e,0x52,0xdd,0xef,0xef,0xbc,0xef,0x10,0xcd,0x77,0x78,0x21,0xf2,
3543
0x13,0xd5,0xd6,0xfd,0x56,0xb7,0x59,0x5b,0xf7,0xdb,0xc4,0x8b,0x61,0x30,0x5c,0x07,
3544
0x37,0x58,0x54,0xcb,0x1f,0x74,0xb2,0x29,0xbb,0x55,0xd8,0x37,0x43,0xf7,0x02,0x41,
3545
0x67,0x37,0xba,0xdf,0xc4,0xc1,0x75,0x7a,0x14,0x6a,0x42,0x53,0xb8,0xc2,0xac,0xdf,
3546
0x04,0xdf,0x41,0x51,0xae,0x55,0x5b,0xe8,0x0e,0x37,0x0a,0xf3,0xdd,0xdf,0x74,0x98,
3547
0x03,0xcb,0xe0,0x94,0x0e,0xee,0xf7,0x90,0xa7,0xa2,0x6d,0xd0,0x21,0xed,0xdd,0x6f,
3548
0x39,0xbf,0xa2,0xfe,0xbc,0x8d,0xdf,0x37,0x50,0x08,0xfb,0x6d,0x68,0x12,0x9a,0x08,
3549
0xcf,0xc1,0xf6,0x92,0x41,0xe7,0x6b,0xf4,0x7b,0x88,0xea,0xe8,0xd6,0xd5,0x0a,0xe6,
3550
0xfb,0x41,0x98,0x7a,0x4a,0xd0,0xd9,0x05,0x5f,0x62,0x2f,0x4d,0x43,0xaa,0x04,0x1b,
3551
0xb1,0xf7,0x44,0xbf,0xe2,0x62,0x1d,0x86,0x7c,0xd4,0x8b,0x7a,0x62,0xe5,0xe9,0x41,
3552
0xe7,0x35,0x74,0x63,0x27,0xf7,0xfb,0xdc,0x03,0x70,0x5a,0xe9,0xa0,0xf3,0x0b,0x1a,
3553
0x75,0x09,0x79,0xe8,0xec,0xae,0x37,0x3c,0x8a,0x8b,0xdc,0x45,0xdf,0x6a,0x2e,0x81,
3554
0x3b,0x60,0xfb,0x59,0x41,0xa7,0x21,0x75,0x79,0x07,0xda,0x1f,0xed,0x03,0x23,0xe0,
3555
0x53,0xd8,0x0a,0xd5,0xa9,0x14,0x3f,0xa1,0x95,0x2f,0xa3,0x5e,0x98,0xef,0x19,0xa1,
3556
0x1b,0x7e,0x63,0xca,0x07,0x9d,0x11,0xe8,0x4c,0xdc,0x73,0xe0,0xa5,0xcb,0xdc,0x6f,
3557
0xc4,0xef,0x7e,0x22,0x98,0xbb,0x56,0x71,0x62,0x6c,0x30,0x97,0xc0,0x68,0xce,0xdd,
3558
0xd9,0x65,0x05,0xe1,0xe7,0x27,0x05,0x9d,0x8f,0xba,0x06,0x9d,0x6e,0xb8,0xfb,0xc0,
3559
0x36,0xfc,0x1e,0x44,0xd7,0xc0,0x06,0x38,0x08,0xa3,0xba,0x50,0x9f,0xa8,0x88,0x67,
3560
0xa6,0xbb,0xdf,0x94,0xbe,0x57,0x31,0xe8,0xac,0x40,0x9b,0xf2,0x03,0xfb,0xbc,0xae,
3561
0xee,0x77,0x94,0x46,0xaf,0xd1,0xb7,0x94,0xb3,0xe1,0x49,0x98,0x01,0x9f,0xe8,0xbb,
3562
0x4a,0xf3,0x6d,0xbc,0x59,0xaf,0xa4,0x34,0x5c,0x0a,0xb3,0xe0,0x3d,0x68,0x4d,0x5b,
3563
0x2d,0x58,0x35,0xe8,0xd4,0x45,0x0f,0xe3,0xbe,0x02,0x1d,0x03,0xdb,0x61,0x3f,0xfe,
3564
0x15,0xf8,0xe1,0xfe,0x06,0xf6,0x69,0x10,0x5f,0x8b,0xfc,0xe2,0xbe,0x1e,0x1e,0x81,
3565
0x61,0xd0,0xb7,0x96,0xfb,0x5d,0x6b,0xdf,0x1e,0x66,0x6e,0x4a,0xd0,0xd9,0x86,0xfe,
3566
0x40,0xbf,0xd2,0x0c,0x4e,0xaf,0xed,0x7e,0xeb,0x9a,0x0f,0xdd,0x4e,0xb8,0xbb,0xa9,
3567
0xd3,0x13,0xdb,0xb8,0x2f,0x00,0x1e,0xc6,0xff,0xf9,0x91,0x3c,0xef,0x35,0x3c,0xf2,
3568
0x6d,0x67,0x79,0xb8,0x0c,0xda,0xc2,0x6b,0xc9,0x41,0xa7,0x19,0xc7,0x1d,0xc2,0x3e,
3569
0x16,0x2e,0xb8,0xc2,0xfd,0x66,0xb6,0x5f,0x4a,0xd0,0xb9,0x13,0x2d,0x0b,0x25,0x7b,
3570
0x3b,0xb9,0xdf,0x45,0x66,0xa2,0x4f,0xc0,0x2e,0x98,0x7a,0x25,0xf6,0xb4,0xa0,0xb3,
3571
0x09,0x3d,0xad,0x0e,0x71,0xf6,0xe1,0xf7,0x41,0xcd,0xa0,0x73,0x21,0x7a,0x3e,0xee,
3572
0x41,0x66,0x5d,0x6c,0x7d,0x3f,0xfa,0x0a,0xdc,0x51,0x2b,0xe8,0x14,0xe0,0x5a,0x1f,
3573
0x42,0xcf,0xef,0xcb,0xef,0x81,0x3a,0x41,0x67,0x31,0xba,0x06,0x7a,0xc1,0x29,0xfd,
3574
0xa8,0x53,0xfd,0xdc,0x6f,0x75,0xcd,0xf7,0xa6,0xbd,0x61,0x38,0x8c,0x85,0x32,0x75,
3575
0x83,0x4e,0x0a,0x5a,0x9d,0x7e,0xad,0x3f,0x24,0xd7,0x75,0xbf,0x45,0x5d,0x01,0xef,
3576
0xd6,0x0b,0x3a,0x07,0xd9,0xd7,0x9f,0xfe,0xf2,0xb2,0xfa,0xa4,0x19,0x96,0x63,0x4f,
3577
0xcf,0x76,0xbf,0x53,0x2d,0x0d,0xf7,0x11,0xbe,0x39,0x7a,0x1d,0x0c,0x83,0xe7,0xe1,
3578
0x1c,0xfa,0x84,0x2c,0xfa,0xe4,0xee,0x99,0x41,0xe7,0x61,0x74,0x7a,0xc3,0xa0,0x53,
3579
0x79,0x90,0xfb,0x3d,0x6b,0x6b,0xc8,0xd7,0x38,0xe8,0x8c,0x44,0x27,0x1a,0xbf,0x26,
3580
0x41,0xa7,0x64,0xd3,0xa0,0x73,0xcd,0x60,0xda,0x13,0x3c,0x57,0x8f,0xdf,0x44,0xe8,
3581
0xfc,0x7a,0x2e,0x4d,0x86,0x38,0xce,0x25,0x43,0xdc,0xef,0x5f,0xc7,0x9a,0xef,0xdf,
3582
0xa1,0x74,0x7d,0xc7,0x39,0x9b,0xbe,0x37,0xed,0xbc,0xa0,0x53,0xcf,0xac,0x41,0x8d,
3583
0x9a,0x6f,0xfc,0x1f,0xa3,0xfe,0x16,0xa5,0xdf,0x9c,0xd2,0x2a,0xe8,0xcc,0x87,0x46,
3584
0xad,0x83,0xce,0x61,0xc2,0xe6,0xcb,0x70,0xbf,0x91,0x3d,0x80,0xfb,0x6b,0x38,0xbd,
3585
0x4d,0xd0,0x49,0x86,0x32,0xc3,0xb8,0x06,0xc2,0x7c,0x3f,0x6b,0xbe,0x4b,0xbd,0x0d,
3586
0x6d,0x8c,0xde,0x97,0x61,0xbe,0x05,0xa7,0x3c,0x87,0xbb,0x6b,0x1b,0x98,0xef,0x6a,
3587
0xb7,0xe1,0x57,0xb1,0x7d,0x30,0xf7,0x3b,0xe6,0x07,0xd1,0x37,0xc0,0x7c,0x8b,0xbd,
3588
0x1b,0xaa,0x37,0x70,0xbf,0x67,0x6e,0x0e,0xad,0x60,0x44,0xc7,0xa0,0xf3,0xcc,0xc5,
3589
0x2e,0x5f,0xe1,0x0e,0x72,0x73,0x9e,0xde,0x89,0xf2,0xbb,0x96,0x3e,0x0f,0x2a,0xe1,
3590
0x1e,0x79,0x49,0xd0,0x59,0x37,0x82,0xdf,0x85,0xd8,0x77,0xa2,0xdb,0x34,0x49,0xe0,
3591
0xa6,0xce,0x41,0xa7,0x3b,0x1a,0xa0,0x5e,0xad,0x40,0x83,0xd7,0x73,0x3f,0x87,0x14,
3592
0xdc,0x95,0xbb,0x05,0x9d,0x26,0xd0,0x11,0xfb,0x87,0xe8,0x35,0x37,0x70,0x6d,0xbb,
3593
0x07,0x9d,0x89,0xe8,0x21,0x7d,0xe3,0xfb,0xd1,0xe5,0x41,0x27,0xb6,0x07,0x7d,0x3c,
3594
0xf6,0xa9,0x68,0x36,0xda,0x99,0xba,0xf8,0x3e,0xc7,0xcc,0xc6,0x1e,0x31,0xca,0x71,
3595
0x0a,0x70,0xf3,0xad,0x87,0xce,0xa5,0xff,0x79,0xa6,0x57,0xd0,0x99,0x0b,0xf7,0x10,
3596
0xe6,0xe1,0x64,0xb7,0x7d,0x47,0xc2,0xa3,0xe3,0x69,0xcf,0x84,0xbb,0x0b,0xfb,0x6d,
3597
0xf0,0x08,0xcc,0xa1,0x1f,0x9c,0x65,0x14,0x16,0xc2,0x0e,0xa8,0xd3,0x27,0x98,0xbb,
3598
0x36,0xc2,0x59,0x63,0xb8,0xe6,0xf0,0x3c,0xc4,0xc2,0x42,0xf8,0x7c,0x8c,0xfb,0xed,
3599
0x76,0x5b,0x74,0x15,0xbc,0x05,0x39,0x90,0xd6,0x37,0xe8,0xf4,0xe9,0x47,0x9a,0xd0,
3600
0xaa,0x3c,0xac,0xec,0x27,0xcc,0x01,0x38,0x65,0x2c,0xe1,0x06,0x07,0x9d,0xcb,0xd1,
3601
0x6a,0x03,0x82,0xce,0xa5,0xec,0xeb,0x0a,0xb3,0xb0,0xaf,0xcb,0xe6,0x18,0xec,0xad,
3602
0xb5,0x06,0x45,0x2f,0xe8,0x0d,0xd3,0x60,0x1c,0x14,0xbe,0x99,0xfe,0xed,0x26,0xf7,
3603
0xdb,0xe6,0xca,0xd0,0x07,0x6e,0x82,0x0d,0x1c,0xf3,0x29,0x1a,0x18,0x47,0x5f,0x84,
3604
0xbd,0x8b,0xd6,0x04,0xef,0x35,0x34,0xe8,0x6c,0x40,0x3f,0x81,0x54,0x1e,0x96,0x0e,
3605
0xa1,0xaf,0x70,0xaf,0x7a,0x61,0x78,0xd0,0xe9,0x79,0x75,0xd0,0x59,0x84,0xdf,0x0a,
3606
0x98,0xac,0x6f,0xa1,0xcd,0x77,0xd0,0x66,0xbd,0xf0,0xa9,0x23,0x82,0xce,0x74,0x74,
3607
0x29,0x94,0xe6,0x19,0x61,0x18,0x54,0xbf,0x21,0xe8,0x44,0xe6,0x0b,0x3a,0xab,0xb1,
3608
0xbf,0x0a,0xfb,0xe0,0x13,0xdc,0xef,0xdd,0xe9,0x7e,0x37,0xbd,0x6e,0x6c,0xd0,0xd9,
3609
0x03,0xf7,0xf2,0x9c,0xb1,0x1f,0x8a,0xf1,0xbc,0x10,0x7f,0x73,0xd0,0x29,0x8d,0xd6,
3610
0xbc,0x9b,0x34,0xc2,0x46,0xf3,0x4d,0x35,0x1c,0xbc,0x87,0xfb,0xe3,0xbd,0xa4,0xe7,
3611
0xb6,0xa0,0x73,0xdb,0x44,0xda,0x09,0x0f,0x6f,0xf3,0x26,0x9a,0xf3,0x04,0x9d,0x1d,
3612
0xd8,0x5f,0xbb,0x8f,0xeb,0x48,0xff,0x1d,0x7b,0x3f,0xf5,0x82,0xfb,0xec,0x19,0x77,
3613
0xd3,0xcf,0xf3,0x20,0x35,0x14,0xb6,0xe0,0x97,0xff,0xde,0xa0,0x33,0x1b,0xfb,0x7d,
3614
0xa8,0xf9,0x1e,0xdb,0x70,0x2e,0xbc,0x34,0x31,0xe8,0x6c,0x45,0x93,0x79,0x08,0x3c,
3615
0x77,0x12,0xd7,0x1d,0x96,0xc1,0xcf,0xf0,0x36,0x7e,0x09,0x0f,0x05,0x73,0xbf,0xdb,
3616
0xce,0x78,0x98,0xfb,0x03,0xbc,0xcd,0x83,0xe2,0x1e,0xe8,0xf5,0x08,0xf6,0xc9,0x41,
3617
0xe7,0x07,0xec,0xa1,0x29,0x41,0xa7,0xf0,0xe3,0x41,0xe7,0x2e,0x30,0x6b,0x8f,0xb7,
3618
0x6f,0xe9,0xae,0x39,0xfe,0x33,0x84,0x1e,0x73,0x9c,0x22,0x70,0x8a,0xd6,0x1c,0xcf,
3619
0x9d,0x30,0x40,0xb1,0x07,0x23,0x22,0x43,0x51,0xd1,0xf9,0x62,0xf2,0x17,0x28,0x58,
3620
0xa8,0x30,0x41,0x72,0x97,0xda,0x2d,0x5e,0xa2,0x64,0xa9,0x53,0xe8,0x37,0x9d,0x23,
3621
0xdb,0x69,0xa7,0x73,0xcf,0x74,0xfe,0x17,0x5b,0x69,0xe7,0xcc,0xb3,0xca,0x94,0xfd,
3622
0x83,0x23,0x75,0xff,0xaa,0x55,0x85,0xd8,0xb3,0x5d,0xe7,0x39,0x74,0x1e,0x95,0x2a,
3623
0x9f,0x5b,0xa5,0x6a,0xb5,0xb8,0xf8,0xea,0x09,0x89,0x49,0xc9,0x4e,0x4a,0x6a,0xee,
3624
0x63,0xda,0x1f,0xb4,0xd5,0xf0,0x1e,0xf5,0xfe,0xb0,0xad,0xd6,0xb1,0x3c,0x6b,0xd7,
3625
0x39,0xca,0x59,0xb7,0x66,0x3d,0x77,0x3e,0x57,0x03,0x27,0xbc,0x85,0xb7,0xf0,0x16,
3626
0xde,0xc2,0x5b,0x78,0x0b,0x6f,0xe1,0x2d,0xbc,0x85,0xb7,0xf0,0x16,0xde,0xc2,0x5b,
3627
0x78,0x0b,0x6f,0xff,0xd2,0x6d,0xc7,0xb1,0xb6,0x9d,0x39,0x6c,0x3b,0x37,0x9a,0xff,
3628
0x73,0x56,0xad,0x3a,0xf2,0xbf,0xb6,0x80,0xd9,0x8c,0xc5,0x0b,0xbf,0x6f,0x87,0xeb,
3629
0xc8,0xc9,0x71,0x72,0xff,0xc7,0x41,0x14,0x3b,0xbe,0xd8,0xb5,0xcb,0xfc,0x3b,0x2a,
3630
0xea,0x70,0x89,0x1f,0xfb,0x12,0x84,0x8b,0x41,0x5b,0x6e,0xa5,0x32,0xff,0x7d,0xa2,
3631
0xea,0xe5,0xd6,0xb9,0x5c,0xbf,0x4f,0xb6,0xef,0xc8,0x7d,0x47,0x59,0xc4,0xbc,0x9e,
3632
0xcc,0x7d,0x3f,0x79,0xaa,0x79,0x29,0xb9,0x23,0xc7,0x29,0xfe,0x47,0xb7,0x87,0x32,
3633
0x65,0xcb,0x9d,0xec,0xa1,0xa5,0xcd,0x3b,0xca,0x72,0xe5,0x2b,0x98,0x24,0xef,0x50,
3634
0x2e,0x72,0xfc,0x81,0x62,0xff,0xcc,0x56,0xed,0x5a,0x72,0x72,0xd5,0x39,0x56,0x6a,
3635
0x8e,0xb1,0x9d,0x7d,0x9c,0x98,0xdd,0x2b,0x61,0xae,0x88,0xf9,0x97,0x1b,0xbd,0x6b,
3636
0x76,0xfc,0x4d,0xba,0xba,0x9c,0x23,0x09,0xcd,0xf9,0x4f,0x41,0x8f,0x74,0x8d,0xce,
3637
0xaf,0xae,0x93,0xa9,0xc7,0x39,0x39,0xbf,0x2b,0xb1,0xea,0x5e,0x4f,0x32,0x7b,0x39,
3638
0x76,0xb7,0xac,0xd4,0xeb,0x8a,0xb9,0x7b,0xa9,0xa4,0xaa,0x99,0x39,0xbf,0xbb,0xdf,
3639
0x89,0xf6,0x7b,0xc4,0xa8,0x82,0xfc,0x49,0x17,0xf4,0x98,0xe7,0x3f,0xb9,0x52,0xfe,
3640
0x1f,0x9f,0xdf,0x09,0x9f,0xff,0x8f,0xdc,0xfe,0x2a,0xf9,0xbf,0xb0,0xd3,0xbf,0xa1,
3641
0xfc,0x63,0x62,0xfe,0x52,0xd7,0xff,0xcf,0x3d,0x79,0xaf,0x5e,0x47,0x9f,0xaf,0x0f,
3642
0xdb,0x9f,0x79,0xfe,0xa1,0x43,0x8f,0x3e,0xff,0x35,0xd7,0x98,0x19,0x70,0x7f,0xe0,
3643
0x63,0xd8,0x7f,0xba,0x7b,0xe5,0x60,0x36,0xfe,0xc6,0x88,0x47,0x8d,0x76,0x6e,0xcc,
3644
0xb5,0x8c,0x66,0xe3,0x7f,0xee,0x5b,0x31,0xce,0xef,0xbd,0x65,0xe4,0xfc,0xd9,0x95,
3645
0x2d,0xfa,0x18,0xb5,0xff,0x0f,0x28,0xf4,0x7f,0xde,0x2f,0x9b,0xbf,0x63,0xb2,0x8f,
3646
0x77,0x69,0x63,0xfe,0xda,0xa9,0xff,0xa3,0x1e,0x6f,0xfe,0x5a,0xdb,0xf6,0xbf,0x58,
3647
0x7a,0x3e,0xd9,0xf1,0x4f,0x6b,0xad,0x47,0xff,0xfc,0xf8,0x6f,0xde,0x95,0x8f,0xbc,
3648
0x0c,0x3a,0xe9,0xd3,0x1c,0xfd,0x4a,0xc0,0xc9,0xc9,0xb1,0x7f,0x6d,0xff,0x49,0xdd,
3649
0x4d,0xf4,0x6f,0xeb,0x0f,0x76,0xe4,0xfc,0xae,0x77,0x60,0xbf,0xe7,0x86,0x13,0xfd,
3650
0x07,0xc5,0x93,0xf7,0xa3,0xe7,0x5f,0xe9,0x96,0x13,0xf0,0xaa,0x87,0xf9,0xdf,0x09,
3651
0xb8,0x9b,0x75,0x7f,0xdd,0x91,0x1b,0xee,0x9f,0x72,0x8b,0xcd,0xf9,0xf5,0xbd,0xc6,
3652
0x8e,0x5d,0x1f,0xe4,0xac,0xda,0x71,0x22,0xdb,0xce,0xed,0xdb,0x73,0x3e,0xda,0xf1,
3653
0x45,0xce,0x3f,0xaf,0x0f,0xdb,0xb1,0x23,0x10,0x30,0x39,0x0c,0x18,0xf1,0x2e,0x36,
3654
0xf6,0x9c,0x1d,0x7a,0x65,0xed,0xfc,0xab,0xb7,0xbf,0xda,0x13,0x59,0xcc,0x9f,0x90,
3655
0xe1,0xff,0xb8,0x9d,0x78,0x4c,0x1f,0x6d,0xdf,0xf9,0xc9,0x96,0x2d,0x7f,0x5a,0xc9,
3656
0xe4,0xcb,0xf7,0x8f,0xac,0x7f,0x47,0x5f,0x93,0xe3,0x5f,0xbd,0x3f,0xbe,0x3e,0xfc,
3657
0xf6,0x6a,0xf8,0x57,0x7d,0xee,0x8f,0x39,0xa9,0xfa,0xff,0x3b,0x5e,0x09,0xe4,0xfc,
3658
0x25,0x8a,0x29,0xfa,0xef,0xf3,0x5b,0xec,0xbf,0xd1,0x80,0x72,0x87,0x71,0x74,0x19,
3659
0xcd,0xb8,0xc4,0x5f,0xb2,0xdb,0xfd,0xfb,0x35,0x94,0x63,0x6e,0x67,0x38,0xff,0xf6,
3660
0x6d,0x87,0x3d,0x08,0x9b,0x13,0x1e,0xa7,0xfe,0x47,0x6d,0x39,0xe1,0x2c,0xfe,0x0f,
3661
0x5b,0xd5,0x5f,0xb1,0xb0,0x4e,0x38,0x51,0x3b,0x02,0x39,0x7f,0x9f,0x1b,0xc9,0xef,
3662
0xfc,0x99,0x1b,0x9e,0x9f,0xf3,0x17,0x69,0x34,0x7f,0x78,0x7d,0xcf,0xc9,0xf9,0xa3,
3663
0x22,0x72,0x27,0xc2,0xfc,0x96,0x08,0x77,0xfc,0x03,0xde,0xc2,0xc4,0xfc,0xd6,0x90,
3664
0xbf,0xbd,0xff,0x88,0x89,0xfe,0x83,0x2a,0xd5,0x49,0xd7,0xaa,0xdf,0xfb,0x02,0x35,
3665
0xfa,0xbf,0x53,0xf2,0x7f,0xe2,0x2b,0xd9,0x98,0xe8,0xbf,0x5f,0x15,0x8d,0xfe,0xc3,
3666
0x6f,0x55,0xd1,0x27,0x3e,0xff,0xe2,0xc8,0x4f,0xef,0x7f,0xde,0x64,0xcf,0x98,0xff,
3667
0x50,0xf7,0x76,0x84,0x2b,0xe3,0x3f,0x3b,0xf3,0x31,0xff,0xa2,0x6c,0xc7,0x38,0xe1,
3668
0x2d,0xdc,0xec,0xfe,0xff,0x93,0xc0,0x5f,0xba,0x20,0x62,0xfe,0x9c,0x38,0x63,0xfe,
3669
0xa5,0xad,0x2d,0xdc,0x27,0xfc,0x77,0xa6,0xc2,0xc5,0xfc,0xcd,0xfa,0x80,0xf0,0xf6,
3670
0x37,0xd9,0x7e,0x9d,0x0b,0xf2,0xdb,0x7f,0x2f,0x86,0x5f,0x07,0xfd,0x8d,0xb7,0xa8,
3671
0xa8,0xbf,0x55,0x6d,0xfd,0x67,0x14,0xfa,0xc6,0x8d,0x6e,0xa3,0xdb,0xba,0xd1,0x6c,
3672
0x9e,0xaf,0xf7,0x39,0xe9,0xaf,0x93,0xfa,0x8e,0xdf,0xf2,0xfe,0x8a,0x99,0xfb,0x7b,
3673
0xf7,0x06,0xd6,0x27,0x6e,0xfe,0x69,0x02,0x47,0x76,0xfd,0x79,0x6f,0x2d,0xc2,0x1d,
3674
0xeb,0x7f,0xb1,0x78,0xfe,0xed,0x37,0xae,0x9d,0x3b,0xff,0xf9,0xd3,0xff,0x7e,0xed,
3675
0x53,0xff,0xf4,0x3e,0x24,0xfc,0x3e,0xe0,0xef,0xf9,0x40,0x9c,0xbb,0xfa,0x67,0x28,
3676
0x14,0x1d,0xca,0x17,0x93,0x3f,0x14,0x2a,0x10,0xfa,0x75,0x2b,0x18,0x0a,0x15,0x2a,
3677
0x1c,0x2a,0x52,0x34,0x64,0x6f,0xc5,0x42,0xff,0xec,0xad,0x78,0x89,0x50,0xc9,0x52,
3678
0xa7,0x60,0x39,0x35,0x14,0xde,0xc2,0x5b,0x78,0x0b,0x6f,0xe1,0x2d,0xbc,0x85,0xb7,
3679
0xf0,0x16,0xde,0xc2,0x5b,0x78,0x0b,0x6f,0xe1,0x2d,0xbc,0x85,0xb7,0x7f,0xc8,0x16,
3680
0x70,0xfe,0x57,0x26,0xc2,0x09,0x39,0xd1,0xb9,0xa6,0x92,0x13,0xe7,0xd4,0x70,0x1a,
3681
0x3a,0x3d,0x9c,0x5e,0xce,0x55,0xce,0x18,0x67,0x8a,0xf3,0x84,0xf3,0xbc,0xb3,0xc0,
3682
0x59,0xec,0xbc,0xeb,0xec,0x77,0xbe,0xc5,0x84,0x02,0x25,0x02,0xe5,0x03,0x4d,0x02,
3683
0x2d,0x02,0x1d,0x02,0x9d,0x02,0xfd,0x02,0x57,0x1f,0x65,0x26,0x05,0x1e,0x0b,0x4c,
3684
0x0b,0xcc,0x0d,0x6c,0x08,0x7c,0x18,0xf8,0x3c,0xf0,0x7d,0xa0,0x44,0xf0,0xd4,0x60,
3685
0xf9,0x60,0x5c,0x30,0x39,0x98,0x15,0xec,0x11,0xec,0x8d,0xb9,0x3a,0x78,0x73,0xf0,
3686
0xfe,0xe0,0xc2,0xe0,0xd2,0xe0,0x3b,0xc1,0xf5,0xc1,0xcf,0x83,0x07,0xfe,0x8b,0xe6,
3687
0xe0,0x6f,0x30,0x81,0x88,0x40,0x44,0x44,0x44,0x28,0x22,0x26,0xa2,0x40,0xae,0x29,
3688
0xf1,0xab,0x29,0xf5,0xab,0x39,0x2b,0x22,0x36,0xe2,0x1c,0x4c,0x25,0x99,0xea,0x96,
3689
0xa9,0x81,0x49,0x8f,0xa8,0x1d,0x51,0x3f,0xa2,0x41,0xae,0x69,0xf6,0xab,0x69,0xf1,
3690
0xab,0x69,0x1b,0xd1,0x31,0xa2,0x13,0xe6,0x52,0x99,0x1e,0x47,0x99,0x7e,0x11,0x57,
3691
0xfd,0x47,0x73,0x75,0xc4,0x75,0x7f,0xba,0x19,0x15,0x31,0x36,0x4f,0x73,0x73,0xc4,
3692
0x2d,0xbf,0x9a,0xdb,0x22,0xee,0x38,0xca,0x8c,0x8f,0xb8,0x2b,0xe2,0x9e,0x88,0x89,
3693
0x27,0x68,0xee,0xff,0xdd,0x66,0x4a,0xc4,0xf4,0xff,0x60,0xe6,0x46,0x2c,0x3e,0xca,
3694
0x2c,0xfd,0x53,0xcc,0x6b,0x11,0x6f,0xfc,0x8f,0xcc,0x8a,0x88,0x37,0x23,0x56,0x47,
3695
0xac,0xf9,0xd5,0xbc,0x13,0xf1,0xee,0x3f,0xc2,0xac,0x0f,0x9b,0x7f,0xb5,0xf9,0x54,
3696
0xe6,0x0b,0xcc,0x01,0x4c,0x20,0xf2,0x88,0x89,0xc1,0x14,0x90,0x39,0x55,0xa6,0x7c,
3697
0xae,0x89,0xc5,0x9c,0x93,0x6b,0x52,0x65,0xea,0x62,0x9a,0x61,0x3a,0x5a,0xa6,0x2b,
3698
0xa6,0x87,0xcc,0x55,0x32,0xa3,0x22,0x6f,0x8e,0xbc,0x23,0xd7,0x8c,0x97,0xb9,0xe7,
3699
0x4f,0x33,0x13,0x8f,0x61,0x26,0xe5,0x9a,0x87,0x30,0x53,0x22,0x9f,0x8a,0x7c,0x26,
3700
0x72,0x06,0x66,0x96,0xcc,0x9c,0x5f,0xcd,0x2b,0x32,0x0b,0x65,0x16,0x63,0x96,0xe6,
3701
0x9a,0x37,0x72,0xcd,0x0a,0xcc,0x9a,0xc8,0x77,0x23,0xd7,0x47,0x6e,0xc2,0x7c,0x2c,
3702
0xb3,0xf9,0x57,0xf3,0xb9,0xcc,0x17,0x32,0xbb,0x31,0x7b,0xfe,0x9f,0xd9,0xfb,0x3b,
3703
0xcc,0xfe,0xc8,0x03,0xff,0x08,0xf3,0x6d,0xe4,0xf7,0xff,0xd1,0x1c,0x8c,0xfc,0xf1,
3704
0xa4,0x4c,0x78,0x28,0xf0,0xdf,0xbe,0xfd,0x18,0xf9,0xc7,0x9a,0x40,0xe8,0xf7,0x1a,
3705
0x1e,0x89,0xff,0x65,0xbf,0xc7,0xa2,0x8f,0x6b,0x62,0x72,0x4d,0x81,0xbf,0x89,0x29,
3706
0xe4,0x33,0x45,0x72,0x4d,0xb1,0xb0,0x39,0x21,0x53,0xea,0x5f,0x6f,0x4a,0xff,0x25,
3707
0xcd,0x59,0x7f,0x92,0x29,0x1f,0x8a,0xfd,0x97,0x9b,0x73,0xfe,0x75,0xa6,0xd2,0x51,
3708
0x26,0x4e,0xa6,0xfa,0xbf,0xd6,0x24,0x87,0x52,0xc3,0xe6,0xb8,0xa6,0x76,0xae,0xa9,
3709
0xfb,0x17,0x34,0xf5,0xc3,0xe6,0x6f,0x6e,0x1a,0x60,0x1a,0x62,0xb2,0x30,0x4d,0x30,
3710
0xcd,0x64,0x5a,0xfc,0xe1,0xa6,0x25,0xa6,0x15,0xa6,0x4d,0xa8,0x6d,0xae,0x69,0x17,
3711
0x36,0xff,0x12,0xd3,0x21,0xd4,0xf1,0x0f,0x31,0x9d,0x42,0x97,0x1e,0x65,0x3a,0x87,
3712
0xba,0xfe,0xcf,0x4c,0x8f,0x50,0xef,0x93,0x32,0x7d,0x42,0xfd,0x4e,0xc8,0x0c,0x08,
3713
0x0d,0xfc,0x93,0xcc,0xd5,0xa1,0x51,0xa1,0x31,0xa1,0xb1,0xa1,0x9b,0x43,0xb7,0x84,
3714
0x6e,0x0b,0xdd,0x11,0x9a,0x18,0x7a,0x24,0xf4,0x58,0x68,0x4a,0xe8,0x89,0xd0,0x53,
3715
0xa1,0x67,0x42,0xd3,0x42,0xcf,0x87,0x66,0x1d,0x65,0xe6,0x86,0x16,0x1c,0x65,0x96,
3716
0x86,0xde,0x0c,0xad,0x0e,0xad,0x09,0xbd,0x13,0x7a,0x37,0xb4,0x3e,0xf4,0x7e,0xe8,
3717
0xe3,0xd0,0x67,0xa1,0xcf,0x43,0x5f,0x84,0x76,0x87,0xf6,0x84,0xf6,0x86,0xf6,0x87,
3718
0xbe,0x0f,0xfd,0x74,0x94,0x89,0x88,0x8a,0x39,0xca,0x14,0x8a,0x2a,0x76,0x94,0x29,
3719
0x15,0x75,0xfa,0x51,0xa6,0x6c,0xd4,0x39,0x3e,0x53,0xf5,0x28,0x93,0x1c,0x55,0x3b,
3720
0xaa,0x6e,0x54,0xfd,0xa8,0x06,0x51,0x0d,0xa3,0xb2,0xa2,0x9a,0x44,0xb5,0x8a,0xea,
3721
0x10,0xd5,0x31,0xaa,0x53,0xd4,0xa5,0x51,0x9d,0xa3,0xba,0x46,0x75,0x8f,0xea,0x21,
3722
0xd3,0xcb,0x67,0x7a,0xff,0x0f,0x4c,0x9f,0xff,0x67,0x06,0x1e,0x65,0x06,0xff,0x97,
3723
0xcd,0x55,0x3e,0x73,0x6d,0xd8,0x9c,0x80,0xb9,0x0e,0x73,0x03,0x66,0xd4,0xff,0xc8,
3724
0x8c,0xc1,0x8c,0xc5,0xdc,0xfc,0x5f,0x36,0xb7,0xfc,0x6a,0x6e,0xcb,0x35,0x77,0x9c,
3725
0xa4,0x19,0x8f,0xb9,0xeb,0xa4,0xcc,0x3d,0x47,0x99,0x89,0x98,0xfb,0x73,0xcd,0xa4,
3726
0x5f,0xcd,0x43,0x27,0x68,0x1e,0xc9,0x35,0x8f,0x45,0x4d,0xc9,0xd3,0x3c,0x11,0xf5,
3727
0x54,0xae,0x79,0x26,0x6a,0x5a,0xae,0x99,0x1e,0xf5,0x7c,0xd4,0x8c,0xa8,0x59,0xbf,
3728
0x9a,0x39,0x51,0x73,0x73,0xcd,0xbc,0xa8,0x05,0xc7,0x30,0xaf,0x44,0x2d,0x3c,0x8e,
3729
0x59,0x6c,0x99,0xa5,0x51,0xaf,0x61,0xde,0x38,0xca,0xac,0x88,0x7a,0x33,0x6a,0x75,
3730
0xd4,0x9a,0xb0,0x39,0xae,0x79,0xe7,0x57,0xf3,0x2e,0x66,0x3d,0xe6,0x7d,0xcc,0x06,
3731
0xcc,0x87,0x98,0x4d,0x98,0x8f,0x31,0x9b,0x31,0x9f,0x62,0xb6,0x61,0x3e,0xc3,0x7c,
3732
0x9e,0x6b,0xbe,0xc0,0xec,0xc6,0xec,0x39,0xca,0xec,0xcf,0x35,0xdf,0xe6,0x9a,0x83,
3733
0xb9,0xe6,0xa7,0x5c,0x13,0x88,0xfe,0xfd,0x26,0xe2,0xff,0x99,0x23,0x2f,0x72,0xcd,
3734
0x16,0x83,0x29,0x80,0x29,0x84,0x29,0x82,0x29,0x86,0x29,0x81,0x29,0x85,0x39,0x15,
3735
0x73,0x3a,0xa6,0x34,0xe6,0xac,0x5c,0x53,0x16,0x53,0x1e,0x13,0x7b,0x94,0xa9,0x94,
3736
0x6b,0xaa,0xe6,0x9a,0xea,0xb9,0x26,0x39,0xd7,0xd4,0x38,0x41,0x93,0x1e,0x5d,0x3b,
3737
0xba,0x6e,0x74,0xfd,0x63,0x9a,0x06,0x61,0xf3,0x1b,0x4d,0x43,0x4c,0xd6,0x31,0x4c,
3738
0x93,0xb0,0xc9,0xc3,0x34,0x8b,0x6e,0x11,0x36,0x61,0x73,0x82,0xa6,0x55,0xd8,0x84,
3739
0xcd,0x3f,0xde,0xb4,0x0b,0x9b,0x7f,0xb5,0xe9,0x10,0xdd,0xf1,0x5f,0x6b,0x3a,0x85,
3740
0xcd,0x5f,0xd0,0x84,0x67,0x49,0x85,0xb7,0xf0,0x16,0xde,0xc2,0x5b,0x78,0x0b,0x6f,
3741
0xe1,0x2d,0xbc,0x85,0xb7,0xf0,0x16,0xde,0xc2,0x5b,0x78,0x0b,0x6f,0xe1,0x2d,0xbc,
3742
0x85,0xb7,0xf0,0x16,0xde,0xc2,0x5b,0x78,0x0b,0x6f,0xe1,0x2d,0xbc,0x85,0xb7,0xf0,
3743
0x16,0xde,0xc2,0x5b,0x78,0x0b,0x6f,0xe1,0x2d,0xbc,0x85,0xb7,0xf0,0x16,0xde,0xc2,
3744
0x5b,0x78,0x0b,0x6f,0xe1,0x2d,0xbc,0x85,0xb7,0xf0,0x16,0xde,0xc2,0x5b,0x78,0x0b,
3745
0x6f,0xe1,0x2d,0xbc,0x85,0xb7,0xf0,0x16,0xde,0xc2,0x5b,0x78,0x0b,0x6f,0xe1,0x2d,
3746
0xbc,0x85,0xb7,0xf0,0x16,0xde,0xc2,0x5b,0x78,0x0b,0x6f,0xe1,0x2d,0xbc,0x85,0xb7,
3747
0xf0,0x16,0xde,0xc2,0x5b,0x78,0x0b,0x6f,0xe1,0x2d,0xbc,0x85,0xb7,0xf0,0x16,0xde,
3748
0xc2,0x5b,0x78,0x0b,0x6f,0xe1,0x2d,0xbc,0x85,0xb7,0xf0,0x16,0xde,0xc2,0xdb,0xdf,
3749
0x6f,0xab,0x19,0xe1,0x38,0xfd,0x2b,0xb8,0xda,0x45,0x3a,0x00,0x75,0xd0,0x25,0x48,
3750
0x00,0x5d,0x8a,0x06,0xd1,0x65,0xc6,0x1b,0x7d,0x0d,0x8d,0x8c,0x30,0x3b,0x1d,0x27,
3751
0x0a,0x0d,0xa2,0xd1,0x68,0xc5,0xa0,0xe3,0xe4,0x43,0x5f,0x67,0x57,0x0c,0xfa,0x78,
3752
0x19,0xc7,0xc9,0x8f,0xbe,0x81,0xbb,0x20,0xba,0x86,0x70,0x45,0xcc,0x71,0x84,0x2b,
3753
0x66,0x8e,0x43,0x63,0xd1,0xc9,0x84,0x3b,0xc7,0xf8,0xa3,0x95,0xd1,0x48,0xc5,0x17,
3754
0x2c,0xe3,0xee,0x8f,0x44,0x13,0xd1,0xa8,0x32,0x6e,0x7a,0xa2,0x02,0x6e,0x7a,0xf2,
3755
0x29,0x5c,0xfe,0x80,0x1b,0x7f,0x41,0xb4,0x12,0xba,0xc2,0x91,0x7f,0x19,0xd7,0xbf,
3756
0x70,0xc0,0x8d,0xa7,0x60,0x19,0x77,0x7f,0x51,0x34,0x0e,0x2d,0xae,0x78,0x0b,0x97,
3757
0x71,0xf3,0xbb,0x52,0xf9,0x7d,0x53,0xf9,0x5d,0xa5,0xfc,0xbe,0x5a,0xc6,0xcd,0x6f,
3758
0x71,0xe5,0xb7,0xa4,0xce,0x7b,0x4a,0xc0,0xcd,0xef,0x6a,0xe5,0xf7,0x65,0x9d,0xef,
3759
0x0c,0xe5,0x33,0x52,0xf9,0x8c,0x52,0x3e,0xe7,0xeb,0xfc,0x95,0x83,0x6e,0x3e,0x4f,
3760
0x0b,0xb8,0xe9,0x38,0x0d,0xff,0x04,0x73,0x5c,0x19,0x37,0xde,0x32,0xca,0xe7,0x37,
3761
0xca,0xe7,0x99,0x01,0xf7,0xfc,0xe5,0xca,0xb8,0xe7,0x2f,0xa3,0xf3,0x97,0x53,0xbe,
3762
0x77,0x28,0xdf,0x15,0x14,0xfe,0x6c,0xed,0xaf,0x50,0xc6,0x4d,0x5f,0x45,0xa5,0xab,
3763
0x8c,0xd2,0x71,0xb6,0x97,0x0e,0x34,0x1e,0xad,0xa2,0xfc,0xbf,0xa5,0xfc,0xaf,0x51,
3764
0xfe,0xdf,0x56,0xfe,0x2b,0xeb,0xfc,0x55,0x94,0xff,0x6a,0x8a,0x3f,0x41,0xf9,0x7f,
3765
0x47,0xf9,0x5f,0xa9,0xf3,0xbc,0xa3,0xfc,0xe7,0x53,0xfe,0xf3,0xeb,0xbc,0xab,0x74,
3766
0x7d,0xe3,0x03,0x6e,0x7e,0xab,0x95,0x71,0xcf,0x93,0x12,0x70,0xcf,0x9b,0xa0,0xe3,
3767
0x77,0xea,0x7a,0x25,0x29,0x9d,0x69,0x01,0xf7,0x3a,0xa5,0xa8,0x5c,0xd2,0x95,0xef,
3768
0xba,0x0a,0x97,0xa6,0x70,0xb5,0x55,0x9e,0x75,0x74,0x5d,0x6b,0x29,0x7c,0x3d,0x95,
3769
0x6b,0x86,0xea,0x53,0xa6,0xf2,0xfb,0x83,0xce,0xdb,0x30,0xe0,0xe6,0xf3,0x5d,0xd5,
3770
0x9b,0x46,0x4a,0x47,0x13,0xc5,0xdf,0x58,0xf1,0x67,0x29,0xfe,0xe6,0x8a,0xbf,0xa9,
3771
0xe2,0x59,0xa7,0x72,0x5b,0xaf,0x72,0x7b,0x4f,0xe5,0xf6,0xbe,0xda,0xc9,0x79,0x2a,
3772
0xb7,0xf3,0x55,0x6e,0xf1,0x6a,0x27,0x1f,0xa8,0xdc,0xde,0x26,0x9e,0x02,0x68,0x6b,
3773
0xe5,0xeb,0x5d,0x95,0x5f,0x41,0x95,0x5f,0x61,0xb4,0xb4,0x69,0x27,0x4a,0xcf,0x5b,
3774
0x2a,0xc7,0x5d,0x4a,0xff,0x85,0xca,0x5f,0x7b,0xe5,0xf7,0x42,0x9d,0xe7,0x22,0xe5,
3775
0xe3,0x22,0xc5,0x57,0x54,0xf1,0x15,0xd7,0xf5,0xb8,0x58,0xf9,0x6a,0xaf,0xf2,0xbd,
3776
0x4c,0xc7,0x5f,0xac,0x7a,0x74,0x89,0xe2,0xe9,0xa2,0x78,0xba,0xe8,0xfc,0xdd,0x70,
3777
0x57,0x34,0xf5,0x36,0xe8,0x1e,0x7f,0x99,0xc2,0x5d,0xa9,0x70,0x97,0x2b,0x5c,0x5f,
3778
0x85,0x3b,0x43,0xe1,0xba,0xa9,0xfc,0xb2,0x55,0x7e,0xfd,0x55,0x7e,0x1f,0xaa,0xfc,
3779
0x3e,0x52,0xf9,0x6d,0x52,0xf9,0x5d,0xa1,0x7a,0x77,0xa5,0xca,0xaf,0xaf,0xea,0x5b,
3780
0x8e,0xca,0x6d,0x87,0xfa,0x97,0xfe,0x01,0xb7,0xfc,0xb2,0x55,0x7e,0xeb,0x95,0xdf,
3781
0x92,0xca,0xef,0x29,0x2a,0xbf,0x19,0x4a,0xd7,0x76,0x8e,0x3b,0x1b,0x1d,0xa4,0x72,
3782
0x1c,0xa4,0x74,0x0d,0x55,0x3b,0x1c,0x52,0xc6,0x3d,0xff,0x08,0xd5,0x97,0xeb,0x95,
3783
0xce,0x91,0x2a,0x9f,0xd1,0xaa,0xb7,0x43,0x94,0xef,0x9b,0xd4,0xce,0x6e,0x54,0xf8,
3784
0x71,0xba,0x1e,0xb7,0xca,0xff,0x76,0x1d,0xff,0xb5,0x8e,0xff,0x58,0xf9,0x1c,0xaa,
3785
0x7a,0xf7,0x83,0xfa,0x97,0xa4,0xa0,0x7b,0xdc,0x9d,0x3a,0x6e,0x78,0xc0,0xcd,0xe7,
3786
0x77,0x8a,0xf7,0x1b,0x1d,0x7f,0xb5,0xae,0xcf,0x04,0x9d,0xe7,0x5a,0xe5,0xfb,0x3a,
3787
0xe5,0xef,0x6e,0x95,0xef,0xbd,0x3a,0xef,0x16,0x95,0xef,0xa7,0x3a,0xef,0x56,0x95,
3788
0xef,0x36,0xd5,0xcf,0x80,0xca,0x37,0x42,0xf9,0xa9,0xa4,0xfa,0xb9,0x5d,0xe5,0xfc,
3789
0x84,0xca,0xf9,0x33,0xf5,0xe3,0x6f,0xab,0x7c,0x03,0x2a,0xdf,0x08,0xd5,0xa7,0x29,
3790
0xea,0xc7,0x03,0x2a,0xd7,0x90,0xe2,0x8b,0x50,0xfa,0x43,0x4a,0x57,0xb4,0xf2,0x11,
3791
0xad,0x7c,0xc4,0x28,0x5c,0x01,0xe5,0xa3,0x90,0xfa,0xb3,0xcf,0xd5,0x1e,0x0b,0xa8,
3792
0x5e,0x15,0x51,0xfe,0x0a,0xa9,0xde,0x16,0x53,0x3f,0x5e,0x42,0xf1,0x16,0x51,0x7e,
3793
0x77,0x2a,0xbf,0x5f,0x28,0xbf,0xbb,0x94,0xdf,0x85,0x2a,0xe7,0x12,0xca,0x6f,0x29,
3794
0x9d,0xf7,0x54,0xd5,0xab,0xdd,0xca,0xef,0x2b,0x3a,0x5f,0x69,0xe5,0x33,0xa4,0x7c,
3795
0x46,0x2b,0x9f,0x0b,0x74,0xfe,0x73,0xd5,0x8f,0x9f,0xae,0xfa,0x73,0xba,0xea,0x4f,
3796
0x69,0x5d,0x97,0xb2,0xca,0xe7,0xb7,0xca,0xe7,0x59,0xaa,0xcf,0xe5,0xd5,0x8f,0x97,
3797
0xd5,0xf9,0xcb,0x2b,0xdf,0x9f,0x2b,0xdf,0xb1,0x0a,0x7f,0x8e,0xf6,0xc7,0xaa,0x3e,
3798
0x54,0x52,0xba,0xca,0x2a,0x1d,0xe7,0x78,0xe9,0x50,0x3f,0x5e,0x55,0xe5,0x70,0x9f,
3799
0xca,0xe1,0x4b,0x95,0xc3,0x1e,0x95,0xc3,0x57,0x2a,0x87,0x73,0x95,0x8e,0xaa,0x2a,
3800
0x87,0x38,0xe5,0x7f,0xaf,0xf2,0xff,0xa6,0xce,0xb3,0x56,0xf9,0x8f,0x51,0xfe,0x0b,
3801
0xe8,0xbc,0xab,0x75,0x7d,0xab,0xab,0x1f,0x8f,0x53,0x7b,0x48,0x55,0x3e,0xf6,0xa9,
3802
0x5f,0x4a,0x54,0x3c,0x5f,0xe8,0xba,0x25,0x2b,0xbd,0x35,0xd4,0xdf,0xa4,0xaa,0x7c,
3803
0x6a,0xe9,0xb8,0x7a,0x0a,0x57,0x43,0xe1,0xea,0xa8,0x5c,0xeb,0x2a,0x5f,0xb5,0x15,
3804
0xbe,0xbe,0xca,0xb7,0x81,0xea,0x55,0x43,0xe5,0xf7,0xa0,0xce,0xdb,0x48,0xed,0x6a,
3805
0xbf,0xea,0x4f,0x96,0xd2,0xd1,0x54,0xf1,0x37,0x51,0xfc,0x8d,0x15,0x7f,0x0b,0xc5,
3806
0xdf,0xcc,0x6b,0xa7,0x2a,0xb7,0x03,0x2a,0xb7,0x6f,0x54,0x6e,0xdf,0xaa,0xbd,0xb4,
3807
0x54,0xb9,0xb5,0xd2,0xf5,0xa9,0xae,0xf6,0xf2,0x9d,0xca,0xef,0x1d,0xf5,0xe7,0x6d,
3808
0x94,0xaf,0x75,0x2a,0xc7,0x42,0x2a,0xc7,0x22,0xea,0x8f,0xa6,0x28,0x3d,0x6b,0x54,
3809
0x9e,0xbb,0x95,0xfe,0x76,0xca,0x5f,0x07,0xe5,0xb7,0x9d,0xce,0xd3,0x51,0xf9,0xe8,
3810
0xa8,0xf8,0x8a,0x29,0xbe,0x12,0xba,0x2e,0x9d,0x94,0xaf,0x0e,0x2a,0xdf,0xce,0x3a,
3811
0xbe,0x93,0xea,0xd3,0xa5,0x8a,0xa7,0xab,0xe2,0xe9,0xaa,0xf3,0x77,0x57,0x3f,0x7d,
3812
0xba,0xfa,0xe9,0xce,0x0a,0xd7,0x47,0xf5,0xee,0x7e,0x85,0xef,0xa1,0xf0,0xfd,0x14,
3813
0xbe,0xb4,0xc2,0x77,0x57,0x39,0x0e,0x54,0x39,0x0e,0xf0,0xae,0x87,0xca,0xf1,0x90,
3814
0xca,0xf1,0x47,0x95,0x63,0x6f,0xd5,0xbf,0x3e,0x2a,0xc7,0x7e,0xaa,0x7f,0x87,0x55,
3815
0x7e,0x9f,0xab,0xbf,0x19,0xa0,0x7e,0x7d,0xa0,0xca,0xf1,0x3d,0xe5,0xbb,0x94,0xf2,
3816
0x7d,0xaa,0xca,0x71,0xa6,0xd2,0xf5,0x99,0xfa,0xf5,0xc1,0x2a,0xcf,0xc1,0x4a,0xd7,
3817
0x30,0xb5,0xcb,0xab,0xd4,0xaf,0x5f,0xa7,0x7a,0x73,0x83,0xd2,0x39,0x4a,0xe5,0x34,
3818
0x46,0xf5,0xf8,0x2a,0xe5,0xff,0x66,0xe5,0x7f,0xac,0xd2,0xf3,0x80,0x8e,0xbb,0x45,
3819
0xd7,0xe7,0x36,0xed,0xbf,0x43,0xf1,0x1c,0x50,0x3c,0x3f,0x29,0xbf,0xc3,0x54,0x0f,
3820
0x0f,0xaa,0xdf,0x49,0x56,0xff,0x3e,0x5e,0xc7,0xfd,0xa2,0xfc,0x7e,0xaf,0xf8,0x27,
3821
0x29,0xfe,0x6f,0x15,0xcf,0x35,0xba,0x6e,0x77,0xe9,0x7c,0x23,0x54,0x0e,0xd7,0x2b,
3822
0xbf,0xf7,0xa8,0xbc,0x27,0xea,0xfc,0x7b,0xca,0xba,0xc7,0x8d,0x35,0xcf,0x38,0xe6,
3823
0xb9,0xbd,0xac,0xeb,0xff,0xb4,0xe2,0x7b,0x52,0xf9,0x7f,0xb6,0x8c,0x7b,0xde,0xa9,
3824
0x4a,0xd7,0x27,0xaa,0x77,0x87,0xa4,0x87,0x75,0x7d,0xb6,0xca,0x9d,0x4f,0xf1,0x2f,
3825
0x51,0x3c,0x8b,0x14,0xcf,0xeb,0x8a,0x67,0x99,0xfc,0xe3,0xbd,0xe7,0x21,0xb9,0xd7,
3826
0x2a,0xdc,0x07,0x0a,0xf7,0x9e,0xfc,0xcf,0xd3,0x79,0xab,0xa9,0xdd,0x9c,0x2f,0x77,
3827
0x95,0xa0,0xbb,0xff,0xe7,0x80,0x1b,0xcf,0x26,0x9d,0x7f,0x83,0xd2,0xf3,0xbe,0xf2,
3828
0xff,0xa1,0xf6,0x3f,0xa3,0xf8,0x9e,0xd2,0x79,0xa6,0xeb,0x3c,0xd3,0x14,0xdf,0x66,
3829
0x1d,0xff,0xa3,0xf4,0x27,0xc5,0xb3,0x4d,0xee,0x18,0xa5,0x77,0xa9,0xe2,0x59,0xac,
3830
0x78,0xde,0x50,0x3c,0xaf,0xc9,0xbf,0xba,0xc2,0xad,0x97,0xfb,0x5d,0x85,0xdb,0xa0,
3831
0x70,0xef,0xcb,0xbf,0xa5,0xce,0x1b,0xa7,0x7c,0xb5,0x92,0xbb,0xaa,0xf2,0xf5,0x8b,
3832
0xd2,0x9d,0xa3,0xf3,0x6f,0x54,0x7a,0x3e,0x50,0xbe,0x3e,0xd2,0xfe,0x99,0x8a,0xef,
3833
0x05,0x9d,0xe7,0x45,0x9d,0x67,0xb6,0xd2,0x31,0x4b,0xfb,0x67,0x68,0xff,0x5c,0xed,
3834
0x9f,0xa3,0xfd,0x25,0xb5,0xff,0x14,0xb9,0x4b,0xc9,0x7d,0xaa,0xdc,0xad,0xe5,0xbe,
3835
0x40,0xee,0x36,0x72,0xb7,0x55,0x3d,0xbb,0x5c,0xda,0x43,0xda,0x53,0xda,0x4b,0xe1,
3836
0x86,0x7b,0xcf,0x21,0xaa,0xc7,0xd7,0x48,0xaf,0x55,0xb8,0x87,0x14,0x6f,0x8e,0xc2,
3837
0x7d,0xa4,0x74,0x6e,0x51,0x3a,0x3f,0x51,0x3d,0xdf,0xaa,0x70,0x1f,0x2b,0xdc,0x26,
3838
0x85,0xfb,0x54,0xe1,0x36,0x2b,0xdc,0x36,0x85,0xdb,0xa5,0x70,0x3b,0x15,0xee,0x2b,
3839
0x85,0xfb,0x52,0xe1,0xf6,0x29,0xdc,0x6e,0x85,0xfb,0x42,0xe1,0xf6,0x2a,0xdc,0x1e,
3840
0x85,0xdb,0xaf,0xfe,0xec,0x2b,0x95,0xff,0x97,0xd2,0x3d,0xd2,0x2d,0xd2,0x4f,0xd5,
3841
0x3f,0x9d,0xa9,0xfb,0xf5,0x59,0xba,0x9e,0x09,0x41,0x57,0x13,0x83,0x6e,0x3c,0x7b,
3842
0x75,0xdd,0x5e,0x56,0xfb,0xbb,0x29,0xc2,0xdd,0xbf,0xa0,0xac,0x7b,0xdc,0x7c,0xb4,
3843
0x84,0x69,0x47,0x68,0x49,0x53,0xef,0xd0,0x2c,0xf3,0xbb,0x52,0xed,0x73,0xa5,0x8e,
3844
0x1b,0x17,0xe1,0x86,0x3b,0x4d,0xe1,0x4e,0xd7,0xfe,0x55,0xda,0x7f,0x8b,0xf6,0x57,
3845
0xd6,0xfe,0x73,0x15,0xcf,0x5b,0x0a,0xf7,0x91,0xc2,0xdd,0xaa,0xf3,0x7f,0xa8,0xf3,
3846
0x6f,0x2c,0xeb,0x5e,0x9f,0x67,0x75,0x7c,0x4d,0x1d,0x9f,0xae,0xe3,0x7e,0xd0,0x71,
3847
0xb7,0x6b,0x7f,0x53,0xed,0x6f,0x26,0xfd,0x52,0xe1,0x76,0x29,0xdc,0x9d,0x8a,0xff,
3848
0x0b,0xc5,0xbf,0x53,0xf1,0x4f,0x8f,0x70,0xc3,0x77,0x54,0xf8,0x43,0x0a,0x3f,0x5e,
3849
0xf1,0x5e,0xa1,0xf8,0x7a,0x2b,0xdd,0x87,0xa5,0x2f,0x4a,0x5f,0xd7,0x71,0xd9,0x3a,
3850
0xee,0x39,0x9d,0x67,0x96,0xce,0x33,0x53,0xe5,0xe8,0x28,0x9e,0x40,0x59,0xb7,0x9f,
3851
0x7b,0x49,0xc7,0xcf,0xd1,0xf1,0x83,0x74,0xfc,0xf3,0x3a,0x6f,0x51,0x85,0x2f,0xa6,
3852
0xfd,0x43,0xb4,0xff,0x05,0xed,0x2f,0xa7,0xfd,0xe5,0x15,0xdf,0x72,0xc5,0xf7,0x9a,
3853
0xc2,0x0f,0x55,0xf8,0x19,0x4a,0xcf,0xbb,0x4a,0xcf,0x5a,0xe5,0x7b,0x95,0xe2,0x49,
3854
0x50,0x3c,0x89,0x8a,0xe7,0x03,0x1d,0x3f,0x5c,0xc7,0xbf,0xa5,0x70,0x19,0x0a,0xd7,
3855
0x40,0xf9,0xd9,0x2e,0xf7,0x67,0x0a,0x7f,0x8d,0xc2,0xaf,0xd1,0xf9,0x3e,0xd5,0xf9,
3856
0xb6,0xe8,0x7c,0xab,0x15,0x4f,0x6b,0x1d,0xd7,0x46,0xe7,0xdb,0xa1,0xe3,0x47,0xe8,
3857
0xf8,0xb7,0x15,0xae,0x8b,0xc2,0x75,0x55,0xb8,0xef,0x94,0xbf,0x03,0x0a,0xbf,0x4e,
3858
0xe1,0x27,0xe8,0xbe,0xb1,0x41,0xfe,0x5b,0xe5,0x3f,0x53,0xfe,0x9f,0xeb,0xb8,0x6f,
3859
0xe4,0xbf,0x3e,0xc2,0x4d,0xcf,0x7b,0xd2,0xe8,0x48,0x95,0x4b,0xa4,0xeb,0x5e,0x17,
3860
0xe9,0x86,0x8b,0x88,0x74,0xe3,0x73,0xb4,0xff,0x03,0xed,0x0f,0xc8,0xbd,0x54,0xee,
3861
0x1c,0xe9,0x27,0x0a,0x5f,0x28,0x52,0xf7,0x21,0x85,0x3b,0x5d,0xfb,0xb7,0x2b,0xde,
3862
0x82,0x72,0xef,0x50,0xb8,0xaf,0x14,0xae,0xb0,0xfc,0xf7,0x45,0xba,0xcf,0x0f,0x5f,
3863
0xcb,0xfd,0x8d,0xf4,0x07,0xe9,0x97,0x0a,0xff,0xae,0xdc,0xeb,0x15,0x6f,0x5b,0x9d,
3864
0xbf,0xb5,0xf6,0x6f,0xd0,0xfe,0x36,0x72,0x2f,0x93,0xfb,0x63,0xe9,0x66,0x85,0xbf,
3865
0x54,0xe9,0xd8,0xa6,0x70,0xe9,0xda,0xff,0x99,0xe2,0xbd,0x44,0xee,0xcf,0x15,0x6e,
3866
0xaf,0xc2,0x5d,0x26,0xff,0xfd,0x4a,0xef,0x01,0xb9,0xbf,0x95,0x1e,0x94,0xee,0x91,
3867
0x76,0x88,0x74,0x9f,0x83,0x86,0x4a,0x87,0xc9,0xff,0x23,0xe9,0x26,0xe9,0x2e,0xe9,
3868
0x6e,0xb4,0x6d,0x94,0xe3,0x54,0x80,0x0b,0x21,0x16,0xda,0xc1,0x39,0x72,0x9f,0x2d,
3869
0xad,0x28,0x5d,0x26,0x5d,0x2f,0x5d,0x02,0x75,0x62,0xe8,0x6f,0x62,0x5c,0x4d,0x94,
3870
0xa6,0xc0,0x22,0x58,0x0d,0x1b,0xe0,0x2d,0xa8,0x57,0x80,0xe7,0x69,0x68,0x0f,0x4d,
3871
0xa1,0x03,0x9c,0x07,0x1b,0xe0,0x5e,0x58,0x04,0xab,0xe4,0x7e,0x4b,0xee,0xd5,0x26,
3872
0x7c,0x41,0xc2,0xc3,0xfb,0xb0,0x04,0x96,0xc1,0x2a,0xb9,0x57,0xc0,0x07,0xb0,0x52,
3873
0xee,0xd5,0x50,0xaf,0x90,0xe3,0x34,0x87,0x0e,0x70,0x5e,0x21,0xd7,0xdd,0x02,0x56,
3874
0xc1,0x47,0xf0,0x0e,0xe4,0xc0,0x66,0xf8,0x44,0xfe,0x1f,0x43,0x7c,0x51,0xf2,0x09,
3875
0xa9,0xa5,0x29,0xfb,0xd2,0xae,0xe6,0x93,0xe6,0x97,0x16,0x94,0x16,0x96,0x16,0x97,
3876
0xd6,0x96,0xd6,0x95,0x66,0x48,0x1b,0x48,0x1b,0x96,0x76,0xaf,0x6b,0x4d,0xdd,0x27,
3877
0xd2,0xa5,0x97,0x48,0x2f,0xd5,0xfd,0xf1,0x0a,0x69,0x6f,0x3d,0x6f,0x3e,0xa7,0xfb,
3878
0xcb,0x4b,0x72,0x3f,0x2f,0xf7,0x3c,0xb9,0x97,0x4b,0x57,0x48,0x37,0x4a,0x3f,0xd4,
3879
0xfd,0x2e,0xa8,0xf6,0x18,0xa9,0xf6,0x1d,0xa5,0x76,0x3a,0x52,0xed,0x38,0x42,0xfb,
3880
0x43,0xda,0x1f,0xad,0xfd,0xa3,0xa4,0xa3,0xa5,0x63,0xa4,0x37,0x4a,0xc7,0x4a,0x6f,
3881
0x92,0xde,0xac,0xf8,0xf2,0x2b,0xbe,0x82,0x8a,0xaf,0xb0,0xf6,0x8f,0xd3,0xfe,0x02,
3882
0xda,0x5f,0x48,0xfb,0x8b,0x68,0xff,0x2d,0xd2,0x5b,0xa5,0xb7,0x49,0x6f,0x97,0xde,
3883
0x21,0xbd,0x53,0x3a,0x5e,0xf1,0x15,0x57,0x7c,0x25,0xe5,0x2e,0x21,0x77,0x29,0xb9,
3884
0xcf,0x90,0xfb,0x4c,0xb9,0x4b,0xcb,0x7d,0x96,0xdc,0x15,0xe4,0x3e,0x5b,0xe9,0xa9,
3885
0xa8,0xf8,0x27,0x68,0x7f,0xac,0xf6,0x9f,0xa3,0xfd,0x95,0xb4,0xff,0x2e,0xe9,0xdd,
3886
0xd2,0x7b,0xa4,0xf7,0x4a,0x27,0x4a,0xef,0x93,0xde,0xaf,0xf8,0xaa,0x28,0xbe,0x6a,
3887
0x8a,0x2f,0x5e,0xfb,0x1f,0xd0,0xfe,0xaa,0xda,0x1f,0xa7,0xfd,0xd5,0xb5,0x7f,0x92,
3888
0xf4,0x41,0xe9,0x43,0xd2,0x87,0xa5,0x8f,0x48,0x1f,0x95,0x3e,0xa6,0xf8,0x92,0x14,
3889
0x5f,0x8a,0xe2,0x4b,0x93,0x7f,0xb2,0xfc,0x53,0xe5,0x5f,0x43,0xfe,0xb5,0xe4,0x5f,
3890
0x47,0xfe,0xf5,0xe4,0x5f,0x5b,0xfe,0x75,0xe5,0x5f,0x5f,0xfe,0x99,0xf2,0x6f,0x24,
3891
0x77,0x43,0xb9,0xb3,0xe4,0x6e,0x2e,0xf7,0x79,0x72,0xb7,0x90,0xbb,0xa5,0xdc,0x17,
3892
0xc8,0x7d,0xa1,0xe2,0x6d,0x2f,0xff,0xb6,0xf2,0x6f,0x27,0xff,0x0e,0xf2,0xef,0x24,
3893
0xff,0x4b,0xe5,0xdf,0x59,0xfe,0xdd,0xe4,0x7f,0xb9,0xfc,0x7b,0xaa,0x1c,0x26,0x6b,
3894
0x7f,0x77,0xed,0xef,0xa1,0xfd,0xbd,0xb4,0x7f,0x8a,0xf4,0x71,0xe9,0x13,0xd2,0x27,
3895
0xa5,0x4f,0x49,0x9f,0x96,0x3e,0xa3,0xf8,0xae,0x54,0x7c,0x7d,0x15,0x5f,0x7f,0xed,
3896
0x9f,0xaa,0xfd,0x7d,0xb4,0xbf,0x9f,0xf6,0x0f,0xd0,0xfe,0x69,0xd2,0x67,0xa5,0xd3,
3897
0xa5,0xcf,0x49,0x9f,0x97,0xbe,0x20,0x9d,0x21,0x9d,0x2d,0x5d,0x26,0xfd,0x5a,0x3a,
3898
0x4f,0xe7,0x5b,0xe3,0xdd,0xd7,0x75,0xbe,0x77,0xb4,0x7f,0x85,0xf4,0x7b,0x85,0xfb,
3899
0x58,0xe1,0x3e,0x51,0xb8,0xcd,0x65,0xdd,0x71,0x9d,0x07,0xcb,0xbb,0xfa,0x90,0xf4,
3900
0x05,0xe9,0x1a,0xe9,0x3b,0xd2,0xb7,0xa5,0x91,0x1a,0x0f,0x8a,0x91,0x16,0x94,0x9e,
3901
0x2d,0xad,0x28,0x6d,0x20,0x6d,0x24,0x6d,0x22,0x6d,0x26,0xed,0x27,0xed,0x26,0xcd,
3902
0x96,0x0e,0x94,0x0e,0x91,0x5e,0x25,0x1d,0x2e,0xbd,0x5a,0x3a,0x52,0x3a,0x4a,0xba,
3903
0x45,0xfa,0xa9,0xf4,0x46,0xe9,0x58,0xe9,0x38,0xe9,0x2d,0xd2,0xad,0xd2,0x6d,0xd2,
3904
0xe7,0xa4,0xcf,0x4b,0x5f,0x90,0xce,0x90,0xee,0x92,0xee,0x96,0x7e,0x29,0xdd,0x83,
3905
0x4e,0x4a,0xa0,0xfd,0x27,0xb8,0x7a,0x9e,0xf4,0x7c,0x69,0x6b,0xe9,0x05,0xd2,0x0b,
3906
0xa5,0xed,0xa5,0x17,0x49,0x2f,0x96,0x5e,0x22,0xbd,0x4c,0xda,0x45,0xda,0x4d,0xda,
3907
0x43,0xda,0x4b,0xda,0x5b,0x9a,0x0d,0x0f,0xc2,0x40,0xb9,0x07,0xcb,0x3d,0x44,0xee,
3908
0xa1,0x72,0x0f,0x93,0xfb,0x6a,0xb9,0xaf,0x91,0x7b,0x84,0xdc,0xd7,0xc9,0xfd,0xa8,
3909
0xf4,0x1b,0xe9,0x73,0xd2,0x17,0xa4,0x33,0xa5,0xb3,0xa5,0x2f,0x4a,0x5f,0x92,0xce,
3910
0x97,0xbe,0x2c,0x7d,0x55,0xba,0x48,0xba,0x44,0xba,0x4c,0xfa,0x86,0x74,0x85,0xf4,
3911
0x4d,0xe9,0x5a,0xa5,0xeb,0x5d,0xb9,0xd7,0xcb,0xfd,0x9e,0xdc,0x1f,0xc8,0xbd,0x41,
3912
0xee,0x0f,0xe5,0xfe,0x48,0xee,0x1c,0xb9,0x3f,0x96,0xfb,0x7b,0xe9,0x0f,0xd2,0x83,
3913
0xd2,0x43,0xd2,0x9f,0x4d,0x9a,0x8b,0x06,0x9c,0x07,0xc1,0xe8,0xc3,0xd2,0xe9,0x50,
3914
0xa9,0x58,0xc0,0x89,0x2f,0xe6,0x6a,0x75,0xa8,0x57,0x22,0xe0,0xb4,0x80,0x0e,0x70,
3915
0x1e,0xcc,0x2c,0x19,0x70,0x5e,0x85,0x97,0xe1,0x15,0x58,0x08,0x8b,0x60,0x46,0x29,
3916
0xfc,0x4a,0xb9,0xfa,0x0a,0x24,0x9c,0x1e,0x70,0x6a,0x02,0xa7,0x72,0xd2,0xa1,0x01,
3917
0x5c,0x0c,0x9d,0x45,0x57,0xb8,0x06,0x9e,0x15,0x73,0xc5,0x3c,0xf1,0xb2,0x30,0x63,
3918
0xb1,0x66,0xbc,0x68,0xa3,0xe3,0xbe,0x67,0xfc,0xc1,0xf8,0xf3,0xbb,0xf3,0x15,0xf1,
3919
0x2a,0x2c,0x86,0x25,0xf0,0x1a,0xbc,0x0e,0xf7,0xf0,0xfb,0xf4,0x5e,0x98,0x08,0xf7,
3920
0xc1,0x0c,0x98,0x09,0x4b,0x61,0x39,0xbc,0x0b,0x5b,0x60,0x3b,0x7c,0x29,0xbe,0x12,
3921
0xa6,0x1f,0x19,0x60,0xda,0xaa,0x79,0x8f,0x66,0xda,0xa8,0x18,0x6a,0x9e,0x37,0xcd,
3922
0x6f,0x14,0x71,0xad,0x79,0x9f,0x66,0xde,0xa5,0x89,0x9b,0xc4,0xcd,0x62,0x9c,0x7e,
3923
0x8f,0xde,0x2e,0xcc,0x6f,0xc7,0x29,0xa6,0x0f,0x36,0xcf,0xb7,0xa6,0xcf,0x32,0xed,
3924
0x9a,0xe7,0xd3,0x31,0x70,0x33,0xdc,0x0a,0xd5,0x43,0x3c,0x63,0x42,0x7b,0xe8,0x28,
3925
0xba,0xc0,0x38,0xb8,0x0b,0x16,0xc2,0x62,0xb1,0x14,0x96,0xc1,0xeb,0xf0,0x06,0xac,
3926
0x10,0x6b,0x61,0x17,0xec,0x85,0xaf,0xa1,0x28,0xcf,0xb0,0x67,0x40,0x39,0xa8,0x0f,
3927
0x19,0xa2,0x01,0x34,0x87,0x16,0xd0,0x19,0xba,0x40,0x6f,0xe8,0x0f,0x03,0x20,0x5b,
3928
0x0c,0xd4,0xf3,0xf0,0xfb,0xe2,0x03,0xc8,0x81,0xcd,0xb0,0x1d,0x3e,0x83,0x1d,0xf0,
3929
0x39,0xec,0x84,0x5d,0xb0,0x07,0xbe,0x82,0xbd,0xb0,0x0f,0x0e,0xc2,0x21,0x38,0x0c,
3930
0xbf,0x88,0xa2,0xd1,0x2e,0xc5,0x44,0x71,0xa8,0x0e,0x09,0xd0,0x1c,0x5a,0xc2,0x53,
3931
0xf0,0x34,0xcc,0x84,0x59,0x62,0x09,0xbc,0x09,0xab,0x60,0x17,0xec,0x86,0x03,0xf0,
3932
0x0d,0x7c,0x0b,0x87,0xc4,0x4f,0xc2,0xc9,0xc7,0xf3,0x12,0x9c,0x02,0xa7,0xc3,0x19,
3933
0xa2,0x34,0xc4,0xc2,0xd9,0xe2,0x1c,0xa8,0x04,0x95,0xc5,0xb9,0x10,0x07,0x19,0x70,
3934
0x11,0x74,0x84,0x4e,0xd0,0x05,0xae,0x84,0x6c,0xb8,0x19,0x6e,0x81,0xf1,0x70,0x3f,
3935
0x3c,0x06,0x93,0x61,0x25,0xbc,0x29,0x56,0xc1,0xa7,0xb0,0x0d,0x82,0xfc,0x4e,0x88,
3936
0x10,0x91,0x90,0x0e,0xb5,0x44,0x6d,0x51,0x47,0xd4,0x15,0xf5,0x20,0x03,0x1a,0x40,
3937
0x53,0x68,0x06,0xe7,0x41,0x4b,0x71,0x3e,0xb4,0x82,0xd6,0xa2,0x0d,0x74,0x80,0x8b,
3938
0xa0,0x2b,0x74,0x83,0xee,0xd0,0x13,0x06,0xc0,0x40,0x31,0x08,0x46,0xc2,0x28,0x31,
3939
0x1a,0xc6,0xc0,0x58,0xb8,0x1d,0xc6,0xc3,0x04,0xb8,0x07,0xa6,0xc2,0xb3,0x30,0x13,
3940
0x66,0x8b,0x97,0x60,0x01,0xbc,0x2a,0x16,0x0a,0xf3,0xbb,0x68,0x09,0x2c,0x85,0xd7,
3941
0x61,0x05,0xac,0xd4,0x6f,0x25,0xf3,0x3b,0x69,0x8d,0x78,0x5b,0x6c,0x10,0x39,0xf0,
3942
0x31,0x6c,0x86,0x4f,0x61,0x2b,0x6c,0x83,0x1d,0xb0,0x17,0xf6,0xc1,0x7e,0x38,0x2c,
3943
0x7e,0x16,0x81,0xfc,0x94,0x2b,0x44,0x88,0x10,0xe4,0x87,0x22,0x50,0x14,0x4a,0x40,
3944
0x65,0xa8,0x02,0x09,0x90,0x04,0xc9,0x90,0x0a,0x69,0x50,0x13,0xd2,0xa1,0x8e,0xa8,
3945
0x07,0x19,0xd0,0x00,0x32,0xa1,0x09,0x34,0x85,0x16,0xd0,0x12,0xda,0x88,0x8e,0x70,
3946
0x09,0x5c,0x26,0x7a,0xc2,0x00,0xc8,0x86,0x81,0x30,0x08,0x86,0xc0,0x55,0x62,0x14,
3947
0x8c,0x86,0x31,0x62,0x2c,0xdc,0x01,0xe3,0xe1,0x2e,0xb8,0x07,0xa6,0xc2,0xb3,0x30,
3948
0x13,0x66,0xc3,0x1c,0x98,0x0b,0x0b,0xe0,0x55,0xb1,0x50,0x2c,0x82,0x25,0xb0,0x14,
3949
0xde,0x80,0x15,0xb0,0x12,0xde,0x14,0xab,0xe1,0x2d,0x58,0x23,0xd6,0x8a,0x2d,0xf0,
3950
0x29,0x6c,0x85,0x6d,0xb0,0x03,0xf6,0xc2,0x41,0x71,0x08,0x7e,0x81,0x40,0x01,0x97,
3951
0x20,0x44,0x40,0x08,0x0a,0x42,0x11,0x28,0x0a,0x25,0xa0,0x32,0x54,0x81,0x04,0x48,
3952
0x82,0x64,0x48,0x85,0x74,0xa8,0x23,0xea,0x8a,0x7a,0xa2,0xbe,0xc8,0x10,0x0d,0xa0,
3953
0x11,0x34,0xd1,0xef,0xe6,0x16,0xfa,0xdd,0xdc,0x52,0xb4,0xd3,0x6f,0xea,0x0e,0xe2,
3954
0x12,0xb8,0x14,0x3a,0x43,0x57,0xe8,0x06,0xdd,0xa1,0x27,0x0c,0x80,0x81,0x62,0xb4,
3955
0x18,0x23,0xc6,0xc2,0xad,0x70,0x27,0x4c,0x80,0xbb,0x61,0x22,0x4c,0x82,0x07,0xe1,
3956
0x61,0xf1,0x28,0x3c,0x06,0x4f,0xc0,0x93,0x30,0x15,0x9e,0x85,0x17,0x60,0x81,0x7e,
3957
0xb7,0x2f,0x86,0x25,0x62,0x29,0x2c,0x83,0xe5,0xb0,0x52,0xbf,0xf1,0xcd,0xef,0xfb,
3958
0x35,0x62,0xad,0xd8,0x20,0x76,0xc0,0xde,0x02,0x66,0x40,0xd9,0x25,0x00,0x11,0x10,
3959
0x29,0x42,0x50,0x10,0x0a,0x43,0x51,0x28,0x0e,0x95,0xa1,0x0a,0xa4,0x43,0x1d,0x51,
3960
0x57,0xd4,0x83,0x0c,0x68,0x00,0x8d,0xa0,0xb1,0xde,0x27,0x34,0x87,0x96,0xd0,0xae,
3961
0xa0,0xfb,0x8e,0xe1,0x22,0xb8,0x18,0x2e,0x81,0x4b,0xa1,0x0b,0x74,0x85,0x6e,0xd0,
3962
0x1d,0x7a,0xc2,0x00,0x18,0x29,0x46,0x89,0xd1,0x30,0x06,0xc6,0xc2,0xed,0x70,0x27,
3963
0x4c,0x80,0xbb,0x61,0x2a,0x3c,0x0b,0x73,0x60,0x2e,0x2c,0x80,0x57,0xc5,0x42,0xb1,
3964
0x48,0x2c,0x16,0xe6,0x1d,0xc7,0xeb,0xb0,0x5c,0xac,0xd0,0xfb,0x8d,0x55,0x7a,0xbf,
3965
0xf1,0x16,0xac,0xd1,0xfb,0x0e,0xf3,0xee,0x23,0x07,0x3e,0x81,0x2d,0xf0,0x29,0x6c,
3966
0x85,0x6d,0xb0,0x03,0xf6,0xc2,0x7e,0xf8,0x1a,0x0e,0x08,0xa7,0x10,0x65,0x0a,0x41,
3967
0x88,0x80,0x48,0x28,0x08,0x85,0xa1,0x28,0x14,0x87,0x5a,0x50,0x1b,0xea,0x40,0x5d,
3968
0x61,0xde,0xa3,0x64,0x40,0x03,0x68,0x04,0x8d,0xa1,0xa9,0xde,0xb5,0x98,0xf7,0x2c,
3969
0x2d,0xc5,0xf9,0xe2,0x42,0x68,0xaf,0xf7,0x30,0x86,0xce,0xd0,0x15,0xba,0x41,0x77,
3970
0xe8,0x09,0x03,0xe0,0x1a,0xb8,0x01,0x46,0x89,0xd1,0x30,0x06,0xc6,0xc2,0x7d,0xf0,
3971
0x20,0xcc,0x82,0x39,0xf0,0x0a,0x2c,0x14,0x4b,0x60,0xb9,0xde,0xdf,0xac,0xd2,0x7b,
3972
0x9d,0x77,0x61,0x1d,0xbc,0x07,0x1f,0x88,0x8d,0x7a,0xd7,0xb3,0x03,0xf6,0xc2,0xd7,
3973
0x70,0xc0,0x94,0x41,0x61,0xda,0x25,0x24,0x8a,0x24,0x48,0x86,0x14,0xa8,0x05,0x19,
3974
0x90,0x05,0x8d,0x45,0x13,0x38,0x1f,0x5a,0x43,0x47,0x18,0x05,0xa3,0xe1,0x46,0x71,
3975
0x13,0xdc,0x0a,0xb7,0xc3,0x13,0xf0,0x94,0x78,0x06,0x66,0xc2,0x2c,0x31,0x1b,0xe6,
3976
0xc0,0x8b,0xf0,0x2a,0x2c,0x14,0x4b,0xe0,0x75,0x58,0x2e,0x56,0xc2,0xdb,0xb0,0x16,
3977
0x3e,0x84,0x1c,0xd8,0x0c,0x4e,0x11,0x97,0xd3,0xe0,0x74,0x28,0x07,0xe7,0x42,0xaa,
3978
0xa8,0x21,0xd2,0x45,0x3d,0xa8,0x0f,0x19,0xd0,0x04,0x9a,0x41,0x5f,0x18,0x08,0xd7,
3979
0xc3,0x0d,0x62,0x24,0xdc,0x08,0x37,0xc1,0xcd,0x30,0x0e,0x6e,0x87,0x3b,0xe0,0x7e,
3980
0x98,0x04,0xaf,0xc2,0x72,0xe1,0x14,0xa5,0xcd,0x41,0x55,0xa8,0x06,0x71,0x90,0x00,
3981
0x89,0x22,0x09,0x6a,0x40,0x4d,0x91,0x0e,0xb5,0xa0,0x36,0xd4,0x81,0xba,0x50,0x0f,
3982
0xea,0x8b,0x0c,0x68,0x06,0xad,0xa1,0x1d,0xb4,0x87,0x0e,0x70,0x11,0x74,0x84,0x8b,
3983
0xe1,0x52,0xb8,0x0c,0xba,0x40,0x57,0xd1,0x0d,0x2e,0x87,0x1e,0xd0,0x13,0x7a,0x41,
3984
0x3f,0xe8,0x0f,0xd9,0x30,0x10,0x86,0xc0,0x55,0x30,0x0a,0x46,0x8b,0x31,0x70,0x23,
3985
0x8c,0x85,0x9b,0xe0,0x66,0xb8,0x1d,0xee,0x10,0x77,0x8a,0xf1,0x62,0x02,0x4c,0x82,
3986
0x07,0xe1,0x61,0x78,0x44,0x4c,0x86,0x37,0x60,0x85,0x58,0x23,0xd6,0xc2,0x21,0x38,
3987
0x2c,0x7e,0x82,0x5f,0xc0,0x29,0x46,0xbb,0x29,0x4e,0xbb,0x81,0x96,0xd0,0x1a,0xda,
3988
0xc3,0x45,0xe2,0x62,0xb8,0x14,0xba,0xc0,0x38,0xb8,0x15,0xee,0x80,0x09,0x30,0x13,
3989
0x66,0xc3,0x5c,0x98,0x0f,0x8b,0x60,0x89,0x58,0x06,0x6f,0xc0,0x4a,0xf8,0x00,0x36,
3990
0x42,0xd1,0x12,0xb4,0x67,0x28,0x05,0xa7,0xc1,0xc5,0x70,0x29,0x74,0x86,0xde,0x30,
3991
0x10,0x46,0xc2,0x78,0x98,0x0c,0xdf,0xc2,0x0f,0xf0,0x13,0x04,0x4a,0x52,0x4f,0x4e,
3992
0xa1,0x8d,0xc2,0x0d,0x30,0x0a,0x1e,0x84,0xc9,0xb0,0x0b,0xbe,0x82,0x7d,0xb0,0x1f,
3993
0x7e,0x00,0xe7,0x54,0xb2,0x06,0xc5,0xa1,0x24,0x94,0x12,0x65,0x21,0x11,0x92,0x20,
3994
0x19,0x52,0x44,0x06,0xb4,0x81,0x0b,0xa0,0x2d,0x74,0x81,0xbe,0xd0,0x1f,0xb2,0x61,
3995
0x10,0x0c,0x86,0x91,0x30,0x07,0x5e,0x84,0xb9,0xf0,0x92,0x98,0x07,0x0b,0x61,0x11,
3996
0xbc,0x01,0xcb,0xc5,0x0a,0x58,0x09,0x6f,0xc2,0x7a,0xd8,0x20,0x72,0xc4,0xc7,0x62,
3997
0x0b,0x7c,0x01,0x05,0x4e,0xa3,0x4b,0x84,0x22,0xa2,0x28,0x9c,0x0e,0xe5,0x20,0x13,
3998
0x1a,0x8a,0x46,0x30,0x1c,0x46,0xc2,0x8d,0x30,0x16,0x6e,0x82,0x9b,0x61,0x2a,0x4c,
3999
0x13,0xcf,0x8a,0x99,0xf0,0x2d,0x38,0xa7,0x3b,0x4e,0x19,0x28,0x07,0x15,0x20,0x16,
4000
0x2a,0x42,0x25,0xa8,0x0c,0xe7,0x42,0x55,0x48,0x80,0x44,0x48,0x12,0xc9,0x50,0x13,
4001
0xd2,0xa1,0x36,0x34,0x86,0x56,0xd0,0x1a,0xfa,0x41,0x36,0x0c,0x81,0x91,0x30,0x1d,
4002
0x66,0xc2,0x9b,0xb0,0x16,0x3e,0x84,0x8f,0x84,0x73,0x06,0xcf,0xf6,0x70,0x2a,0x9c,
4003
0x06,0xa7,0xc3,0x19,0x50,0x5a,0x94,0x83,0x0b,0xa1,0x9d,0x68,0x2f,0x3a,0x88,0x8b,
4004
0xe0,0x32,0xe8,0x22,0xba,0x8a,0x6e,0xa2,0x3b,0x5c,0x0e,0x3d,0xa0,0x2f,0xf4,0x83,
4005
0x41,0x30,0x18,0x46,0xc0,0x0d,0x62,0x24,0xdc,0x02,0x13,0x60,0x12,0x3c,0x23,0x66,
4006
0xc2,0x42,0x58,0x0c,0x1f,0xc3,0x16,0xd8,0x0d,0x4e,0x69,0xee,0x4f,0xe6,0xbd,0xb9,
4007
0x08,0x41,0x32,0xa4,0x88,0x54,0x91,0x06,0xb5,0xf4,0x0e,0xde,0x50,0x47,0xd4,0xd5,
4008
0xfb,0xf7,0x4c,0x61,0xde,0xc1,0x37,0x82,0x2c,0x38,0x0f,0x5a,0x43,0x47,0xe8,0x03,
4009
0x83,0x61,0x24,0x8c,0x82,0xd1,0x62,0x0c,0x4c,0x86,0x29,0xe2,0x71,0x78,0x0a,0x9e,
4010
0x86,0x67,0x60,0x2a,0x4c,0x83,0x67,0xc5,0x74,0x78,0x1e,0x5e,0x80,0x19,0x30,0x13,
4011
0x16,0xc0,0xcb,0xf0,0x19,0xec,0x10,0x9f,0x8b,0x9d,0xf0,0x05,0xec,0x82,0x2f,0x61,
4012
0x8f,0xf8,0x4a,0xec,0x85,0xfd,0xf0,0x35,0x1c,0x00,0xe7,0x4c,0xea,0x0e,0x9c,0x0d,
4013
0x55,0xa1,0x1a,0x24,0x43,0x0a,0xa4,0x42,0x1a,0xd4,0x80,0x0c,0x68,0x06,0x2d,0xa1,
4014
0x15,0xb4,0x86,0x8e,0x70,0x31,0x0c,0x83,0xe1,0x70,0x1d,0x8c,0x84,0x5b,0x61,0x02,
4015
0xbc,0x0c,0x0b,0x61,0x31,0xac,0x85,0x75,0xf0,0x1e,0x6c,0x81,0x4f,0xc5,0x56,0xd8,
4016
0x09,0x5f,0xc0,0x97,0xb0,0x47,0x7c,0x05,0x07,0xe0,0x1b,0xf1,0x2d,0x7c,0x07,0xdf,
4017
0x8b,0x1f,0xe0,0x20,0x1c,0x12,0xce,0x59,0xa4,0x1f,0xaa,0xc1,0x95,0xd0,0x07,0x86,
4018
0xc1,0x70,0x71,0x35,0x3c,0x08,0x0f,0xc1,0x62,0x58,0x02,0xbf,0x9c,0xe5,0xce,0x01,
4019
0x37,0xef,0xf5,0xcd,0x18,0xb8,0x79,0x7f,0x6f,0xc6,0x66,0xcd,0x7b,0x66,0x33,0x26,
4020
0x6d,0xde,0x27,0x9b,0x31,0x4f,0xf3,0x9e,0xb8,0xa3,0xe8,0x24,0x2e,0x15,0xe6,0x5d,
4021
0xf1,0x75,0x65,0xdd,0xb1,0x0f,0x33,0xae,0x6c,0xc6,0x86,0xcd,0x38,0xfb,0x22,0x61,
4022
0xde,0xad,0x9a,0x71,0x66,0x33,0xc6,0x6b,0xc6,0xcd,0xcd,0x18,0xee,0xfa,0xb2,0xee,
4023
0x58,0xed,0xa6,0xb2,0xee,0x18,0xab,0x19,0xef,0x36,0xef,0x5e,0xcd,0x38,0xa7,0x19,
4024
0x2b,0x35,0xe3,0xd4,0x05,0xcb,0xd1,0x7f,0x40,0x7d,0xc8,0x80,0x0b,0xc5,0x40,0x71,
4025
0x83,0x98,0x00,0x0f,0xc3,0x5a,0xc8,0x81,0x4f,0xc5,0x67,0xb0,0x0f,0x82,0xe5,0x5d,
4026
0xa2,0x45,0x7e,0x28,0x01,0xa5,0xc4,0x69,0xe2,0x74,0x38,0x0b,0xce,0x16,0x15,0x45,
4027
0x65,0x51,0x05,0xe2,0x20,0x5e,0x54,0x87,0x14,0x48,0x35,0xef,0x6e,0x21,0x5d,0xd4,
4028
0x81,0xfa,0x90,0x05,0xcd,0xe0,0x7c,0xd1,0x05,0x46,0xc3,0x18,0xb8,0x11,0xc6,0xc2,
4029
0x38,0x70,0xaa,0x39,0xce,0xb5,0x30,0x02,0xae,0x83,0xeb,0x61,0x3b,0xec,0x86,0xaf,
4030
0x60,0x2f,0xec,0x87,0xaf,0xe1,0x00,0x38,0x71,0x8e,0x73,0x0e,0x54,0x12,0x71,0x22,
4031
0x01,0x7a,0xc1,0x00,0x71,0x83,0x18,0x09,0xf7,0xc1,0x64,0x78,0x1a,0xa6,0xc2,0x0b,
4032
0x30,0x13,0x5e,0x82,0xf9,0xb0,0x08,0x96,0xc0,0x72,0x58,0x09,0x6f,0xc3,0x5a,0xf8,
4033
0x00,0x36,0xc2,0x27,0xb0,0x05,0x7e,0x81,0x50,0x82,0x4b,0x94,0x88,0x16,0xe5,0xe1,
4034
0x5c,0xa8,0x02,0x71,0x10,0x0f,0xd5,0x21,0x11,0x52,0xa1,0x26,0xd4,0x82,0xda,0xa2,
4035
0x8e,0x68,0x00,0xf7,0xe9,0xfd,0xa0,0x79,0x97,0xf8,0x10,0x3c,0x0c,0x8f,0xe8,0x3d,
4036
0xe9,0x63,0x62,0x8a,0xde,0x23,0xfe,0x28,0x0e,0xeb,0x7d,0xe2,0x2f,0x22,0x94,0xc8,
4037
0xf9,0x20,0x11,0xee,0x84,0xc9,0xb0,0x18,0xf6,0xc1,0x2f,0xe0,0xa4,0xe0,0x6e,0x89,
4038
0x9e,0xcf,0x7d,0x74,0x32,0xd7,0x5e,0x9c,0x02,0xb7,0x3f,0x49,0x7e,0xe1,0x7b,0xf8,
4039
0x01,0x7e,0x02,0xe7,0x29,0xee,0x61,0x4f,0x53,0x0f,0x45,0x51,0x28,0x0b,0xe5,0xe0,
4040
0x5c,0xa8,0x02,0x55,0x21,0x03,0xfa,0x41,0x7f,0x31,0x40,0x0c,0x81,0xeb,0xe0,0x06,
4041
0x31,0x12,0x1e,0x82,0x87,0xe1,0x11,0x78,0x14,0x1e,0x83,0xc9,0xf0,0x19,0xec,0x80,
4042
0xbd,0xb0,0x0f,0xf6,0xc3,0xa9,0xcf,0x70,0x3e,0xa8,0x00,0x03,0x20,0x5b,0x0c,0x84,
4043
0x9b,0x61,0x9c,0xb8,0x0d,0xee,0x84,0xf1,0x62,0x02,0xe4,0xc0,0x7e,0xf8,0x06,0xbe,
4044
0x85,0xef,0xe0,0x7b,0xf1,0x03,0x1c,0x84,0x43,0xe2,0x47,0x08,0x4c,0xa5,0x8d,0x88,
4045
0x08,0x08,0x41,0x94,0x88,0x86,0xfc,0x50,0x40,0x14,0x84,0x0a,0x10,0x0b,0x67,0xc3,
4046
0x39,0x50,0x11,0x2a,0x89,0x6a,0x22,0x03,0x06,0xc3,0x48,0x18,0x05,0xa3,0x61,0x0e,
4047
0xbc,0x08,0xaf,0xc1,0xeb,0xf0,0x06,0xac,0x85,0x0f,0x61,0x0b,0xec,0x87,0xaf,0xe1,
4048
0x7b,0xf8,0x51,0xfc,0x04,0x3f,0xc3,0x2f,0xc2,0x99,0xe6,0x38,0x31,0x90,0x1f,0xce,
4049
0x81,0x8a,0x10,0x07,0x09,0xd0,0x18,0x9a,0x40,0x1b,0xb8,0x00,0xda,0x42,0x17,0x18,
4050
0x01,0x23,0x61,0x34,0x8c,0x11,0x37,0xc2,0x6c,0x98,0x23,0x5e,0x84,0xb9,0xf0,0x12,
4051
0x2c,0x80,0x97,0xe1,0x15,0x78,0x15,0x16,0xc2,0x22,0x58,0x02,0xef,0x88,0xb5,0xf0,
4052
0x21,0x6c,0x81,0xed,0xf0,0x99,0xd8,0x21,0x3e,0x87,0xbd,0xb0,0x0f,0x0e,0xc2,0x21,
4053
0xf8,0x79,0x9a,0xfb,0xd2,0xb9,0x32,0x9c,0x0b,0xf1,0x50,0x1d,0x12,0x20,0x11,0x92,
4054
0x20,0x19,0x52,0x20,0x15,0xd2,0x20,0x03,0x32,0xa1,0xa1,0x68,0x04,0x2d,0xe0,0x3c,
4055
0xd1,0x52,0xb4,0x86,0x8e,0xd0,0x05,0x06,0x40,0xb6,0x18,0x08,0x43,0xe1,0x1a,0x71,
4056
0xad,0x18,0x21,0xae,0x13,0xd7,0xc3,0x0c,0x98,0x29,0x66,0x89,0xd9,0xf0,0x22,0xcc,
4057
0x85,0x97,0x60,0x1e,0xcc,0x87,0x05,0xb0,0x10,0x16,0xc1,0x62,0x58,0x22,0x96,0x8a,
4058
0x65,0x62,0x13,0xe4,0xc0,0xc7,0x62,0x0b,0xec,0x82,0xdd,0xe2,0x4b,0xd8,0x03,0x5f,
4059
0xc1,0x5e,0xf8,0x5a,0x1c,0x80,0x6f,0xe0,0x5b,0xf1,0x9d,0x08,0x4c,0xa7,0x5e,0x42,
4060
0x0c,0x14,0x86,0x62,0x70,0x0a,0x94,0x83,0x8a,0x50,0x19,0xe2,0x21,0x01,0x2e,0x86,
4061
0x4b,0xa0,0x33,0x74,0x81,0x2b,0xa0,0xb7,0xc8,0x86,0xc5,0xb0,0x04,0xb6,0xc2,0x36,
4062
0xd8,0x0e,0x9f,0x89,0x1d,0xf0,0x39,0xec,0x14,0x5f,0xc0,0x2e,0xf8,0x52,0xec,0x11,
4063
0xfb,0xe0,0x20,0x38,0xcf,0xf1,0xfb,0x74,0x03,0x65,0x07,0xcb,0x61,0x35,0xfc,0x08,
4064
0x66,0x52,0x6e,0xbf,0x43,0x9c,0x0f,0x3e,0x34,0x13,0x73,0x7f,0x24,0xfd,0x50,0x02,
4065
0x4e,0x85,0xb3,0x44,0x19,0x51,0x16,0x2a,0x43,0x15,0x48,0x83,0x9a,0x50,0x07,0xea,
4066
0x89,0x0c,0x68,0x00,0x0d,0xa1,0x11,0x34,0x86,0x59,0xb0,0x1e,0xea,0xfe,0x44,0x3d,
4067
0x80,0xf1,0x70,0x37,0xac,0x80,0x7d,0xf0,0xa3,0x99,0x20,0xfb,0x33,0xcf,0xe1,0x50,
4068
0x0e,0xaa,0x43,0x32,0xa4,0x40,0x4b,0x68,0x05,0xd9,0x30,0x04,0x86,0xc2,0x61,0x28,
4069
0xfa,0x0b,0xf7,0x44,0x28,0x0f,0xb5,0xa0,0xbe,0x68,0x00,0x17,0x43,0x0f,0xd1,0x13,
4070
0x06,0x40,0xb6,0x18,0x08,0x8f,0xc0,0xa3,0xf0,0x18,0x4c,0x86,0x45,0xb0,0x0c,0x56,
4071
0xc0,0x2a,0x78,0x07,0xd6,0xc1,0x06,0xf8,0x08,0x72,0xcc,0xc4,0x5c,0x27,0xe0,0x14,
4072
0x80,0x42,0x50,0x11,0x2a,0x43,0x2d,0xa8,0x03,0x75,0xa1,0x3e,0xb4,0x84,0xd6,0x70,
4073
0x29,0x8c,0x84,0x43,0x90,0x11,0x08,0x38,0x43,0xe0,0x27,0x31,0x32,0x18,0x70,0x1e,
4074
0x86,0xc9,0xb0,0x16,0xb6,0x08,0xf3,0xb1,0x45,0x59,0x88,0x83,0x0c,0x68,0x20,0x32,
4075
0xa1,0x19,0x34,0x17,0xad,0xe1,0x2a,0x18,0x0a,0xd7,0xc0,0x48,0x78,0x04,0x26,0xc3,
4076
0x6b,0xb0,0x12,0xde,0x81,0x77,0xe1,0x7d,0xf3,0x01,0x47,0x64,0xc0,0x69,0x05,0xad,
4077
0xe1,0x11,0x98,0x0c,0xd3,0x60,0x26,0xac,0x87,0x8d,0xf0,0xa3,0xf9,0xc0,0x2e,0x14,
4078
0x70,0x2a,0x41,0x02,0x74,0x87,0x6c,0xb8,0x06,0x46,0xc0,0xad,0x70,0x3b,0xdc,0x0d,
4079
0xf7,0xc2,0x44,0xb8,0x1f,0xa6,0xc0,0x13,0x30,0x0b,0xe6,0xc0,0x02,0x78,0x05,0x5e,
4080
0x85,0x25,0x70,0xc0,0x7c,0xf0,0x11,0x15,0x70,0xd2,0xa2,0xc9,0x13,0xb4,0x83,0x2e,
4081
0xd0,0x0b,0x46,0xc2,0x58,0xb8,0x19,0x66,0xc2,0x6c,0x78,0xd9,0x7c,0x00,0x92,0x2f,
4082
0xe0,0x84,0x20,0x9f,0xc8,0x0f,0xa9,0x50,0x03,0x6a,0x42,0x1d,0x51,0x1f,0xda,0x41,
4083
0x17,0x18,0x0a,0x23,0xe1,0x51,0xd8,0x02,0x5f,0xc3,0x37,0xf0,0xad,0xf9,0x20,0x30,
4084
0x26,0xe0,0x94,0x82,0x72,0x90,0x0e,0x19,0xd0,0x11,0x46,0xc2,0x3c,0x58,0x04,0x8b,
4085
0xcd,0x07,0x27,0xf9,0x5d,0x02,0x10,0x01,0x21,0x88,0x82,0x82,0x50,0x04,0x8a,0x42,
4086
0x09,0x28,0x05,0xa7,0xc2,0xe9,0x90,0x0a,0x35,0xa1,0x16,0xd4,0x17,0x5d,0x60,0x04,
4087
0x8c,0x84,0x87,0x61,0x09,0xac,0x80,0x37,0x61,0x3b,0x7c,0x06,0x3b,0xcc,0xb9,0x0a,
4088
0x70,0x3c,0x64,0x40,0x3b,0xe8,0x02,0x83,0x60,0x24,0xdc,0x95,0xfb,0xe1,0x4b,0xc0,
4089
0x69,0x0a,0x23,0x61,0x36,0x2c,0x81,0xaf,0xcd,0x07,0x8d,0x85,0x02,0x4e,0x2c,0x9c,
4090
0x0d,0x95,0x20,0x01,0xd2,0x21,0x03,0x9a,0x41,0x73,0x68,0x09,0xe7,0x8b,0x56,0xa2,
4091
0x35,0xf4,0x80,0xde,0xd0,0x0f,0x06,0x88,0x6c,0x18,0x0b,0x23,0x0b,0x53,0x2f,0x60,
4092
0x3a,0x3c,0x07,0x33,0x61,0x16,0x2c,0x83,0xd7,0xe1,0x0d,0xb1,0x1c,0x56,0xc0,0x21,
4093
0xf8,0xc5,0x7c,0x48,0x59,0x24,0xe0,0x9c,0x09,0x95,0x44,0x02,0x64,0x41,0x63,0x68,
4094
0x0d,0xd9,0x30,0x0a,0x46,0xc3,0x58,0x98,0x09,0xaf,0xc3,0x16,0xf8,0xce,0x7c,0xc0,
4095
0x53,0xd4,0x25,0x20,0x82,0x22,0x02,0x6a,0x40,0x4d,0x68,0x0c,0x3d,0x61,0x00,0x64,
4096
0x8b,0x81,0x30,0x08,0x06,0xc3,0x10,0xb8,0x4a,0xdc,0x00,0xa3,0x60,0xb4,0x18,0x03,
4097
0x33,0x60,0x26,0xcc,0x86,0x39,0xf0,0x12,0xcc,0x83,0xf9,0xb0,0x40,0x63,0xbc,0xcb,
4098
0xc4,0x5a,0xd8,0x09,0xfb,0xe0,0xa0,0x49,0x5b,0x31,0xd2,0x03,0x11,0x50,0x51,0xe3,
4099
0xbf,0x55,0xa1,0x9a,0x88,0x83,0x14,0x48,0x83,0xfa,0xd0,0x48,0x64,0x41,0x63,0x68,
4100
0x22,0x5a,0xc3,0x20,0x18,0x2c,0x86,0x8a,0x91,0x30,0x0a,0x46,0x8b,0x31,0x30,0x1b,
4101
0xe6,0xc0,0x5c,0x78,0x09,0x16,0xc1,0x62,0x58,0x02,0x4b,0xe1,0x75,0x78,0x13,0xde,
4102
0x82,0xb7,0xc5,0x3b,0x62,0x2d,0x7c,0x08,0x1f,0x89,0x1c,0x61,0x3e,0x56,0x2d,0x06,
4103
0x25,0xa0,0x2a,0x54,0x83,0x78,0xa8,0x0e,0x89,0x90,0x04,0xc9,0x90,0x22,0x52,0x45,
4104
0x1a,0xd4,0x80,0x7a,0xa2,0x3e,0x64,0x40,0x03,0x31,0x12,0x6e,0x82,0x71,0xe2,0x56,
4105
0xb8,0x03,0xc6,0xc3,0x23,0xf0,0x18,0x4c,0x85,0x99,0xf0,0x09,0x6c,0x16,0x5b,0x60,
4106
0x2b,0x6c,0x83,0x5d,0xb0,0x0f,0x0e,0x9a,0x0f,0x6a,0x4b,0x50,0x0f,0x20,0x08,0x11,
4107
0x10,0x82,0x82,0x50,0x04,0x8a,0x42,0x09,0xa8,0x0c,0x55,0x20,0x01,0x92,0x20,0x19,
4108
0x52,0x21,0x1d,0x6a,0x43,0x1d,0xa8,0x2b,0xcc,0x38,0x7d,0x7d,0xc8,0x10,0x0d,0xa0,
4109
0x11,0x34,0x81,0xa6,0x1a,0xc3,0x6f,0x09,0xad,0x45,0x07,0x71,0x29,0x74,0x85,0x6e,
4110
0xd0,0x1d,0x7a,0x42,0x5f,0xc8,0x86,0x21,0x30,0x12,0x6e,0x81,0xdb,0xc4,0x9d,0x62,
4111
0x02,0xcc,0x85,0x79,0x62,0x3e,0xbc,0x0c,0xaf,0xc0,0x12,0x58,0x26,0xde,0x10,0x2b,
4112
0x60,0x15,0xbc,0x05,0x6b,0xe0,0x6d,0xf1,0x8e,0x58,0x2b,0xde,0x15,0xeb,0xc4,0x7a,
4113
0xf1,0x29,0x6c,0x35,0x1f,0xb0,0x95,0xe4,0xba,0x41,0x2a,0xd4,0x80,0x9a,0x50,0x1f,
4114
0x32,0xa0,0x01,0x64,0x42,0x23,0xc8,0x12,0x8d,0x45,0x13,0x68,0x0e,0xad,0xa1,0x23,
4115
0x5c,0x26,0x3a,0x43,0x57,0x18,0x69,0xe6,0x30,0x94,0x74,0xe7,0x37,0xcc,0x86,0x39,
4116
0x30,0x1f,0x16,0x88,0x97,0xad,0x39,0x0f,0x66,0xbe,0xc3,0x62,0x58,0x02,0x4b,0xc5,
4117
0x32,0x78,0x0d,0x5e,0x87,0x37,0x60,0x85,0x58,0x0b,0x1f,0x9a,0xf8,0x4b,0x05,0x9c,
4118
0x17,0x34,0x3f,0x62,0x16,0xcc,0x86,0xb9,0x30,0x5f,0xf3,0x25,0x5e,0x85,0x85,0xb0,
4119
0x48,0x2c,0x86,0x25,0xb0,0x11,0x36,0x41,0x0e,0x7c,0x6c,0x3e,0xdc,0x3b,0x85,0xba,
4120
0x0c,0x09,0x90,0x04,0xc9,0x50,0x0b,0x6a,0x43,0x1d,0xa8,0x2b,0xea,0x89,0xfa,0x90,
4121
0x01,0x8d,0x44,0x6b,0xe8,0x08,0x23,0xe1,0x59,0x98,0x2e,0x9e,0x13,0xcf,0x8b,0x17,
4122
0x60,0x06,0xcc,0x84,0xb9,0xf0,0x92,0x98,0x27,0xe6,0x8b,0x25,0xf0,0x26,0xac,0x85,
4123
0x6d,0xe6,0xc3,0xf0,0x53,0x03,0xce,0x19,0x70,0x96,0x28,0x23,0xca,0x8a,0x72,0x50,
4124
0x1e,0x2a,0xc0,0x39,0x50,0x51,0x54,0x82,0xaa,0x90,0x00,0xe9,0x90,0x01,0x8d,0xcd,
4125
0x07,0x8a,0xa7,0xe1,0x0f,0xd5,0x20,0x1e,0xaa,0x43,0x0d,0xa8,0x29,0xd2,0xa1,0x16,
4126
0x4c,0x86,0xcd,0xb0,0x05,0xbe,0x80,0x5f,0x20,0xea,0xf4,0x80,0x13,0x23,0x0a,0x42,
4127
0x09,0x28,0x05,0xa7,0xc0,0x69,0x50,0xfd,0x74,0x77,0x9e,0x4a,0x2a,0xd4,0xd0,0x7c,
4128
0x95,0xda,0x50,0x07,0xea,0x8a,0x7a,0xa2,0xbe,0xc8,0x10,0x0d,0x44,0xa6,0x68,0x28,
4129
0x5a,0x43,0x47,0x98,0x0c,0xcf,0xc0,0xb3,0xb0,0x16,0xde,0x85,0xf5,0xf0,0x1e,0x6c,
4130
0x80,0x8f,0x60,0x13,0xe4,0xc0,0x66,0xd8,0x22,0x3e,0x15,0xdb,0xc4,0x76,0x91,0xfb,
4131
0x71,0x3d,0x04,0x20,0x3f,0x14,0x80,0x24,0x48,0x86,0x9a,0x90,0x2e,0x6a,0x89,0xda,
4132
0x50,0x0f,0x9a,0x88,0xd6,0xa2,0x0d,0xb4,0x87,0x0e,0x70,0x11,0x74,0x84,0x4e,0x70,
4133
0x09,0xdc,0x02,0xb7,0xc2,0x7d,0x70,0xbf,0x78,0x00,0x26,0xc1,0x23,0x62,0x26,0xfc,
4134
0x00,0x5d,0x4a,0xbb,0x74,0x15,0xdd,0xe0,0x72,0xe8,0x21,0x7a,0x8a,0x5e,0x62,0x09,
4135
0x6c,0x81,0x7d,0x70,0xd0,0x7c,0x60,0x7a,0x26,0xcf,0x3d,0x90,0x1f,0xe2,0xa1,0xba,
4136
0x48,0x80,0x34,0xa8,0x09,0x75,0xa1,0x9e,0xa8,0x2f,0x32,0x44,0x6b,0xe8,0x08,0x83,
4137
0x60,0x3c,0xdc,0x0d,0xcf,0xc0,0x34,0xf1,0x2c,0xcc,0x84,0x59,0x62,0x36,0xcc,0x81,
4138
0x17,0xc5,0x5c,0x78,0xc9,0x2c,0x30,0x70,0x16,0xf5,0x04,0xf2,0x41,0x0c,0x14,0x80,
4139
0x04,0x48,0x84,0x34,0xa8,0x25,0xea,0x40,0x5d,0xa8,0x0f,0x59,0xd0,0x58,0x34,0x11,
4140
0xad,0xa1,0x23,0x74,0x81,0x1e,0xd0,0x0b,0xae,0x80,0x2b,0xe1,0x16,0xb8,0x15,0xee,
4141
0x84,0x09,0x70,0x17,0xdc,0x03,0xf7,0xc2,0x44,0x71,0x9f,0xb8,0x5f,0x3c,0x20,0x26,
4142
0xc3,0x34,0x98,0x09,0x1b,0xe1,0x43,0xf1,0x11,0x6c,0x82,0x2d,0xf0,0x85,0xd1,0x32,
4143
0x3c,0x37,0xc1,0x01,0xf8,0x06,0xbe,0x85,0xef,0xcc,0x82,0x09,0x65,0xa9,0x33,0x10,
4144
0x14,0x11,0x22,0x12,0x8a,0x42,0x71,0x48,0x86,0x14,0x48,0x85,0x34,0xa8,0x05,0xf5,
4145
0xa0,0x3e,0x64,0x88,0x06,0x22,0x53,0xb4,0x86,0x8e,0x70,0xb1,0x98,0x29,0xcc,0xe2,
4146
0x0c,0x93,0xcc,0x87,0xbc,0x67,0x07,0x9c,0xfe,0x30,0x12,0x1a,0x9e,0x43,0xbe,0xab,
4147
0x73,0xed,0x73,0x3f,0x9c,0xe5,0x3a,0xa7,0x10,0xa7,0x68,0x00,0x8d,0xa1,0x09,0xb4,
4148
0x83,0x2e,0x70,0xc8,0x2c,0x4c,0xd0,0x08,0x7f,0xf3,0xa1,0x6a,0x57,0xfa,0x11,0x28,
4149
0x03,0xe7,0x42,0x15,0xa8,0x06,0x71,0x50,0x1d,0x12,0x20,0xdd,0x7c,0xd0,0x79,0x05,
4150
0x75,0xe6,0x4a,0xe2,0x84,0xcb,0xa0,0x0b,0xf4,0x86,0x6c,0x58,0x04,0x4b,0xe0,0x4d,
4151
0x58,0x0b,0x7b,0x60,0x1f,0x7c,0x63,0x3e,0xb0,0xef,0x43,0x3c,0x90,0x00,0x69,0x90,
4152
0x01,0x0d,0xa1,0x35,0x74,0x84,0xee,0x30,0x0c,0xae,0x83,0xf1,0x66,0x7f,0x3f,0xf2,
4153
0x0f,0x0d,0xe1,0x4a,0xe8,0x03,0x7d,0x21,0x1b,0xae,0x86,0x8c,0xfe,0x3c,0x9b,0xc1,
4154
0x64,0x98,0x0f,0xaf,0xc0,0x7a,0xf3,0xa1,0xfe,0x00,0xee,0x3f,0xd0,0x4a,0xb4,0x16,
4155
0x6d,0xe0,0x66,0x18,0x0f,0x77,0xc3,0x3d,0xf0,0x18,0x6c,0x81,0x4f,0x61,0x9b,0xd8,
4156
0x2e,0xf6,0xc1,0x7e,0xf8,0x1a,0x0e,0xc0,0x37,0xf0,0x9d,0xf9,0x60,0x34,0x9b,0xdf,
4157
0x41,0xb7,0xd3,0xef,0x41,0x99,0x3b,0x28,0x77,0xf8,0x1a,0xf6,0xcd,0x20,0x1c,0x7c,
4158
0x0b,0x3f,0xc2,0x4f,0xf0,0xb3,0x59,0x10,0x60,0x26,0x7d,0xf0,0x2c,0xfa,0x10,0xd1,
4159
0x1a,0x2e,0x80,0x76,0xe2,0x72,0xe8,0x05,0xd9,0xf0,0xe3,0x6c,0x77,0xa2,0xdd,0x95,
4160
0x90,0x0d,0x23,0x60,0x24,0x8c,0x83,0x09,0x30,0x09,0x1e,0x81,0x47,0x61,0xdf,0x5b,
4161
0xb4,0x6f,0x30,0x8b,0x61,0xc4,0x41,0x02,0x34,0x86,0x1e,0xef,0xd2,0x1f,0x40,0x2f,
4162
0xe8,0x0d,0xfd,0x60,0x10,0x5c,0x0b,0xa3,0x61,0x2c,0xdc,0x06,0xcf,0xc2,0xf3,0x90,
4163
0xb9,0x8e,0xfb,0x95,0xf9,0x80,0xf8,0xbd,0x80,0x73,0x21,0xb4,0x87,0x87,0xe1,0x51,
4164
0x78,0x0c,0x1e,0x17,0x4f,0xc1,0xd3,0x30,0x0d,0x9e,0x83,0x17,0x60,0x01,0xbc,0x22,
4165
0x16,0xc2,0x6b,0xf0,0x06,0x84,0xde,0x0f,0x38,0xd1,0x90,0x1f,0x0a,0x41,0x49,0x38,
4166
0x05,0xce,0x84,0x32,0x90,0x0e,0xb5,0xa1,0x1e,0x64,0x40,0x23,0x68,0x2c,0x9a,0x43,
4167
0x6b,0xb8,0x00,0x9e,0xfa,0x80,0x67,0x3d,0x58,0x02,0xcb,0xe0,0x23,0xc8,0x81,0x43,
4168
0x70,0x18,0x4a,0x6e,0x20,0x5e,0x48,0x81,0x34,0x38,0x1f,0x5a,0x43,0x7f,0xc8,0x86,
4169
0x71,0x70,0x2b,0x4c,0x85,0x67,0x61,0x19,0xbc,0x0e,0xab,0xe1,0x6d,0xf8,0xc5,0x7c,
4170
0xf8,0xf9,0x11,0xc7,0x42,0x6d,0xe8,0x0b,0x57,0x89,0x1b,0xc5,0x43,0xf0,0x18,0x4c,
4171
0x81,0x19,0xe6,0x03,0xca,0xcd,0xf4,0x5f,0x90,0x5f,0x14,0x80,0x32,0x70,0x0e,0x54,
4172
0x31,0x1f,0x84,0x6e,0xa1,0x9f,0x83,0x7c,0x70,0x1a,0x94,0x86,0xf2,0x10,0x0b,0x67,
4173
0x43,0x45,0xa8,0x02,0x09,0xd0,0x0f,0xc6,0x0b,0xf3,0x31,0x60,0x35,0x48,0x80,0x34,
4174
0xa8,0x01,0x75,0x21,0x03,0x9a,0xc1,0xf9,0x62,0xc2,0x56,0xae,0x1b,0xbc,0x20,0x96,
4175
0xc0,0x6e,0xf8,0x12,0xf6,0xc2,0x3e,0x38,0x08,0x6b,0xb7,0xf3,0x1c,0x0c,0xbb,0xc5,
4176
0x97,0xb0,0x17,0xf6,0xc1,0x41,0x58,0xfb,0x19,0xed,0x13,0xbe,0x82,0xbd,0xb0,0x4f,
4177
0xec,0x87,0x43,0xb0,0x64,0x07,0xcf,0xd7,0xb0,0x05,0xb6,0xc2,0x36,0xb1,0x1d,0x3e,
4178
0x83,0x1d,0xe2,0x73,0xd8,0x03,0x5f,0xc1,0x5e,0xd8,0x07,0xdf,0xc0,0xb7,0xe2,0x67,
4179
0xf1,0x8b,0xd8,0xf2,0x39,0xc7,0xc1,0x4e,0xd8,0x0d,0x7b,0xe0,0x2b,0xd8,0x07,0x3f,
4180
0x9b,0x05,0x0a,0x76,0x72,0x8d,0x60,0x2d,0x7c,0x60,0x16,0x6a,0xf9,0x82,0x3e,0x00,
4181
0x1a,0x41,0x73,0x68,0x21,0x5a,0x43,0x47,0xf3,0xe1,0xff,0x57,0xf4,0xb3,0x10,0x82,
4182
0xb2,0x50,0x1e,0x2a,0xc0,0xd9,0xa2,0x92,0x38,0x17,0x92,0x20,0x05,0x6a,0x40,0xba,
4183
0xa8,0x2d,0x32,0x45,0x13,0xd1,0x4c,0xb4,0x10,0x2d,0xa1,0x15,0xb4,0x81,0x0b,0xe0,
4184
0x42,0xd1,0x41,0x74,0x14,0x9d,0xc4,0xa5,0xa2,0xb3,0xe8,0x0a,0xdd,0xe0,0x72,0xd1,
4185
0x0b,0xae,0x84,0xbe,0x30,0x08,0x86,0xc0,0x30,0xb8,0x1a,0x46,0xc0,0xf5,0x62,0x24,
4186
0xdc,0x02,0xb7,0xc1,0x43,0x30,0x05,0x9e,0x80,0xa7,0x60,0x1a,0x4c,0x87,0x57,0x60,
4187
0xdf,0x8f,0x5c,0x57,0xf3,0x21,0xb2,0x13,0x74,0x36,0x3f,0x1d,0x74,0x9c,0x67,0x82,
4188
0xce,0x59,0xf3,0x83,0x4e,0x39,0x78,0xfe,0xed,0xa0,0x33,0x13,0xb6,0xec,0x0e,0x3a,
4189
0xfb,0xe0,0x52,0x33,0x01,0xf7,0x07,0xf6,0x1f,0x72,0x27,0xe2,0x36,0x2f,0x11,0xc1,
4190
0x6f,0x95,0x08,0xe7,0xea,0x94,0x88,0xdc,0x09,0x2d,0x7b,0xc1,0x9b,0x47,0x9c,0xd7,
4191
0xfc,0xe1,0xff,0xd5,0xbc,0xe1,0xdf,0x3a,0x5f,0xf8,0x44,0xe7,0x09,0x1f,0x6f,0x7e,
4192
0xb0,0x7f,0xde,0x6f,0x5e,0xf3,0x7d,0xbd,0xf9,0xbd,0xfe,0x79,0xbd,0xde,0x3c,0x5e,
4193
0x6f,0xde,0x6e,0x5e,0xf3,0x75,0xbd,0x79,0xba,0xde,0xfc,0x5c,0x6f,0x5e,0xae,0x37,
4194
0x1f,0xd7,0x3f,0x0f,0xd7,0x9b,0x7f,0xeb,0xcd,0xbb,0xf5,0xe6,0xdb,0x7a,0xf3,0x6c,
4195
0xbd,0xf9,0xb5,0x79,0xcd,0xab,0xf5,0xcf,0xa7,0xf5,0xe6,0xcd,0x7a,0xf3,0x63,0xbd,
4196
0x79,0xaf,0xde,0x7c,0x57,0xff,0xfc,0xd6,0x93,0x9d,0xcf,0xea,0xcd,0x63,0xf5,0xe6,
4197
0xa7,0xfa,0xe7,0xa5,0xfa,0xe7,0xa1,0xfe,0xd6,0xf9,0xa6,0xfe,0xf9,0xa3,0xde,0x7c,
4198
0xd1,0x93,0x9d,0x17,0xea,0xcd,0x07,0xf5,0xcf,0xef,0xf4,0xe6,0x73,0x9e,0xec,0xbc,
4199
0x4d,0x6f,0xbe,0xa6,0x7f,0x9e,0xa5,0x37,0xaf,0xf2,0x8f,0x9e,0x4f,0xe9,0xcd,0x8f,
4200
0x3c,0xde,0xbc,0x47,0x6f,0xbe,0x63,0x5e,0xf3,0x18,0xbd,0x79,0x8b,0x27,0x3a,0x4f,
4201
0xd1,0x9b,0x9f,0xe8,0x9f,0x5f,0xe8,0xcd,0x27,0xcc,0x6b,0xde,0xa0,0x37,0x5f,0xd0,
4202
0x3f,0x0f,0xd0,0x9b,0xff,0xe7,0xcd,0xf7,0x3b,0xd1,0xf9,0x7d,0xde,0x3c,0x3d,0x6f,
4203
0x7e,0x9e,0x7f,0x5e,0xde,0xc9,0xce,0xc3,0xf3,0xe6,0xdf,0xe5,0x35,0xef,0xce,0x3f,
4204
0xcf,0xce,0x3f,0x6f,0xce,0x9b,0x17,0xe7,0xcd,0x7f,0xf3,0xe6,0xaf,0x79,0xf3,0xd6,
4205
0xbc,0x79,0x6a,0xde,0xfc,0x34,0x6f,0x5e,0x9a,0x37,0x1f,0xcd,0x9b,0x87,0xe6,0xcd,
4206
0x2f,0xfb,0xbb,0xcd,0x1f,0xfb,0xa3,0xe7,0x8b,0x79,0xf3,0xc3,0xbc,0xf9,0x60,0xfe,
4207
0x79,0x60,0xde,0xfc,0x2f,0xff,0x3c,0xae,0x93,0x9d,0x9f,0x95,0xd7,0xbc,0xac,0xe3,
4208
0xcd,0xa7,0xf2,0xe6,0x4f,0x79,0xf3,0xa4,0xbc,0x79,0x4b,0xde,0x7c,0x24,0x6f,0x3e,
4209
0x91,0x37,0x5f,0xc8,0x9b,0xff,0xe3,0xcd,0xfb,0xf1,0xe6,0xed,0x78,0xf3,0x71,0x4e,
4210
0x74,0x1e,0x8e,0x37,0xcf,0xc6,0x9b,0x5f,0xe3,0xcd,0xab,0xf9,0xad,0xf3,0x68,0xfe,
4211
0xaa,0xf3,0x67,0xf2,0x9a,0x27,0xf3,0x77,0x9f,0x0f,0x73,0xb2,0xf3,0x60,0xfe,0xa8,
4212
0xf9,0x2f,0xc7,0x9b,0xf7,0x72,0xa2,0xf3,0x5c,0x8e,0x37,0xbf,0xe5,0x7f,0x35,0xaf,
4213
0x25,0xaf,0xf9,0x2c,0x79,0xcd,0x5f,0xf1,0xcf,0x5b,0xf9,0xb3,0xe7,0xab,0x78,0xf3,
4214
0x54,0xbc,0xf9,0x29,0xde,0xbc,0x14,0x6f,0xde,0x89,0x37,0xdf,0x24,0xaf,0xf9,0x24,
4215
0xde,0xfc,0x11,0x6f,0xde,0x88,0x37,0x4f,0xc4,0x9b,0x17,0xe2,0xcd,0xf3,0xf0,0xe6,
4216
0x77,0xf8,0xe7,0x75,0xf8,0xe7,0x73,0x78,0xf3,0x34,0xbc,0xf9,0x19,0xc7,0x9b,0x87,
4217
0xe1,0xcd,0xb7,0xf0,0xe6,0x59,0x78,0xf3,0x2b,0xbc,0x79,0x15,0xde,0x7c,0x8a,0xe3,
4218
0xcd,0xa3,0xf0,0xcf,0x97,0xf8,0x6f,0xcd,0x8f,0xf8,0xbd,0xf3,0x1b,0xfe,0x5b,0xf3,
4219
0x1a,0xfc,0xf3,0x16,0xbc,0xf9,0x0a,0xde,0x3c,0x85,0xbf,0xca,0xfc,0x04,0xff,0xbc,
4220
0x84,0x93,0x9d,0x8f,0x70,0xb2,0xf3,0x10,0xc2,0xf3,0x0f,0x8e,0x3d,0xff,0x20,0xaf,
4221
0x79,0x06,0xc7,0x9b,0x57,0xf0,0x7b,0xe7,0x13,0x1c,0x6f,0xde,0x40,0x5e,0xf3,0x05,
4222
0x8e,0x37,0x4f,0x20,0xaf,0xf9,0x01,0xde,0xbc,0x00,0xff,0x7c,0x00,0x6f,0xdc,0xdf,
4223
0x1b,0xdf,0xf7,0xc6,0xf5,0xbd,0x71,0x7c,0x6f,0x7c,0xde,0x1b,0x8f,0xf7,0xc6,0xdb,
4224
0xfd,0xe3,0xec,0xde,0xf8,0xba,0x37,0x9e,0xee,0x8d,0x9b,0x1f,0x6f,0x5c,0xdc,0x1b,
4225
0xdf,0x3e,0xd9,0x71,0xed,0x93,0x1d,0xa7,0xf6,0xc6,0xa7,0xbd,0x71,0x67,0x6f,0xbc,
4226
0xf9,0x44,0xc7,0x95,0xbd,0xf1,0x60,0x6f,0x1c,0xd8,0x1b,0xff,0xf5,0xc6,0x73,0xfd,
4227
0xe3,0xb7,0xfe,0xf1,0x57,0x6f,0xdc,0xd5,0x1b,0x47,0xf5,0xc6,0x4f,0xbd,0xf1,0x50,
4228
0x6f,0x1c,0xd4,0x1b,0xcf,0xf4,0xc6,0x2f,0xfd,0xe3,0x8f,0xde,0xf8,0xe2,0x89,0x8e,
4229
0x2b,0x7a,0xe3,0x85,0xde,0x38,0xa1,0x7f,0x3c,0xd0,0x3f,0xce,0xe7,0x8d,0xef,0x79,
4230
0xe3,0x7a,0xde,0x38,0x9e,0x37,0x6e,0xe7,0x8d,0xcf,0xf9,0xc7,0xe1,0xbc,0x71,0x35,
4231
0xff,0x78,0x9a,0x37,0x4e,0xe6,0x8d,0x8f,0xe5,0x35,0xce,0xe5,0x8d,0x63,0xe5,0x35,
4232
0x6e,0xe5,0x8d,0x43,0xe5,0x39,0xfe,0xa4,0x71,0x27,0x6f,0x7c,0xc9,0x3f,0xae,0x74,
4233
0xb2,0xe3,0x42,0xde,0x78,0x50,0x5e,0xe3,0x40,0xfe,0x71,0x1e,0x6f,0x7c,0xc7,0x1b,
4234
0xd7,0xf1,0xc6,0x73,0xbc,0x71,0x9c,0x13,0x1d,0xbf,0x39,0xde,0xb8,0x8d,0x37,0x5e,
4235
0x93,0xd7,0xf8,0xcc,0x5f,0x6d,0x3c,0xe6,0xdf,0x36,0x6e,0x72,0xbc,0xf1,0x0f,0x6f,
4236
0x5c,0xc3,0x1b,0xcf,0xf0,0xc6,0x31,0xfc,0xe3,0x17,0xde,0xb8,0x85,0x7f,0x9c,0xc2,
4237
0x1b,0x97,0xf0,0xc6,0x23,0xfc,0xe3,0x10,0xde,0xf8,0x83,0x37,0xee,0xe0,0x8d,0x37,
4238
0xfc,0xd6,0x71,0x06,0x6f,0x7c,0xc1,0x1b,0x57,0x08,0x8f,0x27,0xb8,0xe3,0x09,0xbf,
4239
0x7b,0x1c,0xc1,0xac,0x3d,0x0b,0xf9,0xc1,0xfb,0x0c,0xbb,0x10,0x14,0x76,0x5f,0x65,
4240
0x98,0x25,0x16,0x1d,0x7e,0x9e,0x3b,0xe6,0x27,0x70,0x2c,0x54,0x84,0xaa,0xee,0xcf,
4241
0x61,0xf3,0x53,0xd7,0x89,0x07,0xb3,0xa6,0x49,0x2d,0xa8,0xad,0x75,0x4d,0x3a,0x69,
4242
0x3c,0xe2,0x5a,0xb8,0x01,0xc6,0xc2,0x4d,0xc0,0x4f,0x3f,0x67,0x0a,0x3c,0x0e,0x4f,
4243
0x6b,0x9c,0xc2,0x3c,0xc2,0x3f,0x0f,0x2f,0xc0,0x4c,0x98,0x0d,0x2f,0x6a,0xec,0xe2,
4244
0x25,0x58,0xa0,0xf1,0x8b,0x57,0x34,0x86,0xb1,0x41,0x63,0x18,0xdf,0x6b,0x0c,0x63,
4245
0x01,0x59,0x7a,0x05,0x96,0xc1,0x5a,0x58,0xa7,0x31,0x89,0xcf,0x34,0x0e,0xb1,0x57,
4246
0x6b,0x98,0x64,0x5b,0xe3,0x10,0x66,0xfc,0xe1,0x7a,0x8d,0x3b,0xdc,0x68,0xad,0x53,
4247
0x32,0xce,0x1a,0x73,0x30,0xe3,0x0d,0xdf,0x69,0xbc,0x61,0x8c,0xc6,0x1b,0x12,0x35,
4248
0xc6,0x70,0x2b,0xdc,0x01,0xe3,0xb5,0x0e,0xc9,0x22,0xad,0x41,0xb2,0x44,0xeb,0x90,
4249
0xbc,0xa6,0x75,0x48,0x96,0x5b,0x6b,0x90,0x98,0x71,0x08,0x27,0x8a,0x7f,0x90,0x0f,
4250
0x62,0xa0,0x00,0x14,0x84,0x42,0x50,0x38,0xca,0x5d,0x9b,0xa4,0x34,0x94,0xd1,0x3a,
4251
0x24,0x66,0x0d,0x92,0x2b,0xa1,0x0f,0xf4,0xb3,0xd6,0x1f,0x31,0x6b,0x8e,0x7c,0x0c,
4252
0x9f,0x68,0xdd,0x91,0xcf,0xb4,0xde,0xc8,0x17,0x5a,0x6f,0xe4,0x2b,0xad,0x33,0x62,
4253
0xc6,0x2c,0x8a,0x58,0xeb,0x89,0x24,0x68,0x9c,0xe2,0x69,0x6b,0xed,0x90,0xdd,0x1a,
4254
0xa3,0xf8,0xce,0x5a,0x27,0xe4,0xe7,0x68,0x77,0x7d,0x10,0x6f,0x5d,0x10,0x6f,0x3d,
4255
0x10,0x6f,0x1d,0x90,0x04,0x8d,0x53,0x98,0x35,0x40,0x2e,0xd3,0x58,0x85,0x19,0x97,
4256
0x78,0x09,0xd6,0xc3,0x56,0xad,0xef,0x11,0x61,0xad,0xe5,0xe1,0xad,0xe1,0xd1,0x40,
4257
0x6b,0x76,0x78,0x6b,0x75,0xb4,0xd1,0x58,0x85,0x59,0x97,0xe3,0x72,0x6b,0xed,0x8d,
4258
0xb1,0x1a,0xa3,0xb8,0x47,0x63,0x13,0xde,0x98,0x84,0xb7,0xb6,0xc6,0x52,0xad,0xa5,
4259
0xb1,0xda,0x5a,0x3f,0xc3,0x5b,0x37,0x63,0xb3,0xd6,0xcb,0x30,0x6b,0x65,0x7c,0x0d,
4260
0xdf,0xc0,0x8f,0xd6,0x3a,0x19,0x01,0x6b,0x6d,0x8c,0x22,0x1a,0xa3,0xa8,0xa2,0xb1,
4261
0x89,0x54,0x8d,0x49,0x78,0x6b,0x5f,0x34,0xd0,0x9a,0x17,0x2d,0xac,0x75,0x2e,0xbc,
4262
0xf5,0x2d,0xb2,0x35,0x4e,0x61,0xd6,0xb3,0x18,0xaa,0x35,0x2d,0xbc,0xb5,0x2c,0xc6,
4263
0x6b,0xac,0xe2,0x59,0x8d,0x51,0xcc,0xb5,0xd6,0xab,0x58,0xaa,0xf5,0x29,0xbc,0x75,
4264
0x29,0xd6,0x58,0x63,0x15,0x5b,0xb5,0x06,0xc5,0x7e,0x6b,0xfd,0x09,0x6f,0xdd,0x89,
4265
0x90,0xc6,0x2d,0x4a,0x68,0xbc,0x22,0x49,0xe3,0x14,0xde,0xba,0x12,0xf5,0xad,0x35,
4266
0x24,0x9a,0x68,0xed,0x08,0x6f,0xcd,0x08,0x6f,0xad,0x88,0xce,0x5a,0x23,0xa2,0xa7,
4267
0xb5,0x1e,0xc4,0x58,0x8d,0x5b,0xdc,0xad,0xf1,0x0a,0x6f,0x9c,0xe2,0x09,0x8d,0x4f,
4268
0xbc,0xa0,0x75,0x1e,0xbc,0xf5,0x1d,0x96,0x6b,0x5d,0x87,0x35,0xd6,0x5a,0x0e,0x66,
4269
0x1d,0x87,0x03,0x70,0x10,0x0e,0x15,0x38,0xb2,0x96,0x83,0xb7,0x86,0x43,0x61,0x8d,
4270
0x61,0x54,0xb1,0xd6,0x69,0x68,0xa0,0xf5,0x19,0x9a,0x6b,0x5d,0x86,0x8b,0x34,0x7e,
4271
0xd1,0x4d,0xeb,0x2f,0x0c,0x83,0xe1,0x70,0x83,0xb5,0xf6,0xc2,0x9d,0x1a,0xc3,0x78,
4272
0x56,0x63,0x17,0xde,0xda,0x0a,0xcb,0xb5,0x66,0xc2,0x5b,0x5a,0x2b,0xc1,0x1b,0xc3,
4273
0xd8,0xaa,0xb5,0x11,0xf6,0xab,0x63,0x0b,0x6a,0x0c,0xa3,0xb8,0xd6,0x3c,0xa8,0xab,
4274
0x35,0x0e,0x1a,0x6b,0x6d,0x83,0x96,0xd6,0x38,0x46,0x37,0xad,0x5b,0xe0,0xad,0x53,
4275
0x30,0x56,0xe3,0x17,0x73,0xac,0x31,0x0b,0x6f,0x2d,0x82,0x75,0xd6,0xfa,0x03,0x3b,
4276
0xb4,0xee,0x40,0xc0,0x5a,0x6b,0xc0,0xac,0x33,0x50,0x5f,0xe3,0x19,0x66,0x6d,0x81,
4277
0x56,0x1a,0xcb,0xf0,0xc6,0x30,0x6e,0xb7,0xc6,0x2d,0xbc,0x75,0x03,0x5e,0xb4,0xc6,
4278
0x2c,0xbc,0x35,0x02,0xd6,0x6a,0xcc,0xc2,0x5b,0x13,0xe0,0x0c,0xad,0x03,0x90,0xa6,
4279
0x75,0x00,0x6a,0x6a,0x1d,0x80,0x5a,0x5a,0x0b,0xa0,0x99,0xbe,0xfd,0xf7,0xbe,0xf9,
4280
0x1f,0xab,0x6f,0xfe,0xc7,0xe9,0x5b,0x7f,0xf3,0x9d,0xff,0x22,0x7d,0xe3,0xbf,0x02,
4281
0xde,0xd6,0x58,0x47,0x9c,0xf5,0x5d,0xbf,0xf7,0x3d,0x7f,0x6d,0x7d,0xc7,0x5f,0x5f,
4282
0xdf,0xe9,0x5f,0xac,0xef,0xf3,0xbb,0xea,0xbb,0xfb,0xab,0xac,0x6f,0xed,0xc7,0xea,
4283
0x1b,0x7b,0xef,0xdb,0x7a,0xf3,0xed,0xfc,0xa3,0xd6,0x98,0x87,0x19,0xef,0x68,0xae,
4284
0xf1,0x0c,0x6f,0x1c,0xa3,0x8b,0xc6,0x2f,0x26,0x68,0xdc,0x62,0xbe,0x35,0x56,0xb1,
4285
0x52,0x63,0x14,0xc5,0x35,0x36,0x61,0xbe,0x6b,0xef,0xa2,0xf1,0x89,0x09,0x1a,0x9f,
4286
0x30,0x63,0x13,0x4e,0x49,0x77,0x6c,0x62,0xa4,0xc6,0x24,0x1e,0xd2,0x98,0x84,0x19,
4287
0x7f,0x28,0xac,0xef,0xd5,0xcb,0xe9,0xfb,0xf4,0x54,0x8d,0x43,0x5c,0xa0,0x71,0x88,
4288
0xfe,0xff,0x57,0xd9,0xb9,0x40,0x47,0x59,0x98,0x69,0x78,0x26,0x4c,0x92,0x49,0xc2,
4289
0x25,0x56,0x11,0xaf,0x88,0x82,0x02,0xa2,0x24,0x87,0x84,0x8b,0x5c,0xe3,0x0a,0xca,
4290
0xd9,0x2e,0x27,0x41,0x2b,0x95,0x65,0x95,0xb8,0x8a,0x56,0x6a,0x0b,0xd5,0x54,0xad,
4291
0x5a,0x8c,0xa0,0x45,0x50,0x2c,0xa7,0xab,0xed,0xd1,0xe2,0x82,0x6b,0xbd,0x50,0x45,
4292
0xc2,0xa2,0xd6,0xae,0x0a,0x51,0xcb,0x6a,0xab,0x14,0x14,0xad,0xbb,0x5a,0x05,0xb4,
4293
0xed,0x52,0x95,0xca,0x4d,0x91,0x9b,0xd9,0xf7,0x9b,0xff,0xf9,0x92,0x2f,0x63,0x50,
4294
0x3b,0x39,0x6f,0x12,0x26,0x21,0x33,0xf9,0x33,0x13,0x7e,0xde,0xef,0x7d,0x9f,0x8f,
4295
0x1e,0x7a,0x23,0xfd,0x73,0xef,0x9d,0xaf,0x0a,0x5d,0x73,0xeb,0x99,0xbf,0x26,0xbd,
4296
0x15,0xfa,0xe5,0xd6,0x2d,0xdf,0x26,0xa5,0x8e,0x48,0xfa,0xe5,0x5d,0xe9,0x95,0xf7,
4297
0x62,0x3e,0x71,0x33,0x73,0x89,0xa5,0x61,0x26,0x91,0xa2,0x23,0xde,0x9b,0x6e,0x78,
4298
0x7f,0x3a,0xe1,0xde,0x05,0xb7,0x1e,0x78,0x8d,0x34,0x96,0x2e,0xf8,0x4c,0x66,0x15,
4299
0x4d,0x74,0xbe,0xdf,0x61,0x56,0xd1,0x83,0x8e,0xb7,0x75,0xbb,0x7b,0x86,0x2e,0xf7,
4300
0x79,0xa1,0xbf,0xed,0xbd,0xed,0x69,0xf4,0xb5,0xaf,0x0c,0x1d,0x6d,0xeb,0x67,0x2f,
4301
0xa1,0x97,0x9d,0xa2,0x7b,0x5d,0x1d,0xba,0xd6,0x23,0x42,0xbf,0xda,0x7b,0xd5,0x75,
4302
0xf4,0xa8,0x1b,0xe8,0x51,0xcf,0xa6,0x2f,0xfd,0x00,0x3d,0x69,0xef,0x47,0x3f,0x1a,
4303
0x3a,0xd0,0x5b,0xe8,0x3e,0x6f,0x0d,0x7d,0x67,0xeb,0x3a,0xef,0x3f,0x3a,0xe9,0x36,
4304
0x57,0xd3,0x69,0x1e,0xc1,0xec,0x64,0x21,0xb3,0x11,0xeb,0x27,0x6f,0xa0,0x9f,0xec,
4305
0xbd,0xe4,0xbf,0x86,0x2e,0xb2,0x77,0x90,0x3f,0x0d,0x73,0x12,0xeb,0x10,0xef,0x63,
4306
0x06,0x72,0x04,0xb3,0x8f,0xf1,0xcc,0x3c,0x26,0x87,0x39,0xc7,0x54,0xe6,0x1b,0x36,
4307
0xdb,0x78,0x86,0xb9,0xc6,0x6a,0x66,0x1b,0x36,0xd7,0x58,0xcb,0x5c,0xc3,0x66,0x1a,
4308
0x6f,0x33,0xd3,0xd8,0xca,0x4c,0xc3,0xe6,0x19,0x07,0x38,0x39,0x2a,0x93,0xba,0x4a,
4309
0xdd,0xa4,0x72,0xa9,0x9f,0xd4,0x5f,0x3a,0x59,0x1a,0x20,0x9d,0x22,0x9d,0x2a,0x0d,
4310
0x94,0x2a,0xa4,0x4a,0x69,0xb0,0x34,0x56,0x1a,0x27,0x4d,0x95,0xea,0xa5,0x4b,0xa4,
4311
0x4b,0xa5,0x6f,0x49,0x97,0x49,0xd3,0xa5,0x99,0xcc,0x4b,0x1a,0xa4,0x6b,0xa5,0xeb,
4312
0x99,0x9b,0x34,0x4a,0xf3,0xa5,0xdb,0x98,0xa1,0x2c,0xa1,0x6b,0x9c,0x62,0x8e,0xd2,
4313
0x89,0x39,0x4a,0x96,0x59,0xca,0x61,0xcc,0x51,0x0e,0x67,0x86,0xd2,0x93,0xf9,0xc9,
4314
0x89,0xcc,0x4f,0xfa,0x32,0x3f,0xe9,0xcf,0x0c,0xc5,0x67,0x27,0xc3,0x99,0x95,0xd4,
4315
0x30,0x2b,0xf9,0x47,0xe6,0x24,0x75,0xcc,0x4a,0xe6,0x49,0x0b,0xa5,0xaf,0x9d,0xa0,
4316
0x7f,0x97,0xa4,0xc3,0xa4,0x21,0x3a,0x51,0xbc,0x4e,0xba,0x53,0xfa,0xa9,0x54,0xd3,
4317
0x47,0x9f,0x2b,0xdd,0x22,0x2d,0x92,0xde,0x97,0x1e,0xd1,0x89,0xe4,0x32,0x3b,0x99,
4318
0xec,0x27,0xf5,0xd7,0xbf,0x9f,0x3a,0xa9,0xfc,0x19,0x27,0x96,0x95,0x52,0xbd,0xf4,
4319
0x67,0xe6,0x2b,0x1f,0x31,0x5f,0xd9,0xc3,0x49,0x67,0xdf,0x30,0x53,0x99,0x11,0xfa,
4320
0xc4,0x4b,0x98,0xa3,0x34,0x31,0x3f,0x69,0x66,0x6e,0xb2,0x9e,0x79,0xc9,0x26,0x4e,
4321
0x58,0x1b,0xa5,0x9f,0xdb,0x89,0x6b,0x85,0x9e,0xb7,0x15,0xc9,0x09,0x6c,0x9a,0x39,
4322
0x4a,0x96,0xd9,0xc9,0xc9,0x74,0x85,0x2b,0x99,0xa1,0x0c,0x61,0x86,0x32,0x8a,0x99,
4323
0xc9,0x5d,0xcc,0x4c,0x6c,0x5e,0xb2,0x84,0x39,0x89,0xf7,0x7f,0x0b,0x99,0x8b,0x2c,
4324
0x94,0x9a,0x99,0x89,0x1c,0x3b,0x48,0x0f,0x15,0xa9,0x4e,0xaa,0x97,0xae,0x97,0x6e,
4325
0x90,0x56,0x48,0xcd,0xd2,0xcb,0xd2,0x7a,0xe9,0xea,0x2a,0x1d,0x3b,0xe9,0x1d,0x69,
4326
0x93,0xd4,0x52,0x95,0xcc,0x52,0x9a,0x99,0xa5,0xd8,0x49,0xf4,0x42,0xe6,0x27,0x5d,
4327
0x98,0x93,0xd4,0xd0,0xed,0xbd,0x92,0x7e,0xef,0x2c,0xe6,0x22,0xff,0xce,0x3c,0xc4,
4328
0xba,0xbb,0x3b,0xec,0x84,0x9b,0x39,0x88,0xcd,0x3b,0xe6,0x49,0xcf,0x31,0xd7,0xf0,
4329
0x7e,0xad,0xf7,0x6a,0xbd,0x4f,0x7b,0x22,0xdd,0xd9,0x7e,0x74,0x67,0x2b,0xa5,0x61,
4330
0xcc,0x32,0x1a,0xe8,0xd0,0x5a,0x5f,0xf6,0xf7,0xf4,0x64,0x77,0x84,0x2e,0xac,0xf5,
4331
0x5f,0x07,0xd2,0x7b,0xb5,0xce,0xeb,0x54,0xba,0xae,0x73,0x42,0xaf,0xf5,0x09,0xfa,
4332
0xac,0x4f,0xd3,0x63,0xb5,0xb9,0xc6,0x3b,0xa1,0xaf,0x9a,0xa2,0x8f,0x5a,0x41,0x0f,
4333
0xb5,0x8a,0xfe,0x69,0x4d,0xe8,0x9c,0xfe,0x53,0xe8,0x99,0xfe,0x4b,0xe8,0x8e,0x36,
4334
0x85,0x9e,0xe8,0xe3,0xf4,0x43,0x7f,0x4d,0x2f,0xb4,0x39,0x74,0x41,0xdf,0xa2,0xeb,
4335
0xf9,0xb7,0xd0,0xe3,0x2c,0x61,0x3e,0xd1,0x8b,0xb9,0x84,0xcd,0x24,0xa6,0x33,0x7b,
4336
0xf0,0x0e,0xa6,0x77,0x2f,0xbd,0x6b,0x69,0x73,0x88,0x26,0xe6,0x0f,0xf6,0x1f,0x94,
4337
0x99,0xcc,0x1c,0x0e,0x0d,0x3d,0x4a,0x9b,0x35,0xf4,0x67,0xd6,0x30,0x2c,0xcc,0x17,
4338
0xce,0x60,0xae,0x50,0xc7,0x5c,0x61,0x34,0x73,0x85,0x9f,0x30,0x4f,0x38,0x40,0x4f,
4339
0xb2,0x9c,0x9e,0x64,0xa5,0x54,0x27,0x4d,0x94,0xce,0x96,0xbe,0x21,0x9d,0x2b,0x4d,
4340
0x92,0xa6,0x4a,0xf5,0xd2,0xbf,0x4a,0x17,0x4b,0xdf,0x92,0x2e,0x93,0xbe,0x4d,0x97,
4341
0xd2,0xe6,0x11,0x2d,0x52,0xba,0x45,0x3f,0x73,0xa9,0x48,0x2a,0x93,0x3a,0x4b,0x5d,
4342
0xa4,0xae,0x2d,0x49,0xc7,0xf2,0x28,0xe9,0x68,0x7a,0x96,0x23,0x98,0x5b,0x4c,0x61,
4343
0x6e,0xf1,0x1c,0xf3,0x88,0x57,0x99,0x43,0x6c,0x92,0xde,0x95,0xfe,0x2c,0x6d,0x91,
4344
0xf6,0x30,0x97,0xe8,0xc2,0x3c,0x62,0x24,0x73,0x88,0x3a,0xe6,0x0f,0xb6,0x68,0x2a,
4345
0x2d,0x15,0x48,0xc5,0xd2,0xd0,0x74,0x32,0x8f,0x58,0x20,0x2d,0x94,0x96,0x48,0xeb,
4346
0x43,0x6f,0x72,0x09,0x5d,0xc9,0xcd,0xcc,0x27,0x4e,0x65,0xfe,0x70,0x15,0xf3,0x87,
4347
0xc5,0xcc,0x1d,0x52,0xf4,0x1c,0x9b,0x98,0x2f,0xa4,0x98,0x2b,0xcc,0x60,0x1e,0x50,
4348
0xc3,0x1c,0x20,0x15,0x3c,0xfe,0xa1,0xc1,0xd7,0xff,0xa6,0xf4,0x20,0x5e,0xbe,0xf9,
4349
0xf8,0xfb,0xa4,0xe3,0xf0,0xf0,0xc7,0xe0,0xdd,0x3f,0x2d,0xbd,0x5a,0x92,0xf4,0x05,
4350
0x0b,0xe9,0x09,0x96,0xe3,0xdb,0x1f,0x49,0x2f,0xd0,0xfa,0x80,0x35,0x52,0x1d,0xfe,
4351
0x7d,0x33,0xfd,0xbf,0x0f,0xf0,0xeb,0x4f,0xc3,0xaf,0x3f,0x4f,0xba,0x46,0xba,0x4b,
4352
0x5a,0x8a,0x57,0xdf,0x88,0x47,0xbf,0x17,0x8f,0xbe,0x0f,0x5d,0xbf,0xfa,0xae,0x89,
4353
0xf7,0x6e,0x3d,0xbd,0x65,0xf8,0xef,0x29,0x7c,0x75,0xeb,0xdc,0x4d,0xc4,0x53,0xdf,
4354
0xd4,0xad,0xad,0x57,0x57,0x40,0x8f,0xee,0x2c,0xe9,0x6c,0xba,0x74,0x37,0xd0,0x8f,
4355
0x5b,0x49,0x17,0xce,0x7a,0x70,0x4f,0x49,0x6b,0xf1,0xd8,0xb7,0xd1,0x7d,0xeb,0x44,
4356
0xe7,0xcd,0xbb,0x6e,0x43,0xf0,0xd8,0xad,0xc3,0xd6,0x40,0x7f,0x6d,0x36,0x3d,0xb5,
4357
0xd5,0xf4,0xd2,0xd6,0x86,0x2e,0xda,0x66,0x3c,0xf6,0x43,0xe9,0x9a,0x0d,0x0a,0xfd,
4358
0x32,0xeb,0x96,0x0d,0xa3,0x57,0xd6,0x18,0x7c,0xf6,0x1f,0xe3,0xaf,0x37,0x85,0xae,
4359
0xd8,0x7b,0x74,0xc4,0x52,0x74,0xc3,0x0a,0xf1,0xda,0x0f,0xc5,0x63,0x1f,0x84,0xb7,
4360
0x3e,0x02,0x5f,0xdd,0xbb,0x5e,0x67,0xd1,0xf1,0xaa,0x0b,0xbd,0xae,0x4b,0xe8,0x71,
4361
0xa5,0xe8,0x49,0xd5,0xd0,0x8f,0x1a,0x17,0x3a,0x51,0xe7,0x87,0x1e,0x54,0x23,0xbd,
4362
0xa7,0x5f,0x87,0xae,0xd3,0xea,0xd0,0x6f,0xfa,0x0d,0x7d,0xa6,0x46,0xfa,0x4b,0x4f,
4363
0xd2,0x5b,0xf2,0xbe,0xd2,0xb3,0xf4,0x94,0x52,0xf4,0x92,0x46,0x84,0x2e,0x92,0xf5,
4364
0x90,0x4e,0xa7,0x7f,0x54,0x8f,0xef,0xfe,0x70,0xe8,0x1c,0x3d,0x4a,0xd7,0xe8,0x89,
4365
0xd0,0x2f,0x6a,0xc6,0x8f,0x3f,0x96,0xde,0xd0,0x09,0xa1,0x2b,0x54,0x89,0x37,0x5f,
4366
0x11,0x7a,0x40,0x23,0xf0,0xe9,0xcd,0xa3,0x77,0x6f,0xbe,0x3b,0x9e,0xfc,0x50,0xba,
4367
0x3d,0xa3,0x42,0x9f,0xc7,0xfa,0x3a,0x63,0xe9,0xec,0x2c,0xc1,0x9b,0x7f,0x8d,0x6e,
4368
0xce,0x1f,0x43,0x1f,0xc7,0x7b,0x37,0xc5,0x52,0x09,0x1e,0x7d,0x15,0x7d,0x1b,0xeb,
4369
0xd9,0x8c,0x09,0x1d,0x9b,0x89,0x74,0x6b,0x26,0xe3,0xd9,0xcf,0x0f,0x3d,0x9a,0xbb,
4370
0xcd,0xaf,0x3f,0x2a,0xf1,0xea,0x4b,0xe9,0xba,0x0c,0xa3,0xdf,0x62,0x7d,0x96,0x99,
4371
0xf4,0x58,0xbc,0xbf,0xe2,0xbd,0x15,0xef,0xab,0xa4,0xf0,0xef,0xcb,0xe8,0xa7,0x78,
4372
0x2f,0x65,0x4c,0xe8,0xa2,0xd4,0xe1,0xe5,0x5f,0x8a,0x87,0xbf,0x90,0xae,0xc9,0x9d,
4373
0xa1,0x5f,0xe2,0xbd,0x92,0x4d,0xf4,0x45,0xac,0x2b,0x62,0x1e,0x7d,0xb3,0xf4,0xba,
4374
0xf4,0xb6,0xb4,0x59,0x6a,0x39,0x2e,0xf1,0xeb,0x67,0xe2,0xd7,0x9b,0x47,0x5f,0x59,
4375
0x9d,0x78,0xf2,0xe6,0xc3,0xd7,0xd0,0xb3,0xf8,0x2e,0xfe,0xbb,0x75,0x2a,0x3e,0xc6,
4376
0x83,0xb7,0x3e,0xc5,0x50,0x7a,0x14,0x53,0xf0,0xe1,0xcd,0x83,0xaf,0xc1,0x53,0xf7,
4377
0x0e,0xc4,0x8f,0xf1,0xd4,0xcd,0x4f,0x7f,0x37,0x74,0x1d,0xb6,0xe1,0xa1,0xa7,0x6e,
4378
0x91,0x16,0x24,0xfe,0x78,0x1d,0x3e,0xb8,0x79,0xe0,0x29,0xbc,0xef,0x46,0x3c,0xef,
4379
0x45,0x74,0x10,0x16,0x4b,0x4b,0xcc,0xff,0xb6,0x25,0x6e,0xaf,0xa4,0x53,0xfd,0xe9,
4380
0x1c,0x4c,0x97,0xae,0xa4,0x6f,0x30,0x87,0xbe,0xc1,0x6d,0xf4,0x0d,0x1e,0xb5,0xc5,
4381
0x93,0xaf,0x26,0x9d,0x83,0x71,0xd2,0x26,0xeb,0x1d,0x6c,0xd0,0xf7,0xb6,0x21,0xf1,
4382
0xd1,0x27,0xe1,0x9f,0xbb,0x6f,0xbe,0x14,0xbf,0xdc,0x7d,0x72,0xf3,0xc8,0x8b,0xf1,
4383
0xc6,0x0f,0xc7,0x13,0x1f,0x81,0x17,0xee,0x1e,0xb8,0xf9,0xdf,0xe6,0x7d,0xbf,0x85,
4384
0xe7,0xdd,0x1d,0xaf,0xbb,0x16,0x8f,0x7b,0x1e,0xde,0xf6,0xf3,0x78,0xda,0xd6,0x03,
4385
0xc8,0x2d,0x4a,0x7a,0x53,0xc7,0x91,0x1e,0xc0,0x77,0xe8,0x00,0x5c,0x45,0x07,0xe0,
4386
0x66,0x7a,0x00,0xd6,0x01,0x48,0x91,0xed,0x3f,0x9a,0x4c,0xff,0x49,0x78,0xdd,0x95,
4387
0x78,0xdd,0x35,0xf8,0xdc,0xcd,0x64,0xf2,0x2d,0x8f,0xdf,0xf2,0x6e,0xe2,0x37,0xbf,
4388
0x40,0xae,0x3d,0x45,0x9e,0xdd,0x73,0xec,0x17,0x48,0xdf,0xfb,0x50,0x8f,0xfd,0xad,
4389
0x89,0xff,0x5c,0x88,0xef,0xdc,0x27,0x78,0xcd,0xd5,0xc1,0x5f,0xfe,0x87,0xe0,0x29,
4390
0xbb,0x97,0x3c,0x31,0xf8,0xc7,0x93,0x83,0x67,0xec,0x5e,0xb1,0x7b,0xc4,0x97,0xe3,
4391
0x0d,0xff,0x20,0xf8,0xc1,0xb7,0xe2,0x03,0xdf,0x8f,0xff,0xbb,0xcd,0xfc,0xdf,0x6d,
4392
0xfa,0x9e,0xa4,0x25,0xd2,0x0a,0xe9,0x59,0xe9,0x15,0x5b,0xbc,0xb7,0x5d,0xcf,0x0b,
4393
0xa9,0x5c,0xaa,0x90,0x2a,0xa5,0xe9,0xd2,0x4c,0x69,0x99,0xf4,0x17,0xfb,0xd8,0x0e,
4394
0x1d,0x07,0xa9,0x4e,0xaa,0x97,0x52,0x3b,0xf5,0xb3,0xfe,0x44,0x5f,0x57,0x4a,0xed,
4395
0xd6,0x6d,0x4a,0x9b,0x24,0x5b,0x90,0x5a,0x2e,0xd5,0x49,0xf5,0xd2,0x42,0xa9,0xc9,
4396
0x96,0xa6,0xee,0x49,0xa7,0xae,0x95,0xd6,0x4a,0xf5,0x7b,0xf5,0xb5,0xa5,0x6b,0xa4,
4397
0x46,0x69,0xa1,0xd4,0x24,0x35,0x4b,0xeb,0x6d,0xa1,0xd8,0xbe,0x74,0xea,0x8e,0x7d,
4398
0x49,0xfe,0x3d,0xb7,0xf8,0xf7,0xc1,0x82,0x54,0xcd,0xaf,0x12,0xbf,0xda,0xbc,0x6a,
4399
0xf3,0xa7,0xcd,0xa8,0x4d,0xa7,0xba,0xea,0xbf,0x54,0x5d,0x13,0xf3,0x24,0x95,0x98,
4400
0x11,0xd9,0x83,0x78,0xd4,0x47,0x27,0xff,0xc5,0x6b,0xf5,0xa8,0x6d,0x5d,0xf1,0x89,
4401
0xd2,0xc9,0x79,0x1e,0x75,0x05,0xcc,0x6d,0xf3,0xa8,0x6b,0xc8,0xcb,0xd7,0x93,0x97,
4402
0x9f,0x25,0xdd,0x84,0x47,0xbd,0x38,0x78,0xd4,0xf7,0x27,0xa7,0xb1,0x39,0x8f,0xfa,
4403
0x11,0x3c,0xea,0xe5,0xd2,0x0a,0x69,0x65,0xf0,0xa8,0x9f,0x0c,0x1e,0xf5,0x6a,0x32,
4404
0xf6,0x6f,0x90,0xb1,0x37,0x8f,0x5a,0xdf,0x5e,0xea,0xbf,0xc8,0xcc,0xaf,0x23,0x33,
4405
0xbf,0x91,0xcc,0xfc,0x56,0x3c,0xea,0x96,0x82,0x84,0xb1,0x6d,0x79,0xf9,0xef,0x93,
4406
0x93,0xff,0x61,0xf0,0xa8,0x6f,0x0e,0x1e,0xb5,0x67,0xe3,0xef,0x25,0x0f,0x6f,0x1e,
4407
0xf5,0xec,0x8c,0xce,0xe7,0xc9,0xc3,0x5b,0x16,0x7e,0x1e,0x1e,0xf5,0xed,0x78,0xd4,
4408
0xcf,0xe4,0x79,0xd4,0xcf,0xe1,0x51,0xaf,0x09,0x1e,0xb5,0x65,0xe5,0x77,0x49,0x85,
4409
0x45,0xfa,0x3f,0x00,0x1e,0x75,0x69,0x9e,0x47,0xdd,0x0d,0x76,0xf6,0x31,0x64,0xe7,
4410
0xa7,0xc2,0xc8,0x36,0x8f,0xfa,0xf2,0xc0,0xc9,0x7e,0x1d,0x26,0xb6,0x7b,0xd4,0x7f,
4411
0x22,0x4b,0xbf,0x05,0x8f,0x7a,0x2b,0x99,0x7a,0xe3,0x60,0x77,0x09,0xdc,0xeb,0x0a,
4412
0x58,0xd7,0xf7,0x07,0xc6,0xf5,0xfb,0xf0,0xac,0x2d,0x43,0xbf,0x27,0x78,0xd4,0xdd,
4413
0x03,0xbf,0xda,0xb9,0xd5,0xce,0xab,0x36,0x4e,0xf5,0x68,0x72,0xf4,0x53,0xf0,0xa8,
4414
0x2d,0x4b,0xff,0x98,0xf4,0x02,0xfc,0xe9,0x77,0xe1,0x4f,0x9f,0x96,0xe7,0x51,0xd7,
4415
0xc0,0x95,0x76,0xa6,0x74,0x1d,0xfc,0xe8,0x0b,0xe1,0x46,0x3b,0x23,0x7a,0x0e,0x39,
4416
0xfa,0x85,0xe4,0xe7,0x3d,0x3b,0xef,0x0c,0xe8,0x66,0x78,0xcf,0x2f,0x06,0xce,0xb3,
4417
0x7b,0xd4,0x6f,0x93,0x9d,0x7f,0x8f,0xec,0xfc,0x4e,0x69,0x2f,0x1e,0xf5,0x01,0x3c,
4418
0x6a,0x67,0x38,0x97,0x92,0xa3,0xef,0x47,0x7e,0xbe,0x8a,0xdc,0xbc,0x33,0x9a,0x6b,
4419
0xe0,0x32,0x8f,0x0f,0x3c,0x66,0xcf,0xd1,0xcf,0x80,0xbd,0xdc,0x10,0x3c,0x6a,0x67,
4420
0x2e,0x2f,0x20,0x4f,0xff,0x10,0x39,0xfa,0x95,0x81,0xab,0xdc,0x0c,0x43,0xd9,0xf9,
4421
0xc9,0x2f,0x07,0x8f,0x7a,0x33,0x9c,0xe4,0x6d,0xc1,0xa3,0x76,0x3e,0x72,0x27,0xb2,
4422
0xf5,0xe5,0x64,0xea,0x2b,0xc9,0xd2,0x3b,0xff,0x78,0x74,0xf0,0xa8,0xc7,0xc2,0x37,
4423
0x76,0xb6,0xb1,0x33,0x8d,0xcf,0x27,0x5f,0x6f,0x0c,0xe3,0xab,0x83,0x47,0x3d,0x9f,
4424
0x5c,0xfd,0x9d,0x21,0x4f,0xbf,0x98,0x0c,0xfd,0x2f,0xc9,0xce,0x3b,0x87,0xf8,0x39,
4425
0xd8,0xc3,0x2f,0xe7,0x79,0xd4,0x3b,0xa4,0x4f,0xf3,0x3c,0x6a,0x67,0x0d,0x77,0x26,
4426
0x67,0xdf,0x2f,0xe4,0xeb,0x6b,0x60,0x08,0x8f,0x87,0x1d,0x3c,0x89,0xac,0xfd,0x85,
4427
0x30,0x82,0x67,0xe0,0x51,0xcf,0x0a,0x8c,0xe0,0xdb,0xc8,0xd9,0x3f,0x44,0xbe,0xde,
4428
0x19,0xc0,0xbf,0x81,0xeb,0xfb,0x12,0x3c,0xdf,0x3f,0xe0,0x51,0x6f,0x86,0xdf,0xfb,
4429
0x11,0x39,0xfb,0x34,0x39,0xfb,0x72,0xf2,0xf5,0x23,0xe1,0xf0,0x8e,0x85,0xbf,0xeb,
4430
0xec,0xdd,0x5a,0xf2,0xf5,0x17,0x05,0x9e,0xee,0x1c,0x32,0xf6,0x2b,0x42,0xb6,0xde,
4431
0x99,0xb9,0xaf,0x04,0x4e,0xee,0x46,0xd8,0xb8,0xbb,0xba,0xb4,0x31,0x71,0xab,0xe0,
4432
0xe0,0x8e,0x21,0x67,0x6f,0xec,0xdb,0x29,0x21,0x6b,0x3f,0x3f,0xe4,0xeb,0x9d,0x6f,
4433
0xbb,0x32,0x30,0x6d,0x3d,0x53,0xbf,0x16,0x7e,0xad,0x65,0xea,0x7b,0xc0,0xac,0xad,
4434
0x3e,0x88,0x47,0x3d,0x8a,0xac,0xfd,0xe5,0x81,0x4d,0x7b,0x13,0x1e,0xf5,0x5c,0x72,
4435
0xf7,0x3f,0x83,0x43,0xbb,0x06,0x8f,0xfa,0x65,0xe9,0xcd,0x6e,0x09,0x83,0xd6,0xf9,
4436
0xb3,0xce,0x9d,0x1d,0x0e,0x6b,0x76,0x34,0x2c,0xd9,0xc9,0x64,0xf3,0xeb,0xc9,0xe2,
4437
0x37,0x04,0x26,0xec,0x4d,0x70,0x60,0x9d,0x01,0xeb,0x8c,0xd7,0x35,0xc1,0xa3,0x1e,
4438
0x4f,0xe6,0xde,0xf3,0xf6,0xe7,0x93,0xb1,0x5f,0x40,0xb6,0xfe,0xf1,0x90,0xa9,0x5f,
4439
0x43,0x8e,0xbe,0x9c,0xfc,0xfc,0x3f,0xc3,0x5d,0xbd,0x9e,0xfc,0xfc,0x5d,0xe4,0xe7,
4440
0x0f,0xe0,0x51,0x5b,0x66,0xbe,0x91,0xcc,0xfc,0x22,0x32,0xf2,0x9d,0xc9,0xc8,0x1f,
4441
0x46,0x46,0xde,0xb8,0xa9,0x43,0xc8,0xc9,0x9f,0x43,0x4e,0x7e,0x26,0x9c,0xd4,0x95,
4442
0x81,0x8f,0xfa,0x4c,0x60,0xa2,0xbe,0x08,0x07,0xf5,0xcd,0x3c,0x8f,0xda,0xd8,0xa7,
4443
0x7b,0xa4,0x52,0xf8,0xa7,0x5d,0xe1,0x9e,0x5e,0x43,0x7e,0xfe,0x47,0x81,0x6b,0xfa,
4444
0x4b,0x32,0xf3,0x3d,0x61,0x98,0x9e,0x04,0xbb,0x74,0x40,0x60,0x96,0x0e,0x83,0x53,
4445
0x6a,0x1e,0xf5,0x38,0x32,0xf5,0x0d,0x64,0xe9,0x7f,0x0b,0x8b,0xb4,0xe5,0xc8,0x24,
4446
0x4b,0x7f,0x44,0x60,0x90,0x9e,0x1b,0x3c,0xea,0x0b,0xf2,0x3c,0xea,0x8b,0x61,0x8a,
4447
0x5e,0x11,0x58,0xa2,0xf3,0xe0,0x87,0x2e,0x93,0x9a,0x8f,0x4a,0x18,0xa1,0x55,0xc1,
4448
0xa3,0x1e,0x1e,0x3c,0x6a,0xe7,0x7f,0x7e,0x5d,0x9a,0x0e,0xe7,0xf3,0x7a,0x38,0x9f,
4449
0xf7,0xc2,0xf3,0x7c,0x30,0x70,0x3c,0x97,0x05,0x56,0xe7,0xff,0xc1,0xe7,0xfc,0x30,
4450
0x78,0xd4,0xdb,0x61,0x71,0x0e,0x80,0xbd,0x39,0x18,0xe6,0xa6,0xf1,0x36,0x6f,0x21,
4451
0xbf,0xff,0x02,0xfc,0xcc,0x0d,0x81,0x9f,0xb9,0x25,0x30,0x33,0x9d,0x95,0xb9,0x3b,
4452
0x70,0x31,0x2d,0x9f,0xbf,0x07,0xce,0x65,0x77,0xf2,0xf9,0xe3,0xc8,0xe5,0x7f,0x33,
4453
0xcf,0xa3,0xfe,0x21,0xf9,0xfb,0xa7,0x83,0x47,0xfd,0x2c,0xd9,0x7b,0xcb,0xdd,0xaf,
4454
0x23,0x77,0x6f,0x99,0xfb,0x8d,0x64,0xee,0x3f,0x22,0x73,0x6f,0x79,0xfb,0xcf,0xa4,
4455
0x52,0x98,0x95,0xee,0x51,0xf7,0xfd,0x0a,0x1e,0x75,0xb5,0x74,0x06,0x1e,0xf5,0x05,
4456
0x78,0xd4,0x17,0x77,0xe0,0x51,0xcf,0x08,0x1e,0xf5,0x0f,0xa4,0xeb,0xa4,0x59,0x78,
4457
0xd4,0xf3,0xa4,0x5b,0xa5,0xdb,0xc9,0xf8,0xaf,0x86,0x7d,0x99,0xc6,0xa3,0x2e,0xc2,
4458
0xa3,0x2e,0x21,0xeb,0x7f,0x58,0xc8,0xfa,0x5b,0xc6,0xbf,0xf7,0x17,0x78,0xd4,0x9e,
4459
0xf1,0xb7,0x2c,0xff,0x08,0xb2,0xfc,0x63,0xc9,0xf2,0x4f,0x90,0x6a,0xa5,0xa9,0x64,
4460
0xf7,0x6f,0x95,0x0e,0x39,0xa1,0xcd,0xa3,0x1e,0xdc,0x5b,0xe7,0x7e,0xd2,0x1d,0x78,
4461
0xd4,0x27,0xf5,0xd1,0x79,0x87,0x34,0x57,0xfa,0xb9,0xf4,0x57,0xe9,0xe1,0x93,0x12,
4462
0x8f,0xba,0xa5,0xaf,0xd4,0x4f,0x8f,0x25,0x9d,0x50,0xde,0x29,0xb5,0x48,0x03,0x75,
4463
0x62,0x79,0x01,0xf9,0xff,0xf7,0xc9,0xff,0x6f,0x27,0xff,0xdf,0x72,0x4a,0x5b,0xfe,
4464
0xff,0x54,0x32,0xff,0x33,0xf1,0xa8,0x7f,0x4a,0xd6,0xff,0x51,0x32,0xfe,0xab,0xc8,
4465
0xf6,0xff,0x9e,0x4c,0xff,0x3b,0xb0,0x2c,0xcf,0x1e,0xa8,0xc7,0xbc,0xb4,0x53,0x7a,
4466
0x5d,0x27,0xaf,0xfb,0xf0,0xa8,0x33,0x64,0xfb,0x7b,0x91,0xed,0x3f,0x15,0x96,0x65,
4467
0x25,0x19,0xff,0xa1,0x64,0xfa,0xc7,0x90,0xe9,0xbf,0x9b,0x4c,0xff,0x62,0x3c,0x6a,
4468
0xe7,0x54,0x5a,0x7e,0xbf,0x82,0xdc,0xbe,0x65,0xf6,0xdf,0x93,0x8e,0x19,0xa4,0xe7,
4469
0xbb,0x54,0x2b,0x4d,0x95,0xae,0x93,0x66,0x49,0x4d,0xd2,0x6a,0xe9,0x25,0x69,0x9d,
4470
0x74,0x55,0x95,0x8e,0x9d,0xf4,0xb6,0xb4,0x51,0xfa,0x0c,0x8f,0xda,0xb2,0xfe,0x2d,
4471
0xd2,0xfe,0xc5,0x49,0xbe,0xff,0xbf,0x7f,0x91,0xe4,0xf8,0xbb,0x91,0xdf,0xb7,0xcc,
4472
0xfe,0x15,0x78,0xd4,0xce,0x9f,0xbc,0x07,0xd6,0xe4,0x47,0xb0,0x25,0x77,0x4b,0xc7,
4473
0x87,0x5c,0xfe,0x6a,0xe9,0x77,0x81,0x03,0xe9,0xfc,0x47,0xe7,0x3e,0xf6,0x09,0x8c,
4474
0xc7,0x01,0x78,0xd4,0x43,0xa5,0xd3,0xc8,0xda,0x5f,0x0d,0xd3,0x71,0x0d,0x2c,0xc7,
4475
0xed,0x81,0xd9,0x78,0x22,0x7c,0xc6,0x33,0xe1,0x32,0x9e,0x43,0xce,0x7e,0x76,0xe0,
4476
0x2f,0x3e,0x0e,0x73,0xf1,0x29,0x58,0x8b,0x6b,0x61,0x2b,0x3a,0x57,0xd1,0x72,0xf6,
4477
0xfd,0xe0,0x25,0x56,0xc2,0x49,0xac,0x86,0x8f,0xe8,0x6c,0xc4,0xaf,0x07,0x8f,0x7a,
4478
0x72,0x60,0x1c,0x2e,0x0f,0x1e,0xf5,0x63,0x64,0xec,0x9f,0x24,0x63,0xbf,0x3a,0xcf,
4479
0xa3,0xfe,0x00,0x16,0xa1,0xf3,0x06,0x8b,0xc8,0xd0,0x1f,0x4e,0x76,0x7e,0x20,0xd9,
4480
0xf8,0x6f,0x07,0x56,0xa0,0x33,0x02,0x9d,0x09,0x68,0x2c,0xc0,0xfb,0xc8,0xc8,0x5b,
4481
0x3e,0xfe,0x3b,0xe4,0xe2,0x8b,0x42,0x1e,0xbe,0x27,0x59,0xf8,0xfe,0x64,0xe1,0x3d,
4482
0x07,0x7f,0x3a,0xd9,0xf7,0x5a,0xe9,0x59,0x72,0xef,0x63,0xc8,0xbd,0x5b,0xe6,0x7d,
4483
0x3f,0x1e,0xb5,0x71,0xfc,0x8e,0x84,0xe3,0x57,0x7b,0x10,0x8f,0xfa,0x02,0x3c,0xea,
4484
0x0b,0xa5,0x8b,0xa4,0x4b,0xf0,0xa8,0xa7,0xe3,0x51,0x37,0x90,0x97,0x37,0x8f,0xba,
4485
0xa0,0x45,0x3f,0x73,0xa9,0x34,0xcf,0xa3,0xee,0x06,0x03,0xd0,0x3c,0xea,0x5e,0xe4,
4486
0xea,0x6b,0x02,0xff,0x6f,0x15,0x99,0xf9,0x75,0x64,0xe5,0x2d,0x27,0xbf,0x59,0xfa,
4487
0x93,0xf4,0x17,0xe9,0x6f,0xd2,0x01,0xfb,0x9a,0x64,0xe6,0x87,0x93,0x95,0x9f,0x40,
4488
0x46,0x7e,0x6f,0x9e,0x47,0x5d,0x25,0x8d,0x91,0x6e,0x93,0x6e,0x97,0x16,0xe1,0x51,
4489
0xef,0xc7,0xa3,0x5e,0x14,0x98,0x7e,0xfb,0xa4,0xde,0x64,0xe4,0xbf,0x0f,0xab,0xef,
4490
0x1e,0xb2,0xf1,0x96,0x87,0xbf,0x07,0x0e,0xdf,0x06,0xf2,0xef,0x7d,0xc9,0xbd,0x9b,
4491
0x47,0x3d,0x84,0xac,0xba,0xe5,0xd4,0x3d,0x8b,0x3e,0x38,0xe4,0xcf,0xcf,0x25,0x6b,
4492
0xbe,0x9c,0xac,0xb9,0xe5,0xcc,0x8f,0x2e,0x49,0x3c,0xea,0xd3,0xf0,0xa8,0x2d,0x5b,
4493
0xbe,0x8e,0x5c,0x79,0x27,0x58,0x76,0xdd,0xc8,0x96,0xf7,0x20,0x53,0xee,0xdc,0xba,
4494
0xf1,0xd2,0x79,0xd2,0x62,0xb2,0xe4,0xc6,0xa7,0xfb,0xa4,0x34,0xc9,0x93,0x8f,0x21,
4495
0x4f,0x7e,0x05,0x39,0xf2,0x45,0xd2,0xf2,0xb2,0x24,0x4b,0xfe,0x9f,0x64,0xc8,0x5b,
4496
0x3a,0x27,0x19,0xf2,0xbe,0xb0,0xe8,0x66,0x91,0x0d,0x7f,0x04,0x8f,0xda,0xf2,0xe1,
4497
0x7d,0xc9,0x7d,0x1b,0x13,0x6e,0xb2,0xf4,0x52,0xe0,0xbf,0xa5,0xc9,0x7c,0x1b,0xe7,
4498
0x6d,0x82,0x34,0x0d,0xd6,0xdb,0x8d,0x30,0xdb,0x9e,0x80,0xd5,0x66,0x9c,0xb6,0x67,
4499
0xf1,0xa8,0xb7,0xc0,0x67,0x2b,0x20,0x07,0xee,0x4c,0xb6,0x6a,0x72,0xe0,0x57,0x04,
4500
0xce,0xda,0x8d,0xb0,0xd4,0x8c,0xa3,0xf6,0x62,0xe0,0xa6,0x99,0x47,0xbd,0x51,0xda,
4501
0x75,0x48,0x92,0x01,0x1f,0x08,0x0b,0xad,0x2a,0x78,0xd4,0xc6,0x3e,0x1b,0x85,0x47,
4502
0xed,0x79,0xf0,0x05,0x64,0xc0,0x97,0x06,0xa6,0xd9,0xbb,0x70,0xcc,0x8c,0x61,0x96,
4503
0x86,0x5d,0xd6,0x99,0x2c,0x78,0x3f,0x32,0xe0,0x55,0x64,0xbf,0x47,0x06,0x26,0xd9,
4504
0x58,0x38,0x64,0x13,0x82,0x47,0x7d,0x11,0xac,0x31,0xe3,0x8c,0x0d,0x85,0xe3,0x75,
4505
0x7a,0xe0,0x77,0x99,0x47,0x3d,0x25,0x78,0xd4,0x17,0xc2,0xe6,0x7a,0x32,0x78,0xd4,
4506
0xab,0x02,0x87,0xeb,0x79,0x32,0xdf,0xc6,0xdb,0x5a,0x01,0x5f,0xeb,0xa9,0xc0,0xd5,
4507
0x6a,0x26,0x03,0x6e,0x1c,0xad,0x41,0x70,0xb3,0x46,0x06,0x8f,0xda,0x39,0x59,0xc6,
4508
0xc7,0xba,0x3c,0xf0,0xb1,0xdc,0xa3,0x5e,0x1e,0x58,0x58,0xee,0x51,0x1b,0xfb,0xea,
4509
0x28,0xd8,0x56,0xc7,0x07,0xa6,0x95,0xb1,0xac,0xc6,0xf4,0x48,0x98,0x55,0xce,0xab,
4510
0x1a,0x8e,0x47,0xbd,0x23,0x64,0xc8,0x0f,0x25,0x37,0x3e,0x18,0xfe,0xd4,0xc8,0xe0,
4511
0x51,0x3b,0x57,0xea,0x4c,0x98,0x52,0x0f,0xc2,0x90,0x7a,0x03,0x76,0x94,0x73,0xa3,
4512
0x9c,0x0f,0x55,0x24,0x65,0xe1,0x43,0x0d,0x82,0x0b,0x35,0x1c,0x0e,0xd4,0x99,0xc1,
4513
0xa3,0x9e,0x04,0xfb,0x69,0x0a,0x99,0x72,0xe7,0x3d,0x19,0xe7,0xe9,0x3f,0xc8,0x95,
4514
0x67,0xe1,0x31,0x0d,0x81,0xc3,0x34,0x4e,0xba,0x9c,0x2c,0xb9,0x73,0x96,0x9c,0xaf,
4515
0xe4,0x5c,0x25,0xe3,0x29,0x15,0x91,0x2f,0xaf,0x0c,0xfc,0xa4,0x51,0x81,0x99,0x74,
4516
0x16,0x9c,0xa4,0x69,0xe4,0xcc,0x6f,0x87,0x87,0x74,0x47,0x07,0x1e,0xb5,0x71,0x8f,
4517
0x76,0xc0,0x33,0xfa,0x14,0x8f,0xfa,0x35,0xe9,0x8f,0xd2,0x26,0x69,0xfb,0x71,0x49,
4518
0xa6,0xdc,0xf2,0xe4,0x0d,0xe4,0xc9,0x07,0x56,0xeb,0xfb,0xae,0x4e,0x32,0xe3,0xc3,
4519
0xc8,0x88,0x1b,0x07,0x68,0x06,0xf9,0xf0,0x5d,0x78,0xd4,0x15,0xf0,0x7e,0xc6,0xc1,
4520
0xf9,0xb9,0x90,0x9c,0xb8,0x65,0xc4,0xef,0xfe,0x6e,0x1b,0xab,0x67,0x2e,0x5c,0x9e,
4521
0xc5,0xe4,0xbd,0xa3,0x47,0x6d,0x1c,0x9e,0xdd,0x73,0x93,0x9c,0x77,0x76,0x41,0x3a,
4522
0xd5,0x93,0xcc,0xf6,0xa5,0x64,0xb4,0xa7,0x93,0xcd,0xbe,0x85,0x4c,0xf6,0x22,0x18,
4523
0x39,0xe6,0x51,0xdf,0x27,0x7d,0xbc,0x5e,0x8f,0x15,0xb8,0x38,0x97,0xc1,0xc3,0xb9,
4524
0x16,0x1e,0xce,0x4d,0xf0,0x70,0x96,0xc2,0xc3,0xd9,0x22,0x9d,0x0e,0x13,0xc7,0x3c,
4525
0xea,0x9d,0xd2,0xa4,0x0d,0xe9,0xd4,0x35,0x1b,0x92,0x9c,0xf7,0xa2,0x90,0xef,0x7e,
4526
0x80,0x4c,0xb7,0xe7,0xb9,0x9f,0x27,0xc3,0x5d,0x4a,0x76,0xfb,0x18,0x32,0xdb,0xa3,
4527
0x43,0x56,0xbb,0x8e,0x7c,0xf6,0x9b,0x78,0xd4,0x96,0xc5,0xee,0x4e,0x06,0xbb,0x96,
4528
0xec,0xf5,0x3c,0x32,0xd7,0xcf,0x93,0xb9,0x36,0x4e,0x4d,0xcb,0xff,0x26,0x9c,0x9a,
4529
0xe1,0x70,0x6a,0x1a,0xf0,0xa8,0xe7,0xe0,0x51,0xdf,0x0a,0xa7,0xc6,0x18,0x35,0x45,
4530
0xb0,0x67,0x8e,0x87,0x39,0x63,0xbc,0x99,0x53,0xe0,0xca,0x8c,0x82,0x27,0x53,0xbb,
4531
0x39,0xc9,0x5f,0x7f,0x04,0x2f,0xc6,0x3c,0x6a,0xcb,0x43,0xaf,0x83,0xbb,0x72,0x46,
4532
0xe0,0xad,0x18,0x67,0x65,0xaa,0xf4,0xd8,0x87,0xfa,0xfb,0x5b,0x93,0x7c,0xf4,0x71,
4533
0x21,0x17,0xdd,0x97,0x2c,0xf4,0xd0,0x2f,0xf0,0xa8,0x6b,0x43,0xce,0xb9,0x23,0x8f,
4534
0xda,0xb3,0xcc,0xd3,0xc9,0x2f,0x5f,0x1d,0x72,0xcb,0xf3,0xc8,0x2a,0xdf,0x47,0x46,
4535
0xd9,0xf2,0xc9,0xdb,0xa5,0x01,0xdb,0xd2,0xa9,0x7f,0x93,0x1e,0x95,0x56,0x4b,0xeb,
4536
0xa4,0x8f,0xa5,0xd2,0xed,0xfa,0xb7,0x49,0x1a,0x88,0x47,0x7d,0x99,0x34,0x43,0x7a,
4537
0x04,0x8f,0xba,0x60,0x87,0xee,0xa3,0x34,0x5e,0x9a,0x28,0x4d,0x93,0xde,0xf8,0x24,
4538
0x9d,0xfa,0x50,0xda,0x2f,0x5d,0xb9,0x3b,0x9d,0xfa,0x1f,0xe9,0x03,0xa9,0xec,0x53,
4539
0x7d,0x1f,0xd2,0x64,0x69,0xae,0xb4,0x4c,0x5a,0x21,0x5d,0xb3,0x47,0x3f,0x1b,0xe9,
4540
0x9c,0xbd,0x69,0x9d,0xf3,0xe8,0xe7,0x21,0x5d,0x2b,0xfd,0x48,0x7a,0x48,0x7a,0x42,
4541
0x7a,0x4e,0xfa,0x83,0xf4,0x93,0x7d,0xe9,0xd4,0xef,0xe0,0xb3,0xbc,0xfd,0x40,0x41,
4542
0xaa,0xfa,0x57,0x49,0xa6,0xfa,0x5e,0xb2,0xd4,0x96,0x9f,0xb6,0xec,0xb4,0x79,0xd4,
4543
0x37,0xa4,0x12,0xfe,0xca,0x81,0x96,0x6e,0x52,0x79,0x2a,0x7d,0x78,0xf7,0xc3,0x3b,
4544
0x77,0x4f,0xeb,0x55,0xa6,0x2c,0xd3,0xa9,0xa0,0x53,0x41,0x61,0x41,0xa6,0x48,0x2f,
4545
0xe9,0xee,0xe9,0x02,0x5d,0xa3,0x77,0x32,0x65,0x85,0x7a,0x53,0x58,0x94,0x69,0xff,
4546
0x92,0xd5,0x2b,0xde,0x2f,0xb2,0x77,0xb2,0xf6,0x3a,0x53,0x96,0x2d,0xf6,0x97,0xe2,
4547
0xd2,0x4c,0x49,0x59,0x49,0x41,0x49,0x26,0x5b,0x52,0x92,0x2d,0x2d,0x2b,0x2d,0xc9,
4548
0xea,0x8d,0xfe,0x90,0x95,0x0a,0x4b,0xec,0x4f,0x7a,0xd1,0xe7,0x65,0x8a,0xc3,0xdf,
4549
0xc9,0x16,0x97,0xd8,0x67,0x67,0x8b,0xda,0xbf,0x24,0x97,0xdc,0x7b,0xd9,0xe4,0xbd,
4550
0x32,0xbd,0x64,0xfd,0x03,0xf6,0x91,0x6c,0xee,0x4f,0x79,0x9f,0x9e,0x7c,0x7e,0x36,
4551
0x7e,0x2e,0x9f,0xd1,0xfa,0xd9,0x6d,0x97,0x2c,0xd2,0xb7,0xed,0x1f,0xc8,0x7d,0xdd,
4552
0xdc,0xb5,0x99,0xd6,0x6b,0x5a,0x95,0x0d,0x77,0xa9,0xf5,0x2b,0x65,0xb9,0x25,0xbd,
4553
0x2d,0x6b,0x7f,0xc7,0x8b,0xda,0xee,0x5f,0x36,0xd3,0xfa,0x5e,0x36,0x5e,0xdd,0xe1,
4554
0x77,0x5d,0xd4,0xfe,0x2e,0xe6,0x8e,0x7a,0xe7,0xdc,0x51,0x8f,0x37,0x9e,0xbc,0xd8,
4555
0x4d,0x66,0x32,0xd9,0x74,0xb8,0xcd,0xe4,0xe3,0x99,0xdc,0x4f,0x29,0xf7,0x5d,0xb4,
4556
0xde,0x2c,0x77,0x35,0x1b,0x6e,0xb0,0x83,0xfb,0x90,0xf5,0x23,0x1e,0xaf,0x8b,0xf7,
4557
0x2d,0x93,0xdc,0x25,0xde,0x76,0x4e,0x17,0x15,0x67,0x3a,0x77,0xef,0x51,0xde,0xad,
4558
0x6b,0x97,0x82,0xb2,0x4c,0x81,0xae,0x38,0xec,0x90,0xaf,0x1d,0x9a,0x2e,0x2c,0x2a,
4559
0xec,0x94,0xc9,0xa9,0x2c,0x9b,0xc9,0x7f,0x2c,0xe9,0x7e,0xb7,0xbe,0x9f,0xe9,0x54,
4560
0x96,0xbc,0xf5,0x87,0x5c,0xee,0xae,0xdb,0x1d,0xcf,0xb4,0xfe,0x00,0x38,0x18,0x19,
4561
0xbb,0x74,0xce,0xf0,0xc1,0xdc,0xdb,0xf0,0x80,0xfc,0xfc,0x4b,0xf2,0x4a,0x8f,0xbf,
4562
0xe4,0x30,0x64,0x5a,0x0f,0x62,0xee,0x4f,0xd9,0xdc,0xbd,0xe8,0xe0,0x60,0xe4,0x1d,
4563
0xe3,0xa2,0x0e,0x8f,0x4f,0xdb,0xb1,0xe5,0xa2,0x87,0x72,0xa7,0xe2,0xdc,0xa5,0xa4,
4564
0x24,0xa3,0x07,0x75,0xc6,0x6e,0xb7,0x20,0xf7,0xa2,0x27,0x9a,0x9e,0x29,0xba,0x32,
4565
0xdd,0xfe,0x39,0x97,0xfb,0x7b,0x65,0xba,0x2e,0xd3,0x76,0x6c,0x73,0x77,0x3a,0xf7,
4566
0xe0,0xcb,0x16,0xb6,0xfb,0xee,0x73,0xb7,0xd1,0x76,0xc9,0xe4,0x5e,0xeb,0xd1,0x9a,
4567
0x7b,0x9d,0x7b,0xdf,0xaf,0xcc,0xdd,0x87,0x6c,0x69,0xa9,0x5d,0x53,0x6c,0xcf,0xb9,
4568
0x62,0xbe,0xfd,0x6c,0xfb,0x1f,0x6e,0xfb,0x47,0x5e,0xbb,0x07,0xe1,0xe7,0x9e,0x85,
4569
0x45,0xf1,0x81,0x93,0x7f,0xb0,0xda,0x1d,0x9f,0xcc,0xe7,0x3e,0x14,0x8f,0x52,0xdb,
4570
0xcd,0x1d,0xec,0xf1,0x17,0x9e,0xaa,0x7c,0x91,0x6c,0xb6,0xfd,0xdd,0xf6,0x27,0x6d,
4571
0xde,0x13,0xa5,0xdd,0xfd,0xcd,0xe4,0x1d,0xb9,0x6c,0x51,0xf2,0x1c,0x49,0xfb,0x0f,
4572
0xdf,0x0f,0x7f,0xfe,0xa5,0xed,0xd1,0x53,0xd8,0x76,0xaf,0x92,0x4b,0xeb,0xaf,0xa2,
4573
0xe2,0xe4,0x77,0x97,0xfd,0xea,0xfa,0xb2,0x4b,0x26,0xb9,0x14,0x66,0xc2,0xaf,0xce,
4574
0x83,0x5e,0x0a,0xb9,0x0f,0x69,0xdd,0xcb,0xa2,0x54,0xdb,0x4e,0xdb,0x39,0xcc,0xcd,
4575
0xbe,0xea,0x2e,0x59,0xdf,0x1d,0xeb,0x3b,0x62,0x7d,0x27,0x6c,0xfe,0x0e,0xd8,0xfc,
4576
0xdd,0xaf,0xbe,0xd3,0xd5,0x77,0xb9,0xfa,0x0e,0x57,0xdf,0xd5,0xea,0xbb,0x59,0x7d,
4577
0x27,0xab,0xef,0x62,0xf5,0x1d,0xac,0xbe,0x7b,0xd5,0x77,0xae,0x6e,0x08,0x3b,0x54,
4578
0xbd,0x63,0x31,0x92,0xdd,0xa8,0xb5,0x61,0xe7,0xa9,0xef,0x3a,0xf5,0x79,0x95,0xef,
4579
0x26,0x5d,0xd5,0xc1,0x2e,0xd2,0xb5,0x61,0xf7,0xa8,0xef,0x1a,0xfd,0x2c,0xaf,0x2f,
4580
0x11,0x77,0x82,0x7e,0xd1,0x2e,0x50,0xdf,0xf9,0x19,0x77,0x7d,0xce,0x09,0x3b,0x3b,
4581
0x57,0x85,0x1d,0x9d,0xb1,0x03,0xe1,0x3b,0x38,0xf7,0xe6,0xcd,0x94,0x46,0x86,0xf9,
4582
0x51,0xfe,0x6e,0xcc,0xd8,0x6f,0xf0,0xdd,0x97,0xbe,0xeb,0x72,0x55,0x07,0xbb,0x28,
4583
0xd7,0x86,0xdd,0x93,0x29,0x66,0x3f,0xa3,0xbf,0x64,0x57,0xa4,0xef,0x84,0xbc,0x91,
4584
0xdd,0x8f,0xbe,0xd3,0x71,0x55,0xd8,0xdd,0xe8,0x3b,0x1b,0xe3,0xae,0x46,0xdf,0xcd,
4585
0x98,0x62,0xf7,0xa2,0xef,0x58,0x1c,0xdd,0xc1,0x4e,0xc5,0x09,0x61,0x77,0xa2,0xef,
4586
0x4c,0xf4,0x99,0x4e,0xdc,0x79,0xd8,0xd1,0xae,0x43,0xdf,0x71,0xe8,0xbb,0x0d,0x7d,
4587
0xa7,0xa1,0xef,0x30,0xf4,0x5d,0x84,0xbe,0x83,0xf0,0x45,0xe6,0x34,0xbe,0x53,0xf0,
4588
0xcb,0x76,0x09,0x7e,0x2f,0x6f,0x57,0xe0,0xc1,0x76,0x04,0x0e,0x60,0xf6,0x32,0x89,
4589
0xd9,0x8b,0xef,0xee,0xf3,0x9d,0x7d,0xbe,0xab,0xcf,0x77,0xf4,0xcd,0x66,0xf6,0xe2,
4590
0x3b,0xf7,0xee,0x66,0x06,0xe3,0x3b,0xeb,0x7c,0xb7,0xdc,0x20,0x66,0x21,0xbe,0x3b,
4591
0xce,0x77,0xc5,0x3d,0xc6,0xac,0xc3,0x77,0xbc,0xf9,0x6e,0x37,0x67,0x01,0xf9,0x8e,
4592
0xb6,0x5e,0x61,0xe7,0x9a,0xcd,0x2c,0x7a,0x84,0x59,0x84,0xcf,0x20,0xe2,0xee,0xb2,
4593
0x26,0x66,0x0d,0x31,0x0f,0x3f,0x36,0x6f,0x77,0xd8,0x6c,0x66,0x0a,0xcb,0x98,0x1f,
4594
0xd8,0x9c,0xa0,0x0f,0xf3,0x81,0xb8,0x53,0x6b,0x4b,0xd8,0x9d,0xb5,0x2b,0x6f,0x16,
4595
0xd0,0xcc,0x1c,0x60,0x1f,0xb3,0x80,0xf5,0xf8,0xe3,0xbe,0x5b,0xc9,0x77,0x25,0xf9,
4596
0x8e,0xa3,0x93,0xf1,0x7b,0x7d,0x27,0xd1,0x0c,0x3c,0x55,0xdf,0xe9,0xe3,0xbb,0x7b,
4597
0x7c,0x57,0x8f,0xef,0xce,0xf1,0x9d,0x39,0xbe,0x2b,0xa7,0x77,0xde,0x4e,0x1c,0xdf,
4598
0x85,0xf3,0x18,0x5e,0xa9,0xef,0xbc,0xf1,0xdd,0x36,0xbe,0xcb,0xe6,0x2c,0x7c,0xd2,
4599
0x98,0xe3,0x6d,0x0e,0x3b,0x66,0xfa,0xe3,0x7d,0xfa,0x4e,0x18,0xf7,0x3d,0xaf,0x0b,
4600
0x99,0xdc,0xa6,0xb0,0xbb,0xc5,0x77,0xb6,0xf8,0xae,0x16,0xdf,0xd1,0xf2,0x01,0x3b,
4601
0x57,0xdc,0xef,0x7c,0x2f,0xec,0x38,0x31,0x2f,0xd3,0x77,0x92,0xe4,0xef,0x0e,0xf1,
4602
0x5d,0x1b,0xbe,0x5b,0xc3,0x77,0x65,0x1c,0x6c,0xb7,0x43,0xfe,0x0e,0x07,0xdf,0xd1,
4603
0xe0,0x3b,0x16,0x7c,0x27,0x82,0xef,0x34,0x48,0x85,0x4c,0xe5,0x99,0x21,0x4b,0xd9,
4604
0x84,0x47,0xe5,0x3b,0x03,0xfa,0xe2,0x47,0xf9,0x2e,0x00,0x67,0xff,0x7b,0x66,0x72,
4605
0x25,0x4c,0xff,0xdf,0xe6,0x79,0x52,0xa7,0xe4,0x31,0xf7,0x37,0xe2,0x2d,0xa5,0xf0,
4606
0x95,0x9c,0x71,0x3f,0xfa,0x20,0x2c,0x7b,0x67,0xd8,0x1f,0x8c,0x5d,0x3f,0x18,0x0f,
4607
0xc9,0x59,0xef,0x4d,0x78,0x44,0xcb,0x03,0x7b,0xbd,0x39,0xb0,0xd5,0x2b,0xf1,0x80,
4608
0x1e,0xc6,0xdf,0x39,0x16,0x1f,0xe7,0x14,0xbc,0x9b,0x8e,0x58,0xe1,0xa3,0x03,0x13,
4609
0xdc,0xfd,0x9a,0x57,0x02,0xe3,0x7b,0x53,0x60,0x78,0x3b,0xbb,0x3b,0x66,0x07,0x23,
4610
0xa3,0x7b,0x22,0x9e,0xcc,0x7c,0xbc,0x98,0x8a,0xc0,0xc2,0x1e,0x93,0xc7,0xb8,0x36,
4611
0xaf,0xe5,0xcb,0x18,0xd5,0xce,0xa6,0xee,0x88,0x3d,0x6d,0x1e,0xcb,0x4e,0x18,0xd1,
4612
0xce,0x42,0x76,0x06,0xb2,0x33,0x8a,0xf3,0xd9,0xc4,0xf9,0x0c,0x62,0x67,0xfe,0x4e,
4613
0xfb,0x7b,0x99,0xbe,0x7f,0x2f,0xdb,0xf6,0xab,0xb2,0x6b,0xf1,0x12,0x9c,0x39,0xeb,
4614
0xac,0x56,0x67,0xb4,0x3a,0x43,0xf4,0xff,0x01,
4615
};
4616
}  // namespace ada::idna::table_blob
4617
#endif
4618
/* end file src/table_blob.inc */
4619
4620
#include <atomic>
4621
#include <bit>
4622
#include <cstdint>
4623
#include <cstddef>
4624
#include <new>
4625
4626
namespace ada::idna {
4627
4628
// table_blob.inc is packed little-endian (see scripts/pack_tables.py). After
4629
// inflate the multi-byte sections must be converted to host endianness so
4630
// big-endian platforms (s390x) can load uint16_t/uint32_t/uint64_t natively.
4631
// CRC is checked on the raw little-endian payload before any conversion.
4632
namespace detail {
4633
4634
template <typename T>
4635
0
inline void bswap_inplace(T* data, size_t count) noexcept {
4636
0
  if constexpr (std::endian::native == std::endian::little) {
4637
0
    (void)data;
4638
0
    (void)count;
4639
0
    return;
4640
0
  }
4641
0
  for (size_t i = 0; i < count; ++i) {
4642
0
    if constexpr (sizeof(T) == 2) {
4643
0
#if defined(__GNUC__) || defined(__clang__)
4644
0
      data[i] =
4645
0
          static_cast<T>(__builtin_bswap16(static_cast<uint16_t>(data[i])));
4646
0
#else
4647
0
      const auto v = static_cast<uint16_t>(data[i]);
4648
0
      data[i] = static_cast<T>(static_cast<uint16_t>((v >> 8) | (v << 8)));
4649
0
#endif
4650
0
    } else if constexpr (sizeof(T) == 4) {
4651
0
#if defined(__GNUC__) || defined(__clang__)
4652
0
      data[i] =
4653
0
          static_cast<T>(__builtin_bswap32(static_cast<uint32_t>(data[i])));
4654
0
#else
4655
0
      auto v = static_cast<uint32_t>(data[i]);
4656
0
      v = ((v & 0x000000FFu) << 24) | ((v & 0x0000FF00u) << 8) |
4657
0
          ((v & 0x00FF0000u) >> 8) | ((v & 0xFF000000u) >> 24);
4658
0
      data[i] = static_cast<T>(v);
4659
0
#endif
4660
0
    } else if constexpr (sizeof(T) == 8) {
4661
0
#if defined(__GNUC__) || defined(__clang__)
4662
0
      data[i] =
4663
0
          static_cast<T>(__builtin_bswap64(static_cast<uint64_t>(data[i])));
4664
0
#else
4665
0
      auto v = static_cast<uint64_t>(data[i]);
4666
0
      v = ((v & 0x00000000000000FFull) << 56) |
4667
0
          ((v & 0x000000000000FF00ull) << 40) |
4668
0
          ((v & 0x0000000000FF0000ull) << 24) |
4669
0
          ((v & 0x00000000FF000000ull) << 8) |
4670
0
          ((v & 0x000000FF00000000ull) >> 8) |
4671
0
          ((v & 0x0000FF0000000000ull) >> 24) |
4672
0
          ((v & 0x00FF000000000000ull) >> 40) |
4673
0
          ((v & 0xFF00000000000000ull) >> 56);
4674
0
      data[i] = static_cast<T>(v);
4675
0
#endif
4676
0
    } else {
4677
0
      static_assert(sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8);
4678
0
    }
4679
0
  }
4680
0
}
Unexecuted instantiation: void ada::idna::detail::bswap_inplace<unsigned short>(unsigned short*, unsigned long)
Unexecuted instantiation: void ada::idna::detail::bswap_inplace<unsigned int>(unsigned int*, unsigned long)
Unexecuted instantiation: void ada::idna::detail::bswap_inplace<unsigned long>(unsigned long*, unsigned long)
4681
4682
// Convert every multi-byte section of the inflated little-endian blob to host
4683
// order. Single-byte sections are left unchanged. Safe no-op on little-endian.
4684
1
inline void convert_table_blob_to_host_endian(uint8_t* buffer) noexcept {
4685
1
  if constexpr (std::endian::native == std::endian::little) {
4686
1
    (void)buffer;
4687
1
    return;
4688
1
  }
4689
0
  auto u16 = [&](size_t off, size_t count) {
4690
1
    bswap_inplace(reinterpret_cast<uint16_t*>(buffer + off), count);
4691
1
  };
4692
1
  auto u32 = [&](size_t off, size_t count) {
4693
1
    bswap_inplace(reinterpret_cast<uint32_t*>(buffer + off), count);
4694
1
  };
4695
1
  auto u64 = [&](size_t off, size_t count) {
4696
1
    bswap_inplace(reinterpret_cast<uint64_t*>(buffer + off), count);
4697
1
  };
4698
4699
1
  u16(table_blob::off_idna_stage1, table_blob::count_idna_stage1);
4700
1
  u16(table_blob::off_idna_stage2, table_blob::count_idna_stage2);
4701
1
  u64(table_blob::off_idna_bool_blocks, table_blob::count_idna_bool_blocks);
4702
1
  u16(table_blob::off_decomposition_block,
4703
1
      table_blob::count_decomposition_block);
4704
1
  u32(table_blob::off_decomposition_data, table_blob::count_decomposition_data);
4705
1
  u16(table_blob::off_composition_block, table_blob::count_composition_block);
4706
1
  u32(table_blob::off_composition_data, table_blob::count_composition_data);
4707
1
  u32(table_blob::off_id_continue_flat, table_blob::count_id_continue_flat);
4708
1
  u32(table_blob::off_id_start_flat, table_blob::count_id_start_flat);
4709
1
  u32(table_blob::off_dir_start, table_blob::count_dir_start);
4710
1
  u32(table_blob::off_dir_final, table_blob::count_dir_final);
4711
1
  u32(table_blob::off_combining_flat, table_blob::count_combining_flat);
4712
1
}
4713
4714
}  // namespace detail
4715
4716
// --- Blob layout invariants --------------------------------------------------
4717
static_assert(table_blob::count_decomposition_index == 4352);
4718
static_assert(table_blob::count_ccc_index == 4352);
4719
static_assert(table_blob::count_composition_index == 4352);
4720
static_assert(table_blob::count_decomposition_block ==
4721
              table_blob::decomposition_block_rows *
4722
                  table_blob::decomposition_block_cols);
4723
static_assert(table_blob::count_ccc_block ==
4724
              table_blob::ccc_block_rows * table_blob::ccc_block_cols);
4725
static_assert(table_blob::count_composition_block ==
4726
              table_blob::composition_block_rows *
4727
                  table_blob::composition_block_cols);
4728
static_assert(table_blob::count_dir_start == table_blob::dir_table_count &&
4729
              table_blob::count_dir_final == table_blob::dir_table_count &&
4730
              table_blob::count_dir_value == table_blob::dir_table_count);
4731
static_assert(table_blob::count_id_continue_flat ==
4732
              table_blob::id_continue_count * 2);
4733
static_assert(table_blob::count_id_start_flat ==
4734
              table_blob::id_start_count * 2);
4735
static_assert(table_blob::count_combining_flat ==
4736
              table_blob::combining_range_count * 2);
4737
static_assert(table_blob::off_idna_stage1 % alignof(uint16_t) == 0);
4738
static_assert(table_blob::off_idna_stage2 % alignof(uint16_t) == 0);
4739
static_assert(table_blob::off_idna_bool_blocks % alignof(uint64_t) == 0);
4740
static_assert(table_blob::off_decomposition_block % alignof(uint16_t) == 0);
4741
static_assert(table_blob::off_decomposition_data % alignof(char32_t) == 0);
4742
static_assert(table_blob::off_composition_block % alignof(uint16_t) == 0);
4743
static_assert(table_blob::off_composition_data % alignof(char32_t) == 0);
4744
static_assert(table_blob::off_id_continue_flat % alignof(uint32_t) == 0);
4745
static_assert(table_blob::off_id_start_flat % alignof(uint32_t) == 0);
4746
static_assert(table_blob::off_dir_start % alignof(uint32_t) == 0);
4747
static_assert(table_blob::off_dir_final % alignof(uint32_t) == 0);
4748
static_assert(table_blob::off_combining_flat % alignof(uint32_t) == 0);
4749
static_assert(table_blob::compressed_size == sizeof(table_blob::compressed));
4750
4751
// Every section must lie entirely inside the uncompressed buffer.
4752
#define ADA_IDNA_SECTION_IN_BOUNDS(off, count, width)                       \
4753
  static_assert((off) + (count) * (width) <= table_blob::uncompressed_size, \
4754
                #off " overflows uncompressed buffer")
4755
ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_idna_stage1,
4756
                           table_blob::count_idna_stage1, 2);
4757
ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_idna_stage2,
4758
                           table_blob::count_idna_stage2, 2);
4759
ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_idna_bool_blocks,
4760
                           table_blob::count_idna_bool_blocks, 8);
4761
ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_idna_utf8_mappings,
4762
                           table_blob::count_idna_utf8_mappings, 1);
4763
ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_decomposition_index,
4764
                           table_blob::count_decomposition_index, 1);
4765
ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_decomposition_block,
4766
                           table_blob::count_decomposition_block, 2);
4767
ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_decomposition_data,
4768
                           table_blob::count_decomposition_data, 4);
4769
ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_ccc_index,
4770
                           table_blob::count_ccc_index, 1);
4771
ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_ccc_block,
4772
                           table_blob::count_ccc_block, 1);
4773
ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_composition_index,
4774
                           table_blob::count_composition_index, 1);
4775
ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_composition_block,
4776
                           table_blob::count_composition_block, 2);
4777
ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_composition_data,
4778
                           table_blob::count_composition_data, 4);
4779
ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_id_continue_flat,
4780
                           table_blob::count_id_continue_flat, 4);
4781
ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_id_start_flat,
4782
                           table_blob::count_id_start_flat, 4);
4783
ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_dir_start,
4784
                           table_blob::count_dir_start, 4);
4785
ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_dir_final,
4786
                           table_blob::count_dir_final, 4);
4787
ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_dir_value,
4788
                           table_blob::count_dir_value, 1);
4789
ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_combining_flat,
4790
                           table_blob::count_combining_flat, 4);
4791
#undef ADA_IDNA_SECTION_IN_BOUNDS
4792
4793
// --- Mapping -----------------------------------------------------------------
4794
inline const uint16_t* idna_stage1 = nullptr;
4795
inline const uint16_t* idna_stage2 = nullptr;
4796
inline const uint64_t* idna_bool_blocks = nullptr;
4797
inline const uint8_t* idna_utf8_mappings = nullptr;
4798
4799
// --- Normalization (O(1) multi-stage) ----------------------------------------
4800
inline const uint8_t* decomposition_index = nullptr;
4801
inline const uint16_t* decomposition_block_flat = nullptr;
4802
inline const char32_t* decomposition_data = nullptr;
4803
inline const uint8_t* ccc_index = nullptr;
4804
inline const uint8_t* ccc_block_flat = nullptr;
4805
inline const uint8_t* composition_index = nullptr;
4806
inline const uint16_t* composition_block_flat = nullptr;
4807
inline const char32_t* composition_data = nullptr;
4808
4809
// --- Identifier --------------------------------------------------------------
4810
// Pointer-to-array alias. CF17 vs CF22 disagree on spacing inside (*)[2].
4811
// clang-format off
4812
using range_pair_ptr = const uint32_t(*)[2];
4813
// clang-format on
4814
inline range_pair_ptr id_continue = nullptr;
4815
inline range_pair_ptr id_start = nullptr;
4816
4817
// --- Validity (const SoA) ----------------------------------------------------
4818
inline const uint32_t* dir_start = nullptr;
4819
inline const uint32_t* dir_final = nullptr;
4820
inline const uint8_t* dir_value = nullptr;
4821
inline range_pair_ptr combining_ranges = nullptr;
4822
4823
inline constexpr size_t id_continue_count = table_blob::id_continue_count;
4824
inline constexpr size_t id_start_count = table_blob::id_start_count;
4825
inline constexpr size_t dir_table_count = table_blob::dir_table_count;
4826
inline constexpr size_t combining_range_count =
4827
    table_blob::combining_range_count;
4828
inline constexpr size_t idna_utf8_mappings_size =
4829
    table_blob::count_idna_utf8_mappings;
4830
inline constexpr size_t decomposition_data_size =
4831
    table_blob::count_decomposition_data;
4832
inline constexpr size_t composition_data_size =
4833
    table_blob::count_composition_data;
4834
4835
inline constexpr size_t kDecompBlockCols =
4836
    table_blob::decomposition_block_cols;                            // 257
4837
inline constexpr size_t kCccBlockCols = table_blob::ccc_block_cols;  // 256
4838
inline constexpr size_t kCompBlockCols =
4839
    table_blob::composition_block_cols;  // 257
4840
inline constexpr size_t kDecompBlockRows = table_blob::decomposition_block_rows;
4841
inline constexpr size_t kCccBlockRows = table_blob::ccc_block_rows;
4842
inline constexpr size_t kCompBlockRows = table_blob::composition_block_rows;
4843
4844
// Init state: 0=uninit, 1=in progress, 2=ready, 3=failed.
4845
inline constexpr uint8_t kTablesUninit = 0;
4846
inline constexpr uint8_t kTablesInProgress = 1;
4847
inline constexpr uint8_t kTablesReady = 2;
4848
inline constexpr uint8_t kTablesFailed = 3;
4849
4850
inline std::atomic<uint8_t> tables_init_state{kTablesUninit};
4851
// Process-lifetime allocation published only by the winning init thread.
4852
// Never freed: shared read-only data for the process. Do not dlclose a DSO
4853
// that owns this buffer while other code may still call into ada::idna.
4854
inline uint8_t* tables_buffer = nullptr;
4855
4856
// Cap spin-wait so a stuck peer cannot hang the process forever.
4857
inline constexpr uint64_t kTablesSpinLimit = 1'000'000'000ull;
4858
4859
// ISO HDLC / zlib CRC-32 of the uncompressed table payload.
4860
[[nodiscard]] inline uint32_t crc32_ieee(const uint8_t* data,
4861
1
                                         size_t len) noexcept {
4862
1
  uint32_t c = 0xFFFFFFFFu;
4863
224k
  for (size_t i = 0; i < len; ++i) {
4864
224k
    c ^= data[i];
4865
2.02M
    for (int k = 0; k < 8; ++k) {
4866
1.79M
      const uint32_t mask = 0u - (c & 1u);
4867
1.79M
      c = (c >> 1) ^ (0xEDB88320u & mask);
4868
1.79M
    }
4869
224k
  }
4870
1
  return ~c;
4871
1
}
4872
4873
16.5k
[[nodiscard]] inline bool tables_are_ready() noexcept {
4874
16.5k
  return tables_init_state.load(std::memory_order_acquire) == kTablesReady;
4875
16.5k
}
4876
4877
// Returns true only when all table pointers are safe to use.
4878
44.5k
[[nodiscard]] inline bool ensure_tables() noexcept {
4879
44.5k
  uint8_t state = tables_init_state.load(std::memory_order_acquire);
4880
44.5k
  if (state == kTablesReady) {
4881
44.5k
    return true;
4882
44.5k
  }
4883
1
  if (state == kTablesFailed) {
4884
0
    return false;
4885
0
  }
4886
4887
1
  uint8_t expected = kTablesUninit;
4888
1
  if (tables_init_state.compare_exchange_strong(expected, kTablesInProgress,
4889
1
                                                std::memory_order_acq_rel,
4890
1
                                                std::memory_order_acquire)) {
4891
1
    uint8_t* buffer = new (std::nothrow) uint8_t[table_blob::uncompressed_size];
4892
1
    if (buffer == nullptr) {
4893
0
      tables_init_state.store(kTablesFailed, std::memory_order_release);
4894
0
      return false;
4895
0
    }
4896
4897
1
    const size_t n = deflate::inflate_raw(table_blob::compressed,
4898
1
                                          table_blob::compressed_size, buffer,
4899
1
                                          table_blob::uncompressed_size);
4900
1
    if (n != table_blob::uncompressed_size ||
4901
1
        crc32_ieee(buffer, n) != table_blob::uncompressed_crc32) {
4902
0
      delete[] buffer;
4903
0
      tables_init_state.store(kTablesFailed, std::memory_order_release);
4904
0
      return false;
4905
0
    }
4906
4907
    // LE payload verified; convert multi-byte fields for big-endian hosts.
4908
1
    detail::convert_table_blob_to_host_endian(buffer);
4909
4910
18
    auto at = [&](size_t off) noexcept -> const uint8_t* {
4911
18
      return buffer + off;
4912
18
    };
4913
4914
    // Publish all non-atomic pointers before READY. Waiters synchronize via
4915
    // acquire on tables_init_state and then observe these writes.
4916
1
    idna_stage1 =
4917
1
        reinterpret_cast<const uint16_t*>(at(table_blob::off_idna_stage1));
4918
1
    idna_stage2 =
4919
1
        reinterpret_cast<const uint16_t*>(at(table_blob::off_idna_stage2));
4920
1
    idna_bool_blocks =
4921
1
        reinterpret_cast<const uint64_t*>(at(table_blob::off_idna_bool_blocks));
4922
1
    idna_utf8_mappings = at(table_blob::off_idna_utf8_mappings);
4923
4924
1
    decomposition_index = at(table_blob::off_decomposition_index);
4925
1
    decomposition_block_flat = reinterpret_cast<const uint16_t*>(
4926
1
        at(table_blob::off_decomposition_block));
4927
1
    decomposition_data = reinterpret_cast<const char32_t*>(
4928
1
        at(table_blob::off_decomposition_data));
4929
1
    ccc_index = at(table_blob::off_ccc_index);
4930
1
    ccc_block_flat = at(table_blob::off_ccc_block);
4931
1
    composition_index = at(table_blob::off_composition_index);
4932
1
    composition_block_flat = reinterpret_cast<const uint16_t*>(
4933
1
        at(table_blob::off_composition_block));
4934
1
    composition_data =
4935
1
        reinterpret_cast<const char32_t*>(at(table_blob::off_composition_data));
4936
4937
1
    id_continue =
4938
1
        reinterpret_cast<range_pair_ptr>(at(table_blob::off_id_continue_flat));
4939
1
    id_start =
4940
1
        reinterpret_cast<range_pair_ptr>(at(table_blob::off_id_start_flat));
4941
4942
1
    dir_start =
4943
1
        reinterpret_cast<const uint32_t*>(at(table_blob::off_dir_start));
4944
1
    dir_final =
4945
1
        reinterpret_cast<const uint32_t*>(at(table_blob::off_dir_final));
4946
1
    dir_value = at(table_blob::off_dir_value);
4947
1
    combining_ranges =
4948
1
        reinterpret_cast<range_pair_ptr>(at(table_blob::off_combining_flat));
4949
4950
1
    tables_buffer = buffer;
4951
1
    tables_init_state.store(kTablesReady, std::memory_order_release);
4952
1
    return true;
4953
1
  }
4954
4955
  // Another thread owns init (or finished between our loads).
4956
0
  for (uint64_t spins = 0; spins < kTablesSpinLimit; ++spins) {
4957
0
    state = tables_init_state.load(std::memory_order_acquire);
4958
0
    if (state == kTablesReady) {
4959
0
      return true;
4960
0
    }
4961
0
    if (state == kTablesFailed) {
4962
0
      return false;
4963
0
    }
4964
0
#if defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || \
4965
0
    defined(_M_IX86)
4966
0
#if defined(__GNUC__) || defined(__clang__)
4967
0
    __builtin_ia32_pause();
4968
0
#endif
4969
#elif defined(__aarch64__) || defined(_M_ARM64)
4970
#if defined(__GNUC__) || defined(__clang__)
4971
    asm volatile("yield" ::: "memory");
4972
#endif
4973
#endif
4974
0
  }
4975
  // Timed out waiting for a peer - treat as failure rather than hang.
4976
0
  return false;
4977
0
}
4978
4979
// O(1) multi-stage accessors. Block indices from the tables are uint8_t and
4980
// theoretically can be out of range if the blob is corrupt; clamp to a valid
4981
// empty/default row (index 0) instead of reading OOB.
4982
634k
inline const uint16_t* decomposition_block_row(uint8_t bi) noexcept {
4983
634k
  if (bi >= kDecompBlockRows) {
4984
0
    bi = 0;
4985
0
  }
4986
634k
  return decomposition_block_flat + static_cast<size_t>(bi) * kDecompBlockCols;
4987
634k
}
4988
4989
902k
inline const uint8_t* ccc_block_row(uint8_t bi) noexcept {
4990
902k
  if (bi >= kCccBlockRows) {
4991
0
    bi = 0;
4992
0
  }
4993
902k
  return ccc_block_flat + static_cast<size_t>(bi) * kCccBlockCols;
4994
902k
}
4995
4996
279k
inline const uint16_t* composition_block_row(uint8_t bi) noexcept {
4997
279k
  if (bi >= kCompBlockRows) {
4998
0
    bi = 0;
4999
0
  }
5000
279k
  return composition_block_flat + static_cast<size_t>(bi) * kCompBlockCols;
5001
279k
}
5002
5003
}  // namespace ada::idna
5004
/* end file src/table_store.hpp */
5005
/* begin file src/mapping_tables.cpp */
5006
// IDNA 17.0.0
5007
// Two-level compressed mapping table.
5008
// All constants are derived from the table data; no hardcoded boundaries.
5009
// Total binary size: 48659 bytes (47.5 KB)
5010
//   stage1:        6564 bytes  (3282 uint16_t entries)
5011
//   stage2:       22912 bytes  (179 mixed blocks x 64)
5012
//   bool_blocks:   1800 bytes  (225 uint64_t words)
5013
//   utf8 maps:    17383 bytes
5014
5015
// clang-format off
5016
#ifndef ADA_IDNA_MAPPING_TABLE_H
5017
#define ADA_IDNA_MAPPING_TABLE_H
5018
#include <cstdint>
5019
5020
namespace ada::idna {
5021
5022
// Block size for two-level table (2^6 = 64 code points per block).
5023
constexpr uint32_t IDNA_BLOCK_BITS = 6u;
5024
constexpr uint32_t IDNA_BLOCK_SIZE = 64u;
5025
constexpr uint32_t IDNA_BLOCK_MASK = 63u;
5026
5027
// Sentinel values stored in stage2 / returned by lookup.
5028
constexpr uint16_t IDNA_VALID      = 0xFFFF;  // code point is valid as-is
5029
constexpr uint16_t IDNA_DISALLOWED = 0xFFFE;  // code point is disallowed
5030
constexpr uint16_t IDNA_IGNORED    = 0x0000;    // ignored (index into empty UTF-8 entry)
5031
5032
// Bit 15 of a stage1 entry: set = boolean block, clear = mixed block.
5033
constexpr uint16_t IDNA_BOOL_FLAG  = 0x8000;
5034
5035
// Two-level table covers code points [0, IDNA_LOW_RANGE_END).
5036
// Derived from the highest non-disallowed code point below the high-ignored range,
5037
// rounded up to the next 64-code-point block boundary.
5038
constexpr uint32_t IDNA_LOW_RANGE_END    = 0x00033480;
5039
5040
// Variation selectors supplement: U+E0100..U+E01EF are all ignored.
5041
// These are handled with a simple range check; everything else above
5042
// IDNA_LOW_RANGE_END is disallowed.
5043
constexpr uint32_t IDNA_HIGH_IGNORED_START = 0x000E0100;
5044
constexpr uint32_t IDNA_HIGH_IGNORED_END   = 0x000E01F0;  // exclusive
5045
5046
// idna_stage1[cp >> 6]: one entry per 64-code-point block.
5047
// Bit 15 set  -> lower 15 bits = index into idna_bool_blocks[].
5048
// Bit 15 clear -> value = base offset into idna_stage2[] for this block.
5049
5050
}  // namespace ada::idna
5051
#endif  // ADA_IDNA_MAPPING_TABLE_H
5052
/* end file src/mapping_tables.cpp */
5053
5054
namespace ada::idna {
5055
5056
// --- O(1) two-level table lookup ---------------------------------------------
5057
//
5058
// Returns one of:
5059
//   IDNA_VALID      - keep code point in output unchanged
5060
//   IDNA_DISALLOWED - code point is not allowed (map() returns error)
5061
//   IDNA_IGNORED    - code point is ignored (index 0 = empty UTF-8 entry)
5062
//   other           - byte offset into idna_utf8_mappings[] (null-terminated)
5063
//
5064
// Assumes ensure_tables() has already been called by the public entry point.
5065
436k
static uint16_t idna_lookup(uint32_t cp) noexcept {
5066
436k
  if (cp < IDNA_LOW_RANGE_END) {
5067
433k
    uint16_t ref = idna_stage1[cp >> IDNA_BLOCK_BITS];
5068
433k
    if (ref & IDNA_BOOL_FLAG) {
5069
179k
      uint32_t bit_idx =
5070
179k
          static_cast<uint32_t>(ref & ~IDNA_BOOL_FLAG) * IDNA_BLOCK_SIZE +
5071
179k
          (cp & IDNA_BLOCK_MASK);
5072
179k
      bool is_valid = (idna_bool_blocks[bit_idx >> 6] >> (bit_idx & 63u)) & 1u;
5073
179k
      return is_valid ? IDNA_VALID : IDNA_DISALLOWED;
5074
179k
    }
5075
254k
    return idna_stage2[ref + (cp & IDNA_BLOCK_MASK)];
5076
433k
  }
5077
5078
2.36k
  if (cp >= IDNA_HIGH_IGNORED_START && cp < IDNA_HIGH_IGNORED_END) {
5079
1.53k
    return IDNA_IGNORED;
5080
1.53k
  }
5081
5082
824
  return IDNA_DISALLOWED;
5083
2.36k
}
5084
5085
// Advances *ptr past one well-formed UTF-8 code point from the mapping table.
5086
322k
static char32_t utf8_next(const uint8_t*& ptr) noexcept {
5087
322k
  uint8_t b0 = *ptr++;
5088
322k
  if (b0 < 0x80u) return static_cast<char32_t>(b0);
5089
259k
  if (b0 < 0xE0u) {
5090
249k
    uint32_t cp = (b0 & 0x1Fu) << 6;
5091
249k
    cp |= (*ptr++ & 0x3Fu);
5092
249k
    return static_cast<char32_t>(cp);
5093
249k
  }
5094
10.0k
  if (b0 < 0xF0u) {
5095
9.61k
    uint32_t cp = (b0 & 0x0Fu) << 12;
5096
9.61k
    cp |= ((*ptr++ & 0x3Fu) << 6);
5097
9.61k
    cp |= (*ptr++ & 0x3Fu);
5098
9.61k
    return static_cast<char32_t>(cp);
5099
9.61k
  }
5100
440
  uint32_t cp = (b0 & 0x07u) << 18;
5101
440
  cp |= ((*ptr++ & 0x3Fu) << 12);
5102
440
  cp |= ((*ptr++ & 0x3Fu) << 6);
5103
440
  cp |= (*ptr++ & 0x3Fu);
5104
440
  return static_cast<char32_t>(cp);
5105
10.0k
}
5106
5107
// Count UTF-8 code points in a null-terminated mapping string (trusted table).
5108
30.8k
static size_t utf8_count_codepoints(const uint8_t* ptr) noexcept {
5109
30.8k
  size_t n = 0;
5110
353k
  while (*ptr != 0) {
5111
322k
    ++n;
5112
322k
    if (*ptr < 0x80u) {
5113
63.0k
      ++ptr;
5114
259k
    } else if (*ptr < 0xE0u) {
5115
249k
      ptr += 2;
5116
249k
    } else if (*ptr < 0xF0u) {
5117
9.62k
      ptr += 3;
5118
9.62k
    } else {
5119
440
      ptr += 4;
5120
440
    }
5121
322k
  }
5122
30.8k
  return n;
5123
30.8k
}
5124
5125
// --- ASCII fast path ---------------------------------------------------------
5126
13.4k
void ascii_map(char* input, size_t length) {
5127
40.3k
  auto broadcast = [](uint8_t v) -> uint64_t {
5128
40.3k
    return 0x101010101010101ull * v;
5129
40.3k
  };
5130
13.4k
  uint64_t broadcast_80 = broadcast(0x80);
5131
13.4k
  uint64_t broadcast_Ap = broadcast(128 - 'A');
5132
13.4k
  uint64_t broadcast_Zp = broadcast(128 - 'Z' - 1);
5133
13.4k
  size_t i = 0;
5134
5135
49.8k
  for (; i + 7 < length; i += 8) {
5136
36.3k
    uint64_t word{};
5137
36.3k
    std::memcpy(&word, input + i, sizeof(word));
5138
36.3k
    word ^=
5139
36.3k
        (((word + broadcast_Ap) ^ (word + broadcast_Zp)) & broadcast_80) >> 2;
5140
36.3k
    std::memcpy(input + i, &word, sizeof(word));
5141
36.3k
  }
5142
13.4k
  if (i < length) {
5143
7.21k
    uint64_t word{};
5144
7.21k
    std::memcpy(&word, input + i, length - i);
5145
7.21k
    word ^=
5146
7.21k
        (((word + broadcast_Ap) ^ (word + broadcast_Zp)) & broadcast_80) >> 2;
5147
7.21k
    std::memcpy(input + i, &word, length - i);
5148
7.21k
  }
5149
13.4k
}
5150
5151
// Two-pass map: first validate + exact size, then write once (no growth
5152
// realloc).
5153
18.4k
bool map(std::u32string_view input, std::u32string& out) {
5154
  //  [Map](https://www.unicode.org/reports/tr46/#ProcessingStepMap).
5155
18.4k
  out.clear();
5156
18.4k
  if (!ensure_tables()) {
5157
0
    return false;
5158
0
  }
5159
5160
  // Pass 1: validate and compute exact output length.
5161
18.4k
  size_t out_size = 0;
5162
219k
  for (char32_t x : input) {
5163
219k
    uint16_t status = idna_lookup(static_cast<uint32_t>(x));
5164
219k
    if (status == IDNA_DISALLOWED) {
5165
1.76k
      return false;
5166
1.76k
    }
5167
217k
    if (status == IDNA_VALID) {
5168
186k
      ++out_size;
5169
186k
      continue;
5170
186k
    }
5171
30.8k
    if (static_cast<size_t>(status) >= idna_utf8_mappings_size) {
5172
0
      return false;
5173
0
    }
5174
30.8k
    out_size += utf8_count_codepoints(idna_utf8_mappings + status);
5175
30.8k
  }
5176
5177
  // Pass 2: write into a single allocation.
5178
16.6k
  out.resize(out_size);
5179
16.6k
  size_t w = 0;
5180
216k
  for (char32_t x : input) {
5181
216k
    uint16_t status = idna_lookup(static_cast<uint32_t>(x));
5182
216k
    if (status == IDNA_VALID) {
5183
186k
      out[w++] = x;
5184
186k
      continue;
5185
186k
    }
5186
    // IGNORED or mapped (status already validated in pass 1).
5187
30.6k
    const uint8_t* ptr = idna_utf8_mappings + status;
5188
353k
    while (*ptr != 0) {
5189
322k
      out[w++] = utf8_next(ptr);
5190
322k
    }
5191
30.6k
  }
5192
16.6k
  return true;
5193
18.4k
}
5194
5195
3.77k
std::u32string map(std::u32string_view input) {
5196
3.77k
  std::u32string answer;
5197
3.77k
  if (!map(input, answer)) {
5198
289
    return {};
5199
289
  }
5200
3.48k
  return answer;
5201
3.77k
}
5202
5203
}  // namespace ada::idna
5204
/* end file src/mapping.cpp */
5205
/* begin file src/normalization.cpp */
5206
/* begin file include/ada/idna/normalization.h */
5207
#ifndef ADA_IDNA_NORMALIZATION_H
5208
#define ADA_IDNA_NORMALIZATION_H
5209
5210
#include <string>
5211
#include <string_view>
5212
5213
namespace ada::idna {
5214
5215
// Returns true if `input` is already in Unicode Normalization Form C.
5216
// Requires that internal tables have been loaded (call ensure via normalize
5217
// or map first, or this returns false if tables are unavailable).
5218
[[nodiscard]] bool is_already_nfc(std::u32string_view input) noexcept;
5219
5220
// Normalize the characters according to IDNA (Unicode Normalization Form C).
5221
// Returns false if the internal Unicode tables could not be loaded; in that
5222
// case `input` is left unchanged. Skips work when the string is already NFC.
5223
[[nodiscard]] bool normalize(std::u32string& input);
5224
5225
}  // namespace ada::idna
5226
#endif
5227
/* end file include/ada/idna/normalization.h */
5228
/* begin file src/normalization_tables.cpp */
5229
// Normalization table helpers.
5230
// Array payloads live in the DEFLATE blob (table_store.hpp).
5231
// clang-format off
5232
#ifndef ADA_IDNA_NORMALIZATION_TABLES_H
5233
#define ADA_IDNA_NORMALIZATION_TABLES_H
5234
5235
namespace ada::idna {
5236
5237
// Accessors and multi-stage tables are provided by table_store.hpp after
5238
// ensure_tables(). Lookup code matches the classic O(1) uni-algo layout.
5239
5240
}  // namespace ada::idna
5241
#endif  // ADA_IDNA_NORMALIZATION_TABLES_H
5242
/* end file src/normalization_tables.cpp */
5243
5244
#include <cstdint>
5245
5246
namespace ada::idna {
5247
5248
// See
5249
// https://github.com/uni-algo/uni-algo/blob/c612968c5ed3ace39bde4c894c24286c5f2c7fe2/include/uni_algo/impl/impl_norm.h#L467
5250
constexpr char32_t hangul_sbase = 0xAC00;
5251
constexpr char32_t hangul_tbase = 0x11A7;
5252
constexpr char32_t hangul_vbase = 0x1161;
5253
constexpr char32_t hangul_lbase = 0x1100;
5254
constexpr char32_t hangul_lcount = 19;
5255
constexpr char32_t hangul_vcount = 21;
5256
constexpr char32_t hangul_tcount = 28;
5257
constexpr char32_t hangul_ncount = hangul_vcount * hangul_tcount;
5258
constexpr char32_t hangul_scount =
5259
    hangul_lcount * hangul_vcount * hangul_tcount;
5260
5261
// Canonical decomposition length (0 if none / compatibility-only / Hangul
5262
// syllable). Length 1 means a singleton mapping (character is not NFC form).
5263
// Length >= 2 means a primary composite that is already the NFC form of its
5264
// decomposition (e.g. U+00E9 LATIN SMALL LETTER E WITH ACUTE).
5265
583k
static size_t canonical_decomp_length(char32_t current_character) noexcept {
5266
583k
  if (current_character >= hangul_sbase &&
5267
24.6k
      current_character < hangul_sbase + hangul_scount) {
5268
    // Hangul precomposed syllables are NFC.
5269
6.00k
    return 0;
5270
6.00k
  }
5271
577k
  if (current_character >= 0x110000) {
5272
0
    return 0;
5273
0
  }
5274
577k
  const uint8_t di = decomposition_index[current_character >> 8];
5275
577k
  const uint16_t* const decomposition =
5276
577k
      decomposition_block_row(di) + (current_character % 256);
5277
577k
  size_t decomposition_length =
5278
577k
      (decomposition[1] >> 2) - (decomposition[0] >> 2);
5279
577k
  if ((decomposition_length > 0) && (decomposition[0] & 1)) {
5280
13.2k
    decomposition_length = 0;  // compatibility-only: ignored for NFC
5281
13.2k
  }
5282
577k
  return decomposition_length;
5283
577k
}
5284
5285
std::pair<bool, size_t> compute_decomposition_length(
5286
4.13k
    const std::u32string_view input) noexcept {
5287
4.13k
  bool decomposition_needed{false};
5288
4.13k
  size_t additional_elements{0};
5289
32.7k
  for (char32_t current_character : input) {
5290
32.7k
    size_t decomposition_length{0};
5291
5292
32.7k
    if (current_character >= hangul_sbase &&
5293
2.88k
        current_character < hangul_sbase + hangul_scount) {
5294
      // Full NFD-style Hangul decomp for the decompose() step.
5295
1.46k
      decomposition_length = 2;
5296
1.46k
      if ((current_character - hangul_sbase) % hangul_tcount) {
5297
859
        decomposition_length = 3;
5298
859
      }
5299
31.2k
    } else if (current_character < 0x110000) {
5300
31.2k
      const uint8_t di = decomposition_index[current_character >> 8];
5301
31.2k
      const uint16_t* const decomposition =
5302
31.2k
          decomposition_block_row(di) + (current_character % 256);
5303
31.2k
      decomposition_length = (decomposition[1] >> 2) - (decomposition[0] >> 2);
5304
31.2k
      if ((decomposition_length > 0) && (decomposition[0] & 1)) {
5305
364
        decomposition_length = 0;
5306
364
      }
5307
31.2k
    }
5308
32.7k
    if (decomposition_length != 0) {
5309
6.10k
      decomposition_needed = true;
5310
6.10k
      additional_elements += decomposition_length - 1;
5311
6.10k
    }
5312
32.7k
  }
5313
4.13k
  return {decomposition_needed, additional_elements};
5314
4.13k
}
5315
5316
2.71k
void decompose(std::u32string& input, size_t additional_elements) {
5317
2.71k
  input.resize(input.size() + additional_elements);
5318
2.71k
  for (size_t descending_idx = input.size(),
5319
2.71k
              input_count = descending_idx - additional_elements;
5320
23.9k
       input_count--;) {
5321
21.2k
    if (input[input_count] >= hangul_sbase &&
5322
2.44k
        input[input_count] < hangul_sbase + hangul_scount) {
5323
      // Hangul decomposition.
5324
1.46k
      char32_t s_index = input[input_count] - hangul_sbase;
5325
1.46k
      if (s_index % hangul_tcount != 0) {
5326
859
        input[--descending_idx] = hangul_tbase + s_index % hangul_tcount;
5327
859
      }
5328
1.46k
      input[--descending_idx] =
5329
1.46k
          hangul_vbase + (s_index % hangul_ncount) / hangul_tcount;
5330
1.46k
      input[--descending_idx] = hangul_lbase + s_index / hangul_ncount;
5331
19.7k
    } else if (input[input_count] < 0x110000) {
5332
19.7k
      const uint16_t* decomposition =
5333
19.7k
          decomposition_block_row(
5334
19.7k
              decomposition_index[input[input_count] >> 8]) +
5335
19.7k
          (input[input_count] % 256);
5336
19.7k
      uint16_t decomposition_length =
5337
19.7k
          (decomposition[1] >> 2) - (decomposition[0] >> 2);
5338
19.7k
      if (decomposition_length > 0 && (decomposition[0] & 1)) {
5339
353
        decomposition_length = 0;
5340
353
      }
5341
19.7k
      if (decomposition_length > 0) {
5342
4.63k
        const size_t base = static_cast<size_t>(decomposition[0] >> 2);
5343
4.63k
        if (base + decomposition_length > decomposition_data_size) {
5344
0
          input[--descending_idx] = input[input_count];
5345
4.63k
        } else {
5346
14.6k
          while (decomposition_length-- > 0) {
5347
10.0k
            input[--descending_idx] =
5348
10.0k
                decomposition_data[base + decomposition_length];
5349
10.0k
          }
5350
4.63k
        }
5351
15.1k
      } else {
5352
15.1k
        input[--descending_idx] = input[input_count];
5353
15.1k
      }
5354
19.7k
    } else {
5355
0
      input[--descending_idx] = input[input_count];
5356
0
    }
5357
21.2k
  }
5358
2.71k
}
5359
5360
902k
uint8_t get_ccc(char32_t c) noexcept {
5361
902k
  if (c >= 0x110000) {
5362
0
    return 0;
5363
0
  }
5364
902k
  return ccc_block_row(ccc_index[c >> 8])[c % 256];
5365
902k
}
5366
5367
4.13k
void sort_marks(std::u32string& input) {
5368
40.4k
  for (size_t idx = 1; idx < input.size(); idx++) {
5369
36.3k
    uint8_t ccc = get_ccc(input[idx]);
5370
36.3k
    if (ccc == 0) {
5371
26.3k
      continue;
5372
26.3k
    }
5373
9.96k
    auto current_character = input[idx];
5374
9.96k
    size_t back_idx = idx;
5375
16.3k
    while (back_idx != 0 && get_ccc(input[back_idx - 1]) > ccc) {
5376
6.35k
      input[back_idx] = input[back_idx - 1];
5377
6.35k
      back_idx--;
5378
6.35k
    }
5379
9.96k
    input[back_idx] = current_character;
5380
9.96k
  }
5381
4.13k
}
5382
5383
4.13k
void decompose_nfc(std::u32string& input) {
5384
  /**
5385
   * Decompose the domain_name string to Unicode Normalization Form C.
5386
   * @see https://www.unicode.org/reports/tr46/#ProcessingStepDecompose
5387
   */
5388
4.13k
  auto [decomposition_needed, additional_elements] =
5389
4.13k
      compute_decomposition_length(input);
5390
4.13k
  if (decomposition_needed) {
5391
2.71k
    decompose(input, additional_elements);
5392
2.71k
  }
5393
4.13k
  sort_marks(input);
5394
4.13k
}
5395
5396
// Returns true if a composition step would change the string.
5397
13.0k
static bool would_compose(std::u32string_view input) noexcept {
5398
265k
  for (size_t input_count = 0; input_count < input.size();) {
5399
254k
    const char32_t current = input[input_count];
5400
254k
    if (current >= hangul_lbase && current < hangul_lbase + hangul_lcount) {
5401
1.68k
      if (input_count + 1 < input.size() &&
5402
1.58k
          input[input_count + 1] >= hangul_vbase &&
5403
750
          input[input_count + 1] < hangul_vbase + hangul_vcount) {
5404
436
        return true;
5405
436
      }
5406
1.24k
      ++input_count;
5407
1.24k
      continue;
5408
1.68k
    }
5409
252k
    if (current >= hangul_sbase && current < hangul_sbase + hangul_scount) {
5410
2.32k
      if ((current - hangul_sbase) % hangul_tcount &&
5411
1.78k
          input_count + 1 < input.size() &&
5412
1.58k
          input[input_count + 1] > hangul_tbase &&
5413
1.17k
          input[input_count + 1] < hangul_tbase + hangul_tcount) {
5414
207
        return true;
5415
207
      }
5416
2.11k
      ++input_count;
5417
2.11k
      continue;
5418
2.32k
    }
5419
250k
    if (current < 0x110000) {
5420
250k
      const uint16_t* composition =
5421
250k
          composition_block_row(composition_index[current >> 8]) +
5422
250k
          (current % 256);
5423
250k
      int32_t previous_ccc = -1;
5424
250k
      size_t j = input_count;
5425
254k
      for (; j + 1 < input.size(); ++j) {
5426
243k
        uint8_t ccc = get_ccc(input[j + 1]);
5427
243k
        if (composition[1] != composition[0] && previous_ccc < ccc) {
5428
67.9k
          int left = composition[0];
5429
67.9k
          int right = composition[1];
5430
67.9k
          if (left < 0 || right < left ||
5431
67.9k
              static_cast<size_t>(right) > composition_data_size) {
5432
0
            break;
5433
0
          }
5434
184k
          while (left + 2 < right) {
5435
116k
            int middle = left + (((right - left) >> 1) & ~1);
5436
116k
            if (composition_data[static_cast<size_t>(middle)] <= input[j + 1]) {
5437
5.44k
              left = middle;
5438
5.44k
            }
5439
116k
            if (composition_data[static_cast<size_t>(middle)] >= input[j + 1]) {
5440
111k
              right = middle;
5441
111k
            }
5442
116k
          }
5443
67.9k
          if (static_cast<size_t>(left + 1) < composition_data_size &&
5444
67.9k
              composition_data[static_cast<size_t>(left)] == input[j + 1]) {
5445
710
            return true;
5446
710
          }
5447
67.9k
        }
5448
242k
        if (ccc == 0) {
5449
238k
          break;
5450
238k
        }
5451
4.73k
        previous_ccc = ccc;
5452
4.73k
      }
5453
249k
      input_count = j + 1;
5454
249k
      continue;
5455
250k
    }
5456
0
    ++input_count;
5457
0
  }
5458
11.6k
  return false;
5459
13.0k
}
5460
5461
// Trailing canonical combining class of a character: the combining class of the
5462
// last code point of its canonical decomposition, or the character's own class
5463
// when it has none. A precomposed starter such as U+00E1 (a + U+0301, class
5464
// 230) has class 0 but a nonzero trailing class, so a following mark of lower
5465
// class reorders past the hidden mark during normalization.
5466
286k
static uint8_t trailing_ccc(char32_t c) noexcept {
5467
286k
  const size_t length = canonical_decomp_length(c);
5468
286k
  if (length == 0) {
5469
281k
    return get_ccc(c);
5470
281k
  }
5471
5.93k
  const uint16_t* const decomposition =
5472
5.93k
      decomposition_block_row(decomposition_index[c >> 8]) + (c % 256);
5473
5.93k
  const size_t base = decomposition[0] >> 2;
5474
5.93k
  return get_ccc(decomposition_data[base + length - 1]);
5475
286k
}
5476
5477
16.5k
bool is_already_nfc(std::u32string_view input) noexcept {
5478
16.5k
  if (input.empty()) {
5479
0
    return true;
5480
0
  }
5481
16.5k
  if (!tables_are_ready() && !ensure_tables()) {
5482
0
    return false;
5483
0
  }
5484
  // 1) Singleton decompositions are never NFC (e.g. U+212B ANGSTROM SIGN).
5485
  //    Multi-code-point decomps are primary composites that are NFC as-is.
5486
296k
  for (char32_t c : input) {
5487
296k
    if (canonical_decomp_length(c) == 1) {
5488
420
      return false;
5489
420
    }
5490
296k
  }
5491
  // 2) Combining marks already in canonical order. prev_ccc carries the
5492
  //    trailing class of the previous character's canonical decomposition so a
5493
  //    composite starter followed by a lower-class mark is caught.
5494
16.1k
  uint8_t prev_ccc = 0;
5495
290k
  for (char32_t c : input) {
5496
290k
    uint8_t ccc = get_ccc(c);
5497
290k
    if (ccc != 0 && prev_ccc > ccc) {
5498
3.14k
      return false;
5499
3.14k
    }
5500
286k
    prev_ccc = trailing_ccc(c);
5501
286k
  }
5502
  // 3) No pairwise composition would apply (including Hangul L+V / LV+T).
5503
13.0k
  return !would_compose(input);
5504
16.1k
}
5505
5506
4.13k
void compose(std::u32string& input) {
5507
  /**
5508
   * Compose the domain_name string to Unicode Normalization Form C.
5509
   * @see https://www.unicode.org/reports/tr46/#ProcessingStepCompose
5510
   */
5511
4.13k
  size_t input_count{0};
5512
4.13k
  size_t composition_count{0};
5513
30.4k
  for (; input_count < input.size(); input_count++, composition_count++) {
5514
26.3k
    input[composition_count] = input[input_count];
5515
26.3k
    if (input[input_count] >= hangul_lbase &&
5516
7.51k
        input[input_count] < hangul_lbase + hangul_lcount) {
5517
3.17k
      if (input_count + 1 < input.size() &&
5518
3.01k
          input[input_count + 1] >= hangul_vbase &&
5519
2.27k
          input[input_count + 1] < hangul_vbase + hangul_vcount) {
5520
1.92k
        input[composition_count] =
5521
1.92k
            hangul_sbase +
5522
1.92k
            ((input[input_count] - hangul_lbase) * hangul_vcount +
5523
1.92k
             input[input_count + 1] - hangul_vbase) *
5524
1.92k
                hangul_tcount;
5525
1.92k
        input_count++;
5526
1.92k
        if (input_count + 1 < input.size() &&
5527
1.71k
            input[input_count + 1] > hangul_tbase &&
5528
1.14k
            input[input_count + 1] < hangul_tbase + hangul_tcount) {
5529
925
          input[composition_count] += input[++input_count] - hangul_tbase;
5530
925
        }
5531
1.92k
      }
5532
23.1k
    } else if (input[input_count] >= hangul_sbase &&
5533
1.19k
               input[input_count] < hangul_sbase + hangul_scount) {
5534
0
      if ((input[input_count] - hangul_sbase) % hangul_tcount &&
5535
0
          input_count + 1 < input.size() &&
5536
0
          input[input_count + 1] > hangul_tbase &&
5537
0
          input[input_count + 1] < hangul_tbase + hangul_tcount) {
5538
0
        input[composition_count] += input[++input_count] - hangul_tbase;
5539
0
      }
5540
23.1k
    } else if (input[input_count] < 0x110000) {
5541
23.1k
      const uint16_t* composition =
5542
23.1k
          composition_block_row(composition_index[input[input_count] >> 8]) +
5543
23.1k
          (input[input_count] % 256);
5544
23.1k
      size_t initial_composition_count = composition_count;
5545
34.4k
      for (int32_t previous_ccc = -1; input_count + 1 < input.size();
5546
30.7k
           input_count++) {
5547
30.7k
        uint8_t ccc = get_ccc(input[input_count + 1]);
5548
5549
30.7k
        if (composition[1] != composition[0] && previous_ccc < ccc) {
5550
12.3k
          int left = composition[0];
5551
12.3k
          int right = composition[1];
5552
12.3k
          if (left < 0 || right < left ||
5553
12.3k
              static_cast<size_t>(right) > composition_data_size) {
5554
0
            break;
5555
0
          }
5556
33.6k
          while (left + 2 < right) {
5557
21.3k
            int middle = left + (((right - left) >> 1) & ~1);
5558
21.3k
            if (composition_data[static_cast<size_t>(middle)] <=
5559
21.3k
                input[input_count + 1]) {
5560
14.2k
              left = middle;
5561
14.2k
            }
5562
21.3k
            if (composition_data[static_cast<size_t>(middle)] >=
5563
21.3k
                input[input_count + 1]) {
5564
10.0k
              right = middle;
5565
10.0k
            }
5566
21.3k
          }
5567
12.3k
          if (static_cast<size_t>(left + 1) < composition_data_size &&
5568
12.3k
              composition_data[static_cast<size_t>(left)] ==
5569
12.3k
                  input[input_count + 1]) {
5570
5.73k
            char32_t composed = composition_data[static_cast<size_t>(left + 1)];
5571
5.73k
            input[initial_composition_count] = composed;
5572
5.73k
            composition =
5573
5.73k
                composition_block_row(composition_index[composed >> 8]) +
5574
5.73k
                (composed % 256);
5575
5.73k
            continue;
5576
5.73k
          }
5577
12.3k
        }
5578
5579
24.9k
        if (ccc == 0) {
5580
19.4k
          break;
5581
19.4k
        }
5582
5.50k
        previous_ccc = ccc;
5583
5.50k
        input[++composition_count] = input[input_count + 1];
5584
5.50k
      }
5585
23.1k
    }
5586
26.3k
  }
5587
5588
4.13k
  if (composition_count < input_count) {
5589
3.06k
    input.resize(composition_count);
5590
3.06k
  }
5591
4.13k
}
5592
5593
13.4k
bool normalize(std::u32string& input) {
5594
  /**
5595
   * Normalize the characters according to IDNA (Unicode Normalization Form C).
5596
   * @see https://www.unicode.org/reports/tr46/#ProcessingStepNormalize
5597
   */
5598
13.4k
  if (!ensure_tables() || decomposition_index == nullptr ||
5599
13.4k
      composition_index == nullptr) {
5600
0
    return false;
5601
0
  }
5602
13.4k
  if (is_already_nfc(input)) {
5603
9.27k
    return true;
5604
9.27k
  }
5605
4.13k
  decompose_nfc(input);
5606
4.13k
  compose(input);
5607
4.13k
  return true;
5608
13.4k
}
5609
5610
}  // namespace ada::idna
5611
/* end file src/normalization.cpp */
5612
/* begin file src/punycode.cpp */
5613
/* begin file include/ada/idna/punycode.h */
5614
#ifndef ADA_IDNA_PUNYCODE_H
5615
#define ADA_IDNA_PUNYCODE_H
5616
5617
#include <string>
5618
#include <string_view>
5619
5620
namespace ada::idna {
5621
5622
bool punycode_to_utf32(std::string_view input, std::u32string& out);
5623
bool verify_punycode(std::string_view input);
5624
bool utf32_to_punycode(std::u32string_view input, std::string& out);
5625
5626
}  // namespace ada::idna
5627
5628
#endif  // ADA_IDNA_PUNYCODE_H
5629
/* end file include/ada/idna/punycode.h */
5630
5631
#include <cstdint>
5632
5633
namespace ada::idna {
5634
5635
constexpr int32_t base = 36;
5636
constexpr int32_t tmin = 1;
5637
constexpr int32_t tmax = 26;
5638
constexpr int32_t skew = 38;
5639
constexpr int32_t damp = 700;
5640
constexpr int32_t initial_bias = 72;
5641
constexpr uint32_t initial_n = 128;
5642
5643
183k
static constexpr int32_t char_to_digit_value(char value) {
5644
183k
  if (value >= 'a' && value <= 'z') return value - 'a';
5645
35.2k
  if (value >= '0' && value <= '9') return value - '0' + 26;
5646
6.50k
  return -1;
5647
35.2k
}
5648
5649
89.9k
static constexpr char digit_to_char(int32_t digit) {
5650
89.9k
  return digit < 26 ? char(digit + 97) : char(digit + 22);
5651
89.9k
}
5652
5653
194k
static constexpr int32_t adapt(int32_t d, int32_t n, bool firsttime) {
5654
194k
  if (firsttime) {
5655
18.7k
    d = d / damp;
5656
175k
  } else {
5657
175k
    d = d / 2;
5658
175k
  }
5659
194k
  d += d / n;
5660
194k
  int32_t k = 0;
5661
209k
  while (d > ((base - tmin) * tmax) / 2) {
5662
15.2k
    d /= base - tmin;
5663
15.2k
    k += base;
5664
15.2k
  }
5665
194k
  return k + (((base - tmin + 1) * d) / (d + skew));
5666
194k
}
5667
5668
28.7k
bool punycode_to_utf32(std::string_view input, std::u32string &out) {
5669
28.7k
  int32_t written_out{0};
5670
28.7k
  out.reserve(out.size() + input.size());
5671
28.7k
  uint32_t n = initial_n;
5672
28.7k
  int32_t i = 0;
5673
28.7k
  int32_t bias = initial_bias;
5674
  // grab ascii content
5675
28.7k
  size_t end_of_ascii = input.find_last_of('-');
5676
28.7k
  if (end_of_ascii != std::string_view::npos) {
5677
60.7k
    for (uint8_t c : input.substr(0, end_of_ascii)) {
5678
60.7k
      if (c >= 0x80) {
5679
298
        return false;
5680
298
      }
5681
60.4k
      out.push_back(c);
5682
60.4k
      written_out++;
5683
60.4k
    }
5684
4.24k
    input.remove_prefix(end_of_ascii + 1);
5685
4.24k
  }
5686
141k
  while (!input.empty()) {
5687
117k
    int32_t oldi = i;
5688
117k
    int32_t w = 1;
5689
164k
    for (int32_t k = base;; k += base) {
5690
164k
      if (input.empty()) {
5691
394
        return false;
5692
394
      }
5693
164k
      uint8_t code_point = input.front();
5694
164k
      input.remove_prefix(1);
5695
164k
      int32_t digit = char_to_digit_value(code_point);
5696
164k
      if (digit < 0) {
5697
3.87k
        return false;
5698
3.87k
      }
5699
160k
      if (digit > (0x7fffffff - i) / w) {
5700
99
        return false;
5701
99
      }
5702
160k
      i = i + digit * w;
5703
160k
      int32_t t = k <= bias ? tmin : k >= bias + tmax ? tmax : k - bias;
5704
160k
      if (digit < t) {
5705
113k
        break;
5706
113k
      }
5707
47.3k
      if (w > 0x7fffffff / (base - t)) {
5708
0
        return false;
5709
0
      }
5710
47.3k
      w = w * (base - t);
5711
47.3k
    }
5712
113k
    bias = adapt(i - oldi, written_out + 1, oldi == 0);
5713
113k
    if (i / (written_out + 1) > int32_t(0x7fffffff - n)) {
5714
130
      return false;
5715
130
    }
5716
113k
    n = n + i / (written_out + 1);
5717
113k
    i = i % (written_out + 1);
5718
113k
    if (n < 0x80) {
5719
0
      return false;
5720
0
    }
5721
113k
    out.insert(out.begin() + i, n);
5722
113k
    written_out++;
5723
113k
    ++i;
5724
113k
  }
5725
  // See https://github.com/whatwg/url/issues/803
5726
  // Reject labels whose decoded form begins with "xn--" (double-encoded ACE).
5727
23.9k
  if (out.size() >= 4 && out[0] == U'x' && out[1] == U'n' && out[2] == U'-' &&
5728
447
      out[3] == U'-') {
5729
301
    return false;
5730
301
  }
5731
23.6k
  return true;
5732
23.9k
}
5733
5734
4.54k
bool verify_punycode(std::string_view input) {
5735
  // Track only the first 4 decoded code points to check for the "xn--" prefix.
5736
  // This avoids heap allocation while still detecting double-encoded ACE
5737
  // labels.
5738
4.54k
  uint32_t first4[4]{};
5739
4.54k
  size_t written_out{0};
5740
4.54k
  uint32_t n = initial_n;
5741
4.54k
  int32_t i = 0;
5742
4.54k
  int32_t bias = initial_bias;
5743
  // grab ascii content
5744
4.54k
  size_t end_of_ascii = input.find_last_of('-');
5745
4.54k
  if (end_of_ascii != std::string_view::npos) {
5746
33.7k
    for (uint8_t c : input.substr(0, end_of_ascii)) {
5747
33.7k
      if (c >= 0x80) {
5748
276
        return false;
5749
276
      }
5750
33.4k
      if (written_out < 4) {
5751
4.16k
        first4[written_out] = c;
5752
4.16k
      }
5753
33.4k
      written_out++;
5754
33.4k
    }
5755
1.09k
    input.remove_prefix(end_of_ascii + 1);
5756
1.09k
  }
5757
14.8k
  while (!input.empty()) {
5758
13.3k
    int32_t oldi = i;
5759
13.3k
    int32_t w = 1;
5760
19.3k
    for (int32_t k = base;; k += base) {
5761
19.3k
      if (input.empty()) {
5762
88
        return false;
5763
88
      }
5764
19.2k
      uint8_t code_point = input.front();
5765
19.2k
      input.remove_prefix(1);
5766
19.2k
      int32_t digit = char_to_digit_value(code_point);
5767
19.2k
      if (digit < 0) {
5768
2.62k
        return false;
5769
2.62k
      }
5770
16.6k
      if (digit > (0x7fffffff - i) / w) {
5771
19
        return false;
5772
19
      }
5773
16.6k
      i = i + digit * w;
5774
16.6k
      int32_t t = k <= bias ? tmin : k >= bias + tmax ? tmax : k - bias;
5775
16.6k
      if (digit < t) {
5776
10.5k
        break;
5777
10.5k
      }
5778
6.01k
      if (w > 0x7fffffff / (base - t)) {
5779
0
        return false;
5780
0
      }
5781
6.01k
      w = w * (base - t);
5782
6.01k
    }
5783
10.5k
    bias = adapt(i - oldi, int32_t(written_out + 1), oldi == 0);
5784
10.5k
    if (i / (written_out + 1) > 0x7fffffff - n) {
5785
32
      return false;
5786
32
    }
5787
10.5k
    n = n + i / int32_t(written_out + 1);
5788
10.5k
    i = i % int32_t(written_out + 1);
5789
10.5k
    if (n < 0x80) {
5790
0
      return false;
5791
0
    }
5792
    // Simulate insert at position i, maintaining only the first 4 slots.
5793
10.5k
    size_t insert_pos = size_t(i);
5794
10.5k
    if (insert_pos < 4) {
5795
6.32k
      for (size_t j = 3; j > insert_pos; j--) {
5796
3.99k
        first4[j] = first4[j - 1];
5797
3.99k
      }
5798
2.32k
      first4[insert_pos] = n;
5799
2.32k
    }
5800
10.5k
    written_out++;
5801
10.5k
    ++i;
5802
10.5k
  }
5803
  // See https://github.com/whatwg/url/issues/803
5804
  // Reject labels whose decoded form begins with "xn--" (double-encoded ACE).
5805
1.50k
  if (written_out >= 4 && first4[0] == U'x' && first4[1] == U'n' &&
5806
381
      first4[2] == U'-' && first4[3] == U'-') {
5807
220
    return false;
5808
220
  }
5809
1.28k
  return true;
5810
1.50k
}
5811
5812
4.25k
bool utf32_to_punycode(std::u32string_view input, std::string &out) {
5813
4.25k
  out.reserve(input.size() + out.size());
5814
4.25k
  uint32_t n = initial_n;
5815
4.25k
  int32_t d = 0;
5816
4.25k
  int32_t bias = initial_bias;
5817
4.25k
  size_t h = 0;
5818
  // first push the ascii content
5819
94.0k
  for (uint32_t c : input) {
5820
94.0k
    if (c < 0x80) {
5821
23.5k
      ++h;
5822
23.5k
      out.push_back(char(c));
5823
23.5k
    }
5824
94.0k
    if (c > 0x10ffff || (c >= 0xd800 && c < 0xe000)) {
5825
156
      return false;
5826
156
    }
5827
94.0k
  }
5828
4.10k
  size_t b = h;
5829
4.10k
  if (b > 0) {
5830
1.90k
    out.push_back('-');
5831
1.90k
  }
5832
16.1k
  while (h < input.size()) {
5833
12.0k
    uint32_t m = 0x10FFFF;
5834
938k
    for (auto code_point : input) {
5835
938k
      if (code_point >= n && code_point < m) m = code_point;
5836
938k
    }
5837
5838
12.0k
    if ((m - n) > (0x7fffffff - d) / (h + 1)) {
5839
0
      return false;
5840
0
    }
5841
12.0k
    d = d + int32_t((m - n) * (h + 1));
5842
12.0k
    n = m;
5843
938k
    for (auto c : input) {
5844
938k
      if (c < n) {
5845
549k
        if (d == 0x7fffffff) {
5846
0
          return false;
5847
0
        }
5848
549k
        ++d;
5849
549k
      }
5850
938k
      if (c == n) {
5851
70.2k
        int32_t q = d;
5852
89.9k
        for (int32_t k = base;; k += base) {
5853
89.9k
          int32_t t = k <= bias ? tmin : k >= bias + tmax ? tmax : k - bias;
5854
5855
89.9k
          if (q < t) {
5856
70.2k
            break;
5857
70.2k
          }
5858
19.6k
          out.push_back(digit_to_char(t + ((q - t) % (base - t))));
5859
19.6k
          q = (q - t) / (base - t);
5860
19.6k
        }
5861
70.2k
        out.push_back(digit_to_char(q));
5862
70.2k
        bias = adapt(d, int32_t(h + 1), h == b);
5863
70.2k
        d = 0;
5864
70.2k
        ++h;
5865
70.2k
      }
5866
938k
    }
5867
12.0k
    ++d;
5868
12.0k
    ++n;
5869
12.0k
  }
5870
4.10k
  return true;
5871
4.10k
}
5872
5873
}  // namespace ada::idna
5874
/* end file src/punycode.cpp */
5875
/* begin file src/validity.cpp */
5876
5877
#include <algorithm>
5878
#include <span>
5879
#include <string_view>
5880
5881
namespace ada::idna {
5882
5883
enum direction : uint8_t {
5884
  NONE,
5885
  BN,
5886
  CS,
5887
  ES,
5888
  ON,
5889
  EN,
5890
  L,
5891
  R,
5892
  NSM,
5893
  AL,
5894
  AN,
5895
  ET,
5896
  WS,
5897
  RLO,
5898
  LRO,
5899
  PDF,
5900
  RLE,
5901
  RLI,
5902
  FSI,
5903
  PDI,
5904
  LRI,
5905
  B,
5906
  S,
5907
  LRE
5908
};
5909
5910
// Bidi direction ranges live in the compressed blob as const SoA arrays
5911
// (dir_start / dir_final / dir_value). See table_store.hpp layout asserts.
5912
5913
// CheckJoiners and CheckBidi are true for URL specification.
5914
5915
// Assumes ensure_tables() has already been called by is_label_valid().
5916
92.1k
inline static direction find_direction(uint32_t code_point) noexcept {
5917
  // Binary search on dir_final (sorted upper bounds).
5918
92.1k
  size_t lo = 0, hi = dir_table_count;
5919
1.05M
  while (lo < hi) {
5920
966k
    size_t mid = lo + (hi - lo) / 2;
5921
966k
    if (dir_final[mid] < code_point) {
5922
377k
      lo = mid + 1;
5923
589k
    } else {
5924
589k
      hi = mid;
5925
589k
    }
5926
966k
  }
5927
92.1k
  if (lo == dir_table_count) {
5928
902
    return direction::NONE;
5929
902
  }
5930
91.2k
  return code_point >= dir_start[lo] ? static_cast<direction>(dir_value[lo])
5931
91.2k
                                     : direction::NONE;
5932
92.1k
}
5933
5934
inline static size_t find_last_not_of_nsm(
5935
10.2k
    const std::u32string_view label) noexcept {
5936
13.5k
  for (int i = static_cast<int>(label.size() - 1); i >= 0; i--)
5937
13.5k
    if (find_direction(label[i]) != direction::NSM) return i;
5938
5939
0
  return std::u32string_view::npos;
5940
10.2k
}
5941
5942
// An RTL label is a label that contains at least one character of type R, AL,
5943
// or AN. https://www.rfc-editor.org/rfc/rfc5893#section-2
5944
10.2k
inline static bool is_rtl_label(const std::u32string_view label) noexcept {
5945
10.2k
  const size_t mask =
5946
10.2k
      (1u << direction::R) | (1u << direction::AL) | (1u << direction::AN);
5947
5948
10.2k
  size_t directions = 0;
5949
72.1k
  for (size_t i = 0; i < label.size(); i++) {
5950
61.9k
    directions |= 1u << find_direction(label[i]);
5951
61.9k
  }
5952
10.2k
  return (directions & mask) != 0;
5953
10.2k
}
5954
5955
12.6k
bool is_label_valid(const std::u32string_view label) {
5956
12.6k
  if (label.empty()) {
5957
0
    return true;
5958
0
  }
5959
12.6k
  if (!ensure_tables() || combining_ranges == nullptr || dir_start == nullptr ||
5960
12.6k
      dir_final == nullptr || dir_value == nullptr) {
5961
0
    return false;
5962
0
  }
5963
5964
  ///////////////
5965
  // We have a normalization step which ensures that we are in NFC.
5966
  // If we receive punycode, we normalize and check that the normalized
5967
  // version matches the original.
5968
  // --------------------------------------
5969
  // The label must be in Unicode Normalization Form NFC.
5970
5971
  // Current URL standard indicatest that CheckHyphens is set to false.
5972
  // ---------------------------------------
5973
  // If CheckHyphens, the label must not contain a U+002D HYPHEN-MINUS character
5974
  // in both the third and fourth positions. If CheckHyphens, the label must
5975
  // neither begin nor end with a U+002D HYPHEN-MINUS character.
5976
5977
  // This is not necessary because we segment the
5978
  // labels by '.'.
5979
  // ---------------------------------------
5980
  // The label must not contain a U+002E ( . ) FULL STOP.
5981
  // if (label.find('.') != std::string_view::npos) return false;
5982
5983
  // The label must not begin with a combining mark.
5984
  // Range membership via lower_bound on range end.
5985
12.6k
  const std::span<const uint32_t[2]> comb_span{combining_ranges,
5986
12.6k
                                               combining_range_count};
5987
12.6k
  const auto comb_it = std::ranges::lower_bound(
5988
109k
      comb_span, label.front(), {}, [](const auto& range) { return range[1]; });
5989
12.6k
  if (comb_it != comb_span.end() && label.front() >= (*comb_it)[0]) {
5990
275
    return false;
5991
275
  }
5992
  // We verify this next step as part of the mapping:
5993
  // ---------------------------------------------
5994
  // Each code point in the label must only have certain status values
5995
  // according to Section 5, IDNA Mapping Table:
5996
  // - For Transitional Processing, each value must be valid.
5997
  // - For Nontransitional Processing, each value must be either valid or
5998
  // deviation.
5999
6000
  // If CheckJoiners, the label must satisfy the ContextJ rules from Appendix
6001
  // A, in The Unicode Code Points and Internationalized Domain Names for
6002
  // Applications (IDNA) [IDNA2008].
6003
12.3k
  constexpr static uint32_t virama[] = {
6004
12.3k
      0x094D,  0x09CD,  0x0A4D,  0x0ACD,  0x0B4D,  0x0BCD,  0x0C4D,  0x0CCD,
6005
12.3k
      0x0D3B,  0x0D3C,  0x0D4D,  0x0DCA,  0x0E3A,  0x0EBA,  0x0F84,  0x1039,
6006
12.3k
      0x103A,  0x1714,  0x1734,  0x17D2,  0x1A60,  0x1B44,  0x1BAA,  0x1BAB,
6007
12.3k
      0x1BF2,  0x1BF3,  0x2D7F,  0xA806,  0xA82C,  0xA8C4,  0xA953,  0xA9C0,
6008
12.3k
      0xAAF6,  0xABED,  0x10A3F, 0x11046, 0x1107F, 0x110B9, 0x11133, 0x11134,
6009
12.3k
      0x111C0, 0x11235, 0x112EA, 0x1134D, 0x11442, 0x114C2, 0x115BF, 0x1163F,
6010
12.3k
      0x116B6, 0x1172B, 0x11839, 0x1193D, 0x1193E, 0x119E0, 0x11A34, 0x11A47,
6011
12.3k
      0x11A99, 0x11C3F, 0x11D44, 0x11D45, 0x11D97};
6012
12.3k
  constexpr static uint32_t R[] = {
6013
12.3k
      0x622, 0x623, 0x624, 0x625, 0x627, 0x629, 0x62f, 0x630, 0x631,
6014
12.3k
      0x632, 0x648, 0x671, 0x672, 0x673, 0x675, 0x676, 0x677, 0x688,
6015
12.3k
      0x689, 0x68a, 0x68b, 0x68c, 0x68d, 0x68e, 0x68f, 0x690, 0x691,
6016
12.3k
      0x692, 0x693, 0x694, 0x695, 0x696, 0x697, 0x698, 0x699, 0x6c0,
6017
12.3k
      0x6c3, 0x6c4, 0x6c5, 0x6c6, 0x6c7, 0x6c8, 0x6c9, 0x6ca, 0x6cb,
6018
12.3k
      0x6cd, 0x6cf, 0x6d2, 0x6d3, 0x6d5, 0x6ee, 0x6ef, 0x710, 0x715,
6019
12.3k
      0x716, 0x717, 0x718, 0x719, 0x71e, 0x728, 0x72a, 0x72c, 0x72f,
6020
12.3k
      0x74d, 0x759, 0x75a, 0x75b, 0x854, 0x8aa, 0x8ab, 0x8ac};
6021
12.3k
  constexpr static uint32_t L[] = {0xa872};
6022
12.3k
  constexpr static uint32_t D[] = {
6023
12.3k
      0x620,  0x626,  0x628,  0x62a,  0x62b,  0x62c,  0x62d,  0x62e,  0x633,
6024
12.3k
      0x634,  0x635,  0x636,  0x637,  0x638,  0x639,  0x63a,  0x63b,  0x63c,
6025
12.3k
      0x63d,  0x63e,  0x63f,  0x641,  0x642,  0x643,  0x644,  0x645,  0x646,
6026
12.3k
      0x647,  0x649,  0x64a,  0x66e,  0x66f,  0x678,  0x679,  0x67a,  0x67b,
6027
12.3k
      0x67c,  0x67d,  0x67e,  0x67f,  0x680,  0x681,  0x682,  0x683,  0x684,
6028
12.3k
      0x685,  0x686,  0x687,  0x69a,  0x69b,  0x69c,  0x69d,  0x69e,  0x69f,
6029
12.3k
      0x6a0,  0x6a1,  0x6a2,  0x6a3,  0x6a4,  0x6a5,  0x6a6,  0x6a7,  0x6a8,
6030
12.3k
      0x6a9,  0x6aa,  0x6ab,  0x6ac,  0x6ad,  0x6ae,  0x6af,  0x6b0,  0x6b1,
6031
12.3k
      0x6b2,  0x6b3,  0x6b4,  0x6b5,  0x6b6,  0x6b7,  0x6b8,  0x6b9,  0x6ba,
6032
12.3k
      0x6bb,  0x6bc,  0x6bd,  0x6be,  0x6bf,  0x6c1,  0x6c2,  0x6cc,  0x6ce,
6033
12.3k
      0x6d0,  0x6d1,  0x6fa,  0x6fb,  0x6fc,  0x6ff,  0x712,  0x713,  0x714,
6034
12.3k
      0x71a,  0x71b,  0x71c,  0x71d,  0x71f,  0x720,  0x721,  0x722,  0x723,
6035
12.3k
      0x724,  0x725,  0x726,  0x727,  0x729,  0x72b,  0x72d,  0x72e,  0x74e,
6036
12.3k
      0x74f,  0x750,  0x751,  0x752,  0x753,  0x754,  0x755,  0x756,  0x757,
6037
12.3k
      0x758,  0x75c,  0x75d,  0x75e,  0x75f,  0x760,  0x761,  0x762,  0x763,
6038
12.3k
      0x764,  0x765,  0x766,  0x850,  0x851,  0x852,  0x853,  0x855,  0x8a0,
6039
12.3k
      0x8a2,  0x8a3,  0x8a4,  0x8a5,  0x8a6,  0x8a7,  0x8a8,  0x8a9,  0x1807,
6040
12.3k
      0x1820, 0x1821, 0x1822, 0x1823, 0x1824, 0x1825, 0x1826, 0x1827, 0x1828,
6041
12.3k
      0x1829, 0x182a, 0x182b, 0x182c, 0x182d, 0x182e, 0x182f, 0x1830, 0x1831,
6042
12.3k
      0x1832, 0x1833, 0x1834, 0x1835, 0x1836, 0x1837, 0x1838, 0x1839, 0x183a,
6043
12.3k
      0x183b, 0x183c, 0x183d, 0x183e, 0x183f, 0x1840, 0x1841, 0x1842, 0x1843,
6044
12.3k
      0x1844, 0x1845, 0x1846, 0x1847, 0x1848, 0x1849, 0x184a, 0x184b, 0x184c,
6045
12.3k
      0x184d, 0x184e, 0x184f, 0x1850, 0x1851, 0x1852, 0x1853, 0x1854, 0x1855,
6046
12.3k
      0x1856, 0x1857, 0x1858, 0x1859, 0x185a, 0x185b, 0x185c, 0x185d, 0x185e,
6047
12.3k
      0x185f, 0x1860, 0x1861, 0x1862, 0x1863, 0x1864, 0x1865, 0x1866, 0x1867,
6048
12.3k
      0x1868, 0x1869, 0x186a, 0x186b, 0x186c, 0x186d, 0x186e, 0x186f, 0x1870,
6049
12.3k
      0x1871, 0x1872, 0x1873, 0x1874, 0x1875, 0x1876, 0x1877, 0x1887, 0x1888,
6050
12.3k
      0x1889, 0x188a, 0x188b, 0x188c, 0x188d, 0x188e, 0x188f, 0x1890, 0x1891,
6051
12.3k
      0x1892, 0x1893, 0x1894, 0x1895, 0x1896, 0x1897, 0x1898, 0x1899, 0x189a,
6052
12.3k
      0x189b, 0x189c, 0x189d, 0x189e, 0x189f, 0x18a0, 0x18a1, 0x18a2, 0x18a3,
6053
12.3k
      0x18a4, 0x18a5, 0x18a6, 0x18a7, 0x18a8, 0x18aa, 0xa840, 0xa841, 0xa842,
6054
12.3k
      0xa843, 0xa844, 0xa845, 0xa846, 0xa847, 0xa848, 0xa849, 0xa84a, 0xa84b,
6055
12.3k
      0xa84c, 0xa84d, 0xa84e, 0xa84f, 0xa850, 0xa851, 0xa852, 0xa853, 0xa854,
6056
12.3k
      0xa855, 0xa856, 0xa857, 0xa858, 0xa859, 0xa85a, 0xa85b, 0xa85c, 0xa85d,
6057
12.3k
      0xa85e, 0xa85f, 0xa860, 0xa861, 0xa862, 0xa863, 0xa864, 0xa865, 0xa866,
6058
12.3k
      0xa867, 0xa868, 0xa869, 0xa86a, 0xa86b, 0xa86c, 0xa86d, 0xa86e, 0xa86f,
6059
12.3k
      0xa870, 0xa871};
6060
6061
105k
  for (size_t i = 0; i < label.size(); i++) {
6062
95.1k
    uint32_t c = label[i];
6063
95.1k
    if (c == 0x200c) {
6064
1.45k
      if (i > 0) {
6065
1.37k
        if (std::ranges::binary_search(virama, label[i - 1])) {
6066
76
          return true;
6067
76
        }
6068
1.37k
      }
6069
1.37k
      if ((i == 0) || (i + 1 >= label.size())) {
6070
502
        return false;
6071
502
      }
6072
      // we go backward looking for L or D
6073
2.07k
      auto is_l_or_d = [](uint32_t code) {
6074
2.07k
        return std::ranges::binary_search(L, code) ||
6075
2.00k
               std::ranges::binary_search(D, code);
6076
2.07k
      };
6077
1.71k
      auto is_r_or_d = [](uint32_t code) {
6078
1.71k
        return std::ranges::binary_search(R, code) ||
6079
1.54k
               std::ranges::binary_search(D, code);
6080
1.71k
      };
6081
874
      std::u32string_view before = label.substr(0, i);
6082
874
      std::u32string_view after = label.substr(i + 1);
6083
874
      return (std::find_if(before.begin(), before.end(), is_l_or_d) !=
6084
874
              before.end()) &&
6085
746
             (std::find_if(after.begin(), after.end(), is_r_or_d) !=
6086
746
              after.end());
6087
93.6k
    } else if (c == 0x200d) {
6088
725
      if (i > 0) {
6089
524
        if (std::ranges::binary_search(virama, label[i - 1])) {
6090
72
          return true;
6091
72
        }
6092
524
      }
6093
653
      return false;
6094
725
    }
6095
95.1k
  }
6096
6097
  // If CheckBidi, and if the domain name is a  Bidi domain name, then the label
6098
  // must satisfy all six of the numbered conditions in [IDNA2008] RFC 5893,
6099
  // Section 2.
6100
6101
  // The following rule, consisting of six conditions, applies to labels
6102
  // in Bidi domain names.  The requirements that this rule satisfies are
6103
  // described in Section 3.  All of the conditions must be satisfied for
6104
  // the rule to be satisfied.
6105
  //
6106
  //  1.  The first character must be a character with Bidi property L, R,
6107
  //     or AL.  If it has the R or AL property, it is an RTL label; if it
6108
  //     has the L property, it is an LTR label.
6109
  //
6110
  //  2.  In an RTL label, only characters with the Bidi properties R, AL,
6111
  //      AN, EN, ES, CS, ET, ON, BN, or NSM are allowed.
6112
  //
6113
  //   3.  In an RTL label, the end of the label must be a character with
6114
  //       Bidi property R, AL, EN, or AN, followed by zero or more
6115
  //       characters with Bidi property NSM.
6116
  //
6117
  //   4.  In an RTL label, if an EN is present, no AN may be present, and
6118
  //       vice versa.
6119
  //
6120
  //  5.  In an LTR label, only characters with the Bidi properties L, EN,
6121
  //       ES, CS, ET, ON, BN, or NSM are allowed.
6122
  //
6123
  //   6.  In an LTR label, the end of the label must be a character with
6124
  //       Bidi property L or EN, followed by zero or more characters with
6125
  //       Bidi property NSM.
6126
6127
10.2k
  size_t last_non_nsm_char = find_last_not_of_nsm(label);
6128
10.2k
  if (last_non_nsm_char == std::u32string_view::npos) {
6129
0
    return false;
6130
0
  }
6131
6132
  // A "Bidi domain name" is a domain name that contains at least one RTL label.
6133
  // The following rule, consisting of six conditions, applies to labels in Bidi
6134
  // domain names.
6135
10.2k
  if (is_rtl_label(label)) {
6136
    // The first character must be a character with Bidi property L, R,
6137
    // or AL. If it has the R or AL property, it is an RTL label; if it
6138
    // has the L property, it is an LTR label.
6139
6140
2.88k
    if (find_direction(label[0]) == direction::L) {
6141
      // Eval as LTR
6142
6143
      // In an LTR label, only characters with the Bidi properties L, EN,
6144
      // ES, CS, ET, ON, BN, or NSM are allowed.
6145
3.24k
      for (size_t i = 0; i <= last_non_nsm_char; i++) {
6146
3.24k
        const direction d = find_direction(label[i]);
6147
3.24k
        if (!(d == direction::L || d == direction::EN || d == direction::ES ||
6148
1.87k
              d == direction::CS || d == direction::ET || d == direction::ON ||
6149
1.06k
              d == direction::BN || d == direction::NSM)) {
6150
439
          return false;
6151
439
        }
6152
3.24k
      }
6153
6154
0
      const direction last_dir = find_direction(label[last_non_nsm_char]);
6155
0
      if (!(last_dir == direction::L || last_dir == direction::EN)) {
6156
0
        return false;
6157
0
      }
6158
6159
0
      return true;
6160
6161
2.44k
    } else {
6162
      // Eval as RTL
6163
6164
      // The first character must be R or AL; a leading AN (or any other
6165
      // direction) does not start a valid RTL label.
6166
2.44k
      const direction first_dir = find_direction(label[0]);
6167
2.44k
      if (first_dir != direction::R && first_dir != direction::AL) {
6168
158
        return false;
6169
158
      }
6170
6171
2.29k
      bool has_an = false;
6172
2.29k
      bool has_en = false;
6173
9.76k
      for (size_t i = 0; i <= last_non_nsm_char; i++) {
6174
8.01k
        const direction d = find_direction(label[i]);
6175
6176
        // In an RTL label, if an EN is present, no AN may be present, and vice
6177
        // versa.
6178
8.01k
        if ((d == direction::EN && ((has_en = true) && has_an)) ||
6179
7.94k
            (d == direction::AN && ((has_an = true) && has_en))) {
6180
146
          return false;
6181
146
        }
6182
6183
7.87k
        if (!(d == direction::R || d == direction::AL || d == direction::AN ||
6184
2.37k
              d == direction::EN || d == direction::ES || d == direction::CS ||
6185
1.17k
              d == direction::ET || d == direction::ON || d == direction::BN ||
6186
405
              d == direction::NSM)) {
6187
193
          return false;
6188
193
        }
6189
6190
7.67k
        if (i == last_non_nsm_char &&
6191
1.95k
            !(d == direction::R || d == direction::AL || d == direction::AN ||
6192
480
              d == direction::EN)) {
6193
199
          return false;
6194
199
        }
6195
7.67k
      }
6196
6197
1.75k
      return true;
6198
2.29k
    }
6199
2.88k
  }
6200
6201
7.31k
  return true;
6202
10.2k
}
6203
6204
}  // namespace ada::idna
6205
/* end file src/validity.cpp */
6206
/* begin file src/to_ascii.cpp */
6207
/* begin file include/ada/idna/to_ascii.h */
6208
#ifndef ADA_IDNA_TO_ASCII_H
6209
#define ADA_IDNA_TO_ASCII_H
6210
6211
#include <string>
6212
#include <string_view>
6213
6214
/* begin file include/ada/idna/limits.h */
6215
#ifndef ADA_IDNA_LIMITS_H
6216
#define ADA_IDNA_LIMITS_H
6217
6218
#include <cstddef>
6219
6220
namespace ada::idna {
6221
6222
// Maximum accepted UTF-8 domain length for to_ascii / to_unicode.
6223
// Bounds heap growth under untrusted input (DoS resistance). DNS wire limits
6224
// are smaller; this allows long Unicode labels used in URL tests/fixtures.
6225
inline constexpr size_t max_domain_input_bytes = 16384;
6226
6227
}  // namespace ada::idna
6228
6229
#endif  // ADA_IDNA_LIMITS_H
6230
/* end file include/ada/idna/limits.h */
6231
6232
namespace ada::idna {
6233
6234
// Converts a domain (e.g., www.google.com) possibly containing international
6235
// characters to an ascii domain (with punycode). It will not do percent
6236
// decoding: percent decoding should be done prior to calling this function. We
6237
// do not remove tabs and spaces, they should have been removed prior to calling
6238
// this function. We also do not trim control characters. We also assume that
6239
// the input is not empty. We return "" on error. Inputs longer than
6240
// max_domain_input_bytes are rejected.
6241
//
6242
// This function may accept or even produce invalid domains (WHATWG carve-outs).
6243
std::string to_ascii(std::string_view ut8_string);
6244
6245
// Same as to_ascii, but writes into `out` and returns false on error without
6246
// relying on empty-string ambiguity.
6247
[[nodiscard]] bool to_ascii(std::string_view ut8_string, std::string& out);
6248
6249
// Returns true if the string contains a forbidden code point according to the
6250
// WHATGL URL specification:
6251
// https://url.spec.whatwg.org/#forbidden-domain-code-point
6252
bool contains_forbidden_domain_code_point(std::string_view ascii_string);
6253
6254
bool constexpr is_ascii(std::u32string_view view);
6255
bool constexpr is_ascii(std::string_view view);
6256
6257
}  // namespace ada::idna
6258
6259
#endif  // ADA_IDNA_TO_ASCII_H
6260
/* end file include/ada/idna/to_ascii.h */
6261
6262
#include <algorithm>
6263
#include <cstdint>
6264
#include <cstring>
6265
#include <ranges>
6266
6267
/* begin file include/ada/idna/validity.h */
6268
#ifndef ADA_IDNA_VALIDITY_H
6269
#define ADA_IDNA_VALIDITY_H
6270
6271
#include <string>
6272
#include <string_view>
6273
6274
namespace ada::idna {
6275
6276
/**
6277
 * @see https://www.unicode.org/reports/tr46/#Validity_Criteria
6278
 */
6279
bool is_label_valid(std::u32string_view label);
6280
6281
}  // namespace ada::idna
6282
6283
#endif  // ADA_IDNA_VALIDITY_H
6284
/* end file include/ada/idna/validity.h */
6285
6286
#ifdef ADA_USE_SIMDUTF
6287
#include "simdutf.h"
6288
#endif
6289
6290
namespace ada::idna {
6291
6292
21.4k
bool constexpr is_ascii(std::u32string_view view) {
6293
47.5k
  for (uint32_t c : view) {
6294
47.5k
    if (c >= 0x80) {
6295
19.2k
      return false;
6296
19.2k
    }
6297
47.5k
  }
6298
2.17k
  return true;
6299
21.4k
}
6300
6301
30.6k
bool constexpr is_ascii(std::string_view view) {
6302
518k
  for (uint8_t c : view) {
6303
518k
    if (c >= 0x80) {
6304
6.03k
      return false;
6305
6.03k
    }
6306
518k
  }
6307
24.5k
  return true;
6308
30.6k
}
6309
6310
constexpr static uint8_t is_forbidden_domain_code_point_table[] = {
6311
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
6312
    1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
6313
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
6314
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
6315
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6316
    0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
6317
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
6318
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
6319
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
6320
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
6321
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
6322
6323
static_assert(sizeof(is_forbidden_domain_code_point_table) == 256);
6324
6325
48.8k
inline bool is_forbidden_domain_code_point(const char c) noexcept {
6326
48.8k
  return is_forbidden_domain_code_point_table[uint8_t(c)];
6327
48.8k
}
6328
6329
4.54k
bool contains_forbidden_domain_code_point(std::string_view view) {
6330
4.54k
  return std::ranges::any_of(view, is_forbidden_domain_code_point);
6331
4.54k
}
6332
6333
// Per the WHATWG URL "domain to ASCII" algorithm, when beStrict is false and
6334
// the input domain is an ASCII string, the result is the input lowercased,
6335
// regardless of the outcome of Unicode ToASCII.
6336
//
6337
// See https://url.spec.whatwg.org/#concept-domain-to-ascii
6338
8.92k
static void from_ascii_to_ascii(std::string_view ut8_string, std::string& out) {
6339
8.92k
  out.assign(ut8_string);
6340
8.92k
  ascii_map(out.data(), out.size());
6341
8.92k
}
6342
6343
// Append ASCII code units from a UTF-32 label (all values < 0x80).
6344
1.69k
static void append_ascii_label(std::string& out, std::u32string_view label) {
6345
1.69k
  const size_t old = out.size();
6346
1.69k
  out.resize(old + label.size());
6347
1.69k
  char* dest = out.data() + old;
6348
14.6k
  for (char32_t c : label) {
6349
14.6k
    *dest++ = static_cast<char>(c);
6350
14.6k
  }
6351
1.69k
}
6352
6353
// True if label begins with "xn--" (already lowercased by mapping).
6354
5.71k
static bool is_ace_prefix(std::u32string_view label) noexcept {
6355
5.71k
  return label.size() >= 4 && label[0] == U'x' && label[1] == U'n' &&
6356
1.44k
         label[2] == U'-' && label[3] == U'-';
6357
5.71k
}
6358
6359
11.9k
[[nodiscard]] bool to_ascii(std::string_view ut8_string, std::string& out) {
6360
11.9k
  out.clear();
6361
11.9k
  if (ut8_string.size() > max_domain_input_bytes) {
6362
0
    return false;
6363
0
  }
6364
11.9k
  if (is_ascii(ut8_string)) {
6365
8.92k
    from_ascii_to_ascii(ut8_string, out);
6366
8.92k
    return true;
6367
8.92k
  }
6368
6369
#ifdef ADA_USE_SIMDUTF
6370
  size_t utf32_length =
6371
      simdutf::utf32_length_from_utf8(ut8_string.data(), ut8_string.size());
6372
  if (utf32_length == 0 && !ut8_string.empty()) {
6373
    return false;
6374
  }
6375
  std::u32string working(utf32_length, U'\0');
6376
  size_t actual_utf32_length = simdutf::convert_utf8_to_utf32(
6377
      ut8_string.data(), ut8_string.size(), working.data());
6378
#else
6379
2.98k
  size_t utf32_length =
6380
2.98k
      ada::idna::utf32_length_from_utf8(ut8_string.data(), ut8_string.size());
6381
2.98k
  if (utf32_length == 0 && !ut8_string.empty()) {
6382
21
    return false;
6383
21
  }
6384
2.96k
  std::u32string working(utf32_length, U'\0');
6385
2.96k
  size_t actual_utf32_length = ada::idna::utf8_to_utf32(
6386
2.96k
      ut8_string.data(), ut8_string.size(), working.data());
6387
2.96k
#endif
6388
2.96k
  if (actual_utf32_length == 0 || actual_utf32_length != utf32_length) {
6389
333
    return false;
6390
333
  }
6391
2.62k
  working.resize(actual_utf32_length);
6392
6393
  // Map into a second buffer with exact sizing (no growth reallocs).
6394
2.62k
  std::u32string mapped;
6395
2.62k
  if (!ada::idna::map(working, mapped)) {
6396
295
    return false;
6397
295
  }
6398
  // Drop UTF-32 input; reuse `working` as scratch for ACE validation below.
6399
2.33k
  working.clear();
6400
6401
  // Skip NFC when already normalized (ASCII is a fast subset of this check).
6402
2.33k
  if (!is_ascii(mapped) && !is_already_nfc(mapped)) {
6403
301
    if (!normalize(mapped)) {
6404
0
      return false;
6405
0
    }
6406
301
  }
6407
6408
  // Estimate ASCII output size (punycode may expand non-ASCII labels).
6409
2.33k
  out.reserve(mapped.size() + 8);
6410
6411
  // Walk labels with a single pointer scan (no repeated string::find).
6412
2.33k
  const char32_t* p = mapped.data();
6413
2.33k
  const char32_t* const end = p + mapped.size();
6414
2.33k
  std::u32string post_map;
6415
6416
7.80k
  while (p < end) {
6417
6.18k
    const char32_t* label_begin = p;
6418
120k
    while (p < end && *p != U'.') {
6419
113k
      ++p;
6420
113k
    }
6421
6.18k
    const size_t label_size = static_cast<size_t>(p - label_begin);
6422
6.18k
    std::u32string_view label_view(label_begin, label_size);
6423
6.18k
    const bool is_last_label = (p == end);
6424
6.18k
    if (p < end) {
6425
3.94k
      ++p;  // skip dot
6426
3.94k
    }
6427
6428
6.18k
    if (label_size == 0) {
6429
      // empty label
6430
5.71k
    } else if (is_ace_prefix(label_view)) {
6431
13.2k
      for (char32_t c : label_view) {
6432
13.2k
        if (c >= 0x80) {
6433
14
          out.clear();
6434
14
          return false;
6435
14
        }
6436
13.2k
      }
6437
1.24k
      append_ascii_label(out, label_view);
6438
1.24k
      std::string_view puny_segment_ascii(
6439
1.24k
          out.data() + (out.size() - label_size) + 4, label_size - 4);
6440
1.24k
      working.clear();
6441
1.24k
      if (!ada::idna::punycode_to_utf32(puny_segment_ascii, working)) {
6442
9
        out.clear();
6443
9
        return false;
6444
9
      }
6445
1.24k
      if (is_ascii(working)) {
6446
41
        out.clear();
6447
41
        return false;
6448
41
      }
6449
1.19k
      if (!ada::idna::map(working, post_map) || working != post_map) {
6450
68
        out.clear();
6451
68
        return false;
6452
68
      }
6453
      // Mapping must be stable; NFC must not change the mapped form either.
6454
1.13k
      if (!is_ascii(post_map) && !is_already_nfc(post_map)) {
6455
482
        if (!normalize(post_map) || post_map != working) {
6456
33
          out.clear();
6457
33
          return false;
6458
33
        }
6459
482
      }
6460
1.09k
      if (post_map.empty() || !is_label_valid(post_map)) {
6461
11
        out.clear();
6462
11
        return false;
6463
11
      }
6464
4.45k
    } else if (is_ascii(label_view)) {
6465
442
      append_ascii_label(out, label_view);
6466
4.01k
    } else {
6467
4.01k
      if (!is_label_valid(label_view)) {
6468
535
        out.clear();
6469
535
        return false;
6470
535
      }
6471
3.47k
      out.append("xn--");
6472
3.47k
      if (!ada::idna::utf32_to_punycode(label_view, out)) {
6473
0
        out.clear();
6474
0
        return false;
6475
0
      }
6476
3.47k
    }
6477
5.46k
    if (!is_last_label) {
6478
3.90k
      out.push_back('.');
6479
3.90k
    }
6480
5.46k
  }
6481
1.62k
  return true;
6482
2.33k
}
6483
6484
11.9k
std::string to_ascii(std::string_view ut8_string) {
6485
11.9k
  std::string out;
6486
11.9k
  if (!to_ascii(ut8_string, out)) {
6487
1.36k
    return {};
6488
1.36k
  }
6489
10.5k
  return out;
6490
11.9k
}
6491
}  // namespace ada::idna
6492
/* end file src/to_ascii.cpp */
6493
/* begin file src/to_unicode.cpp */
6494
/* begin file include/ada/idna/to_unicode.h */
6495
#ifndef ADA_IDNA_TO_UNICODE_H
6496
#define ADA_IDNA_TO_UNICODE_H
6497
6498
#include <string>
6499
#include <string_view>
6500
6501
6502
namespace ada::idna {
6503
6504
// UTS #46 ToUnicode. Never fails per the standard: on step failure the original
6505
// label is kept. Inputs longer than max_domain_input_bytes are returned
6506
// unchanged as a safety measure under untrusted input.
6507
std::string to_unicode(std::string_view input);
6508
6509
// Writes into `out`. Returns false only if the input exceeds
6510
// max_domain_input_bytes (out is left empty). Otherwise always returns true
6511
// (ToUnicode does not fail).
6512
[[nodiscard]] bool to_unicode(std::string_view input, std::string& out);
6513
6514
}  // namespace ada::idna
6515
6516
#endif  // ADA_IDNA_TO_UNICODE_H
6517
/* end file include/ada/idna/to_unicode.h */
6518
6519
#include <algorithm>
6520
#include <string>
6521
6522
/* begin file include/idna.h */
6523
#ifndef ADA_IDNA_H
6524
#define ADA_IDNA_H
6525
6526
/* begin file include/ada/idna/identifier.h */
6527
#ifndef ADA_IDNA_IDENTIFIER_H
6528
#define ADA_IDNA_IDENTIFIER_H
6529
6530
#include <string>
6531
#include <string_view>
6532
6533
namespace ada::idna {
6534
6535
// Verify if it is valid name code point given a Unicode code point and a
6536
// boolean first: If first is true return the result of checking if code point
6537
// is contained in the IdentifierStart set of code points. Otherwise return the
6538
// result of checking if code point is contained in the IdentifierPart set of
6539
// code points. Returns false if the input is empty or the code point is not
6540
// valid. There is minimal Unicode error handling: the input should be valid
6541
// UTF-8. https://urlpattern.spec.whatwg.org/#is-a-valid-name-code-point
6542
bool valid_name_code_point(char32_t code_point, bool first);
6543
6544
}  // namespace ada::idna
6545
6546
#endif
6547
/* end file include/ada/idna/identifier.h */
6548
6549
#endif
6550
/* end file include/idna.h */
6551
6552
#ifdef ADA_USE_SIMDUTF
6553
#include "simdutf.h"
6554
#endif
6555
6556
namespace ada::idna {
6557
6558
11.3k
[[nodiscard]] bool to_unicode(std::string_view input, std::string& output) {
6559
11.3k
  output.clear();
6560
11.3k
  if (input.size() > max_domain_input_bytes) {
6561
0
    return false;
6562
0
  }
6563
11.3k
  output.reserve(input.size());
6564
6565
11.3k
  size_t label_start = 0;
6566
11.3k
  std::u32string tmp_buffer;
6567
11.3k
  std::u32string post_map;
6568
40.6k
  while (label_start < input.size()) {
6569
29.2k
    size_t loc_dot = input.find('.', label_start);
6570
29.2k
    bool is_last_label = (loc_dot == std::string_view::npos);
6571
29.2k
    size_t label_size =
6572
29.2k
        is_last_label ? input.size() - label_start : loc_dot - label_start;
6573
29.2k
    auto label_view = std::string_view(input.data() + label_start, label_size);
6574
6575
29.2k
    if (label_view.starts_with("xn--") && ada::idna::is_ascii(label_view)) {
6576
13.8k
      label_view.remove_prefix(4);
6577
13.8k
      tmp_buffer.clear();
6578
13.8k
      if (ada::idna::punycode_to_utf32(label_view, tmp_buffer)) {
6579
        // Per UTS #46, the decoded label must be re-validated. Reject decodings
6580
        // that are pure ASCII (xn-- encoding of an ASCII-only label), or whose
6581
        // mapping/normalization is not stable, or that fail label validity.
6582
12.2k
        bool accept_decoded = true;
6583
12.2k
        if (ada::idna::is_ascii(tmp_buffer)) {
6584
1.40k
          accept_decoded = false;
6585
10.8k
        } else {
6586
10.8k
          post_map.clear();
6587
10.8k
          if (!ada::idna::map(tmp_buffer, post_map) || post_map != tmp_buffer) {
6588
1.99k
            accept_decoded = false;
6589
8.84k
          } else if (!ada::idna::normalize(post_map) ||
6590
8.84k
                     post_map != tmp_buffer || post_map.empty() ||
6591
7.03k
                     !ada::idna::is_label_valid(post_map)) {
6592
3.99k
            accept_decoded = false;
6593
3.99k
          }
6594
10.8k
        }
6595
6596
12.2k
        if (accept_decoded) {
6597
#ifdef ADA_USE_SIMDUTF
6598
          auto utf8_size = simdutf::utf8_length_from_utf32(tmp_buffer.data(),
6599
                                                           tmp_buffer.size());
6600
          size_t old_size = output.size();
6601
          output.resize(old_size + utf8_size);
6602
          size_t written = simdutf::convert_utf32_to_utf8(
6603
              tmp_buffer.data(), tmp_buffer.size(), output.data() + old_size);
6604
          if (written != utf8_size) {
6605
            output.resize(old_size);
6606
            output.append(
6607
                std::string_view(input.data() + label_start, label_size));
6608
          }
6609
#else
6610
4.85k
          auto utf8_size = ada::idna::utf8_length_from_utf32(tmp_buffer.data(),
6611
4.85k
                                                             tmp_buffer.size());
6612
4.85k
          size_t old_size = output.size();
6613
4.85k
          output.resize(old_size + utf8_size);
6614
4.85k
          size_t written = ada::idna::utf32_to_utf8(
6615
4.85k
              tmp_buffer.data(), tmp_buffer.size(), output.data() + old_size);
6616
4.85k
          if (written != utf8_size) {
6617
0
            output.resize(old_size);
6618
0
            output.append(
6619
0
                std::string_view(input.data() + label_start, label_size));
6620
0
          }
6621
4.85k
#endif
6622
7.40k
        } else {
6623
          // ToUnicode never fails. If any step fails, return the original
6624
          // input sequence for the label.
6625
7.40k
          output.append(
6626
7.40k
              std::string_view(input.data() + label_start, label_size));
6627
7.40k
        }
6628
12.2k
      } else {
6629
1.55k
        output.append(std::string_view(input.data() + label_start, label_size));
6630
1.55k
      }
6631
15.4k
    } else {
6632
15.4k
      output.append(label_view);
6633
15.4k
    }
6634
6635
29.2k
    if (!is_last_label) {
6636
18.5k
      output.push_back('.');
6637
18.5k
    }
6638
6639
29.2k
    label_start += label_size + 1;
6640
29.2k
  }
6641
6642
11.3k
  return true;
6643
11.3k
}
6644
6645
11.3k
std::string to_unicode(std::string_view input) {
6646
11.3k
  std::string output;
6647
11.3k
  if (!to_unicode(input, output)) {
6648
    // Over-limit input: return original (ToUnicode never fails in the sense of
6649
    // producing no answer for valid-length inputs).
6650
0
    return std::string(input);
6651
0
  }
6652
11.3k
  return output;
6653
11.3k
}
6654
}  // namespace ada::idna
6655
/* end file src/to_unicode.cpp */
6656
/* begin file src/identifier.cpp */
6657
6658
#include <algorithm>
6659
#include <array>
6660
#include <span>
6661
#include <string>
6662
6663
/* begin file src/id_tables.cpp */
6664
// IDNA  17.0.0
6665
// Identifier range tables are stored in the compressed blob (table_store.hpp).
6666
6667
// clang-format off
6668
#ifndef ADA_IDNA_IDENTIFIER_TABLES_H
6669
#define ADA_IDNA_IDENTIFIER_TABLES_H
6670
#include <cstdint>
6671
6672
namespace ada::idna {
6673
6674
// id_continue / id_start pointers and counts are provided by table_store.hpp.
6675
6676
}  // namespace ada::idna
6677
#endif  // ADA_IDNA_IDENTIFIER_TABLES_H
6678
/* end file src/id_tables.cpp */
6679
6680
namespace ada::idna {
6681
0
constexpr bool is_ascii_letter(char32_t c) noexcept {
6682
0
  return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
6683
0
}
6684
6685
0
constexpr bool is_ascii_letter_or_digit(char32_t c) noexcept {
6686
0
  return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
6687
0
         (c >= '0' && c <= '9');
6688
0
}
6689
6690
0
bool valid_name_code_point(char32_t code_point, bool first) {
6691
  // https://tc39.es/ecma262/#prod-IdentifierStart
6692
6693
  // Fast paths (no table needed)
6694
0
  if (first && (code_point == U'$' || code_point == U'_' ||
6695
0
                is_ascii_letter(code_point))) {
6696
0
    return true;
6697
0
  }
6698
0
  if (!first && (code_point == U'$' || is_ascii_letter_or_digit(code_point))) {
6699
0
    return true;
6700
0
  }
6701
6702
  // Minimal error handling for invalid code point
6703
0
  if (code_point > 0x10FFFF) {
6704
0
    return false;
6705
0
  }
6706
0
  if (code_point >= 0xD800 && code_point <= 0xDFFF) {
6707
0
    return false;
6708
0
  }
6709
6710
0
  if (!ensure_tables() || id_start == nullptr || id_continue == nullptr) {
6711
0
    return false;
6712
0
  }
6713
6714
  // Slow path: binary search through the appropriate Unicode range table.
6715
  // Each entry is a [low, high] inclusive range.
6716
0
  const std::span<const uint32_t[2]> ranges =
6717
0
      first ? std::span<const uint32_t[2]>{ada::idna::id_start,
6718
0
                                           ada::idna::id_start_count}
6719
0
            : std::span<const uint32_t[2]>{ada::idna::id_continue,
6720
0
                                           ada::idna::id_continue_count};
6721
6722
0
  const auto iter = std::ranges::lower_bound(
6723
0
      ranges, code_point, {},
6724
0
      [](const auto& range) { return range[1]; });  // project to range-high
6725
6726
0
  return iter != ranges.end() && code_point >= (*iter)[0];
6727
0
}
6728
}  // namespace ada::idna
6729
/* end file src/identifier.cpp */
6730
/* end file src/idna.cpp */
6731
/* end file src/ada_idna.cpp */
6732
ADA_POP_DISABLE_WARNINGS
6733
6734
#include <algorithm>
6735
#include <array>
6736
#include <cstring>
6737
#if ADA_SSSE3
6738
#include <tmmintrin.h>
6739
#elif ADA_NEON
6740
#include <arm_neon.h>
6741
#elif ADA_SSE2
6742
#include <emmintrin.h>
6743
#elif ADA_LSX
6744
#include <lsxintrin.h>
6745
#elif ADA_RVV
6746
#include <riscv_vector.h>
6747
#endif
6748
6749
#include <ranges>
6750
6751
namespace ada::unicode {
6752
6753
0
constexpr bool is_tabs_or_newline(char c) noexcept {
6754
0
  return c == '\r' || c == '\n' || c == '\t';
6755
0
}
6756
6757
0
constexpr uint64_t broadcast(uint8_t v) noexcept {
6758
0
  return 0x101010101010101ull * v;
6759
0
}
6760
6761
0
constexpr bool to_lower_ascii(char* input, size_t length) noexcept {
6762
0
  uint64_t broadcast_80 = broadcast(0x80);
6763
0
  uint64_t broadcast_Ap = broadcast(128 - 'A');
6764
0
  uint64_t broadcast_Zp = broadcast(128 - 'Z' - 1);
6765
0
  uint64_t non_ascii = 0;
6766
0
  size_t i = 0;
6767
6768
0
  for (; i + 7 < length; i += 8) {
6769
0
    uint64_t word{};
6770
0
    memcpy(&word, input + i, sizeof(word));
6771
0
    non_ascii |= (word & broadcast_80);
6772
0
    word ^=
6773
0
        (((word + broadcast_Ap) ^ (word + broadcast_Zp)) & broadcast_80) >> 2;
6774
0
    memcpy(input + i, &word, sizeof(word));
6775
0
  }
6776
0
  if (i < length) {
6777
0
    uint64_t word{};
6778
0
    memcpy(&word, input + i, length - i);
6779
0
    non_ascii |= (word & broadcast_80);
6780
0
    word ^=
6781
0
        (((word + broadcast_Ap) ^ (word + broadcast_Zp)) & broadcast_80) >> 2;
6782
0
    memcpy(input + i, &word, length - i);
6783
0
  }
6784
0
  return non_ascii == 0;
6785
0
}
6786
#if ADA_SSSE3
6787
ada_really_inline bool has_tabs_or_newline(
6788
    std::string_view user_input) noexcept {
6789
  // first check for short strings in which case we do it naively.
6790
  if (user_input.size() < 16) {  // slow path
6791
    return std::ranges::any_of(user_input, is_tabs_or_newline);
6792
  }
6793
  // fast path for long strings (expected to be common)
6794
  // Using SSSE3's _mm_shuffle_epi8 for table lookup (same approach as NEON)
6795
  size_t i = 0;
6796
  // Lookup table where positions 9, 10, 13 contain their own values
6797
  // Everything else is set to 1 so it won't match
6798
  const __m128i rnt =
6799
      _mm_setr_epi8(1, 0, 0, 0, 0, 0, 0, 0, 0, 9, 10, 0, 0, 13, 0, 0);
6800
  __m128i running = _mm_setzero_si128();
6801
  for (; i + 15 < user_input.size(); i += 16) {
6802
    __m128i word = _mm_loadu_si128((const __m128i*)(user_input.data() + i));
6803
    // Shuffle the lookup table using input bytes as indices
6804
    __m128i shuffled = _mm_shuffle_epi8(rnt, word);
6805
    // Compare: if shuffled value matches input, we found \t, \n, or \r
6806
    __m128i matches = _mm_cmpeq_epi8(shuffled, word);
6807
    running = _mm_or_si128(running, matches);
6808
  }
6809
  if (i < user_input.size()) {
6810
    __m128i word = _mm_loadu_si128(
6811
        (const __m128i*)(user_input.data() + user_input.length() - 16));
6812
    __m128i shuffled = _mm_shuffle_epi8(rnt, word);
6813
    __m128i matches = _mm_cmpeq_epi8(shuffled, word);
6814
    running = _mm_or_si128(running, matches);
6815
  }
6816
  return _mm_movemask_epi8(running) != 0;
6817
}
6818
#elif ADA_NEON
6819
ada_really_inline bool has_tabs_or_newline(
6820
    std::string_view user_input) noexcept {
6821
  // first check for short strings in which case we do it naively.
6822
  if (user_input.size() < 16) {  // slow path
6823
    return std::ranges::any_of(user_input, is_tabs_or_newline);
6824
  }
6825
  // fast path for long strings (expected to be common)
6826
  size_t i = 0;
6827
  /**
6828
   * The fastest way to check for `\t` (==9), '\n'(== 10) and `\r` (==13) relies
6829
   * on table lookup instruction. We notice that these are all unique numbers
6830
   * between 0..15. Let's prepare a special register, where we put '\t' in the
6831
   * 9th position, '\n' - 10th and '\r' - 13th. Then we shuffle this register by
6832
   * input register. If the input had `\t` in position X then this shuffled
6833
   * register will also have '\t' in that position. Comparing input with this
6834
   * shuffled register will mark us all interesting characters in the input.
6835
   *
6836
   * credit for algorithmic idea: @aqrit, credit for description:
6837
   * @DenisYaroshevskiy
6838
   */
6839
  static uint8_t rnt_array[16] = {1, 0, 0,  0, 0, 0,  0, 0,
6840
                                  0, 9, 10, 0, 0, 13, 0, 0};
6841
  const uint8x16_t rnt = vld1q_u8(rnt_array);
6842
  // m['0xd', '0xa', '0x9']
6843
  uint8x16_t running{0};
6844
  for (; i + 15 < user_input.size(); i += 16) {
6845
    uint8x16_t word = vld1q_u8((const uint8_t*)user_input.data() + i);
6846
6847
    running = vorrq_u8(running, vceqq_u8(vqtbl1q_u8(rnt, word), word));
6848
  }
6849
  if (i < user_input.size()) {
6850
    uint8x16_t word =
6851
        vld1q_u8((const uint8_t*)user_input.data() + user_input.length() - 16);
6852
    running = vorrq_u8(running, vceqq_u8(vqtbl1q_u8(rnt, word), word));
6853
  }
6854
  // `running` accumulates comparison results, so every lane is 0x00 or 0xFF:
6855
  // narrowing to four bits per lane and comparing the result against zero as a
6856
  // double is a cheaper "is anything set?" test than a horizontal maximum.
6857
  uint8x8_t narrowed = vshrn_n_u16(vreinterpretq_u16_u8(running), 4);
6858
  return vdupd_lane_f64(vreinterpret_f64_u8(narrowed), 0) != 0.0;
6859
}
6860
#elif ADA_SSE2
6861
ada_really_inline bool has_tabs_or_newline(
6862
0
    std::string_view user_input) noexcept {
6863
  // first check for short strings in which case we do it naively.
6864
0
  if (user_input.size() < 16) {  // slow path
6865
0
    return std::ranges::any_of(user_input, is_tabs_or_newline);
6866
0
  }
6867
  // fast path for long strings (expected to be common)
6868
0
  size_t i = 0;
6869
0
  const __m128i mask1 = _mm_set1_epi8('\r');
6870
0
  const __m128i mask2 = _mm_set1_epi8('\n');
6871
0
  const __m128i mask3 = _mm_set1_epi8('\t');
6872
  // If we supported SSSE3, we could use the algorithm that we use for NEON.
6873
0
  __m128i running{0};
6874
0
  for (; i + 15 < user_input.size(); i += 16) {
6875
0
    __m128i word = _mm_loadu_si128((const __m128i*)(user_input.data() + i));
6876
0
    running = _mm_or_si128(
6877
0
        _mm_or_si128(running, _mm_or_si128(_mm_cmpeq_epi8(word, mask1),
6878
0
                                           _mm_cmpeq_epi8(word, mask2))),
6879
0
        _mm_cmpeq_epi8(word, mask3));
6880
0
  }
6881
0
  if (i < user_input.size()) {
6882
0
    __m128i word = _mm_loadu_si128(
6883
0
        (const __m128i*)(user_input.data() + user_input.length() - 16));
6884
0
    running = _mm_or_si128(
6885
0
        _mm_or_si128(running, _mm_or_si128(_mm_cmpeq_epi8(word, mask1),
6886
0
                                           _mm_cmpeq_epi8(word, mask2))),
6887
0
        _mm_cmpeq_epi8(word, mask3));
6888
0
  }
6889
0
  return _mm_movemask_epi8(running) != 0;
6890
0
}
6891
#elif ADA_LSX
6892
ada_really_inline bool has_tabs_or_newline(
6893
    std::string_view user_input) noexcept {
6894
  // first check for short strings in which case we do it naively.
6895
  if (user_input.size() < 16) {  // slow path
6896
    return std::ranges::any_of(user_input, is_tabs_or_newline);
6897
  }
6898
  // fast path for long strings (expected to be common)
6899
  size_t i = 0;
6900
  const __m128i mask1 = __lsx_vrepli_b('\r');
6901
  const __m128i mask2 = __lsx_vrepli_b('\n');
6902
  const __m128i mask3 = __lsx_vrepli_b('\t');
6903
  // If we supported SSSE3, we could use the algorithm that we use for NEON.
6904
  __m128i running{0};
6905
  for (; i + 15 < user_input.size(); i += 16) {
6906
    __m128i word = __lsx_vld((const __m128i*)(user_input.data() + i), 0);
6907
    running = __lsx_vor_v(
6908
        __lsx_vor_v(running, __lsx_vor_v(__lsx_vseq_b(word, mask1),
6909
                                         __lsx_vseq_b(word, mask2))),
6910
        __lsx_vseq_b(word, mask3));
6911
  }
6912
  if (i < user_input.size()) {
6913
    __m128i word = __lsx_vld(
6914
        (const __m128i*)(user_input.data() + user_input.length() - 16), 0);
6915
    running = __lsx_vor_v(
6916
        __lsx_vor_v(running, __lsx_vor_v(__lsx_vseq_b(word, mask1),
6917
                                         __lsx_vseq_b(word, mask2))),
6918
        __lsx_vseq_b(word, mask3));
6919
  }
6920
  if (__lsx_bz_v(running)) return false;
6921
  return true;
6922
}
6923
#elif ADA_RVV
6924
ada_really_inline bool has_tabs_or_newline(
6925
    std::string_view user_input) noexcept {
6926
  uint8_t* src = (uint8_t*)user_input.data();
6927
  for (size_t vl, n = user_input.size(); n > 0; n -= vl, src += vl) {
6928
    vl = __riscv_vsetvl_e8m1(n);
6929
    vuint8m1_t v = __riscv_vle8_v_u8m1(src, vl);
6930
    vbool8_t m1 = __riscv_vmseq(v, '\r', vl);
6931
    vbool8_t m2 = __riscv_vmseq(v, '\n', vl);
6932
    vbool8_t m3 = __riscv_vmseq(v, '\t', vl);
6933
    vbool8_t m = __riscv_vmor(__riscv_vmor(m1, m2, vl), m3, vl);
6934
    long idx = __riscv_vfirst(m, vl);
6935
    if (idx >= 0) return true;
6936
  }
6937
  return false;
6938
}
6939
#else
6940
ada_really_inline bool has_tabs_or_newline(
6941
    std::string_view user_input) noexcept {
6942
  auto has_zero_byte = [](uint64_t v) {
6943
    return ((v - 0x0101010101010101) & ~(v) & 0x8080808080808080);
6944
  };
6945
  size_t i = 0;
6946
  uint64_t mask1 = broadcast('\r');
6947
  uint64_t mask2 = broadcast('\n');
6948
  uint64_t mask3 = broadcast('\t');
6949
  uint64_t running{0};
6950
  for (; i + 7 < user_input.size(); i += 8) {
6951
    uint64_t word{};
6952
    memcpy(&word, user_input.data() + i, sizeof(word));
6953
    uint64_t xor1 = word ^ mask1;
6954
    uint64_t xor2 = word ^ mask2;
6955
    uint64_t xor3 = word ^ mask3;
6956
    running |= has_zero_byte(xor1) | has_zero_byte(xor2) | has_zero_byte(xor3);
6957
  }
6958
  if (i < user_input.size()) {
6959
    uint64_t word{};
6960
    memcpy(&word, user_input.data() + i, user_input.size() - i);
6961
    uint64_t xor1 = word ^ mask1;
6962
    uint64_t xor2 = word ^ mask2;
6963
    uint64_t xor3 = word ^ mask3;
6964
    running |= has_zero_byte(xor1) | has_zero_byte(xor2) | has_zero_byte(xor3);
6965
  }
6966
  return running;
6967
}
6968
#endif
6969
6970
// A forbidden host code point is U+0000 NULL, U+0009 TAB, U+000A LF, U+000D CR,
6971
// U+0020 SPACE, U+0023 (#), U+002F (/), U+003A (:), U+003C (<), U+003E (>),
6972
// U+003F (?), U+0040 (@), U+005B ([), U+005C (\), U+005D (]), U+005E (^), or
6973
// U+007C (|).
6974
constexpr static std::array<uint8_t, 256> is_forbidden_host_code_point_table =
6975
    []() consteval {
6976
      std::array<uint8_t, 256> result{};
6977
      for (uint8_t c : {'\0', '\x09', '\x0a', '\x0d', ' ', '#', '/', ':', '<',
6978
                        '>', '?', '@', '[', '\\', ']', '^', '|'}) {
6979
        result[c] = true;
6980
      }
6981
      return result;
6982
    }();
6983
6984
ada_really_inline constexpr bool is_forbidden_host_code_point(
6985
0
    const char c) noexcept {
6986
0
  return is_forbidden_host_code_point_table[uint8_t(c)];
6987
0
}
6988
6989
constexpr static std::array<uint8_t, 256> is_forbidden_domain_code_point_table =
6990
    []() consteval {
6991
      std::array<uint8_t, 256> result{};
6992
      for (uint8_t c : {'\0', '\x09', '\x0a', '\x0d', ' ', '#', '/', ':', '<',
6993
                        '>', '?', '@', '[', '\\', ']', '^', '|', '%'}) {
6994
        result[c] = true;
6995
      }
6996
      for (uint8_t c = 0; c <= 32; c++) {
6997
        result[c] = true;
6998
      }
6999
      for (size_t c = 127; c < 256; c++) {
7000
        result[c] = true;
7001
      }
7002
      return result;
7003
    }();
7004
7005
static_assert(sizeof(is_forbidden_domain_code_point_table) == 256);
7006
7007
ada_really_inline constexpr bool is_forbidden_domain_code_point(
7008
0
    const char c) noexcept {
7009
0
  return is_forbidden_domain_code_point_table[uint8_t(c)];
7010
0
}
7011
7012
ada_really_inline constexpr bool contains_forbidden_domain_code_point(
7013
0
    const char* input, size_t length) noexcept {
7014
0
  size_t i = 0;
7015
0
  uint8_t accumulator{};
7016
0
  for (; i + 4 <= length; i += 4) {
7017
0
    accumulator |= is_forbidden_domain_code_point_table[uint8_t(input[i])];
7018
0
    accumulator |= is_forbidden_domain_code_point_table[uint8_t(input[i + 1])];
7019
0
    accumulator |= is_forbidden_domain_code_point_table[uint8_t(input[i + 2])];
7020
0
    accumulator |= is_forbidden_domain_code_point_table[uint8_t(input[i + 3])];
7021
0
  }
7022
0
  for (; i < length; i++) {
7023
0
    accumulator |= is_forbidden_domain_code_point_table[uint8_t(input[i])];
7024
0
  }
7025
0
  return accumulator;
7026
0
}
7027
7028
constexpr static std::array<uint8_t, 256>
7029
    is_forbidden_domain_code_point_table_or_upper = []() consteval {
7030
      std::array<uint8_t, 256> result{};
7031
      for (uint8_t c : {'\0', '\x09', '\x0a', '\x0d', ' ', '#', '/', ':', '<',
7032
                        '>', '?', '@', '[', '\\', ']', '^', '|', '%'}) {
7033
        result[c] = 1;
7034
      }
7035
      for (uint8_t c = 'A'; c <= 'Z'; c++) {
7036
        result[c] = 2;
7037
      }
7038
      for (uint8_t c = 0; c <= 32; c++) {
7039
        result[c] = 1;
7040
      }
7041
      for (size_t c = 127; c < 256; c++) {
7042
        result[c] = 1;
7043
      }
7044
      return result;
7045
    }();
7046
7047
ada_really_inline constexpr uint8_t
7048
contains_forbidden_domain_code_point_or_upper(const char* input,
7049
0
                                              size_t length) noexcept {
7050
0
  size_t i = 0;
7051
0
  uint8_t accumulator{};
7052
0
  for (; i + 4 <= length; i += 4) {
7053
0
    accumulator |=
7054
0
        is_forbidden_domain_code_point_table_or_upper[uint8_t(input[i])];
7055
0
    accumulator |=
7056
0
        is_forbidden_domain_code_point_table_or_upper[uint8_t(input[i + 1])];
7057
0
    accumulator |=
7058
0
        is_forbidden_domain_code_point_table_or_upper[uint8_t(input[i + 2])];
7059
0
    accumulator |=
7060
0
        is_forbidden_domain_code_point_table_or_upper[uint8_t(input[i + 3])];
7061
0
  }
7062
0
  for (; i < length; i++) {
7063
0
    accumulator |=
7064
0
        is_forbidden_domain_code_point_table_or_upper[uint8_t(input[i])];
7065
0
  }
7066
0
  return accumulator;
7067
0
}
7068
7069
// std::isalnum(c) || c == '+' || c == '-' || c == '.') is true for
7070
constexpr static std::array<bool, 256> is_alnum_plus_table = []() consteval {
7071
  std::array<bool, 256> result{};
7072
  for (size_t c = 0; c < 256; c++) {
7073
    result[c] = (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') ||
7074
                (c >= 'A' && c <= 'Z') || c == '+' || c == '-' || c == '.';
7075
  }
7076
  return result;
7077
}();
7078
7079
0
ada_really_inline constexpr bool is_alnum_plus(const char c) noexcept {
7080
0
  return is_alnum_plus_table[uint8_t(c)];
7081
  // A table is almost surely much faster than the
7082
  // following under most compilers: return
7083
  // return (std::isalnum(c) || c == '+' || c == '-' || c == '.');
7084
0
}
7085
7086
0
ada_really_inline constexpr bool is_ascii_hex_digit(const char c) noexcept {
7087
0
  return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') ||
7088
0
         (c >= 'a' && c <= 'f');
7089
0
}
7090
7091
0
ada_really_inline constexpr bool is_ascii_digit(const char c) noexcept {
7092
  // An ASCII digit is a code point in the range U+0030 (0) to U+0039 (9),
7093
  // inclusive.
7094
0
  return (c >= '0' && c <= '9');
7095
0
}
7096
7097
0
ada_really_inline constexpr bool is_ascii(const char32_t c) noexcept {
7098
  // If code point is between U+0000 and U+007F inclusive, then return true.
7099
0
  return c <= 0x7F;
7100
0
}
7101
7102
0
ada_really_inline constexpr bool is_c0_control_or_space(const char c) noexcept {
7103
0
  return (unsigned char)c <= ' ';
7104
0
}
7105
7106
ada_really_inline constexpr bool is_ascii_tab_or_newline(
7107
0
    const char c) noexcept {
7108
0
  return c == '\t' || c == '\n' || c == '\r';
7109
0
}
7110
7111
constexpr std::string_view table_is_double_dot_path_segment[] = {
7112
    "..", "%2e.", ".%2e", "%2e%2e"};
7113
7114
ada_really_inline constexpr bool is_double_dot_path_segment(
7115
0
    std::string_view input) noexcept {
7116
  // This will catch most cases:
7117
  // The length must be 2,4 or 6.
7118
  // We divide by two and require
7119
  // that the result be between 1 and 3 inclusively.
7120
0
  uint64_t half_length = uint64_t(input.size()) / 2;
7121
0
  if (half_length - 1 > 2) {
7122
0
    return false;
7123
0
  }
7124
  // We have a string of length 2, 4 or 6.
7125
  // We now check the first character:
7126
0
  if ((input[0] != '.') && (input[0] != '%')) {
7127
0
    return false;
7128
0
  }
7129
  // We are unlikely the get beyond this point.
7130
0
  int hash_value = (input.size() + (unsigned)(input[0])) & 3;
7131
0
  const std::string_view target = table_is_double_dot_path_segment[hash_value];
7132
0
  if (target.size() != input.size()) {
7133
0
    return false;
7134
0
  }
7135
  // We almost never get here.
7136
  // Optimizing the rest is relatively unimportant.
7137
0
  auto prefix_equal_unsafe = [](std::string_view a, std::string_view b) {
7138
0
    uint16_t A, B;
7139
0
    memcpy(&A, a.data(), sizeof(A));
7140
0
    memcpy(&B, b.data(), sizeof(B));
7141
0
    return A == B;
7142
0
  };
7143
0
  if (!prefix_equal_unsafe(input, target)) {
7144
0
    return false;
7145
0
  }
7146
0
  for (size_t i = 2; i < input.size(); i++) {
7147
0
    char c = input[i];
7148
0
    if ((uint8_t((c | 0x20) - 0x61) <= 25 ? (c | 0x20) : c) != target[i]) {
7149
0
      return false;
7150
0
    }
7151
0
  }
7152
0
  return true;
7153
  // The above code might be a bit better than the code below. Compilers
7154
  // are not stupid and may use the fact that these strings have length 2,4 and
7155
  // 6 and other tricks.
7156
  // return input == ".." ||
7157
  //  input == ".%2e" || input == ".%2E" ||
7158
  //  input == "%2e." || input == "%2E." ||
7159
  //  input == "%2e%2e" || input == "%2E%2E" || input == "%2E%2e" || input ==
7160
  //  "%2e%2E";
7161
0
}
7162
7163
ada_really_inline constexpr bool is_single_dot_path_segment(
7164
0
    std::string_view input) noexcept {
7165
0
  return input == "." || input == "%2e" || input == "%2E";
7166
0
}
7167
7168
0
ada_really_inline constexpr bool is_lowercase_hex(const char c) noexcept {
7169
0
  return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f');
7170
0
}
7171
7172
constexpr static char hex_to_binary_table[] = {
7173
    0,  1,  2,  3,  4, 5, 6, 7, 8, 9, 0, 0,  0,  0,  0,  0,  0, 10, 11,
7174
    12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0,  0,  0,  0, 0,  0,
7175
    0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15};
7176
0
unsigned constexpr convert_hex_to_binary(const char c) noexcept {
7177
0
  return hex_to_binary_table[c - '0'];
7178
0
}
7179
7180
0
std::string percent_decode(const std::string_view input, size_t first_percent) {
7181
  // next line is for safety only, we expect users to avoid calling
7182
  // percent_decode when first_percent is outside the range.
7183
0
  if (first_percent == std::string_view::npos) {
7184
0
    return std::string(input);
7185
0
  }
7186
7187
  // NOLINTNEXTLINE(bugprone-suspicious-stringview-data-usage)
7188
0
  const char* const src = input.data();
7189
0
  const char* const end = src + input.size();
7190
7191
  // Decoding never grows the string, so a single pre-sized buffer written via
7192
  // bulk memcpy of the plain runs (then shrunk to the final length) avoids the
7193
  // byte-at-a-time appends of the naive version.
7194
0
  std::string out(input.size(), '\0');
7195
0
  char* d = out.data();
7196
0
  char* const d0 = d;
7197
7198
0
  std::memcpy(d, src, first_percent);
7199
0
  d += first_percent;
7200
7201
0
  const char* p = src + first_percent;
7202
0
  while (p < end) {
7203
0
    if (*p == '%') {
7204
      // Decode runs of valid %XX tightly (common for nested/encoded URLs).
7205
0
      while (p + 2 < end && *p == '%') {
7206
0
        if (!is_ascii_hex_digit(p[1]) || !is_ascii_hex_digit(p[2])) {
7207
0
          break;
7208
0
        }
7209
0
        *d++ = static_cast<char>(convert_hex_to_binary(p[1]) * 16 +
7210
0
                                 convert_hex_to_binary(p[2]));
7211
0
        p += 3;
7212
0
      }
7213
0
      if (p < end && *p == '%') {
7214
        // Not a valid escape (too few chars left or bad hex): copy '%'
7215
        // literally and keep scanning after it.
7216
0
        *d++ = *p++;
7217
0
      }
7218
0
    } else {
7219
0
      const char* q = static_cast<const char*>(
7220
0
          std::memchr(p, '%', static_cast<size_t>(end - p)));
7221
0
      const char* run_end = q ? q : end;
7222
0
      const size_t n = static_cast<size_t>(run_end - p);
7223
0
      std::memcpy(d, p, n);
7224
0
      d += n;
7225
0
      p = run_end;
7226
0
    }
7227
0
  }
7228
7229
0
  out.resize(static_cast<size_t>(d - d0));
7230
0
  return out;
7231
0
}
7232
7233
// 0..15 for hex digits, 0xFF otherwise - validate and decode with two loads.
7234
constexpr static std::array<uint8_t, 256> unhex_table = []() consteval {
7235
  std::array<uint8_t, 256> t{};
7236
  for (size_t i = 0; i < 256; ++i) {
7237
    t[i] = 0xFF;
7238
  }
7239
  for (uint8_t i = 0; i < 10; ++i) {
7240
    t[static_cast<size_t>('0') + i] = i;
7241
  }
7242
  for (uint8_t i = 0; i < 6; ++i) {
7243
    t[static_cast<size_t>('A') + i] = static_cast<uint8_t>(10 + i);
7244
    t[static_cast<size_t>('a') + i] = static_cast<uint8_t>(10 + i);
7245
  }
7246
  return t;
7247
}();
7248
7249
0
std::string form_urlencoded_decode(const std::string_view input) {
7250
0
  const size_t len = input.size();
7251
0
  if (len == 0) [[unlikely]] {
7252
0
    return {};
7253
0
  }
7254
7255
  // NOLINTNEXTLINE(bugprone-suspicious-stringview-data-usage)
7256
0
  const char* const src = input.data();
7257
0
  const char* const end = src + len;
7258
0
  const char* p = src;
7259
7260
  // Advance over the untransformed prefix.
7261
0
  while (p < end && *p != '+' && *p != '%') {
7262
0
    ++p;
7263
0
  }
7264
0
  if (p == end) {
7265
0
    return std::string(input);
7266
0
  }
7267
7268
  // Output is always at most as long as the input: write into a single
7269
  // pre-sized buffer, then shrink to the final length.
7270
0
  std::string out(len, '\0');
7271
0
  char* d = out.data();
7272
0
  char* const d0 = d;
7273
7274
0
  const size_t prefix = static_cast<size_t>(p - src);
7275
0
  std::memcpy(d, src, prefix);
7276
0
  d += prefix;
7277
7278
0
  while (p < end) {
7279
0
    const char c = *p;
7280
0
    if (c == '+') {
7281
0
      *d++ = ' ';
7282
0
      ++p;
7283
0
    } else if (c == '%') {
7284
      // Decode runs of valid %XX tightly (common for nested URL query values).
7285
0
      while (p + 2 < end && *p == '%') {
7286
0
        const uint8_t hi = unhex_table[static_cast<uint8_t>(p[1])];
7287
0
        const uint8_t lo = unhex_table[static_cast<uint8_t>(p[2])];
7288
0
        if ((hi | lo) >= 16) {
7289
0
          break;
7290
0
        }
7291
0
        *d++ = static_cast<char>((hi << 4) | lo);
7292
0
        p += 3;
7293
0
      }
7294
0
      if (p < end && *p == '%') {
7295
        // Invalid escape: copy '%' literally and continue.
7296
0
        *d++ = *p++;
7297
0
      }
7298
0
    } else {
7299
      // Copy a plain run until the next '+' or '%'.
7300
0
      const char* start = p;
7301
0
      ++p;
7302
0
      while (p < end && *p != '+' && *p != '%') {
7303
0
        ++p;
7304
0
      }
7305
0
      const size_t n = static_cast<size_t>(p - start);
7306
0
      std::memcpy(d, start, n);
7307
0
      d += n;
7308
0
    }
7309
0
  }
7310
7311
0
  out.resize(static_cast<size_t>(d - d0));
7312
0
  return out;
7313
0
}
7314
7315
void percent_encode_suffix(const char* p, const char* end,
7316
                           const uint8_t character_set[], std::string& out);
7317
7318
std::string percent_encode(const std::string_view input,
7319
0
                           const uint8_t character_set[]) {
7320
0
  auto pointer = std::ranges::find_if(input, [character_set](const char c) {
7321
0
    return character_sets::bit_at(character_set, c);
7322
0
  });
7323
  // Optimization: Don't iterate if percent encode is not required
7324
0
  if (pointer == input.end()) {
7325
0
    return std::string(input);
7326
0
  }
7327
7328
0
  std::string result;
7329
0
  result.reserve(input.length());  // in the worst case, percent encoding might
7330
                                   // produce 3 characters.
7331
0
  result.append(input.substr(0, std::distance(input.begin(), pointer)));
7332
0
  if (static_cast<size_t>(input.end() - pointer) >= 48) {
7333
0
    percent_encode_suffix(&*pointer, input.data() + input.size(), character_set,
7334
0
                          result);
7335
0
  } else {
7336
0
    for (; pointer != input.end(); pointer++) {
7337
0
      if (character_sets::bit_at(character_set, *pointer)) {
7338
0
        result.append(character_sets::hex + uint8_t(*pointer) * 4, 3);
7339
0
      } else {
7340
0
        result += *pointer;
7341
0
      }
7342
0
    }
7343
0
  }
7344
0
  return result;
7345
0
}
7346
7347
template <bool append>
7348
bool percent_encode(const std::string_view input, const uint8_t character_set[],
7349
0
                    std::string& out) {
7350
0
  ada_log("percent_encode ", input, " to output string while ",
7351
0
          append ? "appending" : "overwriting");
7352
0
  auto pointer = std::ranges::find_if(input, [character_set](const char c) {
7353
0
    return character_sets::bit_at(character_set, c);
7354
0
  });
Unexecuted instantiation: ada::unicode::percent_encode<true>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, unsigned char const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&)::{lambda(char)#1}::operator()(char) const
Unexecuted instantiation: ada::unicode::percent_encode<false>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, unsigned char const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&)::{lambda(char)#1}::operator()(char) const
7355
0
  ada_log("percent_encode done checking, moved to ",
7356
0
          std::distance(input.begin(), pointer));
7357
7358
  // Optimization: Don't iterate if percent encode is not required
7359
0
  if (pointer == input.end()) {
7360
0
    ada_log("percent_encode encoding not needed.");
7361
0
    return false;
7362
0
  }
7363
0
  if constexpr (!append) {
7364
0
    out.clear();
7365
0
  }
7366
0
  ada_log("percent_encode appending ", std::distance(input.begin(), pointer),
7367
0
          " bytes");
7368
  // NOLINTNEXTLINE(bugprone-suspicious-stringview-data-usage)
7369
0
  out.append(input.data(), std::distance(input.begin(), pointer));
7370
0
  ada_log("percent_encode processing ", std::distance(pointer, input.end()),
7371
0
          " bytes");
7372
0
  for (; pointer != input.end(); pointer++) {
7373
0
    if (character_sets::bit_at(character_set, *pointer)) {
7374
0
      out.append(character_sets::hex + uint8_t(*pointer) * 4, 3);
7375
0
    } else {
7376
0
      out += *pointer;
7377
0
    }
7378
0
  }
7379
0
  return true;
7380
0
}
Unexecuted instantiation: bool ada::unicode::percent_encode<true>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, unsigned char const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&)
Unexecuted instantiation: bool ada::unicode::percent_encode<false>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, unsigned char const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&)
7381
7382
template bool percent_encode<true>(std::string_view input,
7383
                                   const uint8_t character_set[],
7384
                                   std::string& out);
7385
template bool percent_encode<false>(std::string_view input,
7386
                                    const uint8_t character_set[],
7387
                                    std::string& out);
7388
7389
bool to_ascii(std::optional<std::string>& out, const std::string_view plain,
7390
0
              size_t first_percent) {
7391
0
  std::string percent_decoded_buffer;
7392
0
  std::string_view input = plain;
7393
0
  if (first_percent != std::string_view::npos) {
7394
0
    percent_decoded_buffer = unicode::percent_decode(plain, first_percent);
7395
0
    input = percent_decoded_buffer;
7396
0
  }
7397
  // input is a non-empty UTF-8 string, must be percent decoded
7398
0
  std::string idna_ascii = ada::idna::to_ascii(input);
7399
0
  if (idna_ascii.empty() || contains_forbidden_domain_code_point(
7400
0
                                idna_ascii.data(), idna_ascii.size())) {
7401
0
    return false;
7402
0
  }
7403
0
  out = std::move(idna_ascii);
7404
0
  return true;
7405
0
}
7406
7407
std::string percent_encode(const std::string_view input,
7408
0
                           const uint8_t character_set[], size_t index) {
7409
0
  std::string out;
7410
  // NOLINTNEXTLINE(bugprone-suspicious-stringview-data-usage)
7411
0
  out.append(input.data(), index);
7412
0
  auto pointer = input.begin() + index;
7413
0
  if (static_cast<size_t>(input.end() - pointer) >= 48) {
7414
0
    percent_encode_suffix(&*pointer, input.data() + input.size(), character_set,
7415
0
                          out);
7416
0
  } else {
7417
0
    for (; pointer != input.end(); pointer++) {
7418
0
      if (character_sets::bit_at(character_set, *pointer)) {
7419
0
        out.append(character_sets::hex + uint8_t(*pointer) * 4, 3);
7420
0
      } else {
7421
0
        out += *pointer;
7422
0
      }
7423
0
    }
7424
0
  }
7425
0
  return out;
7426
0
}
7427
7428
}  // namespace ada::unicode
7429
/* end file src/unicode.cpp */
7430
#if !defined(ADA_PERCENT_ENCODE_SIMD_SEPARATE_TU)
7431
/* begin file src/unicode_percent_encode.cpp */
7432
#include <cstdint>
7433
7434
7435
7436
#include <cstring>
7437
#if ADA_SSSE3
7438
#include <tmmintrin.h>
7439
#define ADA_UNICODE_SSSE3 1
7440
#elif ADA_NEON
7441
#include <arm_neon.h>
7442
#elif ADA_RVV
7443
#include <riscv_vector.h>
7444
#endif
7445
7446
// gcc/clang honor target("ssse3") on an SSE2 translation unit. clang-cl and
7447
// MSVC do not: they still compile the function as SSE2, then reject
7448
// always_inline _mm_shuffle_epi8. Same approach as parser.cpp.
7449
#if !ADA_UNICODE_SSSE3 && (defined(__x86_64__) || defined(__amd64__)) && \
7450
    defined(__GNUC__) && !defined(_MSC_VER)
7451
#include <tmmintrin.h>
7452
#define ADA_UNICODE_SSSE3 1
7453
#define ADA_UNICODE_NEED_SSSE3_TARGET 1
7454
#endif
7455
#ifndef ADA_UNICODE_SSSE3
7456
#define ADA_UNICODE_SSSE3 0
7457
#endif
7458
#ifdef ADA_UNICODE_NEED_SSSE3_TARGET
7459
#define ADA_UNICODE_SIMD __attribute__((target("ssse3")))
7460
#else
7461
#define ADA_UNICODE_SIMD ada_really_inline
7462
#endif
7463
7464
#ifdef ADA_REGULAR_VISUAL_STUDIO
7465
#include <intrin.h>
7466
#endif
7467
7468
namespace ada::unicode {
7469
namespace {
7470
7471
#if ADA_UNICODE_SSSE3 || ADA_NEON
7472
0
ada_really_inline int trailing_zeroes32(uint32_t input_num) noexcept {
7473
#ifdef ADA_REGULAR_VISUAL_STUDIO
7474
  unsigned long ret;
7475
  _BitScanForward(&ret, input_num);
7476
  return static_cast<int>(ret);
7477
#else
7478
0
  return __builtin_ctz(input_num);
7479
0
#endif
7480
0
}
7481
7482
// Append one window whose set bits mark bytes that need encoding.
7483
ada_really_inline void encode_mask_window(const char* p, uint32_t mask,
7484
0
                                          size_t width, std::string& out) {
7485
0
  uint64_t bits = mask;
7486
0
  size_t off = 0;
7487
0
  while (bits != 0) {
7488
0
    const int zero_run = trailing_zeroes32(static_cast<uint32_t>(bits));
7489
0
    if (zero_run != 0) {
7490
0
      out.append(p + off, static_cast<size_t>(zero_run));
7491
0
    }
7492
0
    off += static_cast<size_t>(zero_run);
7493
0
    out.append(character_sets::hex + uint8_t(p[off]) * 4, 3);
7494
0
    ++off;
7495
0
    bits >>= static_cast<unsigned>(zero_run + 1);
7496
0
  }
7497
0
  if (off < width) {
7498
0
    out.append(p + off, width - off);
7499
0
  }
7500
0
}
7501
#endif  // ADA_UNICODE_SSSE3 || ADA_NEON
7502
7503
ada_really_inline void percent_encode_to_scalar(const char* p, const char* end,
7504
                                                const uint8_t character_set[],
7505
0
                                                std::string& out) {
7506
0
  for (; p != end; ++p) {
7507
0
    if (character_sets::bit_at(character_set, *p)) {
7508
0
      out.append(character_sets::hex + uint8_t(*p) * 4, 3);
7509
0
    } else {
7510
0
      out += *p;
7511
0
    }
7512
0
  }
7513
0
}
7514
7515
#if ADA_UNICODE_SSSE3
7516
// Classify 16 input bytes against the 32-byte character_set bitmap:
7517
// bit_at(cs, b) == cs[b >> 3] & (1 << (b & 7)). pshufb looks up the two
7518
// 16-byte halves of that bitmap; no per-call nibble table is built.
7519
struct ssse3_percent_tables {
7520
  __m128i cs_lo;
7521
  __m128i cs_hi;
7522
  __m128i pow2;
7523
  __m128i mask_0f;
7524
  __m128i mask_07;
7525
  __m128i zero;
7526
};
7527
7528
ADA_UNICODE_SIMD ssse3_percent_tables
7529
0
load_ssse3_percent_tables(const uint8_t character_set[]) noexcept {
7530
0
  ssse3_percent_tables t{};
7531
0
  t.cs_lo = _mm_loadu_si128(reinterpret_cast<const __m128i*>(character_set));
7532
0
  t.cs_hi =
7533
0
      _mm_loadu_si128(reinterpret_cast<const __m128i*>(character_set + 16));
7534
  // 1 << (0..7), duplicated so pshufb(index & 7) works for every lane.
7535
0
  t.pow2 =
7536
0
      _mm_setr_epi8(1, 2, 4, 8, 16, 32, 64, -128, 1, 2, 4, 8, 16, 32, 64, -128);
7537
0
  t.mask_0f = _mm_set1_epi8(0x0F);
7538
0
  t.mask_07 = _mm_set1_epi8(0x07);
7539
0
  t.zero = _mm_setzero_si128();
7540
0
  return t;
7541
0
}
7542
7543
ADA_UNICODE_SIMD int ssse3_percent_mask(
7544
0
    __m128i word, const ssse3_percent_tables& tables) noexcept {
7545
0
  const __m128i idx = _mm_and_si128(_mm_srli_epi16(word, 3), tables.mask_0f);
7546
0
  const __m128i lo = _mm_shuffle_epi8(tables.cs_lo, idx);
7547
0
  const __m128i hi = _mm_shuffle_epi8(tables.cs_hi, idx);
7548
  // Bytes 0x80-0xFF are signed-negative; select the high half of the bitmap.
7549
0
  const __m128i high_byte = _mm_cmpgt_epi8(tables.zero, word);
7550
0
  const __m128i cs_byte = _mm_or_si128(_mm_and_si128(hi, high_byte),
7551
0
                                       _mm_andnot_si128(high_byte, lo));
7552
0
  const __m128i bits =
7553
0
      _mm_shuffle_epi8(tables.pow2, _mm_and_si128(word, tables.mask_07));
7554
0
  const __m128i hits = _mm_and_si128(cs_byte, bits);
7555
0
  return _mm_movemask_epi8(_mm_cmpeq_epi8(hits, tables.zero)) ^ 0xFFFF;
7556
0
}
7557
7558
ADA_UNICODE_SIMD void percent_encode_to_ssse3(
7559
    const char* p, const char* end, const uint8_t character_set[],
7560
0
    const ssse3_percent_tables& tables, std::string& out) {
7561
  // Pair 16-byte windows so a fully clean 32-byte run is one append.
7562
0
  while (p + 32 <= end) {
7563
0
    const __m128i word0 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(p));
7564
0
    const __m128i word1 =
7565
0
        _mm_loadu_si128(reinterpret_cast<const __m128i*>(p + 16));
7566
0
    const int mask0 = ssse3_percent_mask(word0, tables);
7567
0
    const int mask1 = ssse3_percent_mask(word1, tables);
7568
0
    if ((mask0 | mask1) == 0) {
7569
0
      out.append(p, 32);
7570
0
    } else {
7571
0
      if (mask0 == 0) {
7572
0
        out.append(p, 16);
7573
0
      } else {
7574
0
        encode_mask_window(p, static_cast<uint32_t>(mask0), 16, out);
7575
0
      }
7576
0
      if (mask1 == 0) {
7577
0
        out.append(p + 16, 16);
7578
0
      } else {
7579
0
        encode_mask_window(p + 16, static_cast<uint32_t>(mask1), 16, out);
7580
0
      }
7581
0
    }
7582
0
    p += 32;
7583
0
  }
7584
0
  if (p + 16 <= end) {
7585
0
    const __m128i word = _mm_loadu_si128(reinterpret_cast<const __m128i*>(p));
7586
0
    const int mask = ssse3_percent_mask(word, tables);
7587
0
    if (mask == 0) {
7588
0
      out.append(p, 16);
7589
0
    } else {
7590
0
      encode_mask_window(p, static_cast<uint32_t>(mask), 16, out);
7591
0
    }
7592
0
    p += 16;
7593
0
  }
7594
0
  percent_encode_to_scalar(p, end, character_set, out);
7595
0
}
7596
#endif  // ADA_UNICODE_SSSE3
7597
7598
#if ADA_NEON
7599
ada_really_inline uint8x16x2_t
7600
load_neon_percent_table(const uint8_t character_set[]) noexcept {
7601
  uint8x16x2_t table{};
7602
  table.val[0] = vld1q_u8(character_set);
7603
  table.val[1] = vld1q_u8(character_set + 16);
7604
  return table;
7605
}
7606
7607
ada_really_inline uint8x16_t neon_percent_hits(uint8x16_t word,
7608
                                               uint8x16x2_t table) noexcept {
7609
  const uint8x16_t cs_bytes = vqtbl2q_u8(table, vshrq_n_u8(word, 3));
7610
  const uint8x16_t bit_mask = vshlq_u8(
7611
      vdupq_n_u8(1), vreinterpretq_s8_u8(vandq_u8(word, vdupq_n_u8(7))));
7612
  return vandq_u8(cs_bytes, bit_mask);
7613
}
7614
7615
ada_really_inline uint32_t neon_percent_mask(uint8x16_t hits) noexcept {
7616
  const uint8x16_t cmp = vcgtq_u8(hits, vdupq_n_u8(0));
7617
  const uint8x16_t bit = {1, 2, 4, 8, 16, 32, 64, 128,
7618
                          1, 2, 4, 8, 16, 32, 64, 128};
7619
  const uint8x16_t masked = vandq_u8(cmp, bit);
7620
  return static_cast<uint32_t>(vaddv_u8(vget_low_u8(masked))) |
7621
         (static_cast<uint32_t>(vaddv_u8(vget_high_u8(masked))) << 8);
7622
}
7623
7624
ada_really_inline void percent_encode_to_neon(const char* p, const char* end,
7625
                                              const uint8_t character_set[],
7626
                                              uint8x16x2_t table,
7627
                                              std::string& out) {
7628
  while (p + 32 <= end) {
7629
    const uint8x16_t hits0 =
7630
        neon_percent_hits(vld1q_u8(reinterpret_cast<const uint8_t*>(p)), table);
7631
    const uint8x16_t hits1 = neon_percent_hits(
7632
        vld1q_u8(reinterpret_cast<const uint8_t*>(p + 16)), table);
7633
    const bool clean0 = vmaxvq_u32(vreinterpretq_u32_u8(hits0)) == 0;
7634
    const bool clean1 = vmaxvq_u32(vreinterpretq_u32_u8(hits1)) == 0;
7635
    if (clean0 && clean1) {
7636
      out.append(p, 32);
7637
    } else {
7638
      if (clean0) {
7639
        out.append(p, 16);
7640
      } else {
7641
        encode_mask_window(p, neon_percent_mask(hits0), 16, out);
7642
      }
7643
      if (clean1) {
7644
        out.append(p + 16, 16);
7645
      } else {
7646
        encode_mask_window(p + 16, neon_percent_mask(hits1), 16, out);
7647
      }
7648
    }
7649
    p += 32;
7650
  }
7651
  if (p + 16 <= end) {
7652
    const uint8x16_t hits =
7653
        neon_percent_hits(vld1q_u8(reinterpret_cast<const uint8_t*>(p)), table);
7654
    if (vmaxvq_u32(vreinterpretq_u32_u8(hits)) == 0) {
7655
      out.append(p, 16);
7656
    } else {
7657
      encode_mask_window(p, neon_percent_mask(hits), 16, out);
7658
    }
7659
    p += 16;
7660
  }
7661
  percent_encode_to_scalar(p, end, character_set, out);
7662
}
7663
#endif  // ADA_NEON
7664
7665
#if ADA_RVV
7666
ada_really_inline void percent_encode_to_rvv(const char* p, const char* end,
7667
                                             const uint8_t character_set[],
7668
                                             std::string& out) {
7669
  while (p < end) {
7670
    const size_t remaining = static_cast<size_t>(end - p);
7671
    const size_t vl = __riscv_vsetvl_e8m1(remaining);
7672
    const vuint8m1_t word =
7673
        __riscv_vle8_v_u8m1(reinterpret_cast<const uint8_t*>(p), vl);
7674
    const vuint8m1_t cs_bytes =
7675
        __riscv_vluxei8(character_set, __riscv_vsrl(word, 3, vl), vl);
7676
    const vuint8m1_t bit_mask = __riscv_vsll(__riscv_vmv_v_x_u8m1(1, vl),
7677
                                             __riscv_vand(word, 7, vl), vl);
7678
    const long idx = __riscv_vfirst(
7679
        __riscv_vmsne(__riscv_vand(cs_bytes, bit_mask, vl), 0, vl), vl);
7680
    if (idx < 0) {
7681
      out.append(p, vl);
7682
      p += vl;
7683
      continue;
7684
    }
7685
    if (idx > 0) {
7686
      out.append(p, static_cast<size_t>(idx));
7687
      p += idx;
7688
    }
7689
    out.append(character_sets::hex + uint8_t(*p) * 4, 3);
7690
    ++p;
7691
  }
7692
}
7693
#endif  // ADA_RVV
7694
7695
#if ADA_UNICODE_SSSE3 || ADA_NEON || ADA_RVV
7696
// Setter and existing percent_encode benches are 2-44 bytes. Table setup
7697
// plus mask walking costs more instructions than bit_at on those inputs
7698
// (especially dense USERINFO). SIMD pays off on the remaining suffix.
7699
static constexpr size_t kPercentEncodeSimdMin = 48;
7700
7701
void percent_encode_to_wide(const char* p, const char* end,
7702
0
                            const uint8_t character_set[], std::string& out) {
7703
  // Worst case every byte becomes %XX. Avoids realloc while walking windows.
7704
0
  out.reserve(out.size() + static_cast<size_t>(end - p) * 3);
7705
0
#if ADA_UNICODE_SSSE3
7706
0
  const ssse3_percent_tables tables = load_ssse3_percent_tables(character_set);
7707
0
  percent_encode_to_ssse3(p, end, character_set, tables, out);
7708
#elif ADA_NEON
7709
  percent_encode_to_neon(p, end, character_set,
7710
                         load_neon_percent_table(character_set), out);
7711
#elif ADA_RVV
7712
  percent_encode_to_rvv(p, end, character_set, out);
7713
#endif
7714
0
}
7715
#endif
7716
7717
}  // namespace
7718
7719
void percent_encode_suffix(const char* p, const char* end,
7720
0
                           const uint8_t character_set[], std::string& out) {
7721
0
#if ADA_UNICODE_SSSE3 || ADA_NEON || ADA_RVV
7722
0
  if (static_cast<size_t>(end - p) >= kPercentEncodeSimdMin) {
7723
0
    percent_encode_to_wide(p, end, character_set, out);
7724
0
    return;
7725
0
  }
7726
0
#endif
7727
0
  percent_encode_to_scalar(p, end, character_set, out);
7728
0
}
7729
7730
}  // namespace ada::unicode
7731
/* end file src/unicode_percent_encode.cpp */
7732
#endif
7733
/* begin file src/serializers.cpp */
7734
7735
#include <array>
7736
#include <cstdint>
7737
#include <cstring>
7738
#include <string>
7739
7740
namespace ada::serializers {
7741
namespace {
7742
7743
// Digit pair LUT for fast decimal write: index 0..99 -> two chars.
7744
0
constexpr std::array<char, 200> make_digit_pairs() noexcept {
7745
0
  std::array<char, 200> t{};
7746
0
  for (size_t i = 0; i < 100; ++i) {
7747
0
    t[i * 2] = static_cast<char>('0' + i / 10);
7748
0
    t[i * 2 + 1] = static_cast<char>('0' + i % 10);
7749
0
  }
7750
0
  return t;
7751
0
}
7752
7753
constexpr auto digit_pairs = make_digit_pairs();
7754
7755
0
ada_really_inline char* write_u8(char* p, uint8_t v) noexcept {
7756
0
  if (v < 10) {
7757
0
    *p++ = static_cast<char>('0' + v);
7758
0
  } else if (v < 100) {
7759
0
    std::memcpy(p, &digit_pairs[static_cast<size_t>(v) * 2], 2);
7760
0
    p += 2;
7761
0
  } else {
7762
0
    *p++ = static_cast<char>('0' + v / 100);
7763
0
    std::memcpy(p, &digit_pairs[static_cast<size_t>(v % 100) * 2], 2);
7764
0
    p += 2;
7765
0
  }
7766
0
  return p;
7767
0
}
7768
7769
0
ada_really_inline char* write_hex_u16(char* p, uint16_t v) noexcept {
7770
0
  static constexpr char kHex[] = "0123456789abcdef";
7771
0
  if (v >= 0x1000) {
7772
0
    *p++ = kHex[(v >> 12) & 0xf];
7773
0
    *p++ = kHex[(v >> 8) & 0xf];
7774
0
    *p++ = kHex[(v >> 4) & 0xf];
7775
0
    *p++ = kHex[v & 0xf];
7776
0
  } else if (v >= 0x100) {
7777
0
    *p++ = kHex[(v >> 8) & 0xf];
7778
0
    *p++ = kHex[(v >> 4) & 0xf];
7779
0
    *p++ = kHex[v & 0xf];
7780
0
  } else if (v >= 0x10) {
7781
0
    *p++ = kHex[(v >> 4) & 0xf];
7782
0
    *p++ = kHex[v & 0xf];
7783
0
  } else {
7784
0
    *p++ = kHex[v & 0xf];
7785
0
  }
7786
0
  return p;
7787
0
}
7788
7789
}  // namespace
7790
7791
void find_longest_sequence_of_ipv6_pieces(
7792
    const std::array<uint16_t, 8>& address, size_t& compress,
7793
0
    size_t& compress_length) noexcept {
7794
0
  compress = 0;
7795
0
  compress_length = 0;
7796
0
  size_t i = 0;
7797
0
  while (i < 8) {
7798
0
    if (address[i] != 0) {
7799
0
      ++i;
7800
0
      continue;
7801
0
    }
7802
0
    size_t next = i + 1;
7803
0
    while (next < 8 && address[next] == 0) {
7804
0
      ++next;
7805
0
    }
7806
0
    const size_t count = next - i;
7807
0
    if (count > compress_length) {
7808
0
      compress_length = count;
7809
0
      compress = i;
7810
0
    }
7811
0
    i = next;
7812
0
  }
7813
0
}
7814
7815
0
std::string ipv6(const std::array<uint16_t, 8>& address) {
7816
0
  size_t compress = 0;
7817
0
  size_t compress_length = 0;
7818
0
  find_longest_sequence_of_ipv6_pieces(address, compress, compress_length);
7819
7820
  // Skip compression when the longest zero run is a single piece.
7821
0
  if (compress_length <= 1) {
7822
0
    compress = compress_length = 8;
7823
0
  }
7824
7825
  // Max: '[' + 8*4 hex + 7 ':' + ']' = 41
7826
0
  std::string output(4 * 8 + 7 + 2, '\0');
7827
0
  char* point = output.data();
7828
0
  *point++ = '[';
7829
0
  size_t piece_index = 0;
7830
0
  while (true) {
7831
0
    if (piece_index == compress) {
7832
0
      *point++ = ':';
7833
      // If we skip a value initially, we need to write '::'.
7834
0
      if (piece_index == 0) {
7835
0
        *point++ = ':';
7836
0
      }
7837
0
      piece_index += compress_length;
7838
0
      if (piece_index == 8) {
7839
0
        break;
7840
0
      }
7841
0
    }
7842
0
    point = write_hex_u16(point, address[piece_index]);
7843
0
    ++piece_index;
7844
0
    if (piece_index == 8) {
7845
0
      break;
7846
0
    }
7847
0
    *point++ = ':';
7848
0
  }
7849
0
  *point++ = ']';
7850
0
  output.resize(static_cast<size_t>(point - output.data()));
7851
0
  return output;
7852
0
}
7853
7854
0
std::string ipv4(const uint64_t address) {
7855
0
  std::string output(15, '\0');
7856
0
  char* point = output.data();
7857
0
  point = write_u8(point, static_cast<uint8_t>(address >> 24));
7858
0
  *point++ = '.';
7859
0
  point = write_u8(point, static_cast<uint8_t>(address >> 16));
7860
0
  *point++ = '.';
7861
0
  point = write_u8(point, static_cast<uint8_t>(address >> 8));
7862
0
  *point++ = '.';
7863
0
  point = write_u8(point, static_cast<uint8_t>(address));
7864
0
  output.resize(static_cast<size_t>(point - output.data()));
7865
0
  return output;
7866
0
}
7867
7868
}  // namespace ada::serializers
7869
/* end file src/serializers.cpp */
7870
/* begin file src/implementation.cpp */
7871
7872
#include <array>
7873
#include <atomic>
7874
#include <cstring>
7875
#include <limits>
7876
#include <optional>
7877
#include <string_view>
7878
7879
7880
namespace ada {
7881
7882
static std::atomic<uint32_t> max_input_length_{
7883
    std::numeric_limits<uint32_t>::max()};
7884
7885
0
void set_max_input_length(uint32_t length) {
7886
0
  max_input_length_.store(length, std::memory_order_relaxed);
7887
0
}
7888
7889
0
uint32_t get_max_input_length() {
7890
0
  return max_input_length_.load(std::memory_order_relaxed);
7891
0
}
7892
7893
namespace {
7894
7895
constexpr std::array<uint8_t, 256> clean_http_host_byte = []() consteval {
7896
  std::array<uint8_t, 256> result{};
7897
  for (size_t i = 0; i < result.size(); ++i) {
7898
    const auto c = static_cast<uint8_t>(i);
7899
    result[i] =
7900
        static_cast<uint8_t>((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') ||
7901
                             c == '-' || c == '.' || c == '_' || c == '~');
7902
  }
7903
  return result;
7904
}();
7905
7906
// SWAR: eight ASCII host bytes in [a-z0-9-._~] without 8 table lookups.
7907
// High bits must be clear first so the range subtracts cannot borrow
7908
// across bytes.
7909
// High-bit-cleared ASCII only. Subtracts cannot borrow across bytes because
7910
// each (hi|0x80) byte is >= 0x80 and each data byte is <= 0x7F. Do not use
7911
// has-zero (x-ones)&~x: a match followed by match^1 (e.g. "./" or "_^")
7912
// produces a false positive via borrow.
7913
ada_really_inline uint64_t swar_in_range(uint64_t w, uint8_t lo,
7914
0
                                         uint8_t hi) noexcept {
7915
0
  constexpr uint64_t k_ones = 0x0101010101010101ull;
7916
0
  constexpr uint64_t k_high = 0x8080808080808080ull;
7917
0
  const uint64_t ge_lo = (w | k_high) - (k_ones * lo);
7918
0
  const uint64_t le_hi = ((k_ones * hi) | k_high) - w;
7919
0
  return ge_lo & le_hi & k_high;
7920
0
}
7921
7922
ada_really_inline bool eight_clean_http_host_bytes(
7923
0
    const uint8_t* input) noexcept {
7924
0
  uint64_t w = 0;
7925
0
  std::memcpy(&w, input, 8);
7926
0
  constexpr uint64_t k_high = 0x8080808080808080ull;
7927
0
  if ((w & k_high) != 0) {
7928
0
    return false;
7929
0
  }
7930
0
  const uint64_t ok = swar_in_range(w, 'a', 'z') | swar_in_range(w, '0', '9') |
7931
0
                      swar_in_range(w, '-', '-') | swar_in_range(w, '.', '.') |
7932
0
                      swar_in_range(w, '_', '_') | swar_in_range(w, '~', '~');
7933
0
  return ok == k_high;
7934
0
}
7935
7936
// Minimal front end for the overwhelmingly common already-canonical HTTP(S)
7937
// case. It deliberately handles fewer inputs than
7938
// try_can_parse_absolute_fast: anything requiring normalization or detailed
7939
// host parsing falls through to that broader validator.
7940
#if defined(_MSC_VER) || \
7941
    (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
7942
constexpr bool k_can_parse_little_endian = true;
7943
#else
7944
constexpr bool k_can_parse_little_endian = false;
7945
#endif
7946
7947
0
std::optional<bool> try_can_parse_clean_http(std::string_view input) noexcept {
7948
0
  const auto* bytes = reinterpret_cast<const uint8_t*>(input.data());
7949
0
  const size_t length = input.size();
7950
0
  if (length < 7) {
7951
0
    return std::nullopt;
7952
0
  }
7953
7954
0
  size_t authority_start;
7955
0
  if constexpr (k_can_parse_little_endian) {
7956
0
    if (length >= 8) {
7957
0
      uint64_t first8 = 0;
7958
0
      std::memcpy(&first8, bytes, 8);
7959
0
      if (first8 == 0x2f2f3a7370747468ull) {  // "https://"
7960
0
        authority_start = 8;
7961
0
      } else if ((first8 & 0x00ffffffffffffffull) ==
7962
0
                 0x002f2f3a70747468ull) {  // "http://"
7963
0
        authority_start = 7;
7964
0
      } else {
7965
0
        return std::nullopt;
7966
0
      }
7967
0
    } else if (bytes[0] == 'h' && bytes[1] == 't' && bytes[2] == 't' &&
7968
0
               bytes[3] == 'p' && bytes[4] == ':' && bytes[5] == '/' &&
7969
0
               bytes[6] == '/') {
7970
0
      authority_start = 7;
7971
0
    } else {
7972
0
      return std::nullopt;
7973
0
    }
7974
  } else {
7975
    uint32_t first4{};
7976
    std::memcpy(&first4, bytes, 4);
7977
    if (first4 != 0x68747470u) {  // "http"
7978
      return std::nullopt;
7979
    }
7980
    if (length >= 8 && bytes[4] == 's' && bytes[5] == ':' && bytes[6] == '/' &&
7981
        bytes[7] == '/') {
7982
      authority_start = 8;
7983
    } else if (bytes[4] == ':' && bytes[5] == '/' && bytes[6] == '/') {
7984
      authority_start = 7;
7985
    } else {
7986
      return std::nullopt;
7987
    }
7988
  }
7989
7990
0
  if (authority_start >= length) {
7991
0
    return false;
7992
0
  }
7993
7994
0
  size_t cursor = authority_start;
7995
0
  while (cursor + 8 <= length && eight_clean_http_host_bytes(bytes + cursor)) {
7996
0
    cursor += 8;
7997
0
  }
7998
0
  while (cursor < length) {
7999
0
    const uint8_t c = bytes[cursor];
8000
0
    if (c == '/' || c == '?' || c == '#') {
8001
0
      break;
8002
0
    }
8003
0
    if (!clean_http_host_byte[c]) {
8004
0
      return std::nullopt;
8005
0
    }
8006
0
    ++cursor;
8007
0
  }
8008
8009
0
  const size_t host_length = cursor - authority_start;
8010
0
  if (host_length == 0) {
8011
    // Extra special-scheme slashes are normalization, not an empty host.
8012
0
    if (bytes[authority_start] == '/' || bytes[authority_start] == '\\') {
8013
0
      return std::nullopt;
8014
0
    }
8015
0
    return false;
8016
0
  }
8017
0
  if (host_length > 253 || bytes[cursor - 1] == '.') {
8018
0
    return std::nullopt;
8019
0
  }
8020
8021
0
  const std::string_view host(input.data() + authority_start, host_length);
8022
0
  if (checkers::last_label_may_be_a_number(host)) {
8023
0
    return std::nullopt;
8024
0
  }
8025
0
  if (host.find('x') != std::string_view::npos &&
8026
0
      host.find("xn-") != std::string_view::npos) {
8027
0
    return std::nullopt;
8028
0
  }
8029
8030
  // Once a special URL has a valid host, path/query/fragment bytes cannot make
8031
  // it structurally invalid: the full parser percent-encodes them as needed.
8032
0
  return true;
8033
0
}
8034
8035
// @private
8036
// Fast-path validator for can_parse.
8037
//
8038
// Validates absolute special (non-file) URLs without constructing any
8039
// url_aggregator object and without running the state machine.
8040
// Performs a single forward scan over the input bytes.
8041
//
8042
// Returns:
8043
//   true      -- URL is structurally valid
8044
//   false     -- URL is definitely invalid
8045
//   nullopt   -- edge case; fall through to the full parser
8046
//               (credentials, IDNA, IPv4/6, tabs/newlines, relative URLs, ...)
8047
std::optional<bool> try_can_parse_absolute_fast(
8048
0
    std::string_view input) noexcept {
8049
0
  const uint8_t* b = reinterpret_cast<const uint8_t*>(input.data());
8050
0
  size_t len = input.size();
8051
8052
  // -- Inline C0 whitespace trim (no allocation) --------------------------
8053
  // Note: \t (0x09), \n (0x0a), \r (0x0d) are all <= 0x20, so any
8054
  // leading/trailing tabs or newlines are correctly stripped here, matching
8055
  // the WHATWG spec's "remove leading/trailing C0 control and space" step.
8056
0
  while (len > 0 && b[0] <= 0x20) {
8057
0
    b++;
8058
0
    len--;
8059
0
  }
8060
0
  while (len > 0 && b[len - 1] <= 0x20) {
8061
0
    len--;
8062
0
  }
8063
0
  if (len == 0) return false;
8064
8065
  // -- Scheme detection -----------------------------------------------------
8066
  // Fast path for HTTP and HTTPS (covers ~90%+ of real-world URLs).
8067
  // Avoids the general scheme loop, buffer copy, and perfect hash lookup.
8068
  // We know HTTP and HTTPS are special non-file schemes, so no further
8069
  // scheme_type checks are needed on the fast path -- only `pos` matters.
8070
0
  size_t pos;
8071
8072
0
  if (len >= 7 && (b[0] | 0x20) == 'h' && (b[1] | 0x20) == 't' &&
8073
0
      (b[2] | 0x20) == 't' && (b[3] | 0x20) == 'p') {
8074
0
    if (b[4] == ':' && b[5] == '/' && b[6] == '/') {
8075
0
      pos = 7;
8076
0
      goto skip_extra_slashes;
8077
0
    }
8078
0
    if (len >= 8 && (b[4] | 0x20) == 's' && b[5] == ':' && b[6] == '/' &&
8079
0
        b[7] == '/') {
8080
0
      pos = 8;
8081
0
      goto skip_extra_slashes;
8082
0
    }
8083
    // Fall through: could be "httpe://", tabs in scheme, etc.
8084
0
  }
8085
8086
0
  {
8087
    // General scheme detection for ws, wss, ftp, and edge cases.
8088
0
    if (!checkers::is_alpha(static_cast<char>(b[0]))) return false;
8089
8090
    // Scan for ':' within the first 7 bytes. All special schemes are <= 5
8091
    // chars ("https"), so any URL whose first ':' is beyond byte 6 is either
8092
    // non-special or relative -- both require the full parser.
8093
0
    size_t colon_pos = 0;
8094
0
    for (size_t i = 1;; ++i) {
8095
0
      if (i >= 7 || i >= len) return std::nullopt;
8096
0
      const char c = static_cast<char>(b[i]);
8097
0
      if (c == ':') {
8098
0
        colon_pos = i;
8099
0
        break;
8100
0
      }
8101
      // Tabs/newlines in the scheme require the full parser to strip them.
8102
0
      if (c == '\t' || c == '\n' || c == '\r') return std::nullopt;
8103
0
      if (!unicode::is_alnum_plus(c)) return false;
8104
0
    }
8105
8106
    // Lowercase scheme bytes inline and classify via the existing perfect
8107
    // hash.
8108
0
    char scheme_buf[6];
8109
0
    scheme_buf[0] = static_cast<char>(b[0] | 0x20);
8110
0
    for (size_t i = 1; i < colon_pos; ++i)
8111
0
      scheme_buf[i] = static_cast<char>(b[i] | 0x20);
8112
8113
0
    const ada::scheme::type scheme_type =
8114
0
        ada::scheme::get_scheme_type({scheme_buf, colon_pos});
8115
8116
    // Only handle special, non-file schemes.
8117
0
    if (scheme_type == ada::scheme::NOT_SPECIAL) return std::nullopt;
8118
0
    if (scheme_type == ada::scheme::FILE) return std::nullopt;
8119
8120
    // Per WHATWG, special URLs don't require "//": "http:example.com" is valid
8121
    // (SPECIAL_AUTHORITY_IGNORE_SLASHES just skips leading slashes and
8122
    // proceeds to AUTHORITY).  Defer to the inline fallback for any input
8123
    // without "://".
8124
0
    pos = colon_pos + 1;
8125
0
    if (pos + 2 > len || b[pos] != '/' || b[pos + 1] != '/') {
8126
0
      return std::nullopt;
8127
0
    }
8128
0
    pos += 2;
8129
0
  }
8130
8131
0
skip_extra_slashes:
8132
  // SPECIAL_AUTHORITY_IGNORE_SLASHES: the full parser skips any additional
8133
  // leading '/' or '\' after the initial "//".  Mirror that here so we don't
8134
  // mis-identify the host as empty when there are extra slashes.
8135
0
  while (pos < len && (b[pos] == '/' || b[pos] == '\\')) {
8136
0
    ++pos;
8137
0
  }
8138
8139
  // Early IPv6 bail-out: if the authority starts with '[', it's an IPv6
8140
  // literal which requires the full parser.  Checking here avoids scanning
8141
  // the entire bracketed address only to bail out afterward.
8142
0
  if (pos < len && b[pos] == '[') return std::nullopt;
8143
8144
  // -- Merged authority + host scan ------------------------------------------
8145
  // A single forward pass over the authority bytes that simultaneously:
8146
  //   - finds the authority end and port colon
8147
  //   - validates host characters (forbidden domain code points)
8148
  //   - tracks IPv4 indicators (all-decimal-dots, last non-dot char)
8149
  //   - detects xn-- prefixes (IDNA punycode)
8150
  //   - detects tabs/newlines (which require the full parser to strip)
8151
  // This replaces 4 separate scans over the host bytes.
8152
0
  const size_t auth_start = pos;
8153
0
  size_t auth_end = pos;
8154
0
  size_t port_colon = SIZE_MAX;
8155
0
  bool all_dec_dots = true;
8156
8157
0
  for (; auth_end < len; ++auth_end) {
8158
0
    const uint8_t c = b[auth_end];
8159
8160
    // Non-ASCII -> needs IDNA processing -> full parser.
8161
0
    if (c >= 0x80) return std::nullopt;
8162
8163
    // Authority delimiters.
8164
0
    if (c == '/' || c == '?' || c == '#' || c == '\\') break;
8165
8166
    // Port separator.
8167
0
    if (c == ':') {
8168
0
      if (port_colon == SIZE_MAX) port_colon = auth_end;
8169
0
      continue;
8170
0
    }
8171
8172
    // Credentials or percent-encoding -> full parser.
8173
0
    if (c == '@' || c == '%') return std::nullopt;
8174
8175
    // Tabs/newlines anywhere in the authority require the full parser to
8176
    // strip them before validation.  Without this, a tab in the port (e.g.
8177
    // "http://host:8\t0/") would be mis-rejected by port validation.
8178
0
    if (c == '\t' || c == '\n' || c == '\r') return std::nullopt;
8179
8180
    // Skip remaining host-specific checks for port bytes.  Port digits are
8181
    // validated separately below, and no forbidden-domain-code-point check
8182
    // is needed on port characters.
8183
0
    if (port_colon != SIZE_MAX) continue;
8184
8185
    // -- Host byte validation (inlined) ------------------------------------
8186
    // Forbidden domain code points that are not already caught above:
8187
    //   C0 controls and space (0x00-0x20), DEL (0x7F), <, >, [, ], ^, |.
8188
    // At this stage, the input may still be userinfo or be normalized later
8189
    // (e.g., percent-encoded), so we do not reject here and defer to the
8190
    // parser. Characters already caught: >= 0x80 (non-ASCII), '/' '?' '#' '\\'
8191
    // (delimiters), ':' (port), '@' '%' (bail), '\t' '\n' '\r' (bail).
8192
0
    if (c <= 0x20 || c == 0x7F || c == '<' || c == '>' || c == '[' ||
8193
0
        c == ']' || c == '^' || c == '|') {
8194
0
      return std::nullopt;
8195
0
    }
8196
8197
    // Track whether host is all decimal digits and dots (potential IPv4).
8198
0
    if (c != '.' && (c < '0' || c > '9')) all_dec_dots = false;
8199
8200
    // Detect xn-- prefix inline (IDNA punycode -> needs full parser).
8201
    // Checking at every position mirrors the original behavior: any
8202
    // occurrence of "xn--" in the host (not just at label boundaries)
8203
    // triggers a bail-out to the full IDNA validator.
8204
0
    if ((c | 0x20) == 'x' && auth_end + 4 <= len &&
8205
0
        (b[auth_end + 1] | 0x20) == 'n' && b[auth_end + 2] == '-' &&
8206
0
        b[auth_end + 3] == '-') {
8207
0
      return std::nullopt;
8208
0
    }
8209
0
  }
8210
8211
0
  const size_t host_end = (port_colon != SIZE_MAX) ? port_colon : auth_end;
8212
8213
  // Empty host is invalid for special URLs.
8214
0
  if (auth_start == host_end) return false;
8215
8216
  // -- IPv4 handling ---------------------------------------------------------
8217
0
  const char* host_ptr = reinterpret_cast<const char*>(b + auth_start);
8218
0
  const size_t host_len = host_end - auth_start;
8219
8220
0
  if (all_dec_dots) {
8221
    // Host is all decimal digits and dots -> try the fast IPv4 parser.
8222
0
    if (checkers::try_parse_ipv4_fast({host_ptr, host_len}) !=
8223
0
        checkers::ipv4_fast_fail) {
8224
      // Valid decimal IPv4 host.  Do NOT return true yet: the port still
8225
      // needs to be validated below before we can declare the URL valid.
8226
0
      goto validate_port;
8227
0
    }
8228
    // Fast IPv4 parsing failed (e.g. host is ".", "..", "1.2.3.500").
8229
    // Such hosts may still be valid domain names; defer to the full parser.
8230
0
    return std::nullopt;
8231
0
  }
8232
8233
0
  if (checkers::last_label_may_be_a_number({host_ptr, host_len})) {
8234
0
    return std::nullopt;
8235
0
  }
8236
8237
  // -- Port validation -------------------------------------------------------
8238
0
validate_port:
8239
0
  if (port_colon != SIZE_MAX) {
8240
0
    const uint8_t* pp = b + port_colon + 1;
8241
0
    size_t pl = auth_end - port_colon - 1;
8242
0
    if (pl > 0) {
8243
      // Strip leading zeros: "0000001" == 1, "0000000000000" == 0, both valid.
8244
      // Only the significant digits count toward the 5-digit maximum.
8245
0
      while (pl > 0 && *pp == '0') {
8246
0
        ++pp;
8247
0
        --pl;
8248
0
      }
8249
0
      if (pl > 5) return false;  // significant digits > 99999
8250
0
      uint32_t pv = 0;
8251
0
      for (size_t i = 0; i < pl; ++i) {
8252
0
        if (pp[i] < '0' || pp[i] > '9') return false;
8253
0
        pv = pv * 10 + (pp[i] - '0');
8254
0
      }
8255
0
      if (pv > 65535) return false;
8256
0
    }
8257
0
  }
8258
8259
  // Path, query, and fragment are structurally always valid for can_parse --
8260
  // the parser would encode whatever is there.
8261
0
  return true;
8262
0
}
8263
8264
}  // namespace
8265
8266
template <class result_type>
8267
ada_warn_unused tl::expected<result_type, errors> parse(
8268
0
    std::string_view input, const result_type* base_url) {
8269
0
  result_type u = ada::parser::parse_url_impl<result_type>(input, base_url);
8270
0
  if (!u.is_valid) {
8271
0
    return tl::unexpected(errors::type_error);
8272
0
  }
8273
0
  return u;
8274
0
}
Unexecuted instantiation: tl::expected<ada::url, ada::errors> ada::parse<ada::url>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url const*)
Unexecuted instantiation: tl::expected<ada::url_aggregator, ada::errors> ada::parse<ada::url_aggregator>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url_aggregator const*)
8275
8276
template ada::result<url> parse<url>(std::string_view input,
8277
                                     const url* base_url = nullptr);
8278
template ada::result<url_aggregator> parse<url_aggregator>(
8279
    std::string_view input, const url_aggregator* base_url = nullptr);
8280
8281
0
std::string href_from_file(std::string_view input) {
8282
  // Match ada::parse / setters: refuse inputs that already exceed the limit.
8283
  // Path percent-encoding can still expand the result, so we also check the
8284
  // final href below.
8285
0
  const uint32_t max_length = ada::get_max_input_length();
8286
0
  if (input.size() > max_length) {
8287
0
    return {};
8288
0
  }
8289
8290
  // This is going to be much faster than constructing a URL.
8291
0
  std::string tmp_buffer;
8292
0
  std::string_view internal_input;
8293
0
  if (unicode::has_tabs_or_newline(input)) {
8294
0
    tmp_buffer = input;
8295
0
    helpers::remove_ascii_tab_or_newline(tmp_buffer);
8296
0
    internal_input = tmp_buffer;
8297
0
  } else {
8298
0
    internal_input = input;
8299
0
  }
8300
0
  std::string path;
8301
0
  if (internal_input.empty()) {
8302
0
    path = "/";
8303
0
  } else if ((internal_input[0] == '/') || (internal_input[0] == '\\')) {
8304
0
    helpers::parse_prepared_path(internal_input.substr(1),
8305
0
                                 ada::scheme::type::FILE, path);
8306
0
  } else {
8307
0
    helpers::parse_prepared_path(internal_input, ada::scheme::type::FILE, path);
8308
0
  }
8309
0
  std::string result = "file://" + path;
8310
0
  if (result.size() > max_length) {
8311
0
    return {};
8312
0
  }
8313
0
  return result;
8314
0
}
8315
8316
0
bool can_parse(std::string_view input, const std::string_view* base_input) {
8317
  // Must match parse().has_value(), including post-normalization max length.
8318
  // Percent-encoding expands a byte by at most 3x, but IDNA expands more: a
8319
  // 3-byte UTF-8 label such as U+337F becomes the 17-byte "xn--6oqv20b1zgzxr",
8320
  // so a dotted host sustains 4.5x. When the input (plus base, if any) fits in
8321
  // max_length/5, the normalized href cannot exceed max_length, so
8322
  // validation-only parsing (store_values=false) is safe.
8323
8324
  // Hot path first: absolute special URLs, no base. Avoid loading max_length
8325
  // until we need it (common absolute-fast true/false cases).
8326
0
  if (base_input == nullptr) {
8327
0
    auto r = try_can_parse_clean_http(input);
8328
0
    if (!r.has_value()) {
8329
0
      r = try_can_parse_absolute_fast(input);
8330
0
    }
8331
0
    if (r.has_value()) {
8332
0
      if (!*r) {
8333
0
        return false;
8334
0
      }
8335
      // size <= max/5 => normalized href cannot exceed max (4.5x expansion).
8336
      // Check this first: default max is ~4GB so almost all URLs return true.
8337
0
      const uint32_t max_length = ada::get_max_input_length();
8338
0
      if (input.size() <= static_cast<size_t>(max_length) / 5) {
8339
0
        return true;
8340
0
      }
8341
0
      if (input.size() > max_length) {
8342
0
        return false;
8343
0
      }
8344
0
      return ada::parser::parse_url_impl<ada::url_aggregator, true>(input,
8345
0
                                                                    nullptr)
8346
0
          .is_valid;
8347
0
    }
8348
0
  }
8349
8350
0
  const uint32_t max_length = ada::get_max_input_length();
8351
0
  if (input.size() > max_length) {
8352
0
    return false;
8353
0
  }
8354
0
  if (base_input != nullptr && base_input->size() > max_length) {
8355
0
    return false;
8356
0
  }
8357
8358
  // Relative resolution combines base + input; bound the sum so 4.5x expansion
8359
  // of either side cannot push the final href past max_length.
8360
0
  const size_t combined =
8361
0
      input.size() + (base_input == nullptr ? 0 : base_input->size());
8362
0
  const bool size_safe = combined <= static_cast<size_t>(max_length) / 5;
8363
8364
0
  if (size_safe) {
8365
    // Validation-only: no buffer build, host still fully checked.
8366
0
    ada::url_aggregator base_agg;
8367
0
    ada::url_aggregator* base_ptr = nullptr;
8368
0
    if (base_input != nullptr) {
8369
0
      base_agg = ada::parser::parse_url_impl<ada::url_aggregator, false>(
8370
0
          *base_input, nullptr);
8371
0
      if (!base_agg.is_valid) {
8372
0
        return false;
8373
0
      }
8374
0
      base_ptr = &base_agg;
8375
0
    }
8376
0
    return ada::parser::parse_url_impl<ada::url_aggregator, false>(input,
8377
0
                                                                   base_ptr)
8378
0
        .is_valid;
8379
0
  }
8380
8381
  // Near the limit: full parse so post-normalization length matches parse().
8382
0
  if (base_input == nullptr) {
8383
0
    return ada::parser::parse_url_impl<ada::url_aggregator, true>(input,
8384
0
                                                                  nullptr)
8385
0
        .is_valid;
8386
0
  }
8387
0
  ada::url_aggregator base_agg =
8388
0
      ada::parser::parse_url_impl<ada::url_aggregator, true>(*base_input,
8389
0
                                                             nullptr);
8390
0
  if (!base_agg.is_valid) {
8391
0
    return false;
8392
0
  }
8393
0
  return ada::parser::parse_url_impl<ada::url_aggregator, true>(input,
8394
0
                                                                &base_agg)
8395
0
      .is_valid;
8396
0
}
8397
8398
0
ada_warn_unused std::string_view to_string(ada::encoding_type type) {
8399
0
  switch (type) {
8400
0
    case ada::encoding_type::UTF8:
8401
0
      return "UTF-8";
8402
0
    case ada::encoding_type::UTF_16LE:
8403
0
      return "UTF-16LE";
8404
0
    case ada::encoding_type::UTF_16BE:
8405
0
      return "UTF-16BE";
8406
0
    default:
8407
0
      unreachable();
8408
0
  }
8409
0
}
8410
8411
}  // namespace ada
8412
/* end file src/implementation.cpp */
8413
/* begin file src/helpers.cpp */
8414
#include <cstdint>
8415
#include <cstring>
8416
#include <sstream>
8417
8418
8419
#if ADA_SSSE3
8420
#include <tmmintrin.h>
8421
#endif
8422
8423
namespace ada::helpers {
8424
8425
template <typename out_iter>
8426
0
void encode_json(std::string_view view, out_iter out) {
8427
  // trivial implementation. could be faster.
8428
0
  const char* hexvalues =
8429
0
      "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f";
8430
0
  for (uint8_t c : view) {
8431
0
    if (c == '\\') {
8432
0
      *out++ = '\\';
8433
0
      *out++ = '\\';
8434
0
    } else if (c == '"') {
8435
0
      *out++ = '\\';
8436
0
      *out++ = '"';
8437
0
    } else if (c <= 0x1f) {
8438
0
      *out++ = '\\';
8439
0
      *out++ = 'u';
8440
0
      *out++ = '0';
8441
0
      *out++ = '0';
8442
0
      *out++ = hexvalues[2 * c];
8443
0
      *out++ = hexvalues[2 * c + 1];
8444
0
    } else {
8445
0
      *out++ = c;
8446
0
    }
8447
0
  }
8448
0
}
8449
8450
0
ada_unused std::string get_state(ada::state s) {
8451
0
  switch (s) {
8452
0
    case ada::state::AUTHORITY:
8453
0
      return "Authority";
8454
0
    case ada::state::SCHEME_START:
8455
0
      return "Scheme Start";
8456
0
    case ada::state::SCHEME:
8457
0
      return "Scheme";
8458
0
    case ada::state::HOST:
8459
0
      return "Host";
8460
0
    case ada::state::NO_SCHEME:
8461
0
      return "No Scheme";
8462
0
    case ada::state::FRAGMENT:
8463
0
      return "Fragment";
8464
0
    case ada::state::RELATIVE_SCHEME:
8465
0
      return "Relative Scheme";
8466
0
    case ada::state::RELATIVE_SLASH:
8467
0
      return "Relative Slash";
8468
0
    case ada::state::FILE:
8469
0
      return "File";
8470
0
    case ada::state::FILE_HOST:
8471
0
      return "File Host";
8472
0
    case ada::state::FILE_SLASH:
8473
0
      return "File Slash";
8474
0
    case ada::state::PATH_OR_AUTHORITY:
8475
0
      return "Path or Authority";
8476
0
    case ada::state::SPECIAL_AUTHORITY_IGNORE_SLASHES:
8477
0
      return "Special Authority Ignore Slashes";
8478
0
    case ada::state::SPECIAL_AUTHORITY_SLASHES:
8479
0
      return "Special Authority Slashes";
8480
0
    case ada::state::SPECIAL_RELATIVE_OR_AUTHORITY:
8481
0
      return "Special Relative or Authority";
8482
0
    case ada::state::QUERY:
8483
0
      return "Query";
8484
0
    case ada::state::PATH:
8485
0
      return "Path";
8486
0
    case ada::state::PATH_START:
8487
0
      return "Path Start";
8488
0
    case ada::state::OPAQUE_PATH:
8489
0
      return "Opaque Path";
8490
0
    case ada::state::PORT:
8491
0
      return "Port";
8492
0
    default:
8493
0
      return "unknown state";
8494
0
  }
8495
0
}
8496
8497
ada_really_inline std::optional<std::string_view> prune_hash(
8498
0
    std::string_view& input) noexcept {
8499
  // compiles down to 20--30 instructions including a class to memchr (C
8500
  // function). this function should be quite fast.
8501
0
  size_t location_of_first = input.find('#');
8502
0
  if (location_of_first == std::string_view::npos) {
8503
0
    return std::nullopt;
8504
0
  }
8505
0
  std::string_view hash = input;
8506
0
  hash.remove_prefix(location_of_first + 1);
8507
0
  input.remove_suffix(input.size() - location_of_first);
8508
0
  return hash;
8509
0
}
8510
8511
0
ada_really_inline bool shorten_path(std::string& path, ada::scheme::type type) {
8512
  // Let path be url's path.
8513
  // If url's scheme is "file", path's size is 1, and path[0] is a normalized
8514
  // Windows drive letter, then return.
8515
0
  if (type == ada::scheme::type::FILE &&
8516
0
      path.find('/', 1) == std::string_view::npos && !path.empty()) {
8517
0
    if (checkers::is_normalized_windows_drive_letter(
8518
0
            helpers::substring(path, 1))) {
8519
0
      return false;
8520
0
    }
8521
0
  }
8522
8523
  // Remove path's last item, if any.
8524
0
  size_t last_delimiter = path.rfind('/');
8525
0
  if (last_delimiter != std::string::npos) {
8526
0
    path.erase(last_delimiter);
8527
0
    return true;
8528
0
  }
8529
8530
0
  return false;
8531
0
}
8532
8533
ada_really_inline bool shorten_path(std::string_view& path,
8534
0
                                    ada::scheme::type type) {
8535
  // Let path be url's path.
8536
  // If url's scheme is "file", path's size is 1, and path[0] is a normalized
8537
  // Windows drive letter, then return.
8538
0
  if (type == ada::scheme::type::FILE &&
8539
0
      path.find('/', 1) == std::string_view::npos && !path.empty()) {
8540
0
    if (checkers::is_normalized_windows_drive_letter(
8541
0
            helpers::substring(path, 1))) {
8542
0
      return false;
8543
0
    }
8544
0
  }
8545
8546
  // Remove path's last item, if any.
8547
0
  if (!path.empty()) {
8548
0
    size_t slash_loc = path.rfind('/');
8549
0
    if (slash_loc != std::string_view::npos) {
8550
0
      path.remove_suffix(path.size() - slash_loc);
8551
0
      return true;
8552
0
    }
8553
0
  }
8554
8555
0
  return false;
8556
0
}
8557
8558
0
ada_really_inline void remove_ascii_tab_or_newline(std::string& input) {
8559
  // if this ever becomes a performance issue, we could use an approach similar
8560
  // to has_tabs_or_newline
8561
0
  std::erase_if(input, ada::unicode::is_ascii_tab_or_newline);
8562
0
}
8563
8564
ada_really_inline constexpr std::string_view substring(std::string_view input,
8565
0
                                                       size_t pos) {
8566
0
  ADA_ASSERT_TRUE(pos <= input.size());
8567
  // The following is safer but unneeded if we have the above line:
8568
  // return pos > input.size() ? std::string_view() : input.substr(pos);
8569
0
  return input.substr(pos);
8570
0
}
8571
8572
0
ada_really_inline void resize(std::string_view& input, size_t pos) noexcept {
8573
0
  ADA_ASSERT_TRUE(pos <= input.size());
8574
0
  input.remove_suffix(input.size() - pos);
8575
0
}
8576
8577
// computes the number of trailing zeroes
8578
// this is a private inline function only defined in this source file.
8579
0
ada_really_inline int trailing_zeroes(uint32_t input_num) noexcept {
8580
#ifdef ADA_REGULAR_VISUAL_STUDIO
8581
  unsigned long ret;
8582
  // Search the mask data from least significant bit (LSB)
8583
  // to the most significant bit (MSB) for a set bit (1).
8584
  _BitScanForward(&ret, input_num);
8585
  return (int)ret;
8586
#else   // ADA_REGULAR_VISUAL_STUDIO
8587
0
  return __builtin_ctzl(input_num);
8588
0
#endif  // ADA_REGULAR_VISUAL_STUDIO
8589
0
}
8590
8591
#if ADA_NEON
8592
// computes the number of trailing zeroes of a 64-bit word
8593
// this is a private inline function only defined in this source file.
8594
ada_really_inline int trailing_zeroes64(uint64_t input_num) noexcept {
8595
#ifdef ADA_REGULAR_VISUAL_STUDIO
8596
  unsigned long ret;
8597
  _BitScanForward64(&ret, input_num);
8598
  return (int)ret;
8599
#else   // ADA_REGULAR_VISUAL_STUDIO
8600
  return __builtin_ctzll(input_num);
8601
#endif  // ADA_REGULAR_VISUAL_STUDIO
8602
}
8603
8604
// Given a NEON register whose lanes are all either 0x00 or 0xFF (i.e., the
8605
// result of a comparison), produce a 64-bit value with four bits set per
8606
// matching input byte, and zero bits elsewhere. Narrowing by four bits per
8607
// 16-bit lane is cheaper than materializing a 16-bit bitmask, and it keeps
8608
// the value in a vector register so that the "any match?" test can be done
8609
// with a floating-point compare against zero, avoiding a transfer to a
8610
// general-purpose register on the common no-match path.
8611
//
8612
// The floating-point compare is only safe because the lanes are 0x00/0xFF:
8613
// each byte of the narrowed value is then one of 0x00, 0x0F, 0xF0 or 0xFF,
8614
// so the result can never be the negative-zero bit pattern (which would
8615
// compare equal to 0.0). Do not use this on arbitrary vectors.
8616
ada_really_inline uint8x8_t to_nibble_mask(uint8x16_t comparison) noexcept {
8617
  return vshrn_n_u16(vreinterpretq_u16_u8(comparison), 4);
8618
}
8619
8620
ada_really_inline bool any_set(uint8x8_t nibble_mask) noexcept {
8621
  return vdupd_lane_f64(vreinterpret_f64_u8(nibble_mask), 0) != 0.0;
8622
}
8623
8624
// index of the first matching byte; only meaningful when any_set is true.
8625
ada_really_inline size_t first_set(uint8x8_t nibble_mask) noexcept {
8626
  return size_t(trailing_zeroes64(
8627
             vget_lane_u64(vreinterpret_u64_u8(nibble_mask), 0))) >>
8628
         2;
8629
}
8630
#endif  // ADA_NEON
8631
8632
// starting at index location, this finds the next location of a character
8633
// :, /, \\, ? or [. If none is found, view.size() is returned.
8634
// For use within get_host_delimiter_location.
8635
#if ADA_SSSE3
8636
ada_really_inline size_t find_next_host_delimiter_special(
8637
    std::string_view view, size_t location) noexcept {
8638
  // first check for short strings in which case we do it naively.
8639
  if (view.size() - location < 16) {  // slow path
8640
    for (size_t i = location; i < view.size(); i++) {
8641
      if (view[i] == ':' || view[i] == '/' || view[i] == '\\' ||
8642
          view[i] == '?' || view[i] == '[') {
8643
        return i;
8644
      }
8645
    }
8646
    return size_t(view.size());
8647
  }
8648
  // fast path for long strings (expected to be common)
8649
  // Using SSSE3's _mm_shuffle_epi8 for table lookup (same approach as NEON)
8650
  size_t i = location;
8651
  const __m128i low_mask =
8652
      _mm_setr_epi8(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8653
                    0x01, 0x04, 0x04, 0x00, 0x00, 0x03);
8654
  const __m128i high_mask =
8655
      _mm_setr_epi8(0x00, 0x00, 0x02, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
8656
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
8657
  const __m128i fmask = _mm_set1_epi8(0xf);
8658
  const __m128i zero = _mm_setzero_si128();
8659
  for (; i + 15 < view.size(); i += 16) {
8660
    __m128i word = _mm_loadu_si128((const __m128i*)(view.data() + i));
8661
    __m128i lowpart = _mm_shuffle_epi8(low_mask, _mm_and_si128(word, fmask));
8662
    __m128i highpart = _mm_shuffle_epi8(
8663
        high_mask, _mm_and_si128(_mm_srli_epi16(word, 4), fmask));
8664
    __m128i classify = _mm_and_si128(lowpart, highpart);
8665
    __m128i is_zero = _mm_cmpeq_epi8(classify, zero);
8666
    // _mm_movemask_epi8 returns a 16-bit mask in bits 0-15, with bits 16-31
8667
    // zero. After NOT (~), bits 16-31 become 1. We must mask to 16 bits to
8668
    // avoid false positives.
8669
    int mask = ~_mm_movemask_epi8(is_zero) & 0xFFFF;
8670
    if (mask != 0) {
8671
      return i + trailing_zeroes(static_cast<uint32_t>(mask));
8672
    }
8673
  }
8674
  if (i < view.size()) {
8675
    __m128i word =
8676
        _mm_loadu_si128((const __m128i*)(view.data() + view.length() - 16));
8677
    __m128i lowpart = _mm_shuffle_epi8(low_mask, _mm_and_si128(word, fmask));
8678
    __m128i highpart = _mm_shuffle_epi8(
8679
        high_mask, _mm_and_si128(_mm_srli_epi16(word, 4), fmask));
8680
    __m128i classify = _mm_and_si128(lowpart, highpart);
8681
    __m128i is_zero = _mm_cmpeq_epi8(classify, zero);
8682
    // _mm_movemask_epi8 returns a 16-bit mask in bits 0-15, with bits 16-31
8683
    // zero. After NOT (~), bits 16-31 become 1. We must mask to 16 bits to
8684
    // avoid false positives.
8685
    int mask = ~_mm_movemask_epi8(is_zero) & 0xFFFF;
8686
    if (mask != 0) {
8687
      return view.length() - 16 + trailing_zeroes(static_cast<uint32_t>(mask));
8688
    }
8689
  }
8690
  return size_t(view.size());
8691
}
8692
#elif ADA_NEON
8693
// The ada_make_uint8x16_t macro is necessary because Visual Studio does not
8694
// support direct initialization of uint8x16_t. See
8695
// https://developercommunity.visualstudio.com/t/error-C2078:-too-many-initializers-whe/402911?q=backend+neon
8696
#ifndef ada_make_uint8x16_t
8697
#define ada_make_uint8x16_t(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, \
8698
                            x13, x14, x15, x16)                                \
8699
  ([=]() {                                                                     \
8700
    static uint8_t array[16] = {x1, x2,  x3,  x4,  x5,  x6,  x7,  x8,          \
8701
                                x9, x10, x11, x12, x13, x14, x15, x16};        \
8702
    return vld1q_u8(array);                                                    \
8703
  }())
8704
#endif
8705
8706
ada_really_inline size_t find_next_host_delimiter_special(
8707
    std::string_view view, size_t location) noexcept {
8708
  // first check for short strings in which case we do it naively.
8709
  if (view.size() - location < 16) {  // slow path
8710
    for (size_t i = location; i < view.size(); i++) {
8711
      if (view[i] == ':' || view[i] == '/' || view[i] == '\\' ||
8712
          view[i] == '?' || view[i] == '[') {
8713
        return i;
8714
      }
8715
    }
8716
    return size_t(view.size());
8717
  }
8718
  // fast path for long strings (expected to be common)
8719
  size_t i = location;
8720
  uint8x16_t low_mask =
8721
      ada_make_uint8x16_t(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8722
                          0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x03);
8723
  uint8x16_t high_mask =
8724
      ada_make_uint8x16_t(0x00, 0x00, 0x02, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00,
8725
                          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
8726
  uint8x16_t fmask = vmovq_n_u8(0xf);
8727
  for (; i + 15 < view.size(); i += 16) {
8728
    uint8x16_t word = vld1q_u8((const uint8_t*)view.data() + i);
8729
    uint8x16_t lowpart = vqtbl1q_u8(low_mask, vandq_u8(word, fmask));
8730
    uint8x16_t highpart = vqtbl1q_u8(high_mask, vshrq_n_u8(word, 4));
8731
    // vtstq_u8 gives us 0xFF where (lowpart & highpart) is non-zero and 0x00
8732
    // elsewhere: unlike the plain AND, that is a proper comparison mask, which
8733
    // is what to_nibble_mask requires.
8734
    uint8x8_t matches = to_nibble_mask(vtstq_u8(lowpart, highpart));
8735
    if (any_set(matches)) {
8736
      return i + first_set(matches);
8737
    }
8738
  }
8739
8740
  if (i < view.size()) {
8741
    uint8x16_t word =
8742
        vld1q_u8((const uint8_t*)view.data() + view.length() - 16);
8743
    uint8x16_t lowpart = vqtbl1q_u8(low_mask, vandq_u8(word, fmask));
8744
    uint8x16_t highpart = vqtbl1q_u8(high_mask, vshrq_n_u8(word, 4));
8745
    uint8x8_t matches = to_nibble_mask(vtstq_u8(lowpart, highpart));
8746
    if (any_set(matches)) {
8747
      return view.length() - 16 + first_set(matches);
8748
    }
8749
  }
8750
  return size_t(view.size());
8751
}
8752
#elif ADA_SSE2
8753
ada_really_inline size_t find_next_host_delimiter_special(
8754
0
    std::string_view view, size_t location) noexcept {
8755
  // first check for short strings in which case we do it naively.
8756
0
  if (view.size() - location < 16) {  // slow path
8757
0
    for (size_t i = location; i < view.size(); i++) {
8758
0
      if (view[i] == ':' || view[i] == '/' || view[i] == '\\' ||
8759
0
          view[i] == '?' || view[i] == '[') {
8760
0
        return i;
8761
0
      }
8762
0
    }
8763
0
    return size_t(view.size());
8764
0
  }
8765
  // fast path for long strings (expected to be common)
8766
0
  size_t i = location;
8767
0
  const __m128i mask1 = _mm_set1_epi8(':');
8768
0
  const __m128i mask2 = _mm_set1_epi8('/');
8769
0
  const __m128i mask3 = _mm_set1_epi8('\\');
8770
0
  const __m128i mask4 = _mm_set1_epi8('?');
8771
0
  const __m128i mask5 = _mm_set1_epi8('[');
8772
8773
0
  for (; i + 15 < view.size(); i += 16) {
8774
0
    __m128i word = _mm_loadu_si128((const __m128i*)(view.data() + i));
8775
0
    __m128i m1 = _mm_cmpeq_epi8(word, mask1);
8776
0
    __m128i m2 = _mm_cmpeq_epi8(word, mask2);
8777
0
    __m128i m3 = _mm_cmpeq_epi8(word, mask3);
8778
0
    __m128i m4 = _mm_cmpeq_epi8(word, mask4);
8779
0
    __m128i m5 = _mm_cmpeq_epi8(word, mask5);
8780
0
    __m128i m = _mm_or_si128(
8781
0
        _mm_or_si128(_mm_or_si128(m1, m2), _mm_or_si128(m3, m4)), m5);
8782
0
    int mask = _mm_movemask_epi8(m);
8783
0
    if (mask != 0) {
8784
0
      return i + trailing_zeroes(mask);
8785
0
    }
8786
0
  }
8787
0
  if (i < view.size()) {
8788
0
    __m128i word =
8789
0
        _mm_loadu_si128((const __m128i*)(view.data() + view.length() - 16));
8790
0
    __m128i m1 = _mm_cmpeq_epi8(word, mask1);
8791
0
    __m128i m2 = _mm_cmpeq_epi8(word, mask2);
8792
0
    __m128i m3 = _mm_cmpeq_epi8(word, mask3);
8793
0
    __m128i m4 = _mm_cmpeq_epi8(word, mask4);
8794
0
    __m128i m5 = _mm_cmpeq_epi8(word, mask5);
8795
0
    __m128i m = _mm_or_si128(
8796
0
        _mm_or_si128(_mm_or_si128(m1, m2), _mm_or_si128(m3, m4)), m5);
8797
0
    int mask = _mm_movemask_epi8(m);
8798
0
    if (mask != 0) {
8799
0
      return view.length() - 16 + trailing_zeroes(mask);
8800
0
    }
8801
0
  }
8802
0
  return size_t(view.length());
8803
0
}
8804
#elif ADA_LSX
8805
ada_really_inline size_t find_next_host_delimiter_special(
8806
    std::string_view view, size_t location) noexcept {
8807
  // first check for short strings in which case we do it naively.
8808
  if (view.size() - location < 16) {  // slow path
8809
    for (size_t i = location; i < view.size(); i++) {
8810
      if (view[i] == ':' || view[i] == '/' || view[i] == '\\' ||
8811
          view[i] == '?' || view[i] == '[') {
8812
        return i;
8813
      }
8814
    }
8815
    return size_t(view.size());
8816
  }
8817
  // fast path for long strings (expected to be common)
8818
  size_t i = location;
8819
  const __m128i mask1 = __lsx_vrepli_b(':');
8820
  const __m128i mask2 = __lsx_vrepli_b('/');
8821
  const __m128i mask3 = __lsx_vrepli_b('\\');
8822
  const __m128i mask4 = __lsx_vrepli_b('?');
8823
  const __m128i mask5 = __lsx_vrepli_b('[');
8824
8825
  for (; i + 15 < view.size(); i += 16) {
8826
    __m128i word = __lsx_vld((const __m128i*)(view.data() + i), 0);
8827
    __m128i m1 = __lsx_vseq_b(word, mask1);
8828
    __m128i m2 = __lsx_vseq_b(word, mask2);
8829
    __m128i m3 = __lsx_vseq_b(word, mask3);
8830
    __m128i m4 = __lsx_vseq_b(word, mask4);
8831
    __m128i m5 = __lsx_vseq_b(word, mask5);
8832
    __m128i m =
8833
        __lsx_vor_v(__lsx_vor_v(__lsx_vor_v(m1, m2), __lsx_vor_v(m3, m4)), m5);
8834
    int mask = __lsx_vpickve2gr_hu(__lsx_vmsknz_b(m), 0);
8835
    if (mask != 0) {
8836
      return i + trailing_zeroes(mask);
8837
    }
8838
  }
8839
  if (i < view.size()) {
8840
    __m128i word =
8841
        __lsx_vld((const __m128i*)(view.data() + view.length() - 16), 0);
8842
    __m128i m1 = __lsx_vseq_b(word, mask1);
8843
    __m128i m2 = __lsx_vseq_b(word, mask2);
8844
    __m128i m3 = __lsx_vseq_b(word, mask3);
8845
    __m128i m4 = __lsx_vseq_b(word, mask4);
8846
    __m128i m5 = __lsx_vseq_b(word, mask5);
8847
    __m128i m =
8848
        __lsx_vor_v(__lsx_vor_v(__lsx_vor_v(m1, m2), __lsx_vor_v(m3, m4)), m5);
8849
    int mask = __lsx_vpickve2gr_hu(__lsx_vmsknz_b(m), 0);
8850
    if (mask != 0) {
8851
      return view.length() - 16 + trailing_zeroes(mask);
8852
    }
8853
  }
8854
  return size_t(view.length());
8855
}
8856
#elif ADA_RVV
8857
ada_really_inline size_t find_next_host_delimiter_special(
8858
    std::string_view view, size_t location) noexcept {
8859
  // The LUT approach was a bit slower on the SpacemiT X60, but I could see it
8860
  // being faster on future hardware.
8861
#if 0
8862
  // LUT generated using: s=":/\\?["; list(zip([((ord(c)>>2)&0xF)for c in s],s))
8863
  static const uint8_t tbl[16] = {
8864
    0xF, 0, 0, 0, 0, 0, '[', '\\', 0, 0, 0, '/', 0, 0, ':', '?'
8865
  };
8866
  vuint8m1_t vtbl = __riscv_vle8_v_u8m1(tbl, 16);
8867
#endif
8868
  uint8_t* src = (uint8_t*)view.data() + location;
8869
  for (size_t vl, n = view.size() - location; n > 0;
8870
       n -= vl, src += vl, location += vl) {
8871
    vl = __riscv_vsetvl_e8m1(n);
8872
    vuint8m1_t v = __riscv_vle8_v_u8m1(src, vl);
8873
#if 0
8874
    vuint8m1_t vidx = __riscv_vand(__riscv_vsrl(v, 2, vl), 0xF, vl);
8875
    vuint8m1_t vlut = __riscv_vrgather(vtbl, vidx, vl);
8876
    vbool8_t m = __riscv_vmseq(v, vlut, vl);
8877
#else
8878
    vbool8_t m1 = __riscv_vmseq(v, ':', vl);
8879
    vbool8_t m2 = __riscv_vmseq(v, '/', vl);
8880
    vbool8_t m3 = __riscv_vmseq(v, '?', vl);
8881
    vbool8_t m4 = __riscv_vmseq(v, '[', vl);
8882
    vbool8_t m5 = __riscv_vmseq(v, '\\', vl);
8883
    vbool8_t m = __riscv_vmor(
8884
        __riscv_vmor(__riscv_vmor(m1, m2, vl), __riscv_vmor(m3, m4, vl), vl),
8885
        m5, vl);
8886
#endif
8887
    long idx = __riscv_vfirst(m, vl);
8888
    if (idx >= 0) return location + idx;
8889
  }
8890
  return size_t(view.size());
8891
}
8892
#else
8893
// : / [ \\ ?
8894
static constexpr std::array<uint8_t, 256> special_host_delimiters =
8895
    []() consteval {
8896
      std::array<uint8_t, 256> result{};
8897
      for (int i : {':', '/', '[', '\\', '?'}) {
8898
        result[i] = 1;
8899
      }
8900
      return result;
8901
    }();
8902
// credit: @the-moisrex recommended a table-based approach
8903
ada_really_inline size_t find_next_host_delimiter_special(
8904
    std::string_view view, size_t location) noexcept {
8905
  auto const str = view.substr(location);
8906
  for (auto pos = str.begin(); pos != str.end(); ++pos) {
8907
    if (special_host_delimiters[(uint8_t)*pos]) {
8908
      return pos - str.begin() + location;
8909
    }
8910
  }
8911
  return size_t(view.size());
8912
}
8913
#endif
8914
8915
// starting at index location, this finds the next location of a character
8916
// :, /, ? or [. If none is found, view.size() is returned.
8917
// For use within get_host_delimiter_location.
8918
#if ADA_SSSE3
8919
ada_really_inline size_t find_next_host_delimiter(std::string_view view,
8920
                                                  size_t location) noexcept {
8921
  // first check for short strings in which case we do it naively.
8922
  if (view.size() - location < 16) {  // slow path
8923
    for (size_t i = location; i < view.size(); i++) {
8924
      if (view[i] == ':' || view[i] == '/' || view[i] == '?' ||
8925
          view[i] == '[') {
8926
        return i;
8927
      }
8928
    }
8929
    return size_t(view.size());
8930
  }
8931
  // fast path for long strings (expected to be common)
8932
  size_t i = location;
8933
  // Lookup tables for bit classification:
8934
  // ':' (0x3A): low[0xA]=0x01, high[0x3]=0x01 -> match
8935
  // '/' (0x2F): low[0xF]=0x02, high[0x2]=0x02 -> match
8936
  // '?' (0x3F): low[0xF]=0x01, high[0x3]=0x01 -> match
8937
  // '[' (0x5B): low[0xB]=0x04, high[0x5]=0x04 -> match
8938
  const __m128i low_mask =
8939
      _mm_setr_epi8(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8940
                    0x01, 0x04, 0x00, 0x00, 0x00, 0x03);
8941
  const __m128i high_mask =
8942
      _mm_setr_epi8(0x00, 0x00, 0x02, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
8943
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
8944
  const __m128i fmask = _mm_set1_epi8(0xf);
8945
  const __m128i zero = _mm_setzero_si128();
8946
8947
  for (; i + 15 < view.size(); i += 16) {
8948
    __m128i word = _mm_loadu_si128((const __m128i*)(view.data() + i));
8949
    __m128i lowpart = _mm_shuffle_epi8(low_mask, _mm_and_si128(word, fmask));
8950
    __m128i highpart = _mm_shuffle_epi8(
8951
        high_mask, _mm_and_si128(_mm_srli_epi16(word, 4), fmask));
8952
    __m128i classify = _mm_and_si128(lowpart, highpart);
8953
    __m128i is_zero = _mm_cmpeq_epi8(classify, zero);
8954
    // _mm_movemask_epi8 returns a 16-bit mask in bits 0-15, with bits 16-31
8955
    // zero. After NOT (~), bits 16-31 become 1. We must mask to 16 bits to
8956
    // avoid false positives.
8957
    int mask = ~_mm_movemask_epi8(is_zero) & 0xFFFF;
8958
    if (mask != 0) {
8959
      return i + trailing_zeroes(static_cast<uint32_t>(mask));
8960
    }
8961
  }
8962
8963
  if (i < view.size()) {
8964
    __m128i word =
8965
        _mm_loadu_si128((const __m128i*)(view.data() + view.length() - 16));
8966
    __m128i lowpart = _mm_shuffle_epi8(low_mask, _mm_and_si128(word, fmask));
8967
    __m128i highpart = _mm_shuffle_epi8(
8968
        high_mask, _mm_and_si128(_mm_srli_epi16(word, 4), fmask));
8969
    __m128i classify = _mm_and_si128(lowpart, highpart);
8970
    __m128i is_zero = _mm_cmpeq_epi8(classify, zero);
8971
    // _mm_movemask_epi8 returns a 16-bit mask in bits 0-15, with bits 16-31
8972
    // zero. After NOT (~), bits 16-31 become 1. We must mask to 16 bits to
8973
    // avoid false positives.
8974
    int mask = ~_mm_movemask_epi8(is_zero) & 0xFFFF;
8975
    if (mask != 0) {
8976
      return view.length() - 16 + trailing_zeroes(static_cast<uint32_t>(mask));
8977
    }
8978
  }
8979
  return size_t(view.size());
8980
}
8981
#elif ADA_NEON
8982
ada_really_inline size_t find_next_host_delimiter(std::string_view view,
8983
                                                  size_t location) noexcept {
8984
  // first check for short strings in which case we do it naively.
8985
  if (view.size() - location < 16) {  // slow path
8986
    for (size_t i = location; i < view.size(); i++) {
8987
      if (view[i] == ':' || view[i] == '/' || view[i] == '?' ||
8988
          view[i] == '[') {
8989
        return i;
8990
      }
8991
    }
8992
    return size_t(view.size());
8993
  }
8994
  // fast path for long strings (expected to be common)
8995
  size_t i = location;
8996
  uint8x16_t low_mask =
8997
      ada_make_uint8x16_t(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8998
                          0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x03);
8999
  uint8x16_t high_mask =
9000
      ada_make_uint8x16_t(0x00, 0x00, 0x02, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00,
9001
                          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
9002
  uint8x16_t fmask = vmovq_n_u8(0xf);
9003
  for (; i + 15 < view.size(); i += 16) {
9004
    uint8x16_t word = vld1q_u8((const uint8_t*)view.data() + i);
9005
    uint8x16_t lowpart = vqtbl1q_u8(low_mask, vandq_u8(word, fmask));
9006
    uint8x16_t highpart = vqtbl1q_u8(high_mask, vshrq_n_u8(word, 4));
9007
    // vtstq_u8 gives us 0xFF where (lowpart & highpart) is non-zero and 0x00
9008
    // elsewhere: unlike the plain AND, that is a proper comparison mask, which
9009
    // is what to_nibble_mask requires.
9010
    uint8x8_t matches = to_nibble_mask(vtstq_u8(lowpart, highpart));
9011
    if (any_set(matches)) {
9012
      return i + first_set(matches);
9013
    }
9014
  }
9015
9016
  if (i < view.size()) {
9017
    uint8x16_t word =
9018
        vld1q_u8((const uint8_t*)view.data() + view.length() - 16);
9019
    uint8x16_t lowpart = vqtbl1q_u8(low_mask, vandq_u8(word, fmask));
9020
    uint8x16_t highpart = vqtbl1q_u8(high_mask, vshrq_n_u8(word, 4));
9021
    uint8x8_t matches = to_nibble_mask(vtstq_u8(lowpart, highpart));
9022
    if (any_set(matches)) {
9023
      return view.length() - 16 + first_set(matches);
9024
    }
9025
  }
9026
  return size_t(view.size());
9027
}
9028
#elif ADA_SSE2
9029
ada_really_inline size_t find_next_host_delimiter(std::string_view view,
9030
0
                                                  size_t location) noexcept {
9031
  // first check for short strings in which case we do it naively.
9032
0
  if (view.size() - location < 16) {  // slow path
9033
0
    for (size_t i = location; i < view.size(); i++) {
9034
0
      if (view[i] == ':' || view[i] == '/' || view[i] == '?' ||
9035
0
          view[i] == '[') {
9036
0
        return i;
9037
0
      }
9038
0
    }
9039
0
    return size_t(view.size());
9040
0
  }
9041
  // fast path for long strings (expected to be common)
9042
0
  size_t i = location;
9043
0
  const __m128i mask1 = _mm_set1_epi8(':');
9044
0
  const __m128i mask2 = _mm_set1_epi8('/');
9045
0
  const __m128i mask4 = _mm_set1_epi8('?');
9046
0
  const __m128i mask5 = _mm_set1_epi8('[');
9047
9048
0
  for (; i + 15 < view.size(); i += 16) {
9049
0
    __m128i word = _mm_loadu_si128((const __m128i*)(view.data() + i));
9050
0
    __m128i m1 = _mm_cmpeq_epi8(word, mask1);
9051
0
    __m128i m2 = _mm_cmpeq_epi8(word, mask2);
9052
0
    __m128i m4 = _mm_cmpeq_epi8(word, mask4);
9053
0
    __m128i m5 = _mm_cmpeq_epi8(word, mask5);
9054
0
    __m128i m = _mm_or_si128(_mm_or_si128(m1, m2), _mm_or_si128(m4, m5));
9055
0
    int mask = _mm_movemask_epi8(m);
9056
0
    if (mask != 0) {
9057
0
      return i + trailing_zeroes(mask);
9058
0
    }
9059
0
  }
9060
0
  if (i < view.size()) {
9061
0
    __m128i word =
9062
0
        _mm_loadu_si128((const __m128i*)(view.data() + view.length() - 16));
9063
0
    __m128i m1 = _mm_cmpeq_epi8(word, mask1);
9064
0
    __m128i m2 = _mm_cmpeq_epi8(word, mask2);
9065
0
    __m128i m4 = _mm_cmpeq_epi8(word, mask4);
9066
0
    __m128i m5 = _mm_cmpeq_epi8(word, mask5);
9067
0
    __m128i m = _mm_or_si128(_mm_or_si128(m1, m2), _mm_or_si128(m4, m5));
9068
0
    int mask = _mm_movemask_epi8(m);
9069
0
    if (mask != 0) {
9070
0
      return view.length() - 16 + trailing_zeroes(mask);
9071
0
    }
9072
0
  }
9073
0
  return size_t(view.length());
9074
0
}
9075
#elif ADA_LSX
9076
ada_really_inline size_t find_next_host_delimiter(std::string_view view,
9077
                                                  size_t location) noexcept {
9078
  // first check for short strings in which case we do it naively.
9079
  if (view.size() - location < 16) {  // slow path
9080
    for (size_t i = location; i < view.size(); i++) {
9081
      if (view[i] == ':' || view[i] == '/' || view[i] == '?' ||
9082
          view[i] == '[') {
9083
        return i;
9084
      }
9085
    }
9086
    return size_t(view.size());
9087
  }
9088
  // fast path for long strings (expected to be common)
9089
  size_t i = location;
9090
  const __m128i mask1 = __lsx_vrepli_b(':');
9091
  const __m128i mask2 = __lsx_vrepli_b('/');
9092
  const __m128i mask4 = __lsx_vrepli_b('?');
9093
  const __m128i mask5 = __lsx_vrepli_b('[');
9094
9095
  for (; i + 15 < view.size(); i += 16) {
9096
    __m128i word = __lsx_vld((const __m128i*)(view.data() + i), 0);
9097
    __m128i m1 = __lsx_vseq_b(word, mask1);
9098
    __m128i m2 = __lsx_vseq_b(word, mask2);
9099
    __m128i m4 = __lsx_vseq_b(word, mask4);
9100
    __m128i m5 = __lsx_vseq_b(word, mask5);
9101
    __m128i m = __lsx_vor_v(__lsx_vor_v(m1, m2), __lsx_vor_v(m4, m5));
9102
    int mask = __lsx_vpickve2gr_hu(__lsx_vmsknz_b(m), 0);
9103
    if (mask != 0) {
9104
      return i + trailing_zeroes(mask);
9105
    }
9106
  }
9107
  if (i < view.size()) {
9108
    __m128i word =
9109
        __lsx_vld((const __m128i*)(view.data() + view.length() - 16), 0);
9110
    __m128i m1 = __lsx_vseq_b(word, mask1);
9111
    __m128i m2 = __lsx_vseq_b(word, mask2);
9112
    __m128i m4 = __lsx_vseq_b(word, mask4);
9113
    __m128i m5 = __lsx_vseq_b(word, mask5);
9114
    __m128i m = __lsx_vor_v(__lsx_vor_v(m1, m2), __lsx_vor_v(m4, m5));
9115
    int mask = __lsx_vpickve2gr_hu(__lsx_vmsknz_b(m), 0);
9116
    if (mask != 0) {
9117
      return view.length() - 16 + trailing_zeroes(mask);
9118
    }
9119
  }
9120
  return size_t(view.length());
9121
}
9122
#elif ADA_RVV
9123
ada_really_inline size_t find_next_host_delimiter(std::string_view view,
9124
                                                  size_t location) noexcept {
9125
  uint8_t* src = (uint8_t*)view.data() + location;
9126
  for (size_t vl, n = view.size() - location; n > 0;
9127
       n -= vl, src += vl, location += vl) {
9128
    vl = __riscv_vsetvl_e8m1(n);
9129
    vuint8m1_t v = __riscv_vle8_v_u8m1(src, vl);
9130
    vbool8_t m1 = __riscv_vmseq(v, ':', vl);
9131
    vbool8_t m2 = __riscv_vmseq(v, '/', vl);
9132
    vbool8_t m3 = __riscv_vmseq(v, '?', vl);
9133
    vbool8_t m4 = __riscv_vmseq(v, '[', vl);
9134
    vbool8_t m =
9135
        __riscv_vmor(__riscv_vmor(m1, m2, vl), __riscv_vmor(m3, m4, vl), vl);
9136
    long idx = __riscv_vfirst(m, vl);
9137
    if (idx >= 0) return location + idx;
9138
  }
9139
  return size_t(view.size());
9140
}
9141
#else
9142
// : / [ ?
9143
static constexpr std::array<uint8_t, 256> host_delimiters = []() consteval {
9144
  std::array<uint8_t, 256> result{};
9145
  for (int i : {':', '/', '?', '['}) {
9146
    result[i] = 1;
9147
  }
9148
  return result;
9149
}();
9150
// credit: @the-moisrex recommended a table-based approach
9151
ada_really_inline size_t find_next_host_delimiter(std::string_view view,
9152
                                                  size_t location) noexcept {
9153
  auto const str = view.substr(location);
9154
  for (auto pos = str.begin(); pos != str.end(); ++pos) {
9155
    if (host_delimiters[(uint8_t)*pos]) {
9156
      return pos - str.begin() + location;
9157
    }
9158
  }
9159
  return size_t(view.size());
9160
}
9161
#endif
9162
9163
ada_really_inline std::pair<size_t, bool> get_host_delimiter_location(
9164
0
    const bool is_special, std::string_view& view) noexcept {
9165
  /**
9166
   * The spec at https://url.spec.whatwg.org/#hostname-state expects us to
9167
   * compute a variable called insideBrackets but this variable is only used
9168
   * once, to check whether a ':' character was found outside brackets. Exact
9169
   * text: "Otherwise, if c is U+003A (:) and insideBrackets is false, then:".
9170
   * It is conceptually simpler and arguably more efficient to just return a
9171
   * Boolean indicating whether ':' was found outside brackets.
9172
   */
9173
0
  const size_t view_size = view.size();
9174
0
  size_t location = 0;
9175
0
  bool found_colon = false;
9176
  /**
9177
   * Performance analysis:
9178
   *
9179
   * We are basically seeking the end of the hostname which can be indicated
9180
   * by the end of the view, or by one of the characters ':', '/', '?', '\\'
9181
   * (where '\\' is only applicable for special URLs). However, these must
9182
   * appear outside a bracket range. E.g., if you have [something?]fd: then the
9183
   * '?' does not count.
9184
   *
9185
   * So we can skip ahead to the next delimiter, as long as we include '[' in
9186
   * the set of delimiters, and that we handle it first.
9187
   *
9188
   * So the trick is to have a fast function that locates the next delimiter.
9189
   * Unless we find '[', then it only needs to be called once! Ideally, such a
9190
   * function would be provided by the C++ standard library, but it seems that
9191
   * find_first_of is not very fast, so we are forced to roll our own.
9192
   *
9193
   * We do not break into two loops for speed, but for clarity.
9194
   */
9195
0
  if (is_special) {
9196
    // We move to the next delimiter.
9197
0
    location = find_next_host_delimiter_special(view, location);
9198
    // Unless we find '[' then we are going only going to have to call
9199
    // find_next_host_delimiter_special once.
9200
0
    for (; location < view_size;
9201
0
         location = find_next_host_delimiter_special(view, location)) {
9202
0
      if (view[location] == '[') {
9203
0
        location = view.find(']', location);
9204
0
        if (location == std::string_view::npos) {
9205
          // performance: view.find might get translated to a memchr, which
9206
          // has no notion of std::string_view::npos, so the code does not
9207
          // reflect the assembly.
9208
0
          location = view_size;
9209
0
          break;
9210
0
        }
9211
0
      } else {
9212
0
        found_colon = view[location] == ':';
9213
0
        break;
9214
0
      }
9215
0
    }
9216
0
  } else {
9217
    // We move to the next delimiter.
9218
0
    location = find_next_host_delimiter(view, location);
9219
    // Unless we find '[' then we are going only going to have to call
9220
    // find_next_host_delimiter_special once.
9221
0
    for (; location < view_size;
9222
0
         location = find_next_host_delimiter(view, location)) {
9223
0
      if (view[location] == '[') {
9224
0
        location = view.find(']', location);
9225
0
        if (location == std::string_view::npos) {
9226
          // performance: view.find might get translated to a memchr, which
9227
          // has no notion of std::string_view::npos, so the code does not
9228
          // reflect the assembly.
9229
0
          location = view_size;
9230
0
          break;
9231
0
        }
9232
0
      } else {
9233
0
        found_colon = view[location] == ':';
9234
0
        break;
9235
0
      }
9236
0
    }
9237
0
  }
9238
  // performance: remove_suffix may translate into a single instruction.
9239
0
  view.remove_suffix(view_size - location);
9240
0
  return {location, found_colon};
9241
0
}
9242
9243
0
void trim_c0_whitespace(std::string_view& input) noexcept {
9244
0
  while (!input.empty() &&
9245
0
         ada::unicode::is_c0_control_or_space(input.front())) {
9246
0
    input.remove_prefix(1);
9247
0
  }
9248
0
  while (!input.empty() && ada::unicode::is_c0_control_or_space(input.back())) {
9249
0
    input.remove_suffix(1);
9250
0
  }
9251
0
}
9252
9253
ada_really_inline void parse_prepared_path(std::string_view input,
9254
                                           ada::scheme::type type,
9255
0
                                           std::string& path) {
9256
0
  ada_log("parse_prepared_path ", input);
9257
0
  uint8_t accumulator = checkers::path_signature(input);
9258
  // Let us first detect a trivial case.
9259
  // If it is special, we check that we have no dot, no %,  no \ and no
9260
  // character needing percent encoding. Otherwise, we check that we have no %,
9261
  // no dot, and no character needing percent encoding.
9262
0
  constexpr uint8_t need_encoding = 1;
9263
0
  constexpr uint8_t backslash_char = 2;
9264
0
  constexpr uint8_t dot_char = 4;
9265
0
  constexpr uint8_t percent_char = 8;
9266
0
  bool special = type != ada::scheme::NOT_SPECIAL;
9267
0
  bool may_need_slow_file_handling = (type == ada::scheme::type::FILE &&
9268
0
                                      checkers::is_windows_drive_letter(input));
9269
0
  bool trivial_path =
9270
0
      (special ? (accumulator == 0)
9271
0
               : ((accumulator & (need_encoding | dot_char | percent_char)) ==
9272
0
                  0)) &&
9273
0
      (!may_need_slow_file_handling);
9274
0
  if (accumulator == dot_char && !may_need_slow_file_handling) {
9275
    // '4' means that we have at least one dot, but nothing that requires
9276
    // percent encoding or decoding. The only part that is not trivial is
9277
    // that we may have single dots and double dots path segments.
9278
    // If we have such segments, then we either have a path that begins
9279
    // with '.' (easy to check), or we have the sequence './'.
9280
    // Note: input cannot be empty, it must at least contain one character ('.')
9281
    // Note: we know that '\' is not present.
9282
0
    if (input[0] != '.') {
9283
0
      size_t slashdot = 0;
9284
0
      bool dot_is_file = true;
9285
0
      for (;;) {
9286
0
        slashdot = input.find("/.", slashdot);
9287
0
        if (slashdot == std::string_view::npos) {  // common case
9288
0
          break;
9289
0
        } else {  // uncommon
9290
          // only three cases matter: /./, /.. or a final /
9291
0
          slashdot += 2;
9292
0
          dot_is_file &= !(slashdot == input.size() || input[slashdot] == '.' ||
9293
0
                           input[slashdot] == '/');
9294
0
        }
9295
0
      }
9296
0
      trivial_path = dot_is_file;
9297
0
    }
9298
0
  }
9299
0
  if (trivial_path) {
9300
0
    ada_log("parse_path trivial");
9301
0
    path += '/';
9302
0
    path += input;
9303
0
    return;
9304
0
  }
9305
  // We are going to need to look a bit at the path, but let us see if we can
9306
  // ignore percent encoding *and* backslashes *and* percent characters.
9307
  // Except for the trivial case, this is likely to capture 99% of paths out
9308
  // there.
9309
0
  bool fast_path =
9310
0
      (special &&
9311
0
       (accumulator & (need_encoding | backslash_char | percent_char)) == 0) &&
9312
0
      (type != ada::scheme::type::FILE);
9313
0
  if (fast_path) {
9314
0
    ada_log("parse_prepared_path fast");
9315
    // Here we don't need to worry about \ or percent encoding.
9316
    // We also do not have a file protocol. We might have dots, however,
9317
    // but dots must as appear as '.', and they cannot be encoded because
9318
    // the symbol '%' is not present.
9319
0
    size_t previous_location = 0;  // We start at 0.
9320
0
    do {
9321
0
      size_t new_location = input.find('/', previous_location);
9322
      // std::string_view path_view = input;
9323
      //  We process the last segment separately:
9324
0
      if (new_location == std::string_view::npos) {
9325
0
        std::string_view path_view = input.substr(previous_location);
9326
0
        if (path_view == "..") {  // The path ends with ..
9327
          // e.g., if you receive ".." with an empty path, you go to "/".
9328
0
          if (path.empty()) {
9329
0
            path = '/';
9330
0
            return;
9331
0
          }
9332
          // Fast case where we have nothing to do:
9333
0
          if (path.back() == '/') {
9334
0
            return;
9335
0
          }
9336
          // If you have the path "/joe/myfriend",
9337
          // then you delete 'myfriend'.
9338
0
          path.resize(path.rfind('/') + 1);
9339
0
          return;
9340
0
        }
9341
0
        path += '/';
9342
0
        if (path_view != ".") {
9343
0
          path.append(path_view);
9344
0
        }
9345
0
        return;
9346
0
      } else {
9347
        // This is a non-final segment.
9348
0
        std::string_view path_view =
9349
0
            input.substr(previous_location, new_location - previous_location);
9350
0
        previous_location = new_location + 1;
9351
0
        if (path_view == "..") {
9352
0
          size_t last_delimiter = path.rfind('/');
9353
0
          if (last_delimiter != std::string::npos) {
9354
0
            path.erase(last_delimiter);
9355
0
          }
9356
0
        } else if (path_view != ".") {
9357
0
          path += '/';
9358
0
          path.append(path_view);
9359
0
        }
9360
0
      }
9361
0
    } while (true);
9362
0
  } else {
9363
0
    ada_log("parse_path slow");
9364
    // we have reached the general case
9365
0
    bool needs_percent_encoding = (accumulator & 1);
9366
0
    std::string path_buffer_tmp;
9367
0
    do {
9368
0
      size_t location = (special && (accumulator & 2))
9369
0
                            ? input.find_first_of("/\\")
9370
0
                            : input.find('/');
9371
0
      std::string_view path_view = input;
9372
0
      if (location != std::string_view::npos) {
9373
0
        path_view.remove_suffix(path_view.size() - location);
9374
0
        input.remove_prefix(location + 1);
9375
0
      }
9376
      // path_buffer is either path_view or it might point at a percent encoded
9377
      // temporary file.
9378
0
      std::string_view path_buffer =
9379
0
          (needs_percent_encoding &&
9380
0
           ada::unicode::percent_encode<false>(
9381
0
               path_view, character_sets::PATH_PERCENT_ENCODE, path_buffer_tmp))
9382
0
              ? path_buffer_tmp
9383
0
              : path_view;
9384
0
      if (unicode::is_double_dot_path_segment(path_buffer)) {
9385
0
        helpers::shorten_path(path, type);
9386
0
        if (location == std::string_view::npos) {
9387
0
          path += '/';
9388
0
        }
9389
0
      } else if (unicode::is_single_dot_path_segment(path_buffer) &&
9390
0
                 (location == std::string_view::npos)) {
9391
0
        path += '/';
9392
0
      }
9393
      // Otherwise, if path_buffer is not a single-dot path segment, then:
9394
0
      else if (!unicode::is_single_dot_path_segment(path_buffer)) {
9395
        // If url's scheme is "file", url's path is empty, and path_buffer is a
9396
        // Windows drive letter, then replace the second code point in
9397
        // path_buffer with U+003A (:).
9398
0
        if (type == ada::scheme::type::FILE && path.empty() &&
9399
0
            checkers::is_windows_drive_letter(path_buffer)) {
9400
0
          path += '/';
9401
0
          path += path_buffer[0];
9402
0
          path += ':';
9403
0
          path_buffer.remove_prefix(2);
9404
0
          path.append(path_buffer);
9405
0
        } else {
9406
          // Append path_buffer to url's path.
9407
0
          path += '/';
9408
0
          path.append(path_buffer);
9409
0
        }
9410
0
      }
9411
0
      if (location == std::string_view::npos) {
9412
0
        return;
9413
0
      }
9414
0
    } while (true);
9415
0
  }
9416
0
}
9417
9418
0
bool overlaps(std::string_view input1, const std::string& input2) noexcept {
9419
0
  ada_log("helpers::overlaps check if string_view '", input1, "' [",
9420
0
          input1.size(), " bytes] is part of string '", input2, "' [",
9421
0
          input2.size(), " bytes]");
9422
0
  return !input1.empty() && !input2.empty() && input1.data() >= input2.data() &&
9423
0
         input1.data() < input2.data() + input2.size();
9424
0
}
9425
9426
template <class url_type>
9427
0
ada_really_inline void strip_trailing_spaces_from_opaque_path(url_type& url) {
9428
0
  ada_log("helpers::strip_trailing_spaces_from_opaque_path");
9429
0
  if (!url.has_opaque_path) return;
9430
0
  if (url.has_hash()) return;
9431
0
  if (url.has_search()) return;
9432
9433
0
  auto path = std::string(url.get_pathname());
9434
0
  while (!path.empty() && path.back() == ' ') {
9435
0
    path.resize(path.size() - 1);
9436
0
  }
9437
0
  url.update_base_pathname(path);
9438
0
}
Unexecuted instantiation: void ada::helpers::strip_trailing_spaces_from_opaque_path<ada::url>(ada::url&)
Unexecuted instantiation: void ada::helpers::strip_trailing_spaces_from_opaque_path<ada::url_aggregator>(ada::url_aggregator&)
9439
9440
// @ / \\ ?
9441
static constexpr std::array<uint8_t, 256> authority_delimiter_special =
9442
    []() consteval {
9443
      std::array<uint8_t, 256> result{};
9444
      for (uint8_t i : {'@', '/', '\\', '?'}) {
9445
        result[i] = 1;
9446
      }
9447
      return result;
9448
    }();
9449
// credit: @the-moisrex recommended a table-based approach
9450
ada_really_inline size_t
9451
0
find_authority_delimiter_special(std::string_view view) noexcept {
9452
  // performance note: we might be able to gain further performance
9453
  // with SIMD intrinsics.
9454
0
  for (auto pos = view.begin(); pos != view.end(); ++pos) {
9455
0
    if (authority_delimiter_special[(uint8_t)*pos]) {
9456
0
      return pos - view.begin();
9457
0
    }
9458
0
  }
9459
0
  return size_t(view.size());
9460
0
}
9461
9462
// @ / ?
9463
static constexpr std::array<uint8_t, 256> authority_delimiter = []() consteval {
9464
  std::array<uint8_t, 256> result{};
9465
  for (uint8_t i : {'@', '/', '?'}) {
9466
    result[i] = 1;
9467
  }
9468
  return result;
9469
}();
9470
// credit: @the-moisrex recommended a table-based approach
9471
ada_really_inline size_t
9472
0
find_authority_delimiter(std::string_view view) noexcept {
9473
  // performance note: we might be able to gain further performance
9474
  // with SIMD instrinsics.
9475
0
  for (auto pos = view.begin(); pos != view.end(); ++pos) {
9476
0
    if (authority_delimiter[(uint8_t)*pos]) {
9477
0
      return pos - view.begin();
9478
0
    }
9479
0
  }
9480
0
  return size_t(view.size());
9481
0
}
9482
9483
}  // namespace ada::helpers
9484
9485
namespace ada {
9486
0
ada_warn_unused std::string to_string(ada::state state) {
9487
0
  return ada::helpers::get_state(state);
9488
0
}
9489
#undef ada_make_uint8x16_t
9490
}  // namespace ada
9491
/* end file src/helpers.cpp */
9492
/* begin file src/url.cpp */
9493
/* begin file include/ada/url_ip-inl.h */
9494
/**
9495
 * @file url_ip-inl.h
9496
 * @brief Shared IPv4/IPv6 parsing helpers used by url and url_aggregator.
9497
 *
9498
 * Not part of the public API. Defined inline so the single-TU amalgamation
9499
 * (ada.cpp) can include them from multiple translation-unit sources once.
9500
 */
9501
#ifndef ADA_URL_IP_INL_H
9502
#define ADA_URL_IP_INL_H
9503
9504
9505
#include <array>
9506
#include <cstdint>
9507
9508
// The IPv6 kernel needs vpermi2b/vpermb (VBMI) and vpcompressb/vpexpandb
9509
// (VBMI2) on top of ADA_AVX512's BW+VL.
9510
#if defined(ADA_AVX512) && defined(__AVX512VBMI__) && defined(__AVX512VBMI2__)
9511
#define ADA_AVX512_IPV6 1
9512
#endif
9513
9514
#if defined(ADA_AVX512)
9515
#include <immintrin.h>
9516
#endif
9517
9518
namespace ada::detail {
9519
9520
// 256-entry: 0xff = not hex, else nibble value.
9521
0
inline constexpr std::array<uint8_t, 256> make_hex_nibble_table() noexcept {
9522
0
  std::array<uint8_t, 256> t{};
9523
0
  for (size_t i = 0; i < 256; ++i) {
9524
0
    t[i] = 0xff;
9525
0
  }
9526
0
  for (size_t d = 0; d < 10; ++d) {
9527
0
    t[size_t{'0'} + d] = static_cast<uint8_t>(d);
9528
0
  }
9529
0
  for (size_t d = 0; d < 6; ++d) {
9530
0
    t[size_t{'a'} + d] = static_cast<uint8_t>(10 + d);
9531
0
    t[size_t{'A'} + d] = static_cast<uint8_t>(10 + d);
9532
0
  }
9533
0
  return t;
9534
0
}
9535
9536
inline constexpr auto hex_nibble = make_hex_nibble_table();
9537
9538
inline bool parse_ipv4_number(const char*& p, const char* end, uint64_t& value,
9539
0
                              bool& is_pure_decimal) noexcept {
9540
0
  is_pure_decimal = false;
9541
0
  if (p >= end) [[unlikely]] {
9542
0
    return false;
9543
0
  }
9544
0
  if (end - p >= 2 && p[0] == '0' && ((p[1] | 0x20) == 'x')) {
9545
0
    p += 2;
9546
0
    if (p == end || *p == '.') {
9547
0
      value = 0;
9548
0
      return true;
9549
0
    }
9550
0
    uint64_t v = 0;
9551
0
    int digits = 0;
9552
0
    while (p < end && *p != '.') {
9553
0
      const uint8_t nib = hex_nibble[static_cast<unsigned char>(*p)];
9554
0
      if (nib == 0xff) [[unlikely]] {
9555
0
        return false;
9556
0
      }
9557
0
      if (v > (0xFFFFFFFFULL >> 4)) [[unlikely]] {
9558
0
        return false;
9559
0
      }
9560
0
      v = (v << 4) | nib;
9561
0
      ++p;
9562
0
      ++digits;
9563
0
    }
9564
0
    if (digits == 0) [[unlikely]] {
9565
0
      return false;
9566
0
    }
9567
0
    value = v;
9568
0
    return true;
9569
0
  }
9570
0
  if (end - p >= 2 && p[0] == '0' && p[1] >= '0' && p[1] <= '9') {
9571
0
    ++p;
9572
0
    uint64_t v = 0;
9573
0
    while (p < end && *p != '.') {
9574
0
      const char c = *p;
9575
0
      if (c < '0' || c > '7') [[unlikely]] {
9576
0
        return false;
9577
0
      }
9578
0
      if (v > (0xFFFFFFFFULL >> 3)) [[unlikely]] {
9579
0
        return false;
9580
0
      }
9581
0
      v = (v << 3) | static_cast<uint64_t>(c - '0');
9582
0
      ++p;
9583
0
    }
9584
0
    value = v;
9585
0
    return true;
9586
0
  }
9587
0
  if (*p < '0' || *p > '9') [[unlikely]] {
9588
0
    return false;
9589
0
  }
9590
0
  is_pure_decimal = true;
9591
0
  uint64_t v = static_cast<uint64_t>(*p - '0');
9592
0
  ++p;
9593
0
  while (p < end && *p != '.') {
9594
0
    const char c = *p;
9595
0
    if (c < '0' || c > '9') [[unlikely]] {
9596
0
      return false;
9597
0
    }
9598
0
    if (v > 429496729ULL) [[unlikely]] {
9599
0
      return false;
9600
0
    }
9601
0
    v = v * 10u + static_cast<uint64_t>(c - '0');
9602
0
    if (v > 0xFFFFFFFFULL) [[unlikely]] {
9603
0
      return false;
9604
0
    }
9605
0
    ++p;
9606
0
  }
9607
0
  value = v;
9608
0
  return true;
9609
0
}
9610
9611
// Parse up to 4 hex digits. Returns digit count (0 if none).
9612
inline int parse_hex_piece(const char*& pointer, const char* end,
9613
0
                           uint16_t& value) noexcept {
9614
0
  if (pointer == end) {
9615
0
    return 0;
9616
0
  }
9617
0
  const uint8_t n0 = hex_nibble[static_cast<unsigned char>(*pointer)];
9618
0
  if (n0 == 0xff) {
9619
0
    return 0;
9620
0
  }
9621
0
  uint32_t v = n0;
9622
0
  ++pointer;
9623
0
  int length = 1;
9624
0
  if (pointer != end) {
9625
0
    const uint8_t n1 = hex_nibble[static_cast<unsigned char>(*pointer)];
9626
0
    if (n1 != 0xff) {
9627
0
      v = (v << 4) | n1;
9628
0
      ++pointer;
9629
0
      ++length;
9630
0
      if (pointer != end) {
9631
0
        const uint8_t n2 = hex_nibble[static_cast<unsigned char>(*pointer)];
9632
0
        if (n2 != 0xff) {
9633
0
          v = (v << 4) | n2;
9634
0
          ++pointer;
9635
0
          ++length;
9636
0
          if (pointer != end) {
9637
0
            const uint8_t n3 = hex_nibble[static_cast<unsigned char>(*pointer)];
9638
0
            if (n3 != 0xff) {
9639
0
              v = (v << 4) | n3;
9640
0
              ++pointer;
9641
0
              ++length;
9642
0
            }
9643
0
          }
9644
0
        }
9645
0
      }
9646
0
    }
9647
0
  }
9648
0
  value = static_cast<uint16_t>(v);
9649
0
  return length;
9650
0
}
9651
9652
#if defined(ADA_AVX512_IPV6)
9653
// Gather each group's up-to-four nibbles and fold them into eight hextets.
9654
// `prev` is the byte before each group, so an index that runs off the front of
9655
// a short group clamps onto a colon, which translates to zero: no write mask.
9656
ada_really_inline void ipv6_gather(__m128i ends, __m128i prev, __m512i nib,
9657
                                   std::array<uint16_t, 8>& address) noexcept {
9658
  const __m256i grp =
9659
      _mm256_setr_epi8(0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4,
9660
                       4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7);
9661
  const __m256i off = _mm256_setr_epi8(
9662
      -4, -3, -2, -1, -4, -3, -2, -1, -4, -3, -2, -1, -4, -3, -2, -1, -4, -3,
9663
      -2, -1, -4, -3, -2, -1, -4, -3, -2, -1, -4, -3, -2, -1);
9664
  const __m256i idx = _mm256_max_epi8(
9665
      _mm256_add_epi8(
9666
          _mm256_permutexvar_epi8(grp, _mm256_castsi128_si256(ends)), off),
9667
      _mm256_permutexvar_epi8(grp, _mm256_castsi128_si256(prev)));
9668
  const __m256i gathered = _mm512_castsi512_si256(
9669
      _mm512_permutexvar_epi8(_mm512_castsi256_si512(idx), nib));
9670
  // (a,b) -> 16a+b are the sixteen address bytes; 256*hi+lo pairs them.
9671
  const __m256i hextets = _mm256_madd_epi16(
9672
      _mm256_maddubs_epi16(gathered, _mm256_set1_epi16(0x0110)),
9673
      _mm256_set1_epi32(0x00010100));
9674
  _mm_storeu_si128(reinterpret_cast<__m128i*>(address.data()),
9675
                   _mm256_cvtepi32_epi16(hextets));
9676
}
9677
9678
// Parse an IPv6 host with one masked 512-bit load. Derived from
9679
// vtlmks/ipv6-avx512 (Peter Fors, MIT).
9680
//
9681
// Returns false when the input is outside this kernel's grammar and the caller
9682
// must run the scalar parser. Otherwise `valid` receives the verdict, and
9683
// `address` the eight hextets when valid.
9684
ada_really_inline bool try_parse_ipv6_avx512(const char* data, size_t len,
9685
                                             std::array<uint16_t, 8>& address,
9686
                                             bool& valid) noexcept {
9687
  if (len < 2 || len > 45) [[unlikely]] {
9688
    return false;
9689
  }
9690
  // ':' rather than 0x80 for the colon, so a clamped index reads a zero nibble.
9691
  alignas(64) static constexpr uint8_t hex_lo[64] = {
9692
      0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
9693
      0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
9694
      0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
9695
      0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
9696
      0x80, 0x80, 0x80, 0x80, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
9697
      0x07, 0x08, 0x09, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80};
9698
  alignas(64) static constexpr uint8_t hex_hi[64] = {
9699
      0x80, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x80, 0x80, 0x80, 0x80,
9700
      0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
9701
      0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
9702
      0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x80, 0x80, 0x80, 0x80, 0x80,
9703
      0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
9704
      0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80};
9705
  alignas(64) static constexpr uint8_t iota[64] = {
9706
      0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 15,
9707
      16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
9708
      32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
9709
      48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63};
9710
9711
  const __mmask64 active =
9712
      static_cast<__mmask64>(_bzhi_u64(~0ULL, static_cast<uint32_t>(len)));
9713
  const __m512i colon = _mm512_set1_epi8(':');
9714
  // Merging ':' into the tail makes the terminator at `len` a real colon, so
9715
  // the compress mask below never has to be rebuilt in a general register.
9716
  const __m512i v = _mm512_mask_loadu_epi8(colon, active, data);
9717
  const __mmask64 mcolon = _mm512_cmpeq_epi8_mask(v, colon);
9718
9719
  // An embedded dotted quad is the one valid form this kernel does not cover.
9720
  // Because that is the only gap, every other input it does not accept is
9721
  // invalid, which is what makes `valid = false` below safe.
9722
  if (_mm512_cmpeq_epi8_mask(v, _mm512_set1_epi8('.'))) [[unlikely]] {
9723
    return false;
9724
  }
9725
9726
  const __m512i nib = _mm512_permutex2var_epi8(_mm512_load_si512(hex_lo), v,
9727
                                               _mm512_load_si512(hex_hi));
9728
  const __m128i comp = _mm512_castsi512_si128(
9729
      _mm512_maskz_compress_epi8(mcolon, _mm512_load_si512(iota)));
9730
  const __m128i lane0 =
9731
      _mm_setr_epi8(-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
9732
  const __m128i prev = _mm_or_si128(_mm_bslli_si128(comp, 1), lane0);
9733
  const __m128i width = _mm_sub_epi8(comp, prev);  // one too large
9734
9735
  const uint64_t mc = static_cast<uint64_t>(mcolon);
9736
  const uint64_t act = static_cast<uint64_t>(active);
9737
  const uint64_t dc = mc & (mc >> 1) & (act >> 1);  // a "::" inside [0, len)
9738
9739
  if (!dc) {
9740
    ipv6_gather(comp, prev, nib, address);
9741
    // nib | (v & 0x80): one scan for non-hex bytes and for bytes whose high
9742
    // bit made vpermi2b alias a legal one.
9743
    const __m512i fused = _mm512_ternarylogic_epi32(
9744
        nib, v, _mm512_set1_epi8(static_cast<char>(0x80)), 0xf8);
9745
    // Lanes 8..15 bound against 255, which an unsigned byte cannot exceed.
9746
    const __m128i wmax =
9747
        _mm_setr_epi8(3, 3, 3, 3, 3, 3, 3, 3, -1, -1, -1, -1, -1, -1, -1, -1);
9748
    __mmask64 err = _kandn_mask64(mcolon, _mm512_movepi8_mask(fused));
9749
    err = _kor_mask64(
9750
        err, static_cast<__mmask64>(static_cast<uint16_t>(_mm_cmpgt_epu8_mask(
9751
                 _mm_sub_epi8(width, _mm_set1_epi8(2)), wmax))));
9752
    valid = (_mm_popcnt_u64(mc & act) == 7) && !err;
9753
    return true;
9754
  }
9755
9756
  // Drop the zero-width gap field(s), then expand the surviving head and tail
9757
  // fields into eight slots with all-zero groups inserted at the gap.
9758
  const uint32_t head = static_cast<uint32_t>(_mm_popcnt_u64(mc & (dc - 1))) +
9759
                        static_cast<uint32_t>(dc > 1);
9760
  const __mmask16 keep = _mm_cmpgt_epi8_mask(width, _mm_set1_epi8(1));
9761
  const uint32_t kept = static_cast<uint32_t>(_mm_popcnt_u32(keep));
9762
  const __mmask16 slots = static_cast<__mmask16>(
9763
      ~(_bzhi_u32(0xFFFFFFFFu, 8 - kept) << head) & 0xFFu);
9764
  // Inserted groups take prev = -1, so their indices clamp to byte 63, a tail
9765
  // colon, and read zero.
9766
  ipv6_gather(_mm_maskz_expand_epi8(slots, _mm_maskz_compress_epi8(keep, comp)),
9767
              _mm_mask_expand_epi8(_mm_set1_epi8(-1), slots,
9768
                                   _mm_maskz_compress_epi8(keep, prev)),
9769
              nib, address);
9770
9771
  uint64_t err = _mm512_movepi8_mask(v);    // high-bit bytes
9772
  err |= _mm512_movepi8_mask(nib) & ~mc;    // non-hex
9773
  err |= _blsr_u64(dc);                     // a second "::"
9774
  err |= static_cast<uint64_t>(kept >= 8);  // "::" elides nothing
9775
  err |= _mm_cmpgt_epu8_mask(width, _mm_set1_epi8(5)) & keep;  // group > 4
9776
  err |= (mc & 1ULL) & ~dc;                                // leading lone ':'
9777
  err |= ((mc >> (len - 1)) & 1ULL) & ~(dc >> (len - 2));  // trailing lone ':'
9778
  valid = !err;
9779
  return true;
9780
}
9781
#endif  // ADA_AVX512_IPV6
9782
9783
}  // namespace ada::detail
9784
9785
#endif  // ADA_URL_IP_INL_H
9786
/* end file include/ada/url_ip-inl.h */
9787
9788
#include <algorithm>
9789
#include <array>
9790
#include <cstdint>
9791
#include <iterator>
9792
#include <numeric>
9793
#include <ranges>
9794
#include <string>
9795
#include <string_view>
9796
9797
namespace ada {
9798
9799
0
bool url::parse_opaque_host(std::string_view input) {
9800
0
  ada_log("parse_opaque_host ", input, " [", input.size(), " bytes]");
9801
0
  if (std::ranges::any_of(input, ada::unicode::is_forbidden_host_code_point)) {
9802
0
    return is_valid = false;
9803
0
  }
9804
9805
  // Return the result of running UTF-8 percent-encode on input using the C0
9806
  // control percent-encode set.
9807
0
  host = ada::unicode::percent_encode(
9808
0
      input, ada::character_sets::C0_CONTROL_PERCENT_ENCODE);
9809
0
  return true;
9810
0
}
9811
9812
0
bool url::parse_ipv4(std::string_view input) {
9813
0
  ada_log("parse_ipv4 ", input, " [", input.size(), " bytes]");
9814
0
  if (input.empty()) {
9815
0
    return is_valid = false;
9816
0
  }
9817
0
  std::string_view original_input = input;
9818
0
  if (original_input.back() == '.') {
9819
0
    original_input.remove_suffix(1);
9820
0
  }
9821
0
  if (input.back() == '.') {
9822
0
    input.remove_suffix(1);
9823
0
    if (input.empty()) {
9824
0
      return is_valid = false;
9825
0
    }
9826
0
  }
9827
9828
0
  const uint64_t fast = checkers::try_parse_ipv4_fast(input);
9829
0
  if (fast < checkers::ipv4_fast_fail) [[likely]] {
9830
0
    host = original_input;
9831
0
    host_type = IPV4;
9832
0
    return true;
9833
0
  }
9834
9835
0
  const char* p = input.data();
9836
0
  const char* end = p + input.size();
9837
0
  uint64_t ipv4 = 0;
9838
0
  int digit_count = 0;
9839
0
  int pure_decimal_count = 0;
9840
9841
0
  for (; digit_count < 4 && p < end; ++digit_count) {
9842
0
    uint64_t segment = 0;
9843
0
    bool pure = false;
9844
0
    if (!detail::parse_ipv4_number(p, end, segment, pure)) {
9845
0
      return is_valid = false;
9846
0
    }
9847
0
    if (pure) {
9848
0
      ++pure_decimal_count;
9849
0
    }
9850
0
    if (p >= end) {
9851
0
      const unsigned shift = static_cast<unsigned>(32 - digit_count * 8);
9852
0
      if (segment >= (uint64_t{1} << shift)) {
9853
0
        return is_valid = false;
9854
0
      }
9855
0
      ipv4 = (ipv4 << shift) | segment;
9856
0
      host = (pure_decimal_count == 4) ? std::string(original_input)
9857
0
                                       : ada::serializers::ipv4(ipv4);
9858
0
      host_type = IPV4;
9859
0
      return true;
9860
0
    }
9861
0
    if (segment > 255 || *p != '.') {
9862
0
      return is_valid = false;
9863
0
    }
9864
0
    ipv4 = (ipv4 << 8) | segment;
9865
0
    ++p;
9866
0
  }
9867
0
  if (digit_count != 4 || p != end) {
9868
0
    return is_valid = false;
9869
0
  }
9870
0
  host = (pure_decimal_count == 4) ? std::string(original_input)
9871
0
                                   : ada::serializers::ipv4(ipv4);
9872
0
  host_type = IPV4;
9873
0
  return true;
9874
0
}
9875
9876
0
bool url::parse_ipv6(std::string_view input) {
9877
0
  ada_log("parse_ipv6 ", input, " [", input.size(), " bytes]");
9878
0
  if (input.empty() || input.size() > 45) [[unlikely]] {
9879
0
    return is_valid = false;
9880
0
  }
9881
0
  std::array<uint16_t, 8> address{};
9882
#if defined(ADA_AVX512_IPV6)
9883
  if (bool simd_valid; detail::try_parse_ipv6_avx512(input.data(), input.size(),
9884
                                                     address, simd_valid)) {
9885
    if (!simd_valid) [[unlikely]] {
9886
      return is_valid = false;
9887
    }
9888
    host = ada::serializers::ipv6(address);
9889
    host_type = IPV6;
9890
    return true;
9891
  }
9892
  address = {};
9893
#endif
9894
0
  const char* pointer = input.data();
9895
0
  const char* const end = pointer + input.size();
9896
0
  int piece_index = 0;
9897
0
  int compress = -1;
9898
9899
0
  if (*pointer == ':') {
9900
0
    if (input.size() == 1 || pointer[1] != ':') [[unlikely]] {
9901
0
      return is_valid = false;
9902
0
    }
9903
0
    pointer += 2;
9904
0
    compress = ++piece_index;
9905
0
  }
9906
9907
0
  while (pointer != end) {
9908
0
    if (piece_index == 8) [[unlikely]] {
9909
0
      return is_valid = false;
9910
0
    }
9911
0
    if (*pointer == ':') {
9912
0
      if (compress != -1) [[unlikely]] {
9913
0
        return is_valid = false;
9914
0
      }
9915
0
      ++pointer;
9916
0
      compress = ++piece_index;
9917
0
      continue;
9918
0
    }
9919
9920
0
    uint16_t value = 0;
9921
0
    const int length = detail::parse_hex_piece(pointer, end, value);
9922
9923
0
    if (pointer != end && *pointer == '.') {
9924
0
      if (length == 0) [[unlikely]] {
9925
0
        return is_valid = false;
9926
0
      }
9927
0
      pointer -= length;
9928
0
      if (piece_index > 6) [[unlikely]] {
9929
0
        return is_valid = false;
9930
0
      }
9931
9932
0
      int numbers_seen = 0;
9933
0
      while (pointer != end) {
9934
0
        int ipv4_piece = -1;
9935
0
        if (numbers_seen > 0) {
9936
0
          if (*pointer == '.' && numbers_seen < 4) {
9937
0
            ++pointer;
9938
0
          } else {
9939
0
            return is_valid = false;
9940
0
          }
9941
0
        }
9942
0
        if (pointer == end || *pointer < '0' || *pointer > '9') [[unlikely]] {
9943
0
          return is_valid = false;
9944
0
        }
9945
0
        ipv4_piece = *pointer - '0';
9946
0
        ++pointer;
9947
0
        if (pointer != end && *pointer >= '0' && *pointer <= '9') {
9948
0
          if (ipv4_piece == 0) [[unlikely]] {
9949
0
            return is_valid = false;
9950
0
          }
9951
0
          ipv4_piece = ipv4_piece * 10 + (*pointer - '0');
9952
0
          ++pointer;
9953
0
          if (pointer != end && *pointer >= '0' && *pointer <= '9') {
9954
0
            ipv4_piece = ipv4_piece * 10 + (*pointer - '0');
9955
0
            ++pointer;
9956
0
            if (ipv4_piece > 255) [[unlikely]] {
9957
0
              return is_valid = false;
9958
0
            }
9959
0
          }
9960
0
        }
9961
0
        address[static_cast<size_t>(piece_index)] = static_cast<uint16_t>(
9962
0
            address[static_cast<size_t>(piece_index)] * 0x100 +
9963
0
            static_cast<uint16_t>(ipv4_piece));
9964
0
        ++numbers_seen;
9965
0
        if (numbers_seen == 2 || numbers_seen == 4) {
9966
0
          ++piece_index;
9967
0
        }
9968
0
      }
9969
0
      if (numbers_seen != 4) [[unlikely]] {
9970
0
        return is_valid = false;
9971
0
      }
9972
0
      break;
9973
0
    }
9974
9975
0
    if (length == 0) [[unlikely]] {
9976
0
      return is_valid = false;
9977
0
    }
9978
9979
0
    if (pointer != end && *pointer == ':') {
9980
0
      ++pointer;
9981
0
      if (pointer == end) [[unlikely]] {
9982
0
        return is_valid = false;
9983
0
      }
9984
0
    } else if (pointer != end) [[unlikely]] {
9985
0
      return is_valid = false;
9986
0
    }
9987
9988
0
    address[static_cast<size_t>(piece_index)] = value;
9989
0
    ++piece_index;
9990
0
  }
9991
9992
0
  if (compress != -1) {
9993
0
    const int right = piece_index - compress;
9994
0
    if (right > 0) {
9995
0
      const size_t dest = static_cast<size_t>(8 - right);
9996
0
      const size_t src = static_cast<size_t>(compress);
9997
0
      if (dest != src) {
9998
0
        for (size_t i = static_cast<size_t>(right); i-- > 0;) {
9999
0
          address[dest + i] = address[src + i];
10000
0
          address[src + i] = 0;
10001
0
        }
10002
0
      }
10003
0
    }
10004
0
  } else if (piece_index != 8) [[unlikely]] {
10005
0
    return is_valid = false;
10006
0
  }
10007
10008
0
  host = ada::serializers::ipv6(address);
10009
0
  ada_log("parse_ipv6 ", *host);
10010
0
  host_type = IPV6;
10011
0
  return true;
10012
0
}
10013
10014
template <bool has_state_override>
10015
0
ada_really_inline bool url::parse_scheme(const std::string_view input) {
10016
0
  auto parsed_type = ada::scheme::get_scheme_type(input);
10017
0
  bool is_input_special = (parsed_type != ada::scheme::NOT_SPECIAL);
10018
  /**
10019
   * In the common case, we will immediately recognize a special scheme (e.g.,
10020
   *http, https), in which case, we can go really fast.
10021
   **/
10022
0
  if (is_input_special) {  // fast path!!!
10023
0
    if constexpr (has_state_override) {
10024
      // If url's scheme is not a special scheme and buffer is a special scheme,
10025
      // then return.
10026
0
      if (is_special() != is_input_special) {
10027
0
        return false;
10028
0
      }
10029
10030
      // If url includes credentials or has a non-null port, and buffer is
10031
      // "file", then return.
10032
0
      if ((has_credentials() || port.has_value()) &&
10033
0
          parsed_type == ada::scheme::type::FILE) {
10034
0
        return false;
10035
0
      }
10036
10037
      // If url's scheme is "file" and its host is an empty host, then return.
10038
      // An empty host is the empty string.
10039
0
      if (type == ada::scheme::type::FILE && host.has_value() &&
10040
0
          host->empty()) {
10041
0
        return false;
10042
0
      }
10043
0
    }
10044
10045
0
    type = parsed_type;
10046
10047
0
    if constexpr (has_state_override) {
10048
      // This is uncommon.
10049
0
      uint16_t urls_scheme_port = get_special_port();
10050
10051
0
      if (urls_scheme_port) {
10052
        // If url's port is url's scheme's default port, then set url's port to
10053
        // null.
10054
0
        if (port.has_value() && *port == urls_scheme_port) {
10055
0
          port = std::nullopt;
10056
0
        }
10057
0
      }
10058
0
    }
10059
0
  } else {  // slow path
10060
0
    std::string _buffer(input);
10061
    // Next function is only valid if the input is ASCII and returns false
10062
    // otherwise, but it seems that we always have ascii content so we do not
10063
    // need to check the return value.
10064
    // bool is_ascii =
10065
0
    unicode::to_lower_ascii(_buffer.data(), _buffer.size());
10066
10067
0
    if constexpr (has_state_override) {
10068
      // The state-override validation errors below ("return" in the WHATWG URL
10069
      // parser) leave the URL unchanged. The setter contract is
10070
      // "true on success, false if the scheme is invalid" -- the fast path
10071
      // above already returns false here, so the slow path must agree.
10072
10073
      // If url's scheme is a special scheme and buffer is not a special scheme,
10074
      // then return. If url's scheme is not a special scheme and buffer is a
10075
      // special scheme, then return.
10076
0
      if (is_special() != ada::scheme::is_special(_buffer)) {
10077
0
        return false;
10078
0
      }
10079
10080
      // If url includes credentials or has a non-null port, and buffer is
10081
      // "file", then return.
10082
0
      if ((has_credentials() || port.has_value()) && _buffer == "file") {
10083
0
        return false;
10084
0
      }
10085
10086
      // If url's scheme is "file" and its host is an empty host, then return.
10087
      // An empty host is the empty string.
10088
0
      if (type == ada::scheme::type::FILE && host.has_value() &&
10089
0
          host->empty()) {
10090
0
        return false;
10091
0
      }
10092
0
    }
10093
10094
0
    set_scheme(std::move(_buffer));
10095
10096
0
    if constexpr (has_state_override) {
10097
      // This is uncommon.
10098
0
      uint16_t urls_scheme_port = get_special_port();
10099
10100
0
      if (urls_scheme_port) {
10101
        // If url's port is url's scheme's default port, then set url's port to
10102
        // null.
10103
0
        if (port.has_value() && *port == urls_scheme_port) {
10104
0
          port = std::nullopt;
10105
0
        }
10106
0
      }
10107
0
    }
10108
0
  }
10109
10110
0
  return true;
10111
0
}
Unexecuted instantiation: bool ada::url::parse_scheme<true>(std::__1::basic_string_view<char, std::__1::char_traits<char> >)
Unexecuted instantiation: bool ada::url::parse_scheme<false>(std::__1::basic_string_view<char, std::__1::char_traits<char> >)
10112
10113
0
ada_really_inline bool url::parse_host(std::string_view input) {
10114
0
  ada_log("parse_host ", input, " [", input.size(), " bytes]");
10115
0
  if (input.empty()) {
10116
0
    return is_valid = false;
10117
0
  }  // technically unnecessary.
10118
  // If input starts with U+005B ([), then:
10119
0
  if (input[0] == '[') {
10120
    // If input does not end with U+005D (]), validation error, return failure.
10121
0
    if (input.back() != ']') {
10122
0
      return is_valid = false;
10123
0
    }
10124
0
    ada_log("parse_host ipv6");
10125
10126
    // Return the result of IPv6 parsing input with its leading U+005B ([) and
10127
    // trailing U+005D (]) removed.
10128
0
    input.remove_prefix(1);
10129
0
    input.remove_suffix(1);
10130
0
    return parse_ipv6(input);
10131
0
  }
10132
10133
  // If isNotSpecial is true, then return the result of opaque-host parsing
10134
  // input.
10135
0
  if (!is_special()) {
10136
0
    return parse_opaque_host(input);
10137
0
  }
10138
10139
  // Fast path: try to parse as pure decimal IPv4 first.
10140
0
  const uint64_t fast_result = checkers::try_parse_ipv4_fast(input);
10141
0
  if (fast_result < checkers::ipv4_fast_fail) {
10142
0
    if (!input.empty() && input.back() == '.') {
10143
0
      host = input.substr(0, input.size() - 1);
10144
0
    } else {
10145
0
      host = input;
10146
0
    }
10147
0
    host_type = IPV4;
10148
0
    is_valid = true;
10149
0
    ada_log("parse_host fast path decimal ipv4");
10150
0
    return true;
10151
0
  }
10152
  // Let domain be the result of running UTF-8 decode without BOM on the
10153
  // percent-decoding of input. Let asciiDomain be the result of running domain
10154
  // to ASCII with domain and false. The most common case is an ASCII input, in
10155
  // which case we do not need to call the expensive 'to_ascii' if a few
10156
  // conditions are met: no '%' and no 'xn-' subsequence.
10157
0
  const uint8_t forbidden_or_upper =
10158
0
      unicode::contains_forbidden_domain_code_point_or_upper(input.data(),
10159
0
                                                             input.size());
10160
0
  static constexpr std::string_view xn_dash{"xn-", 3};
10161
0
  if ((forbidden_or_upper & 1) == 0) {
10162
0
    host = std::string(input);
10163
0
    if ((forbidden_or_upper & 2) != 0) {
10164
0
      unicode::to_lower_ascii(host->data(), host->size());
10165
0
    }
10166
0
    if (host->find('-') == std::string_view::npos ||
10167
0
        host->find(xn_dash) == std::string_view::npos) {
10168
0
      if (checkers::is_ipv4(*host)) {
10169
0
        ada_log("parse_host fast path ipv4");
10170
0
        return parse_ipv4(*host);
10171
0
      }
10172
0
      ada_log("parse_host fast path ", *host);
10173
0
      is_valid = true;
10174
0
      return true;
10175
0
    }
10176
0
  } else if (const size_t first_percent = input.find('%');
10177
0
             first_percent != std::string_view::npos) {
10178
0
    std::string decoded = unicode::percent_decode(input, first_percent);
10179
0
    const uint8_t decoded_flags =
10180
0
        unicode::contains_forbidden_domain_code_point_or_upper(decoded.data(),
10181
0
                                                               decoded.size());
10182
0
    if ((decoded_flags & 1) == 0) {
10183
0
      if ((decoded_flags & 2) != 0) {
10184
0
        unicode::to_lower_ascii(decoded.data(), decoded.size());
10185
0
      }
10186
0
      if (decoded.find('-') == std::string_view::npos ||
10187
0
          decoded.find(xn_dash) == std::string_view::npos) {
10188
0
        host = std::move(decoded);
10189
0
        if (checkers::is_ipv4(*host)) {
10190
0
          return parse_ipv4(*host);
10191
0
        }
10192
0
        is_valid = true;
10193
0
        return true;
10194
0
      }
10195
0
    }
10196
0
  }
10197
0
  ada_log("parse_host calling to_ascii");
10198
0
  is_valid = ada::unicode::to_ascii(host, input, input.find('%'));
10199
0
  if (!is_valid || !host.has_value()) {
10200
0
    ada_log("parse_host to_ascii returns false");
10201
0
    return is_valid = false;
10202
0
  }
10203
0
  ada_log("parse_host to_ascii succeeded ", *host, " [", host->size(),
10204
0
          " bytes]");
10205
10206
0
  if (std::any_of(host->begin(), host->end(),
10207
0
                  ada::unicode::is_forbidden_domain_code_point)) {
10208
0
    host = std::nullopt;
10209
0
    return is_valid = false;
10210
0
  }
10211
10212
  // If asciiDomain ends in a number, then return the result of IPv4 parsing
10213
  // asciiDomain.
10214
0
  if (checkers::is_ipv4(*host)) {
10215
0
    ada_log("parse_host got ipv4 ", *host);
10216
0
    return parse_ipv4(*host);
10217
0
  }
10218
10219
0
  return true;
10220
0
}
10221
10222
0
ada_really_inline void url::parse_path(std::string_view input) {
10223
0
  ada_log("parse_path ", input);
10224
0
  std::string tmp_buffer;
10225
0
  std::string_view internal_input;
10226
0
  if (unicode::has_tabs_or_newline(input)) {
10227
0
    tmp_buffer = input;
10228
    // Optimization opportunity: Instead of copying and then pruning, we could
10229
    // just directly build the string from user_input.
10230
0
    helpers::remove_ascii_tab_or_newline(tmp_buffer);
10231
0
    internal_input = tmp_buffer;
10232
0
  } else {
10233
0
    internal_input = input;
10234
0
  }
10235
10236
  // If url is special, then:
10237
0
  if (is_special()) {
10238
0
    if (internal_input.empty()) {
10239
0
      path = "/";
10240
0
    } else if ((internal_input[0] == '/') || (internal_input[0] == '\\')) {
10241
0
      helpers::parse_prepared_path(internal_input.substr(1), type, path);
10242
0
    } else {
10243
0
      helpers::parse_prepared_path(internal_input, type, path);
10244
0
    }
10245
0
  } else if (!internal_input.empty()) {
10246
0
    if (internal_input[0] == '/') {
10247
0
      helpers::parse_prepared_path(internal_input.substr(1), type, path);
10248
0
    } else {
10249
0
      helpers::parse_prepared_path(internal_input, type, path);
10250
0
    }
10251
0
  } else {
10252
0
    if (!host.has_value()) {
10253
0
      path = "/";
10254
0
    }
10255
0
  }
10256
0
}
10257
10258
0
[[nodiscard]] std::string url::to_string() const {
10259
0
  if (!is_valid) {
10260
0
    return "null";
10261
0
  }
10262
0
  std::string answer;
10263
0
  auto back = std::back_insert_iterator(answer);
10264
0
  answer.append("{\n");
10265
0
  answer.append("\t\"protocol\":\"");
10266
0
  helpers::encode_json(get_protocol(), back);
10267
0
  answer.append("\",\n");
10268
0
  if (has_credentials()) {
10269
0
    answer.append("\t\"username\":\"");
10270
0
    helpers::encode_json(username, back);
10271
0
    answer.append("\",\n");
10272
0
    answer.append("\t\"password\":\"");
10273
0
    helpers::encode_json(password, back);
10274
0
    answer.append("\",\n");
10275
0
  }
10276
0
  if (host.has_value()) {
10277
0
    answer.append("\t\"host\":\"");
10278
0
    helpers::encode_json(host.value(), back);
10279
0
    answer.append("\",\n");
10280
0
  }
10281
0
  if (port.has_value()) {
10282
0
    answer.append("\t\"port\":\"");
10283
0
    answer.append(std::to_string(port.value()));
10284
0
    answer.append("\",\n");
10285
0
  }
10286
0
  answer.append("\t\"path\":\"");
10287
0
  helpers::encode_json(path, back);
10288
0
  answer.append("\",\n");
10289
0
  answer.append("\t\"opaque path\":");
10290
0
  answer.append((has_opaque_path ? "true" : "false"));
10291
0
  if (has_search()) {
10292
0
    answer.append(",\n");
10293
0
    answer.append("\t\"query\":\"");
10294
    // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
10295
0
    helpers::encode_json(query.value(), back);
10296
0
    answer.append("\"");
10297
0
  }
10298
0
  if (hash.has_value()) {
10299
0
    answer.append(",\n");
10300
0
    answer.append("\t\"hash\":\"");
10301
0
    helpers::encode_json(hash.value(), back);
10302
0
    answer.append("\"");
10303
0
  }
10304
0
  answer.append("\n}");
10305
0
  return answer;
10306
0
}
10307
10308
0
[[nodiscard]] bool url::has_valid_domain() const noexcept {
10309
0
  if (!host.has_value()) {
10310
0
    return false;
10311
0
  }
10312
0
  return checkers::verify_dns_length(*host);
10313
0
}
10314
10315
0
[[nodiscard]] std::string url::get_origin() const {
10316
0
  if (is_special()) {
10317
    // Return a new opaque origin.
10318
0
    if (type == scheme::FILE) {
10319
0
      return "null";
10320
0
    }
10321
0
    return ada::helpers::concat(get_protocol(), "//", get_host());
10322
0
  }
10323
10324
0
  if (non_special_scheme == "blob") {
10325
0
    if (!path.empty()) {
10326
0
      auto result = ada::parse<ada::url>(path);
10327
0
      if (result &&
10328
0
          (result->type == scheme::HTTP || result->type == scheme::HTTPS)) {
10329
        // If pathURL's scheme is not "http" and not "https", then return a
10330
        // new opaque origin.
10331
0
        return ada::helpers::concat(result->get_protocol(), "//",
10332
0
                                    result->get_host());
10333
0
      }
10334
0
    }
10335
0
  }
10336
10337
  // Return a new opaque origin.
10338
0
  return "null";
10339
0
}
10340
10341
0
[[nodiscard]] std::string url::get_protocol() const {
10342
0
  if (is_special()) {
10343
0
    return helpers::concat(ada::scheme::details::is_special_list[type], ":");
10344
0
  }
10345
  // We only move the 'scheme' if it is non-special.
10346
0
  return helpers::concat(non_special_scheme, ":");
10347
0
}
10348
10349
0
[[nodiscard]] std::string url::get_host() const {
10350
  // If url's host is null, then return the empty string.
10351
  // If url's port is null, return url's host, serialized.
10352
  // Return url's host, serialized, followed by U+003A (:) and url's port,
10353
  // serialized.
10354
0
  if (!host.has_value()) {
10355
0
    return "";
10356
0
  }
10357
0
  if (port.has_value()) {
10358
0
    return host.value() + ":" + get_port();
10359
0
  }
10360
0
  return host.value();
10361
0
}
10362
10363
0
[[nodiscard]] std::string url::get_hostname() const {
10364
0
  return host.value_or("");
10365
0
}
10366
10367
0
[[nodiscard]] std::string url::get_search() const {
10368
  // If this's URL's query is either null or the empty string, then return the
10369
  // empty string. Return U+003F (?), followed by this's URL's query.
10370
0
  return (!query.has_value() || (query->empty())) ? "" : "?" + query.value();
10371
0
}
10372
10373
0
[[nodiscard]] const std::string& url::get_username() const noexcept {
10374
0
  return username;
10375
0
}
10376
10377
0
[[nodiscard]] const std::string& url::get_password() const noexcept {
10378
0
  return password;
10379
0
}
10380
10381
0
[[nodiscard]] std::string url::get_port() const {
10382
0
  return port.has_value() ? std::to_string(port.value()) : "";
10383
0
}
10384
10385
0
[[nodiscard]] std::string url::get_hash() const {
10386
  // If this's URL's fragment is either null or the empty string, then return
10387
  // the empty string. Return U+0023 (#), followed by this's URL's fragment.
10388
0
  return (!hash.has_value() || (hash->empty())) ? "" : "#" + hash.value();
10389
0
}
10390
10391
0
bool url::needs_rollback_snapshot(size_t input_len) const noexcept {
10392
0
  return get_href_size() + input_len + 16 > ada::get_max_input_length();
10393
0
}
10394
10395
template <bool override_hostname>
10396
0
bool url::set_host_or_hostname(const std::string_view input) {
10397
0
  if (has_opaque_path) {
10398
0
    return false;
10399
0
  }
10400
10401
0
  url saved_url(*this);
10402
10403
0
  size_t host_end_pos = input.find('#');
10404
0
  std::string _host(input.data(), host_end_pos != std::string_view::npos
10405
0
                                      ? host_end_pos
10406
0
                                      : input.size());
10407
0
  helpers::remove_ascii_tab_or_newline(_host);
10408
0
  std::string_view new_host(_host);
10409
10410
0
  auto check_url_size = [&]() -> bool {
10411
0
    if (get_href_size() > ada::get_max_input_length()) {
10412
0
      *this = std::move(saved_url);
10413
0
      return false;
10414
0
    }
10415
0
    return true;
10416
0
  };
Unexecuted instantiation: ada::url::set_host_or_hostname<false>(std::__1::basic_string_view<char, std::__1::char_traits<char> >)::{lambda()#1}::operator()() const
Unexecuted instantiation: ada::url::set_host_or_hostname<true>(std::__1::basic_string_view<char, std::__1::char_traits<char> >)::{lambda()#1}::operator()() const
10417
10418
  // If url's scheme is "file", then set state to file host state, instead of
10419
  // host state.
10420
0
  if (type != ada::scheme::type::FILE) {
10421
0
    std::string_view host_view(_host.data(), _host.length());
10422
0
    auto [location, found_colon] =
10423
0
        helpers::get_host_delimiter_location(is_special(), host_view);
10424
10425
    // Otherwise, if c is U+003A (:) and insideBrackets is false, then:
10426
    // Note: the 'found_colon' value is true if and only if a colon was
10427
    // encountered while not inside brackets.
10428
0
    if (found_colon) {
10429
      // If buffer is the empty string, host-missing validation error, return
10430
      // failure.
10431
0
      std::string_view buffer = host_view.substr(0, location);
10432
0
      if (buffer.empty()) {
10433
0
        return false;
10434
0
      }
10435
10436
      // If state override is given and state override is hostname state, then
10437
      // return failure.
10438
0
      if constexpr (override_hostname) {
10439
0
        return false;
10440
0
      }
10441
10442
      // Let host be the result of host parsing buffer with url is not special.
10443
0
      bool succeeded = parse_host(buffer);
10444
0
      if (!succeeded) {
10445
0
        *this = std::move(saved_url);
10446
0
        return false;
10447
0
      }
10448
10449
      // Set url's host to host, buffer to the empty string, and state to port
10450
      // state.
10451
0
      std::string_view port_buffer = new_host.substr(location + 1);
10452
0
      if (!port_buffer.empty()) {
10453
0
        set_port(port_buffer);
10454
0
      }
10455
0
      return check_url_size();
10456
0
    }
10457
    // Otherwise, if one of the following is true:
10458
    // - c is the EOF code point, U+002F (/), U+003F (?), or U+0023 (#)
10459
    // - url is special and c is U+005C (\)
10460
0
    else {
10461
      // If url is special and host_view is the empty string, host-missing
10462
      // validation error, return failure.
10463
0
      if (host_view.empty() && is_special()) {
10464
0
        return false;
10465
0
      }
10466
10467
      // Otherwise, if state override is given, host_view is the empty string,
10468
      // and either url includes credentials or url's port is non-null, then
10469
      // return failure.
10470
0
      if (host_view.empty() && (has_credentials() || port.has_value())) {
10471
0
        return false;
10472
0
      }
10473
10474
      // Let host be the result of host parsing host_view with url is not
10475
      // special.
10476
0
      if (host_view.empty() && !is_special()) {
10477
0
        host = "";
10478
0
        return check_url_size();
10479
0
      }
10480
10481
0
      bool succeeded = parse_host(host_view);
10482
0
      if (!succeeded) {
10483
0
        *this = std::move(saved_url);
10484
0
        return false;
10485
0
      }
10486
0
      return check_url_size();
10487
0
    }
10488
0
  }
10489
10490
0
  size_t location = new_host.find_first_of("/\\?");
10491
0
  if (location != std::string_view::npos) {
10492
0
    new_host.remove_suffix(new_host.length() - location);
10493
0
  }
10494
10495
0
  if (new_host.empty()) {
10496
    // Set url's host to the empty string.
10497
0
    host = "";
10498
0
  } else {
10499
    // Let host be the result of host parsing buffer with url is not special.
10500
0
    if (!parse_host(new_host)) {
10501
0
      *this = std::move(saved_url);
10502
0
      return false;
10503
0
    }
10504
10505
    // If host is "localhost", then set host to the empty string.
10506
0
    if (host == "localhost") {
10507
0
      host = "";
10508
0
    }
10509
0
  }
10510
0
  return check_url_size();
10511
0
}
Unexecuted instantiation: bool ada::url::set_host_or_hostname<false>(std::__1::basic_string_view<char, std::__1::char_traits<char> >)
Unexecuted instantiation: bool ada::url::set_host_or_hostname<true>(std::__1::basic_string_view<char, std::__1::char_traits<char> >)
10512
10513
0
bool url::set_host(const std::string_view input) {
10514
0
  return set_host_or_hostname<false>(input);
10515
0
}
10516
10517
0
bool url::set_hostname(const std::string_view input) {
10518
0
  return set_host_or_hostname<true>(input);
10519
0
}
10520
10521
0
bool url::set_username(const std::string_view input) {
10522
0
  if (cannot_have_credentials_or_port()) {
10523
0
    return false;
10524
0
  }
10525
0
  auto previous_username = std::move(username);
10526
0
  username = ada::unicode::percent_encode(
10527
0
      input, character_sets::USERINFO_PERCENT_ENCODE);
10528
0
  if (get_href_size() > ada::get_max_input_length()) {
10529
0
    username = std::move(previous_username);
10530
0
    return false;
10531
0
  }
10532
0
  return true;
10533
0
}
10534
10535
0
bool url::set_password(const std::string_view input) {
10536
0
  if (cannot_have_credentials_or_port()) {
10537
0
    return false;
10538
0
  }
10539
0
  auto previous_password = std::move(password);
10540
0
  password = ada::unicode::percent_encode(
10541
0
      input, character_sets::USERINFO_PERCENT_ENCODE);
10542
0
  if (get_href_size() > ada::get_max_input_length()) {
10543
0
    password = std::move(previous_password);
10544
0
    return false;
10545
0
  }
10546
0
  return true;
10547
0
}
10548
10549
0
bool url::set_port(const std::string_view input) {
10550
0
  if (cannot_have_credentials_or_port()) {
10551
0
    return false;
10552
0
  }
10553
10554
0
  if (input.empty()) {
10555
0
    port = std::nullopt;
10556
0
    return true;
10557
0
  }
10558
10559
0
  std::string trimmed(input);
10560
0
  helpers::remove_ascii_tab_or_newline(trimmed);
10561
10562
0
  if (trimmed.empty()) {
10563
0
    return true;
10564
0
  }
10565
10566
  // Input should not start with a non-digit character.
10567
0
  if (!ada::unicode::is_ascii_digit(trimmed.front())) {
10568
0
    return false;
10569
0
  }
10570
10571
  // Find the first non-digit character to determine the length of digits
10572
0
  auto first_non_digit =
10573
0
      std::ranges::find_if_not(trimmed, ada::unicode::is_ascii_digit);
10574
0
  std::string_view digits_to_parse =
10575
0
      std::string_view(trimmed.data(), first_non_digit - trimmed.begin());
10576
10577
  // Revert changes if parse_port fails.
10578
0
  std::optional<uint16_t> previous_port = port;
10579
0
  parse_port(digits_to_parse);
10580
0
  if (is_valid) {
10581
0
    if (get_href_size() > ada::get_max_input_length()) {
10582
0
      port = std::move(previous_port);
10583
0
      return false;
10584
0
    }
10585
0
    return true;
10586
0
  }
10587
0
  port = std::move(previous_port);
10588
0
  is_valid = true;
10589
0
  return false;
10590
0
}
10591
10592
0
void url::set_hash(const std::string_view input) {
10593
0
  if (input.empty()) {
10594
0
    hash = std::nullopt;
10595
0
    helpers::strip_trailing_spaces_from_opaque_path(*this);
10596
0
    return;
10597
0
  }
10598
10599
0
  std::string new_value;
10600
0
  new_value = input[0] == '#' ? input.substr(1) : input;
10601
0
  helpers::remove_ascii_tab_or_newline(new_value);
10602
0
  auto previous_hash = std::move(hash);
10603
0
  hash = unicode::percent_encode(new_value,
10604
0
                                 ada::character_sets::FRAGMENT_PERCENT_ENCODE);
10605
0
  if (get_href_size() > ada::get_max_input_length()) {
10606
0
    hash = std::move(previous_hash);
10607
0
  }
10608
0
}
10609
10610
0
void url::set_search(const std::string_view input) {
10611
0
  if (input.empty()) {
10612
0
    query = std::nullopt;
10613
0
    helpers::strip_trailing_spaces_from_opaque_path(*this);
10614
0
    return;
10615
0
  }
10616
10617
0
  std::string new_value;
10618
0
  new_value = input[0] == '?' ? input.substr(1) : input;
10619
0
  helpers::remove_ascii_tab_or_newline(new_value);
10620
10621
0
  auto query_percent_encode_set =
10622
0
      is_special() ? ada::character_sets::SPECIAL_QUERY_PERCENT_ENCODE
10623
0
                   : ada::character_sets::QUERY_PERCENT_ENCODE;
10624
10625
0
  auto previous_query = std::move(query);
10626
0
  query = ada::unicode::percent_encode(new_value, query_percent_encode_set);
10627
0
  if (get_href_size() > ada::get_max_input_length()) {
10628
0
    query = std::move(previous_query);
10629
0
  }
10630
0
}
10631
10632
0
bool url::set_pathname(const std::string_view input) {
10633
0
  if (has_opaque_path) {
10634
0
    return false;
10635
0
  }
10636
0
  auto previous_path = std::move(path);
10637
0
  path.clear();
10638
0
  parse_path(input);
10639
0
  if (get_href_size() > ada::get_max_input_length()) {
10640
0
    path = std::move(previous_path);
10641
0
    return false;
10642
0
  }
10643
0
  return true;
10644
0
}
10645
10646
0
bool url::set_protocol(const std::string_view input) {
10647
0
  std::string view(input);
10648
0
  helpers::remove_ascii_tab_or_newline(view);
10649
0
  if (view.empty()) {
10650
0
    return true;
10651
0
  }
10652
10653
  // Schemes should start with alpha values.
10654
0
  if (!checkers::is_alpha(view[0])) {
10655
0
    return false;
10656
0
  }
10657
10658
0
  view.append(":");
10659
10660
0
  std::string::iterator pointer =
10661
0
      std::ranges::find_if_not(view, unicode::is_alnum_plus);
10662
10663
0
  if (pointer != view.end() && *pointer == ':') {
10664
0
    std::optional<url> saved_url;
10665
0
    if (needs_rollback_snapshot(view.size())) {
10666
0
      saved_url = *this;
10667
0
    }
10668
0
    bool result = parse_scheme<true>(
10669
0
        std::string_view(view.data(), pointer - view.begin()));
10670
0
    if (result && saved_url && get_href_size() > ada::get_max_input_length()) {
10671
0
      *this = std::move(*saved_url);
10672
0
      return false;
10673
0
    }
10674
0
    return result;
10675
0
  }
10676
0
  return false;
10677
0
}
10678
10679
0
bool url::set_href(const std::string_view input) {
10680
0
  ada::result<ada::url> out = ada::parse<ada::url>(input);
10681
10682
0
  if (out) {
10683
    // The parser enforces get_max_input_length() on both the input and the
10684
    // normalized result. This is a defense-in-depth check.
10685
0
    if (out->get_href_size() > ada::get_max_input_length()) {
10686
0
      return false;
10687
0
    }
10688
0
    *this = *out;
10689
0
  }
10690
10691
0
  return out.has_value();
10692
0
}
10693
10694
}  // namespace ada
10695
/* end file src/url.cpp */
10696
/* begin file src/parser.cpp */
10697
10698
#include <array>
10699
#include <bit>
10700
#include <charconv>
10701
#include <cstdint>
10702
#include <cstring>
10703
#include <limits>
10704
#include <ranges>
10705
10706
10707
#if ADA_NEON
10708
#include <arm_neon.h>
10709
#elif defined(__SSSE3__)
10710
#include <tmmintrin.h>
10711
#define ADA_PARSER_SSSE3 1
10712
#elif (defined(__x86_64__) || defined(__amd64__)) && defined(__GNUC__) && \
10713
    !defined(_MSC_VER)
10714
// gcc/clang honor target("ssse3"). clang-cl and MSVC do not: they still
10715
// compile the function as SSE2, then reject always_inline _mm_shuffle_epi8.
10716
#include <tmmintrin.h>
10717
#define ADA_PARSER_SSSE3 1
10718
#define ADA_PARSER_NEED_SSSE3_TARGET 1
10719
#elif ADA_SSE2
10720
#include <emmintrin.h>
10721
#endif
10722
#ifndef ADA_PARSER_SSSE3
10723
#define ADA_PARSER_SSSE3 0
10724
#endif
10725
10726
#ifdef ADA_PARSER_NEED_SSSE3_TARGET
10727
#define ADA_PARSER_SIMD __attribute__((target("ssse3")))
10728
#else
10729
#define ADA_PARSER_SIMD ada_really_inline
10730
#endif
10731
10732
#ifdef ADA_REGULAR_VISUAL_STUDIO
10733
#include <intrin.h>
10734
#endif
10735
10736
namespace ada::parser {
10737
10738
// Classification tables and 16-byte run scanners for the absolute-URL fast
10739
// path. Inspired by oven-sh/WebKit#452 and #454: scan 16 bytes at a time
10740
// (nibble-table pshufb/tbl when SSSE3 or NEON is available), and when the
10741
// path/query/fragment is not already canonical, keep the parsed host and
10742
// finish with the existing path helpers instead of re-parsing from scratch.
10743
namespace {
10744
10745
// 0 = host byte, 1 = host delimiter (/ ? # :), 2 = reject
10746
constexpr std::array<uint8_t, 256> k_host_class = []() consteval {
10747
  std::array<uint8_t, 256> t{};
10748
  for (size_t i = 0; i < 256; ++i) {
10749
    t[i] = 2;
10750
  }
10751
  for (size_t i = 0x21; i <= 0x7E; ++i) {
10752
    t[i] = 0;
10753
  }
10754
  for (uint8_t c :
10755
       {'#', '/', ':', '<', '>', '?', '@', '[', '\\', ']', '^', '|', '%'}) {
10756
    t[c] = 2;
10757
  }
10758
  t[static_cast<uint8_t>('/')] = 1;
10759
  t[static_cast<uint8_t>('?')] = 1;
10760
  t[static_cast<uint8_t>('#')] = 1;
10761
  t[static_cast<uint8_t>(':')] = 1;
10762
  return t;
10763
}();
10764
10765
// Path: 0 = copy, 1 = ?/#, 2 = needs work. Apostrophe is copyable in a path.
10766
constexpr std::array<uint8_t, 256> k_path = []() consteval {
10767
  std::array<uint8_t, 256> t{};
10768
  for (size_t i = 0; i < 256; ++i) {
10769
    t[i] = 2;
10770
  }
10771
  for (uint8_t c = 0x21; c <= 0x7E; ++c) {
10772
    t[c] = 0;
10773
  }
10774
  for (uint8_t c : {static_cast<uint8_t>('"'), static_cast<uint8_t>('<'),
10775
                    static_cast<uint8_t>('>'), static_cast<uint8_t>('`'),
10776
                    static_cast<uint8_t>('{'), static_cast<uint8_t>('}'),
10777
                    static_cast<uint8_t>('^'), static_cast<uint8_t>('\\'),
10778
                    static_cast<uint8_t>('%')}) {
10779
    t[c] = 2;
10780
  }
10781
  t[static_cast<uint8_t>('?')] = 1;
10782
  t[static_cast<uint8_t>('#')] = 1;
10783
  return t;
10784
}();
10785
10786
// Special-query: 0 = copy, 1 = #, 2 = needs work. Apostrophe must be encoded.
10787
constexpr std::array<uint8_t, 256> k_query = []() consteval {
10788
  std::array<uint8_t, 256> t{};
10789
  for (size_t i = 0; i < 256; ++i) {
10790
    t[i] = 2;
10791
  }
10792
  for (uint8_t c = 0x21; c <= 0x7E; ++c) {
10793
    t[c] = 0;
10794
  }
10795
  for (uint8_t c : {static_cast<uint8_t>('"'), static_cast<uint8_t>('<'),
10796
                    static_cast<uint8_t>('>'), static_cast<uint8_t>('\'')}) {
10797
    t[c] = 2;
10798
  }
10799
  t[static_cast<uint8_t>('#')] = 1;
10800
  return t;
10801
}();
10802
10803
// Fragment: 0 = copy, 2 = needs work. '?' '#' '%' are copyable.
10804
constexpr std::array<uint8_t, 256> k_hash = []() consteval {
10805
  std::array<uint8_t, 256> t{};
10806
  for (size_t i = 0; i < 256; ++i) {
10807
    t[i] = 2;
10808
  }
10809
  for (uint8_t c = 0x21; c <= 0x7E; ++c) {
10810
    t[c] = 0;
10811
  }
10812
  for (uint8_t c : {static_cast<uint8_t>('"'), static_cast<uint8_t>('<'),
10813
                    static_cast<uint8_t>('>'), static_cast<uint8_t>('`')}) {
10814
    t[c] = 2;
10815
  }
10816
  return t;
10817
}();
10818
10819
// Nibble tables for pshufb / tbl classification (oven-sh/WebKit#454).
10820
// A byte is a stop when low[b & 0xF] & high[b >> 4] != 0. High nibbles whose
10821
// sixteen bytes share a stop pattern share a bit, so any set with at most
10822
// eight distinct patterns fits. Tables are built from the scalar class
10823
// arrays, so the vector and scalar paths cannot disagree.
10824
struct nibble_tables {
10825
  alignas(16) uint8_t low[16]{};
10826
  alignas(16) uint8_t high[16]{};
10827
  bool fits{true};
10828
};
10829
10830
consteval nibble_tables make_stop_nibble_tables(
10831
    const std::array<uint8_t, 256>& cls) {
10832
  nibble_tables t{};
10833
  uint16_t patterns[16]{};
10834
  for (int hi = 0; hi < 16; ++hi) {
10835
    for (int lo = 0; lo < 16; ++lo) {
10836
      if (cls[static_cast<size_t>((hi << 4) | lo)] != 0) {
10837
        patterns[hi] = static_cast<uint16_t>(patterns[hi] | (1u << lo));
10838
      }
10839
    }
10840
  }
10841
  int bits_used = 0;
10842
  for (int hi = 0; hi < 16; ++hi) {
10843
    if (patterns[hi] == 0 || t.high[hi] != 0) {
10844
      continue;
10845
    }
10846
    if (bits_used == 8) {
10847
      t.fits = false;
10848
      return t;
10849
    }
10850
    const uint8_t bit = static_cast<uint8_t>(1u << bits_used++);
10851
    for (int other = hi; other < 16; ++other) {
10852
      if (patterns[other] == patterns[hi]) {
10853
        t.high[other] = static_cast<uint8_t>(t.high[other] | bit);
10854
      }
10855
    }
10856
    for (int lo = 0; lo < 16; ++lo) {
10857
      if ((patterns[hi] & (1u << lo)) != 0) {
10858
        t.low[lo] = static_cast<uint8_t>(t.low[lo] | bit);
10859
      }
10860
    }
10861
  }
10862
  return t;
10863
}
10864
10865
constexpr nibble_tables k_host_nibbles = make_stop_nibble_tables(k_host_class);
10866
constexpr nibble_tables k_path_nibbles = make_stop_nibble_tables(k_path);
10867
constexpr nibble_tables k_query_nibbles = make_stop_nibble_tables(k_query);
10868
constexpr nibble_tables k_hash_nibbles = make_stop_nibble_tables(k_hash);
10869
static_assert(k_host_nibbles.fits);
10870
static_assert(k_path_nibbles.fits);
10871
static_assert(k_query_nibbles.fits);
10872
static_assert(k_hash_nibbles.fits);
10873
10874
// WHATWG serializes a port as its decimal value with no leading zeros.
10875
0
ada_really_inline uint32_t port_decimal_digit_count(uint32_t port) noexcept {
10876
0
  uint32_t digits = 1;
10877
0
  while (port >= 10) {
10878
0
    port /= 10;
10879
0
    ++digits;
10880
0
  }
10881
0
  return digits;
10882
0
}
10883
10884
ada_really_inline void append_canonical_port(std::string& buffer,
10885
0
                                             uint32_t port) {
10886
0
  buffer += ':';
10887
0
  char port_buf[5];
10888
0
  auto [ptr, ec] = std::to_chars(port_buf, port_buf + 5, port);
10889
0
  (void)ec;
10890
0
  buffer.append(port_buf, static_cast<size_t>(ptr - port_buf));
10891
0
}
10892
10893
0
ada_really_inline int trailing_zeroes32(uint32_t input_num) noexcept {
10894
#ifdef ADA_REGULAR_VISUAL_STUDIO
10895
  unsigned long ret;
10896
  _BitScanForward(&ret, input_num);
10897
  return static_cast<int>(ret);
10898
#else
10899
0
  return __builtin_ctz(input_num);
10900
0
#endif
10901
0
}
10902
10903
0
ada_really_inline int trailing_zeroes64(uint64_t input_num) noexcept {
10904
0
#ifdef ADA_REGULAR_VISUAL_STUDIO
10905
0
  unsigned long ret;
10906
0
  _BitScanForward64(&ret, input_num);
10907
0
  return static_cast<int>(ret);
10908
0
#else
10909
0
  return __builtin_ctzll(input_num);
10910
0
#endif
10911
0
}
10912
10913
#if ADA_PARSER_SSSE3
10914
0
ADA_PARSER_SIMD __m128i nibble_load(const uint8_t* t) noexcept {
10915
0
  return _mm_load_si128(reinterpret_cast<const __m128i*>(t));
10916
0
}
10917
10918
// Non-zero lanes are stops. Tables are passed in so the scan loops can hoist
10919
// the loads out of the 16-byte iteration.
10920
ADA_PARSER_SIMD int ssse3_nibble_mask(__m128i w, __m128i lo_tbl,
10921
0
                                      __m128i hi_tbl) noexcept {
10922
0
  const __m128i nibble = _mm_set1_epi8(0x0F);
10923
0
  const __m128i lo = _mm_and_si128(w, nibble);
10924
0
  const __m128i hi = _mm_and_si128(_mm_srli_epi16(w, 4), nibble);
10925
0
  const __m128i hit =
10926
0
      _mm_and_si128(_mm_shuffle_epi8(lo_tbl, lo), _mm_shuffle_epi8(hi_tbl, hi));
10927
0
  return _mm_movemask_epi8(_mm_cmpeq_epi8(hit, _mm_setzero_si128())) ^ 0xFFFF;
10928
0
}
10929
#endif  // ADA_PARSER_SSSE3
10930
10931
#if ADA_SSE2
10932
#if !ADA_PARSER_SSSE3
10933
// Signed < 0x21 matches 0x00-0x20 and 0x80-0xFF; 0x7F is checked separately.
10934
ada_really_inline __m128i sse2_ctrl_or_nonascii(__m128i w) noexcept {
10935
  return _mm_or_si128(_mm_cmplt_epi8(w, _mm_set1_epi8(0x21)),
10936
                      _mm_cmpeq_epi8(w, _mm_set1_epi8(0x7F)));
10937
}
10938
10939
ada_really_inline int sse2_host_stop(__m128i w) noexcept {
10940
  const __m128i ctrl = sse2_ctrl_or_nonascii(w);
10941
  const __m128i is_upper = _mm_and_si128(
10942
      _mm_cmpgt_epi8(w, _mm_set1_epi8(static_cast<char>('A' - 1))),
10943
      _mm_cmplt_epi8(w, _mm_set1_epi8(static_cast<char>('Z' + 1))));
10944
  const __m128i at = _mm_sub_epi8(w, _mm_set1_epi8('@'));
10945
  const __m128i at_through_caret =
10946
      _mm_cmpeq_epi8(_mm_min_epu8(at, _mm_set1_epi8('^' - '@')), at);
10947
  const __m128i at_not_upper = _mm_andnot_si128(is_upper, at_through_caret);
10948
  const __m128i spec = _mm_or_si128(
10949
      _mm_or_si128(_mm_or_si128(_mm_cmpeq_epi8(w, _mm_set1_epi8('#')),
10950
                                _mm_cmpeq_epi8(w, _mm_set1_epi8('%'))),
10951
                   _mm_or_si128(_mm_cmpeq_epi8(w, _mm_set1_epi8('/')),
10952
                                _mm_cmpeq_epi8(w, _mm_set1_epi8(':')))),
10953
      _mm_or_si128(_mm_or_si128(_mm_cmpeq_epi8(w, _mm_set1_epi8('<')),
10954
                                _mm_cmpeq_epi8(w, _mm_set1_epi8('>'))),
10955
                   _mm_or_si128(_mm_cmpeq_epi8(w, _mm_set1_epi8('?')),
10956
                                _mm_cmpeq_epi8(w, _mm_set1_epi8('|')))));
10957
  return _mm_movemask_epi8(
10958
      _mm_or_si128(_mm_or_si128(ctrl, at_not_upper), spec));
10959
}
10960
10961
ada_really_inline int sse2_path_stop(__m128i w) noexcept {
10962
  const __m128i ctrl = sse2_ctrl_or_nonascii(w);
10963
  const __m128i spec = _mm_or_si128(
10964
      _mm_or_si128(_mm_or_si128(_mm_cmpeq_epi8(w, _mm_set1_epi8('"')),
10965
                                _mm_cmpeq_epi8(w, _mm_set1_epi8('#'))),
10966
                   _mm_or_si128(_mm_cmpeq_epi8(w, _mm_set1_epi8('%')),
10967
                                _mm_cmpeq_epi8(w, _mm_set1_epi8('<')))),
10968
      _mm_or_si128(
10969
          _mm_or_si128(_mm_or_si128(_mm_cmpeq_epi8(w, _mm_set1_epi8('>')),
10970
                                    _mm_cmpeq_epi8(w, _mm_set1_epi8('?'))),
10971
                       _mm_or_si128(_mm_cmpeq_epi8(w, _mm_set1_epi8('\\')),
10972
                                    _mm_cmpeq_epi8(w, _mm_set1_epi8('^')))),
10973
          _mm_or_si128(_mm_or_si128(_mm_cmpeq_epi8(w, _mm_set1_epi8('`')),
10974
                                    _mm_cmpeq_epi8(w, _mm_set1_epi8('{'))),
10975
                       _mm_cmpeq_epi8(w, _mm_set1_epi8('}')))));
10976
  return _mm_movemask_epi8(_mm_or_si128(ctrl, spec));
10977
}
10978
10979
ada_really_inline int sse2_query_stop(__m128i w) noexcept {
10980
  const __m128i ctrl = sse2_ctrl_or_nonascii(w);
10981
  const __m128i spec = _mm_or_si128(
10982
      _mm_or_si128(_mm_cmpeq_epi8(w, _mm_set1_epi8('"')),
10983
                   _mm_cmpeq_epi8(w, _mm_set1_epi8('#'))),
10984
      _mm_or_si128(_mm_or_si128(_mm_cmpeq_epi8(w, _mm_set1_epi8('<')),
10985
                                _mm_cmpeq_epi8(w, _mm_set1_epi8('>'))),
10986
                   _mm_cmpeq_epi8(w, _mm_set1_epi8('\''))));
10987
  return _mm_movemask_epi8(_mm_or_si128(ctrl, spec));
10988
}
10989
10990
ada_really_inline int sse2_hash_stop(__m128i w) noexcept {
10991
  const __m128i ctrl = sse2_ctrl_or_nonascii(w);
10992
  const __m128i spec =
10993
      _mm_or_si128(_mm_or_si128(_mm_cmpeq_epi8(w, _mm_set1_epi8('"')),
10994
                                _mm_cmpeq_epi8(w, _mm_set1_epi8('<'))),
10995
                   _mm_or_si128(_mm_cmpeq_epi8(w, _mm_set1_epi8('>')),
10996
                                _mm_cmpeq_epi8(w, _mm_set1_epi8('`'))));
10997
  return _mm_movemask_epi8(_mm_or_si128(ctrl, spec));
10998
}
10999
#endif  // !ADA_PARSER_SSSE3
11000
11001
0
ada_really_inline int sse2_uppercase(__m128i w) noexcept {
11002
0
  return _mm_movemask_epi8(_mm_and_si128(
11003
0
      _mm_cmpgt_epi8(w, _mm_set1_epi8(static_cast<char>('A' - 1))),
11004
0
      _mm_cmplt_epi8(w, _mm_set1_epi8(static_cast<char>('Z' + 1)))));
11005
0
}
11006
#endif  // ADA_SSE2
11007
11008
#if ADA_NEON
11009
ada_really_inline uint64_t neon_nibble_bits(uint8x16_t matches) noexcept {
11010
  const uint8x8_t nib = vshrn_n_u16(vreinterpretq_u16_u8(matches), 4);
11011
  return vget_lane_u64(vreinterpret_u64_u8(nib), 0);
11012
}
11013
11014
ada_really_inline uint64_t neon_table_stop(uint8x16_t w, uint8x16_t lo_tbl,
11015
                                           uint8x16_t hi_tbl) noexcept {
11016
  const uint8x16_t hit =
11017
      vandq_u8(vqtbl1q_u8(lo_tbl, vandq_u8(w, vdupq_n_u8(0x0F))),
11018
               vqtbl1q_u8(hi_tbl, vshrq_n_u8(w, 4)));
11019
  return neon_nibble_bits(vtstq_u8(hit, hit));
11020
}
11021
11022
ada_really_inline uint64_t neon_uppercase(uint8x16_t w) noexcept {
11023
  return neon_nibble_bits(
11024
      vandq_u8(vcgeq_u8(w, vdupq_n_u8('A')), vcleq_u8(w, vdupq_n_u8('Z'))));
11025
}
11026
#endif  // ADA_NEON
11027
11028
// True when '@' appears in the authority before '/', '?', or '#'.
11029
// One 16-byte window covers typical userinfo (SetHref's "user:pass@").
11030
// Longer userinfo still misses inside the never_inline fast path. No
11031
// '@' is a single load + compare so the parse hot path stays cheap.
11032
ada_really_inline bool authority_has_at(const uint8_t* p, size_t host_start,
11033
0
                                        size_t n) noexcept {
11034
0
  const size_t rem = n - host_start;
11035
0
  if (rem == 0) {
11036
0
    return false;
11037
0
  }
11038
#if ADA_NEON
11039
  if (rem >= 16) {
11040
    const uint8x16_t w = vld1q_u8(p + host_start);
11041
    const uint64_t at = neon_nibble_bits(vceqq_u8(w, vdupq_n_u8('@')));
11042
    if (at == 0) {
11043
      return false;
11044
    }
11045
    const uint64_t delim = neon_nibble_bits(vceqq_u8(w, vdupq_n_u8('/'))) |
11046
                           neon_nibble_bits(vceqq_u8(w, vdupq_n_u8('?'))) |
11047
                           neon_nibble_bits(vceqq_u8(w, vdupq_n_u8('#')));
11048
    return delim == 0 || std::countr_zero(at) < std::countr_zero(delim);
11049
  }
11050
#elif ADA_SSE2
11051
0
  if (rem >= 16) {
11052
0
    const __m128i w =
11053
0
        _mm_loadu_si128(reinterpret_cast<const __m128i*>(p + host_start));
11054
0
    const uint16_t at = static_cast<uint16_t>(
11055
0
        _mm_movemask_epi8(_mm_cmpeq_epi8(w, _mm_set1_epi8('@'))));
11056
0
    if (at == 0) {
11057
0
      return false;
11058
0
    }
11059
0
    const uint16_t delim = static_cast<uint16_t>(
11060
0
        _mm_movemask_epi8(_mm_cmpeq_epi8(w, _mm_set1_epi8('/'))) |
11061
0
        _mm_movemask_epi8(_mm_cmpeq_epi8(w, _mm_set1_epi8('?'))) |
11062
0
        _mm_movemask_epi8(_mm_cmpeq_epi8(w, _mm_set1_epi8('#'))));
11063
0
    return delim == 0 || std::countr_zero(at) < std::countr_zero(delim);
11064
0
  }
11065
0
#endif
11066
0
  const size_t lim = host_start + rem;
11067
0
  for (size_t i = host_start; i < lim; ++i) {
11068
0
    const uint8_t c = p[i];
11069
0
    if (c == '@') {
11070
0
      return true;
11071
0
    }
11072
0
    if (c == '/' || c == '?' || c == '#') {
11073
0
      return false;
11074
0
    }
11075
0
  }
11076
0
  return false;
11077
0
}
11078
11079
// Returns false if a forbidden host code point is found. On success, *end is
11080
// the first / ? # or len. has_upper / has_x only count host bytes, not the
11081
// path/query bytes that may sit in the same SIMD window after the delimiter.
11082
ADA_PARSER_SIMD bool scan_plain_host(const uint8_t* b, size_t start, size_t len,
11083
                                     size_t& end, bool& has_upper,
11084
0
                                     bool& has_x) noexcept {
11085
0
  has_upper = false;
11086
0
  has_x = false;
11087
0
  size_t i = start;
11088
0
#if ADA_PARSER_SSSE3
11089
0
  if (len - start >= 16) {
11090
0
    const __m128i lo_tbl = nibble_load(k_host_nibbles.low);
11091
0
    const __m128i hi_tbl = nibble_load(k_host_nibbles.high);
11092
0
    const __m128i x_splat = _mm_set1_epi8('x');
11093
0
    auto visit = [&](size_t at) noexcept -> bool {
11094
0
      const __m128i w =
11095
0
          _mm_loadu_si128(reinterpret_cast<const __m128i*>(b + at));
11096
0
      const int up = sse2_uppercase(w);
11097
0
      const int xs = _mm_movemask_epi8(_mm_cmpeq_epi8(w, x_splat));
11098
0
      const int mask = ssse3_nibble_mask(w, lo_tbl, hi_tbl);
11099
0
      if (mask == 0) {
11100
0
        if (up != 0) {
11101
0
          has_upper = true;
11102
0
        }
11103
0
        if (xs != 0) {
11104
0
          has_x = true;
11105
0
        }
11106
0
        return false;
11107
0
      }
11108
0
      const int hit = trailing_zeroes32(static_cast<uint32_t>(mask));
11109
0
      const int valid = (1 << hit) - 1;
11110
0
      if ((up & valid) != 0) {
11111
0
        has_upper = true;
11112
0
      }
11113
0
      if ((xs & valid) != 0) {
11114
0
        has_x = true;
11115
0
      }
11116
0
      end = at + static_cast<size_t>(hit);
11117
0
      return true;
11118
0
    };
11119
0
    for (; i + 32 <= len; i += 32) {
11120
0
      if (visit(i) || visit(i + 16)) {
11121
0
        return k_host_class[b[end]] == 1;
11122
0
      }
11123
0
    }
11124
0
    for (; i + 16 <= len; i += 16) {
11125
0
      if (visit(i)) {
11126
0
        return k_host_class[b[end]] == 1;
11127
0
      }
11128
0
    }
11129
    // Overlapping tail only after a full 16-byte step so the window cannot
11130
    // start before `start` (a prior '/' would otherwise look like a host stop).
11131
0
    if (i > start && i < len) {
11132
0
      if (visit(len - 16) && end >= i) {
11133
0
        return k_host_class[b[end]] == 1;
11134
0
      }
11135
0
      end = len;
11136
0
      return true;
11137
0
    }
11138
0
  }
11139
#elif ADA_SSE2
11140
  const __m128i x_splat = _mm_set1_epi8('x');
11141
  for (; i + 32 <= len; i += 32) {
11142
    for (size_t off = 0; off < 32; off += 16) {
11143
      const __m128i w =
11144
          _mm_loadu_si128(reinterpret_cast<const __m128i*>(b + i + off));
11145
      const int up = sse2_uppercase(w);
11146
      const int xs = _mm_movemask_epi8(_mm_cmpeq_epi8(w, x_splat));
11147
      const int mask = sse2_host_stop(w);
11148
      if (mask != 0) {
11149
        const int hit = trailing_zeroes32(static_cast<uint32_t>(mask));
11150
        const int valid = (1 << hit) - 1;
11151
        if ((up & valid) != 0) {
11152
          has_upper = true;
11153
        }
11154
        if ((xs & valid) != 0) {
11155
          has_x = true;
11156
        }
11157
        end = i + off + static_cast<size_t>(hit);
11158
        return k_host_class[b[end]] == 1;
11159
      }
11160
      if (up != 0) {
11161
        has_upper = true;
11162
      }
11163
      if (xs != 0) {
11164
        has_x = true;
11165
      }
11166
    }
11167
  }
11168
  for (; i + 16 <= len; i += 16) {
11169
    const __m128i w = _mm_loadu_si128(reinterpret_cast<const __m128i*>(b + i));
11170
    const int up = sse2_uppercase(w);
11171
    const int xs = _mm_movemask_epi8(_mm_cmpeq_epi8(w, x_splat));
11172
    const int mask = sse2_host_stop(w);
11173
    if (mask != 0) {
11174
      const int hit = trailing_zeroes32(static_cast<uint32_t>(mask));
11175
      const int valid = (1 << hit) - 1;
11176
      if ((up & valid) != 0) {
11177
        has_upper = true;
11178
      }
11179
      if ((xs & valid) != 0) {
11180
        has_x = true;
11181
      }
11182
      end = i + static_cast<size_t>(hit);
11183
      return k_host_class[b[end]] == 1;
11184
    }
11185
    if (up != 0) {
11186
      has_upper = true;
11187
    }
11188
    if (xs != 0) {
11189
      has_x = true;
11190
    }
11191
  }
11192
#elif ADA_NEON
11193
  if (len - start >= 16) {
11194
    const uint8x16_t lo_tbl = vld1q_u8(k_host_nibbles.low);
11195
    const uint8x16_t hi_tbl = vld1q_u8(k_host_nibbles.high);
11196
    const uint8x16_t x_splat = vdupq_n_u8('x');
11197
    auto visit = [&](size_t at) noexcept -> bool {
11198
      const uint8x16_t w = vld1q_u8(b + at);
11199
      const uint64_t up = neon_uppercase(w);
11200
      const uint64_t xs = neon_nibble_bits(vceqq_u8(w, x_splat));
11201
      const uint64_t bits = neon_table_stop(w, lo_tbl, hi_tbl);
11202
      if (bits == 0) {
11203
        if (up != 0) {
11204
          has_upper = true;
11205
        }
11206
        if (xs != 0) {
11207
          has_x = true;
11208
        }
11209
        return false;
11210
      }
11211
      const size_t hit = static_cast<size_t>(trailing_zeroes64(bits)) >> 2;
11212
      const uint64_t valid = (hit == 0) ? 0 : (uint64_t{1} << (hit * 4)) - 1;
11213
      if ((up & valid) != 0) {
11214
        has_upper = true;
11215
      }
11216
      if ((xs & valid) != 0) {
11217
        has_x = true;
11218
      }
11219
      end = at + hit;
11220
      return true;
11221
    };
11222
    for (; i + 32 <= len; i += 32) {
11223
      if (visit(i) || visit(i + 16)) {
11224
        return k_host_class[b[end]] == 1;
11225
      }
11226
    }
11227
    for (; i + 16 <= len; i += 16) {
11228
      if (visit(i)) {
11229
        return k_host_class[b[end]] == 1;
11230
      }
11231
    }
11232
    if (i > start && i < len) {
11233
      if (visit(len - 16) && end >= i) {
11234
        return k_host_class[b[end]] == 1;
11235
      }
11236
      end = len;
11237
      return true;
11238
    }
11239
  }
11240
#endif
11241
0
  for (; i < len; ++i) {
11242
0
    const uint8_t c = b[i];
11243
0
    const uint8_t cls = k_host_class[c];
11244
0
    if (cls == 1) {
11245
0
      end = i;
11246
0
      return true;
11247
0
    }
11248
0
    if (cls == 2) {
11249
0
      return false;
11250
0
    }
11251
0
    if (c >= 'A' && c <= 'Z') {
11252
0
      has_upper = true;
11253
0
    } else if (c == 'x') {
11254
0
      has_x = true;
11255
0
    }
11256
0
  }
11257
0
  end = len;
11258
0
  return true;
11259
0
}
11260
11261
ada_really_inline void note_possible_dot_segment(
11262
    const uint8_t* b, size_t pos, size_t run_start,
11263
0
    bool& maybe_dot_segment) noexcept {
11264
0
  if (pos == run_start || b[pos - 1] == '/') {
11265
0
    maybe_dot_segment = true;
11266
0
  }
11267
0
}
11268
11269
#if ADA_PARSER_SSSE3 || ADA_SSE2
11270
// valid_mask selects bytes in this 16-byte window that belong to the path
11271
// (bits after a stop are cleared). A '.' starts a possible dot-segment when
11272
// it is the first path byte or immediately follows '/'.
11273
ada_really_inline void note_dots_in_window(const uint8_t* b, size_t i,
11274
                                           size_t run_start, __m128i w,
11275
                                           int valid_mask,
11276
0
                                           bool& maybe_dot_segment) noexcept {
11277
0
  if (maybe_dot_segment || valid_mask == 0) {
11278
0
    return;
11279
0
  }
11280
0
  const int dots =
11281
0
      _mm_movemask_epi8(_mm_cmpeq_epi8(w, _mm_set1_epi8('.'))) & valid_mask;
11282
0
  if (dots == 0) {
11283
0
    return;
11284
0
  }
11285
0
  const int slashes =
11286
0
      _mm_movemask_epi8(_mm_cmpeq_epi8(w, _mm_set1_epi8('/'))) & valid_mask;
11287
0
  if (((dots & 1) != 0 && (i == run_start || b[i - 1] == '/')) ||
11288
0
      (dots & (slashes << 1)) != 0) {
11289
0
    maybe_dot_segment = true;
11290
0
  }
11291
0
}
11292
#endif
11293
11294
#if ADA_NEON
11295
// Each NEON match nibble occupies 4 bits, so a '.' immediately after '/' is
11296
// (slashes << 4) rather than (slashes << 1).
11297
ada_really_inline void note_dots_in_window_neon(
11298
    const uint8_t* b, size_t i, size_t run_start, uint8x16_t w,
11299
    uint64_t valid_bits, bool& maybe_dot_segment) noexcept {
11300
  if (maybe_dot_segment || valid_bits == 0) {
11301
    return;
11302
  }
11303
  const uint64_t dots =
11304
      neon_nibble_bits(vceqq_u8(w, vdupq_n_u8('.'))) & valid_bits;
11305
  if (dots == 0) {
11306
    return;
11307
  }
11308
  const uint64_t slashes =
11309
      neon_nibble_bits(vceqq_u8(w, vdupq_n_u8('/'))) & valid_bits;
11310
  if (((dots & 0xF) != 0 && (i == run_start || b[i - 1] == '/')) ||
11311
      (dots & (slashes << 4)) != 0) {
11312
    maybe_dot_segment = true;
11313
  }
11314
}
11315
#endif
11316
11317
// Advance i to the first path-class 1 or 2 character (or len).
11318
ADA_PARSER_SIMD void scan_path_run(const uint8_t* b, size_t& i, size_t len,
11319
0
                                   bool& maybe_dot_segment) noexcept {
11320
0
  const size_t run_start = i;
11321
0
#if ADA_PARSER_SSSE3
11322
0
  if (i + 16 <= len) {
11323
0
    const __m128i lo_tbl = nibble_load(k_path_nibbles.low);
11324
0
    const __m128i hi_tbl = nibble_load(k_path_nibbles.high);
11325
0
    for (; i + 32 <= len; i += 32) {
11326
0
      const __m128i w0 =
11327
0
          _mm_loadu_si128(reinterpret_cast<const __m128i*>(b + i));
11328
0
      const int m0 = ssse3_nibble_mask(w0, lo_tbl, hi_tbl);
11329
0
      if (m0 != 0) {
11330
0
        const int hit_bit = trailing_zeroes32(static_cast<uint32_t>(m0));
11331
0
        note_dots_in_window(b, i, run_start, w0, (1 << hit_bit) - 1,
11332
0
                            maybe_dot_segment);
11333
0
        i += static_cast<size_t>(hit_bit);
11334
0
        return;
11335
0
      }
11336
0
      note_dots_in_window(b, i, run_start, w0, 0xFFFF, maybe_dot_segment);
11337
0
      const __m128i w1 =
11338
0
          _mm_loadu_si128(reinterpret_cast<const __m128i*>(b + i + 16));
11339
0
      const int m1 = ssse3_nibble_mask(w1, lo_tbl, hi_tbl);
11340
0
      if (m1 != 0) {
11341
0
        const int hit_bit = trailing_zeroes32(static_cast<uint32_t>(m1));
11342
0
        note_dots_in_window(b, i + 16, run_start, w1, (1 << hit_bit) - 1,
11343
0
                            maybe_dot_segment);
11344
0
        i += 16 + static_cast<size_t>(hit_bit);
11345
0
        return;
11346
0
      }
11347
0
      note_dots_in_window(b, i + 16, run_start, w1, 0xFFFF, maybe_dot_segment);
11348
0
    }
11349
0
    for (; i + 16 <= len; i += 16) {
11350
0
      const __m128i w =
11351
0
          _mm_loadu_si128(reinterpret_cast<const __m128i*>(b + i));
11352
0
      const int mask = ssse3_nibble_mask(w, lo_tbl, hi_tbl);
11353
0
      if (mask != 0) {
11354
0
        const int hit_bit = trailing_zeroes32(static_cast<uint32_t>(mask));
11355
0
        note_dots_in_window(b, i, run_start, w, (1 << hit_bit) - 1,
11356
0
                            maybe_dot_segment);
11357
0
        i += static_cast<size_t>(hit_bit);
11358
0
        return;
11359
0
      }
11360
0
      note_dots_in_window(b, i, run_start, w, 0xFFFF, maybe_dot_segment);
11361
0
    }
11362
0
    if (i > run_start && i < len) {
11363
0
      const __m128i w =
11364
0
          _mm_loadu_si128(reinterpret_cast<const __m128i*>(b + len - 16));
11365
0
      const int mask = ssse3_nibble_mask(w, lo_tbl, hi_tbl);
11366
0
      if (mask != 0) {
11367
0
        const size_t hit =
11368
0
            len - 16 +
11369
0
            static_cast<size_t>(trailing_zeroes32(static_cast<uint32_t>(mask)));
11370
0
        if (hit >= i) {
11371
0
          for (size_t j = i; j < hit; ++j) {
11372
0
            if (b[j] == '.') {
11373
0
              note_possible_dot_segment(b, j, run_start, maybe_dot_segment);
11374
0
            }
11375
0
          }
11376
0
          i = hit;
11377
0
          return;
11378
0
        }
11379
0
      }
11380
0
      for (size_t j = i; j < len; ++j) {
11381
0
        if (b[j] == '.') {
11382
0
          note_possible_dot_segment(b, j, run_start, maybe_dot_segment);
11383
0
        }
11384
0
      }
11385
0
      i = len;
11386
0
      return;
11387
0
    }
11388
0
  }
11389
#elif ADA_SSE2
11390
  for (; i + 16 <= len; i += 16) {
11391
    const __m128i w = _mm_loadu_si128(reinterpret_cast<const __m128i*>(b + i));
11392
    const int mask = sse2_path_stop(w);
11393
    if (mask != 0) {
11394
      const int hit_bit = trailing_zeroes32(static_cast<uint32_t>(mask));
11395
      note_dots_in_window(b, i, run_start, w, (1 << hit_bit) - 1,
11396
                          maybe_dot_segment);
11397
      i += static_cast<size_t>(hit_bit);
11398
      return;
11399
    }
11400
    note_dots_in_window(b, i, run_start, w, 0xFFFF, maybe_dot_segment);
11401
  }
11402
#elif ADA_NEON
11403
  if (i + 16 <= len) {
11404
    const uint8x16_t lo_tbl = vld1q_u8(k_path_nibbles.low);
11405
    const uint8x16_t hi_tbl = vld1q_u8(k_path_nibbles.high);
11406
    for (; i + 32 <= len; i += 32) {
11407
      const uint8x16_t w0 = vld1q_u8(b + i);
11408
      const uint64_t bits0 = neon_table_stop(w0, lo_tbl, hi_tbl);
11409
      if (bits0 != 0) {
11410
        const size_t hit_off =
11411
            static_cast<size_t>(trailing_zeroes64(bits0)) >> 2;
11412
        const uint64_t valid =
11413
            (hit_off == 0) ? 0 : (uint64_t{1} << (hit_off * 4)) - 1;
11414
        note_dots_in_window_neon(b, i, run_start, w0, valid, maybe_dot_segment);
11415
        i += hit_off;
11416
        return;
11417
      }
11418
      note_dots_in_window_neon(b, i, run_start, w0, ~uint64_t{0},
11419
                               maybe_dot_segment);
11420
      const uint8x16_t w1 = vld1q_u8(b + i + 16);
11421
      const uint64_t bits1 = neon_table_stop(w1, lo_tbl, hi_tbl);
11422
      if (bits1 != 0) {
11423
        const size_t hit_off =
11424
            static_cast<size_t>(trailing_zeroes64(bits1)) >> 2;
11425
        const uint64_t valid =
11426
            (hit_off == 0) ? 0 : (uint64_t{1} << (hit_off * 4)) - 1;
11427
        note_dots_in_window_neon(b, i + 16, run_start, w1, valid,
11428
                                 maybe_dot_segment);
11429
        i += 16 + hit_off;
11430
        return;
11431
      }
11432
      note_dots_in_window_neon(b, i + 16, run_start, w1, ~uint64_t{0},
11433
                               maybe_dot_segment);
11434
    }
11435
    for (; i + 16 <= len; i += 16) {
11436
      const uint8x16_t w = vld1q_u8(b + i);
11437
      const uint64_t bits = neon_table_stop(w, lo_tbl, hi_tbl);
11438
      if (bits != 0) {
11439
        const size_t hit_off =
11440
            static_cast<size_t>(trailing_zeroes64(bits)) >> 2;
11441
        const uint64_t valid =
11442
            (hit_off == 0) ? 0 : (uint64_t{1} << (hit_off * 4)) - 1;
11443
        note_dots_in_window_neon(b, i, run_start, w, valid, maybe_dot_segment);
11444
        i += hit_off;
11445
        return;
11446
      }
11447
      note_dots_in_window_neon(b, i, run_start, w, ~uint64_t{0},
11448
                               maybe_dot_segment);
11449
    }
11450
    if (i > run_start && i < len) {
11451
      const uint8x16_t w = vld1q_u8(b + len - 16);
11452
      const uint64_t bits = neon_table_stop(w, lo_tbl, hi_tbl);
11453
      if (bits != 0) {
11454
        const size_t hit =
11455
            len - 16 + (static_cast<size_t>(trailing_zeroes64(bits)) >> 2);
11456
        if (hit >= i) {
11457
          for (size_t j = i; j < hit; ++j) {
11458
            if (b[j] == '.') {
11459
              note_possible_dot_segment(b, j, run_start, maybe_dot_segment);
11460
            }
11461
          }
11462
          i = hit;
11463
          return;
11464
        }
11465
      }
11466
      for (size_t j = i; j < len; ++j) {
11467
        if (b[j] == '.') {
11468
          note_possible_dot_segment(b, j, run_start, maybe_dot_segment);
11469
        }
11470
      }
11471
      i = len;
11472
      return;
11473
    }
11474
  }
11475
#endif
11476
0
  for (; i < len; ++i) {
11477
0
    const uint8_t c = b[i];
11478
0
    const uint8_t cls = k_path[c];
11479
0
    if (cls != 0) {
11480
0
      return;
11481
0
    }
11482
0
    if (c == '.') {
11483
0
      note_possible_dot_segment(b, i, run_start, maybe_dot_segment);
11484
0
    }
11485
0
  }
11486
0
}
11487
11488
// Advance i to the first class-table stop (or len). Query and hash share
11489
// this loop; path keeps its own copy because it also tracks '.' segments.
11490
#if ADA_PARSER_SSSE3
11491
#define ADA_SCAN_STOP_RUN(nibbles, cls, unused_sse2_stop)                    \
11492
0
  do {                                                                       \
11493
0
    const size_t scan_start = i;                                             \
11494
0
    if (i + 16 <= len) {                                                     \
11495
0
      const __m128i lo_tbl = nibble_load((nibbles).low);                     \
11496
0
      const __m128i hi_tbl = nibble_load((nibbles).high);                    \
11497
0
      for (; i + 32 <= len; i += 32) {                                       \
11498
0
        const __m128i w0 =                                                   \
11499
0
            _mm_loadu_si128(reinterpret_cast<const __m128i*>(b + i));        \
11500
0
        const int m0 = ssse3_nibble_mask(w0, lo_tbl, hi_tbl);                \
11501
0
        if (m0 != 0) {                                                       \
11502
0
          i += static_cast<size_t>(                                          \
11503
0
              trailing_zeroes32(static_cast<uint32_t>(m0)));                 \
11504
0
          return;                                                            \
11505
0
        }                                                                    \
11506
0
        const __m128i w1 =                                                   \
11507
0
            _mm_loadu_si128(reinterpret_cast<const __m128i*>(b + i + 16));   \
11508
0
        const int m1 = ssse3_nibble_mask(w1, lo_tbl, hi_tbl);                \
11509
0
        if (m1 != 0) {                                                       \
11510
0
          i += 16 + static_cast<size_t>(                                     \
11511
0
                        trailing_zeroes32(static_cast<uint32_t>(m1)));       \
11512
0
          return;                                                            \
11513
0
        }                                                                    \
11514
0
      }                                                                      \
11515
0
      for (; i + 16 <= len; i += 16) {                                       \
11516
0
        const __m128i w =                                                    \
11517
0
            _mm_loadu_si128(reinterpret_cast<const __m128i*>(b + i));        \
11518
0
        const int mask = ssse3_nibble_mask(w, lo_tbl, hi_tbl);               \
11519
0
        if (mask != 0) {                                                     \
11520
0
          i += static_cast<size_t>(                                          \
11521
0
              trailing_zeroes32(static_cast<uint32_t>(mask)));               \
11522
0
          return;                                                            \
11523
0
        }                                                                    \
11524
0
      }                                                                      \
11525
0
      if (i > scan_start && i < len) {                                       \
11526
0
        const __m128i w =                                                    \
11527
0
            _mm_loadu_si128(reinterpret_cast<const __m128i*>(b + len - 16)); \
11528
0
        const int mask = ssse3_nibble_mask(w, lo_tbl, hi_tbl);               \
11529
0
        if (mask != 0) {                                                     \
11530
0
          const size_t hit = len - 16 +                                      \
11531
0
                             static_cast<size_t>(trailing_zeroes32(          \
11532
0
                                 static_cast<uint32_t>(mask)));              \
11533
0
          if (hit >= i) {                                                    \
11534
0
            i = hit;                                                         \
11535
0
            return;                                                          \
11536
0
          }                                                                  \
11537
0
        }                                                                    \
11538
0
        i = len;                                                             \
11539
0
        return;                                                              \
11540
0
      }                                                                      \
11541
0
    }                                                                        \
11542
0
    for (; i < len; ++i) {                                                   \
11543
0
      if ((cls)[b[i]] != 0) {                                                \
11544
0
        return;                                                              \
11545
0
      }                                                                      \
11546
0
    }                                                                        \
11547
0
  } while (0)
11548
#elif ADA_NEON
11549
#define ADA_SCAN_STOP_RUN(nibbles, cls, unused_sse2_stop)                     \
11550
  do {                                                                        \
11551
    const size_t scan_start = i;                                              \
11552
    if (i + 16 <= len) {                                                      \
11553
      const uint8x16_t lo_tbl = vld1q_u8((nibbles).low);                      \
11554
      const uint8x16_t hi_tbl = vld1q_u8((nibbles).high);                     \
11555
      for (; i + 32 <= len; i += 32) {                                        \
11556
        const uint64_t bits0 =                                                \
11557
            neon_table_stop(vld1q_u8(b + i), lo_tbl, hi_tbl);                 \
11558
        if (bits0 != 0) {                                                     \
11559
          i += static_cast<size_t>(trailing_zeroes64(bits0)) >> 2;            \
11560
          return;                                                             \
11561
        }                                                                     \
11562
        const uint64_t bits1 =                                                \
11563
            neon_table_stop(vld1q_u8(b + i + 16), lo_tbl, hi_tbl);            \
11564
        if (bits1 != 0) {                                                     \
11565
          i += 16 + (static_cast<size_t>(trailing_zeroes64(bits1)) >> 2);     \
11566
          return;                                                             \
11567
        }                                                                     \
11568
      }                                                                       \
11569
      for (; i + 16 <= len; i += 16) {                                        \
11570
        const uint8x16_t w = vld1q_u8(b + i);                                 \
11571
        const uint64_t bits = neon_table_stop(w, lo_tbl, hi_tbl);             \
11572
        if (bits != 0) {                                                      \
11573
          i += static_cast<size_t>(trailing_zeroes64(bits)) >> 2;             \
11574
          return;                                                             \
11575
        }                                                                     \
11576
      }                                                                       \
11577
      if (i > scan_start && i < len) {                                        \
11578
        const uint8x16_t w = vld1q_u8(b + len - 16);                          \
11579
        const uint64_t bits = neon_table_stop(w, lo_tbl, hi_tbl);             \
11580
        if (bits != 0) {                                                      \
11581
          const size_t hit =                                                  \
11582
              len - 16 + (static_cast<size_t>(trailing_zeroes64(bits)) >> 2); \
11583
          if (hit >= i) {                                                     \
11584
            i = hit;                                                          \
11585
            return;                                                           \
11586
          }                                                                   \
11587
        }                                                                     \
11588
        i = len;                                                              \
11589
        return;                                                               \
11590
      }                                                                       \
11591
    }                                                                         \
11592
    for (; i < len; ++i) {                                                    \
11593
      if ((cls)[b[i]] != 0) {                                                 \
11594
        return;                                                               \
11595
      }                                                                       \
11596
    }                                                                         \
11597
  } while (0)
11598
#elif ADA_SSE2
11599
#define ADA_SCAN_STOP_RUN(nibbles, cls, sse2_stop)                  \
11600
  do {                                                              \
11601
    for (; i + 16 <= len; i += 16) {                                \
11602
      const __m128i w =                                             \
11603
          _mm_loadu_si128(reinterpret_cast<const __m128i*>(b + i)); \
11604
      const int mask = sse2_stop(w);                                \
11605
      if (mask != 0) {                                              \
11606
        i += static_cast<size_t>(                                   \
11607
            trailing_zeroes32(static_cast<uint32_t>(mask)));        \
11608
        return;                                                     \
11609
      }                                                             \
11610
    }                                                               \
11611
    for (; i < len; ++i) {                                          \
11612
      if ((cls)[b[i]] != 0) {                                       \
11613
        return;                                                     \
11614
      }                                                             \
11615
    }                                                               \
11616
  } while (0)
11617
#else
11618
#define ADA_SCAN_STOP_RUN(nibbles, cls, unused_sse2_stop) \
11619
  do {                                                    \
11620
    for (; i < len; ++i) {                                \
11621
      if ((cls)[b[i]] != 0) {                             \
11622
        return;                                           \
11623
      }                                                   \
11624
    }                                                     \
11625
  } while (0)
11626
#endif
11627
11628
ADA_PARSER_SIMD void scan_query_run(const uint8_t* b, size_t& i,
11629
0
                                    size_t len) noexcept {
11630
0
  ADA_SCAN_STOP_RUN(k_query_nibbles, k_query, sse2_query_stop);
11631
0
}
11632
11633
ADA_PARSER_SIMD void scan_hash_run(const uint8_t* b, size_t& i,
11634
0
                                   size_t len) noexcept {
11635
0
  ADA_SCAN_STOP_RUN(k_hash_nibbles, k_hash, sse2_hash_stop);
11636
0
}
11637
11638
#undef ADA_SCAN_STOP_RUN
11639
11640
0
bool path_has_dot_segment(std::string_view path) noexcept {
11641
0
  if (path.empty()) {
11642
0
    return false;
11643
0
  }
11644
  // "." / ".." at the start, with or without a leading '/'.
11645
0
  const size_t i = (path[0] == '/') ? 1 : 0;
11646
0
  if (i < path.size() && path[i] == '.') {
11647
0
    const size_t after = i + 1;
11648
0
    if (after == path.size() || path[after] == '/' ||
11649
0
        (after < path.size() && path[after] == '.' &&
11650
0
         (after + 1 == path.size() || path[after + 1] == '/'))) {
11651
0
      return true;
11652
0
    }
11653
0
  }
11654
0
  static constexpr std::string_view slash_dot{"/.", 2};
11655
0
  size_t p = i;
11656
0
  while ((p = path.find(slash_dot, p)) != std::string_view::npos) {
11657
0
    const size_t after = p + 2;
11658
0
    if (after == path.size() || path[after] == '/' ||
11659
0
        (after < path.size() && path[after] == '.' &&
11660
0
         (after + 1 == path.size() || path[after + 1] == '/'))) {
11661
0
      return true;
11662
0
    }
11663
0
    p = after;
11664
0
  }
11665
0
  return false;
11666
0
}
11667
11668
}  // namespace
11669
11670
template <class result_type>
11671
ada_never_inline bool finish_simple_absolute_with_port(
11672
    std::string_view input, result_type& out, ada::scheme::type scheme_type,
11673
    uint32_t protocol_end, size_t host_start, size_t host_end, size_t host_len,
11674
0
    bool has_upper) {
11675
0
  constexpr bool is_ada_url = std::is_same_v<result_type, ada::url>;
11676
0
  constexpr bool is_aggregator =
11677
0
      std::is_same_v<result_type, ada::url_aggregator>;
11678
0
  static_assert(is_ada_url || is_aggregator);
11679
11680
0
  const size_t len = input.size();
11681
0
  const auto* b = reinterpret_cast<const uint8_t*>(input.data());
11682
0
  size_t p = host_end + 1;
11683
0
  uint32_t port_value = 0;
11684
0
  bool any_digit = false;
11685
0
  while (p < len && b[p] >= '0' && b[p] <= '9') {
11686
0
    any_digit = true;
11687
0
    port_value = port_value * 10 + static_cast<uint32_t>(b[p] - '0');
11688
0
    if (port_value > 65535) [[unlikely]] {
11689
0
      return false;
11690
0
    }
11691
0
    ++p;
11692
0
  }
11693
0
  if (p < len && b[p] != '/' && b[p] != '?' && b[p] != '#') [[unlikely]] {
11694
0
    return false;
11695
0
  }
11696
0
  uint32_t parsed_port = url_components::omitted;
11697
0
  const uint16_t default_port = ada::scheme::get_special_port(scheme_type);
11698
0
  if (any_digit && port_value != default_port) {
11699
0
    parsed_port = port_value;
11700
0
  }
11701
0
  const size_t authority_end = p;
11702
11703
0
  size_t i = authority_end;
11704
0
  size_t path_start = host_end;
11705
0
  size_t path_end = host_end;
11706
0
  size_t query_start = std::string_view::npos;
11707
0
  size_t hash_start = std::string_view::npos;
11708
0
  bool has_path = false;
11709
0
  bool maybe_dot_segment = false;
11710
0
  bool rest_simple = true;
11711
11712
0
  if (i < len && b[i] == '/') {
11713
0
    has_path = true;
11714
0
    path_start = i;
11715
0
    ++i;
11716
0
    scan_path_run(b, i, len, maybe_dot_segment);
11717
0
    if (i < len) {
11718
0
      const uint8_t cls = k_path[b[i]];
11719
0
      if (cls == 1) {
11720
0
        path_end = i;
11721
0
        if (b[i] == '?') {
11722
0
          query_start = i;
11723
0
          ++i;
11724
0
          goto scan_query;
11725
0
        }
11726
0
        hash_start = i;
11727
0
        ++i;
11728
0
        goto scan_hash;
11729
0
      }
11730
0
      rest_simple = false;
11731
0
      for (; i < len; ++i) {
11732
0
        if (b[i] == '?') {
11733
0
          path_end = i;
11734
0
          query_start = i;
11735
0
          ++i;
11736
0
          goto scan_query_boundary;
11737
0
        }
11738
0
        if (b[i] == '#') {
11739
0
          path_end = i;
11740
0
          hash_start = i;
11741
0
          ++i;
11742
0
          goto after_rest;
11743
0
        }
11744
0
      }
11745
0
      path_end = i;
11746
0
      goto after_rest;
11747
0
    }
11748
0
    path_end = i;
11749
0
  } else if (i < len && b[i] == '?') {
11750
0
    query_start = i;
11751
0
    ++i;
11752
0
    goto scan_query;
11753
0
  } else if (i < len && b[i] == '#') {
11754
0
    hash_start = i;
11755
0
    ++i;
11756
0
    goto scan_hash;
11757
0
  }
11758
0
  goto after_rest;
11759
11760
0
scan_query:
11761
0
  scan_query_run(b, i, len);
11762
0
  if (i < len) {
11763
0
    if (b[i] == '#') {
11764
0
      hash_start = i;
11765
0
      ++i;
11766
0
      goto scan_hash;
11767
0
    }
11768
0
    rest_simple = false;
11769
0
    goto scan_query_boundary;
11770
0
  }
11771
0
  goto after_rest;
11772
11773
0
scan_query_boundary:
11774
0
  for (; i < len; ++i) {
11775
0
    if (b[i] == '#') {
11776
0
      hash_start = i;
11777
0
      ++i;
11778
0
      goto after_rest;
11779
0
    }
11780
0
  }
11781
0
  goto after_rest;
11782
11783
0
scan_hash:
11784
0
  scan_hash_run(b, i, len);
11785
0
  if (i < len) {
11786
0
    rest_simple = false;
11787
0
  }
11788
11789
0
after_rest:
11790
0
  if (rest_simple && maybe_dot_segment) {
11791
0
    const std::string_view path_body(input.data() + path_start,
11792
0
                                     path_end - path_start);
11793
0
    if (path_has_dot_segment(path_body)) {
11794
0
      rest_simple = false;
11795
0
    }
11796
0
  }
11797
11798
  // The slow path removes ASCII tab/newline anywhere in the input and trims a
11799
  // trailing C0 control or space; this fast path does neither. A query or
11800
  // fragment reaching the helpers below would keep those bytes percent-encoded
11801
  // ("?a\nb" -> "?a%0Ab", "#f " -> "#f%20") instead of stripped, so hand such
11802
  // inputs back to the slow path.
11803
0
  if (!rest_simple && (unicode::is_c0_control_or_space(input.back()) ||
11804
0
                       unicode::has_tabs_or_newline(input))) {
11805
0
    return false;
11806
0
  }
11807
11808
0
  out.type = scheme_type;
11809
0
  out.is_valid = true;
11810
0
  out.has_opaque_path = false;
11811
0
  out.host_type = DEFAULT;
11812
11813
0
  const uint32_t port_bytes = (parsed_port != url_components::omitted)
11814
0
                                  ? (1 + port_decimal_digit_count(parsed_port))
11815
0
                                  : 0;
11816
11817
0
  if (!rest_simple) {
11818
0
    const std::string_view path_view =
11819
0
        has_path
11820
0
            ? std::string_view(input.data() + path_start, path_end - path_start)
11821
0
            : std::string_view{};
11822
0
    auto apply_query_and_hash = [&]() {
11823
0
      if (query_start != std::string_view::npos) {
11824
0
        const size_t q_end =
11825
0
            (hash_start != std::string_view::npos) ? hash_start : len;
11826
0
        out.update_base_search(std::string_view(input.data() + query_start + 1,
11827
0
                                                q_end - query_start - 1),
11828
0
                               character_sets::SPECIAL_QUERY_PERCENT_ENCODE);
11829
0
      }
11830
0
      if (hash_start != std::string_view::npos) {
11831
0
        out.update_unencoded_base_hash(std::string_view(
11832
0
            input.data() + hash_start + 1, len - hash_start - 1));
11833
0
      }
11834
0
    };
Unexecuted instantiation: ada::parser::finish_simple_absolute_with_port<ada::url>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url&, ada::scheme::type, unsigned int, unsigned long, unsigned long, unsigned long, bool)::{lambda()#1}::operator()() const
Unexecuted instantiation: ada::parser::finish_simple_absolute_with_port<ada::url_aggregator>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url_aggregator&, ada::scheme::type, unsigned int, unsigned long, unsigned long, unsigned long, bool)::{lambda()#1}::operator()() const
11835
0
    if constexpr (is_aggregator) {
11836
0
      out.buffer.assign(input.substr(0, host_end));
11837
0
      if (parsed_port != url_components::omitted) {
11838
0
        append_canonical_port(out.buffer, parsed_port);
11839
0
      }
11840
0
      if (has_upper) {
11841
0
        unicode::to_lower_ascii(out.buffer.data() + host_start, host_len);
11842
0
      }
11843
0
      out.components.protocol_end = protocol_end;
11844
0
      out.components.username_end = protocol_end + 2;
11845
0
      out.components.host_start = protocol_end + 2;
11846
0
      out.components.host_end = static_cast<uint32_t>(host_end);
11847
0
      out.components.port = parsed_port;
11848
0
      out.components.pathname_start = static_cast<uint32_t>(out.buffer.size());
11849
0
      out.components.search_start = url_components::omitted;
11850
0
      out.components.hash_start = url_components::omitted;
11851
0
      out.parse_path(path_view);
11852
0
      apply_query_and_hash();
11853
0
    } else {
11854
0
      std::string host_str(input.substr(host_start, host_len));
11855
0
      if (has_upper) {
11856
0
        unicode::to_lower_ascii(host_str.data(), host_str.size());
11857
0
      }
11858
0
      out.host = std::move(host_str);
11859
0
      if (parsed_port != url_components::omitted) {
11860
0
        out.port = static_cast<uint16_t>(parsed_port);
11861
0
      }
11862
0
      out.parse_path(path_view);
11863
0
      apply_query_and_hash();
11864
0
    }
11865
0
    return true;
11866
0
  }
11867
11868
0
  const bool insert_slash = !has_path;
11869
0
  if constexpr (is_aggregator) {
11870
0
    const size_t out_len =
11871
0
        host_end + port_bytes + (insert_slash ? 1 : 0) + (len - authority_end);
11872
0
    const bool omit_port_bytes = parsed_port == url_components::omitted;
11873
0
    if (out_len == len && !insert_slash && !omit_port_bytes) {
11874
0
      out.buffer.assign(input);
11875
0
    } else {
11876
0
      out.buffer.clear();
11877
0
      out.buffer.reserve(out_len);
11878
0
      out.buffer.append(input.substr(0, host_end));
11879
0
      if (parsed_port != url_components::omitted) {
11880
0
        append_canonical_port(out.buffer, parsed_port);
11881
0
      }
11882
0
      if (insert_slash) {
11883
0
        out.buffer.push_back('/');
11884
0
      }
11885
0
      if (authority_end < len) {
11886
0
        out.buffer.append(input.substr(authority_end));
11887
0
      }
11888
0
    }
11889
0
    if (has_upper) {
11890
0
      unicode::to_lower_ascii(out.buffer.data() + host_start, host_len);
11891
0
    }
11892
0
    const uint32_t pathname_start =
11893
0
        static_cast<uint32_t>(host_end) + port_bytes;
11894
0
    const int32_t tail_delta = static_cast<int32_t>(pathname_start) +
11895
0
                               (insert_slash ? 1 : 0) -
11896
0
                               static_cast<int32_t>(authority_end);
11897
0
    out.components.protocol_end = protocol_end;
11898
0
    out.components.username_end = protocol_end + 2;
11899
0
    out.components.host_start = protocol_end + 2;
11900
0
    out.components.host_end = static_cast<uint32_t>(host_end);
11901
0
    out.components.port = parsed_port;
11902
0
    out.components.pathname_start = pathname_start;
11903
0
    out.components.search_start =
11904
0
        (query_start != std::string_view::npos)
11905
0
            ? static_cast<uint32_t>(static_cast<int32_t>(query_start) +
11906
0
                                    tail_delta)
11907
0
            : url_components::omitted;
11908
0
    out.components.hash_start =
11909
0
        (hash_start != std::string_view::npos)
11910
0
            ? static_cast<uint32_t>(static_cast<int32_t>(hash_start) +
11911
0
                                    tail_delta)
11912
0
            : url_components::omitted;
11913
0
  } else {
11914
0
    std::string host_str(input.substr(host_start, host_len));
11915
0
    if (has_upper) {
11916
0
      unicode::to_lower_ascii(host_str.data(), host_str.size());
11917
0
    }
11918
0
    out.host = std::move(host_str);
11919
0
    if (parsed_port != url_components::omitted) {
11920
0
      out.port = static_cast<uint16_t>(parsed_port);
11921
0
    }
11922
0
    if (insert_slash) {
11923
0
      out.path = "/";
11924
0
    } else {
11925
0
      out.path.assign(input.data() + path_start, path_end - path_start);
11926
0
    }
11927
0
    if (query_start != std::string_view::npos) {
11928
0
      const size_t q_end =
11929
0
          (hash_start != std::string_view::npos) ? hash_start : len;
11930
0
      out.query.emplace(input.data() + query_start + 1,
11931
0
                        q_end - query_start - 1);
11932
0
    }
11933
0
    if (hash_start != std::string_view::npos) {
11934
0
      out.hash.emplace(input.data() + hash_start + 1, len - hash_start - 1);
11935
0
    }
11936
0
  }
11937
0
  return true;
11938
0
}
Unexecuted instantiation: bool ada::parser::finish_simple_absolute_with_port<ada::url>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url&, ada::scheme::type, unsigned int, unsigned long, unsigned long, unsigned long, bool)
Unexecuted instantiation: bool ada::parser::finish_simple_absolute_with_port<ada::url_aggregator>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url_aggregator&, ada::scheme::type, unsigned int, unsigned long, unsigned long, unsigned long, bool)
11939
11940
// Fast path for already-canonical special-scheme URLs of the shape
11941
// scheme://host[/path][?query][#fragment]. When the host is a plain domain
11942
// but the rest needs encoding or dot-segment normalization, the host is
11943
// kept and the path/query/hash helpers finish the URL.
11944
template <class result_type>
11945
ada_never_inline bool try_parse_simple_absolute(std::string_view input,
11946
0
                                                result_type& out) {
11947
0
  constexpr bool is_ada_url = std::is_same_v<result_type, ada::url>;
11948
0
  constexpr bool is_aggregator =
11949
0
      std::is_same_v<result_type, ada::url_aggregator>;
11950
0
  static_assert(is_ada_url || is_aggregator);
11951
11952
0
  const size_t len = input.size();
11953
  // Shortest accepted form is "ws://x" (6).
11954
0
  if (len < 6) [[unlikely]] {
11955
0
    return false;
11956
0
  }
11957
0
  const auto* b = reinterpret_cast<const uint8_t*>(input.data());
11958
11959
0
  size_t pos = 0;
11960
0
  ada::scheme::type scheme_type = ada::scheme::type::NOT_SPECIAL;
11961
0
  uint32_t protocol_end = 0;
11962
0
#if (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || \
11963
0
    defined(_M_X64) || defined(_M_IX86) || defined(_M_AMD64)
11964
  // One 8-byte load + integer compare is a single cmp/jcc on x86-64.
11965
  // Masked compares cover the shorter special schemes without extra loads.
11966
0
  if (len >= 8) {
11967
0
    uint64_t first8 = 0;
11968
0
    std::memcpy(&first8, b, 8);
11969
0
    if (first8 == 0x2f2f3a7370747468ull) {  // "https://"
11970
0
      pos = 8;
11971
0
      scheme_type = ada::scheme::type::HTTPS;
11972
0
      protocol_end = 6;
11973
0
    } else if ((first8 & 0x00ffffffffffffffull) ==
11974
0
               0x002f2f3a70747468ull) {  // "http://"
11975
0
      pos = 7;
11976
0
      scheme_type = ada::scheme::type::HTTP;
11977
0
      protocol_end = 5;
11978
0
    } else if ((first8 & 0x0000ffffffffffffull) ==
11979
0
               0x00002f2f3a737377ull) {  // "wss://"
11980
0
      pos = 6;
11981
0
      scheme_type = ada::scheme::type::WSS;
11982
0
      protocol_end = 4;
11983
0
    } else if ((first8 & 0x0000ffffffffffffull) ==
11984
0
               0x00002f2f3a707466ull) {  // "ftp://"
11985
0
      pos = 6;
11986
0
      scheme_type = ada::scheme::type::FTP;
11987
0
      protocol_end = 4;
11988
0
    } else if ((first8 & 0x000000ffffffffffull) ==
11989
0
               0x0000002f2f3a7377ull) {  // "ws://"
11990
0
      pos = 5;
11991
0
      scheme_type = ada::scheme::type::WS;
11992
0
      protocol_end = 3;
11993
0
    } else {
11994
0
      return false;
11995
0
    }
11996
0
  } else if (b[0] == 'w' && b[1] == 's') {
11997
0
    if (b[2] == ':' && b[3] == '/' && b[4] == '/') {
11998
0
      pos = 5;
11999
0
      scheme_type = ada::scheme::type::WS;
12000
0
      protocol_end = 3;
12001
0
    } else if (b[2] == 's' && b[3] == ':' && b[4] == '/' && b[5] == '/') {
12002
0
      pos = 6;
12003
0
      scheme_type = ada::scheme::type::WSS;
12004
0
      protocol_end = 4;
12005
0
    } else {
12006
0
      return false;
12007
0
    }
12008
0
  } else if (b[0] == 'f' && b[1] == 't' && b[2] == 'p' && b[3] == ':' &&
12009
0
             b[4] == '/' && b[5] == '/') {
12010
0
    pos = 6;
12011
0
    scheme_type = ada::scheme::type::FTP;
12012
0
    protocol_end = 4;
12013
0
  } else if (len >= 7 && b[0] == 'h' && b[1] == 't' && b[2] == 't' &&
12014
0
             b[3] == 'p' && b[4] == ':' && b[5] == '/' && b[6] == '/') {
12015
0
    pos = 7;
12016
0
    scheme_type = ada::scheme::type::HTTP;
12017
0
    protocol_end = 5;
12018
0
  } else {
12019
0
    return false;
12020
0
  }
12021
#else
12022
  // Big-endian / uncommon arches: byte-wise special-scheme match.
12023
  if (len >= 8 && b[0] == 'h' && b[1] == 't' && b[2] == 't' && b[3] == 'p' &&
12024
      b[4] == 's' && b[5] == ':' && b[6] == '/' && b[7] == '/') {
12025
    pos = 8;
12026
    scheme_type = ada::scheme::type::HTTPS;
12027
    protocol_end = 6;
12028
  } else if (len >= 7 && b[0] == 'h' && b[1] == 't' && b[2] == 't' &&
12029
             b[3] == 'p' && b[4] == ':' && b[5] == '/' && b[6] == '/') {
12030
    pos = 7;
12031
    scheme_type = ada::scheme::type::HTTP;
12032
    protocol_end = 5;
12033
  } else if (b[0] == 'w' && b[1] == 's') {
12034
    if (b[2] == ':' && b[3] == '/' && b[4] == '/') {
12035
      pos = 5;
12036
      scheme_type = ada::scheme::type::WS;
12037
      protocol_end = 3;
12038
    } else if (len >= 6 && b[2] == 's' && b[3] == ':' && b[4] == '/' &&
12039
               b[5] == '/') {
12040
      pos = 6;
12041
      scheme_type = ada::scheme::type::WSS;
12042
      protocol_end = 4;
12043
    } else {
12044
      return false;
12045
    }
12046
  } else if (b[0] == 'f' && b[1] == 't' && b[2] == 'p' && b[3] == ':' &&
12047
             b[4] == '/' && b[5] == '/') {
12048
    pos = 6;
12049
    scheme_type = ada::scheme::type::FTP;
12050
    protocol_end = 4;
12051
  } else {
12052
    return false;
12053
  }
12054
#endif
12055
0
  if (pos < len && (b[pos] == '/' || b[pos] == '\\')) [[unlikely]] {
12056
0
    return false;
12057
0
  }
12058
12059
  // Digit-led hosts are IPv4/numeric; '[' is IPv6. Skip before scanning.
12060
0
  if (pos < len && ((b[pos] >= '0' && b[pos] <= '9') || b[pos] == '[')) {
12061
0
    return false;
12062
0
  }
12063
12064
0
  const size_t host_start = pos;
12065
0
  bool has_upper = false;
12066
0
  bool has_x = false;
12067
0
  size_t host_end = pos;
12068
0
  if (!scan_plain_host(b, pos, len, host_end, has_upper, has_x)) {
12069
0
    return false;
12070
0
  }
12071
0
  if (host_start == host_end) [[unlikely]] {
12072
0
    return false;
12073
0
  }
12074
0
  const size_t host_len = host_end - host_start;
12075
0
  if (host_len > 253) [[unlikely]] {
12076
0
    return false;
12077
0
  }
12078
0
  {
12079
0
    std::string_view hv(input.data() + host_start, host_len);
12080
0
    char host_buf[256];
12081
0
    if (has_upper) [[unlikely]] {
12082
0
      std::memcpy(host_buf, input.data() + host_start, host_len);
12083
0
      unicode::to_lower_ascii(host_buf, host_len);
12084
0
      hv = std::string_view(host_buf, host_len);
12085
0
    }
12086
0
    if (ada::checkers::last_label_may_be_a_number(hv)) [[unlikely]] {
12087
0
      return false;
12088
0
    }
12089
    // Punycode is "xn--...". The host scan already notes a lowercase 'x';
12090
    // uppercase 'X' is covered by has_upper after the in-place lower.
12091
0
    static constexpr std::string_view xn{"xn-", 3};
12092
0
    if ((has_x || has_upper) && hv.find(xn) != std::string_view::npos)
12093
0
        [[unlikely]] {
12094
0
      return false;
12095
0
    }
12096
0
  }
12097
12098
0
  if (host_end < len && b[host_end] == ':') [[unlikely]] {
12099
0
    return finish_simple_absolute_with_port(input, out, scheme_type,
12100
0
                                            protocol_end, host_start, host_end,
12101
0
                                            host_len, has_upper);
12102
0
  }
12103
12104
0
  size_t i = host_end;
12105
0
  size_t path_start = host_end;
12106
0
  size_t path_end = host_end;
12107
0
  size_t query_start = std::string_view::npos;
12108
0
  size_t hash_start = std::string_view::npos;
12109
0
  bool has_path = false;
12110
0
  bool maybe_dot_segment = false;
12111
0
  bool rest_simple = true;
12112
12113
0
  if (i < len && b[i] == '/') {
12114
0
    has_path = true;
12115
0
    path_start = i;
12116
0
    ++i;
12117
0
    scan_path_run(b, i, len, maybe_dot_segment);
12118
0
    if (i < len) {
12119
0
      const uint8_t cls = k_path[b[i]];
12120
0
      if (cls == 1) {
12121
0
        path_end = i;
12122
0
        if (b[i] == '?') {
12123
0
          query_start = i;
12124
0
          ++i;
12125
0
          goto scan_query;
12126
0
        }
12127
0
        hash_start = i;
12128
0
        ++i;
12129
0
        goto scan_hash;
12130
0
      }
12131
0
      rest_simple = false;
12132
0
      for (; i < len; ++i) {
12133
0
        if (b[i] == '?') {
12134
0
          path_end = i;
12135
0
          query_start = i;
12136
0
          ++i;
12137
0
          goto scan_query_boundary;
12138
0
        }
12139
0
        if (b[i] == '#') {
12140
0
          path_end = i;
12141
0
          hash_start = i;
12142
0
          ++i;
12143
0
          goto after_rest;
12144
0
        }
12145
0
      }
12146
0
      path_end = i;
12147
0
      goto after_rest;
12148
0
    }
12149
0
    path_end = i;
12150
0
  } else if (i < len && b[i] == '?') {
12151
0
    query_start = i;
12152
0
    ++i;
12153
0
    goto scan_query;
12154
0
  } else if (i < len && b[i] == '#') {
12155
0
    hash_start = i;
12156
0
    ++i;
12157
0
    goto scan_hash;
12158
0
  }
12159
0
  goto after_rest;
12160
12161
0
scan_query:
12162
0
  scan_query_run(b, i, len);
12163
0
  if (i < len) {
12164
0
    if (b[i] == '#') {
12165
0
      hash_start = i;
12166
0
      ++i;
12167
0
      goto scan_hash;
12168
0
    }
12169
0
    rest_simple = false;
12170
0
    goto scan_query_boundary;
12171
0
  }
12172
0
  goto after_rest;
12173
12174
0
scan_query_boundary:
12175
0
  for (; i < len; ++i) {
12176
0
    if (b[i] == '#') {
12177
0
      hash_start = i;
12178
0
      ++i;
12179
0
      goto after_rest;
12180
0
    }
12181
0
  }
12182
0
  goto after_rest;
12183
12184
0
scan_hash:
12185
0
  scan_hash_run(b, i, len);
12186
0
  if (i < len) {
12187
0
    rest_simple = false;
12188
0
  }
12189
12190
0
after_rest:
12191
0
  if (rest_simple && maybe_dot_segment) {
12192
0
    const std::string_view path_body(input.data() + path_start,
12193
0
                                     path_end - path_start);
12194
0
    if (path_has_dot_segment(path_body)) {
12195
0
      rest_simple = false;
12196
0
    }
12197
0
  }
12198
12199
  // The slow path removes ASCII tab/newline anywhere in the input and trims a
12200
  // trailing C0 control or space; this fast path does neither. A query or
12201
  // fragment reaching the helpers below would keep those bytes percent-encoded
12202
  // ("?a\nb" -> "?a%0Ab", "#f " -> "#f%20") instead of stripped, so hand such
12203
  // inputs back to the slow path.
12204
0
  if (!rest_simple && (unicode::is_c0_control_or_space(input.back()) ||
12205
0
                       unicode::has_tabs_or_newline(input))) {
12206
0
    return false;
12207
0
  }
12208
12209
0
  out.type = scheme_type;
12210
0
  out.is_valid = true;
12211
0
  out.has_opaque_path = false;
12212
0
  out.host_type = DEFAULT;
12213
12214
0
  if (!rest_simple) {
12215
    // Host is a plain domain. Finish path/query/hash with
12216
    // the regular helpers
12217
    // so percent-encoding and dot segments do not re-parse the authority.
12218
0
    const std::string_view path_view =
12219
0
        has_path
12220
0
            ? std::string_view(input.data() + path_start, path_end - path_start)
12221
0
            : std::string_view{};
12222
0
    auto apply_query_and_hash = [&]() {
12223
0
      if (query_start != std::string_view::npos) {
12224
0
        const size_t q_end =
12225
0
            (hash_start != std::string_view::npos) ? hash_start : len;
12226
0
        out.update_base_search(std::string_view(input.data() + query_start + 1,
12227
0
                                                q_end - query_start - 1),
12228
0
                               character_sets::SPECIAL_QUERY_PERCENT_ENCODE);
12229
0
      }
12230
0
      if (hash_start != std::string_view::npos) {
12231
0
        out.update_unencoded_base_hash(std::string_view(
12232
0
            input.data() + hash_start + 1, len - hash_start - 1));
12233
0
      }
12234
0
    };
Unexecuted instantiation: ada::parser::try_parse_simple_absolute<ada::url>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url&)::{lambda()#1}::operator()() const
Unexecuted instantiation: ada::parser::try_parse_simple_absolute<ada::url_aggregator>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url_aggregator&)::{lambda()#1}::operator()() const
12235
0
    if constexpr (is_aggregator) {
12236
0
      out.buffer.assign(input.substr(0, host_end));
12237
0
      if (has_upper) {
12238
0
        unicode::to_lower_ascii(out.buffer.data() + host_start, host_len);
12239
0
      }
12240
0
      out.components.protocol_end = protocol_end;
12241
0
      out.components.username_end = protocol_end + 2;
12242
0
      out.components.host_start = protocol_end + 2;
12243
0
      out.components.host_end = static_cast<uint32_t>(host_end);
12244
0
      out.components.port = url_components::omitted;
12245
0
      out.components.pathname_start = static_cast<uint32_t>(host_end);
12246
0
      out.components.search_start = url_components::omitted;
12247
0
      out.components.hash_start = url_components::omitted;
12248
0
      out.parse_path(path_view);
12249
0
      apply_query_and_hash();
12250
0
    } else {
12251
0
      std::string host_str(input.substr(host_start, host_len));
12252
0
      if (has_upper) {
12253
0
        unicode::to_lower_ascii(host_str.data(), host_str.size());
12254
0
      }
12255
0
      out.host = std::move(host_str);
12256
0
      out.parse_path(path_view);
12257
0
      apply_query_and_hash();
12258
0
    }
12259
0
    return true;
12260
0
  }
12261
12262
0
  const bool need_slash = !has_path;
12263
0
  if constexpr (is_aggregator) {
12264
0
    if (!need_slash) {
12265
      // assign copies once. resize()+memcpy would value-init then overwrite.
12266
0
      out.buffer.assign(input);
12267
0
      if (has_upper) {
12268
0
        unicode::to_lower_ascii(out.buffer.data() + host_start, host_len);
12269
0
      }
12270
0
      out.components.protocol_end = protocol_end;
12271
0
      out.components.username_end = protocol_end + 2;
12272
0
      out.components.host_start = protocol_end + 2;
12273
0
      out.components.host_end = static_cast<uint32_t>(host_end);
12274
0
      out.components.port = url_components::omitted;
12275
0
      out.components.pathname_start = static_cast<uint32_t>(path_start);
12276
0
      out.components.search_start = (query_start != std::string_view::npos)
12277
0
                                        ? static_cast<uint32_t>(query_start)
12278
0
                                        : url_components::omitted;
12279
0
      out.components.hash_start = (hash_start != std::string_view::npos)
12280
0
                                      ? static_cast<uint32_t>(hash_start)
12281
0
                                      : url_components::omitted;
12282
0
    } else {
12283
0
      out.buffer.clear();
12284
0
      out.buffer.reserve(len + 1);
12285
0
      out.buffer.append(input.substr(0, host_end));
12286
0
      out.buffer.push_back('/');
12287
0
      if (host_end < len) {
12288
0
        out.buffer.append(input.substr(host_end));
12289
0
      }
12290
0
      if (has_upper) {
12291
0
        unicode::to_lower_ascii(out.buffer.data() + host_start, host_len);
12292
0
      }
12293
0
      out.components.protocol_end = protocol_end;
12294
0
      out.components.username_end = protocol_end + 2;
12295
0
      out.components.host_start = protocol_end + 2;
12296
0
      out.components.host_end = static_cast<uint32_t>(host_end);
12297
0
      out.components.port = url_components::omitted;
12298
0
      out.components.pathname_start = static_cast<uint32_t>(host_end);
12299
0
      out.components.search_start = (query_start != std::string_view::npos)
12300
0
                                        ? static_cast<uint32_t>(query_start + 1)
12301
0
                                        : url_components::omitted;
12302
0
      out.components.hash_start = (hash_start != std::string_view::npos)
12303
0
                                      ? static_cast<uint32_t>(hash_start + 1)
12304
0
                                      : url_components::omitted;
12305
0
    }
12306
0
  } else {
12307
0
    std::string host_str(input.substr(host_start, host_len));
12308
0
    if (has_upper) {
12309
0
      unicode::to_lower_ascii(host_str.data(), host_str.size());
12310
0
    }
12311
0
    out.host = std::move(host_str);
12312
0
    if (need_slash) {
12313
0
      out.path = "/";
12314
0
    } else {
12315
0
      out.path.assign(input.data() + path_start, path_end - path_start);
12316
0
    }
12317
0
    if (query_start != std::string_view::npos) {
12318
0
      const size_t q_end =
12319
0
          (hash_start != std::string_view::npos) ? hash_start : len;
12320
0
      out.query.emplace(input.data() + query_start + 1,
12321
0
                        q_end - query_start - 1);
12322
0
    }
12323
0
    if (hash_start != std::string_view::npos) {
12324
0
      out.hash.emplace(input.data() + hash_start + 1, len - hash_start - 1);
12325
0
    }
12326
0
  }
12327
0
  return true;
12328
0
}
Unexecuted instantiation: bool ada::parser::try_parse_simple_absolute<ada::url>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url&)
Unexecuted instantiation: bool ada::parser::try_parse_simple_absolute<ada::url_aggregator>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url_aggregator&)
12329
12330
// Fast path for `/path`, path-relative (`foo`, `c/d?q`), `?query`, and
12331
// `#fragment` against a special-scheme base. Scheme-relative (`//`) and
12332
// scheme-like first segments (`foo:bar`) stay on the state machine.
12333
template <class result_type>
12334
ada_never_inline bool try_parse_simple_relative(std::string_view input,
12335
                                                const result_type& base,
12336
0
                                                result_type& out) {
12337
0
  constexpr bool is_ada_url = std::is_same_v<result_type, ada::url>;
12338
0
  constexpr bool is_aggregator =
12339
0
      std::is_same_v<result_type, ada::url_aggregator>;
12340
0
  static_assert(is_ada_url || is_aggregator);
12341
12342
0
  if (!base.is_special() || base.type == ada::scheme::type::FILE ||
12343
0
      base.has_opaque_path || input.empty()) {
12344
0
    return false;
12345
0
  }
12346
0
  const auto* b = reinterpret_cast<const uint8_t*>(input.data());
12347
0
  const size_t len = input.size();
12348
0
  const uint8_t first = b[0];
12349
0
  const bool path_relative = first != '/' && first != '?' && first != '#';
12350
0
  if (first == '/' && len > 1 && (b[1] == '/' || b[1] == '\\')) {
12351
0
    return false;
12352
0
  }
12353
  // A ':' before the first / ? # is a scheme, not a path segment.
12354
0
  if (path_relative) {
12355
0
    const size_t delim = input.find_first_of("/?#:");
12356
0
    if (delim != std::string_view::npos && input[delim] == ':') {
12357
0
      return false;
12358
0
    }
12359
0
  }
12360
12361
0
  size_t i = 0;
12362
0
  size_t path_start = 0;
12363
0
  size_t path_end = 0;
12364
0
  size_t query_start = std::string_view::npos;
12365
0
  size_t hash_start = std::string_view::npos;
12366
0
  bool has_path = false;
12367
0
  bool maybe_dot_segment = false;
12368
12369
0
  if (first == '/' || path_relative) {
12370
0
    has_path = true;
12371
0
    path_start = 0;
12372
0
    if (first == '/') {
12373
0
      i = 1;
12374
0
    }
12375
0
    scan_path_run(b, i, len, maybe_dot_segment);
12376
0
    if (i < len) {
12377
0
      const uint8_t cls = k_path[b[i]];
12378
0
      if (cls == 2) {
12379
0
        return false;
12380
0
      }
12381
0
    }
12382
0
    path_end = i;
12383
0
    if (i < len && b[i] == '?') {
12384
0
      query_start = i;
12385
0
      ++i;
12386
0
      scan_query_run(b, i, len);
12387
0
      if (i < len) {
12388
0
        if (b[i] != '#') {
12389
0
          return false;
12390
0
        }
12391
0
        hash_start = i;
12392
0
        ++i;
12393
0
        scan_hash_run(b, i, len);
12394
0
        if (i < len) {
12395
0
          return false;
12396
0
        }
12397
0
      }
12398
0
    } else if (i < len && b[i] == '#') {
12399
0
      hash_start = i;
12400
0
      ++i;
12401
0
      scan_hash_run(b, i, len);
12402
0
      if (i < len) {
12403
0
        return false;
12404
0
      }
12405
0
    } else if (i < len) {
12406
0
      return false;
12407
0
    }
12408
0
  } else if (first == '?') {
12409
0
    query_start = 0;
12410
0
    i = 1;
12411
0
    scan_query_run(b, i, len);
12412
0
    if (i < len) {
12413
0
      if (b[i] != '#') {
12414
0
        return false;
12415
0
      }
12416
0
      hash_start = i;
12417
0
      ++i;
12418
0
      scan_hash_run(b, i, len);
12419
0
      if (i < len) {
12420
0
        return false;
12421
0
      }
12422
0
    }
12423
0
  } else {
12424
0
    hash_start = 0;
12425
0
    i = 1;
12426
0
    scan_hash_run(b, i, len);
12427
0
    if (i < len) {
12428
0
      return false;
12429
0
    }
12430
0
  }
12431
12432
0
  if (has_path && maybe_dot_segment) {
12433
0
    const std::string_view path_body(input.data() + path_start,
12434
0
                                     path_end - path_start);
12435
0
    if (path_has_dot_segment(path_body)) {
12436
0
      return false;
12437
0
    }
12438
0
  }
12439
12440
0
  out = base;
12441
0
  out.is_valid = true;
12442
0
  out.has_opaque_path = false;
12443
12444
0
  const size_t q_end =
12445
0
      (hash_start != std::string_view::npos) ? hash_start : len;
12446
0
  const bool has_query = query_start != std::string_view::npos;
12447
0
  const bool has_hash = hash_start != std::string_view::npos;
12448
0
  const std::string_view query =
12449
0
      has_query ? std::string_view(input.data() + query_start + 1,
12450
0
                                   q_end - query_start - 1)
12451
0
                : std::string_view{};
12452
0
  const std::string_view hash =
12453
0
      has_hash ? std::string_view(input.data() + hash_start + 1,
12454
0
                                  len - hash_start - 1)
12455
0
               : std::string_view{};
12456
12457
0
  if constexpr (is_aggregator) {
12458
0
    if (first == '/' || first == '?' || path_relative) {
12459
0
      out.clear_hash();
12460
0
      out.clear_search();
12461
0
    }
12462
0
    if (first == '/') {
12463
0
      out.update_base_pathname(input.substr(path_start, path_end - path_start));
12464
0
    } else if (path_relative) {
12465
0
      const std::string_view base_path = out.get_pathname();
12466
0
      const size_t slash = base_path.rfind('/');
12467
0
      const std::string_view prefix = (slash == std::string_view::npos)
12468
0
                                          ? std::string_view("/")
12469
0
                                          : base_path.substr(0, slash + 1);
12470
0
      const std::string_view rel(input.data() + path_start,
12471
0
                                 path_end - path_start);
12472
0
      std::string new_path;
12473
0
      new_path.reserve(prefix.size() + rel.size());
12474
0
      new_path.assign(prefix);
12475
0
      new_path.append(rel);
12476
0
      out.update_base_pathname(new_path);
12477
0
    }
12478
0
    if (has_query) {
12479
      // Do not use update_base_search: it strips a leading '?' and would
12480
      // collapse '??a=b' into '?a=b'.
12481
0
      out.components.search_start = static_cast<uint32_t>(out.buffer.size());
12482
0
      out.buffer += '?';
12483
0
      out.buffer.append(query);
12484
0
    }
12485
0
    if (has_hash) {
12486
0
      out.update_unencoded_base_hash(hash);
12487
0
    }
12488
0
  } else {
12489
0
    if (first == '/' || first == '?' || path_relative) {
12490
0
      out.hash.reset();
12491
0
    }
12492
0
    if (first == '/') {
12493
0
      out.query.reset();
12494
0
      out.path.assign(input.substr(path_start, path_end - path_start));
12495
0
    } else if (path_relative) {
12496
0
      out.query.reset();
12497
0
      const size_t slash = out.path.rfind('/');
12498
0
      if (slash == std::string::npos) {
12499
0
        out.path = '/';
12500
0
      } else {
12501
0
        out.path.resize(slash + 1);
12502
0
      }
12503
0
      out.path.append(input.substr(path_start, path_end - path_start));
12504
0
    }
12505
0
    if (has_query) {
12506
0
      out.query.emplace(query);
12507
0
    }
12508
0
    if (has_hash) {
12509
0
      out.hash.emplace(hash);
12510
0
    }
12511
0
  }
12512
0
  return true;
12513
0
}
Unexecuted instantiation: bool ada::parser::try_parse_simple_relative<ada::url>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url const&, ada::url&)
Unexecuted instantiation: bool ada::parser::try_parse_simple_relative<ada::url_aggregator>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url_aggregator const&, ada::url_aggregator&)
12514
12515
template <class result_type, bool store_values>
12516
result_type parse_url_impl(std::string_view user_input,
12517
0
                           const result_type* base_url) {
12518
  // We can specialize the implementation per type.
12519
  // Important: result_type_is_ada_url is evaluated at *compile time*. This
12520
  // means that doing if constexpr(result_type_is_ada_url) { something } else {
12521
  // something else } is free (at runtime). This means that ada::url_aggregator
12522
  // and ada::url **do not have to support the exact same API**.
12523
0
  constexpr bool result_type_is_ada_url = std::is_same_v<url, result_type>;
12524
0
  constexpr bool result_type_is_ada_url_aggregator =
12525
0
      std::is_same_v<url_aggregator, result_type>;
12526
0
  static_assert(result_type_is_ada_url ||
12527
0
                result_type_is_ada_url_aggregator);  // We don't support
12528
                                                     // anything else for now.
12529
12530
0
  ada_log("ada::parser::parse_url('", user_input, "' [", user_input.size(),
12531
0
          " bytes],", (base_url != nullptr ? base_url->to_string() : "null"),
12532
0
          ")");
12533
12534
0
  result_type url{};
12535
12536
0
  const uint32_t max_input_length = ada::get_max_input_length();
12537
12538
  // Normalization (percent-encoding, IDNA) can push the serialized URL past
12539
  // max_input_length even when the input fit under it. The check at the end of
12540
  // the state machine covers URLs that run to completion, but several states
12541
  // return early after appending a query or fragment, so run the same check on
12542
  // those exits too. Without this, a query- or fragment-terminated URL such as
12543
  // file://x/?<...> or https://user@x/?<...> is accepted while the equivalent
12544
  // https://x/?<...> that takes the absolute fast path is rejected.
12545
0
  const auto enforce_max_input_length = [&]() {
12546
0
    if constexpr (store_values) {
12547
0
      if (url.is_valid) {
12548
0
        if constexpr (result_type_is_ada_url_aggregator) {
12549
0
          if (url.buffer.size() > max_input_length) [[unlikely]] {
12550
0
            url.is_valid = false;
12551
0
          }
12552
0
        } else {
12553
0
          if (url.get_href_size() > max_input_length) [[unlikely]] {
12554
0
            url.is_valid = false;
12555
0
          }
12556
0
        }
12557
0
      }
12558
0
    }
12559
0
  };
Unexecuted instantiation: ada::parser::parse_url_impl<ada::url, true>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url const*)::{lambda()#1}::operator()() const
Unexecuted instantiation: ada::parser::parse_url_impl<ada::url_aggregator, true>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url_aggregator const*)::{lambda()#1}::operator()() const
Unexecuted instantiation: ada::parser::parse_url_impl<ada::url_aggregator, false>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url_aggregator const*)::{lambda()#1}::operator()() const
12560
12561
  // We refuse to parse URL strings that exceed the maximum input length.
12562
  // By default, this is 4GB but can be configured via
12563
  // ada::set_max_input_length().
12564
0
  if (user_input.size() > max_input_length) [[unlikely]] {
12565
0
    url.is_valid = false;
12566
0
  }
12567
  // Going forward, user_input.size() is in [0,
12568
  // std::numeric_limits<uint32_t>::max). If we are provided with an invalid
12569
  // base, or the optional_url was invalid, we must return.
12570
0
  if (base_url != nullptr) {
12571
0
    url.is_valid &= base_url->is_valid;
12572
0
  }
12573
0
  if (!url.is_valid) {
12574
0
    return url;
12575
0
  }
12576
12577
  // Simple absolute / relative fast paths (before tabs/newline scan).
12578
0
  if constexpr (store_values) {
12579
0
    bool hit_fast_path = false;
12580
0
    if (base_url == nullptr) {
12581
      // IPv4/IPv6 and userinfo miss the fast path. Skip the never_inline
12582
      // call so those URLs (including SetHref) do not pay for a miss.
12583
0
      const auto* p = reinterpret_cast<const uint8_t*>(user_input.data());
12584
0
      const size_t n = user_input.size();
12585
0
      size_t host_start = 0;
12586
0
      if (n >= 8 && p[4] == ':' && p[5] == '/' && p[6] == '/') {
12587
0
        host_start = 7;
12588
0
      } else if (n >= 9 && p[5] == ':' && p[6] == '/' && p[7] == '/') {
12589
0
        host_start = 8;
12590
0
      }
12591
0
      const uint8_t host_first = host_start != 0 ? p[host_start] : 0;
12592
0
      const bool skip_ip =
12593
0
          host_first == '[' || (host_first >= '0' && host_first <= '9');
12594
0
      const bool skip_userinfo =
12595
0
          host_start != 0 && authority_has_at(p, host_start, n);
12596
0
      hit_fast_path = !skip_ip && !skip_userinfo &&
12597
0
                      try_parse_simple_absolute(user_input, url);
12598
0
    } else {
12599
0
      hit_fast_path = try_parse_simple_relative(user_input, *base_url, url);
12600
0
    }
12601
0
    if (hit_fast_path) {
12602
0
      if constexpr (result_type_is_ada_url_aggregator) {
12603
0
        if (url.buffer.size() > max_input_length) [[unlikely]] {
12604
0
          url.is_valid = false;
12605
0
        }
12606
0
      } else {
12607
        // For a small absolute input, even worst-case normalization cannot
12608
        // exceed the limit: percent encoding expands at most 3x and IDNA at
12609
        // most 4.5x. Avoid traversing every stored component on the common
12610
        // default-limit path.
12611
0
        if ((base_url != nullptr ||
12612
0
             user_input.size() > static_cast<size_t>(max_input_length) / 5) &&
12613
0
            url.get_href_size() > max_input_length) [[unlikely]] {
12614
0
          url.is_valid = false;
12615
0
        }
12616
0
      }
12617
0
      return url;
12618
0
    }
12619
0
  }
12620
12621
0
  state state = state::SCHEME_START;
12622
12623
0
  std::string tmp_buffer;
12624
0
  std::string_view url_data;
12625
0
  if (unicode::has_tabs_or_newline(user_input)) [[unlikely]] {
12626
0
    tmp_buffer = user_input;
12627
    // Optimization opportunity: Instead of copying and then pruning, we could
12628
    // just directly build the string from user_input.
12629
0
    helpers::remove_ascii_tab_or_newline(tmp_buffer);
12630
0
    url_data = tmp_buffer;
12631
0
  } else [[likely]] {
12632
0
    url_data = user_input;
12633
0
  }
12634
12635
  // Leading and trailing control characters are uncommon and easy to deal with
12636
  // (no performance concern).
12637
0
  helpers::trim_c0_whitespace(url_data);
12638
12639
0
  if constexpr (result_type_is_ada_url_aggregator && store_values) {
12640
    // Most of the time, we just need user_input.size().
12641
    // In some instances, we may need a bit more.
12642
    ///////////////////////////
12643
    // This is *very* important. This line should *not* be removed
12644
    // hastily. There are principled reasons why reserve is important
12645
    // for performance. If you have a benchmark with small inputs,
12646
    // it may not matter, but in other instances, it could.
12647
    ////
12648
    // This rounds up to the next power of two.
12649
    // We know that user_input.size() is in [0,
12650
    // std::numeric_limits<uint32_t>::max).
12651
0
    uint32_t reserve_capacity =
12652
0
        (0xFFFFFFFF >>
12653
0
         helpers::leading_zeroes(uint32_t(1 | user_input.size()))) +
12654
0
        1;
12655
0
    url.reserve(reserve_capacity);
12656
0
  }
12657
12658
  // Optimization opportunity. Most websites do not have fragment.
12659
0
  std::optional<std::string_view> fragment = helpers::prune_hash(url_data);
12660
  // We add it last so that an implementation like ada::url_aggregator
12661
  // can append it last to its internal buffer, thus improving performance.
12662
12663
  // Here url_data no longer has its fragment.
12664
  // We are going to access the data from url_data (it is immutable).
12665
  // At any given time, we are pointing at byte 'input_position' in url_data.
12666
  // The input_position variable should range from 0 to input_size.
12667
  // It is illegal to access url_data at input_size.
12668
0
  size_t input_position = 0;
12669
0
  const size_t input_size = url_data.size();
12670
  // Keep running the following state machine by switching on state.
12671
  // If after a run pointer points to the EOF code point, go to the next step.
12672
  // Otherwise, increase pointer by 1 and continue with the state machine.
12673
  // We never decrement input_position.
12674
0
  while (input_position <= input_size) {
12675
0
    ada_log("In parsing at ", input_position, " out of ", input_size,
12676
0
            " in state ", ada::to_string(state));
12677
0
    switch (state) {
12678
0
      case state::SCHEME_START: {
12679
0
        ada_log("SCHEME_START ", helpers::substring(url_data, input_position));
12680
        // If c is an ASCII alpha, append c, lowercased, to buffer, and set
12681
        // state to scheme state.
12682
0
        if ((input_position != input_size) &&
12683
0
            checkers::is_alpha(url_data[input_position])) {
12684
0
          state = state::SCHEME;
12685
0
          input_position++;
12686
0
        } else {
12687
          // Otherwise, if state override is not given, set state to no scheme
12688
          // state and decrease pointer by 1.
12689
0
          state = state::NO_SCHEME;
12690
0
        }
12691
0
        break;
12692
0
      }
12693
0
      case state::SCHEME: {
12694
0
        ada_log("SCHEME ", helpers::substring(url_data, input_position));
12695
        // If c is an ASCII alphanumeric, U+002B (+), U+002D (-), or U+002E (.),
12696
        // append c, lowercased, to buffer.
12697
0
        while ((input_position != input_size) &&
12698
0
               (unicode::is_alnum_plus(url_data[input_position]))) {
12699
0
          input_position++;
12700
0
        }
12701
        // Otherwise, if c is U+003A (:), then:
12702
0
        if ((input_position != input_size) &&
12703
0
            (url_data[input_position] == ':')) {
12704
0
          ada_log("SCHEME the scheme should be ",
12705
0
                  url_data.substr(0, input_position));
12706
0
          if constexpr (result_type_is_ada_url) {
12707
0
            if (!url.parse_scheme(url_data.substr(0, input_position))) {
12708
0
              return url;
12709
0
            }
12710
0
          } else {
12711
            // we pass the colon along instead of painfully adding it back.
12712
0
            if (!url.parse_scheme_with_colon(
12713
0
                    url_data.substr(0, input_position + 1))) {
12714
0
              return url;
12715
0
            }
12716
0
          }
12717
0
          ada_log("SCHEME the scheme is ", url.get_protocol());
12718
12719
          // If url's scheme is "file", then:
12720
          // NOLINTNEXTLINE(bugprone-branch-clone)
12721
0
          if (url.type == scheme::type::FILE) {
12722
            // Set state to file state.
12723
0
            state = state::FILE;
12724
0
          }
12725
          // Otherwise, if url is special, base is non-null, and base's scheme
12726
          // is url's scheme: Note: Doing base_url->scheme is unsafe if base_url
12727
          // != nullptr is false.
12728
0
          else if (url.is_special() && base_url != nullptr &&
12729
0
                   base_url->type == url.type) {
12730
            // Set state to special relative or authority state.
12731
0
            state = state::SPECIAL_RELATIVE_OR_AUTHORITY;
12732
0
          }
12733
          // Otherwise, if url is special, set state to special authority
12734
          // slashes state.
12735
0
          else if (url.is_special()) {
12736
0
            state = state::SPECIAL_AUTHORITY_SLASHES;
12737
0
          }
12738
          // Otherwise, if remaining starts with an U+002F (/), set state to
12739
          // path or authority state and increase pointer by 1.
12740
0
          else if (input_position + 1 < input_size &&
12741
0
                   url_data[input_position + 1] == '/') {
12742
0
            state = state::PATH_OR_AUTHORITY;
12743
0
            input_position++;
12744
0
          }
12745
          // Otherwise, set url's path to the empty string and set state to
12746
          // opaque path state.
12747
0
          else {
12748
0
            state = state::OPAQUE_PATH;
12749
0
          }
12750
0
        }
12751
        // Otherwise, if state override is not given, set buffer to the empty
12752
        // string, state to no scheme state, and start over (from the first code
12753
        // point in input).
12754
0
        else {
12755
0
          state = state::NO_SCHEME;
12756
0
          input_position = 0;
12757
0
          break;
12758
0
        }
12759
0
        input_position++;
12760
0
        break;
12761
0
      }
12762
0
      case state::NO_SCHEME: {
12763
0
        ada_log("NO_SCHEME ", helpers::substring(url_data, input_position));
12764
        // The fragment was pruned from url_data before the state machine ran,
12765
        // so 'c is U+0023 (#)' holds exactly when a fragment was found and
12766
        // nothing else remains in front of it.
12767
0
        const bool c_is_hash =
12768
0
            fragment.has_value() && input_position == input_size;
12769
        // If base is null, or base has an opaque path and c is not U+0023 (#),
12770
        // validation error, return failure.
12771
0
        if (base_url == nullptr || (base_url->has_opaque_path && !c_is_hash)) {
12772
0
          ada_log("NO_SCHEME validation error");
12773
0
          url.is_valid = false;
12774
0
          return url;
12775
0
        }
12776
        // Otherwise, if base has an opaque path and c is U+0023 (#),
12777
        // set url's scheme to base's scheme, url's path to base's path, url's
12778
        // query to base's query, and set state to fragment state.
12779
0
        else if (base_url->has_opaque_path && c_is_hash) {
12780
0
          ada_log("NO_SCHEME opaque base with fragment");
12781
0
          url.copy_scheme(*base_url);
12782
0
          url.has_opaque_path = base_url->has_opaque_path;
12783
12784
0
          if constexpr (result_type_is_ada_url) {
12785
0
            url.path = base_url->path;
12786
0
            url.query = base_url->query;
12787
0
          } else {
12788
0
            url.update_base_pathname(base_url->get_pathname());
12789
0
            if (base_url->has_search()) {
12790
              // get_search() returns "" for an empty query string (URL ends
12791
              // with '?'). update_base_search("") would incorrectly clear the
12792
              // query, so pass "?" to preserve the empty query distinction.
12793
0
              auto s = base_url->get_search();
12794
0
              url.update_base_search(s.empty() ? std::string_view("?") : s);
12795
0
            }
12796
0
          }
12797
0
          url.update_unencoded_base_hash(*fragment);
12798
0
          enforce_max_input_length();
12799
0
          return url;
12800
0
        }
12801
        // Otherwise, if base's scheme is not "file", set state to relative
12802
        // state and decrease pointer by 1.
12803
        // NOLINTNEXTLINE(bugprone-branch-clone)
12804
0
        else if (base_url->type != scheme::type::FILE) {
12805
0
          ada_log("NO_SCHEME non-file relative path");
12806
0
          state = state::RELATIVE_SCHEME;
12807
0
        }
12808
        // Otherwise, set state to file state and decrease pointer by 1.
12809
0
        else {
12810
0
          ada_log("NO_SCHEME file base type");
12811
0
          state = state::FILE;
12812
0
        }
12813
0
        break;
12814
0
      }
12815
0
      case state::AUTHORITY: {
12816
0
        ada_log("AUTHORITY ", helpers::substring(url_data, input_position));
12817
        // most URLs have no @. Having no @ tells us that we don't have to worry
12818
        // about AUTHORITY. Of course, we could have @ and still not have to
12819
        // worry about AUTHORITY.
12820
        // TODO: Instead of just collecting a bool, collect the location of the
12821
        // '@' and do something useful with it.
12822
        // TODO: We could do various processing early on, using a single pass
12823
        // over the string to collect information about it, e.g., telling us
12824
        // whether there is a @ and if so, where (or how many).
12825
12826
        // Check if url data contains an @.
12827
0
        if (url_data.find('@', input_position) == std::string_view::npos) {
12828
0
          state = state::HOST;
12829
0
          break;
12830
0
        }
12831
0
        bool at_sign_seen{false};
12832
0
        bool password_token_seen{false};
12833
        /**
12834
         * We expect something of the sort...
12835
         * https://user:pass@example.com:1234/foo/bar?baz#quux
12836
         * --------^
12837
         */
12838
0
        do {
12839
0
          std::string_view view = url_data.substr(input_position);
12840
          // The delimiters are @, /, ? \\.
12841
0
          size_t location =
12842
0
              url.is_special() ? helpers::find_authority_delimiter_special(view)
12843
0
                               : helpers::find_authority_delimiter(view);
12844
0
          std::string_view authority_view = view.substr(0, location);
12845
0
          size_t end_of_authority = input_position + authority_view.size();
12846
          // If c is U+0040 (@), then:
12847
0
          if ((end_of_authority != input_size) &&
12848
0
              (url_data[end_of_authority] == '@')) {
12849
            // If atSignSeen is true, then prepend "%40" to buffer.
12850
0
            if (at_sign_seen) {
12851
0
              if (password_token_seen) {
12852
0
                if constexpr (result_type_is_ada_url) {
12853
0
                  url.password += "%40";
12854
0
                } else {
12855
0
                  url.append_base_password("%40");
12856
0
                }
12857
0
              } else {
12858
0
                if constexpr (result_type_is_ada_url) {
12859
0
                  url.username += "%40";
12860
0
                } else {
12861
0
                  url.append_base_username("%40");
12862
0
                }
12863
0
              }
12864
0
            }
12865
12866
0
            at_sign_seen = true;
12867
12868
0
            if (!password_token_seen) {
12869
0
              size_t password_token_location = authority_view.find(':');
12870
0
              password_token_seen =
12871
0
                  password_token_location != std::string_view::npos;
12872
12873
0
              if constexpr (store_values) {
12874
0
                if (!password_token_seen) {
12875
0
                  if constexpr (result_type_is_ada_url) {
12876
0
                    url.username += unicode::percent_encode(
12877
0
                        authority_view,
12878
0
                        character_sets::USERINFO_PERCENT_ENCODE);
12879
0
                  } else {
12880
0
                    url.append_base_username(unicode::percent_encode(
12881
0
                        authority_view,
12882
0
                        character_sets::USERINFO_PERCENT_ENCODE));
12883
0
                  }
12884
0
                } else {
12885
0
                  if constexpr (result_type_is_ada_url) {
12886
0
                    url.username += unicode::percent_encode(
12887
0
                        authority_view.substr(0, password_token_location),
12888
0
                        character_sets::USERINFO_PERCENT_ENCODE);
12889
0
                    url.password += unicode::percent_encode(
12890
0
                        authority_view.substr(password_token_location + 1),
12891
0
                        character_sets::USERINFO_PERCENT_ENCODE);
12892
0
                  } else {
12893
0
                    url.append_base_username(unicode::percent_encode(
12894
0
                        authority_view.substr(0, password_token_location),
12895
0
                        character_sets::USERINFO_PERCENT_ENCODE));
12896
0
                    url.append_base_password(unicode::percent_encode(
12897
0
                        authority_view.substr(password_token_location + 1),
12898
0
                        character_sets::USERINFO_PERCENT_ENCODE));
12899
0
                  }
12900
0
                }
12901
0
              }
12902
0
            } else if constexpr (store_values) {
12903
0
              if constexpr (result_type_is_ada_url) {
12904
0
                url.password += unicode::percent_encode(
12905
0
                    authority_view, character_sets::USERINFO_PERCENT_ENCODE);
12906
0
              } else {
12907
0
                url.append_base_password(unicode::percent_encode(
12908
0
                    authority_view, character_sets::USERINFO_PERCENT_ENCODE));
12909
0
              }
12910
0
            }
12911
0
          }
12912
          // Otherwise, if one of the following is true:
12913
          // - c is the EOF code point, U+002F (/), U+003F (?), or U+0023 (#)
12914
          // - url is special and c is U+005C (\)
12915
0
          else if (end_of_authority == input_size ||
12916
0
                   url_data[end_of_authority] == '/' ||
12917
0
                   url_data[end_of_authority] == '?' ||
12918
0
                   (url.is_special() && url_data[end_of_authority] == '\\')) {
12919
            // If atSignSeen is true and authority_view is the empty string,
12920
            // validation error, return failure.
12921
0
            if (at_sign_seen && authority_view.empty()) {
12922
0
              url.is_valid = false;
12923
0
              return url;
12924
0
            }
12925
0
            state = state::HOST;
12926
0
            break;
12927
0
          }
12928
0
          if (end_of_authority == input_size) {
12929
0
            if constexpr (store_values) {
12930
0
              if (fragment.has_value()) {
12931
0
                url.update_unencoded_base_hash(*fragment);
12932
0
              }
12933
0
            }
12934
0
            enforce_max_input_length();
12935
0
            return url;
12936
0
          }
12937
0
          input_position = end_of_authority + 1;
12938
0
        } while (true);
12939
12940
0
        break;
12941
0
      }
12942
0
      case state::SPECIAL_RELATIVE_OR_AUTHORITY: {
12943
0
        ada_log("SPECIAL_RELATIVE_OR_AUTHORITY ",
12944
0
                helpers::substring(url_data, input_position));
12945
12946
        // If c is U+002F (/) and remaining starts with U+002F (/),
12947
        // then set state to special authority ignore slashes state and increase
12948
        // pointer by 1.
12949
0
        if (url_data.substr(input_position, 2) == "//") {
12950
0
          state = state::SPECIAL_AUTHORITY_IGNORE_SLASHES;
12951
0
          input_position += 2;
12952
0
        } else {
12953
          // Otherwise, validation error, set state to relative state and
12954
          // decrease pointer by 1.
12955
0
          state = state::RELATIVE_SCHEME;
12956
0
        }
12957
12958
0
        break;
12959
0
      }
12960
0
      case state::PATH_OR_AUTHORITY: {
12961
0
        ada_log("PATH_OR_AUTHORITY ",
12962
0
                helpers::substring(url_data, input_position));
12963
12964
        // If c is U+002F (/), then set state to authority state.
12965
0
        if ((input_position != input_size) &&
12966
0
            (url_data[input_position] == '/')) {
12967
0
          state = state::AUTHORITY;
12968
0
          input_position++;
12969
0
        } else {
12970
          // Otherwise, set state to path state, and decrease pointer by 1.
12971
0
          state = state::PATH;
12972
0
        }
12973
12974
0
        break;
12975
0
      }
12976
0
      case state::RELATIVE_SCHEME: {
12977
0
        ada_log("RELATIVE_SCHEME ",
12978
0
                helpers::substring(url_data, input_position));
12979
12980
        // Set url's scheme to base's scheme.
12981
0
        url.copy_scheme(*base_url);
12982
12983
        // If c is U+002F (/), then set state to relative slash state.
12984
0
        if ((input_position != input_size) &&
12985
            // NOLINTNEXTLINE(bugprone-branch-clone)
12986
0
            (url_data[input_position] == '/')) {
12987
0
          ada_log(
12988
0
              "RELATIVE_SCHEME if c is U+002F (/), then set state to relative "
12989
0
              "slash state");
12990
0
          state = state::RELATIVE_SLASH;
12991
0
        } else if (url.is_special() && (input_position != input_size) &&
12992
0
                   (url_data[input_position] == '\\')) {
12993
          // Otherwise, if url is special and c is U+005C (\), validation error,
12994
          // set state to relative slash state.
12995
0
          ada_log(
12996
0
              "RELATIVE_SCHEME  if url is special and c is U+005C, validation "
12997
0
              "error, set state to relative slash state");
12998
0
          state = state::RELATIVE_SLASH;
12999
0
        } else {
13000
0
          ada_log("RELATIVE_SCHEME otherwise");
13001
          // Set url's username to base's username, url's password to base's
13002
          // password, url's host to base's host, url's port to base's port,
13003
          // url's path to a clone of base's path, and url's query to base's
13004
          // query.
13005
0
          if constexpr (result_type_is_ada_url) {
13006
0
            url.username = base_url->username;
13007
0
            url.password = base_url->password;
13008
0
            url.host = base_url->host;
13009
0
            url.port = base_url->port;
13010
            // cloning the base path includes cloning the has_opaque_path flag
13011
0
            url.has_opaque_path = base_url->has_opaque_path;
13012
0
            url.path = base_url->path;
13013
0
            url.query = base_url->query;
13014
0
          } else {
13015
0
            url.update_base_authority(base_url->get_href(),
13016
0
                                      base_url->get_components());
13017
0
            url.update_host_to_base_host(base_url->get_hostname());
13018
0
            url.update_base_port(base_url->retrieve_base_port());
13019
            // cloning the base path includes cloning the has_opaque_path flag
13020
0
            url.has_opaque_path = base_url->has_opaque_path;
13021
0
            url.update_base_pathname(base_url->get_pathname());
13022
0
            if (base_url->has_search()) {
13023
              // get_search() returns "" for an empty query string (URL ends
13024
              // with '?'). update_base_search("") would incorrectly clear the
13025
              // query, so pass "?" to preserve the empty query distinction.
13026
0
              auto s = base_url->get_search();
13027
0
              url.update_base_search(s.empty() ? std::string_view("?") : s);
13028
0
            }
13029
0
          }
13030
13031
0
          url.has_opaque_path = base_url->has_opaque_path;
13032
13033
          // If c is U+003F (?), then set url's query to the empty string, and
13034
          // state to query state.
13035
0
          if ((input_position != input_size) &&
13036
0
              (url_data[input_position] == '?')) {
13037
0
            state = state::QUERY;
13038
0
          }
13039
          // Otherwise, if c is not the EOF code point:
13040
0
          else if (input_position != input_size) {
13041
            // Set url's query to null.
13042
0
            url.clear_search();
13043
0
            if constexpr (result_type_is_ada_url) {
13044
              // Shorten url's path.
13045
0
              helpers::shorten_path(url.path, url.type);
13046
0
            } else {
13047
0
              std::string_view path = url.get_pathname();
13048
0
              if (helpers::shorten_path(path, url.type)) {
13049
0
                url.update_base_pathname(std::move(std::string(path)));
13050
0
              }
13051
0
            }
13052
            // Set state to path state and decrease pointer by 1.
13053
0
            state = state::PATH;
13054
0
            break;
13055
0
          }
13056
0
        }
13057
0
        input_position++;
13058
0
        break;
13059
0
      }
13060
0
      case state::RELATIVE_SLASH: {
13061
0
        ada_log("RELATIVE_SLASH ",
13062
0
                helpers::substring(url_data, input_position));
13063
13064
        // If url is special and c is U+002F (/) or U+005C (\), then:
13065
        // NOLINTNEXTLINE(bugprone-branch-clone)
13066
0
        if (url.is_special() && (input_position != input_size) &&
13067
0
            (url_data[input_position] == '/' ||
13068
0
             url_data[input_position] == '\\')) {
13069
          // Set state to special authority ignore slashes state.
13070
0
          state = state::SPECIAL_AUTHORITY_IGNORE_SLASHES;
13071
0
        }
13072
        // Otherwise, if c is U+002F (/), then set state to authority state.
13073
0
        else if ((input_position != input_size) &&
13074
0
                 (url_data[input_position] == '/')) {
13075
0
          state = state::AUTHORITY;
13076
0
        }
13077
        // Otherwise, set
13078
        // - url's username to base's username,
13079
        // - url's password to base's password,
13080
        // - url's host to base's host,
13081
        // - url's port to base's port,
13082
        // - state to path state, and then, decrease pointer by 1.
13083
0
        else {
13084
0
          if constexpr (result_type_is_ada_url) {
13085
0
            url.username = base_url->username;
13086
0
            url.password = base_url->password;
13087
0
            url.host = base_url->host;
13088
0
            url.port = base_url->port;
13089
0
          } else {
13090
0
            url.update_base_authority(base_url->get_href(),
13091
0
                                      base_url->get_components());
13092
0
            url.update_host_to_base_host(base_url->get_hostname());
13093
0
            url.update_base_port(base_url->retrieve_base_port());
13094
0
          }
13095
0
          state = state::PATH;
13096
0
          break;
13097
0
        }
13098
13099
0
        input_position++;
13100
0
        break;
13101
0
      }
13102
0
      case state::SPECIAL_AUTHORITY_SLASHES: {
13103
0
        ada_log("SPECIAL_AUTHORITY_SLASHES ",
13104
0
                helpers::substring(url_data, input_position));
13105
13106
        // If c is U+002F (/) and remaining starts with U+002F (/),
13107
        // then set state to special authority ignore slashes state and increase
13108
        // pointer by 1.
13109
0
        if (url_data.substr(input_position, 2) == "//") {
13110
0
          input_position += 2;
13111
0
        }
13112
13113
0
        [[fallthrough]];
13114
0
      }
13115
0
      case state::SPECIAL_AUTHORITY_IGNORE_SLASHES: {
13116
0
        ada_log("SPECIAL_AUTHORITY_IGNORE_SLASHES ",
13117
0
                helpers::substring(url_data, input_position));
13118
13119
        // If c is neither U+002F (/) nor U+005C (\), then set state to
13120
        // authority state and decrease pointer by 1.
13121
0
        while ((input_position != input_size) &&
13122
0
               ((url_data[input_position] == '/') ||
13123
0
                (url_data[input_position] == '\\'))) {
13124
0
          input_position++;
13125
0
        }
13126
0
        state = state::AUTHORITY;
13127
13128
0
        break;
13129
0
      }
13130
0
      case state::QUERY: {
13131
0
        ada_log("QUERY ", helpers::substring(url_data, input_position));
13132
0
        if constexpr (store_values) {
13133
          // Let queryPercentEncodeSet be the special-query percent-encode set
13134
          // if url is special; otherwise the query percent-encode set.
13135
0
          const uint8_t* query_percent_encode_set =
13136
0
              url.is_special() ? character_sets::SPECIAL_QUERY_PERCENT_ENCODE
13137
0
                               : character_sets::QUERY_PERCENT_ENCODE;
13138
13139
          // Percent-encode after encoding, with encoding, buffer, and
13140
          // queryPercentEncodeSet, and append the result to url's query.
13141
0
          url.update_base_search(url_data.substr(input_position),
13142
0
                                 query_percent_encode_set);
13143
0
          ada_log("QUERY update_base_search completed ");
13144
0
          if (fragment.has_value()) {
13145
0
            url.update_unencoded_base_hash(*fragment);
13146
0
          }
13147
0
        }
13148
0
        enforce_max_input_length();
13149
0
        return url;
13150
0
      }
13151
0
      case state::HOST: {
13152
0
        ada_log("HOST ", helpers::substring(url_data, input_position));
13153
13154
0
        std::string_view host_view = url_data.substr(input_position);
13155
0
        auto [location, found_colon] =
13156
0
            helpers::get_host_delimiter_location(url.is_special(), host_view);
13157
0
        input_position = (location != std::string_view::npos)
13158
0
                             ? input_position + location
13159
0
                             : input_size;
13160
        // Otherwise, if c is U+003A (:) and insideBrackets is false, then:
13161
        // Note: the 'found_colon' value is true if and only if a colon was
13162
        // encountered while not inside brackets.
13163
0
        if (found_colon) {
13164
          // If buffer is the empty string, validation error, return failure.
13165
          // Let host be the result of host parsing buffer with url is not
13166
          // special.
13167
0
          ada_log("HOST parsing ", host_view);
13168
0
          if (!url.parse_host(host_view)) {
13169
0
            return url;
13170
0
          }
13171
0
          ada_log("HOST parsing results in ", url.get_hostname());
13172
          // Set url's host to host, buffer to the empty string, and state to
13173
          // port state.
13174
0
          state = state::PORT;
13175
0
          input_position++;
13176
0
        }
13177
        // Otherwise, if one of the following is true:
13178
        // - c is the EOF code point, U+002F (/), U+003F (?), or U+0023 (#)
13179
        // - url is special and c is U+005C (\)
13180
        // The get_host_delimiter_location function either brings us to
13181
        // the colon outside of the bracket, or to one of those characters.
13182
0
        else {
13183
          // If url is special and host_view is the empty string, validation
13184
          // error, return failure.
13185
0
          if (host_view.empty() && url.is_special()) {
13186
0
            url.is_valid = false;
13187
0
            return url;
13188
0
          }
13189
0
          ada_log("HOST parsing ", host_view, " href=", url.get_href());
13190
          // Let host be the result of host parsing host_view with url is not
13191
          // special.
13192
0
          if (host_view.empty()) {
13193
0
            url.update_base_hostname("");
13194
0
          } else if (!url.parse_host(host_view)) {
13195
0
            return url;
13196
0
          }
13197
0
          ada_log("HOST parsing results in ", url.get_hostname(),
13198
0
                  " href=", url.get_href());
13199
13200
          // Set url's host to host, and state to path start state.
13201
0
          state = state::PATH_START;
13202
0
        }
13203
13204
0
        break;
13205
0
      }
13206
0
      case state::OPAQUE_PATH: {
13207
0
        ada_log("OPAQUE_PATH ", helpers::substring(url_data, input_position));
13208
        // Opaque path, query, and fragment are structurally always valid:
13209
        // the parser would just percent-encode whatever is there. When we
13210
        // are not storing values (can_parse), we can return immediately.
13211
        // We must set has_opaque_path = true before returning so that when
13212
        // this URL is used as an internal base inside can_parse, NO_SCHEME
13213
        // correctly rejects relative inputs against an opaque-path base
13214
        // (e.g. can_parse("", &"W:") must return false).
13215
0
        if constexpr (!store_values) {
13216
0
          url.has_opaque_path = true;
13217
0
          return url;
13218
0
        }
13219
0
        std::string_view view = url_data.substr(input_position);
13220
        // If c is U+003F (?), then set url's query to the empty string and
13221
        // state to query state.
13222
0
        size_t location = view.find('?');
13223
0
        if (location != std::string_view::npos) {
13224
0
          view.remove_suffix(view.size() - location);
13225
0
          state = state::QUERY;
13226
0
          input_position += location + 1;
13227
0
        } else {
13228
0
          input_position = input_size + 1;
13229
0
        }
13230
0
        url.has_opaque_path = true;
13231
13232
        // This is a really unlikely scenario in real world. We should not seek
13233
        // to optimize it.
13234
0
        if (view.ends_with(' ')) {
13235
0
          std::string modified_view =
13236
0
              std::string(view.substr(0, view.size() - 1)) + "%20";
13237
0
          url.update_base_pathname(unicode::percent_encode(
13238
0
              modified_view, character_sets::C0_CONTROL_PERCENT_ENCODE));
13239
0
        } else {
13240
0
          url.update_base_pathname(unicode::percent_encode(
13241
0
              view, character_sets::C0_CONTROL_PERCENT_ENCODE));
13242
0
        }
13243
0
        break;
13244
0
      }
13245
0
      case state::PORT: {
13246
0
        ada_log("PORT ", helpers::substring(url_data, input_position));
13247
0
        std::string_view port_view = url_data.substr(input_position);
13248
0
        input_position += url.parse_port(port_view, true);
13249
0
        if (!url.is_valid) {
13250
0
          return url;
13251
0
        }
13252
0
        state = state::PATH_START;
13253
0
        [[fallthrough]];
13254
0
      }
13255
0
      case state::PATH_START: {
13256
0
        ada_log("PATH_START ", helpers::substring(url_data, input_position));
13257
        // Path, query, and fragment are structurally always valid: the
13258
        // parser would just percent-encode whatever is there. When we are
13259
        // not storing values (can_parse), we can return immediately since
13260
        // no subsequent state can invalidate the URL.
13261
0
        if constexpr (!store_values) {
13262
0
          return url;
13263
0
        }
13264
13265
        // If url is special, then:
13266
0
        if (url.is_special()) {
13267
          // Set state to path state.
13268
0
          state = state::PATH;
13269
13270
          // Optimization: Avoiding going into PATH state improves the
13271
          // performance of urls ending with /.
13272
0
          if (input_position == input_size) {
13273
0
            if constexpr (store_values) {
13274
0
              url.update_base_pathname("/");
13275
0
              if (fragment.has_value()) {
13276
0
                url.update_unencoded_base_hash(*fragment);
13277
0
              }
13278
0
            }
13279
0
            enforce_max_input_length();
13280
0
            return url;
13281
0
          }
13282
          // If c is neither U+002F (/) nor U+005C (\), then decrease pointer
13283
          // by 1. We know that (input_position == input_size) is impossible
13284
          // here, because of the previous if-check.
13285
0
          if ((url_data[input_position] != '/') &&
13286
0
              (url_data[input_position] != '\\')) {
13287
0
            break;
13288
0
          }
13289
0
        }
13290
        // Otherwise, if state override is not given and c is U+003F (?),
13291
        // set url's query to the empty string and state to query state.
13292
0
        else if ((input_position != input_size) &&
13293
0
                 (url_data[input_position] == '?')) {
13294
0
          state = state::QUERY;
13295
0
        }
13296
        // Otherwise, if c is not the EOF code point:
13297
0
        else if (input_position != input_size) {
13298
          // Set state to path state.
13299
0
          state = state::PATH;
13300
13301
          // If c is not U+002F (/), then decrease pointer by 1.
13302
0
          if (url_data[input_position] != '/') {
13303
0
            break;
13304
0
          }
13305
0
        }
13306
13307
0
        input_position++;
13308
0
        break;
13309
0
      }
13310
0
      case state::PATH: {
13311
0
        ada_log("PATH ", helpers::substring(url_data, input_position));
13312
        // Path, query, and fragment are structurally always valid: the
13313
        // parser would just percent-encode whatever is there. When we are
13314
        // not storing values (can_parse), we can return immediately since
13315
        // no subsequent state can invalidate the URL.
13316
0
        if constexpr (!store_values) {
13317
0
          return url;
13318
0
        }
13319
0
        std::string_view view = url_data.substr(input_position);
13320
13321
        // Most time, we do not need percent encoding.
13322
        // Furthermore, we can immediately locate the '?'.
13323
0
        size_t locofquestionmark = view.find('?');
13324
0
        if (locofquestionmark != std::string_view::npos) {
13325
0
          state = state::QUERY;
13326
0
          view.remove_suffix(view.size() - locofquestionmark);
13327
0
          input_position += locofquestionmark + 1;
13328
0
        } else {
13329
0
          input_position = input_size + 1;
13330
0
        }
13331
0
        if constexpr (store_values) {
13332
0
          if constexpr (result_type_is_ada_url) {
13333
0
            helpers::parse_prepared_path(view, url.type, url.path);
13334
0
          } else {
13335
0
            url.consume_prepared_path(view);
13336
0
            ADA_ASSERT_TRUE(url.validate());
13337
0
          }
13338
0
        }
13339
0
        break;
13340
0
      }
13341
0
      case state::FILE_SLASH: {
13342
0
        ada_log("FILE_SLASH ", helpers::substring(url_data, input_position));
13343
13344
        // If c is U+002F (/) or U+005C (\), then:
13345
0
        if ((input_position != input_size) &&
13346
0
            (url_data[input_position] == '/' ||
13347
0
             url_data[input_position] == '\\')) {
13348
0
          ada_log("FILE_SLASH c is U+002F or U+005C");
13349
          // Set state to file host state.
13350
0
          state = state::FILE_HOST;
13351
0
          input_position++;
13352
0
        } else {
13353
0
          ada_log("FILE_SLASH otherwise");
13354
          // If base is non-null and base's scheme is "file", then:
13355
          // Note: it is unsafe to do base_url->scheme unless you know that
13356
          // base_url_has_value() is true.
13357
0
          if (base_url != nullptr && base_url->type == scheme::type::FILE) {
13358
            // Set url's host to base's host.
13359
0
            if constexpr (result_type_is_ada_url) {
13360
0
              url.host = base_url->host;
13361
0
            } else {
13362
0
              url.update_host_to_base_host(base_url->get_host());
13363
0
            }
13364
            // If the code point substring from pointer to the end of input does
13365
            // not start with a Windows drive letter and base's path[0] is a
13366
            // normalized Windows drive letter, then append base's path[0] to
13367
            // url's path.
13368
0
            if (!base_url->get_pathname().empty()) {
13369
0
              if (!checkers::is_windows_drive_letter(
13370
0
                      url_data.substr(input_position))) {
13371
0
                std::string_view first_base_url_path =
13372
0
                    base_url->get_pathname().substr(1);
13373
0
                size_t loc = first_base_url_path.find('/');
13374
0
                if (loc != std::string_view::npos) {
13375
0
                  helpers::resize(first_base_url_path, loc);
13376
0
                }
13377
0
                if (checkers::is_normalized_windows_drive_letter(
13378
0
                        first_base_url_path)) {
13379
0
                  if constexpr (result_type_is_ada_url) {
13380
0
                    url.path += '/';
13381
0
                    url.path += first_base_url_path;
13382
0
                  } else {
13383
0
                    url.append_base_pathname(
13384
0
                        helpers::concat("/", first_base_url_path));
13385
0
                  }
13386
0
                }
13387
0
              }
13388
0
            }
13389
0
          }
13390
13391
          // Set state to path state, and decrease pointer by 1.
13392
0
          state = state::PATH;
13393
0
        }
13394
13395
0
        break;
13396
0
      }
13397
0
      case state::FILE_HOST: {
13398
0
        ada_log("FILE_HOST ", helpers::substring(url_data, input_position));
13399
0
        std::string_view view = url_data.substr(input_position);
13400
13401
0
        size_t location = view.find_first_of("/\\?");
13402
0
        std::string_view file_host_buffer = view.substr(
13403
0
            0, (location != std::string_view::npos) ? location : view.size());
13404
13405
0
        if (checkers::is_windows_drive_letter(file_host_buffer)) {
13406
0
          state = state::PATH;
13407
0
        } else if (file_host_buffer.empty()) {
13408
          // Set url's host to the empty string.
13409
0
          if constexpr (result_type_is_ada_url) {
13410
0
            url.host = "";
13411
0
          } else {
13412
0
            url.update_base_hostname("");
13413
0
          }
13414
          // Set state to path start state.
13415
0
          state = state::PATH_START;
13416
0
        } else {
13417
0
          size_t consumed_bytes = file_host_buffer.size();
13418
0
          input_position += consumed_bytes;
13419
          // Let host be the result of host parsing buffer with url is not
13420
          // special.
13421
0
          if (!url.parse_host(file_host_buffer)) {
13422
0
            return url;
13423
0
          }
13424
13425
0
          if constexpr (result_type_is_ada_url) {
13426
            // If host is "localhost", then set host to the empty string.
13427
0
            if (url.host.has_value() && url.host.value() == "localhost") {
13428
0
              url.host = "";
13429
0
            }
13430
0
          } else {
13431
0
            if (url.get_hostname() == "localhost") {
13432
0
              url.update_base_hostname("");
13433
0
            }
13434
0
          }
13435
13436
          // Set buffer to the empty string and state to path start state.
13437
0
          state = state::PATH_START;
13438
0
        }
13439
13440
0
        break;
13441
0
      }
13442
0
      case state::FILE: {
13443
0
        ada_log("FILE ", helpers::substring(url_data, input_position));
13444
0
        std::string_view file_view = url_data.substr(input_position);
13445
13446
0
        url.set_protocol_as_file();
13447
0
        if constexpr (result_type_is_ada_url) {
13448
          // Set url's host to the empty string.
13449
0
          url.host = "";
13450
0
        } else {
13451
0
          url.update_base_hostname("");
13452
0
        }
13453
        // If c is U+002F (/) or U+005C (\), then:
13454
0
        if (input_position != input_size &&
13455
0
            (url_data[input_position] == '/' ||
13456
0
             url_data[input_position] == '\\')) {
13457
0
          ada_log("FILE c is U+002F or U+005C");
13458
          // Set state to file slash state.
13459
0
          state = state::FILE_SLASH;
13460
0
        }
13461
        // Otherwise, if base is non-null and base's scheme is "file":
13462
0
        else if (base_url != nullptr && base_url->type == scheme::type::FILE) {
13463
          // Set url's host to base's host, url's path to a clone of base's
13464
          // path, and url's query to base's query.
13465
0
          ada_log("FILE base non-null");
13466
0
          if constexpr (result_type_is_ada_url) {
13467
0
            url.host = base_url->host;
13468
0
            url.path = base_url->path;
13469
0
            url.query = base_url->query;
13470
0
          } else {
13471
0
            url.update_host_to_base_host(base_url->get_hostname());
13472
0
            url.update_base_pathname(base_url->get_pathname());
13473
0
            if (base_url->has_search()) {
13474
              // get_search() returns "" for an empty query string (URL ends
13475
              // with '?'). update_base_search("") would incorrectly clear the
13476
              // query, so pass "?" to preserve the empty query distinction.
13477
0
              auto s = base_url->get_search();
13478
0
              url.update_base_search(s.empty() ? std::string_view("?") : s);
13479
0
            }
13480
0
          }
13481
0
          url.has_opaque_path = base_url->has_opaque_path;
13482
13483
          // If c is U+003F (?), then set url's query to the empty string and
13484
          // state to query state.
13485
0
          if (input_position != input_size && url_data[input_position] == '?') {
13486
0
            state = state::QUERY;
13487
0
          }
13488
          // Otherwise, if c is not the EOF code point:
13489
0
          else if (input_position != input_size) {
13490
            // Set url's query to null.
13491
0
            url.clear_search();
13492
            // If the code point substring from pointer to the end of input does
13493
            // not start with a Windows drive letter, then shorten url's path.
13494
0
            if (!checkers::is_windows_drive_letter(file_view)) {
13495
0
              if constexpr (result_type_is_ada_url) {
13496
0
                helpers::shorten_path(url.path, url.type);
13497
0
              } else {
13498
0
                std::string_view path = url.get_pathname();
13499
0
                if (helpers::shorten_path(path, url.type)) {
13500
0
                  url.update_base_pathname(std::move(std::string(path)));
13501
0
                }
13502
0
              }
13503
0
            }
13504
            // Otherwise:
13505
0
            else {
13506
              // Set url's path to an empty list.
13507
0
              url.clear_pathname();
13508
0
              url.has_opaque_path = true;
13509
0
            }
13510
13511
            // Set state to path state and decrease pointer by 1.
13512
0
            state = state::PATH;
13513
0
            break;
13514
0
          }
13515
0
        }
13516
        // Otherwise, set state to path state, and decrease pointer by 1.
13517
0
        else {
13518
0
          ada_log("FILE go to path");
13519
0
          state = state::PATH;
13520
0
          break;
13521
0
        }
13522
13523
0
        input_position++;
13524
0
        break;
13525
0
      }
13526
0
      default:
13527
0
        unreachable();
13528
0
    }
13529
0
  }
13530
0
  if constexpr (store_values) {
13531
0
    if (fragment.has_value()) {
13532
0
      url.update_unencoded_base_hash(*fragment);
13533
0
    }
13534
0
  }
13535
0
  enforce_max_input_length();
13536
0
  return url;
13537
0
}
Unexecuted instantiation: ada::url ada::parser::parse_url_impl<ada::url, true>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url const*)
Unexecuted instantiation: ada::url_aggregator ada::parser::parse_url_impl<ada::url_aggregator, true>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url_aggregator const*)
Unexecuted instantiation: ada::url_aggregator ada::parser::parse_url_impl<ada::url_aggregator, false>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url_aggregator const*)
13538
13539
template bool try_parse_simple_absolute<url>(std::string_view, url&);
13540
template bool try_parse_simple_absolute<url_aggregator>(std::string_view,
13541
                                                        url_aggregator&);
13542
template bool finish_simple_absolute_with_port<url>(std::string_view, url&,
13543
                                                    ada::scheme::type, uint32_t,
13544
                                                    size_t, size_t, size_t,
13545
                                                    bool);
13546
template bool finish_simple_absolute_with_port<url_aggregator>(
13547
    std::string_view, url_aggregator&, ada::scheme::type, uint32_t, size_t,
13548
    size_t, size_t, bool);
13549
template bool try_parse_simple_relative<url>(std::string_view, const url&,
13550
                                             url&);
13551
template bool try_parse_simple_relative<url_aggregator>(std::string_view,
13552
                                                        const url_aggregator&,
13553
                                                        url_aggregator&);
13554
13555
template url parse_url_impl<url, true>(std::string_view user_input,
13556
                                       const url* base_url = nullptr);
13557
template url_aggregator parse_url_impl<url_aggregator, true>(
13558
    std::string_view user_input, const url_aggregator* base_url = nullptr);
13559
template url_aggregator parse_url_impl<url_aggregator, false>(
13560
    std::string_view user_input, const url_aggregator* base_url = nullptr);
13561
13562
template <class result_type>
13563
result_type parse_url(std::string_view user_input,
13564
0
                      const result_type* base_url) {
13565
0
  return parse_url_impl<result_type, true>(user_input, base_url);
13566
0
}
Unexecuted instantiation: ada::url ada::parser::parse_url<ada::url>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url const*)
Unexecuted instantiation: ada::url_aggregator ada::parser::parse_url<ada::url_aggregator>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url_aggregator const*)
13567
13568
template url parse_url<url>(std::string_view user_input,
13569
                            const url* base_url = nullptr);
13570
template url_aggregator parse_url<url_aggregator>(
13571
    std::string_view user_input, const url_aggregator* base_url = nullptr);
13572
}  // namespace ada::parser
13573
/* end file src/parser.cpp */
13574
/* begin file src/url_components.cpp */
13575
13576
#include <iterator>
13577
#include <string>
13578
13579
namespace ada {
13580
13581
0
[[nodiscard]] std::string url_components::to_string() const {
13582
0
  std::string answer;
13583
0
  auto back = std::back_insert_iterator(answer);
13584
0
  answer.append("{\n");
13585
13586
0
  answer.append("\t\"protocol_end\":\"");
13587
0
  helpers::encode_json(std::to_string(protocol_end), back);
13588
0
  answer.append("\",\n");
13589
13590
0
  answer.append("\t\"username_end\":\"");
13591
0
  helpers::encode_json(std::to_string(username_end), back);
13592
0
  answer.append("\",\n");
13593
13594
0
  answer.append("\t\"host_start\":\"");
13595
0
  helpers::encode_json(std::to_string(host_start), back);
13596
0
  answer.append("\",\n");
13597
13598
0
  answer.append("\t\"host_end\":\"");
13599
0
  helpers::encode_json(std::to_string(host_end), back);
13600
0
  answer.append("\",\n");
13601
13602
0
  answer.append("\t\"port\":\"");
13603
0
  helpers::encode_json(std::to_string(port), back);
13604
0
  answer.append("\",\n");
13605
13606
0
  answer.append("\t\"pathname_start\":\"");
13607
0
  helpers::encode_json(std::to_string(pathname_start), back);
13608
0
  answer.append("\",\n");
13609
13610
0
  answer.append("\t\"search_start\":\"");
13611
0
  helpers::encode_json(std::to_string(search_start), back);
13612
0
  answer.append("\",\n");
13613
13614
0
  answer.append("\t\"hash_start\":\"");
13615
0
  helpers::encode_json(std::to_string(hash_start), back);
13616
0
  answer.append("\",\n");
13617
13618
0
  answer.append("\n}");
13619
0
  return answer;
13620
0
}
13621
13622
}  // namespace ada
13623
/* end file src/url_components.cpp */
13624
/* begin file src/url_aggregator.cpp */
13625
13626
#include <array>
13627
#include <cstdint>
13628
#include <cstring>
13629
#include <iterator>
13630
#include <ranges>
13631
#include <string>
13632
#include <string_view>
13633
13634
namespace {
13635
13636
ada_really_inline void apply_shifted_non_scheme_offsets(
13637
0
    ada::url_components& components, uint32_t new_difference) {
13638
0
  components.username_end += new_difference;
13639
0
  components.host_start += new_difference;
13640
0
  components.host_end += new_difference;
13641
0
  components.pathname_start += new_difference;
13642
0
  if (components.search_start != ada::url_components::omitted) {
13643
0
    components.search_start += new_difference;
13644
0
  }
13645
0
  if (components.hash_start != ada::url_components::omitted) {
13646
0
    components.hash_start += new_difference;
13647
0
  }
13648
0
}
13649
13650
}  // namespace
13651
13652
namespace ada {
13653
template <bool has_state_override>
13654
[[nodiscard]] ada_really_inline bool url_aggregator::parse_scheme_with_colon(
13655
0
    const std::string_view input_with_colon) {
13656
0
  ada_log("url_aggregator::parse_scheme_with_colon ", input_with_colon);
13657
0
  ADA_ASSERT_TRUE(validate());
13658
0
  ADA_ASSERT_TRUE(!helpers::overlaps(input_with_colon, buffer));
13659
0
  std::string_view input{input_with_colon};
13660
0
  input.remove_suffix(1);
13661
0
  auto parsed_type = ada::scheme::get_scheme_type(input);
13662
0
  const bool is_input_special = (parsed_type != ada::scheme::NOT_SPECIAL);
13663
  /**
13664
   * In the common case, we will immediately recognize a special scheme (e.g.,
13665
   *http, https), in which case, we can go really fast.
13666
   **/
13667
0
  if (is_input_special) {  // fast path!!!
13668
0
    if constexpr (has_state_override) {
13669
      // If url's scheme is not a special scheme and buffer is a special scheme,
13670
      // then return.
13671
0
      if (is_special() != is_input_special) {
13672
0
        return false;
13673
0
      }
13674
13675
      // If url includes credentials or has a non-null port, and buffer is
13676
      // "file", then return.
13677
0
      if ((has_credentials() || components.port != url_components::omitted) &&
13678
0
          parsed_type == ada::scheme::type::FILE) {
13679
0
        return false;
13680
0
      }
13681
13682
      // If url's scheme is "file" and its host is an empty host, then return.
13683
      // An empty host is the empty string.
13684
0
      if (type == ada::scheme::type::FILE &&
13685
0
          components.host_start == components.host_end) {
13686
0
        return false;
13687
0
      }
13688
0
    }
13689
13690
0
    type = parsed_type;
13691
0
    set_scheme_from_view_with_colon(input_with_colon);
13692
13693
0
    if constexpr (has_state_override) {
13694
      // This is uncommon.
13695
0
      uint16_t urls_scheme_port = get_special_port();
13696
13697
0
      if (urls_scheme_port) {
13698
        // If url's port is url's scheme's default port, then set url's port to
13699
        // null.
13700
0
        if (components.port == urls_scheme_port) {
13701
0
          clear_port();
13702
0
        }
13703
0
      }
13704
0
    }
13705
0
  } else {  // slow path
13706
0
    std::string _buffer(input);
13707
    // Next function is only valid if the input is ASCII and returns false
13708
    // otherwise, but it seems that we always have ascii content so we do not
13709
    // need to check the return value.
13710
0
    unicode::to_lower_ascii(_buffer.data(), _buffer.size());
13711
13712
0
    if constexpr (has_state_override) {
13713
      // The state-override validation errors below ("return" in the WHATWG URL
13714
      // parser) leave the URL unchanged. The setter contract is
13715
      // "true on success, false if the scheme is invalid" -- the fast path
13716
      // above already returns false here, so the slow path must agree.
13717
13718
      // If url's scheme is a special scheme and buffer is not a special scheme,
13719
      // then return. If url's scheme is not a special scheme and buffer is a
13720
      // special scheme, then return.
13721
0
      if (is_special() != ada::scheme::is_special(_buffer)) {
13722
0
        return false;
13723
0
      }
13724
13725
      // If url includes credentials or has a non-null port, and buffer is
13726
      // "file", then return.
13727
0
      if ((has_credentials() || components.port != url_components::omitted) &&
13728
0
          _buffer == "file") {
13729
0
        return false;
13730
0
      }
13731
13732
      // If url's scheme is "file" and its host is an empty host, then return.
13733
      // An empty host is the empty string.
13734
0
      if (type == ada::scheme::type::FILE &&
13735
0
          components.host_start == components.host_end) {
13736
0
        return false;
13737
0
      }
13738
0
    }
13739
13740
0
    set_scheme(_buffer);
13741
13742
0
    if constexpr (has_state_override) {
13743
      // This is uncommon.
13744
0
      uint16_t urls_scheme_port = get_special_port();
13745
13746
0
      if (urls_scheme_port) {
13747
        // If url's port is url's scheme's default port, then set url's port to
13748
        // null.
13749
0
        if (components.port == urls_scheme_port) {
13750
0
          clear_port();
13751
0
        }
13752
0
      }
13753
0
    }
13754
0
  }
13755
0
  ADA_ASSERT_TRUE(validate());
13756
0
  return true;
13757
0
}
Unexecuted instantiation: bool ada::url_aggregator::parse_scheme_with_colon<false>(std::__1::basic_string_view<char, std::__1::char_traits<char> >)
Unexecuted instantiation: bool ada::url_aggregator::parse_scheme_with_colon<true>(std::__1::basic_string_view<char, std::__1::char_traits<char> >)
13758
13759
0
inline void url_aggregator::copy_scheme(const url_aggregator& u) {
13760
0
  ada_log("url_aggregator::copy_scheme ", u.buffer);
13761
0
  ADA_ASSERT_TRUE(validate());
13762
  // next line could overflow but unsigned arithmetic has well-defined
13763
  // overflows.
13764
0
  uint32_t new_difference = u.components.protocol_end - components.protocol_end;
13765
13766
0
  type = u.type;
13767
0
  buffer.erase(0, components.protocol_end);
13768
0
  buffer.insert(0, u.get_protocol());
13769
0
  components.protocol_end = u.components.protocol_end;
13770
13771
  // No need to update the components
13772
0
  if (new_difference == 0) {
13773
0
    return;
13774
0
  }
13775
13776
0
  apply_shifted_non_scheme_offsets(components, new_difference);
13777
0
  ADA_ASSERT_TRUE(validate());
13778
0
}
13779
13780
inline void url_aggregator::set_scheme_from_view_with_colon(
13781
0
    std::string_view new_scheme_with_colon) {
13782
0
  ada_log("url_aggregator::set_scheme_from_view_with_colon ",
13783
0
          new_scheme_with_colon);
13784
0
  ADA_ASSERT_TRUE(validate());
13785
0
  ADA_ASSERT_TRUE(!new_scheme_with_colon.empty() &&
13786
0
                  new_scheme_with_colon.back() == ':');
13787
  // next line could overflow but unsigned arithmetic has well-defined
13788
  // overflows.
13789
0
  uint32_t new_difference =
13790
0
      uint32_t(new_scheme_with_colon.size()) - components.protocol_end;
13791
13792
0
  if (buffer.empty()) {
13793
0
    buffer.append(new_scheme_with_colon);
13794
0
  } else {
13795
0
    buffer.erase(0, components.protocol_end);
13796
0
    buffer.insert(0, new_scheme_with_colon);
13797
0
  }
13798
0
  components.protocol_end += new_difference;
13799
13800
0
  apply_shifted_non_scheme_offsets(components, new_difference);
13801
0
  ADA_ASSERT_TRUE(validate());
13802
0
}
13803
13804
0
inline void url_aggregator::set_scheme(std::string_view new_scheme) {
13805
0
  ada_log("url_aggregator::set_scheme ", new_scheme);
13806
0
  ADA_ASSERT_TRUE(validate());
13807
0
  ADA_ASSERT_TRUE(new_scheme.empty() || new_scheme.back() != ':');
13808
  // next line could overflow but unsigned arithmetic has well-defined
13809
  // overflows.
13810
0
  uint32_t new_difference =
13811
0
      uint32_t(new_scheme.size()) - components.protocol_end + 1;
13812
13813
0
  type = ada::scheme::get_scheme_type(new_scheme);
13814
0
  if (buffer.empty()) {
13815
0
    buffer.append(helpers::concat(new_scheme, ":"));
13816
0
  } else {
13817
0
    buffer.erase(0, components.protocol_end);
13818
0
    buffer.insert(0, helpers::concat(new_scheme, ":"));
13819
0
  }
13820
0
  components.protocol_end = uint32_t(new_scheme.size() + 1);
13821
13822
0
  apply_shifted_non_scheme_offsets(components, new_difference);
13823
0
  ADA_ASSERT_TRUE(validate());
13824
0
}
13825
13826
0
bool url_aggregator::needs_rollback_snapshot(size_t input_len) const noexcept {
13827
  // 3x should cover worst-case percent-encoding of every input byte; the
13828
  // constant covers the handful of delimiter bytes a setter may add ("/.", "?",
13829
  // "#" and so on)
13830
0
  return buffer.size() + input_len * 3 + 16 > ada::get_max_input_length();
13831
0
}
13832
13833
0
bool url_aggregator::set_protocol(const std::string_view input) {
13834
0
  ada_log("url_aggregator::set_protocol ", input);
13835
0
  ADA_ASSERT_TRUE(validate());
13836
0
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
13837
0
  std::string view(input);
13838
0
  helpers::remove_ascii_tab_or_newline(view);
13839
0
  if (view.empty()) {
13840
0
    return true;
13841
0
  }
13842
13843
  // Schemes should start with alpha values.
13844
0
  if (!checkers::is_alpha(view[0])) {
13845
0
    return false;
13846
0
  }
13847
13848
0
  view.append(":");
13849
13850
0
  std::string::iterator pointer =
13851
0
      std::ranges::find_if_not(view, unicode::is_alnum_plus);
13852
13853
0
  if (pointer != view.end() && *pointer == ':') {
13854
0
    std::optional<url_aggregator> saved_url;
13855
0
    if (needs_rollback_snapshot(view.size())) {
13856
0
      saved_url = *this;
13857
0
    }
13858
0
    bool result = parse_scheme_with_colon<true>(
13859
0
        view.substr(0, pointer - view.begin() + 1));
13860
0
    if (result && saved_url && buffer.size() > ada::get_max_input_length()) {
13861
0
      *this = std::move(*saved_url);
13862
0
      return false;
13863
0
    }
13864
0
    return result;
13865
0
  }
13866
0
  return false;
13867
0
}
13868
13869
0
bool url_aggregator::set_username(const std::string_view input) {
13870
0
  ada_log("url_aggregator::set_username '", input, "' ");
13871
0
  ADA_ASSERT_TRUE(validate());
13872
0
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
13873
0
  if (cannot_have_credentials_or_port()) {
13874
0
    return false;
13875
0
  }
13876
0
  std::optional<url_aggregator> saved_url;
13877
0
  if (needs_rollback_snapshot(input.size())) {
13878
0
    saved_url = *this;
13879
0
  }
13880
0
  size_t idx = ada::unicode::percent_encode_index(
13881
0
      input, character_sets::USERINFO_PERCENT_ENCODE);
13882
0
  if (idx == input.size()) {
13883
0
    update_base_username(input);
13884
0
  } else {
13885
    // We only create a temporary string if we have to!
13886
0
    update_base_username(ada::unicode::percent_encode(
13887
0
        input, character_sets::USERINFO_PERCENT_ENCODE, idx));
13888
0
  }
13889
0
  if (saved_url && buffer.size() > ada::get_max_input_length()) {
13890
0
    *this = std::move(*saved_url);
13891
0
    return false;
13892
0
  }
13893
0
  ADA_ASSERT_TRUE(validate());
13894
0
  return true;
13895
0
}
13896
13897
0
bool url_aggregator::set_password(const std::string_view input) {
13898
0
  ada_log("url_aggregator::set_password '", input, "'");
13899
0
  ADA_ASSERT_TRUE(validate());
13900
0
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
13901
0
  if (cannot_have_credentials_or_port()) {
13902
0
    return false;
13903
0
  }
13904
0
  std::optional<url_aggregator> saved_url;
13905
0
  if (needs_rollback_snapshot(input.size())) {
13906
0
    saved_url = *this;
13907
0
  }
13908
0
  size_t idx = ada::unicode::percent_encode_index(
13909
0
      input, character_sets::USERINFO_PERCENT_ENCODE);
13910
0
  if (idx == input.size()) {
13911
0
    update_base_password(input);
13912
0
  } else {
13913
    // We only create a temporary string if we have to!
13914
0
    update_base_password(ada::unicode::percent_encode(
13915
0
        input, character_sets::USERINFO_PERCENT_ENCODE, idx));
13916
0
  }
13917
0
  if (saved_url && buffer.size() > ada::get_max_input_length()) {
13918
0
    *this = std::move(*saved_url);
13919
0
    return false;
13920
0
  }
13921
0
  ADA_ASSERT_TRUE(validate());
13922
0
  return true;
13923
0
}
13924
13925
0
bool url_aggregator::set_port(const std::string_view input) {
13926
0
  ada_log("url_aggregator::set_port ", input);
13927
0
  ADA_ASSERT_TRUE(validate());
13928
0
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
13929
0
  if (cannot_have_credentials_or_port()) {
13930
0
    return false;
13931
0
  }
13932
13933
0
  if (input.empty()) {
13934
0
    clear_port();
13935
0
    return true;
13936
0
  }
13937
13938
0
  std::string trimmed(input);
13939
0
  helpers::remove_ascii_tab_or_newline(trimmed);
13940
13941
0
  if (trimmed.empty()) {
13942
0
    return true;
13943
0
  }
13944
13945
  // Input should not start with a non-digit character.
13946
0
  if (!ada::unicode::is_ascii_digit(trimmed.front())) {
13947
0
    return false;
13948
0
  }
13949
13950
  // Find the first non-digit character to determine the length of digits
13951
0
  auto first_non_digit =
13952
0
      std::ranges::find_if_not(trimmed, ada::unicode::is_ascii_digit);
13953
0
  std::string_view digits_to_parse =
13954
0
      std::string_view(trimmed.data(), first_non_digit - trimmed.begin());
13955
13956
  // parse_port only touches the buffer once the digits are already known to
13957
  // be in range, so an invalid port never mutates anything and needs no
13958
  // rollback; a valid one can only grow the buffer by a few bytes.
13959
0
  std::optional<url_aggregator> saved_url;
13960
0
  if (needs_rollback_snapshot(digits_to_parse.size())) {
13961
0
    saved_url = *this;
13962
0
  }
13963
0
  parse_port(digits_to_parse);
13964
0
  if (!is_valid) {
13965
0
    is_valid = true;
13966
0
    ADA_ASSERT_TRUE(validate());
13967
0
    return false;
13968
0
  }
13969
0
  if (saved_url && buffer.size() > ada::get_max_input_length()) {
13970
0
    *this = std::move(*saved_url);
13971
0
    return false;
13972
0
  }
13973
0
  return true;
13974
0
}
13975
13976
0
bool url_aggregator::set_pathname(const std::string_view input) {
13977
0
  ada_log("url_aggregator::set_pathname ", input);
13978
0
  ADA_ASSERT_TRUE(validate());
13979
0
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
13980
0
  if (has_opaque_path) {
13981
0
    return false;
13982
0
  }
13983
0
  std::optional<url_aggregator> saved_url;
13984
0
  if (needs_rollback_snapshot(input.size())) {
13985
0
    saved_url = *this;
13986
0
  }
13987
0
  clear_pathname();
13988
0
  parse_path(input);
13989
0
  if (get_pathname().starts_with("//") && !has_authority() && !has_dash_dot()) {
13990
0
    buffer.insert(components.pathname_start, "/.");
13991
0
    components.pathname_start += 2;
13992
0
    if (components.search_start != url_components::omitted) {
13993
0
      components.search_start += 2;
13994
0
    }
13995
0
    if (components.hash_start != url_components::omitted) {
13996
0
      components.hash_start += 2;
13997
0
    }
13998
0
  }
13999
0
  if (saved_url && buffer.size() > ada::get_max_input_length()) {
14000
0
    *this = std::move(*saved_url);
14001
0
    return false;
14002
0
  }
14003
0
  ADA_ASSERT_TRUE(validate());
14004
0
  return true;
14005
0
}
14006
14007
0
ada_really_inline void url_aggregator::parse_path(std::string_view input) {
14008
0
  ada_log("url_aggregator::parse_path ", input);
14009
0
  ADA_ASSERT_TRUE(validate());
14010
0
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
14011
0
  std::string tmp_buffer;
14012
0
  std::string_view internal_input;
14013
0
  if (unicode::has_tabs_or_newline(input)) {
14014
0
    tmp_buffer = input;
14015
    // Optimization opportunity: Instead of copying and then pruning, we could
14016
    // just directly build the string from user_input.
14017
0
    helpers::remove_ascii_tab_or_newline(tmp_buffer);
14018
0
    internal_input = tmp_buffer;
14019
0
  } else {
14020
0
    internal_input = input;
14021
0
  }
14022
14023
  // If url is special, then:
14024
0
  if (is_special()) {
14025
0
    if (internal_input.empty()) {
14026
0
      update_base_pathname("/");
14027
0
    } else if ((internal_input[0] == '/') || (internal_input[0] == '\\')) {
14028
0
      consume_prepared_path(internal_input.substr(1));
14029
0
    } else {
14030
0
      consume_prepared_path(internal_input);
14031
0
    }
14032
0
  } else if (!internal_input.empty()) {
14033
0
    if (internal_input[0] == '/') {
14034
0
      consume_prepared_path(internal_input.substr(1));
14035
0
    } else {
14036
0
      consume_prepared_path(internal_input);
14037
0
    }
14038
0
  } else {
14039
    // Non-special URLs with an empty host can have their paths erased
14040
    // Path-only URLs cannot have their paths erased
14041
0
    if (components.host_start == components.host_end && !has_authority()) {
14042
0
      update_base_pathname("/");
14043
0
    }
14044
0
  }
14045
0
  ADA_ASSERT_TRUE(validate());
14046
0
}
14047
14048
0
void url_aggregator::set_search(const std::string_view input) {
14049
0
  ada_log("url_aggregator::set_search ", input);
14050
0
  ADA_ASSERT_TRUE(validate());
14051
0
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
14052
0
  if (input.empty()) {
14053
0
    clear_search();
14054
0
    helpers::strip_trailing_spaces_from_opaque_path(*this);
14055
0
    return;
14056
0
  }
14057
14058
0
  std::string new_value;
14059
0
  new_value = input[0] == '?' ? input.substr(1) : input;
14060
0
  helpers::remove_ascii_tab_or_newline(new_value);
14061
14062
0
  auto query_percent_encode_set =
14063
0
      is_special() ? ada::character_sets::SPECIAL_QUERY_PERCENT_ENCODE
14064
0
                   : ada::character_sets::QUERY_PERCENT_ENCODE;
14065
14066
0
  std::optional<url_aggregator> saved_url;
14067
0
  if (needs_rollback_snapshot(new_value.size())) {
14068
0
    saved_url = *this;
14069
0
  }
14070
0
  update_base_search(new_value, query_percent_encode_set);
14071
0
  if (saved_url && buffer.size() > ada::get_max_input_length()) {
14072
0
    *this = std::move(*saved_url);
14073
0
    return;
14074
0
  }
14075
0
  ADA_ASSERT_TRUE(validate());
14076
0
}
14077
14078
0
void url_aggregator::set_hash(const std::string_view input) {
14079
0
  ada_log("url_aggregator::set_hash ", input);
14080
0
  ADA_ASSERT_TRUE(validate());
14081
0
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
14082
0
  if (input.empty()) {
14083
0
    if (components.hash_start != url_components::omitted) {
14084
0
      buffer.resize(components.hash_start);
14085
0
      components.hash_start = url_components::omitted;
14086
0
    }
14087
0
    helpers::strip_trailing_spaces_from_opaque_path(*this);
14088
0
    return;
14089
0
  }
14090
14091
0
  std::string new_value;
14092
0
  new_value = input[0] == '#' ? input.substr(1) : input;
14093
0
  helpers::remove_ascii_tab_or_newline(new_value);
14094
0
  std::optional<url_aggregator> saved_url;
14095
0
  if (needs_rollback_snapshot(new_value.size())) {
14096
0
    saved_url = *this;
14097
0
  }
14098
0
  update_unencoded_base_hash(new_value);
14099
0
  if (saved_url && buffer.size() > ada::get_max_input_length()) {
14100
0
    *this = std::move(*saved_url);
14101
0
    return;
14102
0
  }
14103
0
  ADA_ASSERT_TRUE(validate());
14104
0
}
14105
14106
0
bool url_aggregator::set_href(const std::string_view input) {
14107
0
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
14108
0
  ada_log("url_aggregator::set_href ", input, " [", input.size(), " bytes]");
14109
0
  ada::result<url_aggregator> out = ada::parse<url_aggregator>(input);
14110
0
  ada_log("url_aggregator::set_href, success :", out.has_value());
14111
14112
0
  if (out) {
14113
    // The parser enforces get_max_input_length() on both the input and the
14114
    // normalized result. This is a defense-in-depth check.
14115
0
    if (out->buffer.size() > ada::get_max_input_length()) {
14116
0
      return false;
14117
0
    }
14118
0
    ada_log("url_aggregator::set_href, parsed ", out->to_string());
14119
    // TODO: Figure out why the following line puts test to never finish.
14120
0
    *this = *out;
14121
0
  }
14122
14123
0
  return out.has_value();
14124
0
}
14125
14126
0
ada_really_inline bool url_aggregator::parse_host(std::string_view input) {
14127
0
  ada_log("url_aggregator:parse_host \"", input, "\" [", input.size(),
14128
0
          " bytes]");
14129
0
  ADA_ASSERT_TRUE(validate());
14130
0
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
14131
0
  if (input.empty()) {
14132
0
    return is_valid = false;
14133
0
  }  // technically unnecessary.
14134
  // If input starts with U+005B ([), then:
14135
0
  if (input[0] == '[') {
14136
    // If input does not end with U+005D (]), validation error, return failure.
14137
0
    if (input.back() != ']') {
14138
0
      return is_valid = false;
14139
0
    }
14140
0
    ada_log("parse_host ipv6");
14141
14142
    // Return the result of IPv6 parsing input with its leading U+005B ([) and
14143
    // trailing U+005D (]) removed.
14144
0
    input.remove_prefix(1);
14145
0
    input.remove_suffix(1);
14146
0
    return parse_ipv6(input);
14147
0
  }
14148
14149
  // If isNotSpecial is true, then return the result of opaque-host parsing
14150
  // input.
14151
0
  if (!is_special()) {
14152
0
    return parse_opaque_host(input);
14153
0
  }
14154
  // Let domain be the result of running UTF-8 decode without BOM on the
14155
  // percent-decoding of input. Let asciiDomain be the result of running domain
14156
  // to ASCII with domain and false. The most common case is an ASCII input, in
14157
  // which case we do not need to call the expensive 'to_ascii' if a few
14158
  // conditions are met: no '%' and no 'xn-' subsequence.
14159
14160
  // Often, the input does not contain any forbidden code points, and no upper
14161
  // case ASCII letter, then we can just copy it to the buffer. We want to
14162
  // optimize for such a common case.
14163
14164
  // Fast path: try to parse as pure decimal IPv4 first.
14165
0
  const uint64_t fast_result = checkers::try_parse_ipv4_fast(input);
14166
0
  if (fast_result < checkers::ipv4_fast_fail) {
14167
0
    if (!input.empty() && input.back() == '.') {
14168
0
      update_base_hostname(input.substr(0, input.size() - 1));
14169
0
    } else {
14170
0
      update_base_hostname(input);
14171
0
    }
14172
0
    host_type = IPV4;
14173
0
    is_valid = true;
14174
0
    ada_log("parse_host fast path decimal ipv4");
14175
0
    ADA_ASSERT_TRUE(validate());
14176
0
    return true;
14177
0
  }
14178
0
  uint8_t is_forbidden_or_upper =
14179
0
      unicode::contains_forbidden_domain_code_point_or_upper(input.data(),
14180
0
                                                             input.size());
14181
0
  static constexpr std::string_view xn_dash{"xn-", 3};
14182
0
  if ((is_forbidden_or_upper & 1) == 0) {
14183
0
    if ((is_forbidden_or_upper & 2) != 0) {
14184
0
      std::string lowered(input);
14185
0
      unicode::to_lower_ascii(lowered.data(), lowered.size());
14186
0
      if (lowered.find('-') == std::string_view::npos ||
14187
0
          lowered.find(xn_dash) == std::string_view::npos) {
14188
0
        update_base_hostname(lowered);
14189
0
        if (checkers::is_ipv4(lowered)) {
14190
0
          ada_log("parse_host fast path ipv4");
14191
0
          return parse_ipv4(lowered, true);
14192
0
        }
14193
0
        ada_log("parse_host fast path ", get_hostname());
14194
0
        is_valid = true;
14195
0
        return true;
14196
0
      }
14197
0
    } else if (input.find('-') == std::string_view::npos ||
14198
0
               input.find(xn_dash) == std::string_view::npos) {
14199
0
      update_base_hostname(input);
14200
0
      if (checkers::is_ipv4(input)) {
14201
0
        ada_log("parse_host fast path ipv4");
14202
0
        return parse_ipv4(input, true);
14203
0
      }
14204
0
      ada_log("parse_host fast path ", get_hostname());
14205
0
      is_valid = true;
14206
0
      return true;
14207
0
    }
14208
0
  } else if (const size_t first_percent = input.find('%');
14209
0
             first_percent != std::string_view::npos) {
14210
0
    std::string decoded = unicode::percent_decode(input, first_percent);
14211
0
    const uint8_t decoded_flags =
14212
0
        unicode::contains_forbidden_domain_code_point_or_upper(decoded.data(),
14213
0
                                                               decoded.size());
14214
0
    if ((decoded_flags & 1) == 0) {
14215
0
      if ((decoded_flags & 2) != 0) {
14216
0
        unicode::to_lower_ascii(decoded.data(), decoded.size());
14217
0
      }
14218
0
      if (decoded.find('-') == std::string_view::npos ||
14219
0
          decoded.find(xn_dash) == std::string_view::npos) {
14220
0
        update_base_hostname(decoded);
14221
0
        if (checkers::is_ipv4(decoded)) {
14222
0
          return parse_ipv4(decoded, true);
14223
0
        }
14224
0
        is_valid = true;
14225
0
        return true;
14226
0
      }
14227
0
    }
14228
0
  }
14229
  // We have encountered at least one forbidden code point or the input contains
14230
  // 'xn-' (case insensitive), so we need to call 'to_ascii' to perform the full
14231
  // conversion.
14232
14233
0
  ada_log("parse_host calling to_ascii");
14234
0
  std::optional<std::string> host = std::string(get_hostname());
14235
0
  is_valid = ada::unicode::to_ascii(host, input, input.find('%'));
14236
0
  if (!is_valid) {
14237
0
    ada_log("parse_host to_ascii returns false");
14238
0
    return is_valid = false;
14239
0
  }
14240
0
  ada_log("parse_host to_ascii succeeded ", *host, " [", host->size(),
14241
0
          " bytes]");
14242
14243
0
  if (std::ranges::any_of(host.value(),
14244
0
                          ada::unicode::is_forbidden_domain_code_point)) {
14245
0
    return is_valid = false;
14246
0
  }
14247
14248
  // If asciiDomain ends in a number, then return the result of IPv4 parsing
14249
  // asciiDomain.
14250
0
  if (checkers::is_ipv4(host.value())) {
14251
0
    ada_log("parse_host got ipv4 ", *host);
14252
0
    return parse_ipv4(host.value(), false);
14253
0
  }
14254
14255
0
  update_base_hostname(host.value());
14256
0
  ADA_ASSERT_TRUE(validate());
14257
0
  return true;
14258
0
}
14259
14260
template <bool override_hostname>
14261
0
bool url_aggregator::set_host_or_hostname(const std::string_view input) {
14262
0
  ada_log("url_aggregator::set_host_or_hostname ", input);
14263
0
  ADA_ASSERT_TRUE(validate());
14264
0
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
14265
0
  if (has_opaque_path) {
14266
0
    return false;
14267
0
  }
14268
14269
0
  url_aggregator saved_url(*this);
14270
14271
0
  size_t host_end_pos = input.find('#');
14272
0
  std::string _host(input.data(), host_end_pos != std::string_view::npos
14273
0
                                      ? host_end_pos
14274
0
                                      : input.size());
14275
0
  helpers::remove_ascii_tab_or_newline(_host);
14276
0
  std::string_view new_host(_host);
14277
14278
0
  auto check_url_size = [&]() -> bool {
14279
0
    if (buffer.size() > ada::get_max_input_length()) {
14280
0
      *this = std::move(saved_url);
14281
0
      return false;
14282
0
    }
14283
0
    return true;
14284
0
  };
Unexecuted instantiation: ada::url_aggregator::set_host_or_hostname<false>(std::__1::basic_string_view<char, std::__1::char_traits<char> >)::{lambda()#1}::operator()() const
Unexecuted instantiation: ada::url_aggregator::set_host_or_hostname<true>(std::__1::basic_string_view<char, std::__1::char_traits<char> >)::{lambda()#1}::operator()() const
14285
14286
  // If url's scheme is "file", then set state to file host state, instead of
14287
  // host state.
14288
0
  if (type != ada::scheme::type::FILE) {
14289
0
    std::string_view host_view(_host.data(), _host.length());
14290
0
    auto [location, found_colon] =
14291
0
        helpers::get_host_delimiter_location(is_special(), host_view);
14292
14293
    // Otherwise, if c is U+003A (:) and insideBrackets is false, then:
14294
    // Note: the 'found_colon' value is true if and only if a colon was
14295
    // encountered while not inside brackets.
14296
0
    if (found_colon) {
14297
      // If buffer is the empty string, host-missing validation error, return
14298
      // failure.
14299
0
      std::string_view host_buffer = host_view.substr(0, location);
14300
0
      if (host_buffer.empty()) {
14301
0
        return false;
14302
0
      }
14303
14304
      // If state override is given and state override is hostname state, then
14305
      // return failure.
14306
0
      if constexpr (override_hostname) {
14307
0
        return false;
14308
0
      }
14309
14310
      // Let host be the result of host parsing buffer with url is not special.
14311
0
      bool succeeded = parse_host(host_buffer);
14312
0
      if (!succeeded) {
14313
0
        *this = std::move(saved_url);
14314
0
        return false;
14315
0
      } else if (has_dash_dot()) {
14316
        // The url now has a non-null host, so the "/." that guarded a
14317
        // leading "//" path is no longer needed. Drop it before the port is
14318
        // inserted at host_end, otherwise it stays wedged in the path.
14319
0
        delete_dash_dot();
14320
0
      }
14321
14322
      // Set url's host to host, buffer to the empty string, and state to port
14323
      // state.
14324
0
      std::string_view port_buffer = new_host.substr(location + 1);
14325
0
      if (!port_buffer.empty()) {
14326
0
        set_port(port_buffer);
14327
0
      }
14328
0
      return check_url_size();
14329
0
    }
14330
    // Otherwise, if one of the following is true:
14331
    // - c is the EOF code point, U+002F (/), U+003F (?), or U+0023 (#)
14332
    // - url is special and c is U+005C (\)
14333
0
    else {
14334
      // If url is special and host_view is the empty string, host-missing
14335
      // validation error, return failure.
14336
0
      if (host_view.empty() && is_special()) {
14337
0
        return false;
14338
0
      }
14339
14340
      // Otherwise, if state override is given, host_view is the empty string,
14341
      // and either url includes credentials or url's port is non-null, then
14342
      // return failure.
14343
0
      if (host_view.empty() && (has_credentials() || has_port())) {
14344
0
        return false;
14345
0
      }
14346
14347
      // Let host be the result of host parsing host_view with url is not
14348
      // special.
14349
0
      if (host_view.empty() && !is_special()) {
14350
0
        if (has_hostname()) {
14351
0
          clear_hostname();  // easy!
14352
0
        } else if (has_dash_dot()) {
14353
0
          add_authority_slashes_if_needed();
14354
0
          delete_dash_dot();
14355
0
        } else {
14356
          // The url has no authority yet (e.g. "foo:/bar"); setting an empty
14357
          // host must still give it an (empty) authority, matching ada::url.
14358
0
          add_authority_slashes_if_needed();
14359
0
        }
14360
0
        return check_url_size();
14361
0
      }
14362
14363
0
      bool succeeded = parse_host(host_view);
14364
0
      if (!succeeded) {
14365
0
        *this = std::move(saved_url);
14366
0
        return false;
14367
0
      } else if (has_dash_dot()) {
14368
        // Should remove dash_dot from pathname
14369
0
        delete_dash_dot();
14370
0
      }
14371
0
      return check_url_size();
14372
0
    }
14373
0
  }
14374
14375
0
  size_t location = new_host.find_first_of("/\\?");
14376
0
  if (location != std::string_view::npos) {
14377
0
    new_host.remove_suffix(new_host.length() - location);
14378
0
  }
14379
14380
0
  if (new_host.empty()) {
14381
    // Set url's host to the empty string.
14382
0
    clear_hostname();
14383
0
  } else {
14384
    // Let host be the result of host parsing buffer with url is not special.
14385
0
    if (!parse_host(new_host)) {
14386
0
      *this = std::move(saved_url);
14387
0
      return false;
14388
0
    }
14389
14390
    // If host is "localhost", then set host to the empty string.
14391
0
    if (helpers::substring(buffer, components.host_start,
14392
0
                           components.host_end) == "localhost") {
14393
0
      clear_hostname();
14394
0
    }
14395
0
  }
14396
0
  ADA_ASSERT_TRUE(validate());
14397
0
  return check_url_size();
14398
0
}
Unexecuted instantiation: bool ada::url_aggregator::set_host_or_hostname<false>(std::__1::basic_string_view<char, std::__1::char_traits<char> >)
Unexecuted instantiation: bool ada::url_aggregator::set_host_or_hostname<true>(std::__1::basic_string_view<char, std::__1::char_traits<char> >)
14399
14400
0
bool url_aggregator::set_host(const std::string_view input) {
14401
0
  ada_log("url_aggregator::set_host '", input, "'");
14402
0
  ADA_ASSERT_TRUE(validate());
14403
0
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
14404
0
  return set_host_or_hostname<false>(input);
14405
0
}
14406
14407
0
bool url_aggregator::set_hostname(const std::string_view input) {
14408
0
  ada_log("url_aggregator::set_hostname '", input, "'");
14409
0
  ADA_ASSERT_TRUE(validate());
14410
0
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
14411
0
  return set_host_or_hostname<true>(input);
14412
0
}
14413
14414
0
[[nodiscard]] std::string url_aggregator::get_origin() const {
14415
0
  ada_log("url_aggregator::get_origin");
14416
0
  if (is_special()) {
14417
    // Return a new opaque origin.
14418
0
    if (type == scheme::FILE) {
14419
0
      return "null";
14420
0
    }
14421
14422
0
    return helpers::concat(get_protocol(), "//", get_host());
14423
0
  }
14424
14425
0
  if (get_protocol() == "blob:") {
14426
0
    std::string_view path = get_pathname();
14427
0
    if (!path.empty()) {
14428
0
      auto out = ada::parse<ada::url_aggregator>(path);
14429
0
      if (out && (out->type == scheme::HTTP || out->type == scheme::HTTPS)) {
14430
        // If pathURL's scheme is not "http" and not "https", then return a
14431
        // new opaque origin.
14432
0
        return helpers::concat(out->get_protocol(), "//", out->get_host());
14433
0
      }
14434
0
    }
14435
0
  }
14436
14437
  // Return a new opaque origin.
14438
0
  return "null";
14439
0
}
14440
14441
[[nodiscard]] std::string_view url_aggregator::get_username() const
14442
0
    ada_lifetime_bound {
14443
0
  ada_log("url_aggregator::get_username");
14444
0
  if (has_non_empty_username()) {
14445
0
    return helpers::substring(buffer, components.protocol_end + 2,
14446
0
                              components.username_end);
14447
0
  }
14448
0
  return "";
14449
0
}
14450
14451
[[nodiscard]] std::string_view url_aggregator::get_password() const
14452
0
    ada_lifetime_bound {
14453
0
  ada_log("url_aggregator::get_password");
14454
0
  if (has_non_empty_password()) {
14455
0
    return helpers::substring(buffer, components.username_end + 1,
14456
0
                              components.host_start);
14457
0
  }
14458
0
  return "";
14459
0
}
14460
14461
[[nodiscard]] std::string_view url_aggregator::get_port() const
14462
0
    ada_lifetime_bound {
14463
0
  ada_log("url_aggregator::get_port");
14464
0
  if (components.port == url_components::omitted) {
14465
0
    return "";
14466
0
  }
14467
0
  return helpers::substring(buffer, components.host_end + 1,
14468
0
                            components.pathname_start);
14469
0
}
14470
14471
[[nodiscard]] std::string_view url_aggregator::get_hash() const
14472
0
    ada_lifetime_bound {
14473
0
  ada_log("url_aggregator::get_hash");
14474
  // If this's URL's fragment is either null or the empty string, then return
14475
  // the empty string. Return U+0023 (#), followed by this's URL's fragment.
14476
0
  if (components.hash_start == url_components::omitted) {
14477
0
    return "";
14478
0
  }
14479
0
  if (buffer.size() - components.hash_start <= 1) {
14480
0
    return "";
14481
0
  }
14482
0
  return helpers::substring(buffer, components.hash_start);
14483
0
}
14484
14485
[[nodiscard]] std::string_view url_aggregator::get_host() const
14486
0
    ada_lifetime_bound {
14487
0
  ada_log("url_aggregator::get_host");
14488
  // Technically, we should check if there is a hostname, but
14489
  // the code below works even if there isn't.
14490
  // if(!has_hostname()) { return ""; }
14491
0
  size_t start = components.host_start;
14492
0
  if (components.host_end > components.host_start &&
14493
0
      buffer[components.host_start] == '@') {
14494
0
    start++;
14495
0
  }
14496
  // if we have an empty host, then the space between components.host_end and
14497
  // components.pathname_start may be occupied by /.
14498
0
  if (start == components.host_end) {
14499
0
    return {};
14500
0
  }
14501
0
  return helpers::substring(buffer, start, components.pathname_start);
14502
0
}
14503
14504
[[nodiscard]] std::string_view url_aggregator::get_hostname() const
14505
0
    ada_lifetime_bound {
14506
0
  ada_log("url_aggregator::get_hostname");
14507
  // Technically, we should check if there is a hostname, but
14508
  // the code below works even if there isn't.
14509
  // if(!has_hostname()) { return ""; }
14510
0
  size_t start = components.host_start;
14511
  // So host_start is not where the host begins.
14512
0
  if (components.host_end > components.host_start &&
14513
0
      buffer[components.host_start] == '@') {
14514
0
    start++;
14515
0
  }
14516
0
  return helpers::substring(buffer, start, components.host_end);
14517
0
}
14518
14519
[[nodiscard]] std::string_view url_aggregator::get_search() const
14520
0
    ada_lifetime_bound {
14521
0
  ada_log("url_aggregator::get_search");
14522
  // If this's URL's query is either null or the empty string, then return the
14523
  // empty string. Return U+003F (?), followed by this's URL's query.
14524
0
  if (components.search_start == url_components::omitted) {
14525
0
    return "";
14526
0
  }
14527
0
  auto ending_index = uint32_t(buffer.size());
14528
0
  if (components.hash_start != url_components::omitted) {
14529
0
    ending_index = components.hash_start;
14530
0
  }
14531
0
  if (ending_index - components.search_start <= 1) {
14532
0
    return "";
14533
0
  }
14534
0
  return helpers::substring(buffer, components.search_start, ending_index);
14535
0
}
14536
14537
[[nodiscard]] std::string_view url_aggregator::get_protocol() const
14538
0
    ada_lifetime_bound {
14539
0
  ada_log("url_aggregator::get_protocol");
14540
0
  return helpers::substring(buffer, 0, components.protocol_end);
14541
0
}
14542
14543
0
[[nodiscard]] std::string ada::url_aggregator::to_string() const {
14544
0
  ada_log("url_aggregator::to_string buffer:", buffer, " [", buffer.size(),
14545
0
          " bytes]");
14546
0
  if (!is_valid) {
14547
0
    return "null";
14548
0
  }
14549
14550
0
  std::string answer;
14551
0
  auto back = std::back_insert_iterator(answer);
14552
0
  answer.append("{\n");
14553
14554
0
  answer.append("\t\"buffer\":\"");
14555
0
  helpers::encode_json(buffer, back);
14556
0
  answer.append("\",\n");
14557
14558
0
  answer.append("\t\"protocol\":\"");
14559
0
  helpers::encode_json(get_protocol(), back);
14560
0
  answer.append("\",\n");
14561
14562
0
  if (has_credentials()) {
14563
0
    answer.append("\t\"username\":\"");
14564
0
    helpers::encode_json(get_username(), back);
14565
0
    answer.append("\",\n");
14566
0
    answer.append("\t\"password\":\"");
14567
0
    helpers::encode_json(get_password(), back);
14568
0
    answer.append("\",\n");
14569
0
  }
14570
14571
0
  answer.append("\t\"host\":\"");
14572
0
  helpers::encode_json(get_host(), back);
14573
0
  answer.append("\",\n");
14574
14575
0
  answer.append("\t\"path\":\"");
14576
0
  helpers::encode_json(get_pathname(), back);
14577
0
  answer.append("\",\n");
14578
0
  answer.append("\t\"opaque path\":");
14579
0
  answer.append((has_opaque_path ? "true" : "false"));
14580
0
  answer.append(",\n");
14581
14582
0
  if (components.search_start != url_components::omitted) {
14583
0
    answer.append("\t\"query\":\"");
14584
0
    helpers::encode_json(get_search(), back);
14585
0
    answer.append("\",\n");
14586
0
  }
14587
0
  if (components.hash_start != url_components::omitted) {
14588
0
    answer.append("\t\"fragment\":\"");
14589
0
    helpers::encode_json(get_hash(), back);
14590
0
    answer.append("\",\n");
14591
0
  }
14592
14593
0
  auto convert_offset_to_string = [](uint32_t offset) -> std::string {
14594
0
    if (offset == url_components::omitted) {
14595
0
      return "null";
14596
0
    } else {
14597
0
      return std::to_string(offset);
14598
0
    }
14599
0
  };
14600
14601
0
  answer.append("\t\"protocol_end\":");
14602
0
  answer.append(convert_offset_to_string(components.protocol_end));
14603
0
  answer.append(",\n");
14604
14605
0
  answer.append("\t\"username_end\":");
14606
0
  answer.append(convert_offset_to_string(components.username_end));
14607
0
  answer.append(",\n");
14608
14609
0
  answer.append("\t\"host_start\":");
14610
0
  answer.append(convert_offset_to_string(components.host_start));
14611
0
  answer.append(",\n");
14612
14613
0
  answer.append("\t\"host_end\":");
14614
0
  answer.append(convert_offset_to_string(components.host_end));
14615
0
  answer.append(",\n");
14616
14617
0
  answer.append("\t\"port\":");
14618
0
  answer.append(convert_offset_to_string(components.port));
14619
0
  answer.append(",\n");
14620
14621
0
  answer.append("\t\"pathname_start\":");
14622
0
  answer.append(convert_offset_to_string(components.pathname_start));
14623
0
  answer.append(",\n");
14624
14625
0
  answer.append("\t\"search_start\":");
14626
0
  answer.append(convert_offset_to_string(components.search_start));
14627
0
  answer.append(",\n");
14628
14629
0
  answer.append("\t\"hash_start\":");
14630
0
  answer.append(convert_offset_to_string(components.hash_start));
14631
0
  answer.append("\n}");
14632
14633
0
  return answer;
14634
0
}
14635
14636
0
[[nodiscard]] bool url_aggregator::has_valid_domain() const noexcept {
14637
0
  if (components.host_start == components.host_end) {
14638
0
    return false;
14639
0
  }
14640
  // Avoid allocation: construct a string_view directly into the buffer.
14641
0
  size_t start = components.host_start;
14642
0
  if (components.host_end > components.host_start &&
14643
0
      buffer[components.host_start] == '@') {
14644
0
    start++;
14645
0
  }
14646
0
  return checkers::verify_dns_length(
14647
0
      std::string_view(buffer.data() + start, components.host_end - start));
14648
0
}
14649
14650
0
bool url_aggregator::parse_ipv4(std::string_view input, bool in_place) {
14651
0
  ada_log("parse_ipv4 ", input, " [", input.size(),
14652
0
          " bytes], overlaps with buffer: ",
14653
0
          helpers::overlaps(input, buffer) ? "yes" : "no");
14654
0
  ADA_ASSERT_TRUE(validate());
14655
0
  if (input.empty()) {
14656
0
    return is_valid = false;
14657
0
  }
14658
0
  const bool trailing_dot = (input.back() == '.');
14659
0
  if (trailing_dot) {
14660
0
    input.remove_suffix(1);
14661
0
    if (input.empty()) {
14662
0
      return is_valid = false;
14663
0
    }
14664
0
  }
14665
14666
0
  const uint64_t fast = checkers::try_parse_ipv4_fast(input);
14667
0
  if (fast < checkers::ipv4_fast_fail) [[likely]] {
14668
    // Pure decimal: keep the buffer when it already holds the address.
14669
    // Otherwise write the (trailing-dot-stripped) input.
14670
0
    if (!(in_place && !trailing_dot)) {
14671
0
      if (helpers::overlaps(input, buffer)) {
14672
0
        update_base_hostname(std::string(input));
14673
0
      } else {
14674
0
        update_base_hostname(input);
14675
0
      }
14676
0
    }
14677
0
    host_type = IPV4;
14678
0
    ADA_ASSERT_TRUE(validate());
14679
0
    return true;
14680
0
  }
14681
14682
0
  const char* p = input.data();
14683
0
  const char* end = p + input.size();
14684
0
  uint64_t ipv4 = 0;
14685
0
  int digit_count = 0;
14686
0
  int pure_decimal_count = 0;
14687
14688
0
  for (; digit_count < 4 && p < end; ++digit_count) {
14689
0
    uint64_t segment = 0;
14690
0
    bool pure = false;
14691
0
    if (!detail::parse_ipv4_number(p, end, segment, pure)) {
14692
0
      return is_valid = false;
14693
0
    }
14694
0
    if (pure) {
14695
0
      ++pure_decimal_count;
14696
0
    }
14697
0
    if (p >= end) {
14698
0
      const unsigned shift = static_cast<unsigned>(32 - digit_count * 8);
14699
0
      if (segment >= (uint64_t{1} << shift)) {
14700
0
        return is_valid = false;
14701
0
      }
14702
0
      ipv4 = (ipv4 << shift) | segment;
14703
0
      goto ipv4_done;
14704
0
    }
14705
0
    if (segment > 255 || *p != '.') {
14706
0
      return is_valid = false;
14707
0
    }
14708
0
    ipv4 = (ipv4 << 8) | segment;
14709
0
    ++p;
14710
0
  }
14711
0
  if (digit_count != 4 || p != end) {
14712
0
    return is_valid = false;
14713
0
  }
14714
0
ipv4_done:
14715
0
  ada_log("url_aggregator::parse_ipv4 completed ", get_href(),
14716
0
          " host: ", get_host());
14717
0
  if (in_place && pure_decimal_count == 4 && !trailing_dot) {
14718
0
    ada_log(
14719
0
        "url_aggregator::parse_ipv4 completed and was already correct in the "
14720
0
        "buffer");
14721
0
  } else {
14722
0
    update_base_hostname(ada::serializers::ipv4(ipv4));
14723
0
  }
14724
0
  host_type = IPV4;
14725
0
  ADA_ASSERT_TRUE(validate());
14726
0
  return true;
14727
0
}
14728
14729
0
bool url_aggregator::parse_ipv6(std::string_view input) {
14730
0
  ada_log("parse_ipv6 ", input, " [", input.size(), " bytes]");
14731
0
  ADA_ASSERT_TRUE(validate());
14732
0
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
14733
0
  if (input.empty() || input.size() > 45) [[unlikely]] {
14734
0
    return is_valid = false;
14735
0
  }
14736
0
  std::array<uint16_t, 8> address{};
14737
#if defined(ADA_AVX512_IPV6)
14738
  if (bool simd_valid; detail::try_parse_ipv6_avx512(input.data(), input.size(),
14739
                                                     address, simd_valid)) {
14740
    if (!simd_valid) [[unlikely]] {
14741
      return is_valid = false;
14742
    }
14743
    const std::string serialized = ada::serializers::ipv6(address);
14744
    if (get_hostname() != serialized) {
14745
      update_base_hostname(serialized);
14746
    }
14747
    host_type = IPV6;
14748
    return true;
14749
  }
14750
  address = {};
14751
#endif
14752
0
  const char* pointer = input.data();
14753
0
  const char* const end = pointer + input.size();
14754
0
  int piece_index = 0;
14755
0
  int compress = -1;
14756
14757
0
  if (*pointer == ':') {
14758
0
    if (input.size() == 1 || pointer[1] != ':') [[unlikely]] {
14759
0
      return is_valid = false;
14760
0
    }
14761
0
    pointer += 2;
14762
0
    compress = ++piece_index;
14763
0
  }
14764
14765
0
  while (pointer != end) {
14766
0
    if (piece_index == 8) [[unlikely]] {
14767
0
      return is_valid = false;
14768
0
    }
14769
0
    if (*pointer == ':') {
14770
0
      if (compress != -1) [[unlikely]] {
14771
0
        return is_valid = false;
14772
0
      }
14773
0
      ++pointer;
14774
0
      compress = ++piece_index;
14775
0
      continue;
14776
0
    }
14777
14778
0
    uint16_t value = 0;
14779
0
    const int length = detail::parse_hex_piece(pointer, end, value);
14780
14781
0
    if (pointer != end && *pointer == '.') {
14782
0
      if (length == 0) [[unlikely]] {
14783
0
        return is_valid = false;
14784
0
      }
14785
0
      pointer -= length;
14786
0
      if (piece_index > 6) [[unlikely]] {
14787
0
        return is_valid = false;
14788
0
      }
14789
14790
0
      int numbers_seen = 0;
14791
0
      while (pointer != end) {
14792
0
        int ipv4_piece = -1;
14793
0
        if (numbers_seen > 0) {
14794
0
          if (*pointer == '.' && numbers_seen < 4) {
14795
0
            ++pointer;
14796
0
          } else {
14797
0
            return is_valid = false;
14798
0
          }
14799
0
        }
14800
0
        if (pointer == end || *pointer < '0' || *pointer > '9') [[unlikely]] {
14801
0
          return is_valid = false;
14802
0
        }
14803
0
        ipv4_piece = *pointer - '0';
14804
0
        ++pointer;
14805
0
        if (pointer != end && *pointer >= '0' && *pointer <= '9') {
14806
0
          if (ipv4_piece == 0) [[unlikely]] {
14807
0
            return is_valid = false;
14808
0
          }
14809
0
          ipv4_piece = ipv4_piece * 10 + (*pointer - '0');
14810
0
          ++pointer;
14811
0
          if (pointer != end && *pointer >= '0' && *pointer <= '9') {
14812
0
            ipv4_piece = ipv4_piece * 10 + (*pointer - '0');
14813
0
            ++pointer;
14814
0
            if (ipv4_piece > 255) [[unlikely]] {
14815
0
              return is_valid = false;
14816
0
            }
14817
0
          }
14818
0
        }
14819
0
        address[static_cast<size_t>(piece_index)] = static_cast<uint16_t>(
14820
0
            address[static_cast<size_t>(piece_index)] * 0x100 +
14821
0
            static_cast<uint16_t>(ipv4_piece));
14822
0
        ++numbers_seen;
14823
0
        if (numbers_seen == 2 || numbers_seen == 4) {
14824
0
          ++piece_index;
14825
0
        }
14826
0
      }
14827
0
      if (numbers_seen != 4) [[unlikely]] {
14828
0
        return is_valid = false;
14829
0
      }
14830
0
      break;
14831
0
    }
14832
14833
0
    if (length == 0) [[unlikely]] {
14834
0
      return is_valid = false;
14835
0
    }
14836
14837
0
    if (pointer != end && *pointer == ':') {
14838
0
      ++pointer;
14839
0
      if (pointer == end) [[unlikely]] {
14840
0
        return is_valid = false;
14841
0
      }
14842
0
    } else if (pointer != end) [[unlikely]] {
14843
0
      return is_valid = false;
14844
0
    }
14845
14846
0
    address[static_cast<size_t>(piece_index)] = value;
14847
0
    ++piece_index;
14848
0
  }
14849
14850
0
  if (compress != -1) {
14851
0
    const int right = piece_index - compress;
14852
0
    if (right > 0) {
14853
0
      const size_t dest = static_cast<size_t>(8 - right);
14854
0
      const size_t src = static_cast<size_t>(compress);
14855
0
      if (dest != src) {
14856
0
        for (size_t i = static_cast<size_t>(right); i-- > 0;) {
14857
0
          address[dest + i] = address[src + i];
14858
0
          address[src + i] = 0;
14859
0
        }
14860
0
      }
14861
0
    }
14862
0
  } else if (piece_index != 8) [[unlikely]] {
14863
0
    return is_valid = false;
14864
0
  }
14865
14866
  // Serialize once; skip rewrite when hostname is already canonical.
14867
0
  const std::string serialized = ada::serializers::ipv6(address);
14868
0
  const std::string_view current = get_hostname();
14869
0
  if (current.size() == serialized.size() &&
14870
0
      std::memcmp(current.data(), serialized.data(), serialized.size()) == 0) {
14871
0
    ada_log("parse_ipv6 in-place canonical match");
14872
0
  } else {
14873
0
    update_base_hostname(serialized);
14874
0
  }
14875
0
  ada_log("parse_ipv6 ", get_hostname());
14876
0
  ADA_ASSERT_TRUE(validate());
14877
0
  host_type = IPV6;
14878
0
  return true;
14879
0
}
14880
14881
0
bool url_aggregator::parse_opaque_host(std::string_view input) {
14882
0
  ada_log("parse_opaque_host ", input, " [", input.size(), " bytes]");
14883
0
  ADA_ASSERT_TRUE(validate());
14884
0
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
14885
0
  if (std::ranges::any_of(input, ada::unicode::is_forbidden_host_code_point)) {
14886
0
    return is_valid = false;
14887
0
  }
14888
14889
  // Return the result of running UTF-8 percent-encode on input using the C0
14890
  // control percent-encode set.
14891
0
  size_t idx = ada::unicode::percent_encode_index(
14892
0
      input, character_sets::C0_CONTROL_PERCENT_ENCODE);
14893
0
  if (idx == input.size()) {
14894
0
    update_base_hostname(input);
14895
0
  } else {
14896
    // We only create a temporary string if we need to.
14897
0
    update_base_hostname(ada::unicode::percent_encode(
14898
0
        input, character_sets::C0_CONTROL_PERCENT_ENCODE, idx));
14899
0
  }
14900
0
  ADA_ASSERT_TRUE(validate());
14901
0
  return true;
14902
0
}
14903
14904
0
[[nodiscard]] std::string url_aggregator::to_diagram() const {
14905
0
  if (!is_valid) {
14906
0
    return "invalid";
14907
0
  }
14908
0
  std::string answer;
14909
0
  answer.append(buffer);
14910
0
  answer.append(" [");
14911
0
  answer.append(std::to_string(buffer.size()));
14912
0
  answer.append(" bytes]");
14913
0
  answer.append("\n");
14914
  // first line
14915
0
  std::string line1;
14916
0
  line1.resize(buffer.size(), ' ');
14917
0
  if (components.hash_start != url_components::omitted) {
14918
0
    line1[components.hash_start] = '|';
14919
0
  }
14920
0
  if (components.search_start != url_components::omitted) {
14921
0
    line1[components.search_start] = '|';
14922
0
  }
14923
0
  if (components.pathname_start != buffer.size()) {
14924
0
    line1[components.pathname_start] = '|';
14925
0
  }
14926
0
  if (components.host_end != buffer.size()) {
14927
0
    line1[components.host_end] = '|';
14928
0
  }
14929
0
  if (components.host_start != buffer.size()) {
14930
0
    line1[components.host_start] = '|';
14931
0
  }
14932
0
  if (components.username_end != buffer.size()) {
14933
0
    line1[components.username_end] = '|';
14934
0
  }
14935
0
  if (components.protocol_end != buffer.size()) {
14936
0
    line1[components.protocol_end] = '|';
14937
0
  }
14938
0
  answer.append(line1);
14939
0
  answer.append("\n");
14940
14941
0
  std::string line2 = line1;
14942
0
  if (components.hash_start != url_components::omitted) {
14943
0
    line2[components.hash_start] = '`';
14944
0
    line1[components.hash_start] = ' ';
14945
14946
0
    for (size_t i = components.hash_start + 1; i < line2.size(); i++) {
14947
0
      line2[i] = '-';
14948
0
    }
14949
0
    line2.append(" hash_start");
14950
0
    answer.append(line2);
14951
0
    answer.append("\n");
14952
0
  }
14953
14954
0
  std::string line3 = line1;
14955
0
  if (components.search_start != url_components::omitted) {
14956
0
    line3[components.search_start] = '`';
14957
0
    line1[components.search_start] = ' ';
14958
14959
0
    for (size_t i = components.search_start + 1; i < line3.size(); i++) {
14960
0
      line3[i] = '-';
14961
0
    }
14962
0
    line3.append(" search_start ");
14963
0
    line3.append(std::to_string(components.search_start));
14964
0
    answer.append(line3);
14965
0
    answer.append("\n");
14966
0
  }
14967
14968
0
  std::string line4 = line1;
14969
0
  if (components.pathname_start != buffer.size()) {
14970
0
    line4[components.pathname_start] = '`';
14971
0
    line1[components.pathname_start] = ' ';
14972
0
    for (size_t i = components.pathname_start + 1; i < line4.size(); i++) {
14973
0
      line4[i] = '-';
14974
0
    }
14975
0
    line4.append(" pathname_start ");
14976
0
    line4.append(std::to_string(components.pathname_start));
14977
0
    answer.append(line4);
14978
0
    answer.append("\n");
14979
0
  }
14980
14981
0
  std::string line5 = line1;
14982
0
  if (components.host_end != buffer.size()) {
14983
0
    line5[components.host_end] = '`';
14984
0
    line1[components.host_end] = ' ';
14985
14986
0
    for (size_t i = components.host_end + 1; i < line5.size(); i++) {
14987
0
      line5[i] = '-';
14988
0
    }
14989
0
    line5.append(" host_end ");
14990
0
    line5.append(std::to_string(components.host_end));
14991
0
    answer.append(line5);
14992
0
    answer.append("\n");
14993
0
  }
14994
14995
0
  std::string line6 = line1;
14996
0
  if (components.host_start != buffer.size()) {
14997
0
    line6[components.host_start] = '`';
14998
0
    line1[components.host_start] = ' ';
14999
15000
0
    for (size_t i = components.host_start + 1; i < line6.size(); i++) {
15001
0
      line6[i] = '-';
15002
0
    }
15003
0
    line6.append(" host_start ");
15004
0
    line6.append(std::to_string(components.host_start));
15005
0
    answer.append(line6);
15006
0
    answer.append("\n");
15007
0
  }
15008
15009
0
  std::string line7 = line1;
15010
0
  if (components.username_end != buffer.size()) {
15011
0
    line7[components.username_end] = '`';
15012
0
    line1[components.username_end] = ' ';
15013
15014
0
    for (size_t i = components.username_end + 1; i < line7.size(); i++) {
15015
0
      line7[i] = '-';
15016
0
    }
15017
0
    line7.append(" username_end ");
15018
0
    line7.append(std::to_string(components.username_end));
15019
0
    answer.append(line7);
15020
0
    answer.append("\n");
15021
0
  }
15022
15023
0
  std::string line8 = line1;
15024
0
  if (components.protocol_end != buffer.size()) {
15025
0
    line8[components.protocol_end] = '`';
15026
0
    line1[components.protocol_end] = ' ';
15027
15028
0
    for (size_t i = components.protocol_end + 1; i < line8.size(); i++) {
15029
0
      line8[i] = '-';
15030
0
    }
15031
0
    line8.append(" protocol_end ");
15032
0
    line8.append(std::to_string(components.protocol_end));
15033
0
    answer.append(line8);
15034
0
    answer.append("\n");
15035
0
  }
15036
15037
0
  if (components.hash_start == url_components::omitted) {
15038
0
    answer.append("note: hash omitted\n");
15039
0
  }
15040
0
  if (components.search_start == url_components::omitted) {
15041
0
    answer.append("note: search omitted\n");
15042
0
  }
15043
0
  if (components.protocol_end > buffer.size()) {
15044
0
    answer.append("warning: protocol_end overflows\n");
15045
0
  }
15046
0
  if (components.username_end > buffer.size()) {
15047
0
    answer.append("warning: username_end overflows\n");
15048
0
  }
15049
0
  if (components.host_start > buffer.size()) {
15050
0
    answer.append("warning: host_start overflows\n");
15051
0
  }
15052
0
  if (components.host_end > buffer.size()) {
15053
0
    answer.append("warning: host_end overflows\n");
15054
0
  }
15055
0
  if (components.pathname_start > buffer.size()) {
15056
0
    answer.append("warning: pathname_start overflows\n");
15057
0
  }
15058
0
  return answer;
15059
0
}
15060
15061
0
void url_aggregator::delete_dash_dot() {
15062
0
  ada_log("url_aggregator::delete_dash_dot");
15063
0
  ADA_ASSERT_TRUE(validate());
15064
0
  ADA_ASSERT_TRUE(has_dash_dot());
15065
0
  buffer.erase(components.host_end, 2);
15066
0
  components.pathname_start -= 2;
15067
0
  if (components.search_start != url_components::omitted) {
15068
0
    components.search_start -= 2;
15069
0
  }
15070
0
  if (components.hash_start != url_components::omitted) {
15071
0
    components.hash_start -= 2;
15072
0
  }
15073
0
  ADA_ASSERT_TRUE(validate());
15074
0
  ADA_ASSERT_TRUE(!has_dash_dot());
15075
0
}
15076
15077
0
inline void url_aggregator::consume_prepared_path(std::string_view input) {
15078
0
  ada_log("url_aggregator::consume_prepared_path ", input);
15079
  /***
15080
   * This is largely duplicated code from helpers::parse_prepared_path, which is
15081
   * unfortunate. This particular function is nearly identical, except that it
15082
   * is a method on url_aggregator. The idea is that the trivial path (which is
15083
   * very common) merely appends to the buffer. This is the same trivial path as
15084
   * with helpers::parse_prepared_path, except that we have the additional check
15085
   * for is_at_path(). Otherwise, we grab a copy of the current path and we
15086
   * modify it, and then insert it back into the buffer.
15087
   */
15088
0
  uint8_t accumulator = checkers::path_signature(input);
15089
  // Let us first detect a trivial case.
15090
  // If it is special, we check that we have no dot, no %,  no \ and no
15091
  // character needing percent encoding. Otherwise, we check that we have no %,
15092
  // no dot, and no character needing percent encoding.
15093
0
  constexpr uint8_t need_encoding = 1;
15094
0
  constexpr uint8_t backslash_char = 2;
15095
0
  constexpr uint8_t dot_char = 4;
15096
0
  constexpr uint8_t percent_char = 8;
15097
0
  bool special = type != ada::scheme::NOT_SPECIAL;
15098
0
  bool may_need_slow_file_handling = (type == ada::scheme::type::FILE &&
15099
0
                                      checkers::is_windows_drive_letter(input));
15100
0
  bool trivial_path =
15101
0
      (special ? (accumulator == 0)
15102
0
               : ((accumulator & (need_encoding | dot_char | percent_char)) ==
15103
0
                  0)) &&
15104
0
      (!may_need_slow_file_handling);
15105
0
  if (accumulator == dot_char && !may_need_slow_file_handling) {
15106
    // '4' means that we have at least one dot, but nothing that requires
15107
    // percent encoding or decoding. The only part that is not trivial is
15108
    // that we may have single dots and double dots path segments.
15109
    // If we have such segments, then we either have a path that begins
15110
    // with '.' (easy to check), or we have the sequence './'.
15111
    // Note: input cannot be empty, it must at least contain one character ('.')
15112
    // Note: we know that '\' is not present.
15113
0
    if (input[0] != '.') {
15114
0
      size_t slashdot = 0;
15115
0
      bool dot_is_file = true;
15116
0
      for (;;) {
15117
0
        slashdot = input.find("/.", slashdot);
15118
0
        if (slashdot == std::string_view::npos) {  // common case
15119
0
          break;
15120
0
        } else {  // uncommon
15121
          // only three cases matter: /./, /.. or a final /
15122
0
          slashdot += 2;
15123
0
          dot_is_file &= !(slashdot == input.size() || input[slashdot] == '.' ||
15124
0
                           input[slashdot] == '/');
15125
0
        }
15126
0
      }
15127
0
      trivial_path = dot_is_file;
15128
0
    }
15129
0
  }
15130
0
  if (trivial_path && is_at_path()) {
15131
0
    ada_log("parse_path trivial");
15132
0
    buffer += '/';
15133
0
    buffer += input;
15134
0
    return;
15135
0
  }
15136
0
  std::string path = std::string(get_pathname());
15137
  // We are going to need to look a bit at the path, but let us see if we can
15138
  // ignore percent encoding *and* backslashes *and* percent characters.
15139
  // Except for the trivial case, this is likely to capture 99% of paths out
15140
  // there.
15141
0
  bool fast_path =
15142
0
      (special &&
15143
0
       (accumulator & (need_encoding | backslash_char | percent_char)) == 0) &&
15144
0
      (type != ada::scheme::type::FILE);
15145
0
  if (fast_path) {
15146
0
    ada_log("parse_prepared_path fast");
15147
    // Here we don't need to worry about \ or percent encoding.
15148
    // We also do not have a file protocol. We might have dots, however,
15149
    // but dots must as appear as '.', and they cannot be encoded because
15150
    // the symbol '%' is not present.
15151
0
    size_t previous_location = 0;  // We start at 0.
15152
0
    do {
15153
0
      size_t new_location = input.find('/', previous_location);
15154
      // std::string_view path_view = input;
15155
      //  We process the last segment separately:
15156
0
      if (new_location == std::string_view::npos) {
15157
0
        std::string_view path_view = input.substr(previous_location);
15158
0
        if (path_view == "..") {  // The path ends with ..
15159
          // e.g., if you receive ".." with an empty path, you go to "/".
15160
0
          if (path.empty()) {
15161
0
            path = '/';
15162
0
            update_base_pathname(path);
15163
0
            return;
15164
0
          }
15165
          // Fast case where we have nothing to do:
15166
0
          if (path.back() == '/') {
15167
0
            update_base_pathname(path);
15168
0
            return;
15169
0
          }
15170
          // If you have the path "/joe/myfriend",
15171
          // then you delete 'myfriend'.
15172
0
          path.resize(path.rfind('/') + 1);
15173
0
          update_base_pathname(path);
15174
0
          return;
15175
0
        }
15176
0
        path += '/';
15177
0
        if (path_view != ".") {
15178
0
          path.append(path_view);
15179
0
        }
15180
0
        update_base_pathname(path);
15181
0
        return;
15182
0
      } else {
15183
        // This is a non-final segment.
15184
0
        std::string_view path_view =
15185
0
            input.substr(previous_location, new_location - previous_location);
15186
0
        previous_location = new_location + 1;
15187
0
        if (path_view == "..") {
15188
0
          size_t last_delimiter = path.rfind('/');
15189
0
          if (last_delimiter != std::string::npos) {
15190
0
            path.erase(last_delimiter);
15191
0
          }
15192
0
        } else if (path_view != ".") {
15193
0
          path += '/';
15194
0
          path.append(path_view);
15195
0
        }
15196
0
      }
15197
0
    } while (true);
15198
0
  } else {
15199
0
    ada_log("parse_path slow");
15200
    // we have reached the general case
15201
0
    bool needs_percent_encoding = (accumulator & 1);
15202
0
    std::string path_buffer_tmp;
15203
0
    do {
15204
0
      size_t location = (special && (accumulator & 2))
15205
0
                            ? input.find_first_of("/\\")
15206
0
                            : input.find('/');
15207
0
      std::string_view path_view = input;
15208
0
      if (location != std::string_view::npos) {
15209
0
        path_view.remove_suffix(path_view.size() - location);
15210
0
        input.remove_prefix(location + 1);
15211
0
      }
15212
      // path_buffer is either path_view or it might point at a percent encoded
15213
      // temporary string.
15214
0
      std::string_view path_buffer =
15215
0
          (needs_percent_encoding &&
15216
0
           ada::unicode::percent_encode<false>(
15217
0
               path_view, character_sets::PATH_PERCENT_ENCODE, path_buffer_tmp))
15218
0
              ? path_buffer_tmp
15219
0
              : path_view;
15220
0
      if (unicode::is_double_dot_path_segment(path_buffer)) {
15221
0
        helpers::shorten_path(path, type);
15222
0
        if (location == std::string_view::npos) {
15223
0
          path += '/';
15224
0
        }
15225
0
      } else if (unicode::is_single_dot_path_segment(path_buffer) &&
15226
0
                 (location == std::string_view::npos)) {
15227
0
        path += '/';
15228
0
      }
15229
      // Otherwise, if path_buffer is not a single-dot path segment, then:
15230
0
      else if (!unicode::is_single_dot_path_segment(path_buffer)) {
15231
        // If url's scheme is "file", url's path is empty, and path_buffer is a
15232
        // Windows drive letter, then replace the second code point in
15233
        // path_buffer with U+003A (:).
15234
0
        if (type == ada::scheme::type::FILE && path.empty() &&
15235
0
            checkers::is_windows_drive_letter(path_buffer)) {
15236
0
          path += '/';
15237
0
          path += path_buffer[0];
15238
0
          path += ':';
15239
0
          path_buffer.remove_prefix(2);
15240
0
          path.append(path_buffer);
15241
0
        } else {
15242
          // Append path_buffer to url's path.
15243
0
          path += '/';
15244
0
          path.append(path_buffer);
15245
0
        }
15246
0
      }
15247
0
      if (location == std::string_view::npos) {
15248
0
        update_base_pathname(path);
15249
0
        return;
15250
0
      }
15251
0
    } while (true);
15252
0
  }
15253
0
}
15254
}  // namespace ada
15255
/* end file src/url_aggregator.cpp */
15256
15257
#if ADA_INCLUDE_URL_PATTERN
15258
/* begin file src/url_pattern.cpp */
15259
#if ADA_INCLUDE_URL_PATTERN
15260
15261
15262
#include <algorithm>
15263
#include <optional>
15264
#include <string>
15265
15266
namespace ada {
15267
15268
tl::expected<url_pattern_init, errors> url_pattern_init::process(
15269
    const url_pattern_init& init, url_pattern_init::process_type type,
15270
    std::optional<std::string_view> protocol,
15271
    std::optional<std::string_view> username,
15272
    std::optional<std::string_view> password,
15273
    std::optional<std::string_view> hostname,
15274
    std::optional<std::string_view> port,
15275
    std::optional<std::string_view> pathname,
15276
    std::optional<std::string_view> search,
15277
0
    std::optional<std::string_view> hash) {
15278
  // Let result be the result of creating a new URLPatternInit.
15279
0
  auto result = url_pattern_init{};
15280
15281
  // If protocol is not null, set result["protocol"] to protocol.
15282
0
  if (protocol.has_value()) result.protocol = *protocol;
15283
15284
  // If username is not null, set result["username"] to username.
15285
0
  if (username.has_value()) result.username = *username;
15286
15287
  // If password is not null, set result["password"] to password.
15288
0
  if (password.has_value()) result.password = *password;
15289
15290
  // If hostname is not null, set result["hostname"] to hostname.
15291
0
  if (hostname.has_value()) result.hostname = *hostname;
15292
15293
  // If port is not null, set result["port"] to port.
15294
0
  if (port.has_value()) result.port = *port;
15295
15296
  // If pathname is not null, set result["pathname"] to pathname.
15297
0
  if (pathname.has_value()) result.pathname = *pathname;
15298
15299
  // If search is not null, set result["search"] to search.
15300
0
  if (search.has_value()) result.search = *search;
15301
15302
  // If hash is not null, set result["hash"] to hash.
15303
0
  if (hash.has_value()) result.hash = *hash;
15304
15305
  // Let baseURL be null.
15306
0
  std::optional<url_aggregator> base_url{};
15307
15308
  // If init["baseURL"] exists:
15309
0
  if (init.base_url.has_value()) {
15310
    // Set baseURL to the result of parsing init["baseURL"].
15311
0
    auto parsing_result = ada::parse<url_aggregator>(*init.base_url);
15312
    // If baseURL is failure, then throw a TypeError.
15313
0
    if (!parsing_result) {
15314
0
      return tl::unexpected(errors::type_error);
15315
0
    }
15316
0
    base_url = std::move(*parsing_result);
15317
15318
    // If init["protocol"] does not exist, then set result["protocol"] to the
15319
    // result of processing a base URL string given baseURL's scheme and type.
15320
0
    if (!init.protocol.has_value()) {
15321
0
      ADA_ASSERT_TRUE(base_url.has_value());
15322
0
      std::string_view base_url_protocol = base_url->get_protocol();
15323
0
      if (base_url_protocol.ends_with(":")) base_url_protocol.remove_suffix(1);
15324
0
      result.protocol =
15325
0
          url_pattern_helpers::process_base_url_string(base_url_protocol, type);
15326
0
    }
15327
15328
    // If type is not "pattern" and init contains none of "protocol",
15329
    // "hostname", "port" and "username", then set result["username"] to the
15330
    // result of processing a base URL string given baseURL's username and type.
15331
0
    if (type != process_type::pattern && !init.protocol && !init.hostname &&
15332
0
        !init.port && !init.username) {
15333
0
      result.username = url_pattern_helpers::process_base_url_string(
15334
0
          base_url->get_username(), type);
15335
0
    }
15336
15337
    // TODO: Optimization opportunity: Merge this with the previous check.
15338
    // If type is not "pattern" and init contains none of "protocol",
15339
    // "hostname", "port", "username" and "password", then set
15340
    // result["password"] to the result of processing a base URL string given
15341
    // baseURL's password and type.
15342
0
    if (type != process_type::pattern && !init.protocol && !init.hostname &&
15343
0
        !init.port && !init.username && !init.password) {
15344
0
      result.password = url_pattern_helpers::process_base_url_string(
15345
0
          base_url->get_password(), type);
15346
0
    }
15347
15348
    // If init contains neither "protocol" nor "hostname", then:
15349
0
    if (!init.protocol && !init.hostname) {
15350
      // Let baseHost be baseURL's host.
15351
      // If baseHost is null, then set baseHost to the empty string.
15352
0
      auto base_host = base_url->get_hostname();
15353
      // Set result["hostname"] to the result of processing a base URL string
15354
      // given baseHost and type.
15355
0
      result.hostname =
15356
0
          url_pattern_helpers::process_base_url_string(base_host, type);
15357
0
    }
15358
15359
    // If init contains none of "protocol", "hostname", and "port", then:
15360
0
    if (!init.protocol && !init.hostname && !init.port) {
15361
      // If baseURL's port is null, then set result["port"] to the empty string.
15362
      // Otherwise, set result["port"] to baseURL's port, serialized.
15363
0
      result.port = base_url->get_port();
15364
0
    }
15365
15366
    // If init contains none of "protocol", "hostname", "port", and "pathname",
15367
    // then set result["pathname"] to the result of processing a base URL string
15368
    // given the result of URL path serializing baseURL and type.
15369
0
    if (!init.protocol && !init.hostname && !init.port && !init.pathname) {
15370
0
      result.pathname = url_pattern_helpers::process_base_url_string(
15371
0
          base_url->get_pathname(), type);
15372
0
    }
15373
15374
    // If init contains none of "protocol", "hostname", "port", "pathname", and
15375
    // "search", then:
15376
0
    if (!init.protocol && !init.hostname && !init.port && !init.pathname &&
15377
0
        !init.search) {
15378
      // Let baseQuery be baseURL's query. get_search() carries the leading "?"
15379
      // delimiter, but the spec inherits the query itself, so drop it.
15380
0
      std::string_view base_query = base_url->get_search();
15381
0
      if (base_query.starts_with("?")) base_query.remove_prefix(1);
15382
      // Set result["search"] to the result of processing a base URL string
15383
      // given baseQuery and type.
15384
0
      result.search =
15385
0
          url_pattern_helpers::process_base_url_string(base_query, type);
15386
0
    }
15387
15388
    // If init contains none of "protocol", "hostname", "port", "pathname",
15389
    // "search", and "hash", then:
15390
0
    if (!init.protocol && !init.hostname && !init.port && !init.pathname &&
15391
0
        !init.search && !init.hash) {
15392
      // Let baseFragment be baseURL's fragment. get_hash() carries the leading
15393
      // "#" delimiter, but the spec inherits the fragment itself, so drop it.
15394
0
      std::string_view base_fragment = base_url->get_hash();
15395
0
      if (base_fragment.starts_with("#")) base_fragment.remove_prefix(1);
15396
      // Set result["hash"] to the result of processing a base URL string given
15397
      // baseFragment and type.
15398
0
      result.hash =
15399
0
          url_pattern_helpers::process_base_url_string(base_fragment, type);
15400
0
    }
15401
0
  }
15402
15403
  // If init["protocol"] exists, then set result["protocol"] to the result of
15404
  // process protocol for init given init["protocol"] and type.
15405
0
  if (init.protocol) {
15406
0
    auto process_result = process_protocol(*init.protocol, type);
15407
0
    if (!process_result) {
15408
0
      return tl::unexpected(process_result.error());
15409
0
    }
15410
0
    result.protocol = std::move(*process_result);
15411
0
  }
15412
15413
  // If init["username"] exists, then set result["username"] to the result of
15414
  // process username for init given init["username"] and type.
15415
0
  if (init.username.has_value()) {
15416
0
    auto process_result = process_username(*init.username, type);
15417
0
    if (!process_result) {
15418
0
      return tl::unexpected(process_result.error());
15419
0
    }
15420
0
    result.username = std::move(*process_result);
15421
0
  }
15422
15423
  // If init["password"] exists, then set result["password"] to the result of
15424
  // process password for init given init["password"] and type.
15425
0
  if (init.password.has_value()) {
15426
0
    auto process_result = process_password(*init.password, type);
15427
0
    if (!process_result) {
15428
0
      return tl::unexpected(process_result.error());
15429
0
    }
15430
0
    result.password = std::move(*process_result);
15431
0
  }
15432
15433
  // If init["hostname"] exists, then set result["hostname"] to the result of
15434
  // process hostname for init given init["hostname"] and type.
15435
0
  if (init.hostname.has_value()) {
15436
0
    auto process_result = process_hostname(*init.hostname, type);
15437
0
    if (!process_result) {
15438
0
      return tl::unexpected(process_result.error());
15439
0
    }
15440
0
    result.hostname = std::move(*process_result);
15441
0
  }
15442
15443
  // If init["port"] exists, then set result["port"] to the result of process
15444
  // port for init given init["port"], result["protocol"], and type.
15445
0
  if (init.port) {
15446
0
    auto process_result =
15447
0
        process_port(*init.port, result.protocol.value_or("fake"), type);
15448
0
    if (!process_result) {
15449
0
      return tl::unexpected(process_result.error());
15450
0
    }
15451
0
    result.port = std::move(*process_result);
15452
0
  }
15453
15454
  // If init["pathname"] exists:
15455
0
  if (init.pathname.has_value()) {
15456
    // Set result["pathname"] to init["pathname"].
15457
0
    result.pathname = init.pathname;
15458
15459
    // If the following are all true:
15460
    // - baseURL is not null;
15461
    // - baseURL has an opaque path; and
15462
    // - the result of running is an absolute pathname given result["pathname"]
15463
    // and type is false,
15464
0
    if (base_url && !base_url->has_opaque_path &&
15465
0
        !url_pattern_helpers::is_absolute_pathname(*result.pathname, type)) {
15466
      // Let baseURLPath be the result of running process a base URL string
15467
      // given the result of URL path serializing baseURL and type.
15468
      // TODO: Optimization opportunity: Avoid returning a string if no slash
15469
      // exist.
15470
0
      std::string base_url_path = url_pattern_helpers::process_base_url_string(
15471
0
          base_url->get_pathname(), type);
15472
15473
      // Let slash index be the index of the last U+002F (/) code point found in
15474
      // baseURLPath, interpreted as a sequence of code points, or null if there
15475
      // are no instances of the code point.
15476
0
      auto slash_index = base_url_path.find_last_of('/');
15477
15478
      // If slash index is not null:
15479
0
      if (slash_index != std::string::npos) {
15480
        // Let new pathname be the code point substring from 0 to slash index +
15481
        // 1 within baseURLPath.
15482
0
        base_url_path.resize(slash_index + 1);
15483
        // Append result["pathname"] to the end of new pathname.
15484
0
        ADA_ASSERT_TRUE(result.pathname.has_value());
15485
0
        base_url_path.append(std::move(*result.pathname));
15486
        // Set result["pathname"] to new pathname.
15487
0
        result.pathname = std::move(base_url_path);
15488
0
      }
15489
0
    }
15490
15491
    // Set result["pathname"] to the result of process pathname for init given
15492
    // result["pathname"], result["protocol"], and type.
15493
0
    auto pathname_processing_result =
15494
0
        process_pathname(*result.pathname, result.protocol.value_or(""), type);
15495
0
    if (!pathname_processing_result) {
15496
0
      return tl::unexpected(pathname_processing_result.error());
15497
0
    }
15498
0
    result.pathname = std::move(*pathname_processing_result);
15499
0
  }
15500
15501
  // If init["search"] exists then set result["search"] to the result of process
15502
  // search for init given init["search"] and type.
15503
0
  if (init.search) {
15504
0
    auto process_result = process_search(*init.search, type);
15505
0
    if (!process_result) {
15506
0
      return tl::unexpected(process_result.error());
15507
0
    }
15508
0
    result.search = std::move(*process_result);
15509
0
  }
15510
15511
  // If init["hash"] exists then set result["hash"] to the result of process
15512
  // hash for init given init["hash"] and type.
15513
0
  if (init.hash) {
15514
0
    auto process_result = process_hash(*init.hash, type);
15515
0
    if (!process_result) {
15516
0
      return tl::unexpected(process_result.error());
15517
0
    }
15518
0
    result.hash = std::move(*process_result);
15519
0
  }
15520
  // Return result.
15521
0
  return result;
15522
0
}
15523
15524
tl::expected<std::string, errors> url_pattern_init::process_protocol(
15525
0
    std::string_view value, process_type type) {
15526
0
  ada_log("process_protocol=", value, " [", type, "]");
15527
  // Let strippedValue be the given value with a single trailing U+003A (:)
15528
  // removed, if any.
15529
0
  if (value.ends_with(":")) {
15530
0
    value.remove_suffix(1);
15531
0
  }
15532
  // If type is "pattern" then return strippedValue.
15533
0
  if (type == process_type::pattern) {
15534
0
    return std::string(value);
15535
0
  }
15536
  // Return the result of running canonicalize a protocol given strippedValue.
15537
0
  return url_pattern_helpers::canonicalize_protocol(value);
15538
0
}
15539
15540
tl::expected<std::string, errors> url_pattern_init::process_username(
15541
0
    std::string_view value, process_type type) {
15542
  // If type is "pattern" then return value.
15543
0
  if (type == process_type::pattern) {
15544
0
    return std::string(value);
15545
0
  }
15546
  // Return the result of running canonicalize a username given value.
15547
0
  return url_pattern_helpers::canonicalize_username(value);
15548
0
}
15549
15550
tl::expected<std::string, errors> url_pattern_init::process_password(
15551
0
    std::string_view value, process_type type) {
15552
  // If type is "pattern" then return value.
15553
0
  if (type == process_type::pattern) {
15554
0
    return std::string(value);
15555
0
  }
15556
  // Return the result of running canonicalize a password given value.
15557
0
  return url_pattern_helpers::canonicalize_password(value);
15558
0
}
15559
15560
tl::expected<std::string, errors> url_pattern_init::process_hostname(
15561
0
    std::string_view value, process_type type) {
15562
0
  ada_log("process_hostname value=", value, " type=", type);
15563
  // If type is "pattern" then return value.
15564
0
  if (type == process_type::pattern) {
15565
0
    return std::string(value);
15566
0
  }
15567
  // Return the result of running canonicalize a hostname given value.
15568
0
  return url_pattern_helpers::canonicalize_hostname(value);
15569
0
}
15570
15571
tl::expected<std::string, errors> url_pattern_init::process_port(
15572
0
    std::string_view port, std::string_view protocol, process_type type) {
15573
  // If type is "pattern" then return portValue.
15574
0
  if (type == process_type::pattern) {
15575
0
    return std::string(port);
15576
0
  }
15577
  // Return the result of running canonicalize a port given portValue and
15578
  // protocolValue.
15579
0
  return url_pattern_helpers::canonicalize_port_with_protocol(port, protocol);
15580
0
}
15581
15582
tl::expected<std::string, errors> url_pattern_init::process_pathname(
15583
0
    std::string_view value, std::string_view protocol, process_type type) {
15584
  // If type is "pattern" then return pathnameValue.
15585
0
  if (type == process_type::pattern) {
15586
0
    return std::string(value);
15587
0
  }
15588
15589
  // If protocolValue is a special scheme or the empty string, then return the
15590
  // result of running canonicalize a pathname given pathnameValue.
15591
0
  if (protocol.empty() || scheme::is_special(protocol)) {
15592
0
    return url_pattern_helpers::canonicalize_pathname(value);
15593
0
  }
15594
15595
  // Return the result of running canonicalize an opaque pathname given
15596
  // pathnameValue.
15597
0
  return url_pattern_helpers::canonicalize_opaque_pathname(value);
15598
0
}
15599
15600
tl::expected<std::string, errors> url_pattern_init::process_search(
15601
0
    std::string_view value, process_type type) {
15602
  // Let strippedValue be the given value with a single leading U+003F (?)
15603
  // removed, if any.
15604
0
  if (value.starts_with("?")) {
15605
0
    value.remove_prefix(1);
15606
0
  }
15607
  // We cannot assert that the value is no longer starting with a single
15608
  // question mark because technically it can start. The question is whether or
15609
  // not we should remove the first question mark. Ref:
15610
  // https://github.com/ada-url/ada/pull/992 The spec is not clear on this.
15611
15612
  // If type is "pattern" then return strippedValue.
15613
0
  if (type == process_type::pattern) {
15614
0
    return std::string(value);
15615
0
  }
15616
  // Return the result of running canonicalize a search given strippedValue.
15617
0
  return url_pattern_helpers::canonicalize_search(value);
15618
0
}
15619
15620
tl::expected<std::string, errors> url_pattern_init::process_hash(
15621
0
    std::string_view value, process_type type) {
15622
  // Let strippedValue be the given value with a single leading U+0023 (#)
15623
  // removed, if any.
15624
0
  if (value.starts_with("#")) {
15625
0
    value.remove_prefix(1);
15626
0
  }
15627
0
  ADA_ASSERT_TRUE(!value.starts_with("#"));
15628
  // If type is "pattern" then return strippedValue.
15629
0
  if (type == process_type::pattern) {
15630
0
    return std::string(value);
15631
0
  }
15632
  // Return the result of running canonicalize a hash given strippedValue.
15633
0
  return url_pattern_helpers::canonicalize_hash(value);
15634
0
}
15635
15636
}  // namespace ada
15637
15638
#endif  // ADA_INCLUDE_URL_PATTERN
15639
/* end file src/url_pattern.cpp */
15640
/* begin file src/url_pattern_helpers.cpp */
15641
#if ADA_INCLUDE_URL_PATTERN
15642
15643
#include <algorithm>
15644
#include <array>
15645
#include <charconv>
15646
#include <optional>
15647
#include <ranges>
15648
#include <string>
15649
15650
15651
namespace ada::url_pattern_helpers {
15652
15653
std::tuple<std::string, std::vector<std::string>>
15654
generate_regular_expression_and_name_list(
15655
    const std::vector<url_pattern_part>& part_list,
15656
0
    url_pattern_compile_component_options options) {
15657
  // Let result be "^"
15658
0
  std::string result = "^";
15659
  // Reserve capacity to reduce reallocations
15660
0
  result.reserve(part_list.size() * 16);
15661
15662
  // Let name list be a new list
15663
0
  std::vector<std::string> name_list{};
15664
0
  name_list.reserve(part_list.size());
15665
15666
  // Pre-generate segment wildcard regexp if needed (avoids repeated generation)
15667
0
  std::string segment_wildcard_regexp;
15668
15669
  // For each part of part list:
15670
0
  for (const url_pattern_part& part : part_list) {
15671
    // If part's type is "fixed-text":
15672
0
    if (part.type == url_pattern_part_type::FIXED_TEXT) {
15673
      // If part's modifier is "none"
15674
0
      if (part.modifier == url_pattern_part_modifier::none) {
15675
0
        result.append(escape_regexp_string(part.value));
15676
0
      } else {
15677
        // (?:<fixed text>)<modifier>
15678
0
        result.append("(?:");
15679
0
        result.append(escape_regexp_string(part.value));
15680
0
        result.push_back(')');
15681
0
        result.append(convert_modifier_to_string(part.modifier));
15682
0
      }
15683
0
      continue;
15684
0
    }
15685
15686
    // Assert: part's name is not the empty string
15687
0
    ADA_ASSERT_TRUE(!part.name.empty());
15688
0
    name_list.push_back(part.name);
15689
15690
    // Use string_view to avoid copies where possible
15691
0
    std::string_view regexp_value = part.value;
15692
15693
0
    if (part.type == url_pattern_part_type::SEGMENT_WILDCARD) {
15694
      // Lazy generate segment wildcard regexp
15695
0
      if (segment_wildcard_regexp.empty()) {
15696
0
        segment_wildcard_regexp = generate_segment_wildcard_regexp(options);
15697
0
      }
15698
0
      regexp_value = segment_wildcard_regexp;
15699
0
    } else if (part.type == url_pattern_part_type::FULL_WILDCARD) {
15700
0
      regexp_value = ".*";
15701
0
    }
15702
15703
    // If part's prefix is the empty string and part's suffix is the empty
15704
    // string
15705
0
    if (part.prefix.empty() && part.suffix.empty()) {
15706
      // If part's modifier is "none" or "optional"
15707
0
      if (part.modifier == url_pattern_part_modifier::none ||
15708
0
          part.modifier == url_pattern_part_modifier::optional) {
15709
        // (<regexp value>)<modifier>
15710
0
        result.push_back('(');
15711
0
        result.append(regexp_value);
15712
0
        result.push_back(')');
15713
0
        result.append(convert_modifier_to_string(part.modifier));
15714
0
      } else {
15715
        // ((?:<regexp value>)<modifier>)
15716
0
        result.append("((?:");
15717
0
        result.append(regexp_value);
15718
0
        result.push_back(')');
15719
0
        result.append(convert_modifier_to_string(part.modifier));
15720
0
        result.push_back(')');
15721
0
      }
15722
0
      continue;
15723
0
    }
15724
15725
    // If part's modifier is "none" or "optional"
15726
0
    if (part.modifier == url_pattern_part_modifier::none ||
15727
0
        part.modifier == url_pattern_part_modifier::optional) {
15728
      // (?:<prefix>(<regexp value>)<suffix>)<modifier>
15729
0
      result.append("(?:");
15730
0
      result.append(escape_regexp_string(part.prefix));
15731
0
      result.push_back('(');
15732
0
      result.append(regexp_value);
15733
0
      result.push_back(')');
15734
0
      result.append(escape_regexp_string(part.suffix));
15735
0
      result.push_back(')');
15736
0
      result.append(convert_modifier_to_string(part.modifier));
15737
0
      continue;
15738
0
    }
15739
15740
    // Assert: part's modifier is "zero-or-more" or "one-or-more"
15741
0
    ADA_ASSERT_TRUE(part.modifier == url_pattern_part_modifier::zero_or_more ||
15742
0
                    part.modifier == url_pattern_part_modifier::one_or_more);
15743
15744
    // Assert: part's prefix is not the empty string or part's suffix is not the
15745
    // empty string
15746
0
    ADA_ASSERT_TRUE(!part.prefix.empty() || !part.suffix.empty());
15747
15748
    // (?:<prefix>((?:<regexp value>)(?:<suffix><prefix>(?:<regexp
15749
    // value>))*)<suffix>)?
15750
    // Append "(?:" to the end of result.
15751
0
    result.append("(?:");
15752
    // Append the result of running escape a regexp string given part's prefix
15753
    // to the end of result.
15754
0
    result.append(escape_regexp_string(part.prefix));
15755
    // Append "((?:" to the end of result.
15756
0
    result.append("((?:");
15757
    // Append regexp value to the end of result.
15758
0
    result.append(regexp_value);
15759
    // Append ")(?:" to the end of result.
15760
0
    result.append(")(?:");
15761
    // Append the result of running escape a regexp string given part's suffix
15762
    // to the end of result.
15763
0
    result.append(escape_regexp_string(part.suffix));
15764
    // Append the result of running escape a regexp string given part's prefix
15765
    // to the end of result.
15766
0
    result.append(escape_regexp_string(part.prefix));
15767
    // Append "(?:" to the end of result.
15768
0
    result.append("(?:");
15769
    // Append regexp value to the end of result.
15770
0
    result.append(regexp_value);
15771
    // Append "))*)" to the end of result.
15772
0
    result.append("))*)");
15773
    // Append the result of running escape a regexp string given part's suffix
15774
    // to the end of result.
15775
0
    result.append(escape_regexp_string(part.suffix));
15776
    // Append ")" to the end of result.
15777
0
    result.append(")");
15778
15779
    // If part's modifier is "zero-or-more" then append "?" to the end of result
15780
0
    if (part.modifier == url_pattern_part_modifier::zero_or_more) {
15781
0
      result += "?";
15782
0
    }
15783
0
  }
15784
15785
  // Append "$" to the end of result
15786
0
  result += "$";
15787
15788
  // Return (result, name list)
15789
0
  return {std::move(result), std::move(name_list)};
15790
0
}
15791
15792
0
bool is_ipv6_address(std::string_view input) noexcept {
15793
  // If input's code point length is less than 2, then return false.
15794
0
  if (input.size() < 2) return false;
15795
15796
  // Let input code points be input interpreted as a list of code points.
15797
  // If input code points[0] is U+005B ([), then return true.
15798
0
  if (input.front() == '[') return true;
15799
  // If input code points[0] is U+007B ({) and input code points[1] is U+005B
15800
  // ([), then return true.
15801
0
  if (input.starts_with("{[")) return true;
15802
  // If input code points[0] is U+005C (\) and input code points[1] is U+005B
15803
  // ([), then return true.
15804
0
  return input.starts_with("\\[");
15805
0
}
15806
15807
std::string_view convert_modifier_to_string(
15808
0
    url_pattern_part_modifier modifier) {
15809
0
  switch (modifier) {
15810
      // If modifier is "zero-or-more", then return "*".
15811
0
    case url_pattern_part_modifier::zero_or_more:
15812
0
      return "*";
15813
    // If modifier is "optional", then return "?".
15814
0
    case url_pattern_part_modifier::optional:
15815
0
      return "?";
15816
    // If modifier is "one-or-more", then return "+".
15817
0
    case url_pattern_part_modifier::one_or_more:
15818
0
      return "+";
15819
    // Return the empty string.
15820
0
    default:
15821
0
      return "";
15822
0
  }
15823
0
}
15824
15825
std::string generate_segment_wildcard_regexp(
15826
0
    url_pattern_compile_component_options options) {
15827
  // Let result be "[^".
15828
0
  std::string result = "[^";
15829
  // Append the result of running escape a regexp string given options's
15830
  // delimiter code point to the end of result.
15831
0
  result.append(escape_regexp_string(options.get_delimiter()));
15832
  // Append "]+?" to the end of result.
15833
0
  result.append("]+?");
15834
  // Return result.
15835
0
  ada_log("generate_segment_wildcard_regexp result: ", result);
15836
0
  return result;
15837
0
}
15838
15839
namespace {
15840
// Unified lookup table for URL pattern character classification
15841
// Bit flags for different character types
15842
constexpr uint8_t CHAR_SCHEME = 1;  // valid in scheme (a-z, A-Z, 0-9, +, -, .)
15843
constexpr uint8_t CHAR_UPPER = 2;   // uppercase letter (needs lowercasing)
15844
constexpr uint8_t CHAR_SIMPLE_HOSTNAME = 4;  // simple hostname (a-z, 0-9, -, .)
15845
constexpr uint8_t CHAR_SIMPLE_PATHNAME =
15846
    8;  // simple pathname (a-z, A-Z, 0-9, /, -, _, ~)
15847
15848
constexpr std::array<uint8_t, 256> char_class_table = []() consteval {
15849
  std::array<uint8_t, 256> table{};
15850
  for (int c = 'a'; c <= 'z'; c++)
15851
    table[c] = CHAR_SCHEME | CHAR_SIMPLE_HOSTNAME | CHAR_SIMPLE_PATHNAME;
15852
  for (int c = 'A'; c <= 'Z'; c++)
15853
    table[c] = CHAR_SCHEME | CHAR_UPPER | CHAR_SIMPLE_PATHNAME;
15854
  for (int c = '0'; c <= '9'; c++)
15855
    table[c] = CHAR_SCHEME | CHAR_SIMPLE_HOSTNAME | CHAR_SIMPLE_PATHNAME;
15856
  table['+'] = CHAR_SCHEME;
15857
  table['-'] = CHAR_SCHEME | CHAR_SIMPLE_HOSTNAME | CHAR_SIMPLE_PATHNAME;
15858
  table['.'] =
15859
      CHAR_SCHEME | CHAR_SIMPLE_HOSTNAME;  // not pathname (needs normalization)
15860
  table['/'] = CHAR_SIMPLE_PATHNAME;
15861
  table['_'] = CHAR_SIMPLE_PATHNAME;
15862
  table['~'] = CHAR_SIMPLE_PATHNAME;
15863
  return table;
15864
}();
15865
}  // namespace
15866
15867
tl::expected<std::string, errors> canonicalize_protocol(
15868
0
    std::string_view input) {
15869
0
  ada_log("canonicalize_protocol called with input=", input);
15870
0
  if (input.empty()) [[unlikely]] {
15871
0
    return "";
15872
0
  }
15873
15874
0
  if (input.ends_with(":")) {
15875
0
    input.remove_suffix(1);
15876
0
  }
15877
15878
  // Fast path: special schemes are already canonical
15879
0
  if (scheme::is_special(input)) {
15880
0
    return std::string(input);
15881
0
  }
15882
15883
  // Fast path: validate scheme chars and check for uppercase
15884
  // First char must be alpha (not +, -, ., or digit)
15885
0
  uint8_t first_flags = char_class_table[static_cast<uint8_t>(input[0])];
15886
0
  if (!(first_flags & CHAR_SCHEME) || input[0] == '+' || input[0] == '-' ||
15887
0
      input[0] == '.' || unicode::is_ascii_digit(input[0])) {
15888
0
    return tl::unexpected(errors::type_error);
15889
0
  }
15890
15891
0
  uint8_t needs_lowercase = first_flags & CHAR_UPPER;
15892
0
  for (size_t i = 1; i < input.size(); i++) {
15893
0
    uint8_t flags = char_class_table[static_cast<uint8_t>(input[i])];
15894
0
    if (!(flags & CHAR_SCHEME)) {
15895
0
      return tl::unexpected(errors::type_error);
15896
0
    }
15897
0
    needs_lowercase |= flags & CHAR_UPPER;
15898
0
  }
15899
15900
0
  if (needs_lowercase == 0) {
15901
0
    return std::string(input);
15902
0
  }
15903
15904
0
  std::string result(input);
15905
0
  unicode::to_lower_ascii(result.data(), result.size());
15906
0
  return result;
15907
0
}
15908
15909
tl::expected<std::string, errors> canonicalize_username(
15910
0
    std::string_view input) {
15911
  // If value is the empty string, return value.
15912
0
  if (input.empty()) [[unlikely]] {
15913
0
    return "";
15914
0
  }
15915
  // Percent-encode the input using the userinfo percent-encode set.
15916
0
  size_t idx = ada::unicode::percent_encode_index(
15917
0
      input, character_sets::USERINFO_PERCENT_ENCODE);
15918
0
  if (idx == input.size()) {
15919
    // No encoding needed, return input as-is
15920
0
    return std::string(input);
15921
0
  }
15922
  // Percent-encode from the first character that needs encoding
15923
0
  return ada::unicode::percent_encode(
15924
0
      input, character_sets::USERINFO_PERCENT_ENCODE, idx);
15925
0
}
15926
15927
tl::expected<std::string, errors> canonicalize_password(
15928
0
    std::string_view input) {
15929
  // If value is the empty string, return value.
15930
0
  if (input.empty()) [[unlikely]] {
15931
0
    return "";
15932
0
  }
15933
  // Percent-encode the input using the userinfo percent-encode set.
15934
0
  size_t idx = ada::unicode::percent_encode_index(
15935
0
      input, character_sets::USERINFO_PERCENT_ENCODE);
15936
0
  if (idx == input.size()) {
15937
    // No encoding needed, return input as-is
15938
0
    return std::string(input);
15939
0
  }
15940
  // Percent-encode from the first character that needs encoding
15941
0
  return ada::unicode::percent_encode(
15942
0
      input, character_sets::USERINFO_PERCENT_ENCODE, idx);
15943
0
}
15944
15945
tl::expected<std::string, errors> canonicalize_hostname(
15946
0
    std::string_view input) {
15947
0
  ada_log("canonicalize_hostname input=", input);
15948
0
  if (input.empty()) [[unlikely]] {
15949
0
    return "";
15950
0
  }
15951
15952
  // Fast path: simple hostnames (lowercase ASCII, digits, -, .) need no IDNA.
15953
  // The simple character set also covers IPv4-shaped hosts, which the slow
15954
  // path rewrites ("0" -> "0.0.0.0", "0x7f.1" -> "127.0.0.1"). Exclude those
15955
  // so the fast path can't return a non-canonical hostname.
15956
  //
15957
  // Pure-ASCII "xn--" labels are intentionally left on the fast path: with
15958
  // beStrict=false, domain-to-ASCII returns the lowercased ASCII input even
15959
  // when Unicode ToASCII would fail (e.g. invalid ACE "xn--a"). See
15960
  // https://url.spec.whatwg.org/#concept-domain-to-ascii
15961
0
  bool needs_processing = false;
15962
0
  for (char c : input) {
15963
0
    needs_processing |=
15964
0
        !(char_class_table[static_cast<uint8_t>(c)] & CHAR_SIMPLE_HOSTNAME);
15965
0
  }
15966
0
  if (!needs_processing && !checkers::is_ipv4(input)) {
15967
0
    return std::string(input);
15968
0
  }
15969
15970
  // Let dummyURL be a new URL record.
15971
  // Let parseResult be the result of running the basic URL parser given value
15972
  // with dummyURL as url and hostname state as state override.
15973
15974
  // IMPORTANT: The protocol needs to be a special protocol, otherwise the
15975
  // hostname will not be converted using IDNA.
15976
0
  auto url = ada::parse<url_aggregator>("https://dummy.test", nullptr);
15977
0
  ADA_ASSERT_TRUE(url);
15978
  // if (!isValidHostnameInput(hostname)) return kj::none;
15979
0
  if (!url->set_hostname(input)) {
15980
    // If parseResult is failure, then throw a TypeError.
15981
0
    return tl::unexpected(errors::type_error);
15982
0
  }
15983
  // Return dummyURL's host, serialized, or empty string if it is null.
15984
0
  return std::string(url->get_hostname());
15985
0
}
15986
15987
tl::expected<std::string, errors> canonicalize_ipv6_hostname(
15988
0
    std::string_view input) {
15989
0
  ada_log("canonicalize_ipv6_hostname input=", input);
15990
  // TODO: Optimization opportunity: Use lookup table to speed up checking
15991
0
  if (std::ranges::any_of(input, [](char c) {
15992
0
        return c != '[' && c != ']' && c != ':' &&
15993
0
               !unicode::is_ascii_hex_digit(c);
15994
0
      })) {
15995
0
    return tl::unexpected(errors::type_error);
15996
0
  }
15997
  // Append the result of running ASCII lowercase given code point to the end of
15998
  // result.
15999
0
  auto hostname = std::string(input);
16000
0
  unicode::to_lower_ascii(hostname.data(), hostname.size());
16001
0
  return hostname;
16002
0
}
16003
16004
tl::expected<std::string, errors> canonicalize_port(
16005
0
    std::string_view port_value) {
16006
  // If portValue is the empty string, return portValue.
16007
0
  if (port_value.empty()) [[unlikely]] {
16008
0
    return "";
16009
0
  }
16010
16011
  // Remove ASCII tab or newline characters
16012
0
  std::string trimmed(port_value);
16013
0
  helpers::remove_ascii_tab_or_newline(trimmed);
16014
16015
0
  if (trimmed.empty()) {
16016
0
    return "";
16017
0
  }
16018
16019
  // Input should start with a digit character
16020
0
  if (!unicode::is_ascii_digit(trimmed.front())) {
16021
0
    return tl::unexpected(errors::type_error);
16022
0
  }
16023
16024
  // Find the first non-digit character
16025
0
  auto first_non_digit =
16026
0
      std::ranges::find_if_not(trimmed, unicode::is_ascii_digit);
16027
0
  std::string_view digits_to_parse =
16028
0
      std::string_view(trimmed.data(), first_non_digit - trimmed.begin());
16029
16030
  // Here we have a range of ASCII digit characters identified by
16031
  // digits_to_parse. It is non-empty. The port state of the URL parser reads
16032
  // it as an integer, so leading zeros are part of the number: "0080" is 80
16033
  // and "065535" is 65535, not a six-digit overflow. Only the significant
16034
  // digits count toward the 5-digit maximum, matching the fast path in
16035
  // implementation.cpp.
16036
0
  size_t first_significant = digits_to_parse.find_first_not_of('0');
16037
0
  if (first_significant == std::string_view::npos) {
16038
    // The value is all zeros, i.e. port 0.
16039
0
    return "0";
16040
0
  }
16041
0
  digits_to_parse.remove_prefix(first_significant);
16042
  // We want to determine whether it is a valid port number (0-65535).
16043
  // Clearly, if the length is greater than 5, it is invalid.
16044
  // If the length is 5, we need to compare lexicographically to "65535".
16045
  // Otherwise it is valid.
16046
0
  if (digits_to_parse.size() == 5) {
16047
0
    if (digits_to_parse > "65535") {
16048
0
      return tl::unexpected(errors::type_error);
16049
0
    }
16050
0
  } else if (digits_to_parse.size() > 5) {
16051
0
    return tl::unexpected(errors::type_error);
16052
0
  }
16053
  // It is valid! Most times, we do not need to parse it into an integer.
16054
0
  return std::string(digits_to_parse);
16055
0
}
16056
16057
tl::expected<std::string, errors> canonicalize_port_with_protocol(
16058
0
    std::string_view port_value, std::string_view protocol) {
16059
  // If portValue is the empty string, return portValue.
16060
0
  if (port_value.empty()) [[unlikely]] {
16061
0
    return "";
16062
0
  }
16063
16064
  // Handle empty or trailing colon in protocol
16065
0
  if (protocol.empty()) {
16066
0
    protocol = "fake";
16067
0
  } else if (protocol.ends_with(":")) {
16068
0
    protocol.remove_suffix(1);
16069
0
  }
16070
16071
  // Remove ASCII tab or newline characters
16072
0
  std::string trimmed(port_value);
16073
0
  helpers::remove_ascii_tab_or_newline(trimmed);
16074
16075
0
  if (trimmed.empty()) {
16076
0
    return "";
16077
0
  }
16078
16079
  // Input should start with a digit character
16080
0
  if (!unicode::is_ascii_digit(trimmed.front())) {
16081
0
    return tl::unexpected(errors::type_error);
16082
0
  }
16083
16084
  // Find the first non-digit character
16085
0
  auto first_non_digit =
16086
0
      std::ranges::find_if_not(trimmed, unicode::is_ascii_digit);
16087
0
  std::string_view digits_to_parse =
16088
0
      std::string_view(trimmed.data(), first_non_digit - trimmed.begin());
16089
16090
  // Parse the port number
16091
0
  uint16_t parsed_port{};
16092
  // NOLINTNEXTLINE(bugprone-suspicious-stringview-data-usage)
16093
0
  auto result = std::from_chars(digits_to_parse.data(),
16094
0
                                digits_to_parse.data() + digits_to_parse.size(),
16095
0
                                parsed_port);
16096
16097
0
  if (result.ec == std::errc::result_out_of_range) {
16098
0
    return tl::unexpected(errors::type_error);
16099
0
  }
16100
16101
0
  if (result.ec == std::errc()) {
16102
    // Check if this is the default port for the scheme
16103
0
    uint16_t default_port = scheme::get_special_port(protocol);
16104
16105
    // If it's the default port for a special scheme, return empty string
16106
0
    if (default_port != 0 && default_port == parsed_port) {
16107
0
      return "";
16108
0
    }
16109
16110
    // Successfully parsed, return as string
16111
0
    return std::to_string(parsed_port);
16112
0
  }
16113
16114
0
  return tl::unexpected(errors::type_error);
16115
0
}
16116
16117
tl::expected<std::string, errors> canonicalize_pathname(
16118
0
    std::string_view input) {
16119
0
  if (input.empty()) [[unlikely]] {
16120
0
    return "";
16121
0
  }
16122
16123
  // Fast path: simple pathnames (no . which needs normalization) can be
16124
  // returned as-is
16125
0
  bool needs_processing = false;
16126
0
  for (char c : input) {
16127
0
    needs_processing |=
16128
0
        !(char_class_table[static_cast<uint8_t>(c)] & CHAR_SIMPLE_PATHNAME);
16129
0
  }
16130
0
  if (!needs_processing) {
16131
0
    return std::string(input);
16132
0
  }
16133
16134
  // Let leading slash be true if the first code point in value is U+002F (/)
16135
  // and otherwise false.
16136
0
  const bool leading_slash = input.starts_with("/");
16137
  // Let modified value be "/-" if leading slash is false and otherwise the
16138
  // empty string.
16139
0
  const auto modified_value =
16140
0
      (leading_slash ? std::string() : std::string("/-")) + std::string(input);
16141
  // The spec runs the basic URL parser with the path in state override, where
16142
  // '?' and '#' are ordinary path code points (percent-encoded) and leading or
16143
  // trailing C0 control or space is kept. Building a full URL string and
16144
  // parsing it (no state override) instead let '?' and '#' start the
16145
  // query/fragment, so the pathname was silently truncated at the first literal
16146
  // '?' or '#'. set_pathname runs the parser in path state override, matching
16147
  // how canonicalize_hostname uses set_hostname.
16148
0
  auto url = ada::parse<url_aggregator>("fake://fake-url", nullptr);
16149
0
  ADA_ASSERT_TRUE(url);
16150
0
  if (!url->set_pathname(modified_value)) {
16151
    // If parseResult is failure, then throw a TypeError.
16152
0
    return tl::unexpected(errors::type_error);
16153
0
  }
16154
0
  const auto pathname = url->get_pathname();
16155
  // If leading slash is false, then set result to the code point substring
16156
  // from 2 to the end of the string within result.
16157
0
  if (!leading_slash) {
16158
    // pathname should start with "/-" but path traversal (e.g. "../../")
16159
    // can reduce it to just "/" which is shorter than 2 characters.
16160
0
    if (pathname.size() < 2) {
16161
0
      return tl::unexpected(errors::type_error);
16162
0
    }
16163
0
    return std::string(pathname.substr(2));
16164
0
  }
16165
0
  return std::string(pathname);
16166
0
}
16167
16168
tl::expected<std::string, errors> canonicalize_opaque_pathname(
16169
0
    std::string_view input) {
16170
  // If value is the empty string, return value.
16171
0
  if (input.empty()) [[unlikely]] {
16172
0
    return "";
16173
0
  }
16174
  // Let dummyURL be a new URL record.
16175
  // Set dummyURL's path to the empty string.
16176
  // Let parseResult be the result of running URL parsing given value with
16177
  // dummyURL as url and opaque path state as state override.
16178
0
  if (auto url =
16179
0
          ada::parse<url_aggregator>("fake:" + std::string(input), nullptr)) {
16180
    // Return the result of URL path serializing dummyURL.
16181
0
    return std::string(url->get_pathname());
16182
0
  }
16183
  // If parseResult is failure, then throw a TypeError.
16184
0
  return tl::unexpected(errors::type_error);
16185
0
}
16186
16187
0
tl::expected<std::string, errors> canonicalize_search(std::string_view input) {
16188
  // If value is the empty string, return value.
16189
0
  if (input.empty()) [[unlikely]] {
16190
0
    return "";
16191
0
  }
16192
  // A leading '?' is a valid query code point here: it is the caller (process a
16193
  // search) that removes a single delimiter, not this step, which mirrors the
16194
  // basic URL parser's query state.
16195
0
  std::string new_value(input);
16196
  // Remove ASCII tab or newline characters
16197
0
  helpers::remove_ascii_tab_or_newline(new_value);
16198
16199
0
  if (new_value.empty()) {
16200
0
    return "";
16201
0
  }
16202
16203
  // Percent-encode using QUERY_PERCENT_ENCODE (for non-special URLs)
16204
  // Note: "fake://dummy.test" is not a special URL, so we use
16205
  // QUERY_PERCENT_ENCODE
16206
0
  size_t idx = ada::unicode::percent_encode_index(
16207
0
      new_value, character_sets::QUERY_PERCENT_ENCODE);
16208
0
  if (idx == new_value.size()) {
16209
    // No encoding needed
16210
0
    return new_value;
16211
0
  }
16212
  // Percent-encode from the first character that needs encoding
16213
0
  return ada::unicode::percent_encode(
16214
0
      new_value, character_sets::QUERY_PERCENT_ENCODE, idx);
16215
0
}
16216
16217
0
tl::expected<std::string, errors> canonicalize_hash(std::string_view input) {
16218
  // If value is the empty string, return value.
16219
0
  if (input.empty()) [[unlikely]] {
16220
0
    return "";
16221
0
  }
16222
  // A leading '#' is a valid fragment code point here: it is the caller
16223
  // (process a hash) that removes a single delimiter, not this step, which
16224
  // mirrors the basic URL parser's fragment state.
16225
0
  std::string new_value(input);
16226
  // Remove ASCII tab or newline characters
16227
0
  helpers::remove_ascii_tab_or_newline(new_value);
16228
16229
0
  if (new_value.empty()) {
16230
0
    return "";
16231
0
  }
16232
16233
  // Percent-encode using FRAGMENT_PERCENT_ENCODE
16234
0
  size_t idx = ada::unicode::percent_encode_index(
16235
0
      new_value, character_sets::FRAGMENT_PERCENT_ENCODE);
16236
0
  if (idx == new_value.size()) {
16237
    // No encoding needed
16238
0
    return new_value;
16239
0
  }
16240
  // Percent-encode from the first character that needs encoding
16241
0
  return ada::unicode::percent_encode(
16242
0
      new_value, character_sets::FRAGMENT_PERCENT_ENCODE, idx);
16243
0
}
16244
16245
tl::expected<std::vector<token>, errors> tokenize(std::string_view input,
16246
0
                                                  token_policy policy) {
16247
0
  ada_log("tokenize input: ", input);
16248
  // Let tokenizer be a new tokenizer.
16249
  // Set tokenizer's input to input.
16250
  // Set tokenizer's policy to policy.
16251
0
  auto tokenizer = Tokenizer(input, policy);
16252
  // While tokenizer's index is less than tokenizer's input's code point length:
16253
0
  while (tokenizer.index < tokenizer.input.size()) {
16254
    // Run seek and get the next code point given tokenizer and tokenizer's
16255
    // index.
16256
0
    tokenizer.seek_and_get_next_code_point(tokenizer.index);
16257
16258
    // Malformed UTF-8 must not stall tokenization: report an invalid-char
16259
    // token (lenient) or fail fast (strict), while always making progress.
16260
0
    if (tokenizer.had_invalid_code_point()) {
16261
0
      if (auto error = tokenizer.process_tokenizing_error(tokenizer.next_index,
16262
0
                                                          tokenizer.index)) {
16263
0
        return tl::unexpected(*error);
16264
0
      }
16265
0
      continue;
16266
0
    }
16267
16268
    // If tokenizer's code point is U+002A (*):
16269
0
    if (tokenizer.code_point == '*') {
16270
      // Run add a token with default position and length given tokenizer and
16271
      // "asterisk".
16272
0
      tokenizer.add_token_with_defaults(token_type::ASTERISK);
16273
0
      ada_log("add ASTERISK token");
16274
      // Continue.
16275
0
      continue;
16276
0
    }
16277
16278
    // If tokenizer's code point is U+002B (+) or U+003F (?):
16279
0
    if (tokenizer.code_point == '+' || tokenizer.code_point == '?') {
16280
      // Run add a token with default position and length given tokenizer and
16281
      // "other-modifier".
16282
0
      tokenizer.add_token_with_defaults(token_type::OTHER_MODIFIER);
16283
      // Continue.
16284
0
      continue;
16285
0
    }
16286
16287
    // If tokenizer's code point is U+005C (\):
16288
0
    if (tokenizer.code_point == '\\') {
16289
      // If tokenizer's index is equal to tokenizer's input's code point length
16290
      // - 1:
16291
0
      if (tokenizer.index == tokenizer.input.size() - 1) {
16292
        // Run process a tokenizing error given tokenizer, tokenizer's next
16293
        // index, and tokenizer's index.
16294
0
        if (auto error = tokenizer.process_tokenizing_error(
16295
0
                tokenizer.next_index, tokenizer.index)) {
16296
0
          ada_log("process_tokenizing_error failed");
16297
0
          return tl::unexpected(*error);
16298
0
        }
16299
0
        continue;
16300
0
      }
16301
16302
      // Let escaped index be tokenizer's next index.
16303
0
      auto escaped_index = tokenizer.next_index;
16304
      // Run get the next code point given tokenizer.
16305
0
      tokenizer.get_next_code_point();
16306
0
      if (tokenizer.had_invalid_code_point()) {
16307
0
        if (auto error = tokenizer.process_tokenizing_error(
16308
0
                tokenizer.next_index, escaped_index)) {
16309
0
          return tl::unexpected(*error);
16310
0
        }
16311
0
        continue;
16312
0
      }
16313
      // Run add a token with default length given tokenizer, "escaped-char",
16314
      // tokenizer's next index, and escaped index.
16315
0
      tokenizer.add_token_with_default_length(
16316
0
          token_type::ESCAPED_CHAR, tokenizer.next_index, escaped_index);
16317
0
      ada_log("add ESCAPED_CHAR token on next_index ", tokenizer.next_index,
16318
0
              " with escaped index ", escaped_index);
16319
      // Continue.
16320
0
      continue;
16321
0
    }
16322
16323
    // If tokenizer's code point is U+007B ({):
16324
0
    if (tokenizer.code_point == '{') {
16325
      // Run add a token with default position and length given tokenizer and
16326
      // "open".
16327
0
      tokenizer.add_token_with_defaults(token_type::OPEN);
16328
0
      ada_log("add OPEN token");
16329
0
      continue;
16330
0
    }
16331
16332
    // If tokenizer's code point is U+007D (}):
16333
0
    if (tokenizer.code_point == '}') {
16334
      // Run add a token with default position and length given tokenizer and
16335
      // "close".
16336
0
      tokenizer.add_token_with_defaults(token_type::CLOSE);
16337
0
      ada_log("add CLOSE token");
16338
0
      continue;
16339
0
    }
16340
16341
    // If tokenizer's code point is U+003A (:):
16342
0
    if (tokenizer.code_point == ':') {
16343
      // Let name position be tokenizer's next index.
16344
0
      auto name_position = tokenizer.next_index;
16345
      // Let name start be name position.
16346
0
      auto name_start = name_position;
16347
0
      bool invalid_name = false;
16348
      // While name position is less than tokenizer's input's code point length:
16349
0
      while (name_position < tokenizer.input.size()) {
16350
        // Run seek and get the next code point given tokenizer and name
16351
        // position.
16352
0
        tokenizer.seek_and_get_next_code_point(name_position);
16353
0
        if (tokenizer.had_invalid_code_point()) {
16354
0
          if (auto error = tokenizer.process_tokenizing_error(
16355
0
                  tokenizer.next_index, name_position)) {
16356
0
            return tl::unexpected(*error);
16357
0
          }
16358
0
          invalid_name = true;
16359
0
          break;
16360
0
        }
16361
        // Let first code point be true if name position equals name start and
16362
        // false otherwise.
16363
0
        bool first_code_point = name_position == name_start;
16364
        // Let valid code point be the result of running is a valid name code
16365
        // point given tokenizer's code point and first code point.
16366
0
        auto valid_code_point =
16367
0
            idna::valid_name_code_point(tokenizer.code_point, first_code_point);
16368
0
        ada_log("tokenizer.code_point=", uint32_t(tokenizer.code_point),
16369
0
                " first_code_point=", first_code_point,
16370
0
                " valid_code_point=", valid_code_point);
16371
        // If valid code point is false break.
16372
0
        if (!valid_code_point) break;
16373
        // Set name position to tokenizer's next index.
16374
0
        name_position = tokenizer.next_index;
16375
0
      }
16376
16377
0
      if (invalid_name) {
16378
0
        continue;
16379
0
      }
16380
16381
      // If name position is less than or equal to name start:
16382
0
      if (name_position <= name_start) {
16383
        // Run process a tokenizing error given tokenizer, name start, and
16384
        // tokenizer's index.
16385
0
        if (auto error = tokenizer.process_tokenizing_error(name_start,
16386
0
                                                            tokenizer.index)) {
16387
0
          ada_log("process_tokenizing_error failed");
16388
0
          return tl::unexpected(*error);
16389
0
        }
16390
        // Continue
16391
0
        continue;
16392
0
      }
16393
16394
      // Run add a token with default length given tokenizer, "name", name
16395
      // position, and name start.
16396
0
      tokenizer.add_token_with_default_length(token_type::NAME, name_position,
16397
0
                                              name_start);
16398
0
      continue;
16399
0
    }
16400
16401
    // If tokenizer's code point is U+0028 (():
16402
0
    if (tokenizer.code_point == '(') {
16403
      // Let depth be 1.
16404
0
      size_t depth = 1;
16405
      // Let regexp position be tokenizer's next index.
16406
0
      auto regexp_position = tokenizer.next_index;
16407
      // Let regexp start be regexp position.
16408
0
      auto regexp_start = regexp_position;
16409
      // Let error be false.
16410
0
      bool error = false;
16411
16412
      // While regexp position is less than tokenizer's input's code point
16413
      // length:
16414
0
      while (regexp_position < tokenizer.input.size()) {
16415
        // Run seek and get the next code point given tokenizer and regexp
16416
        // position.
16417
0
        tokenizer.seek_and_get_next_code_point(regexp_position);
16418
0
        if (tokenizer.had_invalid_code_point()) {
16419
0
          if (auto process_error = tokenizer.process_tokenizing_error(
16420
0
                  tokenizer.next_index, regexp_position)) {
16421
0
            return tl::unexpected(*process_error);
16422
0
          }
16423
0
          error = true;
16424
0
          break;
16425
0
        }
16426
16427
        // TODO: Optimization opportunity: The next 2 if statements can be
16428
        // merged. If the result of running is ASCII given tokenizer's code
16429
        // point is false:
16430
0
        if (!unicode::is_ascii(tokenizer.code_point)) {
16431
          // Run process a tokenizing error given tokenizer, regexp start, and
16432
          // tokenizer's index.
16433
0
          if (auto process_error = tokenizer.process_tokenizing_error(
16434
0
                  regexp_start, tokenizer.index)) {
16435
0
            return tl::unexpected(*process_error);
16436
0
          }
16437
          // Set error to true.
16438
0
          error = true;
16439
0
          break;
16440
0
        }
16441
16442
        // If regexp position equals regexp start and tokenizer's code point is
16443
        // U+003F (?):
16444
0
        if (regexp_position == regexp_start && tokenizer.code_point == '?') {
16445
          // Run process a tokenizing error given tokenizer, regexp start, and
16446
          // tokenizer's index.
16447
0
          if (auto process_error = tokenizer.process_tokenizing_error(
16448
0
                  regexp_start, tokenizer.index)) {
16449
0
            return tl::unexpected(*process_error);
16450
0
          }
16451
          // Set error to true;
16452
0
          error = true;
16453
0
          break;
16454
0
        }
16455
16456
        // If tokenizer's code point is U+005C (\):
16457
0
        if (tokenizer.code_point == '\\') {
16458
          // If regexp position equals tokenizer's input's code point length - 1
16459
0
          if (regexp_position == tokenizer.input.size() - 1) {
16460
            // Run process a tokenizing error given tokenizer, regexp start, and
16461
            // tokenizer's index.
16462
0
            if (auto process_error = tokenizer.process_tokenizing_error(
16463
0
                    regexp_start, tokenizer.index)) {
16464
0
              return tl::unexpected(*process_error);
16465
0
            }
16466
            // Set error to true.
16467
0
            error = true;
16468
0
            break;
16469
0
          }
16470
          // Run get the next code point given tokenizer.
16471
0
          auto escaped_index = tokenizer.next_index;
16472
0
          tokenizer.get_next_code_point();
16473
0
          if (tokenizer.had_invalid_code_point()) {
16474
0
            if (auto process_error = tokenizer.process_tokenizing_error(
16475
0
                    tokenizer.next_index, escaped_index)) {
16476
0
              return tl::unexpected(*process_error);
16477
0
            }
16478
0
            error = true;
16479
0
            break;
16480
0
          }
16481
          // If the result of running is ASCII given tokenizer's code point is
16482
          // false:
16483
0
          if (!unicode::is_ascii(tokenizer.code_point)) {
16484
            // Run process a tokenizing error given tokenizer, regexp start, and
16485
            // tokenizer's index.
16486
0
            if (auto process_error = tokenizer.process_tokenizing_error(
16487
0
                    regexp_start, tokenizer.index);
16488
0
                process_error.has_value()) {
16489
0
              return tl::unexpected(*process_error);
16490
0
            }
16491
            // Set error to true.
16492
0
            error = true;
16493
0
            break;
16494
0
          }
16495
          // Set regexp position to tokenizer's next index.
16496
0
          regexp_position = tokenizer.next_index;
16497
0
          continue;
16498
0
        }
16499
16500
        // If tokenizer's code point is U+0029 ()):
16501
0
        if (tokenizer.code_point == ')') {
16502
          // Decrement depth by 1.
16503
0
          depth--;
16504
          // If depth is 0:
16505
0
          if (depth == 0) {
16506
            // Set regexp position to tokenizer's next index.
16507
0
            regexp_position = tokenizer.next_index;
16508
            // Break.
16509
0
            break;
16510
0
          }
16511
0
        } else if (tokenizer.code_point == '(') {
16512
          // Otherwise if tokenizer's code point is U+0028 (():
16513
          // Increment depth by 1.
16514
0
          depth++;
16515
          // If regexp position equals tokenizer's input's code point length -
16516
          // 1:
16517
0
          if (regexp_position == tokenizer.input.size() - 1) {
16518
            // Run process a tokenizing error given tokenizer, regexp start, and
16519
            // tokenizer's index.
16520
0
            if (auto process_error = tokenizer.process_tokenizing_error(
16521
0
                    regexp_start, tokenizer.index)) {
16522
0
              return tl::unexpected(*process_error);
16523
0
            }
16524
            // Set error to true.
16525
0
            error = true;
16526
0
            break;
16527
0
          }
16528
          // Let temporary position be tokenizer's next index.
16529
0
          auto temporary_position = tokenizer.next_index;
16530
          // Run get the next code point given tokenizer.
16531
0
          tokenizer.get_next_code_point();
16532
0
          if (tokenizer.had_invalid_code_point()) {
16533
0
            if (auto process_error = tokenizer.process_tokenizing_error(
16534
0
                    tokenizer.next_index, temporary_position)) {
16535
0
              return tl::unexpected(*process_error);
16536
0
            }
16537
0
            error = true;
16538
0
            break;
16539
0
          }
16540
          // If tokenizer's code point is not U+003F (?):
16541
0
          if (tokenizer.code_point != '?') {
16542
            // Run process a tokenizing error given tokenizer, regexp start, and
16543
            // tokenizer's index.
16544
0
            if (auto process_error = tokenizer.process_tokenizing_error(
16545
0
                    regexp_start, tokenizer.index)) {
16546
0
              return tl::unexpected(*process_error);
16547
0
            }
16548
            // Set error to true.
16549
0
            error = true;
16550
0
            break;
16551
0
          }
16552
          // Set tokenizer's next index to temporary position.
16553
0
          tokenizer.next_index = temporary_position;
16554
0
        }
16555
        // Set regexp position to tokenizer's next index.
16556
0
        regexp_position = tokenizer.next_index;
16557
0
      }
16558
16559
      // If error is true continue.
16560
0
      if (error) continue;
16561
      // If depth is not zero:
16562
0
      if (depth != 0) {
16563
        // Run process a tokenizing error given tokenizer, regexp start, and
16564
        // tokenizer's index.
16565
0
        if (auto process_error = tokenizer.process_tokenizing_error(
16566
0
                regexp_start, tokenizer.index)) {
16567
0
          return tl::unexpected(*process_error);
16568
0
        }
16569
0
        continue;
16570
0
      }
16571
      // Let regexp length be regexp position - regexp start - 1.
16572
0
      auto regexp_length = regexp_position - regexp_start - 1;
16573
      // If regexp length is zero:
16574
0
      if (regexp_length == 0) {
16575
        // Run process a tokenizing error given tokenizer, regexp start, and
16576
        // tokenizer's index.
16577
0
        if (auto process_error = tokenizer.process_tokenizing_error(
16578
0
                regexp_start, tokenizer.index)) {
16579
0
          ada_log("process_tokenizing_error failed");
16580
0
          return tl::unexpected(*process_error);
16581
0
        }
16582
0
        continue;
16583
0
      }
16584
      // Run add a token given tokenizer, "regexp", regexp position, regexp
16585
      // start, and regexp length.
16586
0
      tokenizer.add_token(token_type::REGEXP, regexp_position, regexp_start,
16587
0
                          regexp_length);
16588
0
      continue;
16589
0
    }
16590
    // Run add a token with default position and length given tokenizer and
16591
    // "char".
16592
0
    tokenizer.add_token_with_defaults(token_type::CHAR);
16593
0
  }
16594
  // Run add a token with default length given tokenizer, "end", tokenizer's
16595
  // index, and tokenizer's index.
16596
0
  tokenizer.add_token_with_default_length(token_type::END, tokenizer.index,
16597
0
                                          tokenizer.index);
16598
16599
0
  ada_log("tokenizer.token_list size is: ", tokenizer.token_list.size());
16600
  // Return tokenizer's token list.
16601
0
  return tokenizer.token_list;
16602
0
}
16603
16604
namespace {
16605
constexpr std::array<uint8_t, 256> escape_pattern_table = []() consteval {
16606
  std::array<uint8_t, 256> out{};
16607
  for (auto& c : {'+', '*', '?', ':', '{', '}', '(', ')', '\\'}) {
16608
    out[c] = 1;
16609
  }
16610
  return out;
16611
}();
16612
16613
0
constexpr bool should_escape_pattern_char(char c) {
16614
0
  return escape_pattern_table[static_cast<uint8_t>(c)];
16615
0
}
16616
}  // namespace
16617
16618
0
std::string escape_pattern_string(std::string_view input) {
16619
0
  ada_log("escape_pattern_string called with input=", input);
16620
0
  if (input.empty()) [[unlikely]] {
16621
0
    return "";
16622
0
  }
16623
  // Assert: input is an ASCII string.
16624
0
  ADA_ASSERT_TRUE(ada::idna::is_ascii(input));
16625
  // Let result be the empty string.
16626
0
  std::string result{};
16627
  // Reserve extra space for potential escapes
16628
0
  result.reserve(input.size() * 2);
16629
16630
  // While index is less than input's length:
16631
0
  for (const char c : input) {
16632
0
    if (should_escape_pattern_char(c)) {
16633
      // Append U+005C (\) to the end of result.
16634
0
      result.push_back('\\');
16635
0
    }
16636
    // Append c to the end of result.
16637
0
    result.push_back(c);
16638
0
  }
16639
  // Return result.
16640
0
  return result;
16641
0
}
16642
16643
namespace {
16644
constexpr std::array<uint8_t, 256> escape_regexp_table = []() consteval {
16645
  std::array<uint8_t, 256> out{};
16646
  for (auto& c : {'.', '+', '*', '?', '^', '$', '{', '}', '(', ')', '[', ']',
16647
                  '|', '/', '\\'}) {
16648
    out[c] = 1;
16649
  }
16650
  return out;
16651
}();
16652
16653
0
constexpr bool should_escape_regexp_char(char c) {
16654
0
  return escape_regexp_table[(uint8_t)c];
16655
0
}
16656
}  // namespace
16657
16658
0
std::string escape_regexp_string(std::string_view input) {
16659
  // Assert: input is an ASCII string.
16660
0
  ADA_ASSERT_TRUE(idna::is_ascii(input));
16661
  // Let result be the empty string.
16662
0
  std::string result{};
16663
  // Reserve extra space for potential escapes (worst case: all chars escaped)
16664
0
  result.reserve(input.size() * 2);
16665
0
  for (const char c : input) {
16666
0
    if (should_escape_regexp_char(c)) {
16667
      // Avoid temporary string allocation - directly append characters
16668
0
      result.push_back('\\');
16669
0
      result.push_back(c);
16670
0
    } else {
16671
0
      result.push_back(c);
16672
0
    }
16673
0
  }
16674
0
  return result;
16675
0
}
16676
16677
std::string process_base_url_string(std::string_view input,
16678
0
                                    url_pattern_init::process_type type) {
16679
  // If type is not "pattern" return input.
16680
0
  if (type != url_pattern_init::process_type::pattern) {
16681
0
    return std::string(input);
16682
0
  }
16683
  // Return the result of escaping a pattern string given input.
16684
0
  return escape_pattern_string(input);
16685
0
}
16686
16687
constexpr bool is_absolute_pathname(
16688
0
    std::string_view input, url_pattern_init::process_type type) noexcept {
16689
  // If input is the empty string, then return false.
16690
0
  if (input.empty()) [[unlikely]] {
16691
0
    return false;
16692
0
  }
16693
  // If input[0] is U+002F (/), then return true.
16694
0
  if (input.starts_with("/")) return true;
16695
  // If type is "url", then return false.
16696
0
  if (type == url_pattern_init::process_type::url) return false;
16697
  // If input's code point length is less than 2, then return false.
16698
0
  if (input.size() < 2) return false;
16699
  // If input[0] is U+005C (\) and input[1] is U+002F (/), then return true.
16700
  // If input[0] is U+007B ({) and input[1] is U+002F (/), then return true.
16701
  // Return false.
16702
0
  return input[1] == '/' && (input[0] == '\\' || input[0] == '{');
16703
0
}
16704
16705
std::string generate_pattern_string(
16706
    std::vector<url_pattern_part>& part_list,
16707
0
    url_pattern_compile_component_options& options) {
16708
  // Let result be the empty string.
16709
0
  std::string result{};
16710
  // Let index list be the result of getting the indices for part list.
16711
  // For each index of index list:
16712
0
  for (size_t index = 0; index < part_list.size(); index++) {
16713
    // Let part be part list[index].
16714
    // Use reference to avoid copy
16715
0
    const auto& part = part_list[index];
16716
    // Let previous part be part list[index - 1] if index is greater than 0,
16717
    // otherwise let it be null.
16718
    // Use pointer to avoid copy
16719
0
    const url_pattern_part* previous_part =
16720
0
        index == 0 ? nullptr : &part_list[index - 1];
16721
    // Let next part be part list[index + 1] if index is less than index list's
16722
    // size - 1, otherwise let it be null.
16723
0
    const url_pattern_part* next_part =
16724
0
        index < part_list.size() - 1 ? &part_list[index + 1] : nullptr;
16725
    // If part's type is "fixed-text" then:
16726
0
    if (part.type == url_pattern_part_type::FIXED_TEXT) {
16727
      // If part's modifier is "none" then:
16728
0
      if (part.modifier == url_pattern_part_modifier::none) {
16729
        // Append the result of running escape a pattern string given part's
16730
        // value to the end of result.
16731
0
        result.append(escape_pattern_string(part.value));
16732
0
        continue;
16733
0
      }
16734
      // Append "{" to the end of result.
16735
0
      result += "{";
16736
      // Append the result of running escape a pattern string given part's value
16737
      // to the end of result.
16738
0
      result.append(escape_pattern_string(part.value));
16739
      // Append "}" to the end of result.
16740
0
      result += "}";
16741
      // Append the result of running convert a modifier to a string given
16742
      // part's modifier to the end of result.
16743
0
      result.append(convert_modifier_to_string(part.modifier));
16744
0
      continue;
16745
0
    }
16746
    // Let custom name be true if part's name[0] is not an ASCII digit;
16747
    // otherwise false.
16748
0
    bool custom_name = !unicode::is_ascii_digit(part.name[0]);
16749
    // Let needs grouping be true if at least one of the following are true,
16750
    // otherwise let it be false:
16751
    // - part's suffix is not the empty string.
16752
    // - part's prefix is not the empty string and is not options's prefix code
16753
    // point.
16754
0
    bool needs_grouping =
16755
0
        !part.suffix.empty() ||
16756
0
        (!part.prefix.empty() && (options.get_prefix().empty() ||
16757
0
                                  part.prefix[0] != options.get_prefix()[0]));
16758
16759
    // If all of the following are true:
16760
    // - needs grouping is false; and
16761
    // - custom name is true; and
16762
    // - part's type is "segment-wildcard"; and
16763
    // - part's modifier is "none"; and
16764
    // - next part is not null; and
16765
    // - next part's prefix is the empty string; and
16766
    // - next part's suffix is the empty string
16767
0
    if (!needs_grouping && custom_name &&
16768
0
        part.type == url_pattern_part_type::SEGMENT_WILDCARD &&
16769
0
        part.modifier == url_pattern_part_modifier::none && next_part &&
16770
0
        next_part->prefix.empty() && next_part->suffix.empty()) {
16771
      // If next part's type is "fixed-text":
16772
0
      if (next_part->type == url_pattern_part_type::FIXED_TEXT) {
16773
        // Set needs grouping to true if the result of running is a valid name
16774
        // code point given next part's value's first code point and the boolean
16775
        // false is true.
16776
0
        if (idna::valid_name_code_point(next_part->value[0], false)) {
16777
0
          needs_grouping = true;
16778
0
        }
16779
0
      } else {
16780
        // Set needs grouping to true if next part's name[0] is an ASCII digit.
16781
0
        needs_grouping = !next_part->name.empty() &&
16782
0
                         unicode::is_ascii_digit(next_part->name[0]);
16783
0
      }
16784
0
    }
16785
16786
    // If all of the following are true:
16787
    // - needs grouping is false; and
16788
    // - part's prefix is the empty string; and
16789
    // - previous part is not null; and
16790
    // - previous part's type is "fixed-text"; and
16791
    // - previous part's value's last code point is options's prefix code point.
16792
    // then set needs grouping to true.
16793
0
    if (!needs_grouping && part.prefix.empty() && previous_part &&
16794
0
        previous_part->type == url_pattern_part_type::FIXED_TEXT &&
16795
0
        !previous_part->value.empty() && !options.get_prefix().empty() &&
16796
0
        previous_part->value.back() == options.get_prefix()[0]) {
16797
0
      needs_grouping = true;
16798
0
    }
16799
16800
    // Assert: part's name is not the empty string or null.
16801
0
    ADA_ASSERT_TRUE(!part.name.empty());
16802
16803
    // If needs grouping is true, then append "{" to the end of result.
16804
0
    if (needs_grouping) {
16805
0
      result.append("{");
16806
0
    }
16807
16808
    // Append the result of running escape a pattern string given part's prefix
16809
    // to the end of result.
16810
0
    result.append(escape_pattern_string(part.prefix));
16811
16812
    // If custom name is true:
16813
0
    if (custom_name) {
16814
      // Append ":" to the end of result.
16815
0
      result.append(":");
16816
      // Append part's name to the end of result.
16817
0
      result.append(part.name);
16818
0
    }
16819
16820
    // If part's type is "regexp" then:
16821
0
    if (part.type == url_pattern_part_type::REGEXP) {
16822
      // Append "(" to the end of result.
16823
0
      result.append("(");
16824
      // Append part's value to the end of result.
16825
0
      result.append(part.value);
16826
      // Append ")" to the end of result.
16827
0
      result.append(")");
16828
0
    } else if (part.type == url_pattern_part_type::SEGMENT_WILDCARD &&
16829
0
               !custom_name) {
16830
      // Otherwise if part's type is "segment-wildcard" and custom name is
16831
      // false: Append "(" to the end of result.
16832
0
      result.append("(");
16833
      // Append the result of running generate a segment wildcard regexp given
16834
      // options to the end of result.
16835
0
      result.append(generate_segment_wildcard_regexp(options));
16836
      // Append ")" to the end of result.
16837
0
      result.append(")");
16838
0
    } else if (part.type == url_pattern_part_type::FULL_WILDCARD) {
16839
      // Otherwise if part's type is "full-wildcard":
16840
      // If custom name is false and one of the following is true:
16841
      // - previous part is null; or
16842
      // - previous part's type is "fixed-text"; or
16843
      // - previous part's modifier is not "none"; or
16844
      // - needs grouping is true; or
16845
      // - part's prefix is not the empty string
16846
      // - then append "*" to the end of result.
16847
0
      if (!custom_name &&
16848
0
          (!previous_part ||
16849
0
           previous_part->type == url_pattern_part_type::FIXED_TEXT ||
16850
0
           previous_part->modifier != url_pattern_part_modifier::none ||
16851
0
           needs_grouping || !part.prefix.empty())) {
16852
0
        result.append("*");
16853
0
      } else {
16854
        // Append "(" to the end of result.
16855
        // Append full wildcard regexp value to the end of result.
16856
        // Append ")" to the end of result.
16857
0
        result.append("(.*)");
16858
0
      }
16859
0
    }
16860
16861
    // If all of the following are true:
16862
    // - part's type is "segment-wildcard"; and
16863
    // - custom name is true; and
16864
    // - part's suffix is not the empty string; and
16865
    // - The result of running is a valid name code point given part's suffix's
16866
    // first code point and the boolean false is true then append U+005C (\) to
16867
    // the end of result.
16868
0
    if (part.type == url_pattern_part_type::SEGMENT_WILDCARD && custom_name &&
16869
0
        !part.suffix.empty() &&
16870
0
        idna::valid_name_code_point(part.suffix[0], false)) {
16871
0
      result.append("\\");
16872
0
    }
16873
16874
    // Append the result of running escape a pattern string given part's suffix
16875
    // to the end of result.
16876
0
    result.append(escape_pattern_string(part.suffix));
16877
    // If needs grouping is true, then append "}" to the end of result.
16878
0
    if (needs_grouping) result.append("}");
16879
    // Append the result of running convert a modifier to a string given part's
16880
    // modifier to the end of result.
16881
0
    result.append(convert_modifier_to_string(part.modifier));
16882
0
  }
16883
  // Return result.
16884
0
  return result;
16885
0
}
16886
}  // namespace ada::url_pattern_helpers
16887
16888
#endif  // ADA_INCLUDE_URL_PATTERN
16889
/* end file src/url_pattern_helpers.cpp */
16890
/* begin file src/url_pattern_regex.cpp */
16891
#if ADA_INCLUDE_URL_PATTERN
16892
16893
16894
namespace ada::url_pattern_regex {
16895
16896
#ifdef ADA_USE_UNSAFE_STD_REGEX_PROVIDER
16897
std::optional<std::regex> std_regex_provider::create_instance(
16898
    std::string_view pattern, bool ignore_case) {
16899
  // Let flags be an empty string.
16900
  // If options's ignore case is true then set flags to "vi".
16901
  // Otherwise set flags to "v"
16902
  auto flags = ignore_case
16903
                   ? std::regex::icase | std::regex_constants::ECMAScript
16904
                   : std::regex_constants::ECMAScript;
16905
  try {
16906
    return std::regex(pattern.data(), pattern.size(), flags);
16907
  } catch (const std::regex_error& e) {
16908
    (void)e;
16909
    ada_log("std_regex_provider::create_instance failed:", e.what());
16910
    return std::nullopt;
16911
  }
16912
}
16913
16914
std::optional<std::vector<std::optional<std::string>>>
16915
std_regex_provider::regex_search(std::string_view input,
16916
                                 const std::regex& pattern) {
16917
  // Use iterator-based regex_search to avoid string allocation
16918
  std::match_results<std::string_view::const_iterator> match_result;
16919
  try {
16920
    if (!std::regex_search(input.begin(), input.end(), match_result, pattern,
16921
                           std::regex_constants::match_any)) {
16922
      return std::nullopt;
16923
    }
16924
  } catch (const std::regex_error& e) {
16925
    (void)e;
16926
    ada_log("std_regex_provider::regex_search failed:", e.what());
16927
    return std::nullopt;
16928
  }
16929
  std::vector<std::optional<std::string>> matches;
16930
  // An empty input can still match with capture groups (e.g. "(x*)" or an
16931
  // optional ":a?" against ""), so the group values must be extracted here
16932
  // just like for a non-empty input. A successful regex_search always leaves
16933
  // the full match at index 0, so match_result is never empty at this point.
16934
  if (match_result.empty()) {
16935
    return matches;
16936
  }
16937
  matches.reserve(match_result.size());
16938
  for (size_t i = 1; i < match_result.size(); ++i) {
16939
    if (auto entry = match_result[i]; entry.matched) {
16940
      matches.emplace_back(entry.str());
16941
    } else {
16942
      // A capture group that did not participate in the match is undefined,
16943
      // not absent. Emitting nullopt keeps the result aligned by position with
16944
      // the component's group name list; dropping it shifts every later group
16945
      // onto the wrong name.
16946
      matches.emplace_back(std::nullopt);
16947
    }
16948
  }
16949
  return matches;
16950
}
16951
16952
bool std_regex_provider::regex_match(std::string_view input,
16953
                                     const std::regex& pattern) {
16954
  try {
16955
    return std::regex_match(input.begin(), input.end(), pattern);
16956
  } catch (const std::regex_error& e) {
16957
    (void)e;
16958
    ada_log("std_regex_provider::regex_match failed:", e.what());
16959
    return false;
16960
  }
16961
}
16962
16963
#endif  // ADA_USE_UNSAFE_STD_REGEX_PROVIDER
16964
16965
}  // namespace ada::url_pattern_regex
16966
16967
#endif  // ADA_INCLUDE_URL_PATTERN
16968
/* end file src/url_pattern_regex.cpp */
16969
#endif  // ADA_INCLUDE_URL_PATTERN
16970
16971
/* begin file src/ada_c.cpp */
16972
// NOLINTBEGIN(bugprone-exception-escape,
16973
// bugprone-suspicious-stringview-data-usage)
16974
16975
0
ada::result<ada::url_aggregator>& get_instance(void* result) noexcept {
16976
0
  return *(ada::result<ada::url_aggregator>*)result;
16977
0
}
16978
16979
extern "C" {
16980
typedef void* ada_url;
16981
typedef void* ada_url_search_params;
16982
typedef void* ada_strings;
16983
typedef void* ada_url_search_params_keys_iter;
16984
typedef void* ada_url_search_params_values_iter;
16985
typedef void* ada_url_search_params_entries_iter;
16986
16987
struct ada_string {
16988
  const char* data;
16989
  size_t length;
16990
};
16991
16992
struct ada_owned_string {
16993
  const char* data;
16994
  size_t length;
16995
};
16996
16997
struct ada_string_pair {
16998
  ada_string key;
16999
  ada_string value;
17000
};
17001
17002
0
ada_string ada_string_create(const char* data, size_t length) {
17003
0
  ada_string out{};
17004
0
  out.data = data;
17005
0
  out.length = length;
17006
0
  return out;
17007
0
}
17008
17009
struct ada_url_components {
17010
  /*
17011
   * By using 32-bit integers, we implicitly assume that the URL string
17012
   * cannot exceed 4 GB.
17013
   *
17014
   * https://user:pass@example.com:1234/foo/bar?baz#quux
17015
   *       |     |    |          | ^^^^|       |   |
17016
   *       |     |    |          | |   |       |   `----- hash_start
17017
   *       |     |    |          | |   |       `--------- search_start
17018
   *       |     |    |          | |   `----------------- pathname_start
17019
   *       |     |    |          | `--------------------- port
17020
   *       |     |    |          `----------------------- host_end
17021
   *       |     |    `---------------------------------- host_start
17022
   *       |     `--------------------------------------- username_end
17023
   *       `--------------------------------------------- protocol_end
17024
   */
17025
  uint32_t protocol_end;
17026
  /**
17027
   * Username end is not `omitted` by default (-1) to make username and password
17028
   * getters less costly to implement.
17029
   */
17030
  uint32_t username_end;
17031
  uint32_t host_start;
17032
  uint32_t host_end;
17033
  uint32_t port;
17034
  uint32_t pathname_start;
17035
  uint32_t search_start;
17036
  uint32_t hash_start;
17037
};
17038
17039
0
ada_url ada_parse(const char* input, size_t length) noexcept {
17040
0
  return new ada::result<ada::url_aggregator>(
17041
0
      ada::parse<ada::url_aggregator>(std::string_view(input, length)));
17042
0
}
17043
17044
ada_url ada_parse_with_base(const char* input, size_t input_length,
17045
0
                            const char* base, size_t base_length) noexcept {
17046
0
  auto base_out =
17047
0
      ada::parse<ada::url_aggregator>(std::string_view(base, base_length));
17048
17049
0
  if (!base_out) {
17050
0
    return new ada::result<ada::url_aggregator>(base_out);
17051
0
  }
17052
17053
0
  return new ada::result<ada::url_aggregator>(ada::parse<ada::url_aggregator>(
17054
0
      std::string_view(input, input_length), &base_out.value()));
17055
0
}
17056
17057
0
bool ada_can_parse(const char* input, size_t length) noexcept {
17058
0
  return ada::can_parse(std::string_view(input, length));
17059
0
}
17060
17061
bool ada_can_parse_with_base(const char* input, size_t input_length,
17062
0
                             const char* base, size_t base_length) noexcept {
17063
0
  std::string_view base_view(base, base_length);
17064
0
  return ada::can_parse(std::string_view(input, input_length), &base_view);
17065
0
}
17066
17067
0
void ada_free(ada_url result) noexcept {
17068
0
  auto* r = (ada::result<ada::url_aggregator>*)result;
17069
0
  delete r;
17070
0
}
17071
17072
0
ada_url ada_copy(ada_url input) noexcept {
17073
0
  ada::result<ada::url_aggregator>& r = get_instance(input);
17074
0
  return new ada::result<ada::url_aggregator>(r);
17075
0
}
17076
17077
0
bool ada_is_valid(ada_url result) noexcept {
17078
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
17079
0
  return r.has_value();
17080
0
}
17081
17082
// caller must free the result with ada_free_owned_string
17083
0
ada_owned_string ada_get_origin(ada_url result) noexcept {
17084
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
17085
0
  ada_owned_string owned{};
17086
0
  if (!r) {
17087
0
    owned.data = nullptr;
17088
0
    owned.length = 0;
17089
0
    return owned;
17090
0
  }
17091
0
  std::string out = r->get_origin();
17092
0
  owned.length = out.size();
17093
0
  owned.data = new char[owned.length];
17094
0
  memcpy((void*)owned.data, out.data(), owned.length);
17095
0
  return owned;
17096
0
}
17097
17098
0
void ada_free_owned_string(ada_owned_string owned) noexcept {
17099
0
  delete[] owned.data;
17100
0
}
17101
17102
0
ada_string ada_get_href(ada_url result) noexcept {
17103
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
17104
0
  if (!r) {
17105
0
    return ada_string_create(nullptr, 0);
17106
0
  }
17107
0
  std::string_view out = r->get_href();
17108
0
  return ada_string_create(out.data(), out.length());
17109
0
}
17110
17111
0
ada_string ada_get_username(ada_url result) noexcept {
17112
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
17113
0
  if (!r) {
17114
0
    return ada_string_create(nullptr, 0);
17115
0
  }
17116
0
  std::string_view out = r->get_username();
17117
0
  return ada_string_create(out.data(), out.length());
17118
0
}
17119
17120
0
ada_string ada_get_password(ada_url result) noexcept {
17121
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
17122
0
  if (!r) {
17123
0
    return ada_string_create(nullptr, 0);
17124
0
  }
17125
0
  std::string_view out = r->get_password();
17126
0
  return ada_string_create(out.data(), out.length());
17127
0
}
17128
17129
0
ada_string ada_get_port(ada_url result) noexcept {
17130
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
17131
0
  if (!r) {
17132
0
    return ada_string_create(nullptr, 0);
17133
0
  }
17134
0
  std::string_view out = r->get_port();
17135
0
  return ada_string_create(out.data(), out.length());
17136
0
}
17137
17138
0
ada_string ada_get_hash(ada_url result) noexcept {
17139
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
17140
0
  if (!r) {
17141
0
    return ada_string_create(nullptr, 0);
17142
0
  }
17143
0
  std::string_view out = r->get_hash();
17144
0
  return ada_string_create(out.data(), out.length());
17145
0
}
17146
17147
0
ada_string ada_get_host(ada_url result) noexcept {
17148
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
17149
0
  if (!r) {
17150
0
    return ada_string_create(nullptr, 0);
17151
0
  }
17152
0
  std::string_view out = r->get_host();
17153
0
  return ada_string_create(out.data(), out.length());
17154
0
}
17155
17156
0
ada_string ada_get_hostname(ada_url result) noexcept {
17157
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
17158
0
  if (!r) {
17159
0
    return ada_string_create(nullptr, 0);
17160
0
  }
17161
0
  std::string_view out = r->get_hostname();
17162
0
  return ada_string_create(out.data(), out.length());
17163
0
}
17164
17165
0
ada_string ada_get_pathname(ada_url result) noexcept {
17166
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
17167
0
  if (!r) {
17168
0
    return ada_string_create(nullptr, 0);
17169
0
  }
17170
0
  std::string_view out = r->get_pathname();
17171
0
  return ada_string_create(out.data(), out.length());
17172
0
}
17173
17174
0
ada_string ada_get_search(ada_url result) noexcept {
17175
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
17176
0
  if (!r) {
17177
0
    return ada_string_create(nullptr, 0);
17178
0
  }
17179
0
  std::string_view out = r->get_search();
17180
0
  return ada_string_create(out.data(), out.length());
17181
0
}
17182
17183
0
ada_string ada_get_protocol(ada_url result) noexcept {
17184
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
17185
0
  if (!r) {
17186
0
    return ada_string_create(nullptr, 0);
17187
0
  }
17188
0
  std::string_view out = r->get_protocol();
17189
0
  return ada_string_create(out.data(), out.length());
17190
0
}
17191
17192
0
uint8_t ada_get_host_type(ada_url result) noexcept {
17193
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
17194
0
  if (!r) {
17195
0
    return 0;
17196
0
  }
17197
0
  return r->host_type;
17198
0
}
17199
17200
0
uint8_t ada_get_scheme_type(ada_url result) noexcept {
17201
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
17202
0
  if (!r) {
17203
0
    return 0;
17204
0
  }
17205
0
  return r->type;
17206
0
}
17207
17208
0
bool ada_set_href(ada_url result, const char* input, size_t length) noexcept {
17209
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
17210
0
  if (!r) {
17211
0
    return false;
17212
0
  }
17213
0
  return r->set_href(std::string_view(input, length));
17214
0
}
17215
17216
0
bool ada_set_host(ada_url result, const char* input, size_t length) noexcept {
17217
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
17218
0
  if (!r) {
17219
0
    return false;
17220
0
  }
17221
0
  return r->set_host(std::string_view(input, length));
17222
0
}
17223
17224
bool ada_set_hostname(ada_url result, const char* input,
17225
0
                      size_t length) noexcept {
17226
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
17227
0
  if (!r) {
17228
0
    return false;
17229
0
  }
17230
0
  return r->set_hostname(std::string_view(input, length));
17231
0
}
17232
17233
bool ada_set_protocol(ada_url result, const char* input,
17234
0
                      size_t length) noexcept {
17235
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
17236
0
  if (!r) {
17237
0
    return false;
17238
0
  }
17239
0
  return r->set_protocol(std::string_view(input, length));
17240
0
}
17241
17242
bool ada_set_username(ada_url result, const char* input,
17243
0
                      size_t length) noexcept {
17244
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
17245
0
  if (!r) {
17246
0
    return false;
17247
0
  }
17248
0
  return r->set_username(std::string_view(input, length));
17249
0
}
17250
17251
bool ada_set_password(ada_url result, const char* input,
17252
0
                      size_t length) noexcept {
17253
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
17254
0
  if (!r) {
17255
0
    return false;
17256
0
  }
17257
0
  return r->set_password(std::string_view(input, length));
17258
0
}
17259
17260
0
bool ada_set_port(ada_url result, const char* input, size_t length) noexcept {
17261
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
17262
0
  if (!r) {
17263
0
    return false;
17264
0
  }
17265
0
  return r->set_port(std::string_view(input, length));
17266
0
}
17267
17268
bool ada_set_pathname(ada_url result, const char* input,
17269
0
                      size_t length) noexcept {
17270
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
17271
0
  if (!r) {
17272
0
    return false;
17273
0
  }
17274
0
  return r->set_pathname(std::string_view(input, length));
17275
0
}
17276
17277
/**
17278
 * Update the search/query of the URL.
17279
 *
17280
 * If a URL has `?` as the search value, passing empty string to this function
17281
 * does not remove the attribute. If you need to remove it, please use
17282
 * `ada_clear_search` method.
17283
 */
17284
0
void ada_set_search(ada_url result, const char* input, size_t length) noexcept {
17285
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
17286
0
  if (r) {
17287
0
    r->set_search(std::string_view(input, length));
17288
0
  }
17289
0
}
17290
17291
/**
17292
 * Update the hash/fragment of the URL.
17293
 *
17294
 * If a URL has `#` as the hash value, passing empty string to this function
17295
 * does not remove the attribute. If you need to remove it, please use
17296
 * `ada_clear_hash` method.
17297
 */
17298
0
void ada_set_hash(ada_url result, const char* input, size_t length) noexcept {
17299
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
17300
0
  if (r) {
17301
0
    r->set_hash(std::string_view(input, length));
17302
0
  }
17303
0
}
17304
17305
0
void ada_clear_port(ada_url result) noexcept {
17306
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
17307
0
  if (r) {
17308
0
    r->clear_port();
17309
0
  }
17310
0
}
17311
17312
/**
17313
 * Removes the hash of the URL.
17314
 *
17315
 * Despite `ada_set_hash` method, this function allows the complete
17316
 * removal of the hash attribute, even if it has a value of `#`.
17317
 */
17318
0
void ada_clear_hash(ada_url result) noexcept {
17319
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
17320
0
  if (r) {
17321
0
    r->clear_hash();
17322
0
  }
17323
0
}
17324
17325
/**
17326
 * Removes the search of the URL.
17327
 *
17328
 * Despite `ada_set_search` method, this function allows the complete
17329
 * removal of the search attribute, even if it has a value of `?`.
17330
 */
17331
0
void ada_clear_search(ada_url result) noexcept {
17332
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
17333
0
  if (r) {
17334
0
    r->clear_search();
17335
0
  }
17336
0
}
17337
17338
0
bool ada_has_credentials(ada_url result) noexcept {
17339
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
17340
0
  if (!r) {
17341
0
    return false;
17342
0
  }
17343
0
  return r->has_credentials();
17344
0
}
17345
17346
0
bool ada_has_empty_hostname(ada_url result) noexcept {
17347
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
17348
0
  if (!r) {
17349
0
    return false;
17350
0
  }
17351
0
  return r->has_empty_hostname();
17352
0
}
17353
17354
0
bool ada_has_hostname(ada_url result) noexcept {
17355
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
17356
0
  if (!r) {
17357
0
    return false;
17358
0
  }
17359
0
  return r->has_hostname();
17360
0
}
17361
17362
0
bool ada_has_non_empty_username(ada_url result) noexcept {
17363
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
17364
0
  if (!r) {
17365
0
    return false;
17366
0
  }
17367
0
  return r->has_non_empty_username();
17368
0
}
17369
17370
0
bool ada_has_non_empty_password(ada_url result) noexcept {
17371
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
17372
0
  if (!r) {
17373
0
    return false;
17374
0
  }
17375
0
  return r->has_non_empty_password();
17376
0
}
17377
17378
0
bool ada_has_port(ada_url result) noexcept {
17379
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
17380
0
  if (!r) {
17381
0
    return false;
17382
0
  }
17383
0
  return r->has_port();
17384
0
}
17385
17386
0
bool ada_has_password(ada_url result) noexcept {
17387
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
17388
0
  if (!r) {
17389
0
    return false;
17390
0
  }
17391
0
  return r->has_password();
17392
0
}
17393
17394
0
bool ada_has_hash(ada_url result) noexcept {
17395
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
17396
0
  if (!r) {
17397
0
    return false;
17398
0
  }
17399
0
  return r->has_hash();
17400
0
}
17401
17402
0
bool ada_has_search(ada_url result) noexcept {
17403
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
17404
0
  if (!r) {
17405
0
    return false;
17406
0
  }
17407
0
  return r->has_search();
17408
0
}
17409
17410
// returns a pointer to the internal url_aggregator::url_components
17411
0
const ada_url_components* ada_get_components(ada_url result) noexcept {
17412
0
  static_assert(sizeof(ada_url_components) == sizeof(ada::url_components));
17413
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
17414
0
  if (!r) {
17415
0
    return nullptr;
17416
0
  }
17417
0
  return reinterpret_cast<const ada_url_components*>(&r->get_components());
17418
0
}
17419
17420
0
ada_owned_string ada_idna_to_unicode(const char* input, size_t length) {
17421
0
  std::string out = ada::idna::to_unicode(std::string_view(input, length));
17422
0
  ada_owned_string owned{};
17423
0
  owned.length = out.length();
17424
0
  owned.data = new char[owned.length];
17425
0
  memcpy((void*)owned.data, out.data(), owned.length);
17426
0
  return owned;
17427
0
}
17428
17429
0
ada_owned_string ada_idna_to_ascii(const char* input, size_t length) {
17430
0
  std::string out = ada::idna::to_ascii(std::string_view(input, length));
17431
0
  ada_owned_string owned{};
17432
0
  owned.length = out.size();
17433
0
  owned.data = new char[owned.length];
17434
0
  memcpy((void*)owned.data, out.data(), owned.length);
17435
0
  return owned;
17436
0
}
17437
17438
ada_url_search_params ada_parse_search_params(const char* input,
17439
0
                                              size_t length) {
17440
0
  return new ada::result<ada::url_search_params>(
17441
0
      ada::url_search_params(std::string_view(input, length)));
17442
0
}
17443
17444
0
void ada_free_search_params(ada_url_search_params result) {
17445
0
  auto* r = (ada::result<ada::url_search_params>*)result;
17446
0
  delete r;
17447
0
}
17448
17449
0
ada_owned_string ada_search_params_to_string(ada_url_search_params result) {
17450
0
  ada::result<ada::url_search_params>& r =
17451
0
      *(ada::result<ada::url_search_params>*)result;
17452
0
  if (!r) return ada_owned_string{nullptr, 0};
17453
0
  std::string out = r->to_string();
17454
0
  ada_owned_string owned{};
17455
0
  owned.length = out.size();
17456
0
  owned.data = new char[owned.length];
17457
0
  memcpy((void*)owned.data, out.data(), owned.length);
17458
0
  return owned;
17459
0
}
17460
17461
0
size_t ada_search_params_size(ada_url_search_params result) {
17462
0
  ada::result<ada::url_search_params>& r =
17463
0
      *(ada::result<ada::url_search_params>*)result;
17464
0
  if (!r) {
17465
0
    return 0;
17466
0
  }
17467
0
  return r->size();
17468
0
}
17469
17470
0
void ada_search_params_sort(ada_url_search_params result) {
17471
0
  ada::result<ada::url_search_params>& r =
17472
0
      *(ada::result<ada::url_search_params>*)result;
17473
0
  if (r) {
17474
0
    r->sort();
17475
0
  }
17476
0
}
17477
17478
void ada_search_params_reset(ada_url_search_params result, const char* input,
17479
0
                             size_t length) {
17480
0
  ada::result<ada::url_search_params>& r =
17481
0
      *(ada::result<ada::url_search_params>*)result;
17482
0
  if (r) {
17483
0
    r->reset(std::string_view(input, length));
17484
0
  }
17485
0
}
17486
17487
void ada_search_params_append(ada_url_search_params result, const char* key,
17488
                              size_t key_length, const char* value,
17489
0
                              size_t value_length) {
17490
0
  ada::result<ada::url_search_params>& r =
17491
0
      *(ada::result<ada::url_search_params>*)result;
17492
0
  if (r) {
17493
0
    r->append(std::string_view(key, key_length),
17494
0
              std::string_view(value, value_length));
17495
0
  }
17496
0
}
17497
17498
void ada_search_params_set(ada_url_search_params result, const char* key,
17499
                           size_t key_length, const char* value,
17500
0
                           size_t value_length) {
17501
0
  ada::result<ada::url_search_params>& r =
17502
0
      *(ada::result<ada::url_search_params>*)result;
17503
0
  if (r) {
17504
0
    r->set(std::string_view(key, key_length),
17505
0
           std::string_view(value, value_length));
17506
0
  }
17507
0
}
17508
17509
void ada_search_params_remove(ada_url_search_params result, const char* key,
17510
0
                              size_t key_length) {
17511
0
  ada::result<ada::url_search_params>& r =
17512
0
      *(ada::result<ada::url_search_params>*)result;
17513
0
  if (r) {
17514
0
    r->remove(std::string_view(key, key_length));
17515
0
  }
17516
0
}
17517
17518
void ada_search_params_remove_value(ada_url_search_params result,
17519
                                    const char* key, size_t key_length,
17520
0
                                    const char* value, size_t value_length) {
17521
0
  ada::result<ada::url_search_params>& r =
17522
0
      *(ada::result<ada::url_search_params>*)result;
17523
0
  if (r) {
17524
0
    r->remove(std::string_view(key, key_length),
17525
0
              std::string_view(value, value_length));
17526
0
  }
17527
0
}
17528
17529
bool ada_search_params_has(ada_url_search_params result, const char* key,
17530
0
                           size_t key_length) {
17531
0
  ada::result<ada::url_search_params>& r =
17532
0
      *(ada::result<ada::url_search_params>*)result;
17533
0
  if (!r) {
17534
0
    return false;
17535
0
  }
17536
0
  return r->has(std::string_view(key, key_length));
17537
0
}
17538
17539
bool ada_search_params_has_value(ada_url_search_params result, const char* key,
17540
                                 size_t key_length, const char* value,
17541
0
                                 size_t value_length) {
17542
0
  ada::result<ada::url_search_params>& r =
17543
0
      *(ada::result<ada::url_search_params>*)result;
17544
0
  if (!r) {
17545
0
    return false;
17546
0
  }
17547
0
  return r->has(std::string_view(key, key_length),
17548
0
                std::string_view(value, value_length));
17549
0
}
17550
17551
ada_string ada_search_params_get(ada_url_search_params result, const char* key,
17552
0
                                 size_t key_length) {
17553
0
  ada::result<ada::url_search_params>& r =
17554
0
      *(ada::result<ada::url_search_params>*)result;
17555
0
  if (!r) {
17556
0
    return ada_string_create(nullptr, 0);
17557
0
  }
17558
0
  auto found = r->get(std::string_view(key, key_length));
17559
0
  if (!found.has_value()) {
17560
0
    return ada_string_create(nullptr, 0);
17561
0
  }
17562
0
  return ada_string_create(found->data(), found->length());
17563
0
}
17564
17565
ada_strings ada_search_params_get_all(ada_url_search_params result,
17566
0
                                      const char* key, size_t key_length) {
17567
0
  ada::result<ada::url_search_params>& r =
17568
0
      *(ada::result<ada::url_search_params>*)result;
17569
0
  if (!r) {
17570
0
    return new ada::result<std::vector<std::string>>(
17571
0
        std::vector<std::string>());
17572
0
  }
17573
0
  return new ada::result<std::vector<std::string>>(
17574
0
      r->get_all(std::string_view(key, key_length)));
17575
0
}
17576
17577
ada_url_search_params_keys_iter ada_search_params_get_keys(
17578
0
    ada_url_search_params result) {
17579
0
  ada::result<ada::url_search_params>& r =
17580
0
      *(ada::result<ada::url_search_params>*)result;
17581
0
  if (!r) {
17582
0
    return new ada::result<ada::url_search_params_keys_iter>(
17583
0
        ada::url_search_params_keys_iter());
17584
0
  }
17585
0
  return new ada::result<ada::url_search_params_keys_iter>(r->get_keys());
17586
0
}
17587
17588
ada_url_search_params_values_iter ada_search_params_get_values(
17589
0
    ada_url_search_params result) {
17590
0
  ada::result<ada::url_search_params>& r =
17591
0
      *(ada::result<ada::url_search_params>*)result;
17592
0
  if (!r) {
17593
0
    return new ada::result<ada::url_search_params_values_iter>(
17594
0
        ada::url_search_params_values_iter());
17595
0
  }
17596
0
  return new ada::result<ada::url_search_params_values_iter>(r->get_values());
17597
0
}
17598
17599
ada_url_search_params_entries_iter ada_search_params_get_entries(
17600
0
    ada_url_search_params result) {
17601
0
  ada::result<ada::url_search_params>& r =
17602
0
      *(ada::result<ada::url_search_params>*)result;
17603
0
  if (!r) {
17604
0
    return new ada::result<ada::url_search_params_entries_iter>(
17605
0
        ada::url_search_params_entries_iter());
17606
0
  }
17607
0
  return new ada::result<ada::url_search_params_entries_iter>(r->get_entries());
17608
0
}
17609
17610
0
void ada_free_strings(ada_strings result) {
17611
0
  auto* r = (ada::result<std::vector<std::string>>*)result;
17612
0
  delete r;
17613
0
}
17614
17615
0
size_t ada_strings_size(ada_strings result) {
17616
0
  auto* r = (ada::result<std::vector<std::string>>*)result;
17617
0
  if (!r) {
17618
0
    return 0;
17619
0
  }
17620
0
  return (*r)->size();
17621
0
}
17622
17623
0
ada_string ada_strings_get(ada_strings result, size_t index) {
17624
0
  auto* r = (ada::result<std::vector<std::string>>*)result;
17625
0
  if (!r) {
17626
0
    return ada_string_create(nullptr, 0);
17627
0
  }
17628
0
  std::string_view view = (*r)->at(index);
17629
0
  return ada_string_create(view.data(), view.length());
17630
0
}
17631
17632
0
void ada_free_search_params_keys_iter(ada_url_search_params_keys_iter result) {
17633
0
  auto* r = (ada::result<ada::url_search_params_keys_iter>*)result;
17634
0
  delete r;
17635
0
}
17636
17637
ada_string ada_search_params_keys_iter_next(
17638
0
    ada_url_search_params_keys_iter result) {
17639
0
  auto* r = (ada::result<ada::url_search_params_keys_iter>*)result;
17640
0
  if (!r) {
17641
0
    return ada_string_create(nullptr, 0);
17642
0
  }
17643
0
  auto next = (*r)->next();
17644
0
  if (!next.has_value()) {
17645
0
    return ada_string_create(nullptr, 0);
17646
0
  }
17647
0
  return ada_string_create(next->data(), next->length());
17648
0
}
17649
17650
bool ada_search_params_keys_iter_has_next(
17651
0
    ada_url_search_params_keys_iter result) {
17652
0
  auto* r = (ada::result<ada::url_search_params_keys_iter>*)result;
17653
0
  if (!r) {
17654
0
    return false;
17655
0
  }
17656
0
  return (*r)->has_next();
17657
0
}
17658
17659
void ada_free_search_params_values_iter(
17660
0
    ada_url_search_params_values_iter result) {
17661
0
  auto* r = (ada::result<ada::url_search_params_values_iter>*)result;
17662
0
  delete r;
17663
0
}
17664
17665
ada_string ada_search_params_values_iter_next(
17666
0
    ada_url_search_params_values_iter result) {
17667
0
  auto* r = (ada::result<ada::url_search_params_values_iter>*)result;
17668
0
  if (!r) {
17669
0
    return ada_string_create(nullptr, 0);
17670
0
  }
17671
0
  auto next = (*r)->next();
17672
0
  if (!next.has_value()) {
17673
0
    return ada_string_create(nullptr, 0);
17674
0
  }
17675
0
  return ada_string_create(next->data(), next->length());
17676
0
}
17677
17678
bool ada_search_params_values_iter_has_next(
17679
0
    ada_url_search_params_values_iter result) {
17680
0
  auto* r = (ada::result<ada::url_search_params_values_iter>*)result;
17681
0
  if (!r) {
17682
0
    return false;
17683
0
  }
17684
0
  return (*r)->has_next();
17685
0
}
17686
17687
void ada_free_search_params_entries_iter(
17688
0
    ada_url_search_params_entries_iter result) {
17689
0
  auto* r = (ada::result<ada::url_search_params_entries_iter>*)result;
17690
0
  delete r;
17691
0
}
17692
17693
ada_string_pair ada_search_params_entries_iter_next(
17694
0
    ada_url_search_params_entries_iter result) {
17695
0
  auto* r = (ada::result<ada::url_search_params_entries_iter>*)result;
17696
0
  if (!r) return {ada_string_create(nullptr, 0), ada_string_create(nullptr, 0)};
17697
0
  auto next = (*r)->next();
17698
0
  if (!next.has_value()) {
17699
0
    return {ada_string_create(nullptr, 0), ada_string_create(nullptr, 0)};
17700
0
  }
17701
0
  return ada_string_pair{
17702
0
      ada_string_create(next->first.data(), next->first.length()),
17703
0
      ada_string_create(next->second.data(), next->second.length())};
17704
0
}
17705
17706
bool ada_search_params_entries_iter_has_next(
17707
0
    ada_url_search_params_entries_iter result) {
17708
0
  auto* r = (ada::result<ada::url_search_params_entries_iter>*)result;
17709
0
  if (!r) {
17710
0
    return false;
17711
0
  }
17712
0
  return (*r)->has_next();
17713
0
}
17714
17715
0
void ada_set_max_input_length(uint32_t length) noexcept {
17716
0
  ada::set_max_input_length(length);
17717
0
}
17718
17719
0
uint32_t ada_get_max_input_length() noexcept {
17720
0
  return ada::get_max_input_length();
17721
0
}
17722
17723
typedef struct {
17724
  int major;
17725
  int minor;
17726
  int revision;
17727
} ada_version_components;
17728
17729
0
const char* ada_get_version() { return ADA_VERSION; }
17730
17731
0
ada_version_components ada_get_version_components() {
17732
0
  return ada_version_components{
17733
0
      .major = ada::ADA_VERSION_MAJOR,
17734
0
      .minor = ada::ADA_VERSION_MINOR,
17735
0
      .revision = ada::ADA_VERSION_REVISION,
17736
0
  };
17737
0
}
17738
17739
}  // extern "C"
17740
// NOLINTEND(bugprone-exception-escape,
17741
// bugprone-suspicious-stringview-data-usage)
17742
/* end file src/ada_c.cpp */
17743
/* end file src/ada.cpp */