/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) constUnexecuted 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()() constUnexecuted 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()() constUnexecuted 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()() constUnexecuted 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()() constUnexecuted 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()() constUnexecuted 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()() constUnexecuted 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 */ |