/src/ada-url/build/singleheader/ada.cpp
Line  | Count  | Source (jump to first uncovered line)  | 
1  |  | /* auto-generated on 2023-06-04 13:08:26 -0400. Do not edit! */  | 
2  |  | /* begin file src/ada.cpp */  | 
3  |  | #include "ada.h"  | 
4  |  | /* begin file src/checkers.cpp */  | 
5  |  | #include <algorithm>  | 
6  |  |  | 
7  |  | namespace ada::checkers { | 
8  |  |  | 
9  | 20.2k  | ada_really_inline ada_constexpr bool is_ipv4(std::string_view view) noexcept { | 
10  | 20.2k  |   size_t last_dot = view.rfind('.'); | 
11  | 20.2k  |   if (last_dot == view.size() - 1) { | 
12  | 2.42k  |     view.remove_suffix(1);  | 
13  | 2.42k  |     last_dot = view.rfind('.'); | 
14  | 2.42k  |   }  | 
15  | 20.2k  |   std::string_view number =  | 
16  | 20.2k  |       (last_dot == std::string_view::npos) ? view : view.substr(last_dot + 1);  | 
17  | 20.2k  |   if (number.empty()) { | 
18  | 1.59k  |     return false;  | 
19  | 1.59k  |   }  | 
20  |  |   /** Optimization opportunity: we have basically identified the last number of  | 
21  |  |      the ipv4 if we return true here. We might as well parse it and have at  | 
22  |  |      least one number parsed when we get to parse_ipv4. */  | 
23  | 18.6k  |   if (std::all_of(number.begin(), number.end(), ada::checkers::is_digit)) { | 
24  | 4.77k  |     return true;  | 
25  | 4.77k  |   }  | 
26  | 13.8k  |   return (checkers::has_hex_prefix(number) &&  | 
27  | 13.8k  |           std::all_of(number.begin() + 2, number.end(),  | 
28  | 2.26k  |                       ada::unicode::is_lowercase_hex));  | 
29  | 18.6k  | }  | 
30  |  |  | 
31  |  | // for use with path_signature, we include all characters that need percent  | 
32  |  | // encoding.  | 
33  |  | static constexpr uint8_t path_signature_table[256] = { | 
34  |  |     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  | 
35  |  |     1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0,  | 
36  |  |     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,  | 
37  |  |     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0,  | 
38  |  |     1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
39  |  |     0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  | 
40  |  |     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  | 
41  |  |     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  | 
42  |  |     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  | 
43  |  |     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  | 
44  |  |     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};  | 
45  |  | static_assert(path_signature_table[uint8_t('?')] == 1); | 
46  |  | static_assert(path_signature_table[uint8_t('`')] == 1); | 
47  |  | static_assert(path_signature_table[uint8_t('{')] == 1); | 
48  |  | static_assert(path_signature_table[uint8_t('}')] == 1); | 
49  |  | //  | 
50  |  | static_assert(path_signature_table[uint8_t(' ')] == 1); | 
51  |  | static_assert(path_signature_table[uint8_t('?')] == 1); | 
52  |  | static_assert(path_signature_table[uint8_t('"')] == 1); | 
53  |  | static_assert(path_signature_table[uint8_t('#')] == 1); | 
54  |  | static_assert(path_signature_table[uint8_t('<')] == 1); | 
55  |  | static_assert(path_signature_table[uint8_t('>')] == 1); | 
56  |  | static_assert(path_signature_table[uint8_t('\\')] == 2); | 
57  |  | static_assert(path_signature_table[uint8_t('.')] == 4); | 
58  |  | static_assert(path_signature_table[uint8_t('%')] == 8); | 
59  |  |  | 
60  |  | //  | 
61  |  | static_assert(path_signature_table[0] == 1);  | 
62  |  | static_assert(path_signature_table[31] == 1);  | 
63  |  | static_assert(path_signature_table[127] == 1);  | 
64  |  | static_assert(path_signature_table[128] == 1);  | 
65  |  | static_assert(path_signature_table[255] == 1);  | 
66  |  |  | 
67  |  | ada_really_inline constexpr uint8_t path_signature(  | 
68  | 27.6k  |     std::string_view input) noexcept { | 
69  |  |   // The path percent-encode set is the query percent-encode set and U+003F (?),  | 
70  |  |   // U+0060 (`), U+007B ({), and U+007D (}). The query percent-encode set is the | 
71  |  |   // C0 control percent-encode set and U+0020 SPACE, U+0022 ("), U+0023 (#), | 
72  |  |   // U+003C (<), and U+003E (>). The C0 control percent-encode set are the C0  | 
73  |  |   // controls and all code points greater than U+007E (~).  | 
74  | 27.6k  |   size_t i = 0;  | 
75  | 27.6k  |   uint8_t accumulator{}; | 
76  | 78.0k  |   for (; i + 7 < input.size(); i += 8) { | 
77  | 50.4k  |     accumulator |= uint8_t(path_signature_table[uint8_t(input[i])] |  | 
78  | 50.4k  |                            path_signature_table[uint8_t(input[i + 1])] |  | 
79  | 50.4k  |                            path_signature_table[uint8_t(input[i + 2])] |  | 
80  | 50.4k  |                            path_signature_table[uint8_t(input[i + 3])] |  | 
81  | 50.4k  |                            path_signature_table[uint8_t(input[i + 4])] |  | 
82  | 50.4k  |                            path_signature_table[uint8_t(input[i + 5])] |  | 
83  | 50.4k  |                            path_signature_table[uint8_t(input[i + 6])] |  | 
84  | 50.4k  |                            path_signature_table[uint8_t(input[i + 7])]);  | 
85  | 50.4k  |   }  | 
86  | 98.4k  |   for (; i < input.size(); i++) { | 
87  | 70.8k  |     accumulator |= uint8_t(path_signature_table[uint8_t(input[i])]);  | 
88  | 70.8k  |   }  | 
89  | 27.6k  |   return accumulator;  | 
90  | 27.6k  | }  | 
91  |  |  | 
92  |  | ada_really_inline constexpr bool verify_dns_length(  | 
93  | 0  |     std::string_view input) noexcept { | 
94  | 0  |   if (input.back() == '.') { | 
95  | 0  |     if (input.size() > 254) return false;  | 
96  | 0  |   } else if (input.size() > 253)  | 
97  | 0  |     return false;  | 
98  |  |  | 
99  | 0  |   size_t start = 0;  | 
100  | 0  |   while (start < input.size()) { | 
101  | 0  |     auto dot_location = input.find('.', start); | 
102  |  |     // If not found, it's likely the end of the domain  | 
103  | 0  |     if (dot_location == std::string_view::npos) dot_location = input.size();  | 
104  |  | 
  | 
105  | 0  |     auto label_size = dot_location - start;  | 
106  | 0  |     if (label_size > 63 || label_size == 0) return false;  | 
107  |  |  | 
108  | 0  |     start = dot_location + 1;  | 
109  | 0  |   }  | 
110  |  |  | 
111  | 0  |   return true;  | 
112  | 0  | }  | 
113  |  | }  // namespace ada::checkers  | 
114  |  | /* end file src/checkers.cpp */  | 
115  |  | /* begin file src/unicode.cpp */  | 
116  |  |  | 
117  |  | ADA_PUSH_DISABLE_ALL_WARNINGS  | 
118  |  | /* begin file src/ada_idna.cpp */  | 
119  |  | /* auto-generated on 2023-05-07 19:12:14 -0400. Do not edit! */  | 
120  |  | /* begin file src/idna.cpp */  | 
121  |  | /* begin file src/unicode_transcoding.cpp */  | 
122  |  |  | 
123  |  | #include <cstdint>  | 
124  |  | #include <cstring>  | 
125  |  |  | 
126  |  | namespace ada::idna { | 
127  |  |  | 
128  | 9.77k  | size_t utf8_to_utf32(const char* buf, size_t len, char32_t* utf32_output) { | 
129  | 9.77k  |   const uint8_t* data = reinterpret_cast<const uint8_t*>(buf);  | 
130  | 9.77k  |   size_t pos = 0;  | 
131  | 9.77k  |   char32_t* start{utf32_output}; | 
132  | 125k  |   while (pos < len) { | 
133  |  |     // try to convert the next block of 16 ASCII bytes  | 
134  | 118k  |     if (pos + 16 <= len) {  // if it is safe to read 16 more | 
135  |  |                             // bytes, check that they are ascii  | 
136  | 75.9k  |       uint64_t v1;  | 
137  | 75.9k  |       std::memcpy(&v1, data + pos, sizeof(uint64_t));  | 
138  | 75.9k  |       uint64_t v2;  | 
139  | 75.9k  |       std::memcpy(&v2, data + pos + sizeof(uint64_t), sizeof(uint64_t));  | 
140  | 75.9k  |       uint64_t v{v1 | v2}; | 
141  | 75.9k  |       if ((v & 0x8080808080808080) == 0) { | 
142  | 3.00k  |         size_t final_pos = pos + 16;  | 
143  | 51.0k  |         while (pos < final_pos) { | 
144  | 48.0k  |           *utf32_output++ = char32_t(buf[pos]);  | 
145  | 48.0k  |           pos++;  | 
146  | 48.0k  |         }  | 
147  | 3.00k  |         continue;  | 
148  | 3.00k  |       }  | 
149  | 75.9k  |     }  | 
150  | 115k  |     uint8_t leading_byte = data[pos];  // leading byte  | 
151  | 115k  |     if (leading_byte < 0b10000000) { | 
152  |  |       // converting one ASCII byte !!!  | 
153  | 70.5k  |       *utf32_output++ = char32_t(leading_byte);  | 
154  | 70.5k  |       pos++;  | 
155  | 70.5k  |     } else if ((leading_byte & 0b11100000) == 0b11000000) { | 
156  |  |       // We have a two-byte UTF-8  | 
157  | 11.6k  |       if (pos + 1 >= len) { | 
158  | 249  |         return 0;  | 
159  | 249  |       }  // minimal bound checking  | 
160  | 11.3k  |       if ((data[pos + 1] & 0b11000000) != 0b10000000) { | 
161  | 328  |         return 0;  | 
162  | 328  |       }  | 
163  |  |       // range check  | 
164  | 11.0k  |       uint32_t code_point =  | 
165  | 11.0k  |           (leading_byte & 0b00011111) << 6 | (data[pos + 1] & 0b00111111);  | 
166  | 11.0k  |       if (code_point < 0x80 || 0x7ff < code_point) { | 
167  | 27  |         return 0;  | 
168  | 27  |       }  | 
169  | 10.9k  |       *utf32_output++ = char32_t(code_point);  | 
170  | 10.9k  |       pos += 2;  | 
171  | 33.2k  |     } else if ((leading_byte & 0b11110000) == 0b11100000) { | 
172  |  |       // We have a three-byte UTF-8  | 
173  | 30.5k  |       if (pos + 2 >= len) { | 
174  | 111  |         return 0;  | 
175  | 111  |       }  // minimal bound checking  | 
176  |  |  | 
177  | 30.4k  |       if ((data[pos + 1] & 0b11000000) != 0b10000000) { | 
178  | 165  |         return 0;  | 
179  | 165  |       }  | 
180  | 30.3k  |       if ((data[pos + 2] & 0b11000000) != 0b10000000) { | 
181  | 32  |         return 0;  | 
182  | 32  |       }  | 
183  |  |       // range check  | 
184  | 30.2k  |       uint32_t code_point = (leading_byte & 0b00001111) << 12 |  | 
185  | 30.2k  |                             (data[pos + 1] & 0b00111111) << 6 |  | 
186  | 30.2k  |                             (data[pos + 2] & 0b00111111);  | 
187  | 30.2k  |       if (code_point < 0x800 || 0xffff < code_point ||  | 
188  | 30.2k  |           (0xd7ff < code_point && code_point < 0xe000)) { | 
189  | 43  |         return 0;  | 
190  | 43  |       }  | 
191  | 30.2k  |       *utf32_output++ = char32_t(code_point);  | 
192  | 30.2k  |       pos += 3;  | 
193  | 30.2k  |     } else if ((leading_byte & 0b11111000) == 0b11110000) {  // 0b11110000 | 
194  |  |       // we have a 4-byte UTF-8 word.  | 
195  | 871  |       if (pos + 3 >= len) { | 
196  | 84  |         return 0;  | 
197  | 84  |       }  // minimal bound checking  | 
198  | 787  |       if ((data[pos + 1] & 0b11000000) != 0b10000000) { | 
199  | 92  |         return 0;  | 
200  | 92  |       }  | 
201  | 695  |       if ((data[pos + 2] & 0b11000000) != 0b10000000) { | 
202  | 11  |         return 0;  | 
203  | 11  |       }  | 
204  | 684  |       if ((data[pos + 3] & 0b11000000) != 0b10000000) { | 
205  | 20  |         return 0;  | 
206  | 20  |       }  | 
207  |  |  | 
208  |  |       // range check  | 
209  | 664  |       uint32_t code_point = (leading_byte & 0b00000111) << 18 |  | 
210  | 664  |                             (data[pos + 1] & 0b00111111) << 12 |  | 
211  | 664  |                             (data[pos + 2] & 0b00111111) << 6 |  | 
212  | 664  |                             (data[pos + 3] & 0b00111111);  | 
213  | 664  |       if (code_point <= 0xffff || 0x10ffff < code_point) { | 
214  | 40  |         return 0;  | 
215  | 40  |       }  | 
216  | 624  |       *utf32_output++ = char32_t(code_point);  | 
217  | 624  |       pos += 4;  | 
218  | 1.81k  |     } else { | 
219  | 1.81k  |       return 0;  | 
220  | 1.81k  |     }  | 
221  | 115k  |   }  | 
222  | 6.75k  |   return utf32_output - start;  | 
223  | 9.77k  | }  | 
224  |  |  | 
225  | 1.43k  | size_t utf8_length_from_utf32(const char32_t* buf, size_t len) { | 
226  |  |   // We are not BOM aware.  | 
227  | 1.43k  |   const uint32_t* p = reinterpret_cast<const uint32_t*>(buf);  | 
228  | 1.43k  |   size_t counter{0}; | 
229  | 7.25k  |   for (size_t i = 0; i < len; i++) { | 
230  |  |     /** ASCII **/  | 
231  | 5.82k  |     if (p[i] <= 0x7F) { | 
232  | 1.97k  |       counter++;  | 
233  | 1.97k  |     }  | 
234  |  |     /** two-byte **/  | 
235  | 3.84k  |     else if (p[i] <= 0x7FF) { | 
236  | 804  |       counter += 2;  | 
237  | 804  |     }  | 
238  |  |     /** three-byte **/  | 
239  | 3.04k  |     else if (p[i] <= 0xFFFF) { | 
240  | 1.91k  |       counter += 3;  | 
241  | 1.91k  |     }  | 
242  |  |     /** four-bytes **/  | 
243  | 1.12k  |     else { | 
244  | 1.12k  |       counter += 4;  | 
245  | 1.12k  |     }  | 
246  | 5.82k  |   }  | 
247  | 1.43k  |   return counter;  | 
248  | 1.43k  | }  | 
249  |  |  | 
250  | 9.77k  | size_t utf32_length_from_utf8(const char* buf, size_t len) { | 
251  | 9.77k  |   const int8_t* p = reinterpret_cast<const int8_t*>(buf);  | 
252  | 9.77k  |   size_t counter{0}; | 
253  | 330k  |   for (size_t i = 0; i < len; i++) { | 
254  |  |     // -65 is 0b10111111, anything larger in two-complement's  | 
255  |  |     // should start a new code point.  | 
256  | 320k  |     if (p[i] > -65) { | 
257  | 233k  |       counter++;  | 
258  | 233k  |     }  | 
259  | 320k  |   }  | 
260  | 9.77k  |   return counter;  | 
261  | 9.77k  | }  | 
262  |  |  | 
263  | 1.43k  | size_t utf32_to_utf8(const char32_t* buf, size_t len, char* utf8_output) { | 
264  | 1.43k  |   const uint32_t* data = reinterpret_cast<const uint32_t*>(buf);  | 
265  | 1.43k  |   size_t pos = 0;  | 
266  | 1.43k  |   char* start{utf8_output}; | 
267  | 6.22k  |   while (pos < len) { | 
268  |  |     // try to convert the next block of 2 ASCII characters  | 
269  | 4.95k  |     if (pos + 2 <= len) {  // if it is safe to read 8 more | 
270  |  |                            // bytes, check that they are ascii  | 
271  | 3.85k  |       uint64_t v;  | 
272  | 3.85k  |       std::memcpy(&v, data + pos, sizeof(uint64_t));  | 
273  | 3.85k  |       if ((v & 0xFFFFFF80FFFFFF80) == 0) { | 
274  | 755  |         *utf8_output++ = char(buf[pos]);  | 
275  | 755  |         *utf8_output++ = char(buf[pos + 1]);  | 
276  | 755  |         pos += 2;  | 
277  | 755  |         continue;  | 
278  | 755  |       }  | 
279  | 3.85k  |     }  | 
280  | 4.20k  |     uint32_t word = data[pos];  | 
281  | 4.20k  |     if ((word & 0xFFFFFF80) == 0) { | 
282  |  |       // will generate one UTF-8 bytes  | 
283  | 467  |       *utf8_output++ = char(word);  | 
284  | 467  |       pos++;  | 
285  | 3.73k  |     } else if ((word & 0xFFFFF800) == 0) { | 
286  |  |       // will generate two UTF-8 bytes  | 
287  |  |       // we have 0b110XXXXX 0b10XXXXXX  | 
288  | 796  |       *utf8_output++ = char((word >> 6) | 0b11000000);  | 
289  | 796  |       *utf8_output++ = char((word & 0b111111) | 0b10000000);  | 
290  | 796  |       pos++;  | 
291  | 2.94k  |     } else if ((word & 0xFFFF0000) == 0) { | 
292  |  |       // will generate three UTF-8 bytes  | 
293  |  |       // we have 0b1110XXXX 0b10XXXXXX 0b10XXXXXX  | 
294  | 1.91k  |       if (word >= 0xD800 && word <= 0xDFFF) { | 
295  | 42  |         return 0;  | 
296  | 42  |       }  | 
297  | 1.86k  |       *utf8_output++ = char((word >> 12) | 0b11100000);  | 
298  | 1.86k  |       *utf8_output++ = char(((word >> 6) & 0b111111) | 0b10000000);  | 
299  | 1.86k  |       *utf8_output++ = char((word & 0b111111) | 0b10000000);  | 
300  | 1.86k  |       pos++;  | 
301  | 1.86k  |     } else { | 
302  |  |       // will generate four UTF-8 bytes  | 
303  |  |       // we have 0b11110XXX 0b10XXXXXX 0b10XXXXXX  | 
304  |  |       // 0b10XXXXXX  | 
305  | 1.02k  |       if (word > 0x10FFFF) { | 
306  | 129  |         return 0;  | 
307  | 129  |       }  | 
308  | 900  |       *utf8_output++ = char((word >> 18) | 0b11110000);  | 
309  | 900  |       *utf8_output++ = char(((word >> 12) & 0b111111) | 0b10000000);  | 
310  | 900  |       *utf8_output++ = char(((word >> 6) & 0b111111) | 0b10000000);  | 
311  | 900  |       *utf8_output++ = char((word & 0b111111) | 0b10000000);  | 
312  | 900  |       pos++;  | 
313  | 900  |     }  | 
314  | 4.20k  |   }  | 
315  | 1.26k  |   return utf8_output - start;  | 
316  | 1.43k  | }  | 
317  |  | }  // namespace ada::idna  | 
318  |  | /* end file src/unicode_transcoding.cpp */  | 
319  |  | /* begin file src/mapping.cpp */  | 
320  |  |  | 
321  |  | #include <algorithm>  | 
322  |  | #include <array>  | 
323  |  | #include <string>  | 
324  |  |  | 
325  |  | /* begin file src/mapping_tables.cpp */  | 
326  |  | // IDNA  15.0.0  | 
327  |  |  | 
328  |  | // clang-format off  | 
329  |  | #ifndef ADA_IDNA_TABLES_H  | 
330  |  | #define ADA_IDNA_TABLES_H  | 
331  |  | #include <cstdint>  | 
332  |  |  | 
333  |  | namespace ada::idna { | 
334  |  |  | 
335  |  | const uint32_t mappings[5164] =  | 
336  |  | { | 
337  |  |   97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113,  | 
338  |  |   114, 115, 116, 117, 118, 119, 120, 121, 122, 32, 32, 776, 32, 772, 50, 51, 32, 769,  | 
339  |  |   956, 32, 807, 49, 49, 8260, 52, 49, 8260, 50, 51, 8260, 52, 224, 225, 226, 227,  | 
340  |  |   228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243,  | 
341  |  |   244, 245, 246, 248, 249, 250, 251, 252, 253, 254, 257, 259, 261, 263, 265, 267,  | 
342  |  |   269, 271, 273, 275, 277, 279, 281, 283, 285, 287, 289, 291, 293, 295, 297, 299,  | 
343  |  |   301, 303, 105, 775, 309, 311, 314, 316, 318, 108, 183, 322, 324, 326, 328, 700,  | 
344  |  |   110, 331, 333, 335, 337, 339, 341, 343, 345, 347, 349, 351, 353, 355, 357, 359,  | 
345  |  |   361, 363, 365, 367, 369, 371, 373, 375, 255, 378, 380, 382, 595, 387, 389, 596,  | 
346  |  |   392, 598, 599, 396, 477, 601, 603, 402, 608, 611, 617, 616, 409, 623, 626, 629,  | 
347  |  |   417, 419, 421, 640, 424, 643, 429, 648, 432, 650, 651, 436, 438, 658, 441, 445,  | 
348  |  |   100, 382, 108, 106, 110, 106, 462, 464, 466, 468, 470, 472, 474, 476, 479, 481,  | 
349  |  |   483, 485, 487, 489, 491, 493, 495, 100, 122, 501, 405, 447, 505, 507, 509, 511,  | 
350  |  |   513, 515, 517, 519, 521, 523, 525, 527, 529, 531, 533, 535, 537, 539, 541, 543,  | 
351  |  |   414, 547, 549, 551, 553, 555, 557, 559, 561, 563, 11365, 572, 410, 11366, 578, 384,  | 
352  |  |   649, 652, 583, 585, 587, 589, 591, 614, 633, 635, 641, 32, 774, 32, 775, 32, 778,  | 
353  |  |   32, 808, 32, 771, 32, 779, 661, 768, 787, 776, 769, 953, 881, 883, 697, 887, 32,  | 
354  |  |   953, 59, 1011, 32, 776, 769, 940, 941, 942, 943, 972, 973, 974, 945, 946, 947, 948,  | 
355  |  |   949, 950, 951, 952, 954, 955, 957, 958, 959, 960, 961, 963, 964, 965, 966, 967,  | 
356  |  |   968, 969, 970, 971, 983, 985, 987, 989, 991, 993, 995, 997, 999, 1001, 1003, 1005,  | 
357  |  |   1007, 1016, 1019, 891, 892, 893, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111,  | 
358  |  |   1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1072, 1073, 1074, 1075, 1076, 1077,  | 
359  |  |   1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091,  | 
360  |  |   1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1121, 1123,  | 
361  |  |   1125, 1127, 1129, 1131, 1133, 1135, 1137, 1139, 1141, 1143, 1145, 1147, 1149, 1151,  | 
362  |  |   1153, 1163, 1165, 1167, 1169, 1171, 1173, 1175, 1177, 1179, 1181, 1183, 1185, 1187,  | 
363  |  |   1189, 1191, 1193, 1195, 1197, 1199, 1201, 1203, 1205, 1207, 1209, 1211, 1213, 1215,  | 
364  |  |   1218, 1220, 1222, 1224, 1226, 1228, 1230, 1233, 1235, 1237, 1239, 1241, 1243, 1245,  | 
365  |  |   1247, 1249, 1251, 1253, 1255, 1257, 1259, 1261, 1263, 1265, 1267, 1269, 1271, 1273,  | 
366  |  |   1275, 1277, 1279, 1281, 1283, 1285, 1287, 1289, 1291, 1293, 1295, 1297, 1299, 1301,  | 
367  |  |   1303, 1305, 1307, 1309, 1311, 1313, 1315, 1317, 1319, 1321, 1323, 1325, 1327, 1377,  | 
368  |  |   1378, 1379, 1380, 1381, 1382, 1383, 1384, 1385, 1386, 1387, 1388, 1389, 1390, 1391,  | 
369  |  |   1392, 1393, 1394, 1395, 1396, 1397, 1398, 1399, 1400, 1401, 1402, 1403, 1404, 1405,  | 
370  |  |   1406, 1407, 1408, 1409, 1410, 1411, 1412, 1413, 1414, 1381, 1410, 1575, 1652, 1608,  | 
371  |  |   1652, 1735, 1652, 1610, 1652, 2325, 2364, 2326, 2364, 2327, 2364, 2332, 2364, 2337,  | 
372  |  |   2364, 2338, 2364, 2347, 2364, 2351, 2364, 2465, 2492, 2466, 2492, 2479, 2492, 2610,  | 
373  |  |   2620, 2616, 2620, 2582, 2620, 2583, 2620, 2588, 2620, 2603, 2620, 2849, 2876, 2850,  | 
374  |  |   2876, 3661, 3634, 3789, 3762, 3755, 3737, 3755, 3745, 3851, 3906, 4023, 3916, 4023,  | 
375  |  |   3921, 4023, 3926, 4023, 3931, 4023, 3904, 4021, 3953, 3954, 3953, 3956, 4018, 3968,  | 
376  |  |   4018, 3953, 3968, 4019, 3968, 4019, 3953, 3968, 3986, 4023, 3996, 4023, 4001, 4023,  | 
377  |  |   4006, 4023, 4011, 4023, 3984, 4021, 11559, 11565, 4316, 5104, 5105, 5106, 5107,  | 
378  |  |   5108, 5109, 42571, 4304, 4305, 4306, 4307, 4308, 4309, 4310, 4311, 4312, 4313, 4314,  | 
379  |  |   4315, 4317, 4318, 4319, 4320, 4321, 4322, 4323, 4324, 4325, 4326, 4327, 4328, 4329,  | 
380  |  |   4330, 4331, 4332, 4333, 4334, 4335, 4336, 4337, 4338, 4339, 4340, 4341, 4342, 4343,  | 
381  |  |   4344, 4345, 4346, 4349, 4350, 4351, 592, 593, 7426, 604, 7446, 7447, 7453, 7461,  | 
382  |  |   594, 597, 607, 609, 613, 618, 7547, 669, 621, 7557, 671, 625, 624, 627, 628, 632,  | 
383  |  |   642, 427, 7452, 656, 657, 7681, 7683, 7685, 7687, 7689, 7691, 7693, 7695, 7697,  | 
384  |  |   7699, 7701, 7703, 7705, 7707, 7709, 7711, 7713, 7715, 7717, 7719, 7721, 7723, 7725,  | 
385  |  |   7727, 7729, 7731, 7733, 7735, 7737, 7739, 7741, 7743, 7745, 7747, 7749, 7751, 7753,  | 
386  |  |   7755, 7757, 7759, 7761, 7763, 7765, 7767, 7769, 7771, 7773, 7775, 7777, 7779, 7781,  | 
387  |  |   7783, 7785, 7787, 7789, 7791, 7793, 7795, 7797, 7799, 7801, 7803, 7805, 7807, 7809,  | 
388  |  |   7811, 7813, 7815, 7817, 7819, 7821, 7823, 7825, 7827, 7829, 97, 702, 115, 115, 7841,  | 
389  |  |   7843, 7845, 7847, 7849, 7851, 7853, 7855, 7857, 7859, 7861, 7863, 7865, 7867, 7869,  | 
390  |  |   7871, 7873, 7875, 7877, 7879, 7881, 7883, 7885, 7887, 7889, 7891, 7893, 7895, 7897,  | 
391  |  |   7899, 7901, 7903, 7905, 7907, 7909, 7911, 7913, 7915, 7917, 7919, 7921, 7923, 7925,  | 
392  |  |   7927, 7929, 7931, 7933, 7935, 7936, 7937, 7938, 7939, 7940, 7941, 7942, 7943, 7952,  | 
393  |  |   7953, 7954, 7955, 7956, 7957, 7968, 7969, 7970, 7971, 7972, 7973, 7974, 7975, 7984,  | 
394  |  |   7985, 7986, 7987, 7988, 7989, 7990, 7991, 8000, 8001, 8002, 8003, 8004, 8005, 8017,  | 
395  |  |   8019, 8021, 8023, 8032, 8033, 8034, 8035, 8036, 8037, 8038, 8039, 7936, 953, 7937,  | 
396  |  |   953, 7938, 953, 7939, 953, 7940, 953, 7941, 953, 7942, 953, 7943, 953, 7968, 953,  | 
397  |  |   7969, 953, 7970, 953, 7971, 953, 7972, 953, 7973, 953, 7974, 953, 7975, 953, 8032,  | 
398  |  |   953, 8033, 953, 8034, 953, 8035, 953, 8036, 953, 8037, 953, 8038, 953, 8039, 953,  | 
399  |  |   8048, 953, 945, 953, 940, 953, 8118, 953, 8112, 8113, 32, 787, 32, 834, 32, 776,  | 
400  |  |   834, 8052, 953, 951, 953, 942, 953, 8134, 953, 8050, 32, 787, 768, 32, 787, 769,  | 
401  |  |   32, 787, 834, 912, 8144, 8145, 8054, 32, 788, 768, 32, 788, 769, 32, 788, 834, 944,  | 
402  |  |   8160, 8161, 8058, 8165, 32, 776, 768, 96, 8060, 953, 969, 953, 974, 953, 8182, 953,  | 
403  |  |   8056, 8208, 32, 819, 8242, 8242, 8242, 8242, 8242, 8245, 8245, 8245, 8245, 8245,  | 
404  |  |   33, 33, 32, 773, 63, 63, 63, 33, 33, 63, 48, 53, 54, 55, 56, 57, 43, 8722, 61, 40,  | 
405  |  |   41, 97, 47, 99, 97, 47, 115, 176, 99, 99, 47, 111, 99, 47, 117, 176, 102, 115, 109,  | 
406  |  |   116, 101, 108, 116, 109, 1488, 1489, 1490, 1491, 102, 97, 120, 8721, 49, 8260, 55,  | 
407  |  |   49, 8260, 57, 49, 8260, 49, 48, 49, 8260, 51, 50, 8260, 51, 49, 8260, 53, 50, 8260,  | 
408  |  |   53, 51, 8260, 53, 52, 8260, 53, 49, 8260, 54, 53, 8260, 54, 49, 8260, 56, 51, 8260,  | 
409  |  |   56, 53, 8260, 56, 55, 8260, 56, 105, 105, 105, 105, 105, 105, 118, 118, 105, 118,  | 
410  |  |   105, 105, 118, 105, 105, 105, 105, 120, 120, 105, 120, 105, 105, 48, 8260, 51, 8747,  | 
411  |  |   8747, 8747, 8747, 8747, 8750, 8750, 8750, 8750, 8750, 12296, 12297, 49, 50, 49,  | 
412  |  |   51, 49, 52, 49, 53, 49, 54, 49, 55, 49, 56, 49, 57, 50, 48, 40, 49, 41, 40, 50,  | 
413  |  |   41, 40, 51, 41, 40, 52, 41, 40, 53, 41, 40, 54, 41, 40, 55, 41, 40, 56, 41, 40,  | 
414  |  |   57, 41, 40, 49, 48, 41, 40, 49, 49, 41, 40, 49, 50, 41, 40, 49, 51, 41, 40, 49,  | 
415  |  |   52, 41, 40, 49, 53, 41, 40, 49, 54, 41, 40, 49, 55, 41, 40, 49, 56, 41, 40, 49,  | 
416  |  |   57, 41, 40, 50, 48, 41, 40, 97, 41, 40, 98, 41, 40, 99, 41, 40, 100, 41, 40, 101,  | 
417  |  |   41, 40, 102, 41, 40, 103, 41, 40, 104, 41, 40, 105, 41, 40, 106, 41, 40, 107, 41,  | 
418  |  |   40, 108, 41, 40, 109, 41, 40, 110, 41, 40, 111, 41, 40, 112, 41, 40, 113, 41, 40,  | 
419  |  |   114, 41, 40, 115, 41, 40, 116, 41, 40, 117, 41, 40, 118, 41, 40, 119, 41, 40, 120,  | 
420  |  |   41, 40, 121, 41, 40, 122, 41, 58, 58, 61, 61, 61, 10973, 824, 11312, 11313, 11314,  | 
421  |  |   11315, 11316, 11317, 11318, 11319, 11320, 11321, 11322, 11323, 11324, 11325, 11326,  | 
422  |  |   11327, 11328, 11329, 11330, 11331, 11332, 11333, 11334, 11335, 11336, 11337, 11338,  | 
423  |  |   11339, 11340, 11341, 11342, 11343, 11344, 11345, 11346, 11347, 11348, 11349, 11350,  | 
424  |  |   11351, 11352, 11353, 11354, 11355, 11356, 11357, 11358, 11359, 11361, 619, 7549,  | 
425  |  |   637, 11368, 11370, 11372, 11379, 11382, 575, 576, 11393, 11395, 11397, 11399, 11401,  | 
426  |  |   11403, 11405, 11407, 11409, 11411, 11413, 11415, 11417, 11419, 11421, 11423, 11425,  | 
427  |  |   11427, 11429, 11431, 11433, 11435, 11437, 11439, 11441, 11443, 11445, 11447, 11449,  | 
428  |  |   11451, 11453, 11455, 11457, 11459, 11461, 11463, 11465, 11467, 11469, 11471, 11473,  | 
429  |  |   11475, 11477, 11479, 11481, 11483, 11485, 11487, 11489, 11491, 11500, 11502, 11507,  | 
430  |  |   11617, 27597, 40863, 19968, 20008, 20022, 20031, 20057, 20101, 20108, 20128, 20154,  | 
431  |  |   20799, 20837, 20843, 20866, 20886, 20907, 20960, 20981, 20992, 21147, 21241, 21269,  | 
432  |  |   21274, 21304, 21313, 21340, 21353, 21378, 21430, 21448, 21475, 22231, 22303, 22763,  | 
433  |  |   22786, 22794, 22805, 22823, 22899, 23376, 23424, 23544, 23567, 23586, 23608, 23662,  | 
434  |  |   23665, 24027, 24037, 24049, 24062, 24178, 24186, 24191, 24308, 24318, 24331, 24339,  | 
435  |  |   24400, 24417, 24435, 24515, 25096, 25142, 25163, 25903, 25908, 25991, 26007, 26020,  | 
436  |  |   26041, 26080, 26085, 26352, 26376, 26408, 27424, 27490, 27513, 27571, 27595, 27604,  | 
437  |  |   27611, 27663, 27668, 27700, 28779, 29226, 29238, 29243, 29247, 29255, 29273, 29275,  | 
438  |  |   29356, 29572, 29577, 29916, 29926, 29976, 29983, 29992, 30000, 30091, 30098, 30326,  | 
439  |  |   30333, 30382, 30399, 30446, 30683, 30690, 30707, 31034, 31160, 31166, 31348, 31435,  | 
440  |  |   31481, 31859, 31992, 32566, 32593, 32650, 32701, 32769, 32780, 32786, 32819, 32895,  | 
441  |  |   32905, 33251, 33258, 33267, 33276, 33292, 33307, 33311, 33390, 33394, 33400, 34381,  | 
442  |  |   34411, 34880, 34892, 34915, 35198, 35211, 35282, 35328, 35895, 35910, 35925, 35960,  | 
443  |  |   35997, 36196, 36208, 36275, 36523, 36554, 36763, 36784, 36789, 37009, 37193, 37318,  | 
444  |  |   37324, 37329, 38263, 38272, 38428, 38582, 38585, 38632, 38737, 38750, 38754, 38761,  | 
445  |  |   38859, 38893, 38899, 38913, 39080, 39131, 39135, 39318, 39321, 39340, 39592, 39640,  | 
446  |  |   39647, 39717, 39727, 39730, 39740, 39770, 40165, 40565, 40575, 40613, 40635, 40643,  | 
447  |  |   40653, 40657, 40697, 40701, 40718, 40723, 40736, 40763, 40778, 40786, 40845, 40860,  | 
448  |  |   40864, 46, 12306, 21316, 21317, 32, 12441, 32, 12442, 12424, 12426, 12467, 12488,  | 
449  |  |   4352, 4353, 4522, 4354, 4524, 4525, 4355, 4356, 4357, 4528, 4529, 4530, 4531, 4532,  | 
450  |  |   4533, 4378, 4358, 4359, 4360, 4385, 4361, 4362, 4363, 4364, 4365, 4366, 4367, 4368,  | 
451  |  |   4369, 4370, 4449, 4450, 4451, 4452, 4453, 4454, 4455, 4456, 4457, 4458, 4459, 4460,  | 
452  |  |   4461, 4462, 4463, 4464, 4465, 4466, 4467, 4468, 4469, 4372, 4373, 4551, 4552, 4556,  | 
453  |  |   4558, 4563, 4567, 4569, 4380, 4573, 4575, 4381, 4382, 4384, 4386, 4387, 4391, 4393,  | 
454  |  |   4395, 4396, 4397, 4398, 4399, 4402, 4406, 4416, 4423, 4428, 4593, 4594, 4439, 4440,  | 
455  |  |   4441, 4484, 4485, 4488, 4497, 4498, 4500, 4510, 4513, 19977, 22235, 19978, 20013,  | 
456  |  |   19979, 30002, 19993, 19969, 22825, 22320, 40, 4352, 41, 40, 4354, 41, 40, 4355,  | 
457  |  |   41, 40, 4357, 41, 40, 4358, 41, 40, 4359, 41, 40, 4361, 41, 40, 4363, 41, 40, 4364,  | 
458  |  |   41, 40, 4366, 41, 40, 4367, 41, 40, 4368, 41, 40, 4369, 41, 40, 4370, 41, 40, 44032,  | 
459  |  |   41, 40, 45208, 41, 40, 45796, 41, 40, 46972, 41, 40, 47560, 41, 40, 48148, 41, 40,  | 
460  |  |   49324, 41, 40, 50500, 41, 40, 51088, 41, 40, 52264, 41, 40, 52852, 41, 40, 53440,  | 
461  |  |   41, 40, 54028, 41, 40, 54616, 41, 40, 51452, 41, 40, 50724, 51204, 41, 40, 50724,  | 
462  |  |   54980, 41, 40, 19968, 41, 40, 20108, 41, 40, 19977, 41, 40, 22235, 41, 40, 20116,  | 
463  |  |   41, 40, 20845, 41, 40, 19971, 41, 40, 20843, 41, 40, 20061, 41, 40, 21313, 41, 40,  | 
464  |  |   26376, 41, 40, 28779, 41, 40, 27700, 41, 40, 26408, 41, 40, 37329, 41, 40, 22303,  | 
465  |  |   41, 40, 26085, 41, 40, 26666, 41, 40, 26377, 41, 40, 31038, 41, 40, 21517, 41, 40,  | 
466  |  |   29305, 41, 40, 36001, 41, 40, 31069, 41, 40, 21172, 41, 40, 20195, 41, 40, 21628,  | 
467  |  |   41, 40, 23398, 41, 40, 30435, 41, 40, 20225, 41, 40, 36039, 41, 40, 21332, 41, 40,  | 
468  |  |   31085, 41, 40, 20241, 41, 40, 33258, 41, 40, 33267, 41, 21839, 24188, 31631, 112,  | 
469  |  |   116, 101, 50, 50, 50, 52, 50, 53, 50, 54, 50, 55, 50, 56, 50, 57, 51, 48, 51, 51,  | 
470  |  |   51, 52, 51, 53, 52280, 44256, 51452, 51032, 50864, 31192, 30007, 36969, 20778, 21360,  | 
471  |  |   27880, 38917, 20889, 27491, 24038, 21491, 21307, 23447, 22812, 51, 54, 51, 55, 51,  | 
472  |  |   56, 51, 57, 52, 48, 52, 52, 52, 53, 52, 54, 52, 55, 52, 56, 52, 57, 53, 48, 49,  | 
473  |  |   26376, 50, 26376, 51, 26376, 52, 26376, 53, 26376, 54, 26376, 55, 26376, 56, 26376,  | 
474  |  |   57, 26376, 49, 48, 26376, 49, 49, 26376, 49, 50, 26376, 104, 103, 101, 114, 103,  | 
475  |  |   101, 118, 108, 116, 100, 12450, 12452, 12454, 12456, 12458, 12459, 12461, 12463,  | 
476  |  |   12465, 12469, 12471, 12473, 12475, 12477, 12479, 12481, 12484, 12486, 12490, 12491,  | 
477  |  |   12492, 12493, 12494, 12495, 12498, 12501, 12504, 12507, 12510, 12511, 12512, 12513,  | 
478  |  |   12514, 12516, 12518, 12520, 12521, 12522, 12523, 12524, 12525, 12527, 12528, 12529,  | 
479  |  |   12530, 20196, 21644, 12450, 12497, 12540, 12488, 12450, 12523, 12501, 12449, 12450,  | 
480  |  |   12531, 12506, 12450, 12450, 12540, 12523, 12452, 12491, 12531, 12464, 12452, 12531,  | 
481  |  |   12481, 12454, 12457, 12531, 12456, 12473, 12463, 12540, 12489, 12456, 12540, 12459,  | 
482  |  |   12540, 12458, 12531, 12473, 12458, 12540, 12512, 12459, 12452, 12522, 12459, 12521,  | 
483  |  |   12483, 12488, 12459, 12525, 12522, 12540, 12460, 12525, 12531, 12460, 12531, 12510,  | 
484  |  |   12462, 12460, 12462, 12491, 12540, 12461, 12517, 12522, 12540, 12462, 12523, 12480,  | 
485  |  |   12540, 12461, 12525, 12461, 12525, 12464, 12521, 12512, 12461, 12525, 12513, 12540,  | 
486  |  |   12488, 12523, 12461, 12525, 12527, 12483, 12488, 12464, 12521, 12512, 12488, 12531,  | 
487  |  |   12463, 12523, 12476, 12452, 12525, 12463, 12525, 12540, 12493, 12465, 12540, 12473,  | 
488  |  |   12467, 12523, 12490, 12467, 12540, 12509, 12469, 12452, 12463, 12523, 12469, 12531,  | 
489  |  |   12481, 12540, 12512, 12471, 12522, 12531, 12464, 12475, 12531, 12481, 12475, 12531,  | 
490  |  |   12488, 12480, 12540, 12473, 12487, 12471, 12489, 12523, 12490, 12494, 12494, 12483,  | 
491  |  |   12488, 12495, 12452, 12484, 12497, 12540, 12475, 12531, 12488, 12497, 12540, 12484,  | 
492  |  |   12496, 12540, 12524, 12523, 12500, 12450, 12473, 12488, 12523, 12500, 12463, 12523,  | 
493  |  |   12500, 12467, 12499, 12523, 12501, 12449, 12521, 12483, 12489, 12501, 12451, 12540,  | 
494  |  |   12488, 12502, 12483, 12471, 12455, 12523, 12501, 12521, 12531, 12504, 12463, 12479,  | 
495  |  |   12540, 12523, 12506, 12477, 12506, 12491, 12498, 12504, 12523, 12484, 12506, 12531,  | 
496  |  |   12473, 12506, 12540, 12472, 12505, 12540, 12479, 12509, 12452, 12531, 12488, 12508,  | 
497  |  |   12523, 12488, 12507, 12531, 12509, 12531, 12489, 12507, 12540, 12523, 12507, 12540,  | 
498  |  |   12531, 12510, 12452, 12463, 12525, 12510, 12452, 12523, 12510, 12483, 12495, 12510,  | 
499  |  |   12523, 12463, 12510, 12531, 12471, 12519, 12531, 12511, 12463, 12525, 12531, 12511,  | 
500  |  |   12522, 12511, 12522, 12496, 12540, 12523, 12513, 12460, 12513, 12460, 12488, 12531,  | 
501  |  |   12516, 12540, 12489, 12516, 12540, 12523, 12518, 12450, 12531, 12522, 12483, 12488,  | 
502  |  |   12523, 12522, 12521, 12523, 12500, 12540, 12523, 12540, 12502, 12523, 12524, 12512,  | 
503  |  |   12524, 12531, 12488, 12466, 12531, 48, 28857, 49, 28857, 50, 28857, 51, 28857, 52,  | 
504  |  |   28857, 53, 28857, 54, 28857, 55, 28857, 56, 28857, 57, 28857, 49, 48, 28857, 49,  | 
505  |  |   49, 28857, 49, 50, 28857, 49, 51, 28857, 49, 52, 28857, 49, 53, 28857, 49, 54, 28857,  | 
506  |  |   49, 55, 28857, 49, 56, 28857, 49, 57, 28857, 50, 48, 28857, 50, 49, 28857, 50, 50,  | 
507  |  |   28857, 50, 51, 28857, 50, 52, 28857, 104, 112, 97, 100, 97, 97, 117, 98, 97, 114,  | 
508  |  |   111, 118, 112, 99, 100, 109, 100, 109, 50, 100, 109, 51, 105, 117, 24179, 25104,  | 
509  |  |   26157, 21644, 22823, 27491, 26126, 27835, 26666, 24335, 20250, 31038, 110, 97, 956,  | 
510  |  |   97, 109, 97, 107, 97, 107, 98, 109, 98, 103, 98, 99, 97, 108, 107, 99, 97, 108,  | 
511  |  |   112, 102, 110, 102, 956, 102, 956, 103, 109, 103, 107, 103, 104, 122, 107, 104,  | 
512  |  |   122, 109, 104, 122, 116, 104, 122, 956, 108, 109, 108, 100, 108, 102, 109, 110,  | 
513  |  |   109, 956, 109, 109, 109, 99, 109, 107, 109, 109, 109, 50, 99, 109, 50, 107, 109,  | 
514  |  |   50, 109, 109, 51, 99, 109, 51, 107, 109, 51, 109, 8725, 115, 109, 8725, 115, 50,  | 
515  |  |   107, 112, 97, 109, 112, 97, 103, 112, 97, 114, 97, 100, 114, 97, 100, 8725, 115,  | 
516  |  |   114, 97, 100, 8725, 115, 50, 112, 115, 110, 115, 956, 115, 109, 115, 112, 118, 110,  | 
517  |  |   118, 956, 118, 109, 118, 107, 118, 112, 119, 110, 119, 956, 119, 109, 119, 107,  | 
518  |  |   119, 107, 969, 109, 969, 98, 113, 99, 8725, 107, 103, 100, 98, 103, 121, 104, 97,  | 
519  |  |   105, 110, 107, 107, 107, 116, 108, 110, 108, 111, 103, 108, 120, 109, 105, 108,  | 
520  |  |   109, 111, 108, 112, 104, 112, 112, 109, 112, 114, 115, 118, 119, 98, 118, 8725,  | 
521  |  |   109, 97, 8725, 109, 49, 26085, 50, 26085, 51, 26085, 52, 26085, 53, 26085, 54, 26085,  | 
522  |  |   55, 26085, 56, 26085, 57, 26085, 49, 48, 26085, 49, 49, 26085, 49, 50, 26085, 49,  | 
523  |  |   51, 26085, 49, 52, 26085, 49, 53, 26085, 49, 54, 26085, 49, 55, 26085, 49, 56, 26085,  | 
524  |  |   49, 57, 26085, 50, 48, 26085, 50, 49, 26085, 50, 50, 26085, 50, 51, 26085, 50, 52,  | 
525  |  |   26085, 50, 53, 26085, 50, 54, 26085, 50, 55, 26085, 50, 56, 26085, 50, 57, 26085,  | 
526  |  |   51, 48, 26085, 51, 49, 26085, 103, 97, 108, 42561, 42563, 42565, 42567, 42569, 42573,  | 
527  |  |   42575, 42577, 42579, 42581, 42583, 42585, 42587, 42589, 42591, 42593, 42595, 42597,  | 
528  |  |   42599, 42601, 42603, 42605, 42625, 42627, 42629, 42631, 42633, 42635, 42637, 42639,  | 
529  |  |   42641, 42643, 42645, 42647, 42649, 42651, 42787, 42789, 42791, 42793, 42795, 42797,  | 
530  |  |   42799, 42803, 42805, 42807, 42809, 42811, 42813, 42815, 42817, 42819, 42821, 42823,  | 
531  |  |   42825, 42827, 42829, 42831, 42833, 42835, 42837, 42839, 42841, 42843, 42845, 42847,  | 
532  |  |   42849, 42851, 42853, 42855, 42857, 42859, 42861, 42863, 42874, 42876, 7545, 42879,  | 
533  |  |   42881, 42883, 42885, 42887, 42892, 42897, 42899, 42903, 42905, 42907, 42909, 42911,  | 
534  |  |   42913, 42915, 42917, 42919, 42921, 620, 670, 647, 43859, 42933, 42935, 42937, 42939,  | 
535  |  |   42941, 42943, 42945, 42947, 42900, 7566, 42952, 42954, 42961, 42967, 42969, 42998,  | 
536  |  |   43831, 43858, 653, 5024, 5025, 5026, 5027, 5028, 5029, 5030, 5031, 5032, 5033, 5034,  | 
537  |  |   5035, 5036, 5037, 5038, 5039, 5040, 5041, 5042, 5043, 5044, 5045, 5046, 5047, 5048,  | 
538  |  |   5049, 5050, 5051, 5052, 5053, 5054, 5055, 5056, 5057, 5058, 5059, 5060, 5061, 5062,  | 
539  |  |   5063, 5064, 5065, 5066, 5067, 5068, 5069, 5070, 5071, 5072, 5073, 5074, 5075, 5076,  | 
540  |  |   5077, 5078, 5079, 5080, 5081, 5082, 5083, 5084, 5085, 5086, 5087, 5088, 5089, 5090,  | 
541  |  |   5091, 5092, 5093, 5094, 5095, 5096, 5097, 5098, 5099, 5100, 5101, 5102, 5103, 35912,  | 
542  |  |   26356, 36040, 28369, 20018, 21477, 22865, 21895, 22856, 25078, 30313, 32645, 34367,  | 
543  |  |   34746, 35064, 37007, 27138, 27931, 28889, 29662, 33853, 37226, 39409, 20098, 21365,  | 
544  |  |   27396, 29211, 34349, 40478, 23888, 28651, 34253, 35172, 25289, 33240, 34847, 24266,  | 
545  |  |   26391, 28010, 29436, 37070, 20358, 20919, 21214, 25796, 27347, 29200, 30439, 34310,  | 
546  |  |   34396, 36335, 38706, 39791, 40442, 30860, 31103, 32160, 33737, 37636, 35542, 22751,  | 
547  |  |   24324, 31840, 32894, 29282, 30922, 36034, 38647, 22744, 23650, 27155, 28122, 28431,  | 
548  |  |   32047, 32311, 38475, 21202, 32907, 20956, 20940, 31260, 32190, 33777, 38517, 35712,  | 
549  |  |   25295, 35582, 20025, 23527, 24594, 29575, 30064, 21271, 30971, 20415, 24489, 19981,  | 
550  |  |   27852, 25976, 32034, 21443, 22622, 30465, 33865, 35498, 27578, 27784, 25342, 33509,  | 
551  |  |   25504, 30053, 20142, 20841, 20937, 26753, 31975, 33391, 35538, 37327, 21237, 21570,  | 
552  |  |   24300, 26053, 28670, 31018, 38317, 39530, 40599, 40654, 26310, 27511, 36706, 24180,  | 
553  |  |   24976, 25088, 25754, 28451, 29001, 29833, 31178, 32244, 32879, 36646, 34030, 36899,  | 
554  |  |   37706, 21015, 21155, 21693, 28872, 35010, 24265, 24565, 25467, 27566, 31806, 29557,  | 
555  |  |   22265, 23994, 24604, 29618, 29801, 32666, 32838, 37428, 38646, 38728, 38936, 20363,  | 
556  |  |   31150, 37300, 38584, 24801, 20102, 20698, 23534, 23615, 26009, 29134, 30274, 34044,  | 
557  |  |   36988, 26248, 38446, 21129, 26491, 26611, 27969, 28316, 29705, 30041, 30827, 32016,  | 
558  |  |   39006, 25134, 38520, 20523, 23833, 28138, 36650, 24459, 24900, 26647, 38534, 21033,  | 
559  |  |   21519, 23653, 26131, 26446, 26792, 27877, 29702, 30178, 32633, 35023, 35041, 38626,  | 
560  |  |   21311, 28346, 21533, 29136, 29848, 34298, 38563, 40023, 40607, 26519, 28107, 33256,  | 
561  |  |   31520, 31890, 29376, 28825, 35672, 20160, 33590, 21050, 20999, 24230, 25299, 31958,  | 
562  |  |   23429, 27934, 26292, 36667, 38477, 24275, 20800, 21952, 22618, 26228, 20958, 29482,  | 
563  |  |   30410, 31036, 31070, 31077, 31119, 38742, 31934, 34322, 35576, 36920, 37117, 39151,  | 
564  |  |   39164, 39208, 40372, 37086, 38583, 20398, 20711, 20813, 21193, 21220, 21329, 21917,  | 
565  |  |   22022, 22120, 22592, 22696, 23652, 24724, 24936, 24974, 25074, 25935, 26082, 26257,  | 
566  |  |   26757, 28023, 28186, 28450, 29038, 29227, 29730, 30865, 31049, 31048, 31056, 31062,  | 
567  |  |   31117, 31118, 31296, 31361, 31680, 32265, 32321, 32626, 32773, 33261, 33401, 33879,  | 
568  |  |   35088, 35222, 35585, 35641, 36051, 36104, 36790, 38627, 38911, 38971, 24693, 148206,  | 
569  |  |   33304, 20006, 20917, 20840, 20352, 20805, 20864, 21191, 21242, 21845, 21913, 21986,  | 
570  |  |   22707, 22852, 22868, 23138, 23336, 24274, 24281, 24425, 24493, 24792, 24910, 24840,  | 
571  |  |   24928, 25140, 25540, 25628, 25682, 25942, 26395, 26454, 28379, 28363, 28702, 30631,  | 
572  |  |   29237, 29359, 29809, 29958, 30011, 30237, 30239, 30427, 30452, 30538, 30528, 30924,  | 
573  |  |   31409, 31867, 32091, 32574, 33618, 33775, 34681, 35137, 35206, 35519, 35531, 35565,  | 
574  |  |   35722, 36664, 36978, 37273, 37494, 38524, 38875, 38923, 39698, 141386, 141380, 144341,  | 
575  |  |   15261, 16408, 16441, 152137, 154832, 163539, 40771, 40846, 102, 102, 102, 105, 102,  | 
576  |  |   108, 102, 102, 108, 1396, 1398, 1396, 1381, 1396, 1387, 1406, 1398, 1396, 1389,  | 
577  |  |   1497, 1460, 1522, 1463, 1506, 1492, 1499, 1500, 1501, 1512, 1514, 1513, 1473, 1513,  | 
578  |  |   1474, 1513, 1468, 1473, 1513, 1468, 1474, 1488, 1463, 1488, 1464, 1488, 1468, 1489,  | 
579  |  |   1468, 1490, 1468, 1491, 1468, 1492, 1468, 1493, 1468, 1494, 1468, 1496, 1468, 1497,  | 
580  |  |   1468, 1498, 1468, 1499, 1468, 1500, 1468, 1502, 1468, 1504, 1468, 1505, 1468, 1507,  | 
581  |  |   1468, 1508, 1468, 1510, 1468, 1511, 1468, 1512, 1468, 1514, 1468, 1493, 1465, 1489,  | 
582  |  |   1471, 1499, 1471, 1508, 1471, 1488, 1500, 1649, 1659, 1662, 1664, 1658, 1663, 1657,  | 
583  |  |   1700, 1702, 1668, 1667, 1670, 1671, 1677, 1676, 1678, 1672, 1688, 1681, 1705, 1711,  | 
584  |  |   1715, 1713, 1722, 1723, 1728, 1729, 1726, 1746, 1747, 1709, 1734, 1736, 1739, 1733,  | 
585  |  |   1737, 1744, 1609, 1574, 1575, 1574, 1749, 1574, 1608, 1574, 1735, 1574, 1734, 1574,  | 
586  |  |   1736, 1574, 1744, 1574, 1609, 1740, 1574, 1580, 1574, 1581, 1574, 1605, 1574, 1610,  | 
587  |  |   1576, 1580, 1576, 1581, 1576, 1582, 1576, 1605, 1576, 1609, 1576, 1610, 1578, 1580,  | 
588  |  |   1578, 1581, 1578, 1582, 1578, 1605, 1578, 1609, 1578, 1610, 1579, 1580, 1579, 1605,  | 
589  |  |   1579, 1609, 1579, 1610, 1580, 1581, 1580, 1605, 1581, 1605, 1582, 1580, 1582, 1581,  | 
590  |  |   1582, 1605, 1587, 1580, 1587, 1581, 1587, 1582, 1587, 1605, 1589, 1581, 1589, 1605,  | 
591  |  |   1590, 1580, 1590, 1581, 1590, 1582, 1590, 1605, 1591, 1581, 1591, 1605, 1592, 1605,  | 
592  |  |   1593, 1580, 1593, 1605, 1594, 1580, 1594, 1605, 1601, 1580, 1601, 1581, 1601, 1582,  | 
593  |  |   1601, 1605, 1601, 1609, 1601, 1610, 1602, 1581, 1602, 1605, 1602, 1609, 1602, 1610,  | 
594  |  |   1603, 1575, 1603, 1580, 1603, 1581, 1603, 1582, 1603, 1604, 1603, 1605, 1603, 1609,  | 
595  |  |   1603, 1610, 1604, 1580, 1604, 1581, 1604, 1582, 1604, 1605, 1604, 1609, 1604, 1610,  | 
596  |  |   1605, 1580, 1605, 1605, 1605, 1609, 1605, 1610, 1606, 1580, 1606, 1581, 1606, 1582,  | 
597  |  |   1606, 1605, 1606, 1609, 1606, 1610, 1607, 1580, 1607, 1605, 1607, 1609, 1607, 1610,  | 
598  |  |   1610, 1581, 1610, 1582, 1610, 1609, 1584, 1648, 1585, 1648, 1609, 1648, 32, 1612,  | 
599  |  |   1617, 32, 1613, 1617, 32, 1614, 1617, 32, 1615, 1617, 32, 1616, 1617, 32, 1617,  | 
600  |  |   1648, 1574, 1585, 1574, 1586, 1574, 1606, 1576, 1585, 1576, 1586, 1576, 1606, 1578,  | 
601  |  |   1585, 1578, 1586, 1578, 1606, 1579, 1585, 1579, 1586, 1579, 1606, 1605, 1575, 1606,  | 
602  |  |   1585, 1606, 1586, 1606, 1606, 1610, 1585, 1610, 1586, 1574, 1582, 1574, 1607, 1576,  | 
603  |  |   1607, 1578, 1607, 1589, 1582, 1604, 1607, 1606, 1607, 1607, 1648, 1579, 1607, 1587,  | 
604  |  |   1607, 1588, 1605, 1588, 1607, 1600, 1614, 1617, 1600, 1615, 1617, 1600, 1616, 1617,  | 
605  |  |   1591, 1609, 1591, 1610, 1593, 1609, 1593, 1610, 1594, 1609, 1594, 1610, 1587, 1609,  | 
606  |  |   1587, 1610, 1588, 1609, 1588, 1610, 1581, 1609, 1580, 1609, 1580, 1610, 1582, 1609,  | 
607  |  |   1589, 1609, 1589, 1610, 1590, 1609, 1590, 1610, 1588, 1580, 1588, 1581, 1588, 1582,  | 
608  |  |   1588, 1585, 1587, 1585, 1589, 1585, 1590, 1585, 1575, 1611, 1578, 1580, 1605, 1578,  | 
609  |  |   1581, 1580, 1578, 1581, 1605, 1578, 1582, 1605, 1578, 1605, 1580, 1578, 1605, 1581,  | 
610  |  |   1578, 1605, 1582, 1581, 1605, 1610, 1581, 1605, 1609, 1587, 1581, 1580, 1587, 1580,  | 
611  |  |   1581, 1587, 1580, 1609, 1587, 1605, 1581, 1587, 1605, 1580, 1587, 1605, 1605, 1589,  | 
612  |  |   1581, 1581, 1589, 1605, 1605, 1588, 1581, 1605, 1588, 1580, 1610, 1588, 1605, 1582,  | 
613  |  |   1588, 1605, 1605, 1590, 1581, 1609, 1590, 1582, 1605, 1591, 1605, 1581, 1591, 1605,  | 
614  |  |   1605, 1591, 1605, 1610, 1593, 1580, 1605, 1593, 1605, 1605, 1593, 1605, 1609, 1594,  | 
615  |  |   1605, 1605, 1594, 1605, 1610, 1594, 1605, 1609, 1601, 1582, 1605, 1602, 1605, 1581,  | 
616  |  |   1602, 1605, 1605, 1604, 1581, 1605, 1604, 1581, 1610, 1604, 1581, 1609, 1604, 1580,  | 
617  |  |   1580, 1604, 1582, 1605, 1604, 1605, 1581, 1605, 1581, 1580, 1605, 1581, 1610, 1605,  | 
618  |  |   1580, 1581, 1605, 1582, 1605, 1605, 1580, 1582, 1607, 1605, 1580, 1607, 1605, 1605,  | 
619  |  |   1606, 1581, 1605, 1606, 1581, 1609, 1606, 1580, 1605, 1606, 1580, 1609, 1606, 1605,  | 
620  |  |   1610, 1606, 1605, 1609, 1610, 1605, 1605, 1576, 1582, 1610, 1578, 1580, 1610, 1578,  | 
621  |  |   1580, 1609, 1578, 1582, 1610, 1578, 1582, 1609, 1578, 1605, 1610, 1578, 1605, 1609,  | 
622  |  |   1580, 1605, 1610, 1580, 1581, 1609, 1580, 1605, 1609, 1587, 1582, 1609, 1589, 1581,  | 
623  |  |   1610, 1588, 1581, 1610, 1590, 1581, 1610, 1604, 1580, 1610, 1604, 1605, 1610, 1610,  | 
624  |  |   1580, 1610, 1610, 1605, 1610, 1605, 1605, 1610, 1602, 1605, 1610, 1606, 1581, 1610,  | 
625  |  |   1593, 1605, 1610, 1603, 1605, 1610, 1606, 1580, 1581, 1605, 1582, 1610, 1604, 1580,  | 
626  |  |   1605, 1603, 1605, 1605, 1580, 1581, 1610, 1581, 1580, 1610, 1605, 1580, 1610, 1601,  | 
627  |  |   1605, 1610, 1576, 1581, 1610, 1587, 1582, 1610, 1606, 1580, 1610, 1589, 1604, 1746,  | 
628  |  |   1602, 1604, 1746, 1575, 1604, 1604, 1607, 1575, 1603, 1576, 1585, 1605, 1581, 1605,  | 
629  |  |   1583, 1589, 1604, 1593, 1605, 1585, 1587, 1608, 1604, 1593, 1604, 1610, 1607, 1608,  | 
630  |  |   1587, 1604, 1605, 1589, 1604, 1609, 1589, 1604, 1609, 32, 1575, 1604, 1604, 1607,  | 
631  |  |   32, 1593, 1604, 1610, 1607, 32, 1608, 1587, 1604, 1605, 1580, 1604, 32, 1580, 1604,  | 
632  |  |   1575, 1604, 1607, 1585, 1740, 1575, 1604, 44, 12289, 12310, 12311, 8212, 8211, 95,  | 
633  |  |   123, 125, 12308, 12309, 12304, 12305, 12298, 12299, 12300, 12301, 12302, 12303,  | 
634  |  |   91, 93, 35, 38, 42, 45, 60, 62, 92, 36, 37, 64, 32, 1611, 1600, 1611, 1600, 1617,  | 
635  |  |   32, 1618, 1600, 1618, 1569, 1570, 1571, 1572, 1573, 1577, 1604, 1570, 1604, 1571,  | 
636  |  |   1604, 1573, 34, 39, 94, 124, 126, 10629, 10630, 12539, 12453, 12515, 162, 163, 172,  | 
637  |  |   166, 165, 8361, 9474, 8592, 8593, 8594, 8595, 9632, 9675, 66600, 66601, 66602, 66603,  | 
638  |  |   66604, 66605, 66606, 66607, 66608, 66609, 66610, 66611, 66612, 66613, 66614, 66615,  | 
639  |  |   66616, 66617, 66618, 66619, 66620, 66621, 66622, 66623, 66624, 66625, 66626, 66627,  | 
640  |  |   66628, 66629, 66630, 66631, 66632, 66633, 66634, 66635, 66636, 66637, 66638, 66639,  | 
641  |  |   66776, 66777, 66778, 66779, 66780, 66781, 66782, 66783, 66784, 66785, 66786, 66787,  | 
642  |  |   66788, 66789, 66790, 66791, 66792, 66793, 66794, 66795, 66796, 66797, 66798, 66799,  | 
643  |  |   66800, 66801, 66802, 66803, 66804, 66805, 66806, 66807, 66808, 66809, 66810, 66811,  | 
644  |  |   66967, 66968, 66969, 66970, 66971, 66972, 66973, 66974, 66975, 66976, 66977, 66979,  | 
645  |  |   66980, 66981, 66982, 66983, 66984, 66985, 66986, 66987, 66988, 66989, 66990, 66991,  | 
646  |  |   66992, 66993, 66995, 66996, 66997, 66998, 66999, 67000, 67001, 67003, 67004, 720,  | 
647  |  |   721, 665, 675, 43878, 677, 676, 7569, 600, 606, 681, 612, 610, 667, 668, 615, 644,  | 
648  |  |   682, 683, 122628, 42894, 622, 122629, 654, 122630, 630, 631, 634, 122632, 638, 680,  | 
649  |  |   678, 43879, 679, 11377, 655, 673, 674, 664, 448, 449, 450, 122634, 122654, 68800,  | 
650  |  |   68801, 68802, 68803, 68804, 68805, 68806, 68807, 68808, 68809, 68810, 68811, 68812,  | 
651  |  |   68813, 68814, 68815, 68816, 68817, 68818, 68819, 68820, 68821, 68822, 68823, 68824,  | 
652  |  |   68825, 68826, 68827, 68828, 68829, 68830, 68831, 68832, 68833, 68834, 68835, 68836,  | 
653  |  |   68837, 68838, 68839, 68840, 68841, 68842, 68843, 68844, 68845, 68846, 68847, 68848,  | 
654  |  |   68849, 68850, 71872, 71873, 71874, 71875, 71876, 71877, 71878, 71879, 71880, 71881,  | 
655  |  |   71882, 71883, 71884, 71885, 71886, 71887, 71888, 71889, 71890, 71891, 71892, 71893,  | 
656  |  |   71894, 71895, 71896, 71897, 71898, 71899, 71900, 71901, 71902, 71903, 93792, 93793,  | 
657  |  |   93794, 93795, 93796, 93797, 93798, 93799, 93800, 93801, 93802, 93803, 93804, 93805,  | 
658  |  |   93806, 93807, 93808, 93809, 93810, 93811, 93812, 93813, 93814, 93815, 93816, 93817,  | 
659  |  |   93818, 93819, 93820, 93821, 93822, 93823, 119127, 119141, 119128, 119141, 119128,  | 
660  |  |   119141, 119150, 119128, 119141, 119151, 119128, 119141, 119152, 119128, 119141,  | 
661  |  |   119153, 119128, 119141, 119154, 119225, 119141, 119226, 119141, 119225, 119141,  | 
662  |  |   119150, 119226, 119141, 119150, 119225, 119141, 119151, 119226, 119141, 119151,  | 
663  |  |   305, 567, 8711, 8706, 1231, 125218, 125219, 125220, 125221, 125222, 125223, 125224,  | 
664  |  |   125225, 125226, 125227, 125228, 125229, 125230, 125231, 125232, 125233, 125234,  | 
665  |  |   125235, 125236, 125237, 125238, 125239, 125240, 125241, 125242, 125243, 125244,  | 
666  |  |   125245, 125246, 125247, 125248, 125249, 125250, 125251, 1646, 1697, 1647, 48, 44,  | 
667  |  |   49, 44, 50, 44, 51, 44, 52, 44, 53, 44, 54, 44, 55, 44, 56, 44, 57, 44, 12308, 115,  | 
668  |  |   12309, 119, 122, 104, 118, 115, 100, 112, 112, 118, 119, 99, 109, 114, 100, 106,  | 
669  |  |   12411, 12363, 12467, 12467, 23383, 21452, 22810, 35299, 20132, 26144, 28961, 21069,  | 
670  |  |   24460, 20877, 26032, 21021, 32066, 36009, 22768, 21561, 28436, 25237, 25429, 36938,  | 
671  |  |   25351, 25171, 31105, 31354, 21512, 28288, 30003, 21106, 21942, 37197, 12308, 26412,  | 
672  |  |   12309, 12308, 19977, 12309, 12308, 20108, 12309, 12308, 23433, 12309, 12308, 28857,  | 
673  |  |   12309, 12308, 25171, 12309, 12308, 30423, 12309, 12308, 21213, 12309, 12308, 25943,  | 
674  |  |   12309, 24471, 21487, 20029, 20024, 20033, 131362, 20320, 20411, 20482, 20602, 20633,  | 
675  |  |   20687, 13470, 132666, 20820, 20836, 20855, 132380, 13497, 20839, 132427, 20887,  | 
676  |  |   20900, 20172, 20908, 168415, 20995, 13535, 21051, 21062, 21111, 13589, 21253, 21254,  | 
677  |  |   21321, 21338, 21363, 21373, 21375, 133676, 28784, 21450, 21471, 133987, 21483, 21489,  | 
678  |  |   21510, 21662, 21560, 21576, 21608, 21666, 21750, 21776, 21843, 21859, 21892, 21931,  | 
679  |  |   21939, 21954, 22294, 22295, 22097, 22132, 22766, 22478, 22516, 22541, 22411, 22578,  | 
680  |  |   22577, 22700, 136420, 22770, 22775, 22790, 22818, 22882, 136872, 136938, 23020,  | 
681  |  |   23067, 23079, 23000, 23142, 14062, 23304, 23358, 137672, 23491, 23512, 23539, 138008,  | 
682  |  |   23551, 23558, 14209, 23648, 23744, 23693, 138724, 23875, 138726, 23918, 23915, 23932,  | 
683  |  |   24033, 24034, 14383, 24061, 24104, 24125, 24169, 14434, 139651, 14460, 24240, 24243,  | 
684  |  |   24246, 172946, 140081, 33281, 24354, 14535, 144056, 156122, 24418, 24427, 14563,  | 
685  |  |   24474, 24525, 24535, 24569, 24705, 14650, 14620, 141012, 24775, 24904, 24908, 24954,  | 
686  |  |   25010, 24996, 25007, 25054, 25115, 25181, 25265, 25300, 25424, 142092, 25405, 25340,  | 
687  |  |   25448, 25475, 25572, 142321, 25634, 25541, 25513, 14894, 25705, 25726, 25757, 25719,  | 
688  |  |   14956, 25964, 143370, 26083, 26360, 26185, 15129, 15112, 15076, 20882, 20885, 26368,  | 
689  |  |   26268, 32941, 17369, 26401, 26462, 26451, 144323, 15177, 26618, 26501, 26706, 144493,  | 
690  |  |   26766, 26655, 26900, 26946, 27043, 27114, 27304, 145059, 27355, 15384, 27425, 145575,  | 
691  |  |   27476, 15438, 27506, 27551, 27579, 146061, 138507, 146170, 27726, 146620, 27839,  | 
692  |  |   27853, 27751, 27926, 27966, 28009, 28024, 28037, 146718, 27956, 28207, 28270, 15667,  | 
693  |  |   28359, 147153, 28153, 28526, 147294, 147342, 28614, 28729, 28699, 15766, 28746,  | 
694  |  |   28797, 28791, 28845, 132389, 28997, 148067, 29084, 29224, 29264, 149000, 29312,  | 
695  |  |   29333, 149301, 149524, 29562, 29579, 16044, 29605, 16056, 29767, 29788, 29829, 29898,  | 
696  |  |   16155, 29988, 150582, 30014, 150674, 139679, 30224, 151457, 151480, 151620, 16380,  | 
697  |  |   16392, 151795, 151794, 151833, 151859, 30494, 30495, 30603, 16454, 16534, 152605,  | 
698  |  |   30798, 16611, 153126, 153242, 153285, 31211, 16687, 31306, 31311, 153980, 154279,  | 
699  |  |   16898, 154539, 31686, 31689, 16935, 154752, 31954, 17056, 31976, 31971, 32000, 155526,  | 
700  |  |   32099, 17153, 32199, 32258, 32325, 17204, 156200, 156231, 17241, 156377, 32634,  | 
701  |  |   156478, 32661, 32762, 156890, 156963, 32864, 157096, 32880, 144223, 17365, 32946,  | 
702  |  |   33027, 17419, 33086, 23221, 157607, 157621, 144275, 144284, 33284, 36766, 17515,  | 
703  |  |   33425, 33419, 33437, 21171, 33457, 33459, 33469, 33510, 158524, 33565, 33635, 33709,  | 
704  |  |   33571, 33725, 33767, 33619, 33738, 33740, 33756, 158774, 159083, 158933, 17707,  | 
705  |  |   34033, 34035, 34070, 160714, 34148, 159532, 17757, 17761, 159665, 159954, 17771,  | 
706  |  |   34384, 34407, 34409, 34473, 34440, 34574, 34530, 34600, 34667, 34694, 34785, 34817,  | 
707  |  |   17913, 34912, 161383, 35031, 35038, 17973, 35066, 13499, 161966, 162150, 18110,  | 
708  |  |   18119, 35488, 162984, 36011, 36033, 36123, 36215, 163631, 133124, 36299, 36284,  | 
709  |  |   36336, 133342, 36564, 165330, 165357, 37012, 37105, 37137, 165678, 37147, 37432,  | 
710  |  |   37591, 37592, 37500, 37881, 37909, 166906, 38283, 18837, 38327, 167287, 18918, 38595,  | 
711  |  |   23986, 38691, 168261, 168474, 19054, 19062, 38880, 168970, 19122, 169110, 38953,  | 
712  |  |   169398, 39138, 19251, 39209, 39335, 39362, 39422, 19406, 170800, 40000, 40189, 19662,  | 
713  |  |   19693, 40295, 172238, 19704, 172293, 172558, 172689, 19798, 40702, 40709, 40719,  | 
714  |  |   40726, 173568,  | 
715  |  |  | 
716  |  | };  | 
717  |  | const uint32_t table[8000][2] =  | 
718  |  | { | 
719  |  |   {0, 1}, {65, 16777219}, {66, 16777475}, {67, 16777731}, | 
720  |  |   {68, 16777987}, {69, 16778243}, {70, 16778499}, {71, 16778755}, | 
721  |  |   {72, 16779011}, {73, 16779267}, {74, 16779523}, {75, 16779779}, | 
722  |  |   {76, 16780035}, {77, 16780291}, {78, 16780547}, {79, 16780803}, | 
723  |  |   {80, 16781059}, {81, 16781315}, {82, 16781571}, {83, 16781827}, | 
724  |  |   {84, 16782083}, {85, 16782339}, {86, 16782595}, {87, 16782851}, | 
725  |  |   {88, 16783107}, {89, 16783363}, {90, 16783619}, {91, 1}, | 
726  |  |   {128, 2}, {160, 16783875}, {161, 1}, {168, 33561347}, | 
727  |  |   {169, 1}, {170, 16777219}, {171, 1}, {173, 0}, | 
728  |  |   {174, 1}, {175, 33561859}, {176, 1}, {178, 16785155}, | 
729  |  |   {179, 16785411}, {180, 33562883}, {181, 16786179}, {182, 1}, | 
730  |  |   {184, 33563651}, {185, 16786947}, {186, 16780803}, {187, 1}, | 
731  |  |   {188, 50341635}, {189, 50342403}, {190, 50343171}, {191, 1}, | 
732  |  |   {192, 16789507}, {193, 16789763}, {194, 16790019}, {195, 16790275}, | 
733  |  |   {196, 16790531}, {197, 16790787}, {198, 16791043}, {199, 16791299}, | 
734  |  |   {200, 16791555}, {201, 16791811}, {202, 16792067}, {203, 16792323}, | 
735  |  |   {204, 16792579}, {205, 16792835}, {206, 16793091}, {207, 16793347}, | 
736  |  |   {208, 16793603}, {209, 16793859}, {210, 16794115}, {211, 16794371}, | 
737  |  |   {212, 16794627}, {213, 16794883}, {214, 16795139}, {215, 1}, | 
738  |  |   {216, 16795395}, {217, 16795651}, {218, 16795907}, {219, 16796163}, | 
739  |  |   {220, 16796419}, {221, 16796675}, {222, 16796931}, {223, 1}, | 
740  |  |   {256, 16797187}, {257, 1}, {258, 16797443}, {259, 1}, | 
741  |  |   {260, 16797699}, {261, 1}, {262, 16797955}, {263, 1}, | 
742  |  |   {264, 16798211}, {265, 1}, {266, 16798467}, {267, 1}, | 
743  |  |   {268, 16798723}, {269, 1}, {270, 16798979}, {271, 1}, | 
744  |  |   {272, 16799235}, {273, 1}, {274, 16799491}, {275, 1}, | 
745  |  |   {276, 16799747}, {277, 1}, {278, 16800003}, {279, 1}, | 
746  |  |   {280, 16800259}, {281, 1}, {282, 16800515}, {283, 1}, | 
747  |  |   {284, 16800771}, {285, 1}, {286, 16801027}, {287, 1}, | 
748  |  |   {288, 16801283}, {289, 1}, {290, 16801539}, {291, 1}, | 
749  |  |   {292, 16801795}, {293, 1}, {294, 16802051}, {295, 1}, | 
750  |  |   {296, 16802307}, {297, 1}, {298, 16802563}, {299, 1}, | 
751  |  |   {300, 16802819}, {301, 1}, {302, 16803075}, {303, 1}, | 
752  |  |   {304, 33580547}, {305, 1}, {306, 33556483}, {308, 16803843}, | 
753  |  |   {309, 1}, {310, 16804099}, {311, 1}, {313, 16804355}, | 
754  |  |   {314, 1}, {315, 16804611}, {316, 1}, {317, 16804867}, | 
755  |  |   {318, 1}, {319, 33582339}, {321, 16805635}, {322, 1}, | 
756  |  |   {323, 16805891}, {324, 1}, {325, 16806147}, {326, 1}, | 
757  |  |   {327, 16806403}, {328, 1}, {329, 33583875}, {330, 16807171}, | 
758  |  |   {331, 1}, {332, 16807427}, {333, 1}, {334, 16807683}, | 
759  |  |   {335, 1}, {336, 16807939}, {337, 1}, {338, 16808195}, | 
760  |  |   {339, 1}, {340, 16808451}, {341, 1}, {342, 16808707}, | 
761  |  |   {343, 1}, {344, 16808963}, {345, 1}, {346, 16809219}, | 
762  |  |   {347, 1}, {348, 16809475}, {349, 1}, {350, 16809731}, | 
763  |  |   {351, 1}, {352, 16809987}, {353, 1}, {354, 16810243}, | 
764  |  |   {355, 1}, {356, 16810499}, {357, 1}, {358, 16810755}, | 
765  |  |   {359, 1}, {360, 16811011}, {361, 1}, {362, 16811267}, | 
766  |  |   {363, 1}, {364, 16811523}, {365, 1}, {366, 16811779}, | 
767  |  |   {367, 1}, {368, 16812035}, {369, 1}, {370, 16812291}, | 
768  |  |   {371, 1}, {372, 16812547}, {373, 1}, {374, 16812803}, | 
769  |  |   {375, 1}, {376, 16813059}, {377, 16813315}, {378, 1}, | 
770  |  |   {379, 16813571}, {380, 1}, {381, 16813827}, {382, 1}, | 
771  |  |   {383, 16781827}, {384, 1}, {385, 16814083}, {386, 16814339}, | 
772  |  |   {387, 1}, {388, 16814595}, {389, 1}, {390, 16814851}, | 
773  |  |   {391, 16815107}, {392, 1}, {393, 16815363}, {394, 16815619}, | 
774  |  |   {395, 16815875}, {396, 1}, {398, 16816131}, {399, 16816387}, | 
775  |  |   {400, 16816643}, {401, 16816899}, {402, 1}, {403, 16817155}, | 
776  |  |   {404, 16817411}, {405, 1}, {406, 16817667}, {407, 16817923}, | 
777  |  |   {408, 16818179}, {409, 1}, {412, 16818435}, {413, 16818691}, | 
778  |  |   {414, 1}, {415, 16818947}, {416, 16819203}, {417, 1}, | 
779  |  |   {418, 16819459}, {419, 1}, {420, 16819715}, {421, 1}, | 
780  |  |   {422, 16819971}, {423, 16820227}, {424, 1}, {425, 16820483}, | 
781  |  |   {426, 1}, {428, 16820739}, {429, 1}, {430, 16820995}, | 
782  |  |   {431, 16821251}, {432, 1}, {433, 16821507}, {434, 16821763}, | 
783  |  |   {435, 16822019}, {436, 1}, {437, 16822275}, {438, 1}, | 
784  |  |   {439, 16822531}, {440, 16822787}, {441, 1}, {444, 16823043}, | 
785  |  |   {445, 1}, {452, 33600515}, {455, 33601027}, {458, 33601539}, | 
786  |  |   {461, 16824835}, {462, 1}, {463, 16825091}, {464, 1}, | 
787  |  |   {465, 16825347}, {466, 1}, {467, 16825603}, {468, 1}, | 
788  |  |   {469, 16825859}, {470, 1}, {471, 16826115}, {472, 1}, | 
789  |  |   {473, 16826371}, {474, 1}, {475, 16826627}, {476, 1}, | 
790  |  |   {478, 16826883}, {479, 1}, {480, 16827139}, {481, 1}, | 
791  |  |   {482, 16827395}, {483, 1}, {484, 16827651}, {485, 1}, | 
792  |  |   {486, 16827907}, {487, 1}, {488, 16828163}, {489, 1}, | 
793  |  |   {490, 16828419}, {491, 1}, {492, 16828675}, {493, 1}, | 
794  |  |   {494, 16828931}, {495, 1}, {497, 33606403}, {500, 16829699}, | 
795  |  |   {501, 1}, {502, 16829955}, {503, 16830211}, {504, 16830467}, | 
796  |  |   {505, 1}, {506, 16830723}, {507, 1}, {508, 16830979}, | 
797  |  |   {509, 1}, {510, 16831235}, {511, 1}, {512, 16831491}, | 
798  |  |   {513, 1}, {514, 16831747}, {515, 1}, {516, 16832003}, | 
799  |  |   {517, 1}, {518, 16832259}, {519, 1}, {520, 16832515}, | 
800  |  |   {521, 1}, {522, 16832771}, {523, 1}, {524, 16833027}, | 
801  |  |   {525, 1}, {526, 16833283}, {527, 1}, {528, 16833539}, | 
802  |  |   {529, 1}, {530, 16833795}, {531, 1}, {532, 16834051}, | 
803  |  |   {533, 1}, {534, 16834307}, {535, 1}, {536, 16834563}, | 
804  |  |   {537, 1}, {538, 16834819}, {539, 1}, {540, 16835075}, | 
805  |  |   {541, 1}, {542, 16835331}, {543, 1}, {544, 16835587}, | 
806  |  |   {545, 1}, {546, 16835843}, {547, 1}, {548, 16836099}, | 
807  |  |   {549, 1}, {550, 16836355}, {551, 1}, {552, 16836611}, | 
808  |  |   {553, 1}, {554, 16836867}, {555, 1}, {556, 16837123}, | 
809  |  |   {557, 1}, {558, 16837379}, {559, 1}, {560, 16837635}, | 
810  |  |   {561, 1}, {562, 16837891}, {563, 1}, {570, 16838147}, | 
811  |  |   {571, 16838403}, {572, 1}, {573, 16838659}, {574, 16838915}, | 
812  |  |   {575, 1}, {577, 16839171}, {578, 1}, {579, 16839427}, | 
813  |  |   {580, 16839683}, {581, 16839939}, {582, 16840195}, {583, 1}, | 
814  |  |   {584, 16840451}, {585, 1}, {586, 16840707}, {587, 1}, | 
815  |  |   {588, 16840963}, {589, 1}, {590, 16841219}, {591, 1}, | 
816  |  |   {688, 16779011}, {689, 16841475}, {690, 16779523}, {691, 16781571}, | 
817  |  |   {692, 16841731}, {693, 16841987}, {694, 16842243}, {695, 16782851}, | 
818  |  |   {696, 16783363}, {697, 1}, {728, 33619715}, {729, 33620227}, | 
819  |  |   {730, 33620739}, {731, 33621251}, {732, 33621763}, {733, 33622275}, | 
820  |  |   {734, 1}, {736, 16817411}, {737, 16780035}, {738, 16781827}, | 
821  |  |   {739, 16783107}, {740, 16845571}, {741, 1}, {832, 16845827}, | 
822  |  |   {833, 16785923}, {834, 1}, {835, 16846083}, {836, 33623555}, | 
823  |  |   {837, 16846851}, {838, 1}, {847, 0}, {848, 1}, | 
824  |  |   {880, 16847107}, {881, 1}, {882, 16847363}, {883, 1}, | 
825  |  |   {884, 16847619}, {885, 1}, {886, 16847875}, {887, 1}, | 
826  |  |   {888, 2}, {890, 33625347}, {891, 1}, {894, 16848643}, | 
827  |  |   {895, 16848899}, {896, 2}, {900, 33562883}, {901, 50403587}, | 
828  |  |   {902, 16849923}, {903, 16805379}, {904, 16850179}, {905, 16850435}, | 
829  |  |   {906, 16850691}, {907, 2}, {908, 16850947}, {909, 2}, | 
830  |  |   {910, 16851203}, {911, 16851459}, {912, 1}, {913, 16851715}, | 
831  |  |   {914, 16851971}, {915, 16852227}, {916, 16852483}, {917, 16852739}, | 
832  |  |   {918, 16852995}, {919, 16853251}, {920, 16853507}, {921, 16846851}, | 
833  |  |   {922, 16853763}, {923, 16854019}, {924, 16786179}, {925, 16854275}, | 
834  |  |   {926, 16854531}, {927, 16854787}, {928, 16855043}, {929, 16855299}, | 
835  |  |   {930, 2}, {931, 16855555}, {932, 16855811}, {933, 16856067}, | 
836  |  |   {934, 16856323}, {935, 16856579}, {936, 16856835}, {937, 16857091}, | 
837  |  |   {938, 16857347}, {939, 16857603}, {940, 1}, {975, 16857859}, | 
838  |  |   {976, 16851971}, {977, 16853507}, {978, 16856067}, {979, 16851203}, | 
839  |  |   {980, 16857603}, {981, 16856323}, {982, 16855043}, {983, 1}, | 
840  |  |   {984, 16858115}, {985, 1}, {986, 16858371}, {987, 1}, | 
841  |  |   {988, 16858627}, {989, 1}, {990, 16858883}, {991, 1}, | 
842  |  |   {992, 16859139}, {993, 1}, {994, 16859395}, {995, 1}, | 
843  |  |   {996, 16859651}, {997, 1}, {998, 16859907}, {999, 1}, | 
844  |  |   {1000, 16860163}, {1001, 1}, {1002, 16860419}, {1003, 1}, | 
845  |  |   {1004, 16860675}, {1005, 1}, {1006, 16860931}, {1007, 1}, | 
846  |  |   {1008, 16853763}, {1009, 16855299}, {1010, 16855555}, {1011, 1}, | 
847  |  |   {1012, 16853507}, {1013, 16852739}, {1014, 1}, {1015, 16861187}, | 
848  |  |   {1016, 1}, {1017, 16855555}, {1018, 16861443}, {1019, 1}, | 
849  |  |   {1021, 16861699}, {1022, 16861955}, {1023, 16862211}, {1024, 16862467}, | 
850  |  |   {1025, 16862723}, {1026, 16862979}, {1027, 16863235}, {1028, 16863491}, | 
851  |  |   {1029, 16863747}, {1030, 16864003}, {1031, 16864259}, {1032, 16864515}, | 
852  |  |   {1033, 16864771}, {1034, 16865027}, {1035, 16865283}, {1036, 16865539}, | 
853  |  |   {1037, 16865795}, {1038, 16866051}, {1039, 16866307}, {1040, 16866563}, | 
854  |  |   {1041, 16866819}, {1042, 16867075}, {1043, 16867331}, {1044, 16867587}, | 
855  |  |   {1045, 16867843}, {1046, 16868099}, {1047, 16868355}, {1048, 16868611}, | 
856  |  |   {1049, 16868867}, {1050, 16869123}, {1051, 16869379}, {1052, 16869635}, | 
857  |  |   {1053, 16869891}, {1054, 16870147}, {1055, 16870403}, {1056, 16870659}, | 
858  |  |   {1057, 16870915}, {1058, 16871171}, {1059, 16871427}, {1060, 16871683}, | 
859  |  |   {1061, 16871939}, {1062, 16872195}, {1063, 16872451}, {1064, 16872707}, | 
860  |  |   {1065, 16872963}, {1066, 16873219}, {1067, 16873475}, {1068, 16873731}, | 
861  |  |   {1069, 16873987}, {1070, 16874243}, {1071, 16874499}, {1072, 1}, | 
862  |  |   {1120, 16874755}, {1121, 1}, {1122, 16875011}, {1123, 1}, | 
863  |  |   {1124, 16875267}, {1125, 1}, {1126, 16875523}, {1127, 1}, | 
864  |  |   {1128, 16875779}, {1129, 1}, {1130, 16876035}, {1131, 1}, | 
865  |  |   {1132, 16876291}, {1133, 1}, {1134, 16876547}, {1135, 1}, | 
866  |  |   {1136, 16876803}, {1137, 1}, {1138, 16877059}, {1139, 1}, | 
867  |  |   {1140, 16877315}, {1141, 1}, {1142, 16877571}, {1143, 1}, | 
868  |  |   {1144, 16877827}, {1145, 1}, {1146, 16878083}, {1147, 1}, | 
869  |  |   {1148, 16878339}, {1149, 1}, {1150, 16878595}, {1151, 1}, | 
870  |  |   {1152, 16878851}, {1153, 1}, {1162, 16879107}, {1163, 1}, | 
871  |  |   {1164, 16879363}, {1165, 1}, {1166, 16879619}, {1167, 1}, | 
872  |  |   {1168, 16879875}, {1169, 1}, {1170, 16880131}, {1171, 1}, | 
873  |  |   {1172, 16880387}, {1173, 1}, {1174, 16880643}, {1175, 1}, | 
874  |  |   {1176, 16880899}, {1177, 1}, {1178, 16881155}, {1179, 1}, | 
875  |  |   {1180, 16881411}, {1181, 1}, {1182, 16881667}, {1183, 1}, | 
876  |  |   {1184, 16881923}, {1185, 1}, {1186, 16882179}, {1187, 1}, | 
877  |  |   {1188, 16882435}, {1189, 1}, {1190, 16882691}, {1191, 1}, | 
878  |  |   {1192, 16882947}, {1193, 1}, {1194, 16883203}, {1195, 1}, | 
879  |  |   {1196, 16883459}, {1197, 1}, {1198, 16883715}, {1199, 1}, | 
880  |  |   {1200, 16883971}, {1201, 1}, {1202, 16884227}, {1203, 1}, | 
881  |  |   {1204, 16884483}, {1205, 1}, {1206, 16884739}, {1207, 1}, | 
882  |  |   {1208, 16884995}, {1209, 1}, {1210, 16885251}, {1211, 1}, | 
883  |  |   {1212, 16885507}, {1213, 1}, {1214, 16885763}, {1215, 1}, | 
884  |  |   {1216, 2}, {1217, 16886019}, {1218, 1}, {1219, 16886275}, | 
885  |  |   {1220, 1}, {1221, 16886531}, {1222, 1}, {1223, 16886787}, | 
886  |  |   {1224, 1}, {1225, 16887043}, {1226, 1}, {1227, 16887299}, | 
887  |  |   {1228, 1}, {1229, 16887555}, {1230, 1}, {1232, 16887811}, | 
888  |  |   {1233, 1}, {1234, 16888067}, {1235, 1}, {1236, 16888323}, | 
889  |  |   {1237, 1}, {1238, 16888579}, {1239, 1}, {1240, 16888835}, | 
890  |  |   {1241, 1}, {1242, 16889091}, {1243, 1}, {1244, 16889347}, | 
891  |  |   {1245, 1}, {1246, 16889603}, {1247, 1}, {1248, 16889859}, | 
892  |  |   {1249, 1}, {1250, 16890115}, {1251, 1}, {1252, 16890371}, | 
893  |  |   {1253, 1}, {1254, 16890627}, {1255, 1}, {1256, 16890883}, | 
894  |  |   {1257, 1}, {1258, 16891139}, {1259, 1}, {1260, 16891395}, | 
895  |  |   {1261, 1}, {1262, 16891651}, {1263, 1}, {1264, 16891907}, | 
896  |  |   {1265, 1}, {1266, 16892163}, {1267, 1}, {1268, 16892419}, | 
897  |  |   {1269, 1}, {1270, 16892675}, {1271, 1}, {1272, 16892931}, | 
898  |  |   {1273, 1}, {1274, 16893187}, {1275, 1}, {1276, 16893443}, | 
899  |  |   {1277, 1}, {1278, 16893699}, {1279, 1}, {1280, 16893955}, | 
900  |  |   {1281, 1}, {1282, 16894211}, {1283, 1}, {1284, 16894467}, | 
901  |  |   {1285, 1}, {1286, 16894723}, {1287, 1}, {1288, 16894979}, | 
902  |  |   {1289, 1}, {1290, 16895235}, {1291, 1}, {1292, 16895491}, | 
903  |  |   {1293, 1}, {1294, 16895747}, {1295, 1}, {1296, 16896003}, | 
904  |  |   {1297, 1}, {1298, 16896259}, {1299, 1}, {1300, 16896515}, | 
905  |  |   {1301, 1}, {1302, 16896771}, {1303, 1}, {1304, 16897027}, | 
906  |  |   {1305, 1}, {1306, 16897283}, {1307, 1}, {1308, 16897539}, | 
907  |  |   {1309, 1}, {1310, 16897795}, {1311, 1}, {1312, 16898051}, | 
908  |  |   {1313, 1}, {1314, 16898307}, {1315, 1}, {1316, 16898563}, | 
909  |  |   {1317, 1}, {1318, 16898819}, {1319, 1}, {1320, 16899075}, | 
910  |  |   {1321, 1}, {1322, 16899331}, {1323, 1}, {1324, 16899587}, | 
911  |  |   {1325, 1}, {1326, 16899843}, {1327, 1}, {1328, 2}, | 
912  |  |   {1329, 16900099}, {1330, 16900355}, {1331, 16900611}, {1332, 16900867}, | 
913  |  |   {1333, 16901123}, {1334, 16901379}, {1335, 16901635}, {1336, 16901891}, | 
914  |  |   {1337, 16902147}, {1338, 16902403}, {1339, 16902659}, {1340, 16902915}, | 
915  |  |   {1341, 16903171}, {1342, 16903427}, {1343, 16903683}, {1344, 16903939}, | 
916  |  |   {1345, 16904195}, {1346, 16904451}, {1347, 16904707}, {1348, 16904963}, | 
917  |  |   {1349, 16905219}, {1350, 16905475}, {1351, 16905731}, {1352, 16905987}, | 
918  |  |   {1353, 16906243}, {1354, 16906499}, {1355, 16906755}, {1356, 16907011}, | 
919  |  |   {1357, 16907267}, {1358, 16907523}, {1359, 16907779}, {1360, 16908035}, | 
920  |  |   {1361, 16908291}, {1362, 16908547}, {1363, 16908803}, {1364, 16909059}, | 
921  |  |   {1365, 16909315}, {1366, 16909571}, {1367, 2}, {1369, 1}, | 
922  |  |   {1415, 33687043}, {1416, 1}, {1419, 2}, {1421, 1}, | 
923  |  |   {1424, 2}, {1425, 1}, {1480, 2}, {1488, 1}, | 
924  |  |   {1515, 2}, {1519, 1}, {1525, 2}, {1542, 1}, | 
925  |  |   {1564, 2}, {1565, 1}, {1653, 33687555}, {1654, 33688067}, | 
926  |  |   {1655, 33688579}, {1656, 33689091}, {1657, 1}, {1757, 2}, | 
927  |  |   {1758, 1}, {1806, 2}, {1808, 1}, {1867, 2}, | 
928  |  |   {1869, 1}, {1970, 2}, {1984, 1}, {2043, 2}, | 
929  |  |   {2045, 1}, {2094, 2}, {2096, 1}, {2111, 2}, | 
930  |  |   {2112, 1}, {2140, 2}, {2142, 1}, {2143, 2}, | 
931  |  |   {2144, 1}, {2155, 2}, {2160, 1}, {2191, 2}, | 
932  |  |   {2200, 1}, {2274, 2}, {2275, 1}, {2392, 33689603}, | 
933  |  |   {2393, 33690115}, {2394, 33690627}, {2395, 33691139}, {2396, 33691651}, | 
934  |  |   {2397, 33692163}, {2398, 33692675}, {2399, 33693187}, {2400, 1}, | 
935  |  |   {2436, 2}, {2437, 1}, {2445, 2}, {2447, 1}, | 
936  |  |   {2449, 2}, {2451, 1}, {2473, 2}, {2474, 1}, | 
937  |  |   {2481, 2}, {2482, 1}, {2483, 2}, {2486, 1}, | 
938  |  |   {2490, 2}, {2492, 1}, {2501, 2}, {2503, 1}, | 
939  |  |   {2505, 2}, {2507, 1}, {2511, 2}, {2519, 1}, | 
940  |  |   {2520, 2}, {2524, 33693699}, {2525, 33694211}, {2526, 2}, | 
941  |  |   {2527, 33694723}, {2528, 1}, {2532, 2}, {2534, 1}, | 
942  |  |   {2559, 2}, {2561, 1}, {2564, 2}, {2565, 1}, | 
943  |  |   {2571, 2}, {2575, 1}, {2577, 2}, {2579, 1}, | 
944  |  |   {2601, 2}, {2602, 1}, {2609, 2}, {2610, 1}, | 
945  |  |   {2611, 33695235}, {2612, 2}, {2613, 1}, {2614, 33695747}, | 
946  |  |   {2615, 2}, {2616, 1}, {2618, 2}, {2620, 1}, | 
947  |  |   {2621, 2}, {2622, 1}, {2627, 2}, {2631, 1}, | 
948  |  |   {2633, 2}, {2635, 1}, {2638, 2}, {2641, 1}, | 
949  |  |   {2642, 2}, {2649, 33696259}, {2650, 33696771}, {2651, 33697283}, | 
950  |  |   {2652, 1}, {2653, 2}, {2654, 33697795}, {2655, 2}, | 
951  |  |   {2662, 1}, {2679, 2}, {2689, 1}, {2692, 2}, | 
952  |  |   {2693, 1}, {2702, 2}, {2703, 1}, {2706, 2}, | 
953  |  |   {2707, 1}, {2729, 2}, {2730, 1}, {2737, 2}, | 
954  |  |   {2738, 1}, {2740, 2}, {2741, 1}, {2746, 2}, | 
955  |  |   {2748, 1}, {2758, 2}, {2759, 1}, {2762, 2}, | 
956  |  |   {2763, 1}, {2766, 2}, {2768, 1}, {2769, 2}, | 
957  |  |   {2784, 1}, {2788, 2}, {2790, 1}, {2802, 2}, | 
958  |  |   {2809, 1}, {2816, 2}, {2817, 1}, {2820, 2}, | 
959  |  |   {2821, 1}, {2829, 2}, {2831, 1}, {2833, 2}, | 
960  |  |   {2835, 1}, {2857, 2}, {2858, 1}, {2865, 2}, | 
961  |  |   {2866, 1}, {2868, 2}, {2869, 1}, {2874, 2}, | 
962  |  |   {2876, 1}, {2885, 2}, {2887, 1}, {2889, 2}, | 
963  |  |   {2891, 1}, {2894, 2}, {2901, 1}, {2904, 2}, | 
964  |  |   {2908, 33698307}, {2909, 33698819}, {2910, 2}, {2911, 1}, | 
965  |  |   {2916, 2}, {2918, 1}, {2936, 2}, {2946, 1}, | 
966  |  |   {2948, 2}, {2949, 1}, {2955, 2}, {2958, 1}, | 
967  |  |   {2961, 2}, {2962, 1}, {2966, 2}, {2969, 1}, | 
968  |  |   {2971, 2}, {2972, 1}, {2973, 2}, {2974, 1}, | 
969  |  |   {2976, 2}, {2979, 1}, {2981, 2}, {2984, 1}, | 
970  |  |   {2987, 2}, {2990, 1}, {3002, 2}, {3006, 1}, | 
971  |  |   {3011, 2}, {3014, 1}, {3017, 2}, {3018, 1}, | 
972  |  |   {3022, 2}, {3024, 1}, {3025, 2}, {3031, 1}, | 
973  |  |   {3032, 2}, {3046, 1}, {3067, 2}, {3072, 1}, | 
974  |  |   {3085, 2}, {3086, 1}, {3089, 2}, {3090, 1}, | 
975  |  |   {3113, 2}, {3114, 1}, {3130, 2}, {3132, 1}, | 
976  |  |   {3141, 2}, {3142, 1}, {3145, 2}, {3146, 1}, | 
977  |  |   {3150, 2}, {3157, 1}, {3159, 2}, {3160, 1}, | 
978  |  |   {3163, 2}, {3165, 1}, {3166, 2}, {3168, 1}, | 
979  |  |   {3172, 2}, {3174, 1}, {3184, 2}, {3191, 1}, | 
980  |  |   {3213, 2}, {3214, 1}, {3217, 2}, {3218, 1}, | 
981  |  |   {3241, 2}, {3242, 1}, {3252, 2}, {3253, 1}, | 
982  |  |   {3258, 2}, {3260, 1}, {3269, 2}, {3270, 1}, | 
983  |  |   {3273, 2}, {3274, 1}, {3278, 2}, {3285, 1}, | 
984  |  |   {3287, 2}, {3293, 1}, {3295, 2}, {3296, 1}, | 
985  |  |   {3300, 2}, {3302, 1}, {3312, 2}, {3313, 1}, | 
986  |  |   {3316, 2}, {3328, 1}, {3341, 2}, {3342, 1}, | 
987  |  |   {3345, 2}, {3346, 1}, {3397, 2}, {3398, 1}, | 
988  |  |   {3401, 2}, {3402, 1}, {3408, 2}, {3412, 1}, | 
989  |  |   {3428, 2}, {3430, 1}, {3456, 2}, {3457, 1}, | 
990  |  |   {3460, 2}, {3461, 1}, {3479, 2}, {3482, 1}, | 
991  |  |   {3506, 2}, {3507, 1}, {3516, 2}, {3517, 1}, | 
992  |  |   {3518, 2}, {3520, 1}, {3527, 2}, {3530, 1}, | 
993  |  |   {3531, 2}, {3535, 1}, {3541, 2}, {3542, 1}, | 
994  |  |   {3543, 2}, {3544, 1}, {3552, 2}, {3558, 1}, | 
995  |  |   {3568, 2}, {3570, 1}, {3573, 2}, {3585, 1}, | 
996  |  |   {3635, 33699331}, {3636, 1}, {3643, 2}, {3647, 1}, | 
997  |  |   {3676, 2}, {3713, 1}, {3715, 2}, {3716, 1}, | 
998  |  |   {3717, 2}, {3718, 1}, {3723, 2}, {3724, 1}, | 
999  |  |   {3748, 2}, {3749, 1}, {3750, 2}, {3751, 1}, | 
1000  |  |   {3763, 33699843}, {3764, 1}, {3774, 2}, {3776, 1}, | 
1001  |  |   {3781, 2}, {3782, 1}, {3783, 2}, {3784, 1}, | 
1002  |  |   {3791, 2}, {3792, 1}, {3802, 2}, {3804, 33700355}, | 
1003  |  |   {3805, 33700867}, {3806, 1}, {3808, 2}, {3840, 1}, | 
1004  |  |   {3852, 16924163}, {3853, 1}, {3907, 33701635}, {3908, 1}, | 
1005  |  |   {3912, 2}, {3913, 1}, {3917, 33702147}, {3918, 1}, | 
1006  |  |   {3922, 33702659}, {3923, 1}, {3927, 33703171}, {3928, 1}, | 
1007  |  |   {3932, 33703683}, {3933, 1}, {3945, 33704195}, {3946, 1}, | 
1008  |  |   {3949, 2}, {3953, 1}, {3955, 33704707}, {3956, 1}, | 
1009  |  |   {3957, 33705219}, {3958, 33705731}, {3959, 50483459}, {3960, 33707011}, | 
1010  |  |   {3961, 50484739}, {3962, 1}, {3969, 33706499}, {3970, 1}, | 
1011  |  |   {3987, 33708291}, {3988, 1}, {3992, 2}, {3993, 1}, | 
1012  |  |   {3997, 33708803}, {3998, 1}, {4002, 33709315}, {4003, 1}, | 
1013  |  |   {4007, 33709827}, {4008, 1}, {4012, 33710339}, {4013, 1}, | 
1014  |  |   {4025, 33710851}, {4026, 1}, {4029, 2}, {4030, 1}, | 
1015  |  |   {4045, 2}, {4046, 1}, {4059, 2}, {4096, 1}, | 
1016  |  |   {4256, 2}, {4295, 16934147}, {4296, 2}, {4301, 16934403}, | 
1017  |  |   {4302, 2}, {4304, 1}, {4348, 16934659}, {4349, 1}, | 
1018  |  |   {4447, 2}, {4449, 1}, {4681, 2}, {4682, 1}, | 
1019  |  |   {4686, 2}, {4688, 1}, {4695, 2}, {4696, 1}, | 
1020  |  |   {4697, 2}, {4698, 1}, {4702, 2}, {4704, 1}, | 
1021  |  |   {4745, 2}, {4746, 1}, {4750, 2}, {4752, 1}, | 
1022  |  |   {4785, 2}, {4786, 1}, {4790, 2}, {4792, 1}, | 
1023  |  |   {4799, 2}, {4800, 1}, {4801, 2}, {4802, 1}, | 
1024  |  |   {4806, 2}, {4808, 1}, {4823, 2}, {4824, 1}, | 
1025  |  |   {4881, 2}, {4882, 1}, {4886, 2}, {4888, 1}, | 
1026  |  |   {4955, 2}, {4957, 1}, {4989, 2}, {4992, 1}, | 
1027  |  |   {5018, 2}, {5024, 1}, {5110, 2}, {5112, 16934915}, | 
1028  |  |   {5113, 16935171}, {5114, 16935427}, {5115, 16935683}, {5116, 16935939}, | 
1029  |  |   {5117, 16936195}, {5118, 2}, {5120, 1}, {5760, 2}, | 
1030  |  |   {5761, 1}, {5789, 2}, {5792, 1}, {5881, 2}, | 
1031  |  |   {5888, 1}, {5910, 2}, {5919, 1}, {5943, 2}, | 
1032  |  |   {5952, 1}, {5972, 2}, {5984, 1}, {5997, 2}, | 
1033  |  |   {5998, 1}, {6001, 2}, {6002, 1}, {6004, 2}, | 
1034  |  |   {6016, 1}, {6068, 2}, {6070, 1}, {6110, 2}, | 
1035  |  |   {6112, 1}, {6122, 2}, {6128, 1}, {6138, 2}, | 
1036  |  |   {6144, 1}, {6150, 2}, {6151, 1}, {6155, 0}, | 
1037  |  |   {6158, 2}, {6159, 0}, {6160, 1}, {6170, 2}, | 
1038  |  |   {6176, 1}, {6265, 2}, {6272, 1}, {6315, 2}, | 
1039  |  |   {6320, 1}, {6390, 2}, {6400, 1}, {6431, 2}, | 
1040  |  |   {6432, 1}, {6444, 2}, {6448, 1}, {6460, 2}, | 
1041  |  |   {6464, 1}, {6465, 2}, {6468, 1}, {6510, 2}, | 
1042  |  |   {6512, 1}, {6517, 2}, {6528, 1}, {6572, 2}, | 
1043  |  |   {6576, 1}, {6602, 2}, {6608, 1}, {6619, 2}, | 
1044  |  |   {6622, 1}, {6684, 2}, {6686, 1}, {6751, 2}, | 
1045  |  |   {6752, 1}, {6781, 2}, {6783, 1}, {6794, 2}, | 
1046  |  |   {6800, 1}, {6810, 2}, {6816, 1}, {6830, 2}, | 
1047  |  |   {6832, 1}, {6863, 2}, {6912, 1}, {6989, 2}, | 
1048  |  |   {6992, 1}, {7039, 2}, {7040, 1}, {7156, 2}, | 
1049  |  |   {7164, 1}, {7224, 2}, {7227, 1}, {7242, 2}, | 
1050  |  |   {7245, 1}, {7296, 16867075}, {7297, 16867587}, {7298, 16870147}, | 
1051  |  |   {7299, 16870915}, {7300, 16871171}, {7302, 16873219}, {7303, 16875011}, | 
1052  |  |   {7304, 16936451}, {7305, 2}, {7312, 16936707}, {7313, 16936963}, | 
1053  |  |   {7314, 16937219}, {7315, 16937475}, {7316, 16937731}, {7317, 16937987}, | 
1054  |  |   {7318, 16938243}, {7319, 16938499}, {7320, 16938755}, {7321, 16939011}, | 
1055  |  |   {7322, 16939267}, {7323, 16939523}, {7324, 16934659}, {7325, 16939779}, | 
1056  |  |   {7326, 16940035}, {7327, 16940291}, {7328, 16940547}, {7329, 16940803}, | 
1057  |  |   {7330, 16941059}, {7331, 16941315}, {7332, 16941571}, {7333, 16941827}, | 
1058  |  |   {7334, 16942083}, {7335, 16942339}, {7336, 16942595}, {7337, 16942851}, | 
1059  |  |   {7338, 16943107}, {7339, 16943363}, {7340, 16943619}, {7341, 16943875}, | 
1060  |  |   {7342, 16944131}, {7343, 16944387}, {7344, 16944643}, {7345, 16944899}, | 
1061  |  |   {7346, 16945155}, {7347, 16945411}, {7348, 16945667}, {7349, 16945923}, | 
1062  |  |   {7350, 16946179}, {7351, 16946435}, {7352, 16946691}, {7353, 16946947}, | 
1063  |  |   {7354, 16947203}, {7355, 2}, {7357, 16947459}, {7358, 16947715}, | 
1064  |  |   {7359, 16947971}, {7360, 1}, {7368, 2}, {7376, 1}, | 
1065  |  |   {7419, 2}, {7424, 1}, {7468, 16777219}, {7469, 16791043}, | 
1066  |  |   {7470, 16777475}, {7471, 1}, {7472, 16777987}, {7473, 16778243}, | 
1067  |  |   {7474, 16816131}, {7475, 16778755}, {7476, 16779011}, {7477, 16779267}, | 
1068  |  |   {7478, 16779523}, {7479, 16779779}, {7480, 16780035}, {7481, 16780291}, | 
1069  |  |   {7482, 16780547}, {7483, 1}, {7484, 16780803}, {7485, 16835843}, | 
1070  |  |   {7486, 16781059}, {7487, 16781571}, {7488, 16782083}, {7489, 16782339}, | 
1071  |  |   {7490, 16782851}, {7491, 16777219}, {7492, 16948227}, {7493, 16948483}, | 
1072  |  |   {7494, 16948739}, {7495, 16777475}, {7496, 16777987}, {7497, 16778243}, | 
1073  |  |   {7498, 16816387}, {7499, 16816643}, {7500, 16948995}, {7501, 16778755}, | 
1074  |  |   {7502, 1}, {7503, 16779779}, {7504, 16780291}, {7505, 16807171}, | 
1075  |  |   {7506, 16780803}, {7507, 16814851}, {7508, 16949251}, {7509, 16949507}, | 
1076  |  |   {7510, 16781059}, {7511, 16782083}, {7512, 16782339}, {7513, 16949763}, | 
1077  |  |   {7514, 16818435}, {7515, 16782595}, {7516, 16950019}, {7517, 16851971}, | 
1078  |  |   {7518, 16852227}, {7519, 16852483}, {7520, 16856323}, {7521, 16856579}, | 
1079  |  |   {7522, 16779267}, {7523, 16781571}, {7524, 16782339}, {7525, 16782595}, | 
1080  |  |   {7526, 16851971}, {7527, 16852227}, {7528, 16855299}, {7529, 16856323}, | 
1081  |  |   {7530, 16856579}, {7531, 1}, {7544, 16869891}, {7545, 1}, | 
1082  |  |   {7579, 16950275}, {7580, 16777731}, {7581, 16950531}, {7582, 16793603}, | 
1083  |  |   {7583, 16948995}, {7584, 16778499}, {7585, 16950787}, {7586, 16951043}, | 
1084  |  |   {7587, 16951299}, {7588, 16817923}, {7589, 16817667}, {7590, 16951555}, | 
1085  |  |   {7591, 16951811}, {7592, 16952067}, {7593, 16952323}, {7594, 16952579}, | 
1086  |  |   {7595, 16952835}, {7596, 16953091}, {7597, 16953347}, {7598, 16818691}, | 
1087  |  |   {7599, 16953603}, {7600, 16953859}, {7601, 16818947}, {7602, 16954115}, | 
1088  |  |   {7603, 16954371}, {7604, 16820483}, {7605, 16954627}, {7606, 16839683}, | 
1089  |  |   {7607, 16821507}, {7608, 16954883}, {7609, 16821763}, {7610, 16839939}, | 
1090  |  |   {7611, 16783619}, {7612, 16955139}, {7613, 16955395}, {7614, 16822531}, | 
1091  |  |   {7615, 16853507}, {7616, 1}, {7680, 16955651}, {7681, 1}, | 
1092  |  |   {7682, 16955907}, {7683, 1}, {7684, 16956163}, {7685, 1}, | 
1093  |  |   {7686, 16956419}, {7687, 1}, {7688, 16956675}, {7689, 1}, | 
1094  |  |   {7690, 16956931}, {7691, 1}, {7692, 16957187}, {7693, 1}, | 
1095  |  |   {7694, 16957443}, {7695, 1}, {7696, 16957699}, {7697, 1}, | 
1096  |  |   {7698, 16957955}, {7699, 1}, {7700, 16958211}, {7701, 1}, | 
1097  |  |   {7702, 16958467}, {7703, 1}, {7704, 16958723}, {7705, 1}, | 
1098  |  |   {7706, 16958979}, {7707, 1}, {7708, 16959235}, {7709, 1}, | 
1099  |  |   {7710, 16959491}, {7711, 1}, {7712, 16959747}, {7713, 1}, | 
1100  |  |   {7714, 16960003}, {7715, 1}, {7716, 16960259}, {7717, 1}, | 
1101  |  |   {7718, 16960515}, {7719, 1}, {7720, 16960771}, {7721, 1}, | 
1102  |  |   {7722, 16961027}, {7723, 1}, {7724, 16961283}, {7725, 1}, | 
1103  |  |   {7726, 16961539}, {7727, 1}, {7728, 16961795}, {7729, 1}, | 
1104  |  |   {7730, 16962051}, {7731, 1}, {7732, 16962307}, {7733, 1}, | 
1105  |  |   {7734, 16962563}, {7735, 1}, {7736, 16962819}, {7737, 1}, | 
1106  |  |   {7738, 16963075}, {7739, 1}, {7740, 16963331}, {7741, 1}, | 
1107  |  |   {7742, 16963587}, {7743, 1}, {7744, 16963843}, {7745, 1}, | 
1108  |  |   {7746, 16964099}, {7747, 1}, {7748, 16964355}, {7749, 1}, | 
1109  |  |   {7750, 16964611}, {7751, 1}, {7752, 16964867}, {7753, 1}, | 
1110  |  |   {7754, 16965123}, {7755, 1}, {7756, 16965379}, {7757, 1}, | 
1111  |  |   {7758, 16965635}, {7759, 1}, {7760, 16965891}, {7761, 1}, | 
1112  |  |   {7762, 16966147}, {7763, 1}, {7764, 16966403}, {7765, 1}, | 
1113  |  |   {7766, 16966659}, {7767, 1}, {7768, 16966915}, {7769, 1}, | 
1114  |  |   {7770, 16967171}, {7771, 1}, {7772, 16967427}, {7773, 1}, | 
1115  |  |   {7774, 16967683}, {7775, 1}, {7776, 16967939}, {7777, 1}, | 
1116  |  |   {7778, 16968195}, {7779, 1}, {7780, 16968451}, {7781, 1}, | 
1117  |  |   {7782, 16968707}, {7783, 1}, {7784, 16968963}, {7785, 1}, | 
1118  |  |   {7786, 16969219}, {7787, 1}, {7788, 16969475}, {7789, 1}, | 
1119  |  |   {7790, 16969731}, {7791, 1}, {7792, 16969987}, {7793, 1}, | 
1120  |  |   {7794, 16970243}, {7795, 1}, {7796, 16970499}, {7797, 1}, | 
1121  |  |   {7798, 16970755}, {7799, 1}, {7800, 16971011}, {7801, 1}, | 
1122  |  |   {7802, 16971267}, {7803, 1}, {7804, 16971523}, {7805, 1}, | 
1123  |  |   {7806, 16971779}, {7807, 1}, {7808, 16972035}, {7809, 1}, | 
1124  |  |   {7810, 16972291}, {7811, 1}, {7812, 16972547}, {7813, 1}, | 
1125  |  |   {7814, 16972803}, {7815, 1}, {7816, 16973059}, {7817, 1}, | 
1126  |  |   {7818, 16973315}, {7819, 1}, {7820, 16973571}, {7821, 1}, | 
1127  |  |   {7822, 16973827}, {7823, 1}, {7824, 16974083}, {7825, 1}, | 
1128  |  |   {7826, 16974339}, {7827, 1}, {7828, 16974595}, {7829, 1}, | 
1129  |  |   {7834, 33752067}, {7835, 16967939}, {7836, 1}, {7838, 33752579}, | 
1130  |  |   {7839, 1}, {7840, 16975875}, {7841, 1}, {7842, 16976131}, | 
1131  |  |   {7843, 1}, {7844, 16976387}, {7845, 1}, {7846, 16976643}, | 
1132  |  |   {7847, 1}, {7848, 16976899}, {7849, 1}, {7850, 16977155}, | 
1133  |  |   {7851, 1}, {7852, 16977411}, {7853, 1}, {7854, 16977667}, | 
1134  |  |   {7855, 1}, {7856, 16977923}, {7857, 1}, {7858, 16978179}, | 
1135  |  |   {7859, 1}, {7860, 16978435}, {7861, 1}, {7862, 16978691}, | 
1136  |  |   {7863, 1}, {7864, 16978947}, {7865, 1}, {7866, 16979203}, | 
1137  |  |   {7867, 1}, {7868, 16979459}, {7869, 1}, {7870, 16979715}, | 
1138  |  |   {7871, 1}, {7872, 16979971}, {7873, 1}, {7874, 16980227}, | 
1139  |  |   {7875, 1}, {7876, 16980483}, {7877, 1}, {7878, 16980739}, | 
1140  |  |   {7879, 1}, {7880, 16980995}, {7881, 1}, {7882, 16981251}, | 
1141  |  |   {7883, 1}, {7884, 16981507}, {7885, 1}, {7886, 16981763}, | 
1142  |  |   {7887, 1}, {7888, 16982019}, {7889, 1}, {7890, 16982275}, | 
1143  |  |   {7891, 1}, {7892, 16982531}, {7893, 1}, {7894, 16982787}, | 
1144  |  |   {7895, 1}, {7896, 16983043}, {7897, 1}, {7898, 16983299}, | 
1145  |  |   {7899, 1}, {7900, 16983555}, {7901, 1}, {7902, 16983811}, | 
1146  |  |   {7903, 1}, {7904, 16984067}, {7905, 1}, {7906, 16984323}, | 
1147  |  |   {7907, 1}, {7908, 16984579}, {7909, 1}, {7910, 16984835}, | 
1148  |  |   {7911, 1}, {7912, 16985091}, {7913, 1}, {7914, 16985347}, | 
1149  |  |   {7915, 1}, {7916, 16985603}, {7917, 1}, {7918, 16985859}, | 
1150  |  |   {7919, 1}, {7920, 16986115}, {7921, 1}, {7922, 16986371}, | 
1151  |  |   {7923, 1}, {7924, 16986627}, {7925, 1}, {7926, 16986883}, | 
1152  |  |   {7927, 1}, {7928, 16987139}, {7929, 1}, {7930, 16987395}, | 
1153  |  |   {7931, 1}, {7932, 16987651}, {7933, 1}, {7934, 16987907}, | 
1154  |  |   {7935, 1}, {7944, 16988163}, {7945, 16988419}, {7946, 16988675}, | 
1155  |  |   {7947, 16988931}, {7948, 16989187}, {7949, 16989443}, {7950, 16989699}, | 
1156  |  |   {7951, 16989955}, {7952, 1}, {7958, 2}, {7960, 16990211}, | 
1157  |  |   {7961, 16990467}, {7962, 16990723}, {7963, 16990979}, {7964, 16991235}, | 
1158  |  |   {7965, 16991491}, {7966, 2}, {7968, 1}, {7976, 16991747}, | 
1159  |  |   {7977, 16992003}, {7978, 16992259}, {7979, 16992515}, {7980, 16992771}, | 
1160  |  |   {7981, 16993027}, {7982, 16993283}, {7983, 16993539}, {7984, 1}, | 
1161  |  |   {7992, 16993795}, {7993, 16994051}, {7994, 16994307}, {7995, 16994563}, | 
1162  |  |   {7996, 16994819}, {7997, 16995075}, {7998, 16995331}, {7999, 16995587}, | 
1163  |  |   {8000, 1}, {8006, 2}, {8008, 16995843}, {8009, 16996099}, | 
1164  |  |   {8010, 16996355}, {8011, 16996611}, {8012, 16996867}, {8013, 16997123}, | 
1165  |  |   {8014, 2}, {8016, 1}, {8024, 2}, {8025, 16997379}, | 
1166  |  |   {8026, 2}, {8027, 16997635}, {8028, 2}, {8029, 16997891}, | 
1167  |  |   {8030, 2}, {8031, 16998147}, {8032, 1}, {8040, 16998403}, | 
1168  |  |   {8041, 16998659}, {8042, 16998915}, {8043, 16999171}, {8044, 16999427}, | 
1169  |  |   {8045, 16999683}, {8046, 16999939}, {8047, 17000195}, {8048, 1}, | 
1170  |  |   {8049, 16849923}, {8050, 1}, {8051, 16850179}, {8052, 1}, | 
1171  |  |   {8053, 16850435}, {8054, 1}, {8055, 16850691}, {8056, 1}, | 
1172  |  |   {8057, 16850947}, {8058, 1}, {8059, 16851203}, {8060, 1}, | 
1173  |  |   {8061, 16851459}, {8062, 2}, {8064, 33777667}, {8065, 33778179}, | 
1174  |  |   {8066, 33778691}, {8067, 33779203}, {8068, 33779715}, {8069, 33780227}, | 
1175  |  |   {8070, 33780739}, {8071, 33781251}, {8072, 33777667}, {8073, 33778179}, | 
1176  |  |   {8074, 33778691}, {8075, 33779203}, {8076, 33779715}, {8077, 33780227}, | 
1177  |  |   {8078, 33780739}, {8079, 33781251}, {8080, 33781763}, {8081, 33782275}, | 
1178  |  |   {8082, 33782787}, {8083, 33783299}, {8084, 33783811}, {8085, 33784323}, | 
1179  |  |   {8086, 33784835}, {8087, 33785347}, {8088, 33781763}, {8089, 33782275}, | 
1180  |  |   {8090, 33782787}, {8091, 33783299}, {8092, 33783811}, {8093, 33784323}, | 
1181  |  |   {8094, 33784835}, {8095, 33785347}, {8096, 33785859}, {8097, 33786371}, | 
1182  |  |   {8098, 33786883}, {8099, 33787395}, {8100, 33787907}, {8101, 33788419}, | 
1183  |  |   {8102, 33788931}, {8103, 33789443}, {8104, 33785859}, {8105, 33786371}, | 
1184  |  |   {8106, 33786883}, {8107, 33787395}, {8108, 33787907}, {8109, 33788419}, | 
1185  |  |   {8110, 33788931}, {8111, 33789443}, {8112, 1}, {8114, 33789955}, | 
1186  |  |   {8115, 33790467}, {8116, 33790979}, {8117, 2}, {8118, 1}, | 
1187  |  |   {8119, 33791491}, {8120, 17014787}, {8121, 17015043}, {8122, 17012739}, | 
1188  |  |   {8123, 16849923}, {8124, 33790467}, {8125, 33792515}, {8126, 16846851}, | 
1189  |  |   {8127, 33792515}, {8128, 33793027}, {8129, 50570755}, {8130, 33794307}, | 
1190  |  |   {8131, 33794819}, {8132, 33795331}, {8133, 2}, {8134, 1}, | 
1191  |  |   {8135, 33795843}, {8136, 17019139}, {8137, 16850179}, {8138, 17017091}, | 
1192  |  |   {8139, 16850435}, {8140, 33794819}, {8141, 50573827}, {8142, 50574595}, | 
1193  |  |   {8143, 50575363}, {8144, 1}, {8147, 17021699}, {8148, 2}, | 
1194  |  |   {8150, 1}, {8152, 17021955}, {8153, 17022211}, {8154, 17022467}, | 
1195  |  |   {8155, 16850691}, {8156, 2}, {8157, 50577155}, {8158, 50577923}, | 
1196  |  |   {8159, 50578691}, {8160, 1}, {8163, 17025027}, {8164, 1}, | 
1197  |  |   {8168, 17025283}, {8169, 17025539}, {8170, 17025795}, {8171, 16851203}, | 
1198  |  |   {8172, 17026051}, {8173, 50580739}, {8174, 50403587}, {8175, 17027075}, | 
1199  |  |   {8176, 2}, {8178, 33804547}, {8179, 33805059}, {8180, 33805571}, | 
1200  |  |   {8181, 2}, {8182, 1}, {8183, 33806083}, {8184, 17029379}, | 
1201  |  |   {8185, 16850947}, {8186, 17027331}, {8187, 16851459}, {8188, 33805059}, | 
1202  |  |   {8189, 33562883}, {8190, 33799939}, {8191, 2}, {8192, 16783875}, | 
1203  |  |   {8203, 0}, {8204, 1}, {8206, 2}, {8208, 1}, | 
1204  |  |   {8209, 17029635}, {8210, 1}, {8215, 33807107}, {8216, 1}, | 
1205  |  |   {8228, 2}, {8231, 1}, {8232, 2}, {8239, 16783875}, | 
1206  |  |   {8240, 1}, {8243, 33807619}, {8244, 50585347}, {8245, 1}, | 
1207  |  |   {8246, 33808899}, {8247, 50586627}, {8248, 1}, {8252, 33810179}, | 
1208  |  |   {8253, 1}, {8254, 33810691}, {8255, 1}, {8263, 33811203}, | 
1209  |  |   {8264, 33811715}, {8265, 33812227}, {8266, 1}, {8279, 67362051}, | 
1210  |  |   {8280, 1}, {8287, 16783875}, {8288, 0}, {8289, 2}, | 
1211  |  |   {8292, 0}, {8293, 2}, {8304, 17035523}, {8305, 16779267}, | 
1212  |  |   {8306, 2}, {8308, 16787715}, {8309, 17035779}, {8310, 17036035}, | 
1213  |  |   {8311, 17036291}, {8312, 17036547}, {8313, 17036803}, {8314, 17037059}, | 
1214  |  |   {8315, 17037315}, {8316, 17037571}, {8317, 17037827}, {8318, 17038083}, | 
1215  |  |   {8319, 16780547}, {8320, 17035523}, {8321, 16786947}, {8322, 16785155}, | 
1216  |  |   {8323, 16785411}, {8324, 16787715}, {8325, 17035779}, {8326, 17036035}, | 
1217  |  |   {8327, 17036291}, {8328, 17036547}, {8329, 17036803}, {8330, 17037059}, | 
1218  |  |   {8331, 17037315}, {8332, 17037571}, {8333, 17037827}, {8334, 17038083}, | 
1219  |  |   {8335, 2}, {8336, 16777219}, {8337, 16778243}, {8338, 16780803}, | 
1220  |  |   {8339, 16783107}, {8340, 16816387}, {8341, 16779011}, {8342, 16779779}, | 
1221  |  |   {8343, 16780035}, {8344, 16780291}, {8345, 16780547}, {8346, 16781059}, | 
1222  |  |   {8347, 16781827}, {8348, 16782083}, {8349, 2}, {8352, 1}, | 
1223  |  |   {8360, 33558787}, {8361, 1}, {8385, 2}, {8400, 1}, | 
1224  |  |   {8433, 2}, {8448, 50592771}, {8449, 50593539}, {8450, 16777731}, | 
1225  |  |   {8451, 33817091}, {8452, 1}, {8453, 50594819}, {8454, 50595587}, | 
1226  |  |   {8455, 16816643}, {8456, 1}, {8457, 33819139}, {8458, 16778755}, | 
1227  |  |   {8459, 16779011}, {8463, 16802051}, {8464, 16779267}, {8466, 16780035}, | 
1228  |  |   {8468, 1}, {8469, 16780547}, {8470, 33557763}, {8471, 1}, | 
1229  |  |   {8473, 16781059}, {8474, 16781315}, {8475, 16781571}, {8478, 1}, | 
1230  |  |   {8480, 33819651}, {8481, 50597379}, {8482, 33820931}, {8483, 1}, | 
1231  |  |   {8484, 16783619}, {8485, 1}, {8486, 16857091}, {8487, 1}, | 
1232  |  |   {8488, 16783619}, {8489, 1}, {8490, 16779779}, {8491, 16790787}, | 
1233  |  |   {8492, 16777475}, {8493, 16777731}, {8494, 1}, {8495, 16778243}, | 
1234  |  |   {8497, 16778499}, {8498, 2}, {8499, 16780291}, {8500, 16780803}, | 
1235  |  |   {8501, 17044227}, {8502, 17044483}, {8503, 17044739}, {8504, 17044995}, | 
1236  |  |   {8505, 16779267}, {8506, 1}, {8507, 50599683}, {8508, 16855043}, | 
1237  |  |   {8509, 16852227}, {8511, 16855043}, {8512, 17046019}, {8513, 1}, | 
1238  |  |   {8517, 16777987}, {8519, 16778243}, {8520, 16779267}, {8521, 16779523}, | 
1239  |  |   {8522, 1}, {8528, 50600707}, {8529, 50601475}, {8530, 67379459}, | 
1240  |  |   {8531, 50603267}, {8532, 50604035}, {8533, 50604803}, {8534, 50605571}, | 
1241  |  |   {8535, 50606339}, {8536, 50607107}, {8537, 50607875}, {8538, 50608643}, | 
1242  |  |   {8539, 50609411}, {8540, 50610179}, {8541, 50610947}, {8542, 50611715}, | 
1243  |  |   {8543, 33564419}, {8544, 16779267}, {8545, 33835267}, {8546, 50612995}, | 
1244  |  |   {8547, 33836547}, {8548, 16782595}, {8549, 33837059}, {8550, 50614787}, | 
1245  |  |   {8551, 67392771}, {8552, 33839363}, {8553, 16783107}, {8554, 33839875}, | 
1246  |  |   {8555, 50617603}, {8556, 16780035}, {8557, 16777731}, {8558, 16777987}, | 
1247  |  |   {8559, 16780291}, {8560, 16779267}, {8561, 33835267}, {8562, 50612483}, | 
1248  |  |   {8563, 33836547}, {8564, 16782595}, {8565, 33837059}, {8566, 50614787}, | 
1249  |  |   {8567, 67392771}, {8568, 33839363}, {8569, 16783107}, {8570, 33839875}, | 
1250  |  |   {8571, 50617603}, {8572, 16780035}, {8573, 16777731}, {8574, 16777987}, | 
1251  |  |   {8575, 16780291}, {8576, 1}, {8579, 2}, {8580, 1}, | 
1252  |  |   {8585, 50618371}, {8586, 1}, {8588, 2}, {8592, 1}, | 
1253  |  |   {8748, 33841923}, {8749, 50619651}, {8750, 1}, {8751, 33843203}, | 
1254  |  |   {8752, 50620931}, {8753, 1}, {9001, 17067267}, {9002, 17067523}, | 
1255  |  |   {9003, 1}, {9255, 2}, {9280, 1}, {9291, 2}, | 
1256  |  |   {9312, 16786947}, {9313, 16785155}, {9314, 16785411}, {9315, 16787715}, | 
1257  |  |   {9316, 17035779}, {9317, 17036035}, {9318, 17036291}, {9319, 17036547}, | 
1258  |  |   {9320, 17036803}, {9321, 33825539}, {9322, 33564163}, {9323, 33844995}, | 
1259  |  |   {9324, 33845507}, {9325, 33846019}, {9326, 33846531}, {9327, 33847043}, | 
1260  |  |   {9328, 33847555}, {9329, 33848067}, {9330, 33848579}, {9331, 33849091}, | 
1261  |  |   {9332, 50626819}, {9333, 50627587}, {9334, 50628355}, {9335, 50629123}, | 
1262  |  |   {9336, 50629891}, {9337, 50630659}, {9338, 50631427}, {9339, 50632195}, | 
1263  |  |   {9340, 50632963}, {9341, 67410947}, {9342, 67411971}, {9343, 67412995}, | 
1264  |  |   {9344, 67414019}, {9345, 67415043}, {9346, 67416067}, {9347, 67417091}, | 
1265  |  |   {9348, 67418115}, {9349, 67419139}, {9350, 67420163}, {9351, 67421187}, | 
1266  |  |   {9352, 2}, {9372, 50644995}, {9373, 50645763}, {9374, 50646531}, | 
1267  |  |   {9375, 50647299}, {9376, 50648067}, {9377, 50648835}, {9378, 50649603}, | 
1268  |  |   {9379, 50650371}, {9380, 50651139}, {9381, 50651907}, {9382, 50652675}, | 
1269  |  |   {9383, 50653443}, {9384, 50654211}, {9385, 50654979}, {9386, 50655747}, | 
1270  |  |   {9387, 50656515}, {9388, 50657283}, {9389, 50658051}, {9390, 50658819}, | 
1271  |  |   {9391, 50659587}, {9392, 50660355}, {9393, 50661123}, {9394, 50661891}, | 
1272  |  |   {9395, 50662659}, {9396, 50663427}, {9397, 50664195}, {9398, 16777219}, | 
1273  |  |   {9399, 16777475}, {9400, 16777731}, {9401, 16777987}, {9402, 16778243}, | 
1274  |  |   {9403, 16778499}, {9404, 16778755}, {9405, 16779011}, {9406, 16779267}, | 
1275  |  |   {9407, 16779523}, {9408, 16779779}, {9409, 16780035}, {9410, 16780291}, | 
1276  |  |   {9411, 16780547}, {9412, 16780803}, {9413, 16781059}, {9414, 16781315}, | 
1277  |  |   {9415, 16781571}, {9416, 16781827}, {9417, 16782083}, {9418, 16782339}, | 
1278  |  |   {9419, 16782595}, {9420, 16782851}, {9421, 16783107}, {9422, 16783363}, | 
1279  |  |   {9423, 16783619}, {9424, 16777219}, {9425, 16777475}, {9426, 16777731}, | 
1280  |  |   {9427, 16777987}, {9428, 16778243}, {9429, 16778499}, {9430, 16778755}, | 
1281  |  |   {9431, 16779011}, {9432, 16779267}, {9433, 16779523}, {9434, 16779779}, | 
1282  |  |   {9435, 16780035}, {9436, 16780291}, {9437, 16780547}, {9438, 16780803}, | 
1283  |  |   {9439, 16781059}, {9440, 16781315}, {9441, 16781571}, {9442, 16781827}, | 
1284  |  |   {9443, 16782083}, {9444, 16782339}, {9445, 16782595}, {9446, 16782851}, | 
1285  |  |   {9447, 16783107}, {9448, 16783363}, {9449, 16783619}, {9450, 17035523}, | 
1286  |  |   {9451, 1}, {10764, 67396355}, {10765, 1}, {10868, 50664963}, | 
1287  |  |   {10869, 33888515}, {10870, 50665475}, {10871, 1}, {10972, 33889027}, | 
1288  |  |   {10973, 1}, {11124, 2}, {11126, 1}, {11158, 2}, | 
1289  |  |   {11159, 1}, {11264, 17112323}, {11265, 17112579}, {11266, 17112835}, | 
1290  |  |   {11267, 17113091}, {11268, 17113347}, {11269, 17113603}, {11270, 17113859}, | 
1291  |  |   {11271, 17114115}, {11272, 17114371}, {11273, 17114627}, {11274, 17114883}, | 
1292  |  |   {11275, 17115139}, {11276, 17115395}, {11277, 17115651}, {11278, 17115907}, | 
1293  |  |   {11279, 17116163}, {11280, 17116419}, {11281, 17116675}, {11282, 17116931}, | 
1294  |  |   {11283, 17117187}, {11284, 17117443}, {11285, 17117699}, {11286, 17117955}, | 
1295  |  |   {11287, 17118211}, {11288, 17118467}, {11289, 17118723}, {11290, 17118979}, | 
1296  |  |   {11291, 17119235}, {11292, 17119491}, {11293, 17119747}, {11294, 17120003}, | 
1297  |  |   {11295, 17120259}, {11296, 17120515}, {11297, 17120771}, {11298, 17121027}, | 
1298  |  |   {11299, 17121283}, {11300, 17121539}, {11301, 17121795}, {11302, 17122051}, | 
1299  |  |   {11303, 17122307}, {11304, 17122563}, {11305, 17122819}, {11306, 17123075}, | 
1300  |  |   {11307, 17123331}, {11308, 17123587}, {11309, 17123843}, {11310, 17124099}, | 
1301  |  |   {11311, 17124355}, {11312, 1}, {11360, 17124611}, {11361, 1}, | 
1302  |  |   {11362, 17124867}, {11363, 17125123}, {11364, 17125379}, {11365, 1}, | 
1303  |  |   {11367, 17125635}, {11368, 1}, {11369, 17125891}, {11370, 1}, | 
1304  |  |   {11371, 17126147}, {11372, 1}, {11373, 16948483}, {11374, 16953091}, | 
1305  |  |   {11375, 16948227}, {11376, 16950275}, {11377, 1}, {11378, 17126403}, | 
1306  |  |   {11379, 1}, {11381, 17126659}, {11382, 1}, {11388, 16779523}, | 
1307  |  |   {11389, 16782595}, {11390, 17126915}, {11391, 17127171}, {11392, 17127427}, | 
1308  |  |   {11393, 1}, {11394, 17127683}, {11395, 1}, {11396, 17127939}, | 
1309  |  |   {11397, 1}, {11398, 17128195}, {11399, 1}, {11400, 17128451}, | 
1310  |  |   {11401, 1}, {11402, 17128707}, {11403, 1}, {11404, 17128963}, | 
1311  |  |   {11405, 1}, {11406, 17129219}, {11407, 1}, {11408, 17129475}, | 
1312  |  |   {11409, 1}, {11410, 17129731}, {11411, 1}, {11412, 17129987}, | 
1313  |  |   {11413, 1}, {11414, 17130243}, {11415, 1}, {11416, 17130499}, | 
1314  |  |   {11417, 1}, {11418, 17130755}, {11419, 1}, {11420, 17131011}, | 
1315  |  |   {11421, 1}, {11422, 17131267}, {11423, 1}, {11424, 17131523}, | 
1316  |  |   {11425, 1}, {11426, 17131779}, {11427, 1}, {11428, 17132035}, | 
1317  |  |   {11429, 1}, {11430, 17132291}, {11431, 1}, {11432, 17132547}, | 
1318  |  |   {11433, 1}, {11434, 17132803}, {11435, 1}, {11436, 17133059}, | 
1319  |  |   {11437, 1}, {11438, 17133315}, {11439, 1}, {11440, 17133571}, | 
1320  |  |   {11441, 1}, {11442, 17133827}, {11443, 1}, {11444, 17134083}, | 
1321  |  |   {11445, 1}, {11446, 17134339}, {11447, 1}, {11448, 17134595}, | 
1322  |  |   {11449, 1}, {11450, 17134851}, {11451, 1}, {11452, 17135107}, | 
1323  |  |   {11453, 1}, {11454, 17135363}, {11455, 1}, {11456, 17135619}, | 
1324  |  |   {11457, 1}, {11458, 17135875}, {11459, 1}, {11460, 17136131}, | 
1325  |  |   {11461, 1}, {11462, 17136387}, {11463, 1}, {11464, 17136643}, | 
1326  |  |   {11465, 1}, {11466, 17136899}, {11467, 1}, {11468, 17137155}, | 
1327  |  |   {11469, 1}, {11470, 17137411}, {11471, 1}, {11472, 17137667}, | 
1328  |  |   {11473, 1}, {11474, 17137923}, {11475, 1}, {11476, 17138179}, | 
1329  |  |   {11477, 1}, {11478, 17138435}, {11479, 1}, {11480, 17138691}, | 
1330  |  |   {11481, 1}, {11482, 17138947}, {11483, 1}, {11484, 17139203}, | 
1331  |  |   {11485, 1}, {11486, 17139459}, {11487, 1}, {11488, 17139715}, | 
1332  |  |   {11489, 1}, {11490, 17139971}, {11491, 1}, {11499, 17140227}, | 
1333  |  |   {11500, 1}, {11501, 17140483}, {11502, 1}, {11506, 17140739}, | 
1334  |  |   {11507, 1}, {11508, 2}, {11513, 1}, {11558, 2}, | 
1335  |  |   {11559, 1}, {11560, 2}, {11565, 1}, {11566, 2}, | 
1336  |  |   {11568, 1}, {11624, 2}, {11631, 17140995}, {11632, 1}, | 
1337  |  |   {11633, 2}, {11647, 1}, {11671, 2}, {11680, 1}, | 
1338  |  |   {11687, 2}, {11688, 1}, {11695, 2}, {11696, 1}, | 
1339  |  |   {11703, 2}, {11704, 1}, {11711, 2}, {11712, 1}, | 
1340  |  |   {11719, 2}, {11720, 1}, {11727, 2}, {11728, 1}, | 
1341  |  |   {11735, 2}, {11736, 1}, {11743, 2}, {11744, 1}, | 
1342  |  |   {11870, 2}, {11904, 1}, {11930, 2}, {11931, 1}, | 
1343  |  |   {11935, 17141251}, {11936, 1}, {12019, 17141507}, {12020, 2}, | 
1344  |  |   {12032, 17141763}, {12033, 17142019}, {12034, 17142275}, {12035, 17142531}, | 
1345  |  |   {12036, 17142787}, {12037, 17143043}, {12038, 17143299}, {12039, 17143555}, | 
1346  |  |   {12040, 17143811}, {12041, 17144067}, {12042, 17144323}, {12043, 17144579}, | 
1347  |  |   {12044, 17144835}, {12045, 17145091}, {12046, 17145347}, {12047, 17145603}, | 
1348  |  |   {12048, 17145859}, {12049, 17146115}, {12050, 17146371}, {12051, 17146627}, | 
1349  |  |   {12052, 17146883}, {12053, 17147139}, {12054, 17147395}, {12055, 17147651}, | 
1350  |  |   {12056, 17147907}, {12057, 17148163}, {12058, 17148419}, {12059, 17148675}, | 
1351  |  |   {12060, 17148931}, {12061, 17149187}, {12062, 17149443}, {12063, 17149699}, | 
1352  |  |   {12064, 17149955}, {12065, 17150211}, {12066, 17150467}, {12067, 17150723}, | 
1353  |  |   {12068, 17150979}, {12069, 17151235}, {12070, 17151491}, {12071, 17151747}, | 
1354  |  |   {12072, 17152003}, {12073, 17152259}, {12074, 17152515}, {12075, 17152771}, | 
1355  |  |   {12076, 17153027}, {12077, 17153283}, {12078, 17153539}, {12079, 17153795}, | 
1356  |  |   {12080, 17154051}, {12081, 17154307}, {12082, 17154563}, {12083, 17154819}, | 
1357  |  |   {12084, 17155075}, {12085, 17155331}, {12086, 17155587}, {12087, 17155843}, | 
1358  |  |   {12088, 17156099}, {12089, 17156355}, {12090, 17156611}, {12091, 17156867}, | 
1359  |  |   {12092, 17157123}, {12093, 17157379}, {12094, 17157635}, {12095, 17157891}, | 
1360  |  |   {12096, 17158147}, {12097, 17158403}, {12098, 17158659}, {12099, 17158915}, | 
1361  |  |   {12100, 17159171}, {12101, 17159427}, {12102, 17159683}, {12103, 17159939}, | 
1362  |  |   {12104, 17160195}, {12105, 17160451}, {12106, 17160707}, {12107, 17160963}, | 
1363  |  |   {12108, 17161219}, {12109, 17161475}, {12110, 17161731}, {12111, 17161987}, | 
1364  |  |   {12112, 17162243}, {12113, 17162499}, {12114, 17162755}, {12115, 17163011}, | 
1365  |  |   {12116, 17163267}, {12117, 17163523}, {12118, 17163779}, {12119, 17164035}, | 
1366  |  |   {12120, 17164291}, {12121, 17164547}, {12122, 17164803}, {12123, 17165059}, | 
1367  |  |   {12124, 17165315}, {12125, 17165571}, {12126, 17165827}, {12127, 17166083}, | 
1368  |  |   {12128, 17166339}, {12129, 17166595}, {12130, 17166851}, {12131, 17167107}, | 
1369  |  |   {12132, 17167363}, {12133, 17167619}, {12134, 17167875}, {12135, 17168131}, | 
1370  |  |   {12136, 17168387}, {12137, 17168643}, {12138, 17168899}, {12139, 17169155}, | 
1371  |  |   {12140, 17169411}, {12141, 17169667}, {12142, 17169923}, {12143, 17170179}, | 
1372  |  |   {12144, 17170435}, {12145, 17170691}, {12146, 17170947}, {12147, 17171203}, | 
1373  |  |   {12148, 17171459}, {12149, 17171715}, {12150, 17171971}, {12151, 17172227}, | 
1374  |  |   {12152, 17172483}, {12153, 17172739}, {12154, 17172995}, {12155, 17173251}, | 
1375  |  |   {12156, 17173507}, {12157, 17173763}, {12158, 17174019}, {12159, 17174275}, | 
1376  |  |   {12160, 17174531}, {12161, 17174787}, {12162, 17175043}, {12163, 17175299}, | 
1377  |  |   {12164, 17175555}, {12165, 17175811}, {12166, 17176067}, {12167, 17176323}, | 
1378  |  |   {12168, 17176579}, {12169, 17176835}, {12170, 17177091}, {12171, 17177347}, | 
1379  |  |   {12172, 17177603}, {12173, 17177859}, {12174, 17178115}, {12175, 17178371}, | 
1380  |  |   {12176, 17178627}, {12177, 17178883}, {12178, 17179139}, {12179, 17179395}, | 
1381  |  |   {12180, 17179651}, {12181, 17179907}, {12182, 17180163}, {12183, 17180419}, | 
1382  |  |   {12184, 17180675}, {12185, 17180931}, {12186, 17181187}, {12187, 17181443}, | 
1383  |  |   {12188, 17181699}, {12189, 17181955}, {12190, 17182211}, {12191, 17182467}, | 
1384  |  |   {12192, 17182723}, {12193, 17182979}, {12194, 17183235}, {12195, 17183491}, | 
1385  |  |   {12196, 17183747}, {12197, 17184003}, {12198, 17184259}, {12199, 17184515}, | 
1386  |  |   {12200, 17184771}, {12201, 17185027}, {12202, 17185283}, {12203, 17185539}, | 
1387  |  |   {12204, 17185795}, {12205, 17186051}, {12206, 17186307}, {12207, 17186563}, | 
1388  |  |   {12208, 17186819}, {12209, 17187075}, {12210, 17187331}, {12211, 17187587}, | 
1389  |  |   {12212, 17187843}, {12213, 17188099}, {12214, 17188355}, {12215, 17188611}, | 
1390  |  |   {12216, 17188867}, {12217, 17189123}, {12218, 17189379}, {12219, 17189635}, | 
1391  |  |   {12220, 17189891}, {12221, 17190147}, {12222, 17190403}, {12223, 17190659}, | 
1392  |  |   {12224, 17190915}, {12225, 17191171}, {12226, 17191427}, {12227, 17191683}, | 
1393  |  |   {12228, 17191939}, {12229, 17192195}, {12230, 17192451}, {12231, 17192707}, | 
1394  |  |   {12232, 17192963}, {12233, 17193219}, {12234, 17193475}, {12235, 17193731}, | 
1395  |  |   {12236, 17193987}, {12237, 17194243}, {12238, 17194499}, {12239, 17194755}, | 
1396  |  |   {12240, 17195011}, {12241, 17195267}, {12242, 17195523}, {12243, 17195779}, | 
1397  |  |   {12244, 17196035}, {12245, 17196291}, {12246, 2}, {12288, 16783875}, | 
1398  |  |   {12289, 1}, {12290, 17196547}, {12291, 1}, {12342, 17196803}, | 
1399  |  |   {12343, 1}, {12344, 17147651}, {12345, 17197059}, {12346, 17197315}, | 
1400  |  |   {12347, 1}, {12352, 2}, {12353, 1}, {12439, 2}, | 
1401  |  |   {12441, 1}, {12443, 33974787}, {12444, 33975299}, {12445, 1}, | 
1402  |  |   {12447, 33975811}, {12448, 1}, {12543, 33976323}, {12544, 2}, | 
1403  |  |   {12549, 1}, {12592, 2}, {12593, 17199619}, {12594, 17199875}, | 
1404  |  |   {12595, 17200131}, {12596, 17200387}, {12597, 17200643}, {12598, 17200899}, | 
1405  |  |   {12599, 17201155}, {12600, 17201411}, {12601, 17201667}, {12602, 17201923}, | 
1406  |  |   {12603, 17202179}, {12604, 17202435}, {12605, 17202691}, {12606, 17202947}, | 
1407  |  |   {12607, 17203203}, {12608, 17203459}, {12609, 17203715}, {12610, 17203971}, | 
1408  |  |   {12611, 17204227}, {12612, 17204483}, {12613, 17204739}, {12614, 17204995}, | 
1409  |  |   {12615, 17205251}, {12616, 17205507}, {12617, 17205763}, {12618, 17206019}, | 
1410  |  |   {12619, 17206275}, {12620, 17206531}, {12621, 17206787}, {12622, 17207043}, | 
1411  |  |   {12623, 17207299}, {12624, 17207555}, {12625, 17207811}, {12626, 17208067}, | 
1412  |  |   {12627, 17208323}, {12628, 17208579}, {12629, 17208835}, {12630, 17209091}, | 
1413  |  |   {12631, 17209347}, {12632, 17209603}, {12633, 17209859}, {12634, 17210115}, | 
1414  |  |   {12635, 17210371}, {12636, 17210627}, {12637, 17210883}, {12638, 17211139}, | 
1415  |  |   {12639, 17211395}, {12640, 17211651}, {12641, 17211907}, {12642, 17212163}, | 
1416  |  |   {12643, 17212419}, {12644, 2}, {12645, 17212675}, {12646, 17212931}, | 
1417  |  |   {12647, 17213187}, {12648, 17213443}, {12649, 17213699}, {12650, 17213955}, | 
1418  |  |   {12651, 17214211}, {12652, 17214467}, {12653, 17214723}, {12654, 17214979}, | 
1419  |  |   {12655, 17215235}, {12656, 17215491}, {12657, 17215747}, {12658, 17216003}, | 
1420  |  |   {12659, 17216259}, {12660, 17216515}, {12661, 17216771}, {12662, 17217027}, | 
1421  |  |   {12663, 17217283}, {12664, 17217539}, {12665, 17217795}, {12666, 17218051}, | 
1422  |  |   {12667, 17218307}, {12668, 17218563}, {12669, 17218819}, {12670, 17219075}, | 
1423  |  |   {12671, 17219331}, {12672, 17219587}, {12673, 17219843}, {12674, 17220099}, | 
1424  |  |   {12675, 17220355}, {12676, 17220611}, {12677, 17220867}, {12678, 17221123}, | 
1425  |  |   {12679, 17221379}, {12680, 17221635}, {12681, 17221891}, {12682, 17222147}, | 
1426  |  |   {12683, 17222403}, {12684, 17222659}, {12685, 17222915}, {12686, 17223171}, | 
1427  |  |   {12687, 2}, {12688, 1}, {12690, 17141763}, {12691, 17143299}, | 
1428  |  |   {12692, 17223427}, {12693, 17223683}, {12694, 17223939}, {12695, 17224195}, | 
1429  |  |   {12696, 17224451}, {12697, 17224707}, {12698, 17142787}, {12699, 17224963}, | 
1430  |  |   {12700, 17225219}, {12701, 17225475}, {12702, 17225731}, {12703, 17143811}, | 
1431  |  |   {12704, 1}, {12772, 2}, {12784, 1}, {12800, 50780419}, | 
1432  |  |   {12801, 50781187}, {12802, 50781955}, {12803, 50782723}, {12804, 50783491}, | 
1433  |  |   {12805, 50784259}, {12806, 50785027}, {12807, 50785795}, {12808, 50786563}, | 
1434  |  |   {12809, 50787331}, {12810, 50788099}, {12811, 50788867}, {12812, 50789635}, | 
1435  |  |   {12813, 50790403}, {12814, 50791171}, {12815, 50791939}, {12816, 50792707}, | 
1436  |  |   {12817, 50793475}, {12818, 50794243}, {12819, 50795011}, {12820, 50795779}, | 
1437  |  |   {12821, 50796547}, {12822, 50797315}, {12823, 50798083}, {12824, 50798851}, | 
1438  |  |   {12825, 50799619}, {12826, 50800387}, {12827, 50801155}, {12828, 50801923}, | 
1439  |  |   {12829, 67579907}, {12830, 67580931}, {12831, 2}, {12832, 50804739}, | 
1440  |  |   {12833, 50805507}, {12834, 50806275}, {12835, 50807043}, {12836, 50807811}, | 
1441  |  |   {12837, 50808579}, {12838, 50809347}, {12839, 50810115}, {12840, 50810883}, | 
1442  |  |   {12841, 50811651}, {12842, 50812419}, {12843, 50813187}, {12844, 50813955}, | 
1443  |  |   {12845, 50814723}, {12846, 50815491}, {12847, 50816259}, {12848, 50817027}, | 
1444  |  |   {12849, 50817795}, {12850, 50818563}, {12851, 50819331}, {12852, 50820099}, | 
1445  |  |   {12853, 50820867}, {12854, 50821635}, {12855, 50822403}, {12856, 50823171}, | 
1446  |  |   {12857, 50823939}, {12858, 50824707}, {12859, 50825475}, {12860, 50826243}, | 
1447  |  |   {12861, 50827011}, {12862, 50827779}, {12863, 50828547}, {12864, 50829315}, | 
1448  |  |   {12865, 50830083}, {12866, 50830851}, {12867, 50831619}, {12868, 17277955}, | 
1449  |  |   {12869, 17278211}, {12870, 17158659}, {12871, 17278467}, {12872, 1}, | 
1450  |  |   {12880, 50833155}, {12881, 33845251}, {12882, 34056707}, {12883, 33562371}, | 
1451  |  |   {12884, 34057219}, {12885, 34057731}, {12886, 34058243}, {12887, 34058755}, | 
1452  |  |   {12888, 34059267}, {12889, 34059779}, {12890, 34060291}, {12891, 33827331}, | 
1453  |  |   {12892, 33826563}, {12893, 34060803}, {12894, 34061315}, {12895, 34061827}, | 
1454  |  |   {12896, 17199619}, {12897, 17200387}, {12898, 17201155}, {12899, 17201667}, | 
1455  |  |   {12900, 17203715}, {12901, 17203971}, {12902, 17204739}, {12903, 17205251}, | 
1456  |  |   {12904, 17205507}, {12905, 17206019}, {12906, 17206275}, {12907, 17206531}, | 
1457  |  |   {12908, 17206787}, {12909, 17207043}, {12910, 17236995}, {12911, 17237763}, | 
1458  |  |   {12912, 17238531}, {12913, 17239299}, {12914, 17240067}, {12915, 17240835}, | 
1459  |  |   {12916, 17241603}, {12917, 17242371}, {12918, 17243139}, {12919, 17243907}, | 
1460  |  |   {12920, 17244675}, {12921, 17245443}, {12922, 17246211}, {12923, 17246979}, | 
1461  |  |   {12924, 34062339}, {12925, 34062851}, {12926, 17286147}, {12927, 1}, | 
1462  |  |   {12928, 17141763}, {12929, 17143299}, {12930, 17223427}, {12931, 17223683}, | 
1463  |  |   {12932, 17253635}, {12933, 17254403}, {12934, 17255171}, {12935, 17144579}, | 
1464  |  |   {12936, 17256707}, {12937, 17147651}, {12938, 17160451}, {12939, 17163523}, | 
1465  |  |   {12940, 17163267}, {12941, 17160707}, {12942, 17184259}, {12943, 17149699}, | 
1466  |  |   {12944, 17159939}, {12945, 17263619}, {12946, 17264387}, {12947, 17265155}, | 
1467  |  |   {12948, 17265923}, {12949, 17266691}, {12950, 17267459}, {12951, 17268227}, | 
1468  |  |   {12952, 17268995}, {12953, 17286403}, {12954, 17286659}, {12955, 17151235}, | 
1469  |  |   {12956, 17286915}, {12957, 17287171}, {12958, 17287427}, {12959, 17287683}, | 
1470  |  |   {12960, 17287939}, {12961, 17275907}, {12962, 17288195}, {12963, 17288451}, | 
1471  |  |   {12964, 17223939}, {12965, 17224195}, {12966, 17224451}, {12967, 17288707}, | 
1472  |  |   {12968, 17288963}, {12969, 17289219}, {12970, 17289475}, {12971, 17271299}, | 
1473  |  |   {12972, 17272067}, {12973, 17272835}, {12974, 17273603}, {12975, 17274371}, | 
1474  |  |   {12976, 17289731}, {12977, 34067203}, {12978, 34067715}, {12979, 34068227}, | 
1475  |  |   {12980, 34068739}, {12981, 34069251}, {12982, 33564931}, {12983, 34057475}, | 
1476  |  |   {12984, 34061571}, {12985, 34069763}, {12986, 34070275}, {12987, 34070787}, | 
1477  |  |   {12988, 34071299}, {12989, 34071811}, {12990, 34072323}, {12991, 34072835}, | 
1478  |  |   {12992, 34073347}, {12993, 34073859}, {12994, 34074371}, {12995, 34074883}, | 
1479  |  |   {12996, 34075395}, {12997, 34075907}, {12998, 34076419}, {12999, 34076931}, | 
1480  |  |   {13000, 34077443}, {13001, 50855171}, {13002, 50855939}, {13003, 50856707}, | 
1481  |  |   {13004, 34080259}, {13005, 50857987}, {13006, 34081539}, {13007, 50859267}, | 
1482  |  |   {13008, 17305603}, {13009, 17305859}, {13010, 17306115}, {13011, 17306371}, | 
1483  |  |   {13012, 17306627}, {13013, 17306883}, {13014, 17307139}, {13015, 17307395}, | 
1484  |  |   {13016, 17307651}, {13017, 17199107}, {13018, 17307907}, {13019, 17308163}, | 
1485  |  |   {13020, 17308419}, {13021, 17308675}, {13022, 17308931}, {13023, 17309187}, | 
1486  |  |   {13024, 17309443}, {13025, 17309699}, {13026, 17309955}, {13027, 17199363}, | 
1487  |  |   {13028, 17310211}, {13029, 17310467}, {13030, 17310723}, {13031, 17310979}, | 
1488  |  |   {13032, 17311235}, {13033, 17311491}, {13034, 17311747}, {13035, 17312003}, | 
1489  |  |   {13036, 17312259}, {13037, 17312515}, {13038, 17312771}, {13039, 17313027}, | 
1490  |  |   {13040, 17313283}, {13041, 17313539}, {13042, 17313795}, {13043, 17314051}, | 
1491  |  |   {13044, 17314307}, {13045, 17314563}, {13046, 17314819}, {13047, 17315075}, | 
1492  |  |   {13048, 17315331}, {13049, 17315587}, {13050, 17315843}, {13051, 17316099}, | 
1493  |  |   {13052, 17316355}, {13053, 17316611}, {13054, 17316867}, {13055, 34094339}, | 
1494  |  |   {13056, 67649283}, {13057, 67650307}, {13058, 67651331}, {13059, 50875139}, | 
1495  |  |   {13060, 67653123}, {13061, 50876931}, {13062, 50877699}, {13063, 84432899}, | 
1496  |  |   {13064, 67656963}, {13065, 50880771}, {13066, 50881539}, {13067, 50882307}, | 
1497  |  |   {13068, 67660291}, {13069, 67661315}, {13070, 50885123}, {13071, 50885891}, | 
1498  |  |   {13072, 34109443}, {13073, 50887171}, {13074, 67665155}, {13075, 67666179}, | 
1499  |  |   {13076, 34112771}, {13077, 84444931}, {13078, 101223427}, {13079, 84447747}, | 
1500  |  |   {13080, 50891011}, {13081, 84449027}, {13082, 84450307}, {13083, 67674371}, | 
1501  |  |   {13084, 50898179}, {13085, 50898947}, {13086, 50899715}, {13087, 67677699}, | 
1502  |  |   {13088, 84455939}, {13089, 67680003}, {13090, 50903811}, {13091, 50904579}, | 
1503  |  |   {13092, 50905347}, {13093, 34128899}, {13094, 34129411}, {13095, 34118147}, | 
1504  |  |   {13096, 34129923}, {13097, 50907651}, {13098, 50908419}, {13099, 84463619}, | 
1505  |  |   {13100, 50910467}, {13101, 67688451}, {13102, 84466691}, {13103, 50913539}, | 
1506  |  |   {13104, 34137091}, {13105, 34137603}, {13106, 84469763}, {13107, 67693827}, | 
1507  |  |   {13108, 84472067}, {13109, 50918915}, {13110, 84474115}, {13111, 34143747}, | 
1508  |  |   {13112, 50921475}, {13113, 50922243}, {13114, 50923011}, {13115, 50923779}, | 
1509  |  |   {13116, 50924547}, {13117, 67702531}, {13118, 50926339}, {13119, 34149891}, | 
1510  |  |   {13120, 50927619}, {13121, 50928387}, {13122, 50929155}, {13123, 67707139}, | 
1511  |  |   {13124, 50930947}, {13125, 50931715}, {13126, 50932483}, {13127, 84487683}, | 
1512  |  |   {13128, 67711747}, {13129, 34158339}, {13130, 84490499}, {13131, 34160131}, | 
1513  |  |   {13132, 67715075}, {13133, 67669507}, {13134, 50938883}, {13135, 50939651}, | 
1514  |  |   {13136, 50940419}, {13137, 67718403}, {13138, 34164995}, {13139, 50942723}, | 
1515  |  |   {13140, 67720707}, {13141, 34167299}, {13142, 84499459}, {13143, 50893827}, | 
1516  |  |   {13144, 34169091}, {13145, 34169603}, {13146, 34170115}, {13147, 34170627}, | 
1517  |  |   {13148, 34171139}, {13149, 34171651}, {13150, 34172163}, {13151, 34172675}, | 
1518  |  |   {13152, 34173187}, {13153, 34173699}, {13154, 50951427}, {13155, 50952195}, | 
1519  |  |   {13156, 50952963}, {13157, 50953731}, {13158, 50954499}, {13159, 50955267}, | 
1520  |  |   {13160, 50956035}, {13161, 50956803}, {13162, 50957571}, {13163, 50958339}, | 
1521  |  |   {13164, 50959107}, {13165, 50959875}, {13166, 50960643}, {13167, 50961411}, | 
1522  |  |   {13168, 50962179}, {13169, 50962947}, {13170, 34186499}, {13171, 34187011}, | 
1523  |  |   {13172, 50964739}, {13173, 34188291}, {13174, 34188803}, {13175, 34189315}, | 
1524  |  |   {13176, 50967043}, {13177, 50967811}, {13178, 34191363}, {13179, 34191875}, | 
1525  |  |   {13180, 34192387}, {13181, 34192899}, {13182, 34193411}, {13183, 67748355}, | 
1526  |  |   {13184, 34185987}, {13185, 34194947}, {13186, 34195459}, {13187, 34195971}, | 
1527  |  |   {13188, 34196483}, {13189, 34196995}, {13190, 34197507}, {13191, 34198019}, | 
1528  |  |   {13192, 50975747}, {13193, 67753731}, {13194, 34200323}, {13195, 34200835}, | 
1529  |  |   {13196, 34201347}, {13197, 34201859}, {13198, 34202371}, {13199, 34202883}, | 
1530  |  |   {13200, 34203395}, {13201, 50981123}, {13202, 50981891}, {13203, 50980355}, | 
1531  |  |   {13204, 50982659}, {13205, 34206211}, {13206, 34206723}, {13207, 34207235}, | 
1532  |  |   {13208, 33556995}, {13209, 34207747}, {13210, 34208259}, {13211, 34208771}, | 
1533  |  |   {13212, 34209283}, {13213, 34209795}, {13214, 34210307}, {13215, 50988035}, | 
1534  |  |   {13216, 50988803}, {13217, 34190083}, {13218, 50989571}, {13219, 50990339}, | 
1535  |  |   {13220, 50991107}, {13221, 34190851}, {13222, 50991875}, {13223, 50992643}, | 
1536  |  |   {13224, 67770627}, {13225, 34185987}, {13226, 50994435}, {13227, 50995203}, | 
1537  |  |   {13228, 50995971}, {13229, 50996739}, {13230, 84551939}, {13231, 101330435}, | 
1538  |  |   {13232, 34223107}, {13233, 34223619}, {13234, 34224131}, {13235, 34224643}, | 
1539  |  |   {13236, 34225155}, {13237, 34225667}, {13238, 34226179}, {13239, 34226691}, | 
1540  |  |   {13240, 34227203}, {13241, 34226691}, {13242, 34227715}, {13243, 34228227}, | 
1541  |  |   {13244, 34228739}, {13245, 34229251}, {13246, 34229763}, {13247, 34229251}, | 
1542  |  |   {13248, 34230275}, {13249, 34230787}, {13250, 2}, {13251, 34231299}, | 
1543  |  |   {13252, 33817347}, {13253, 33554947}, {13254, 67786243}, {13255, 2}, | 
1544  |  |   {13256, 34232835}, {13257, 34233347}, {13258, 34233859}, {13259, 34185731}, | 
1545  |  |   {13260, 34234371}, {13261, 34234883}, {13262, 34210307}, {13263, 34235395}, | 
1546  |  |   {13264, 33557251}, {13265, 34235907}, {13266, 51013635}, {13267, 34237187}, | 
1547  |  |   {13268, 34197507}, {13269, 51014915}, {13270, 51015683}, {13271, 34239235}, | 
1548  |  |   {13272, 2}, {13273, 51016963}, {13274, 34240515}, {13275, 34221315}, | 
1549  |  |   {13276, 34241027}, {13277, 34241539}, {13278, 51019267}, {13279, 51020035}, | 
1550  |  |   {13280, 34243587}, {13281, 34244099}, {13282, 34244611}, {13283, 34245123}, | 
1551  |  |   {13284, 34245635}, {13285, 34246147}, {13286, 34246659}, {13287, 34247171}, | 
1552  |  |   {13288, 34247683}, {13289, 51025411}, {13290, 51026179}, {13291, 51026947}, | 
1553  |  |   {13292, 51027715}, {13293, 51028483}, {13294, 51029251}, {13295, 51030019}, | 
1554  |  |   {13296, 51030787}, {13297, 51031555}, {13298, 51032323}, {13299, 51033091}, | 
1555  |  |   {13300, 51033859}, {13301, 51034627}, {13302, 51035395}, {13303, 51036163}, | 
1556  |  |   {13304, 51036931}, {13305, 51037699}, {13306, 51038467}, {13307, 51039235}, | 
1557  |  |   {13308, 51040003}, {13309, 51040771}, {13310, 51041539}, {13311, 51042307}, | 
1558  |  |   {13312, 1}, {42125, 2}, {42128, 1}, {42183, 2}, | 
1559  |  |   {42192, 1}, {42540, 2}, {42560, 17488643}, {42561, 1}, | 
1560  |  |   {42562, 17488899}, {42563, 1}, {42564, 17489155}, {42565, 1}, | 
1561  |  |   {42566, 17489411}, {42567, 1}, {42568, 17489667}, {42569, 1}, | 
1562  |  |   {42570, 16936451}, {42571, 1}, {42572, 17489923}, {42573, 1}, | 
1563  |  |   {42574, 17490179}, {42575, 1}, {42576, 17490435}, {42577, 1}, | 
1564  |  |   {42578, 17490691}, {42579, 1}, {42580, 17490947}, {42581, 1}, | 
1565  |  |   {42582, 17491203}, {42583, 1}, {42584, 17491459}, {42585, 1}, | 
1566  |  |   {42586, 17491715}, {42587, 1}, {42588, 17491971}, {42589, 1}, | 
1567  |  |   {42590, 17492227}, {42591, 1}, {42592, 17492483}, {42593, 1}, | 
1568  |  |   {42594, 17492739}, {42595, 1}, {42596, 17492995}, {42597, 1}, | 
1569  |  |   {42598, 17493251}, {42599, 1}, {42600, 17493507}, {42601, 1}, | 
1570  |  |   {42602, 17493763}, {42603, 1}, {42604, 17494019}, {42605, 1}, | 
1571  |  |   {42624, 17494275}, {42625, 1}, {42626, 17494531}, {42627, 1}, | 
1572  |  |   {42628, 17494787}, {42629, 1}, {42630, 17495043}, {42631, 1}, | 
1573  |  |   {42632, 17495299}, {42633, 1}, {42634, 17495555}, {42635, 1}, | 
1574  |  |   {42636, 17495811}, {42637, 1}, {42638, 17496067}, {42639, 1}, | 
1575  |  |   {42640, 17496323}, {42641, 1}, {42642, 17496579}, {42643, 1}, | 
1576  |  |   {42644, 17496835}, {42645, 1}, {42646, 17497091}, {42647, 1}, | 
1577  |  |   {42648, 17497347}, {42649, 1}, {42650, 17497603}, {42651, 1}, | 
1578  |  |   {42652, 16873219}, {42653, 16873731}, {42654, 1}, {42744, 2}, | 
1579  |  |   {42752, 1}, {42786, 17497859}, {42787, 1}, {42788, 17498115}, | 
1580  |  |   {42789, 1}, {42790, 17498371}, {42791, 1}, {42792, 17498627}, | 
1581  |  |   {42793, 1}, {42794, 17498883}, {42795, 1}, {42796, 17499139}, | 
1582  |  |   {42797, 1}, {42798, 17499395}, {42799, 1}, {42802, 17499651}, | 
1583  |  |   {42803, 1}, {42804, 17499907}, {42805, 1}, {42806, 17500163}, | 
1584  |  |   {42807, 1}, {42808, 17500419}, {42809, 1}, {42810, 17500675}, | 
1585  |  |   {42811, 1}, {42812, 17500931}, {42813, 1}, {42814, 17501187}, | 
1586  |  |   {42815, 1}, {42816, 17501443}, {42817, 1}, {42818, 17501699}, | 
1587  |  |   {42819, 1}, {42820, 17501955}, {42821, 1}, {42822, 17502211}, | 
1588  |  |   {42823, 1}, {42824, 17502467}, {42825, 1}, {42826, 17502723}, | 
1589  |  |   {42827, 1}, {42828, 17502979}, {42829, 1}, {42830, 17503235}, | 
1590  |  |   {42831, 1}, {42832, 17503491}, {42833, 1}, {42834, 17503747}, | 
1591  |  |   {42835, 1}, {42836, 17504003}, {42837, 1}, {42838, 17504259}, | 
1592  |  |   {42839, 1}, {42840, 17504515}, {42841, 1}, {42842, 17504771}, | 
1593  |  |   {42843, 1}, {42844, 17505027}, {42845, 1}, {42846, 17505283}, | 
1594  |  |   {42847, 1}, {42848, 17505539}, {42849, 1}, {42850, 17505795}, | 
1595  |  |   {42851, 1}, {42852, 17506051}, {42853, 1}, {42854, 17506307}, | 
1596  |  |   {42855, 1}, {42856, 17506563}, {42857, 1}, {42858, 17506819}, | 
1597  |  |   {42859, 1}, {42860, 17507075}, {42861, 1}, {42862, 17507331}, | 
1598  |  |   {42863, 1}, {42864, 17507331}, {42865, 1}, {42873, 17507587}, | 
1599  |  |   {42874, 1}, {42875, 17507843}, {42876, 1}, {42877, 17508099}, | 
1600  |  |   {42878, 17508355}, {42879, 1}, {42880, 17508611}, {42881, 1}, | 
1601  |  |   {42882, 17508867}, {42883, 1}, {42884, 17509123}, {42885, 1}, | 
1602  |  |   {42886, 17509379}, {42887, 1}, {42891, 17509635}, {42892, 1}, | 
1603  |  |   {42893, 16951299}, {42894, 1}, {42896, 17509891}, {42897, 1}, | 
1604  |  |   {42898, 17510147}, {42899, 1}, {42902, 17510403}, {42903, 1}, | 
1605  |  |   {42904, 17510659}, {42905, 1}, {42906, 17510915}, {42907, 1}, | 
1606  |  |   {42908, 17511171}, {42909, 1}, {42910, 17511427}, {42911, 1}, | 
1607  |  |   {42912, 17511683}, {42913, 1}, {42914, 17511939}, {42915, 1}, | 
1608  |  |   {42916, 17512195}, {42917, 1}, {42918, 17512451}, {42919, 1}, | 
1609  |  |   {42920, 17512707}, {42921, 1}, {42922, 16841475}, {42923, 16948995}, | 
1610  |  |   {42924, 16951043}, {42925, 17512963}, {42926, 16951555}, {42927, 1}, | 
1611  |  |   {42928, 17513219}, {42929, 17513475}, {42930, 16952067}, {42931, 17513731}, | 
1612  |  |   {42932, 17513987}, {42933, 1}, {42934, 17514243}, {42935, 1}, | 
1613  |  |   {42936, 17514499}, {42937, 1}, {42938, 17514755}, {42939, 1}, | 
1614  |  |   {42940, 17515011}, {42941, 1}, {42942, 17515267}, {42943, 1}, | 
1615  |  |   {42944, 17515523}, {42945, 1}, {42946, 17515779}, {42947, 1}, | 
1616  |  |   {42948, 17516035}, {42949, 16954371}, {42950, 17516291}, {42951, 17516547}, | 
1617  |  |   {42952, 1}, {42953, 17516803}, {42954, 1}, {42955, 2}, | 
1618  |  |   {42960, 17517059}, {42961, 1}, {42962, 2}, {42963, 1}, | 
1619  |  |   {42964, 2}, {42965, 1}, {42966, 17517315}, {42967, 1}, | 
1620  |  |   {42968, 17517571}, {42969, 1}, {42970, 2}, {42994, 16777731}, | 
1621  |  |   {42995, 16778499}, {42996, 16781315}, {42997, 17517827}, {42998, 1}, | 
1622  |  |   {43000, 16802051}, {43001, 16808195}, {43002, 1}, {43053, 2}, | 
1623  |  |   {43056, 1}, {43066, 2}, {43072, 1}, {43128, 2}, | 
1624  |  |   {43136, 1}, {43206, 2}, {43214, 1}, {43226, 2}, | 
1625  |  |   {43232, 1}, {43348, 2}, {43359, 1}, {43389, 2}, | 
1626  |  |   {43392, 1}, {43470, 2}, {43471, 1}, {43482, 2}, | 
1627  |  |   {43486, 1}, {43519, 2}, {43520, 1}, {43575, 2}, | 
1628  |  |   {43584, 1}, {43598, 2}, {43600, 1}, {43610, 2}, | 
1629  |  |   {43612, 1}, {43715, 2}, {43739, 1}, {43767, 2}, | 
1630  |  |   {43777, 1}, {43783, 2}, {43785, 1}, {43791, 2}, | 
1631  |  |   {43793, 1}, {43799, 2}, {43808, 1}, {43815, 2}, | 
1632  |  |   {43816, 1}, {43823, 2}, {43824, 1}, {43868, 17498371}, | 
1633  |  |   {43869, 17518083}, {43870, 17124867}, {43871, 17518339}, {43872, 1}, | 
1634  |  |   {43881, 17518595}, {43882, 1}, {43884, 2}, {43888, 17518851}, | 
1635  |  |   {43889, 17519107}, {43890, 17519363}, {43891, 17519619}, {43892, 17519875}, | 
1636  |  |   {43893, 17520131}, {43894, 17520387}, {43895, 17520643}, {43896, 17520899}, | 
1637  |  |   {43897, 17521155}, {43898, 17521411}, {43899, 17521667}, {43900, 17521923}, | 
1638  |  |   {43901, 17522179}, {43902, 17522435}, {43903, 17522691}, {43904, 17522947}, | 
1639  |  |   {43905, 17523203}, {43906, 17523459}, {43907, 17523715}, {43908, 17523971}, | 
1640  |  |   {43909, 17524227}, {43910, 17524483}, {43911, 17524739}, {43912, 17524995}, | 
1641  |  |   {43913, 17525251}, {43914, 17525507}, {43915, 17525763}, {43916, 17526019}, | 
1642  |  |   {43917, 17526275}, {43918, 17526531}, {43919, 17526787}, {43920, 17527043}, | 
1643  |  |   {43921, 17527299}, {43922, 17527555}, {43923, 17527811}, {43924, 17528067}, | 
1644  |  |   {43925, 17528323}, {43926, 17528579}, {43927, 17528835}, {43928, 17529091}, | 
1645  |  |   {43929, 17529347}, {43930, 17529603}, {43931, 17529859}, {43932, 17530115}, | 
1646  |  |   {43933, 17530371}, {43934, 17530627}, {43935, 17530883}, {43936, 17531139}, | 
1647  |  |   {43937, 17531395}, {43938, 17531651}, {43939, 17531907}, {43940, 17532163}, | 
1648  |  |   {43941, 17532419}, {43942, 17532675}, {43943, 17532931}, {43944, 17533187}, | 
1649  |  |   {43945, 17533443}, {43946, 17533699}, {43947, 17533955}, {43948, 17534211}, | 
1650  |  |   {43949, 17534467}, {43950, 17534723}, {43951, 17534979}, {43952, 17535235}, | 
1651  |  |   {43953, 17535491}, {43954, 17535747}, {43955, 17536003}, {43956, 17536259}, | 
1652  |  |   {43957, 17536515}, {43958, 17536771}, {43959, 17537027}, {43960, 17537283}, | 
1653  |  |   {43961, 17537539}, {43962, 17537795}, {43963, 17538051}, {43964, 17538307}, | 
1654  |  |   {43965, 17538563}, {43966, 17538819}, {43967, 17539075}, {43968, 1}, | 
1655  |  |   {44014, 2}, {44016, 1}, {44026, 2}, {44032, 1}, | 
1656  |  |   {55204, 2}, {55216, 1}, {55239, 2}, {55243, 1}, | 
1657  |  |   {55292, 2}, {63744, 17539331}, {63745, 17539587}, {63746, 17182211}, | 
1658  |  |   {63747, 17539843}, {63748, 17540099}, {63749, 17540355}, {63750, 17540611}, | 
1659  |  |   {63751, 17196035}, {63753, 17540867}, {63754, 17184259}, {63755, 17541123}, | 
1660  |  |   {63756, 17541379}, {63757, 17541635}, {63758, 17541891}, {63759, 17542147}, | 
1661  |  |   {63760, 17542403}, {63761, 17542659}, {63762, 17542915}, {63763, 17543171}, | 
1662  |  |   {63764, 17543427}, {63765, 17543683}, {63766, 17543939}, {63767, 17544195}, | 
1663  |  |   {63768, 17544451}, {63769, 17544707}, {63770, 17544963}, {63771, 17545219}, | 
1664  |  |   {63772, 17545475}, {63773, 17545731}, {63774, 17545987}, {63775, 17546243}, | 
1665  |  |   {63776, 17546499}, {63777, 17546755}, {63778, 17547011}, {63779, 17547267}, | 
1666  |  |   {63780, 17547523}, {63781, 17547779}, {63782, 17548035}, {63783, 17548291}, | 
1667  |  |   {63784, 17548547}, {63785, 17548803}, {63786, 17549059}, {63787, 17549315}, | 
1668  |  |   {63788, 17549571}, {63789, 17549827}, {63790, 17550083}, {63791, 17550339}, | 
1669  |  |   {63792, 17550595}, {63793, 17550851}, {63794, 17551107}, {63795, 17551363}, | 
1670  |  |   {63796, 17173507}, {63797, 17551619}, {63798, 17551875}, {63799, 17552131}, | 
1671  |  |   {63800, 17552387}, {63801, 17552643}, {63802, 17552899}, {63803, 17553155}, | 
1672  |  |   {63804, 17553411}, {63805, 17553667}, {63806, 17553923}, {63807, 17554179}, | 
1673  |  |   {63808, 17192195}, {63809, 17554435}, {63810, 17554691}, {63811, 17554947}, | 
1674  |  |   {63812, 17555203}, {63813, 17555459}, {63814, 17555715}, {63815, 17555971}, | 
1675  |  |   {63816, 17556227}, {63817, 17556483}, {63818, 17556739}, {63819, 17556995}, | 
1676  |  |   {63820, 17557251}, {63821, 17557507}, {63822, 17557763}, {63823, 17558019}, | 
1677  |  |   {63824, 17558275}, {63825, 17558531}, {63826, 17558787}, {63827, 17559043}, | 
1678  |  |   {63828, 17559299}, {63829, 17559555}, {63830, 17559811}, {63831, 17560067}, | 
1679  |  |   {63832, 17560323}, {63833, 17560579}, {63834, 17560835}, {63835, 17561091}, | 
1680  |  |   {63836, 17543427}, {63837, 17561347}, {63838, 17561603}, {63839, 17561859}, | 
1681  |  |   {63840, 17562115}, {63841, 17562371}, {63842, 17562627}, {63843, 17562883}, | 
1682  |  |   {63844, 17563139}, {63845, 17563395}, {63846, 17563651}, {63847, 17563907}, | 
1683  |  |   {63848, 17564163}, {63849, 17564419}, {63850, 17564675}, {63851, 17564931}, | 
1684  |  |   {63852, 17565187}, {63853, 17565443}, {63854, 17565699}, {63855, 17565955}, | 
1685  |  |   {63856, 17566211}, {63857, 17182723}, {63858, 17566467}, {63859, 17566723}, | 
1686  |  |   {63860, 17566979}, {63861, 17567235}, {63862, 17567491}, {63863, 17567747}, | 
1687  |  |   {63864, 17568003}, {63865, 17568259}, {63866, 17568515}, {63867, 17568771}, | 
1688  |  |   {63868, 17569027}, {63869, 17569283}, {63870, 17569539}, {63871, 17569795}, | 
1689  |  |   {63872, 17570051}, {63873, 17151235}, {63874, 17570307}, {63875, 17570563}, | 
1690  |  |   {63876, 17570819}, {63877, 17571075}, {63878, 17571331}, {63879, 17571587}, | 
1691  |  |   {63880, 17571843}, {63881, 17572099}, {63882, 17146371}, {63883, 17572355}, | 
1692  |  |   {63884, 17572611}, {63885, 17572867}, {63886, 17573123}, {63887, 17573379}, | 
1693  |  |   {63888, 17573635}, {63889, 17573891}, {63890, 17574147}, {63891, 17574403}, | 
1694  |  |   {63892, 17574659}, {63893, 17574915}, {63894, 17575171}, {63895, 17575427}, | 
1695  |  |   {63896, 17575683}, {63897, 17575939}, {63898, 17576195}, {63899, 17576451}, | 
1696  |  |   {63900, 17576707}, {63901, 17576963}, {63902, 17577219}, {63903, 17577475}, | 
1697  |  |   {63904, 17577731}, {63905, 17565955}, {63906, 17577987}, {63907, 17578243}, | 
1698  |  |   {63908, 17578499}, {63909, 17578755}, {63910, 17579011}, {63911, 17579267}, | 
1699  |  |   {63912, 17317123}, {63913, 17579523}, {63914, 17561859}, {63915, 17579779}, | 
1700  |  |   {63916, 17580035}, {63917, 17580291}, {63918, 17580547}, {63919, 17580803}, | 
1701  |  |   {63920, 17581059}, {63921, 17581315}, {63922, 17581571}, {63923, 17581827}, | 
1702  |  |   {63924, 17582083}, {63925, 17582339}, {63926, 17582595}, {63927, 17582851}, | 
1703  |  |   {63928, 17583107}, {63929, 17583363}, {63930, 17583619}, {63931, 17583875}, | 
1704  |  |   {63932, 17584131}, {63933, 17584387}, {63934, 17584643}, {63935, 17543427}, | 
1705  |  |   {63936, 17584899}, {63937, 17585155}, {63938, 17585411}, {63939, 17585667}, | 
1706  |  |   {63940, 17195779}, {63941, 17585923}, {63942, 17586179}, {63943, 17586435}, | 
1707  |  |   {63944, 17586691}, {63945, 17586947}, {63946, 17587203}, {63947, 17587459}, | 
1708  |  |   {63948, 17587715}, {63949, 17587971}, {63950, 17588227}, {63951, 17588483}, | 
1709  |  |   {63952, 17588739}, {63953, 17254403}, {63954, 17588995}, {63955, 17589251}, | 
1710  |  |   {63956, 17589507}, {63957, 17589763}, {63958, 17590019}, {63959, 17590275}, | 
1711  |  |   {63960, 17590531}, {63961, 17590787}, {63962, 17591043}, {63963, 17562371}, | 
1712  |  |   {63964, 17591299}, {63965, 17591555}, {63966, 17591811}, {63967, 17592067}, | 
1713  |  |   {63968, 17592323}, {63969, 17592579}, {63970, 17592835}, {63971, 17593091}, | 
1714  |  |   {63972, 17593347}, {63973, 17593603}, {63974, 17593859}, {63975, 17594115}, | 
1715  |  |   {63976, 17594371}, {63977, 17184003}, {63978, 17594627}, {63979, 17594883}, | 
1716  |  |   {63980, 17595139}, {63981, 17595395}, {63982, 17595651}, {63983, 17595907}, | 
1717  |  |   {63984, 17596163}, {63985, 17596419}, {63986, 17596675}, {63987, 17596931}, | 
1718  |  |   {63988, 17597187}, {63989, 17597443}, {63990, 17597699}, {63991, 17171459}, | 
1719  |  |   {63992, 17597955}, {63993, 17598211}, {63994, 17598467}, {63995, 17598723}, | 
1720  |  |   {63996, 17598979}, {63997, 17599235}, {63998, 17599491}, {63999, 17599747}, | 
1721  |  |   {64000, 17600003}, {64001, 17600259}, {64002, 17600515}, {64003, 17600771}, | 
1722  |  |   {64004, 17601027}, {64005, 17601283}, {64006, 17601539}, {64007, 17601795}, | 
1723  |  |   {64008, 17178371}, {64009, 17602051}, {64010, 17179139}, {64011, 17602307}, | 
1724  |  |   {64012, 17602563}, {64013, 17602819}, {64014, 1}, {64016, 17603075}, | 
1725  |  |   {64017, 1}, {64018, 17603331}, {64019, 1}, {64021, 17603587}, | 
1726  |  |   {64022, 17603843}, {64023, 17604099}, {64024, 17604355}, {64025, 17604611}, | 
1727  |  |   {64026, 17604867}, {64027, 17605123}, {64028, 17605379}, {64029, 17605635}, | 
1728  |  |   {64030, 17173251}, {64031, 1}, {64032, 17605891}, {64033, 1}, | 
1729  |  |   {64034, 17606147}, {64035, 1}, {64037, 17606403}, {64038, 17606659}, | 
1730  |  |   {64039, 1}, {64042, 17606915}, {64043, 17607171}, {64044, 17607427}, | 
1731  |  |   {64045, 17607683}, {64046, 17607939}, {64047, 17608195}, {64048, 17608451}, | 
1732  |  |   {64049, 17608707}, {64050, 17608963}, {64051, 17609219}, {64052, 17609475}, | 
1733  |  |   {64053, 17609731}, {64054, 17609987}, {64055, 17610243}, {64056, 17610499}, | 
1734  |  |   {64057, 17610755}, {64058, 17611011}, {64059, 17611267}, {64060, 17153027}, | 
1735  |  |   {64061, 17611523}, {64062, 17611779}, {64063, 17612035}, {64064, 17612291}, | 
1736  |  |   {64065, 17612547}, {64066, 17612803}, {64067, 17613059}, {64068, 17613315}, | 
1737  |  |   {64069, 17613571}, {64070, 17613827}, {64071, 17614083}, {64072, 17614339}, | 
1738  |  |   {64073, 17614595}, {64074, 17614851}, {64075, 17615107}, {64076, 17265155}, | 
1739  |  |   {64077, 17615363}, {64078, 17615619}, {64079, 17615875}, {64080, 17616131}, | 
1740  |  |   {64081, 17268227}, {64082, 17616387}, {64083, 17616643}, {64084, 17616899}, | 
1741  |  |   {64085, 17617155}, {64086, 17617411}, {64087, 17575171}, {64088, 17617667}, | 
1742  |  |   {64089, 17617923}, {64090, 17618179}, {64091, 17618435}, {64092, 17618691}, | 
1743  |  |   {64093, 17618947}, {64095, 17619203}, {64096, 17619459}, {64097, 17619715}, | 
1744  |  |   {64098, 17619971}, {64099, 17620227}, {64100, 17620483}, {64101, 17620739}, | 
1745  |  |   {64102, 17620995}, {64103, 17606403}, {64104, 17621251}, {64105, 17621507}, | 
1746  |  |   {64106, 17621763}, {64107, 17622019}, {64108, 17622275}, {64109, 17622531}, | 
1747  |  |   {64110, 2}, {64112, 17622787}, {64113, 17623043}, {64114, 17623299}, | 
1748  |  |   {64115, 17623555}, {64116, 17623811}, {64117, 17624067}, {64118, 17624323}, | 
1749  |  |   {64119, 17624579}, {64120, 17609987}, {64121, 17624835}, {64122, 17625091}, | 
1750  |  |   {64123, 17625347}, {64124, 17603075}, {64125, 17625603}, {64126, 17625859}, | 
1751  |  |   {64127, 17626115}, {64128, 17626371}, {64129, 17626627}, {64130, 17626883}, | 
1752  |  |   {64131, 17627139}, {64132, 17627395}, {64133, 17627651}, {64134, 17627907}, | 
1753  |  |   {64135, 17628163}, {64136, 17628419}, {64137, 17612035}, {64138, 17628675}, | 
1754  |  |   {64139, 17612291}, {64140, 17628931}, {64141, 17629187}, {64142, 17629443}, | 
1755  |  |   {64143, 17629699}, {64144, 17629955}, {64145, 17603331}, {64146, 17548803}, | 
1756  |  |   {64147, 17630211}, {64148, 17630467}, {64149, 17161475}, {64150, 17566211}, | 
1757  |  |   {64151, 17587203}, {64152, 17630723}, {64153, 17630979}, {64154, 17614083}, | 
1758  |  |   {64155, 17631235}, {64156, 17614339}, {64157, 17631491}, {64158, 17631747}, | 
1759  |  |   {64159, 17632003}, {64160, 17603843}, {64161, 17632259}, {64162, 17632515}, | 
1760  |  |   {64163, 17632771}, {64164, 17633027}, {64165, 17633283}, {64166, 17604099}, | 
1761  |  |   {64167, 17633539}, {64168, 17633795}, {64169, 17634051}, {64170, 17634307}, | 
1762  |  |   {64171, 17634563}, {64172, 17634819}, {64173, 17617411}, {64174, 17635075}, | 
1763  |  |   {64175, 17635331}, {64176, 17575171}, {64177, 17635587}, {64178, 17618435}, | 
1764  |  |   {64179, 17635843}, {64180, 17636099}, {64181, 17636355}, {64182, 17636611}, | 
1765  |  |   {64183, 17636867}, {64184, 17619715}, {64185, 17637123}, {64186, 17606147}, | 
1766  |  |   {64187, 17637379}, {64188, 17619971}, {64189, 17561347}, {64190, 17637635}, | 
1767  |  |   {64191, 17620227}, {64192, 17637891}, {64193, 17620739}, {64194, 17638147}, | 
1768  |  |   {64195, 17638403}, {64196, 17638659}, {64197, 17638915}, {64198, 17639171}, | 
1769  |  |   {64199, 17621251}, {64200, 17605379}, {64201, 17639427}, {64202, 17621507}, | 
1770  |  |   {64203, 17639683}, {64204, 17621763}, {64205, 17639939}, {64206, 17196035}, | 
1771  |  |   {64207, 17640195}, {64208, 17640451}, {64209, 17640707}, {64210, 17640963}, | 
1772  |  |   {64211, 17641219}, {64212, 17641475}, {64213, 17641731}, {64214, 17641987}, | 
1773  |  |   {64215, 17642243}, {64216, 17642499}, {64217, 17642755}, {64218, 2}, | 
1774  |  |   {64256, 34420227}, {64257, 34420739}, {64258, 34421251}, {64259, 51197699}, | 
1775  |  |   {64260, 51198979}, {64261, 33559043}, {64263, 2}, {64275, 34422531}, | 
1776  |  |   {64276, 34423043}, {64277, 34423555}, {64278, 34424067}, {64279, 34424579}, | 
1777  |  |   {64280, 2}, {64285, 34425091}, {64286, 1}, {64287, 34425603}, | 
1778  |  |   {64288, 17648899}, {64289, 17044227}, {64290, 17044995}, {64291, 17649155}, | 
1779  |  |   {64292, 17649411}, {64293, 17649667}, {64294, 17649923}, {64295, 17650179}, | 
1780  |  |   {64296, 17650435}, {64297, 17037059}, {64298, 34427907}, {64299, 34428419}, | 
1781  |  |   {64300, 51206147}, {64301, 51206915}, {64302, 34430467}, {64303, 34430979}, | 
1782  |  |   {64304, 34431491}, {64305, 34432003}, {64306, 34432515}, {64307, 34433027}, | 
1783  |  |   {64308, 34433539}, {64309, 34434051}, {64310, 34434563}, {64311, 2}, | 
1784  |  |   {64312, 34435075}, {64313, 34435587}, {64314, 34436099}, {64315, 34436611}, | 
1785  |  |   {64316, 34437123}, {64317, 2}, {64318, 34437635}, {64319, 2}, | 
1786  |  |   {64320, 34438147}, {64321, 34438659}, {64322, 2}, {64323, 34439171}, | 
1787  |  |   {64324, 34439683}, {64325, 2}, {64326, 34440195}, {64327, 34440707}, | 
1788  |  |   {64328, 34441219}, {64329, 34428931}, {64330, 34441731}, {64331, 34442243}, | 
1789  |  |   {64332, 34442755}, {64333, 34443267}, {64334, 34443779}, {64335, 34444291}, | 
1790  |  |   {64336, 17667587}, {64338, 17667843}, {64342, 17668099}, {64346, 17668355}, | 
1791  |  |   {64350, 17668611}, {64354, 17668867}, {64358, 17669123}, {64362, 17669379}, | 
1792  |  |   {64366, 17669635}, {64370, 17669891}, {64374, 17670147}, {64378, 17670403}, | 
1793  |  |   {64382, 17670659}, {64386, 17670915}, {64388, 17671171}, {64390, 17671427}, | 
1794  |  |   {64392, 17671683}, {64394, 17671939}, {64396, 17672195}, {64398, 17672451}, | 
1795  |  |   {64402, 17672707}, {64406, 17672963}, {64410, 17673219}, {64414, 17673475}, | 
1796  |  |   {64416, 17673731}, {64420, 17673987}, {64422, 17674243}, {64426, 17674499}, | 
1797  |  |   {64430, 17674755}, {64432, 17675011}, {64434, 1}, {64451, 2}, | 
1798  |  |   {64467, 17675267}, {64471, 16911363}, {64473, 17675523}, {64475, 17675779}, | 
1799  |  |   {64477, 33688579}, {64478, 17676035}, {64480, 17676291}, {64482, 17676547}, | 
1800  |  |   {64484, 17676803}, {64488, 17677059}, {64490, 34454531}, {64492, 34455043}, | 
1801  |  |   {64494, 34455555}, {64496, 34456067}, {64498, 34456579}, {64500, 34457091}, | 
1802  |  |   {64502, 34457603}, {64505, 34458115}, {64508, 17681411}, {64512, 34458883}, | 
1803  |  |   {64513, 34459395}, {64514, 34459907}, {64515, 34458115}, {64516, 34460419}, | 
1804  |  |   {64517, 34460931}, {64518, 34461443}, {64519, 34461955}, {64520, 34462467}, | 
1805  |  |   {64521, 34462979}, {64522, 34463491}, {64523, 34464003}, {64524, 34464515}, | 
1806  |  |   {64525, 34465027}, {64526, 34465539}, {64527, 34466051}, {64528, 34466563}, | 
1807  |  |   {64529, 34467075}, {64530, 34467587}, {64531, 34468099}, {64532, 34468611}, | 
1808  |  |   {64533, 34469123}, {64534, 34469635}, {64535, 34469379}, {64536, 34470147}, | 
1809  |  |   {64537, 34470659}, {64538, 34471171}, {64539, 34471683}, {64540, 34472195}, | 
1810  |  |   {64541, 34472707}, {64542, 34473219}, {64543, 34473731}, {64544, 34474243}, | 
1811  |  |   {64545, 34474755}, {64546, 34475267}, {64547, 34475779}, {64548, 34476291}, | 
1812  |  |   {64549, 34476803}, {64550, 34477315}, {64551, 34477827}, {64552, 34478339}, | 
1813  |  |   {64553, 34478851}, {64554, 34479363}, {64555, 34479875}, {64556, 34480387}, | 
1814  |  |   {64557, 34480899}, {64558, 34481411}, {64559, 34481923}, {64560, 34482435}, | 
1815  |  |   {64561, 34482947}, {64562, 34483459}, {64563, 34483971}, {64564, 34484483}, | 
1816  |  |   {64565, 34484995}, {64566, 34485507}, {64567, 34486019}, {64568, 34486531}, | 
1817  |  |   {64569, 34487043}, {64570, 34487555}, {64571, 34488067}, {64572, 34488579}, | 
1818  |  |   {64573, 34489091}, {64574, 34489603}, {64575, 34490115}, {64576, 34490627}, | 
1819  |  |   {64577, 34491139}, {64578, 34491651}, {64579, 34492163}, {64580, 34492675}, | 
1820  |  |   {64581, 34493187}, {64582, 34469891}, {64583, 34470403}, {64584, 34493699}, | 
1821  |  |   {64585, 34494211}, {64586, 34494723}, {64587, 34495235}, {64588, 34495747}, | 
1822  |  |   {64589, 34496259}, {64590, 34496771}, {64591, 34497283}, {64592, 34497795}, | 
1823  |  |   {64593, 34498307}, {64594, 34498819}, {64595, 34499331}, {64596, 34499843}, | 
1824  |  |   {64597, 34468867}, {64598, 34500355}, {64599, 34500867}, {64600, 34492931}, | 
1825  |  |   {64601, 34501379}, {64602, 34500099}, {64603, 34501891}, {64604, 34502403}, | 
1826  |  |   {64605, 34502915}, {64606, 51280643}, {64607, 51281411}, {64608, 51282179}, | 
1827  |  |   {64609, 51282947}, {64610, 51283715}, {64611, 51284483}, {64612, 34508035}, | 
1828  |  |   {64613, 34508547}, {64614, 34459907}, {64615, 34509059}, {64616, 34458115}, | 
1829  |  |   {64617, 34460419}, {64618, 34509571}, {64619, 34510083}, {64620, 34462467}, | 
1830  |  |   {64621, 34510595}, {64622, 34462979}, {64623, 34463491}, {64624, 34511107}, | 
1831  |  |   {64625, 34511619}, {64626, 34465539}, {64627, 34512131}, {64628, 34466051}, | 
1832  |  |   {64629, 34466563}, {64630, 34512643}, {64631, 34513155}, {64632, 34467587}, | 
1833  |  |   {64633, 34513667}, {64634, 34468099}, {64635, 34468611}, {64636, 34482947}, | 
1834  |  |   {64637, 34483459}, {64638, 34484995}, {64639, 34485507}, {64640, 34486019}, | 
1835  |  |   {64641, 34488067}, {64642, 34488579}, {64643, 34489091}, {64644, 34489603}, | 
1836  |  |   {64645, 34491651}, {64646, 34492163}, {64647, 34492675}, {64648, 34514179}, | 
1837  |  |   {64649, 34493699}, {64650, 34514691}, {64651, 34515203}, {64652, 34496771}, | 
1838  |  |   {64653, 34515715}, {64654, 34497283}, {64655, 34497795}, {64656, 34502915}, | 
1839  |  |   {64657, 34516227}, {64658, 34516739}, {64659, 34492931}, {64660, 34494979}, | 
1840  |  |   {64661, 34501379}, {64662, 34500099}, {64663, 34458883}, {64664, 34459395}, | 
1841  |  |   {64665, 34517251}, {64666, 34459907}, {64667, 34517763}, {64668, 34460931}, | 
1842  |  |   {64669, 34461443}, {64670, 34461955}, {64671, 34462467}, {64672, 34518275}, | 
1843  |  |   {64673, 34464003}, {64674, 34464515}, {64675, 34465027}, {64676, 34465539}, | 
1844  |  |   {64677, 34518787}, {64678, 34467587}, {64679, 34469123}, {64680, 34469635}, | 
1845  |  |   {64681, 34469379}, {64682, 34470147}, {64683, 34470659}, {64684, 34471683}, | 
1846  |  |   {64685, 34472195}, {64686, 34472707}, {64687, 34473219}, {64688, 34473731}, | 
1847  |  |   {64689, 34474243}, {64690, 34519299}, {64691, 34474755}, {64692, 34475267}, | 
1848  |  |   {64693, 34475779}, {64694, 34476291}, {64695, 34476803}, {64696, 34477315}, | 
1849  |  |   {64697, 34478339}, {64698, 34478851}, {64699, 34479363}, {64700, 34479875}, | 
1850  |  |   {64701, 34480387}, {64702, 34480899}, {64703, 34481411}, {64704, 34481923}, | 
1851  |  |   {64705, 34482435}, {64706, 34483971}, {64707, 34484483}, {64708, 34486531}, | 
1852  |  |   {64709, 34487043}, {64710, 34487555}, {64711, 34488067}, {64712, 34488579}, | 
1853  |  |   {64713, 34490115}, {64714, 34490627}, {64715, 34491139}, {64716, 34491651}, | 
1854  |  |   {64717, 34519811}, {64718, 34493187}, {64719, 34469891}, {64720, 34470403}, | 
1855  |  |   {64721, 34493699}, {64722, 34495235}, {64723, 34495747}, {64724, 34496259}, | 
1856  |  |   {64725, 34496771}, {64726, 34520323}, {64727, 34498307}, {64728, 34498819}, | 
1857  |  |   {64729, 34520835}, {64730, 34468867}, {64731, 34500355}, {64732, 34500867}, | 
1858  |  |   {64733, 34492931}, {64734, 34498051}, {64735, 34459907}, {64736, 34517763}, | 
1859  |  |   {64737, 34462467}, {64738, 34518275}, {64739, 34465539}, {64740, 34518787}, | 
1860  |  |   {64741, 34467587}, {64742, 34521347}, {64743, 34473731}, {64744, 34521859}, | 
1861  |  |   {64745, 34522371}, {64746, 34522883}, {64747, 34488067}, {64748, 34488579}, | 
1862  |  |   {64749, 34491651}, {64750, 34496771}, {64751, 34520323}, {64752, 34492931}, | 
1863  |  |   {64753, 34498051}, {64754, 51300611}, {64755, 51301379}, {64756, 51302147}, | 
1864  |  |   {64757, 34525699}, {64758, 34526211}, {64759, 34526723}, {64760, 34527235}, | 
1865  |  |   {64761, 34527747}, {64762, 34528259}, {64763, 34528771}, {64764, 34529283}, | 
1866  |  |   {64765, 34529795}, {64766, 34530307}, {64767, 34530819}, {64768, 34500611}, | 
1867  |  |   {64769, 34531331}, {64770, 34531843}, {64771, 34532355}, {64772, 34501123}, | 
1868  |  |   {64773, 34532867}, {64774, 34533379}, {64775, 34533891}, {64776, 34534403}, | 
1869  |  |   {64777, 34534915}, {64778, 34535427}, {64779, 34535939}, {64780, 34522371}, | 
1870  |  |   {64781, 34536451}, {64782, 34536963}, {64783, 34537475}, {64784, 34537987}, | 
1871  |  |   {64785, 34525699}, {64786, 34526211}, {64787, 34526723}, {64788, 34527235}, | 
1872  |  |   {64789, 34527747}, {64790, 34528259}, {64791, 34528771}, {64792, 34529283}, | 
1873  |  |   {64793, 34529795}, {64794, 34530307}, {64795, 34530819}, {64796, 34500611}, | 
1874  |  |   {64797, 34531331}, {64798, 34531843}, {64799, 34532355}, {64800, 34501123}, | 
1875  |  |   {64801, 34532867}, {64802, 34533379}, {64803, 34533891}, {64804, 34534403}, | 
1876  |  |   {64805, 34534915}, {64806, 34535427}, {64807, 34535939}, {64808, 34522371}, | 
1877  |  |   {64809, 34536451}, {64810, 34536963}, {64811, 34537475}, {64812, 34537987}, | 
1878  |  |   {64813, 34534915}, {64814, 34535427}, {64815, 34535939}, {64816, 34522371}, | 
1879  |  |   {64817, 34521859}, {64818, 34522883}, {64819, 34477827}, {64820, 34472195}, | 
1880  |  |   {64821, 34472707}, {64822, 34473219}, {64823, 34534915}, {64824, 34535427}, | 
1881  |  |   {64825, 34535939}, {64826, 34477827}, {64827, 34478339}, {64828, 34538499}, | 
1882  |  |   {64830, 1}, {64848, 51316227}, {64849, 51316995}, {64851, 51317763}, | 
1883  |  |   {64852, 51318531}, {64853, 51319299}, {64854, 51320067}, {64855, 51320835}, | 
1884  |  |   {64856, 51246851}, {64858, 51321603}, {64859, 51322371}, {64860, 51323139}, | 
1885  |  |   {64861, 51323907}, {64862, 51324675}, {64863, 51325443}, {64865, 51326211}, | 
1886  |  |   {64866, 51326979}, {64868, 51327747}, {64870, 51328515}, {64871, 51329283}, | 
1887  |  |   {64873, 51330051}, {64874, 51330819}, {64876, 51331587}, {64878, 51332355}, | 
1888  |  |   {64879, 51333123}, {64881, 51333891}, {64883, 51334659}, {64884, 51335427}, | 
1889  |  |   {64885, 51336195}, {64886, 51336963}, {64888, 51337731}, {64889, 51338499}, | 
1890  |  |   {64890, 51339267}, {64891, 51340035}, {64892, 51340803}, {64894, 51341571}, | 
1891  |  |   {64895, 51342339}, {64896, 51343107}, {64897, 51343875}, {64898, 51344643}, | 
1892  |  |   {64899, 51345411}, {64901, 51346179}, {64903, 51346947}, {64905, 51347715}, | 
1893  |  |   {64906, 51247107}, {64907, 51348483}, {64908, 51349251}, {64909, 51270403}, | 
1894  |  |   {64910, 51247619}, {64911, 51350019}, {64912, 2}, {64914, 51350787}, | 
1895  |  |   {64915, 51351555}, {64916, 51352323}, {64917, 51353091}, {64918, 51353859}, | 
1896  |  |   {64919, 51354627}, {64921, 51355395}, {64922, 51356163}, {64923, 51356931}, | 
1897  |  |   {64924, 51357699}, {64926, 51358467}, {64927, 51359235}, {64928, 51360003}, | 
1898  |  |   {64929, 51360771}, {64930, 51361539}, {64931, 51362307}, {64932, 51363075}, | 
1899  |  |   {64933, 51363843}, {64934, 51364611}, {64935, 51365379}, {64936, 51366147}, | 
1900  |  |   {64937, 51366915}, {64938, 51367683}, {64939, 51368451}, {64940, 51369219}, | 
1901  |  |   {64941, 51369987}, {64942, 51277571}, {64943, 51370755}, {64944, 51371523}, | 
1902  |  |   {64945, 51372291}, {64946, 51373059}, {64947, 51373827}, {64948, 51341571}, | 
1903  |  |   {64949, 51343107}, {64950, 51374595}, {64951, 51375363}, {64952, 51376131}, | 
1904  |  |   {64953, 51376899}, {64954, 51377667}, {64955, 51378435}, {64956, 51377667}, | 
1905  |  |   {64957, 51376131}, {64958, 51379203}, {64959, 51379971}, {64960, 51380739}, | 
1906  |  |   {64961, 51381507}, {64962, 51382275}, {64963, 51378435}, {64964, 51336195}, | 
1907  |  |   {64965, 51328515}, {64966, 51383043}, {64967, 51383811}, {64968, 2}, | 
1908  |  |   {64975, 1}, {64976, 2}, {65008, 51384579}, {65009, 51385347}, | 
1909  |  |   {65010, 68163331}, {65011, 68164355}, {65012, 68165379}, {65013, 68166403}, | 
1910  |  |   {65014, 68167427}, {65015, 68168451}, {65016, 68169475}, {65017, 51393283}, | 
1911  |  |   {65018, 303052291}, {65019, 135284739}, {65020, 68177923}, {65021, 1}, | 
1912  |  |   {65024, 0}, {65040, 17847299}, {65041, 17847555}, {65042, 2}, | 
1913  |  |   {65043, 17110531}, {65044, 16848643}, {65045, 17032963}, {65046, 17033987}, | 
1914  |  |   {65047, 17847811}, {65048, 17848067}, {65049, 2}, {65056, 1}, | 
1915  |  |   {65072, 2}, {65073, 17848323}, {65074, 17848579}, {65075, 17848835}, | 
1916  |  |   {65077, 17037827}, {65078, 17038083}, {65079, 17849091}, {65080, 17849347}, | 
1917  |  |   {65081, 17849603}, {65082, 17849859}, {65083, 17850115}, {65084, 17850371}, | 
1918  |  |   {65085, 17850627}, {65086, 17850883}, {65087, 17067267}, {65088, 17067523}, | 
1919  |  |   {65089, 17851139}, {65090, 17851395}, {65091, 17851651}, {65092, 17851907}, | 
1920  |  |   {65093, 1}, {65095, 17852163}, {65096, 17852419}, {65097, 33810691}, | 
1921  |  |   {65101, 17848835}, {65104, 17847299}, {65105, 17847555}, {65106, 2}, | 
1922  |  |   {65108, 16848643}, {65109, 17110531}, {65110, 17033987}, {65111, 17032963}, | 
1923  |  |   {65112, 17848323}, {65113, 17037827}, {65114, 17038083}, {65115, 17849091}, | 
1924  |  |   {65116, 17849347}, {65117, 17849603}, {65118, 17849859}, {65119, 17852675}, | 
1925  |  |   {65120, 17852931}, {65121, 17853187}, {65122, 17037059}, {65123, 17853443}, | 
1926  |  |   {65124, 17853699}, {65125, 17853955}, {65126, 17037571}, {65127, 2}, | 
1927  |  |   {65128, 17854211}, {65129, 17854467}, {65130, 17854723}, {65131, 17854979}, | 
1928  |  |   {65132, 2}, {65136, 34632451}, {65137, 34632963}, {65138, 34503427}, | 
1929  |  |   {65139, 1}, {65140, 34504195}, {65141, 2}, {65142, 34504963}, | 
1930  |  |   {65143, 34523395}, {65144, 34505731}, {65145, 34524163}, {65146, 34506499}, | 
1931  |  |   {65147, 34524931}, {65148, 34507267}, {65149, 34633475}, {65150, 34633987}, | 
1932  |  |   {65151, 34634499}, {65152, 17857795}, {65153, 17858051}, {65155, 17858307}, | 
1933  |  |   {65157, 17858563}, {65159, 17858819}, {65161, 17677315}, {65165, 16910339}, | 
1934  |  |   {65167, 17683715}, {65171, 17859075}, {65173, 17686787}, {65177, 17689859}, | 
1935  |  |   {65181, 17681923}, {65185, 17682435}, {65189, 17684995}, {65193, 17834499}, | 
1936  |  |   {65195, 17724675}, {65197, 17725187}, {65199, 17731587}, {65201, 17694979}, | 
1937  |  |   {65205, 17745155}, {65209, 17697027}, {65213, 17698051}, {65217, 17700099}, | 
1938  |  |   {65221, 17701123}, {65225, 17701635}, {65229, 17702659}, {65233, 17703683}, | 
1939  |  |   {65237, 17706755}, {65241, 17708803}, {65245, 17711107}, {65249, 17682947}, | 
1940  |  |   {65253, 17718019}, {65257, 17721091}, {65261, 16910851}, {65263, 17677059}, | 
1941  |  |   {65265, 16911875}, {65269, 34636547}, {65271, 34637059}, {65273, 34637571}, | 
1942  |  |   {65275, 34622467}, {65277, 2}, {65279, 0}, {65280, 2}, | 
1943  |  |   {65281, 17032963}, {65282, 17860867}, {65283, 17852675}, {65284, 17854467}, | 
1944  |  |   {65285, 17854723}, {65286, 17852931}, {65287, 17861123}, {65288, 17037827}, | 
1945  |  |   {65289, 17038083}, {65290, 17853187}, {65291, 17037059}, {65292, 17847299}, | 
1946  |  |   {65293, 17853443}, {65294, 17196547}, {65295, 17038595}, {65296, 17035523}, | 
1947  |  |   {65297, 16786947}, {65298, 16785155}, {65299, 16785411}, {65300, 16787715}, | 
1948  |  |   {65301, 17035779}, {65302, 17036035}, {65303, 17036291}, {65304, 17036547}, | 
1949  |  |   {65305, 17036803}, {65306, 17110531}, {65307, 16848643}, {65308, 17853699}, | 
1950  |  |   {65309, 17037571}, {65310, 17853955}, {65311, 17033987}, {65312, 17854979}, | 
1951  |  |   {65313, 16777219}, {65314, 16777475}, {65315, 16777731}, {65316, 16777987}, | 
1952  |  |   {65317, 16778243}, {65318, 16778499}, {65319, 16778755}, {65320, 16779011}, | 
1953  |  |   {65321, 16779267}, {65322, 16779523}, {65323, 16779779}, {65324, 16780035}, | 
1954  |  |   {65325, 16780291}, {65326, 16780547}, {65327, 16780803}, {65328, 16781059}, | 
1955  |  |   {65329, 16781315}, {65330, 16781571}, {65331, 16781827}, {65332, 16782083}, | 
1956  |  |   {65333, 16782339}, {65334, 16782595}, {65335, 16782851}, {65336, 16783107}, | 
1957  |  |   {65337, 16783363}, {65338, 16783619}, {65339, 17852163}, {65340, 17854211}, | 
1958  |  |   {65341, 17852419}, {65342, 17861379}, {65343, 17848835}, {65344, 17027075}, | 
1959  |  |   {65345, 16777219}, {65346, 16777475}, {65347, 16777731}, {65348, 16777987}, | 
1960  |  |   {65349, 16778243}, {65350, 16778499}, {65351, 16778755}, {65352, 16779011}, | 
1961  |  |   {65353, 16779267}, {65354, 16779523}, {65355, 16779779}, {65356, 16780035}, | 
1962  |  |   {65357, 16780291}, {65358, 16780547}, {65359, 16780803}, {65360, 16781059}, | 
1963  |  |   {65361, 16781315}, {65362, 16781571}, {65363, 16781827}, {65364, 16782083}, | 
1964  |  |   {65365, 16782339}, {65366, 16782595}, {65367, 16782851}, {65368, 16783107}, | 
1965  |  |   {65369, 16783363}, {65370, 16783619}, {65371, 17849091}, {65372, 17861635}, | 
1966  |  |   {65373, 17849347}, {65374, 17861891}, {65375, 17862147}, {65376, 17862403}, | 
1967  |  |   {65377, 17196547}, {65378, 17851139}, {65379, 17851395}, {65380, 17847555}, | 
1968  |  |   {65381, 17862659}, {65382, 17316867}, {65383, 17319427}, {65384, 17362435}, | 
1969  |  |   {65385, 17862915}, {65386, 17363971}, {65387, 17323523}, {65388, 17863171}, | 
1970  |  |   {65389, 17333763}, {65390, 17379587}, {65391, 17329155}, {65392, 17318147}, | 
1971  |  |   {65393, 17305603}, {65394, 17305859}, {65395, 17306115}, {65396, 17306371}, | 
1972  |  |   {65397, 17306627}, {65398, 17306883}, {65399, 17307139}, {65400, 17307395}, | 
1973  |  |   {65401, 17307651}, {65402, 17199107}, {65403, 17307907}, {65404, 17308163}, | 
1974  |  |   {65405, 17308419}, {65406, 17308675}, {65407, 17308931}, {65408, 17309187}, | 
1975  |  |   {65409, 17309443}, {65410, 17309699}, {65411, 17309955}, {65412, 17199363}, | 
1976  |  |   {65413, 17310211}, {65414, 17310467}, {65415, 17310723}, {65416, 17310979}, | 
1977  |  |   {65417, 17311235}, {65418, 17311491}, {65419, 17311747}, {65420, 17312003}, | 
1978  |  |   {65421, 17312259}, {65422, 17312515}, {65423, 17312771}, {65424, 17313027}, | 
1979  |  |   {65425, 17313283}, {65426, 17313539}, {65427, 17313795}, {65428, 17314051}, | 
1980  |  |   {65429, 17314307}, {65430, 17314563}, {65431, 17314819}, {65432, 17315075}, | 
1981  |  |   {65433, 17315331}, {65434, 17315587}, {65435, 17315843}, {65436, 17316099}, | 
1982  |  |   {65437, 17319939}, {65438, 17197827}, {65439, 17198339}, {65440, 2}, | 
1983  |  |   {65441, 17199619}, {65442, 17199875}, {65443, 17200131}, {65444, 17200387}, | 
1984  |  |   {65445, 17200643}, {65446, 17200899}, {65447, 17201155}, {65448, 17201411}, | 
1985  |  |   {65449, 17201667}, {65450, 17201923}, {65451, 17202179}, {65452, 17202435}, | 
1986  |  |   {65453, 17202691}, {65454, 17202947}, {65455, 17203203}, {65456, 17203459}, | 
1987  |  |   {65457, 17203715}, {65458, 17203971}, {65459, 17204227}, {65460, 17204483}, | 
1988  |  |   {65461, 17204739}, {65462, 17204995}, {65463, 17205251}, {65464, 17205507}, | 
1989  |  |   {65465, 17205763}, {65466, 17206019}, {65467, 17206275}, {65468, 17206531}, | 
1990  |  |   {65469, 17206787}, {65470, 17207043}, {65471, 2}, {65474, 17207299}, | 
1991  |  |   {65475, 17207555}, {65476, 17207811}, {65477, 17208067}, {65478, 17208323}, | 
1992  |  |   {65479, 17208579}, {65480, 2}, {65482, 17208835}, {65483, 17209091}, | 
1993  |  |   {65484, 17209347}, {65485, 17209603}, {65486, 17209859}, {65487, 17210115}, | 
1994  |  |   {65488, 2}, {65490, 17210371}, {65491, 17210627}, {65492, 17210883}, | 
1995  |  |   {65493, 17211139}, {65494, 17211395}, {65495, 17211651}, {65496, 2}, | 
1996  |  |   {65498, 17211907}, {65499, 17212163}, {65500, 17212419}, {65501, 2}, | 
1997  |  |   {65504, 17863427}, {65505, 17863683}, {65506, 17863939}, {65507, 33561859}, | 
1998  |  |   {65508, 17864195}, {65509, 17864451}, {65510, 17864707}, {65511, 2}, | 
1999  |  |   {65512, 17864963}, {65513, 17865219}, {65514, 17865475}, {65515, 17865731}, | 
2000  |  |   {65516, 17865987}, {65517, 17866243}, {65518, 17866499}, {65519, 2}, | 
2001  |  |   {65536, 1}, {65548, 2}, {65549, 1}, {65575, 2}, | 
2002  |  |   {65576, 1}, {65595, 2}, {65596, 1}, {65598, 2}, | 
2003  |  |   {65599, 1}, {65614, 2}, {65616, 1}, {65630, 2}, | 
2004  |  |   {65664, 1}, {65787, 2}, {65792, 1}, {65795, 2}, | 
2005  |  |   {65799, 1}, {65844, 2}, {65847, 1}, {65935, 2}, | 
2006  |  |   {65936, 1}, {65949, 2}, {65952, 1}, {65953, 2}, | 
2007  |  |   {66000, 1}, {66046, 2}, {66176, 1}, {66205, 2}, | 
2008  |  |   {66208, 1}, {66257, 2}, {66272, 1}, {66300, 2}, | 
2009  |  |   {66304, 1}, {66340, 2}, {66349, 1}, {66379, 2}, | 
2010  |  |   {66384, 1}, {66427, 2}, {66432, 1}, {66462, 2}, | 
2011  |  |   {66463, 1}, {66500, 2}, {66504, 1}, {66518, 2}, | 
2012  |  |   {66560, 17866755}, {66561, 17867011}, {66562, 17867267}, {66563, 17867523}, | 
2013  |  |   {66564, 17867779}, {66565, 17868035}, {66566, 17868291}, {66567, 17868547}, | 
2014  |  |   {66568, 17868803}, {66569, 17869059}, {66570, 17869315}, {66571, 17869571}, | 
2015  |  |   {66572, 17869827}, {66573, 17870083}, {66574, 17870339}, {66575, 17870595}, | 
2016  |  |   {66576, 17870851}, {66577, 17871107}, {66578, 17871363}, {66579, 17871619}, | 
2017  |  |   {66580, 17871875}, {66581, 17872131}, {66582, 17872387}, {66583, 17872643}, | 
2018  |  |   {66584, 17872899}, {66585, 17873155}, {66586, 17873411}, {66587, 17873667}, | 
2019  |  |   {66588, 17873923}, {66589, 17874179}, {66590, 17874435}, {66591, 17874691}, | 
2020  |  |   {66592, 17874947}, {66593, 17875203}, {66594, 17875459}, {66595, 17875715}, | 
2021  |  |   {66596, 17875971}, {66597, 17876227}, {66598, 17876483}, {66599, 17876739}, | 
2022  |  |   {66600, 1}, {66718, 2}, {66720, 1}, {66730, 2}, | 
2023  |  |   {66736, 17876995}, {66737, 17877251}, {66738, 17877507}, {66739, 17877763}, | 
2024  |  |   {66740, 17878019}, {66741, 17878275}, {66742, 17878531}, {66743, 17878787}, | 
2025  |  |   {66744, 17879043}, {66745, 17879299}, {66746, 17879555}, {66747, 17879811}, | 
2026  |  |   {66748, 17880067}, {66749, 17880323}, {66750, 17880579}, {66751, 17880835}, | 
2027  |  |   {66752, 17881091}, {66753, 17881347}, {66754, 17881603}, {66755, 17881859}, | 
2028  |  |   {66756, 17882115}, {66757, 17882371}, {66758, 17882627}, {66759, 17882883}, | 
2029  |  |   {66760, 17883139}, {66761, 17883395}, {66762, 17883651}, {66763, 17883907}, | 
2030  |  |   {66764, 17884163}, {66765, 17884419}, {66766, 17884675}, {66767, 17884931}, | 
2031  |  |   {66768, 17885187}, {66769, 17885443}, {66770, 17885699}, {66771, 17885955}, | 
2032  |  |   {66772, 2}, {66776, 1}, {66812, 2}, {66816, 1}, | 
2033  |  |   {66856, 2}, {66864, 1}, {66916, 2}, {66927, 1}, | 
2034  |  |   {66928, 17886211}, {66929, 17886467}, {66930, 17886723}, {66931, 17886979}, | 
2035  |  |   {66932, 17887235}, {66933, 17887491}, {66934, 17887747}, {66935, 17888003}, | 
2036  |  |   {66936, 17888259}, {66937, 17888515}, {66938, 17888771}, {66939, 2}, | 
2037  |  |   {66940, 17889027}, {66941, 17889283}, {66942, 17889539}, {66943, 17889795}, | 
2038  |  |   {66944, 17890051}, {66945, 17890307}, {66946, 17890563}, {66947, 17890819}, | 
2039  |  |   {66948, 17891075}, {66949, 17891331}, {66950, 17891587}, {66951, 17891843}, | 
2040  |  |   {66952, 17892099}, {66953, 17892355}, {66954, 17892611}, {66955, 2}, | 
2041  |  |   {66956, 17892867}, {66957, 17893123}, {66958, 17893379}, {66959, 17893635}, | 
2042  |  |   {66960, 17893891}, {66961, 17894147}, {66962, 17894403}, {66963, 2}, | 
2043  |  |   {66964, 17894659}, {66965, 17894915}, {66966, 2}, {66967, 1}, | 
2044  |  |   {66978, 2}, {66979, 1}, {66994, 2}, {66995, 1}, | 
2045  |  |   {67002, 2}, {67003, 1}, {67005, 2}, {67072, 1}, | 
2046  |  |   {67383, 2}, {67392, 1}, {67414, 2}, {67424, 1}, | 
2047  |  |   {67432, 2}, {67456, 1}, {67457, 17895171}, {67458, 17895427}, | 
2048  |  |   {67459, 16791043}, {67460, 17895683}, {67461, 16814083}, {67462, 2}, | 
2049  |  |   {67463, 17895939}, {67464, 17896195}, {67465, 17896451}, {67466, 17896707}, | 
2050  |  |   {67467, 16815363}, {67468, 16815619}, {67469, 17896963}, {67470, 17897219}, | 
2051  |  |   {67471, 17897475}, {67472, 17897731}, {67473, 17897987}, {67474, 17898243}, | 
2052  |  |   {67475, 16817155}, {67476, 17898499}, {67477, 16802051}, {67478, 17898755}, | 
2053  |  |   {67479, 17899011}, {67480, 17899267}, {67481, 17899523}, {67482, 17899779}, | 
2054  |  |   {67483, 17512963}, {67484, 17900035}, {67485, 17900291}, {67486, 17900547}, | 
2055  |  |   {67487, 17900803}, {67488, 17901059}, {67489, 17901315}, {67490, 16795395}, | 
2056  |  |   {67491, 17901571}, {67492, 17901827}, {67493, 16781315}, {67494, 17902083}, | 
2057  |  |   {67495, 17902339}, {67496, 17125379}, {67497, 17902595}, {67498, 16819971}, | 
2058  |  |   {67499, 17902851}, {67500, 17903107}, {67501, 17903363}, {67502, 17903619}, | 
2059  |  |   {67503, 16820995}, {67504, 17903875}, {67505, 2}, {67506, 17904131}, | 
2060  |  |   {67507, 17904387}, {67508, 17904643}, {67509, 17904899}, {67510, 17905155}, | 
2061  |  |   {67511, 17905411}, {67512, 17905667}, {67513, 17905923}, {67514, 17906179}, | 
2062  |  |   {67515, 2}, {67584, 1}, {67590, 2}, {67592, 1}, | 
2063  |  |   {67593, 2}, {67594, 1}, {67638, 2}, {67639, 1}, | 
2064  |  |   {67641, 2}, {67644, 1}, {67645, 2}, {67647, 1}, | 
2065  |  |   {67670, 2}, {67671, 1}, {67743, 2}, {67751, 1}, | 
2066  |  |   {67760, 2}, {67808, 1}, {67827, 2}, {67828, 1}, | 
2067  |  |   {67830, 2}, {67835, 1}, {67868, 2}, {67871, 1}, | 
2068  |  |   {67898, 2}, {67903, 1}, {67904, 2}, {67968, 1}, | 
2069  |  |   {68024, 2}, {68028, 1}, {68048, 2}, {68050, 1}, | 
2070  |  |   {68100, 2}, {68101, 1}, {68103, 2}, {68108, 1}, | 
2071  |  |   {68116, 2}, {68117, 1}, {68120, 2}, {68121, 1}, | 
2072  |  |   {68150, 2}, {68152, 1}, {68155, 2}, {68159, 1}, | 
2073  |  |   {68169, 2}, {68176, 1}, {68185, 2}, {68192, 1}, | 
2074  |  |   {68256, 2}, {68288, 1}, {68327, 2}, {68331, 1}, | 
2075  |  |   {68343, 2}, {68352, 1}, {68406, 2}, {68409, 1}, | 
2076  |  |   {68438, 2}, {68440, 1}, {68467, 2}, {68472, 1}, | 
2077  |  |   {68498, 2}, {68505, 1}, {68509, 2}, {68521, 1}, | 
2078  |  |   {68528, 2}, {68608, 1}, {68681, 2}, {68736, 17906435}, | 
2079  |  |   {68737, 17906691}, {68738, 17906947}, {68739, 17907203}, {68740, 17907459}, | 
2080  |  |   {68741, 17907715}, {68742, 17907971}, {68743, 17908227}, {68744, 17908483}, | 
2081  |  |   {68745, 17908739}, {68746, 17908995}, {68747, 17909251}, {68748, 17909507}, | 
2082  |  |   {68749, 17909763}, {68750, 17910019}, {68751, 17910275}, {68752, 17910531}, | 
2083  |  |   {68753, 17910787}, {68754, 17911043}, {68755, 17911299}, {68756, 17911555}, | 
2084  |  |   {68757, 17911811}, {68758, 17912067}, {68759, 17912323}, {68760, 17912579}, | 
2085  |  |   {68761, 17912835}, {68762, 17913091}, {68763, 17913347}, {68764, 17913603}, | 
2086  |  |   {68765, 17913859}, {68766, 17914115}, {68767, 17914371}, {68768, 17914627}, | 
2087  |  |   {68769, 17914883}, {68770, 17915139}, {68771, 17915395}, {68772, 17915651}, | 
2088  |  |   {68773, 17915907}, {68774, 17916163}, {68775, 17916419}, {68776, 17916675}, | 
2089  |  |   {68777, 17916931}, {68778, 17917187}, {68779, 17917443}, {68780, 17917699}, | 
2090  |  |   {68781, 17917955}, {68782, 17918211}, {68783, 17918467}, {68784, 17918723}, | 
2091  |  |   {68785, 17918979}, {68786, 17919235}, {68787, 2}, {68800, 1}, | 
2092  |  |   {68851, 2}, {68858, 1}, {68904, 2}, {68912, 1}, | 
2093  |  |   {68922, 2}, {69216, 1}, {69247, 2}, {69248, 1}, | 
2094  |  |   {69290, 2}, {69291, 1}, {69294, 2}, {69296, 1}, | 
2095  |  |   {69298, 2}, {69373, 1}, {69416, 2}, {69424, 1}, | 
2096  |  |   {69466, 2}, {69488, 1}, {69514, 2}, {69552, 1}, | 
2097  |  |   {69580, 2}, {69600, 1}, {69623, 2}, {69632, 1}, | 
2098  |  |   {69710, 2}, {69714, 1}, {69750, 2}, {69759, 1}, | 
2099  |  |   {69821, 2}, {69822, 1}, {69827, 2}, {69840, 1}, | 
2100  |  |   {69865, 2}, {69872, 1}, {69882, 2}, {69888, 1}, | 
2101  |  |   {69941, 2}, {69942, 1}, {69960, 2}, {69968, 1}, | 
2102  |  |   {70007, 2}, {70016, 1}, {70112, 2}, {70113, 1}, | 
2103  |  |   {70133, 2}, {70144, 1}, {70162, 2}, {70163, 1}, | 
2104  |  |   {70210, 2}, {70272, 1}, {70279, 2}, {70280, 1}, | 
2105  |  |   {70281, 2}, {70282, 1}, {70286, 2}, {70287, 1}, | 
2106  |  |   {70302, 2}, {70303, 1}, {70314, 2}, {70320, 1}, | 
2107  |  |   {70379, 2}, {70384, 1}, {70394, 2}, {70400, 1}, | 
2108  |  |   {70404, 2}, {70405, 1}, {70413, 2}, {70415, 1}, | 
2109  |  |   {70417, 2}, {70419, 1}, {70441, 2}, {70442, 1}, | 
2110  |  |   {70449, 2}, {70450, 1}, {70452, 2}, {70453, 1}, | 
2111  |  |   {70458, 2}, {70459, 1}, {70469, 2}, {70471, 1}, | 
2112  |  |   {70473, 2}, {70475, 1}, {70478, 2}, {70480, 1}, | 
2113  |  |   {70481, 2}, {70487, 1}, {70488, 2}, {70493, 1}, | 
2114  |  |   {70500, 2}, {70502, 1}, {70509, 2}, {70512, 1}, | 
2115  |  |   {70517, 2}, {70656, 1}, {70748, 2}, {70749, 1}, | 
2116  |  |   {70754, 2}, {70784, 1}, {70856, 2}, {70864, 1}, | 
2117  |  |   {70874, 2}, {71040, 1}, {71094, 2}, {71096, 1}, | 
2118  |  |   {71134, 2}, {71168, 1}, {71237, 2}, {71248, 1}, | 
2119  |  |   {71258, 2}, {71264, 1}, {71277, 2}, {71296, 1}, | 
2120  |  |   {71354, 2}, {71360, 1}, {71370, 2}, {71424, 1}, | 
2121  |  |   {71451, 2}, {71453, 1}, {71468, 2}, {71472, 1}, | 
2122  |  |   {71495, 2}, {71680, 1}, {71740, 2}, {71840, 17919491}, | 
2123  |  |   {71841, 17919747}, {71842, 17920003}, {71843, 17920259}, {71844, 17920515}, | 
2124  |  |   {71845, 17920771}, {71846, 17921027}, {71847, 17921283}, {71848, 17921539}, | 
2125  |  |   {71849, 17921795}, {71850, 17922051}, {71851, 17922307}, {71852, 17922563}, | 
2126  |  |   {71853, 17922819}, {71854, 17923075}, {71855, 17923331}, {71856, 17923587}, | 
2127  |  |   {71857, 17923843}, {71858, 17924099}, {71859, 17924355}, {71860, 17924611}, | 
2128  |  |   {71861, 17924867}, {71862, 17925123}, {71863, 17925379}, {71864, 17925635}, | 
2129  |  |   {71865, 17925891}, {71866, 17926147}, {71867, 17926403}, {71868, 17926659}, | 
2130  |  |   {71869, 17926915}, {71870, 17927171}, {71871, 17927427}, {71872, 1}, | 
2131  |  |   {71923, 2}, {71935, 1}, {71943, 2}, {71945, 1}, | 
2132  |  |   {71946, 2}, {71948, 1}, {71956, 2}, {71957, 1}, | 
2133  |  |   {71959, 2}, {71960, 1}, {71990, 2}, {71991, 1}, | 
2134  |  |   {71993, 2}, {71995, 1}, {72007, 2}, {72016, 1}, | 
2135  |  |   {72026, 2}, {72096, 1}, {72104, 2}, {72106, 1}, | 
2136  |  |   {72152, 2}, {72154, 1}, {72165, 2}, {72192, 1}, | 
2137  |  |   {72264, 2}, {72272, 1}, {72355, 2}, {72368, 1}, | 
2138  |  |   {72441, 2}, {72448, 1}, {72458, 2}, {72704, 1}, | 
2139  |  |   {72713, 2}, {72714, 1}, {72759, 2}, {72760, 1}, | 
2140  |  |   {72774, 2}, {72784, 1}, {72813, 2}, {72816, 1}, | 
2141  |  |   {72848, 2}, {72850, 1}, {72872, 2}, {72873, 1}, | 
2142  |  |   {72887, 2}, {72960, 1}, {72967, 2}, {72968, 1}, | 
2143  |  |   {72970, 2}, {72971, 1}, {73015, 2}, {73018, 1}, | 
2144  |  |   {73019, 2}, {73020, 1}, {73022, 2}, {73023, 1}, | 
2145  |  |   {73032, 2}, {73040, 1}, {73050, 2}, {73056, 1}, | 
2146  |  |   {73062, 2}, {73063, 1}, {73065, 2}, {73066, 1}, | 
2147  |  |   {73103, 2}, {73104, 1}, {73106, 2}, {73107, 1}, | 
2148  |  |   {73113, 2}, {73120, 1}, {73130, 2}, {73440, 1}, | 
2149  |  |   {73465, 2}, {73472, 1}, {73489, 2}, {73490, 1}, | 
2150  |  |   {73531, 2}, {73534, 1}, {73562, 2}, {73648, 1}, | 
2151  |  |   {73649, 2}, {73664, 1}, {73714, 2}, {73727, 1}, | 
2152  |  |   {74650, 2}, {74752, 1}, {74863, 2}, {74864, 1}, | 
2153  |  |   {74869, 2}, {74880, 1}, {75076, 2}, {77712, 1}, | 
2154  |  |   {77811, 2}, {77824, 1}, {78896, 2}, {78912, 1}, | 
2155  |  |   {78934, 2}, {82944, 1}, {83527, 2}, {92160, 1}, | 
2156  |  |   {92729, 2}, {92736, 1}, {92767, 2}, {92768, 1}, | 
2157  |  |   {92778, 2}, {92782, 1}, {92863, 2}, {92864, 1}, | 
2158  |  |   {92874, 2}, {92880, 1}, {92910, 2}, {92912, 1}, | 
2159  |  |   {92918, 2}, {92928, 1}, {92998, 2}, {93008, 1}, | 
2160  |  |   {93018, 2}, {93019, 1}, {93026, 2}, {93027, 1}, | 
2161  |  |   {93048, 2}, {93053, 1}, {93072, 2}, {93760, 17927683}, | 
2162  |  |   {93761, 17927939}, {93762, 17928195}, {93763, 17928451}, {93764, 17928707}, | 
2163  |  |   {93765, 17928963}, {93766, 17929219}, {93767, 17929475}, {93768, 17929731}, | 
2164  |  |   {93769, 17929987}, {93770, 17930243}, {93771, 17930499}, {93772, 17930755}, | 
2165  |  |   {93773, 17931011}, {93774, 17931267}, {93775, 17931523}, {93776, 17931779}, | 
2166  |  |   {93777, 17932035}, {93778, 17932291}, {93779, 17932547}, {93780, 17932803}, | 
2167  |  |   {93781, 17933059}, {93782, 17933315}, {93783, 17933571}, {93784, 17933827}, | 
2168  |  |   {93785, 17934083}, {93786, 17934339}, {93787, 17934595}, {93788, 17934851}, | 
2169  |  |   {93789, 17935107}, {93790, 17935363}, {93791, 17935619}, {93792, 1}, | 
2170  |  |   {93851, 2}, {93952, 1}, {94027, 2}, {94031, 1}, | 
2171  |  |   {94088, 2}, {94095, 1}, {94112, 2}, {94176, 1}, | 
2172  |  |   {94181, 2}, {94192, 1}, {94194, 2}, {94208, 1}, | 
2173  |  |   {100344, 2}, {100352, 1}, {101590, 2}, {101632, 1}, | 
2174  |  |   {101641, 2}, {110576, 1}, {110580, 2}, {110581, 1}, | 
2175  |  |   {110588, 2}, {110589, 1}, {110591, 2}, {110592, 1}, | 
2176  |  |   {110883, 2}, {110898, 1}, {110899, 2}, {110928, 1}, | 
2177  |  |   {110931, 2}, {110933, 1}, {110934, 2}, {110948, 1}, | 
2178  |  |   {110952, 2}, {110960, 1}, {111356, 2}, {113664, 1}, | 
2179  |  |   {113771, 2}, {113776, 1}, {113789, 2}, {113792, 1}, | 
2180  |  |   {113801, 2}, {113808, 1}, {113818, 2}, {113820, 1}, | 
2181  |  |   {113824, 0}, {113828, 2}, {118528, 1}, {118574, 2}, | 
2182  |  |   {118576, 1}, {118599, 2}, {118608, 1}, {118724, 2}, | 
2183  |  |   {118784, 1}, {119030, 2}, {119040, 1}, {119079, 2}, | 
2184  |  |   {119081, 1}, {119134, 34713091}, {119135, 34713603}, {119136, 51491331}, | 
2185  |  |   {119137, 51492099}, {119138, 51492867}, {119139, 51493635}, {119140, 51494403}, | 
2186  |  |   {119141, 1}, {119155, 2}, {119163, 1}, {119227, 34717955}, | 
2187  |  |   {119228, 34718467}, {119229, 51496195}, {119230, 51496963}, {119231, 51497731}, | 
2188  |  |   {119232, 51498499}, {119233, 1}, {119275, 2}, {119296, 1}, | 
2189  |  |   {119366, 2}, {119488, 1}, {119508, 2}, {119520, 1}, | 
2190  |  |   {119540, 2}, {119552, 1}, {119639, 2}, {119648, 1}, | 
2191  |  |   {119673, 2}, {119808, 16777219}, {119809, 16777475}, {119810, 16777731}, | 
2192  |  |   {119811, 16777987}, {119812, 16778243}, {119813, 16778499}, {119814, 16778755}, | 
2193  |  |   {119815, 16779011}, {119816, 16779267}, {119817, 16779523}, {119818, 16779779}, | 
2194  |  |   {119819, 16780035}, {119820, 16780291}, {119821, 16780547}, {119822, 16780803}, | 
2195  |  |   {119823, 16781059}, {119824, 16781315}, {119825, 16781571}, {119826, 16781827}, | 
2196  |  |   {119827, 16782083}, {119828, 16782339}, {119829, 16782595}, {119830, 16782851}, | 
2197  |  |   {119831, 16783107}, {119832, 16783363}, {119833, 16783619}, {119834, 16777219}, | 
2198  |  |   {119835, 16777475}, {119836, 16777731}, {119837, 16777987}, {119838, 16778243}, | 
2199  |  |   {119839, 16778499}, {119840, 16778755}, {119841, 16779011}, {119842, 16779267}, | 
2200  |  |   {119843, 16779523}, {119844, 16779779}, {119845, 16780035}, {119846, 16780291}, | 
2201  |  |   {119847, 16780547}, {119848, 16780803}, {119849, 16781059}, {119850, 16781315}, | 
2202  |  |   {119851, 16781571}, {119852, 16781827}, {119853, 16782083}, {119854, 16782339}, | 
2203  |  |   {119855, 16782595}, {119856, 16782851}, {119857, 16783107}, {119858, 16783363}, | 
2204  |  |   {119859, 16783619}, {119860, 16777219}, {119861, 16777475}, {119862, 16777731}, | 
2205  |  |   {119863, 16777987}, {119864, 16778243}, {119865, 16778499}, {119866, 16778755}, | 
2206  |  |   {119867, 16779011}, {119868, 16779267}, {119869, 16779523}, {119870, 16779779}, | 
2207  |  |   {119871, 16780035}, {119872, 16780291}, {119873, 16780547}, {119874, 16780803}, | 
2208  |  |   {119875, 16781059}, {119876, 16781315}, {119877, 16781571}, {119878, 16781827}, | 
2209  |  |   {119879, 16782083}, {119880, 16782339}, {119881, 16782595}, {119882, 16782851}, | 
2210  |  |   {119883, 16783107}, {119884, 16783363}, {119885, 16783619}, {119886, 16777219}, | 
2211  |  |   {119887, 16777475}, {119888, 16777731}, {119889, 16777987}, {119890, 16778243}, | 
2212  |  |   {119891, 16778499}, {119892, 16778755}, {119893, 2}, {119894, 16779267}, | 
2213  |  |   {119895, 16779523}, {119896, 16779779}, {119897, 16780035}, {119898, 16780291}, | 
2214  |  |   {119899, 16780547}, {119900, 16780803}, {119901, 16781059}, {119902, 16781315}, | 
2215  |  |   {119903, 16781571}, {119904, 16781827}, {119905, 16782083}, {119906, 16782339}, | 
2216  |  |   {119907, 16782595}, {119908, 16782851}, {119909, 16783107}, {119910, 16783363}, | 
2217  |  |   {119911, 16783619}, {119912, 16777219}, {119913, 16777475}, {119914, 16777731}, | 
2218  |  |   {119915, 16777987}, {119916, 16778243}, {119917, 16778499}, {119918, 16778755}, | 
2219  |  |   {119919, 16779011}, {119920, 16779267}, {119921, 16779523}, {119922, 16779779}, | 
2220  |  |   {119923, 16780035}, {119924, 16780291}, {119925, 16780547}, {119926, 16780803}, | 
2221  |  |   {119927, 16781059}, {119928, 16781315}, {119929, 16781571}, {119930, 16781827}, | 
2222  |  |   {119931, 16782083}, {119932, 16782339}, {119933, 16782595}, {119934, 16782851}, | 
2223  |  |   {119935, 16783107}, {119936, 16783363}, {119937, 16783619}, {119938, 16777219}, | 
2224  |  |   {119939, 16777475}, {119940, 16777731}, {119941, 16777987}, {119942, 16778243}, | 
2225  |  |   {119943, 16778499}, {119944, 16778755}, {119945, 16779011}, {119946, 16779267}, | 
2226  |  |   {119947, 16779523}, {119948, 16779779}, {119949, 16780035}, {119950, 16780291}, | 
2227  |  |   {119951, 16780547}, {119952, 16780803}, {119953, 16781059}, {119954, 16781315}, | 
2228  |  |   {119955, 16781571}, {119956, 16781827}, {119957, 16782083}, {119958, 16782339}, | 
2229  |  |   {119959, 16782595}, {119960, 16782851}, {119961, 16783107}, {119962, 16783363}, | 
2230  |  |   {119963, 16783619}, {119964, 16777219}, {119965, 2}, {119966, 16777731}, | 
2231  |  |   {119967, 16777987}, {119968, 2}, {119970, 16778755}, {119971, 2}, | 
2232  |  |   {119973, 16779523}, {119974, 16779779}, {119975, 2}, {119977, 16780547}, | 
2233  |  |   {119978, 16780803}, {119979, 16781059}, {119980, 16781315}, {119981, 2}, | 
2234  |  |   {119982, 16781827}, {119983, 16782083}, {119984, 16782339}, {119985, 16782595}, | 
2235  |  |   {119986, 16782851}, {119987, 16783107}, {119988, 16783363}, {119989, 16783619}, | 
2236  |  |   {119990, 16777219}, {119991, 16777475}, {119992, 16777731}, {119993, 16777987}, | 
2237  |  |   {119994, 2}, {119995, 16778499}, {119996, 2}, {119997, 16779011}, | 
2238  |  |   {119998, 16779267}, {119999, 16779523}, {120000, 16779779}, {120001, 16780035}, | 
2239  |  |   {120002, 16780291}, {120003, 16780547}, {120004, 2}, {120005, 16781059}, | 
2240  |  |   {120006, 16781315}, {120007, 16781571}, {120008, 16781827}, {120009, 16782083}, | 
2241  |  |   {120010, 16782339}, {120011, 16782595}, {120012, 16782851}, {120013, 16783107}, | 
2242  |  |   {120014, 16783363}, {120015, 16783619}, {120016, 16777219}, {120017, 16777475}, | 
2243  |  |   {120018, 16777731}, {120019, 16777987}, {120020, 16778243}, {120021, 16778499}, | 
2244  |  |   {120022, 16778755}, {120023, 16779011}, {120024, 16779267}, {120025, 16779523}, | 
2245  |  |   {120026, 16779779}, {120027, 16780035}, {120028, 16780291}, {120029, 16780547}, | 
2246  |  |   {120030, 16780803}, {120031, 16781059}, {120032, 16781315}, {120033, 16781571}, | 
2247  |  |   {120034, 16781827}, {120035, 16782083}, {120036, 16782339}, {120037, 16782595}, | 
2248  |  |   {120038, 16782851}, {120039, 16783107}, {120040, 16783363}, {120041, 16783619}, | 
2249  |  |   {120042, 16777219}, {120043, 16777475}, {120044, 16777731}, {120045, 16777987}, | 
2250  |  |   {120046, 16778243}, {120047, 16778499}, {120048, 16778755}, {120049, 16779011}, | 
2251  |  |   {120050, 16779267}, {120051, 16779523}, {120052, 16779779}, {120053, 16780035}, | 
2252  |  |   {120054, 16780291}, {120055, 16780547}, {120056, 16780803}, {120057, 16781059}, | 
2253  |  |   {120058, 16781315}, {120059, 16781571}, {120060, 16781827}, {120061, 16782083}, | 
2254  |  |   {120062, 16782339}, {120063, 16782595}, {120064, 16782851}, {120065, 16783107}, | 
2255  |  |   {120066, 16783363}, {120067, 16783619}, {120068, 16777219}, {120069, 16777475}, | 
2256  |  |   {120070, 2}, {120071, 16777987}, {120072, 16778243}, {120073, 16778499}, | 
2257  |  |   {120074, 16778755}, {120075, 2}, {120077, 16779523}, {120078, 16779779}, | 
2258  |  |   {120079, 16780035}, {120080, 16780291}, {120081, 16780547}, {120082, 16780803}, | 
2259  |  |   {120083, 16781059}, {120084, 16781315}, {120085, 2}, {120086, 16781827}, | 
2260  |  |   {120087, 16782083}, {120088, 16782339}, {120089, 16782595}, {120090, 16782851}, | 
2261  |  |   {120091, 16783107}, {120092, 16783363}, {120093, 2}, {120094, 16777219}, | 
2262  |  |   {120095, 16777475}, {120096, 16777731}, {120097, 16777987}, {120098, 16778243}, | 
2263  |  |   {120099, 16778499}, {120100, 16778755}, {120101, 16779011}, {120102, 16779267}, | 
2264  |  |   {120103, 16779523}, {120104, 16779779}, {120105, 16780035}, {120106, 16780291}, | 
2265  |  |   {120107, 16780547}, {120108, 16780803}, {120109, 16781059}, {120110, 16781315}, | 
2266  |  |   {120111, 16781571}, {120112, 16781827}, {120113, 16782083}, {120114, 16782339}, | 
2267  |  |   {120115, 16782595}, {120116, 16782851}, {120117, 16783107}, {120118, 16783363}, | 
2268  |  |   {120119, 16783619}, {120120, 16777219}, {120121, 16777475}, {120122, 2}, | 
2269  |  |   {120123, 16777987}, {120124, 16778243}, {120125, 16778499}, {120126, 16778755}, | 
2270  |  |   {120127, 2}, {120128, 16779267}, {120129, 16779523}, {120130, 16779779}, | 
2271  |  |   {120131, 16780035}, {120132, 16780291}, {120133, 2}, {120134, 16780803}, | 
2272  |  |   {120135, 2}, {120138, 16781827}, {120139, 16782083}, {120140, 16782339}, | 
2273  |  |   {120141, 16782595}, {120142, 16782851}, {120143, 16783107}, {120144, 16783363}, | 
2274  |  |   {120145, 2}, {120146, 16777219}, {120147, 16777475}, {120148, 16777731}, | 
2275  |  |   {120149, 16777987}, {120150, 16778243}, {120151, 16778499}, {120152, 16778755}, | 
2276  |  |   {120153, 16779011}, {120154, 16779267}, {120155, 16779523}, {120156, 16779779}, | 
2277  |  |   {120157, 16780035}, {120158, 16780291}, {120159, 16780547}, {120160, 16780803}, | 
2278  |  |   {120161, 16781059}, {120162, 16781315}, {120163, 16781571}, {120164, 16781827}, | 
2279  |  |   {120165, 16782083}, {120166, 16782339}, {120167, 16782595}, {120168, 16782851}, | 
2280  |  |   {120169, 16783107}, {120170, 16783363}, {120171, 16783619}, {120172, 16777219}, | 
2281  |  |   {120173, 16777475}, {120174, 16777731}, {120175, 16777987}, {120176, 16778243}, | 
2282  |  |   {120177, 16778499}, {120178, 16778755}, {120179, 16779011}, {120180, 16779267}, | 
2283  |  |   {120181, 16779523}, {120182, 16779779}, {120183, 16780035}, {120184, 16780291}, | 
2284  |  |   {120185, 16780547}, {120186, 16780803}, {120187, 16781059}, {120188, 16781315}, | 
2285  |  |   {120189, 16781571}, {120190, 16781827}, {120191, 16782083}, {120192, 16782339}, | 
2286  |  |   {120193, 16782595}, {120194, 16782851}, {120195, 16783107}, {120196, 16783363}, | 
2287  |  |   {120197, 16783619}, {120198, 16777219}, {120199, 16777475}, {120200, 16777731}, | 
2288  |  |   {120201, 16777987}, {120202, 16778243}, {120203, 16778499}, {120204, 16778755}, | 
2289  |  |   {120205, 16779011}, {120206, 16779267}, {120207, 16779523}, {120208, 16779779}, | 
2290  |  |   {120209, 16780035}, {120210, 16780291}, {120211, 16780547}, {120212, 16780803}, | 
2291  |  |   {120213, 16781059}, {120214, 16781315}, {120215, 16781571}, {120216, 16781827}, | 
2292  |  |   {120217, 16782083}, {120218, 16782339}, {120219, 16782595}, {120220, 16782851}, | 
2293  |  |   {120221, 16783107}, {120222, 16783363}, {120223, 16783619}, {120224, 16777219}, | 
2294  |  |   {120225, 16777475}, {120226, 16777731}, {120227, 16777987}, {120228, 16778243}, | 
2295  |  |   {120229, 16778499}, {120230, 16778755}, {120231, 16779011}, {120232, 16779267}, | 
2296  |  |   {120233, 16779523}, {120234, 16779779}, {120235, 16780035}, {120236, 16780291}, | 
2297  |  |   {120237, 16780547}, {120238, 16780803}, {120239, 16781059}, {120240, 16781315}, | 
2298  |  |   {120241, 16781571}, {120242, 16781827}, {120243, 16782083}, {120244, 16782339}, | 
2299  |  |   {120245, 16782595}, {120246, 16782851}, {120247, 16783107}, {120248, 16783363}, | 
2300  |  |   {120249, 16783619}, {120250, 16777219}, {120251, 16777475}, {120252, 16777731}, | 
2301  |  |   {120253, 16777987}, {120254, 16778243}, {120255, 16778499}, {120256, 16778755}, | 
2302  |  |   {120257, 16779011}, {120258, 16779267}, {120259, 16779523}, {120260, 16779779}, | 
2303  |  |   {120261, 16780035}, {120262, 16780291}, {120263, 16780547}, {120264, 16780803}, | 
2304  |  |   {120265, 16781059}, {120266, 16781315}, {120267, 16781571}, {120268, 16781827}, | 
2305  |  |   {120269, 16782083}, {120270, 16782339}, {120271, 16782595}, {120272, 16782851}, | 
2306  |  |   {120273, 16783107}, {120274, 16783363}, {120275, 16783619}, {120276, 16777219}, | 
2307  |  |   {120277, 16777475}, {120278, 16777731}, {120279, 16777987}, {120280, 16778243}, | 
2308  |  |   {120281, 16778499}, {120282, 16778755}, {120283, 16779011}, {120284, 16779267}, | 
2309  |  |   {120285, 16779523}, {120286, 16779779}, {120287, 16780035}, {120288, 16780291}, | 
2310  |  |   {120289, 16780547}, {120290, 16780803}, {120291, 16781059}, {120292, 16781315}, | 
2311  |  |   {120293, 16781571}, {120294, 16781827}, {120295, 16782083}, {120296, 16782339}, | 
2312  |  |   {120297, 16782595}, {120298, 16782851}, {120299, 16783107}, {120300, 16783363}, | 
2313  |  |   {120301, 16783619}, {120302, 16777219}, {120303, 16777475}, {120304, 16777731}, | 
2314  |  |   {120305, 16777987}, {120306, 16778243}, {120307, 16778499}, {120308, 16778755}, | 
2315  |  |   {120309, 16779011}, {120310, 16779267}, {120311, 16779523}, {120312, 16779779}, | 
2316  |  |   {120313, 16780035}, {120314, 16780291}, {120315, 16780547}, {120316, 16780803}, | 
2317  |  |   {120317, 16781059}, {120318, 16781315}, {120319, 16781571}, {120320, 16781827}, | 
2318  |  |   {120321, 16782083}, {120322, 16782339}, {120323, 16782595}, {120324, 16782851}, | 
2319  |  |   {120325, 16783107}, {120326, 16783363}, {120327, 16783619}, {120328, 16777219}, | 
2320  |  |   {120329, 16777475}, {120330, 16777731}, {120331, 16777987}, {120332, 16778243}, | 
2321  |  |   {120333, 16778499}, {120334, 16778755}, {120335, 16779011}, {120336, 16779267}, | 
2322  |  |   {120337, 16779523}, {120338, 16779779}, {120339, 16780035}, {120340, 16780291}, | 
2323  |  |   {120341, 16780547}, {120342, 16780803}, {120343, 16781059}, {120344, 16781315}, | 
2324  |  |   {120345, 16781571}, {120346, 16781827}, {120347, 16782083}, {120348, 16782339}, | 
2325  |  |   {120349, 16782595}, {120350, 16782851}, {120351, 16783107}, {120352, 16783363}, | 
2326  |  |   {120353, 16783619}, {120354, 16777219}, {120355, 16777475}, {120356, 16777731}, | 
2327  |  |   {120357, 16777987}, {120358, 16778243}, {120359, 16778499}, {120360, 16778755}, | 
2328  |  |   {120361, 16779011}, {120362, 16779267}, {120363, 16779523}, {120364, 16779779}, | 
2329  |  |   {120365, 16780035}, {120366, 16780291}, {120367, 16780547}, {120368, 16780803}, | 
2330  |  |   {120369, 16781059}, {120370, 16781315}, {120371, 16781571}, {120372, 16781827}, | 
2331  |  |   {120373, 16782083}, {120374, 16782339}, {120375, 16782595}, {120376, 16782851}, | 
2332  |  |   {120377, 16783107}, {120378, 16783363}, {120379, 16783619}, {120380, 16777219}, | 
2333  |  |   {120381, 16777475}, {120382, 16777731}, {120383, 16777987}, {120384, 16778243}, | 
2334  |  |   {120385, 16778499}, {120386, 16778755}, {120387, 16779011}, {120388, 16779267}, | 
2335  |  |   {120389, 16779523}, {120390, 16779779}, {120391, 16780035}, {120392, 16780291}, | 
2336  |  |   {120393, 16780547}, {120394, 16780803}, {120395, 16781059}, {120396, 16781315}, | 
2337  |  |   {120397, 16781571}, {120398, 16781827}, {120399, 16782083}, {120400, 16782339}, | 
2338  |  |   {120401, 16782595}, {120402, 16782851}, {120403, 16783107}, {120404, 16783363}, | 
2339  |  |   {120405, 16783619}, {120406, 16777219}, {120407, 16777475}, {120408, 16777731}, | 
2340  |  |   {120409, 16777987}, {120410, 16778243}, {120411, 16778499}, {120412, 16778755}, | 
2341  |  |   {120413, 16779011}, {120414, 16779267}, {120415, 16779523}, {120416, 16779779}, | 
2342  |  |   {120417, 16780035}, {120418, 16780291}, {120419, 16780547}, {120420, 16780803}, | 
2343  |  |   {120421, 16781059}, {120422, 16781315}, {120423, 16781571}, {120424, 16781827}, | 
2344  |  |   {120425, 16782083}, {120426, 16782339}, {120427, 16782595}, {120428, 16782851}, | 
2345  |  |   {120429, 16783107}, {120430, 16783363}, {120431, 16783619}, {120432, 16777219}, | 
2346  |  |   {120433, 16777475}, {120434, 16777731}, {120435, 16777987}, {120436, 16778243}, | 
2347  |  |   {120437, 16778499}, {120438, 16778755}, {120439, 16779011}, {120440, 16779267}, | 
2348  |  |   {120441, 16779523}, {120442, 16779779}, {120443, 16780035}, {120444, 16780291}, | 
2349  |  |   {120445, 16780547}, {120446, 16780803}, {120447, 16781059}, {120448, 16781315}, | 
2350  |  |   {120449, 16781571}, {120450, 16781827}, {120451, 16782083}, {120452, 16782339}, | 
2351  |  |   {120453, 16782595}, {120454, 16782851}, {120455, 16783107}, {120456, 16783363}, | 
2352  |  |   {120457, 16783619}, {120458, 16777219}, {120459, 16777475}, {120460, 16777731}, | 
2353  |  |   {120461, 16777987}, {120462, 16778243}, {120463, 16778499}, {120464, 16778755}, | 
2354  |  |   {120465, 16779011}, {120466, 16779267}, {120467, 16779523}, {120468, 16779779}, | 
2355  |  |   {120469, 16780035}, {120470, 16780291}, {120471, 16780547}, {120472, 16780803}, | 
2356  |  |   {120473, 16781059}, {120474, 16781315}, {120475, 16781571}, {120476, 16781827}, | 
2357  |  |   {120477, 16782083}, {120478, 16782339}, {120479, 16782595}, {120480, 16782851}, | 
2358  |  |   {120481, 16783107}, {120482, 16783363}, {120483, 16783619}, {120484, 17944835}, | 
2359  |  |   {120485, 17945091}, {120486, 2}, {120488, 16851715}, {120489, 16851971}, | 
2360  |  |   {120490, 16852227}, {120491, 16852483}, {120492, 16852739}, {120493, 16852995}, | 
2361  |  |   {120494, 16853251}, {120495, 16853507}, {120496, 16846851}, {120497, 16853763}, | 
2362  |  |   {120498, 16854019}, {120499, 16786179}, {120500, 16854275}, {120501, 16854531}, | 
2363  |  |   {120502, 16854787}, {120503, 16855043}, {120504, 16855299}, {120505, 16853507}, | 
2364  |  |   {120506, 16855555}, {120507, 16855811}, {120508, 16856067}, {120509, 16856323}, | 
2365  |  |   {120510, 16856579}, {120511, 16856835}, {120512, 16857091}, {120513, 17945347}, | 
2366  |  |   {120514, 16851715}, {120515, 16851971}, {120516, 16852227}, {120517, 16852483}, | 
2367  |  |   {120518, 16852739}, {120519, 16852995}, {120520, 16853251}, {120521, 16853507}, | 
2368  |  |   {120522, 16846851}, {120523, 16853763}, {120524, 16854019}, {120525, 16786179}, | 
2369  |  |   {120526, 16854275}, {120527, 16854531}, {120528, 16854787}, {120529, 16855043}, | 
2370  |  |   {120530, 16855299}, {120531, 16855555}, {120533, 16855811}, {120534, 16856067}, | 
2371  |  |   {120535, 16856323}, {120536, 16856579}, {120537, 16856835}, {120538, 16857091}, | 
2372  |  |   {120539, 17945603}, {120540, 16852739}, {120541, 16853507}, {120542, 16853763}, | 
2373  |  |   {120543, 16856323}, {120544, 16855299}, {120545, 16855043}, {120546, 16851715}, | 
2374  |  |   {120547, 16851971}, {120548, 16852227}, {120549, 16852483}, {120550, 16852739}, | 
2375  |  |   {120551, 16852995}, {120552, 16853251}, {120553, 16853507}, {120554, 16846851}, | 
2376  |  |   {120555, 16853763}, {120556, 16854019}, {120557, 16786179}, {120558, 16854275}, | 
2377  |  |   {120559, 16854531}, {120560, 16854787}, {120561, 16855043}, {120562, 16855299}, | 
2378  |  |   {120563, 16853507}, {120564, 16855555}, {120565, 16855811}, {120566, 16856067}, | 
2379  |  |   {120567, 16856323}, {120568, 16856579}, {120569, 16856835}, {120570, 16857091}, | 
2380  |  |   {120571, 17945347}, {120572, 16851715}, {120573, 16851971}, {120574, 16852227}, | 
2381  |  |   {120575, 16852483}, {120576, 16852739}, {120577, 16852995}, {120578, 16853251}, | 
2382  |  |   {120579, 16853507}, {120580, 16846851}, {120581, 16853763}, {120582, 16854019}, | 
2383  |  |   {120583, 16786179}, {120584, 16854275}, {120585, 16854531}, {120586, 16854787}, | 
2384  |  |   {120587, 16855043}, {120588, 16855299}, {120589, 16855555}, {120591, 16855811}, | 
2385  |  |   {120592, 16856067}, {120593, 16856323}, {120594, 16856579}, {120595, 16856835}, | 
2386  |  |   {120596, 16857091}, {120597, 17945603}, {120598, 16852739}, {120599, 16853507}, | 
2387  |  |   {120600, 16853763}, {120601, 16856323}, {120602, 16855299}, {120603, 16855043}, | 
2388  |  |   {120604, 16851715}, {120605, 16851971}, {120606, 16852227}, {120607, 16852483}, | 
2389  |  |   {120608, 16852739}, {120609, 16852995}, {120610, 16853251}, {120611, 16853507}, | 
2390  |  |   {120612, 16846851}, {120613, 16853763}, {120614, 16854019}, {120615, 16786179}, | 
2391  |  |   {120616, 16854275}, {120617, 16854531}, {120618, 16854787}, {120619, 16855043}, | 
2392  |  |   {120620, 16855299}, {120621, 16853507}, {120622, 16855555}, {120623, 16855811}, | 
2393  |  |   {120624, 16856067}, {120625, 16856323}, {120626, 16856579}, {120627, 16856835}, | 
2394  |  |   {120628, 16857091}, {120629, 17945347}, {120630, 16851715}, {120631, 16851971}, | 
2395  |  |   {120632, 16852227}, {120633, 16852483}, {120634, 16852739}, {120635, 16852995}, | 
2396  |  |   {120636, 16853251}, {120637, 16853507}, {120638, 16846851}, {120639, 16853763}, | 
2397  |  |   {120640, 16854019}, {120641, 16786179}, {120642, 16854275}, {120643, 16854531}, | 
2398  |  |   {120644, 16854787}, {120645, 16855043}, {120646, 16855299}, {120647, 16855555}, | 
2399  |  |   {120649, 16855811}, {120650, 16856067}, {120651, 16856323}, {120652, 16856579}, | 
2400  |  |   {120653, 16856835}, {120654, 16857091}, {120655, 17945603}, {120656, 16852739}, | 
2401  |  |   {120657, 16853507}, {120658, 16853763}, {120659, 16856323}, {120660, 16855299}, | 
2402  |  |   {120661, 16855043}, {120662, 16851715}, {120663, 16851971}, {120664, 16852227}, | 
2403  |  |   {120665, 16852483}, {120666, 16852739}, {120667, 16852995}, {120668, 16853251}, | 
2404  |  |   {120669, 16853507}, {120670, 16846851}, {120671, 16853763}, {120672, 16854019}, | 
2405  |  |   {120673, 16786179}, {120674, 16854275}, {120675, 16854531}, {120676, 16854787}, | 
2406  |  |   {120677, 16855043}, {120678, 16855299}, {120679, 16853507}, {120680, 16855555}, | 
2407  |  |   {120681, 16855811}, {120682, 16856067}, {120683, 16856323}, {120684, 16856579}, | 
2408  |  |   {120685, 16856835}, {120686, 16857091}, {120687, 17945347}, {120688, 16851715}, | 
2409  |  |   {120689, 16851971}, {120690, 16852227}, {120691, 16852483}, {120692, 16852739}, | 
2410  |  |   {120693, 16852995}, {120694, 16853251}, {120695, 16853507}, {120696, 16846851}, | 
2411  |  |   {120697, 16853763}, {120698, 16854019}, {120699, 16786179}, {120700, 16854275}, | 
2412  |  |   {120701, 16854531}, {120702, 16854787}, {120703, 16855043}, {120704, 16855299}, | 
2413  |  |   {120705, 16855555}, {120707, 16855811}, {120708, 16856067}, {120709, 16856323}, | 
2414  |  |   {120710, 16856579}, {120711, 16856835}, {120712, 16857091}, {120713, 17945603}, | 
2415  |  |   {120714, 16852739}, {120715, 16853507}, {120716, 16853763}, {120717, 16856323}, | 
2416  |  |   {120718, 16855299}, {120719, 16855043}, {120720, 16851715}, {120721, 16851971}, | 
2417  |  |   {120722, 16852227}, {120723, 16852483}, {120724, 16852739}, {120725, 16852995}, | 
2418  |  |   {120726, 16853251}, {120727, 16853507}, {120728, 16846851}, {120729, 16853763}, | 
2419  |  |   {120730, 16854019}, {120731, 16786179}, {120732, 16854275}, {120733, 16854531}, | 
2420  |  |   {120734, 16854787}, {120735, 16855043}, {120736, 16855299}, {120737, 16853507}, | 
2421  |  |   {120738, 16855555}, {120739, 16855811}, {120740, 16856067}, {120741, 16856323}, | 
2422  |  |   {120742, 16856579}, {120743, 16856835}, {120744, 16857091}, {120745, 17945347}, | 
2423  |  |   {120746, 16851715}, {120747, 16851971}, {120748, 16852227}, {120749, 16852483}, | 
2424  |  |   {120750, 16852739}, {120751, 16852995}, {120752, 16853251}, {120753, 16853507}, | 
2425  |  |   {120754, 16846851}, {120755, 16853763}, {120756, 16854019}, {120757, 16786179}, | 
2426  |  |   {120758, 16854275}, {120759, 16854531}, {120760, 16854787}, {120761, 16855043}, | 
2427  |  |   {120762, 16855299}, {120763, 16855555}, {120765, 16855811}, {120766, 16856067}, | 
2428  |  |   {120767, 16856323}, {120768, 16856579}, {120769, 16856835}, {120770, 16857091}, | 
2429  |  |   {120771, 17945603}, {120772, 16852739}, {120773, 16853507}, {120774, 16853763}, | 
2430  |  |   {120775, 16856323}, {120776, 16855299}, {120777, 16855043}, {120778, 16858627}, | 
2431  |  |   {120780, 2}, {120782, 17035523}, {120783, 16786947}, {120784, 16785155}, | 
2432  |  |   {120785, 16785411}, {120786, 16787715}, {120787, 17035779}, {120788, 17036035}, | 
2433  |  |   {120789, 17036291}, {120790, 17036547}, {120791, 17036803}, {120792, 17035523}, | 
2434  |  |   {120793, 16786947}, {120794, 16785155}, {120795, 16785411}, {120796, 16787715}, | 
2435  |  |   {120797, 17035779}, {120798, 17036035}, {120799, 17036291}, {120800, 17036547}, | 
2436  |  |   {120801, 17036803}, {120802, 17035523}, {120803, 16786947}, {120804, 16785155}, | 
2437  |  |   {120805, 16785411}, {120806, 16787715}, {120807, 17035779}, {120808, 17036035}, | 
2438  |  |   {120809, 17036291}, {120810, 17036547}, {120811, 17036803}, {120812, 17035523}, | 
2439  |  |   {120813, 16786947}, {120814, 16785155}, {120815, 16785411}, {120816, 16787715}, | 
2440  |  |   {120817, 17035779}, {120818, 17036035}, {120819, 17036291}, {120820, 17036547}, | 
2441  |  |   {120821, 17036803}, {120822, 17035523}, {120823, 16786947}, {120824, 16785155}, | 
2442  |  |   {120825, 16785411}, {120826, 16787715}, {120827, 17035779}, {120828, 17036035}, | 
2443  |  |   {120829, 17036291}, {120830, 17036547}, {120831, 17036803}, {120832, 1}, | 
2444  |  |   {121484, 2}, {121499, 1}, {121504, 2}, {121505, 1}, | 
2445  |  |   {121520, 2}, {122624, 1}, {122655, 2}, {122661, 1}, | 
2446  |  |   {122667, 2}, {122880, 1}, {122887, 2}, {122888, 1}, | 
2447  |  |   {122905, 2}, {122907, 1}, {122914, 2}, {122915, 1}, | 
2448  |  |   {122917, 2}, {122918, 1}, {122923, 2}, {122928, 16866563}, | 
2449  |  |   {122929, 16866819}, {122930, 16867075}, {122931, 16867331}, {122932, 16867587}, | 
2450  |  |   {122933, 16867843}, {122934, 16868099}, {122935, 16868355}, {122936, 16868611}, | 
2451  |  |   {122937, 16869123}, {122938, 16869379}, {122939, 16869635}, {122940, 16870147}, | 
2452  |  |   {122941, 16870403}, {122942, 16870659}, {122943, 16870915}, {122944, 16871171}, | 
2453  |  |   {122945, 16871427}, {122946, 16871683}, {122947, 16871939}, {122948, 16872195}, | 
2454  |  |   {122949, 16872451}, {122950, 16872707}, {122951, 16873475}, {122952, 16873987}, | 
2455  |  |   {122953, 16874243}, {122954, 17495299}, {122955, 16888835}, {122956, 16864003}, | 
2456  |  |   {122957, 16864515}, {122958, 16890883}, {122959, 16883715}, {122960, 17945859}, | 
2457  |  |   {122961, 16866563}, {122962, 16866819}, {122963, 16867075}, {122964, 16867331}, | 
2458  |  |   {122965, 16867587}, {122966, 16867843}, {122967, 16868099}, {122968, 16868355}, | 
2459  |  |   {122969, 16868611}, {122970, 16869123}, {122971, 16869379}, {122972, 16870147}, | 
2460  |  |   {122973, 16870403}, {122974, 16870915}, {122975, 16871427}, {122976, 16871683}, | 
2461  |  |   {122977, 16871939}, {122978, 16872195}, {122979, 16872451}, {122980, 16872707}, | 
2462  |  |   {122981, 16873219}, {122982, 16873475}, {122983, 16879875}, {122984, 16864003}, | 
2463  |  |   {122985, 16863747}, {122986, 16866307}, {122987, 16883203}, {122988, 17490435}, | 
2464  |  |   {122989, 16883971}, {122990, 2}, {123023, 1}, {123024, 2}, | 
2465  |  |   {123136, 1}, {123181, 2}, {123184, 1}, {123198, 2}, | 
2466  |  |   {123200, 1}, {123210, 2}, {123214, 1}, {123216, 2}, | 
2467  |  |   {123536, 1}, {123567, 2}, {123584, 1}, {123642, 2}, | 
2468  |  |   {123647, 1}, {123648, 2}, {124112, 1}, {124154, 2}, | 
2469  |  |   {124896, 1}, {124903, 2}, {124904, 1}, {124908, 2}, | 
2470  |  |   {124909, 1}, {124911, 2}, {124912, 1}, {124927, 2}, | 
2471  |  |   {124928, 1}, {125125, 2}, {125127, 1}, {125143, 2}, | 
2472  |  |   {125184, 17946115}, {125185, 17946371}, {125186, 17946627}, {125187, 17946883}, | 
2473  |  |   {125188, 17947139}, {125189, 17947395}, {125190, 17947651}, {125191, 17947907}, | 
2474  |  |   {125192, 17948163}, {125193, 17948419}, {125194, 17948675}, {125195, 17948931}, | 
2475  |  |   {125196, 17949187}, {125197, 17949443}, {125198, 17949699}, {125199, 17949955}, | 
2476  |  |   {125200, 17950211}, {125201, 17950467}, {125202, 17950723}, {125203, 17950979}, | 
2477  |  |   {125204, 17951235}, {125205, 17951491}, {125206, 17951747}, {125207, 17952003}, | 
2478  |  |   {125208, 17952259}, {125209, 17952515}, {125210, 17952771}, {125211, 17953027}, | 
2479  |  |   {125212, 17953283}, {125213, 17953539}, {125214, 17953795}, {125215, 17954051}, | 
2480  |  |   {125216, 17954307}, {125217, 17954563}, {125218, 1}, {125260, 2}, | 
2481  |  |   {125264, 1}, {125274, 2}, {125278, 1}, {125280, 2}, | 
2482  |  |   {126065, 1}, {126133, 2}, {126209, 1}, {126270, 2}, | 
2483  |  |   {126464, 16910339}, {126465, 17683715}, {126466, 17681923}, {126467, 17834499}, | 
2484  |  |   {126468, 2}, {126469, 16910851}, {126470, 17731587}, {126471, 17682435}, | 
2485  |  |   {126472, 17700099}, {126473, 16911875}, {126474, 17708803}, {126475, 17711107}, | 
2486  |  |   {126476, 17682947}, {126477, 17718019}, {126478, 17694979}, {126479, 17701635}, | 
2487  |  |   {126480, 17703683}, {126481, 17697027}, {126482, 17706755}, {126483, 17725187}, | 
2488  |  |   {126484, 17745155}, {126485, 17686787}, {126486, 17689859}, {126487, 17684995}, | 
2489  |  |   {126488, 17724675}, {126489, 17698051}, {126490, 17701123}, {126491, 17702659}, | 
2490  |  |   {126492, 17954819}, {126493, 17673475}, {126494, 17955075}, {126495, 17955331}, | 
2491  |  |   {126496, 2}, {126497, 17683715}, {126498, 17681923}, {126499, 2}, | 
2492  |  |   {126500, 17721091}, {126501, 2}, {126503, 17682435}, {126504, 2}, | 
2493  |  |   {126505, 16911875}, {126506, 17708803}, {126507, 17711107}, {126508, 17682947}, | 
2494  |  |   {126509, 17718019}, {126510, 17694979}, {126511, 17701635}, {126512, 17703683}, | 
2495  |  |   {126513, 17697027}, {126514, 17706755}, {126515, 2}, {126516, 17745155}, | 
2496  |  |   {126517, 17686787}, {126518, 17689859}, {126519, 17684995}, {126520, 2}, | 
2497  |  |   {126521, 17698051}, {126522, 2}, {126523, 17702659}, {126524, 2}, | 
2498  |  |   {126530, 17681923}, {126531, 2}, {126535, 17682435}, {126536, 2}, | 
2499  |  |   {126537, 16911875}, {126538, 2}, {126539, 17711107}, {126540, 2}, | 
2500  |  |   {126541, 17718019}, {126542, 17694979}, {126543, 17701635}, {126544, 2}, | 
2501  |  |   {126545, 17697027}, {126546, 17706755}, {126547, 2}, {126548, 17745155}, | 
2502  |  |   {126549, 2}, {126551, 17684995}, {126552, 2}, {126553, 17698051}, | 
2503  |  |   {126554, 2}, {126555, 17702659}, {126556, 2}, {126557, 17673475}, | 
2504  |  |   {126558, 2}, {126559, 17955331}, {126560, 2}, {126561, 17683715}, | 
2505  |  |   {126562, 17681923}, {126563, 2}, {126564, 17721091}, {126565, 2}, | 
2506  |  |   {126567, 17682435}, {126568, 17700099}, {126569, 16911875}, {126570, 17708803}, | 
2507  |  |   {126571, 2}, {126572, 17682947}, {126573, 17718019}, {126574, 17694979}, | 
2508  |  |   {126575, 17701635}, {126576, 17703683}, {126577, 17697027}, {126578, 17706755}, | 
2509  |  |   {126579, 2}, {126580, 17745155}, {126581, 17686787}, {126582, 17689859}, | 
2510  |  |   {126583, 17684995}, {126584, 2}, {126585, 17698051}, {126586, 17701123}, | 
2511  |  |   {126587, 17702659}, {126588, 17954819}, {126589, 2}, {126590, 17955075}, | 
2512  |  |   {126591, 2}, {126592, 16910339}, {126593, 17683715}, {126594, 17681923}, | 
2513  |  |   {126595, 17834499}, {126596, 17721091}, {126597, 16910851}, {126598, 17731587}, | 
2514  |  |   {126599, 17682435}, {126600, 17700099}, {126601, 16911875}, {126602, 2}, | 
2515  |  |   {126603, 17711107}, {126604, 17682947}, {126605, 17718019}, {126606, 17694979}, | 
2516  |  |   {126607, 17701635}, {126608, 17703683}, {126609, 17697027}, {126610, 17706755}, | 
2517  |  |   {126611, 17725187}, {126612, 17745155}, {126613, 17686787}, {126614, 17689859}, | 
2518  |  |   {126615, 17684995}, {126616, 17724675}, {126617, 17698051}, {126618, 17701123}, | 
2519  |  |   {126619, 17702659}, {126620, 2}, {126625, 17683715}, {126626, 17681923}, | 
2520  |  |   {126627, 17834499}, {126628, 2}, {126629, 16910851}, {126630, 17731587}, | 
2521  |  |   {126631, 17682435}, {126632, 17700099}, {126633, 16911875}, {126634, 2}, | 
2522  |  |   {126635, 17711107}, {126636, 17682947}, {126637, 17718019}, {126638, 17694979}, | 
2523  |  |   {126639, 17701635}, {126640, 17703683}, {126641, 17697027}, {126642, 17706755}, | 
2524  |  |   {126643, 17725187}, {126644, 17745155}, {126645, 17686787}, {126646, 17689859}, | 
2525  |  |   {126647, 17684995}, {126648, 17724675}, {126649, 17698051}, {126650, 17701123}, | 
2526  |  |   {126651, 17702659}, {126652, 2}, {126704, 1}, {126706, 2}, | 
2527  |  |   {126976, 1}, {127020, 2}, {127024, 1}, {127124, 2}, | 
2528  |  |   {127136, 1}, {127151, 2}, {127153, 1}, {127168, 2}, | 
2529  |  |   {127169, 1}, {127184, 2}, {127185, 1}, {127222, 2}, | 
2530  |  |   {127233, 34732803}, {127234, 34733315}, {127235, 34733827}, {127236, 34734339}, | 
2531  |  |   {127237, 34734851}, {127238, 34735363}, {127239, 34735875}, {127240, 34736387}, | 
2532  |  |   {127241, 34736899}, {127242, 34737411}, {127243, 1}, {127248, 50644995}, | 
2533  |  |   {127249, 50645763}, {127250, 50646531}, {127251, 50647299}, {127252, 50648067}, | 
2534  |  |   {127253, 50648835}, {127254, 50649603}, {127255, 50650371}, {127256, 50651139}, | 
2535  |  |   {127257, 50651907}, {127258, 50652675}, {127259, 50653443}, {127260, 50654211}, | 
2536  |  |   {127261, 50654979}, {127262, 50655747}, {127263, 50656515}, {127264, 50657283}, | 
2537  |  |   {127265, 50658051}, {127266, 50658819}, {127267, 50659587}, {127268, 50660355}, | 
2538  |  |   {127269, 50661123}, {127270, 50661891}, {127271, 50662659}, {127272, 50663427}, | 
2539  |  |   {127273, 50664195}, {127274, 51515139}, {127275, 16777731}, {127276, 16781571}, | 
2540  |  |   {127277, 33554947}, {127278, 34738691}, {127279, 1}, {127280, 16777219}, | 
2541  |  |   {127281, 16777475}, {127282, 16777731}, {127283, 16777987}, {127284, 16778243}, | 
2542  |  |   {127285, 16778499}, {127286, 16778755}, {127287, 16779011}, {127288, 16779267}, | 
2543  |  |   {127289, 16779523}, {127290, 16779779}, {127291, 16780035}, {127292, 16780291}, | 
2544  |  |   {127293, 16780547}, {127294, 16780803}, {127295, 16781059}, {127296, 16781315}, | 
2545  |  |   {127297, 16781571}, {127298, 16781827}, {127299, 16782083}, {127300, 16782339}, | 
2546  |  |   {127301, 16782595}, {127302, 16782851}, {127303, 16783107}, {127304, 16783363}, | 
2547  |  |   {127305, 16783619}, {127306, 34739203}, {127307, 34226691}, {127308, 34739715}, | 
2548  |  |   {127309, 33752579}, {127310, 51517443}, {127311, 34740995}, {127312, 1}, | 
2549  |  |   {127338, 34209539}, {127339, 34189571}, {127340, 34741507}, {127341, 1}, | 
2550  |  |   {127376, 34742019}, {127377, 1}, {127406, 2}, {127462, 1}, | 
2551  |  |   {127488, 34742531}, {127489, 34743043}, {127490, 17307907}, {127491, 2}, | 
2552  |  |   {127504, 17157891}, {127505, 17966339}, {127506, 17966595}, {127507, 17351683}, | 
2553  |  |   {127508, 17143299}, {127509, 17966851}, {127510, 17967107}, {127511, 17225475}, | 
2554  |  |   {127512, 17967363}, {127513, 17967619}, {127514, 17967875}, {127515, 17584643}, | 
2555  |  |   {127516, 17968131}, {127517, 17968387}, {127518, 17968643}, {127519, 17968899}, | 
2556  |  |   {127520, 17969155}, {127521, 17969411}, {127522, 17167107}, {127523, 17969667}, | 
2557  |  |   {127524, 17969923}, {127525, 17970179}, {127526, 17970435}, {127527, 17970691}, | 
2558  |  |   {127528, 17970947}, {127529, 17141763}, {127530, 17223427}, {127531, 17971203}, | 
2559  |  |   {127532, 17288707}, {127533, 17224195}, {127534, 17288963}, {127535, 17971459}, | 
2560  |  |   {127536, 17181443}, {127537, 17971715}, {127538, 17971971}, {127539, 17972227}, | 
2561  |  |   {127540, 17972483}, {127541, 17972739}, {127542, 17264387}, {127543, 17160451}, | 
2562  |  |   {127544, 17972995}, {127545, 17973251}, {127546, 17973507}, {127547, 17973763}, | 
2563  |  |   {127548, 2}, {127552, 51528451}, {127553, 51529219}, {127554, 51529987}, | 
2564  |  |   {127555, 51530755}, {127556, 51531523}, {127557, 51532291}, {127558, 51533059}, | 
2565  |  |   {127559, 51533827}, {127560, 51534595}, {127561, 2}, {127568, 17980931}, | 
2566  |  |   {127569, 17981187}, {127570, 2}, {127584, 1}, {127590, 2}, | 
2567  |  |   {127744, 1}, {128728, 2}, {128732, 1}, {128749, 2}, | 
2568  |  |   {128752, 1}, {128765, 2}, {128768, 1}, {128887, 2}, | 
2569  |  |   {128891, 1}, {128986, 2}, {128992, 1}, {129004, 2}, | 
2570  |  |   {129008, 1}, {129009, 2}, {129024, 1}, {129036, 2}, | 
2571  |  |   {129040, 1}, {129096, 2}, {129104, 1}, {129114, 2}, | 
2572  |  |   {129120, 1}, {129160, 2}, {129168, 1}, {129198, 2}, | 
2573  |  |   {129200, 1}, {129202, 2}, {129280, 1}, {129620, 2}, | 
2574  |  |   {129632, 1}, {129646, 2}, {129648, 1}, {129661, 2}, | 
2575  |  |   {129664, 1}, {129673, 2}, {129680, 1}, {129726, 2}, | 
2576  |  |   {129727, 1}, {129734, 2}, {129742, 1}, {129756, 2}, | 
2577  |  |   {129760, 1}, {129769, 2}, {129776, 1}, {129785, 2}, | 
2578  |  |   {129792, 1}, {129939, 2}, {129940, 1}, {129995, 2}, | 
2579  |  |   {130032, 17035523}, {130033, 16786947}, {130034, 16785155}, {130035, 16785411}, | 
2580  |  |   {130036, 16787715}, {130037, 17035779}, {130038, 17036035}, {130039, 17036291}, | 
2581  |  |   {130040, 17036547}, {130041, 17036803}, {130042, 2}, {131072, 1}, | 
2582  |  |   {173792, 2}, {173824, 1}, {177978, 2}, {177984, 1}, | 
2583  |  |   {178206, 2}, {178208, 1}, {183970, 2}, {183984, 1}, | 
2584  |  |   {191457, 2}, {194560, 17981443}, {194561, 17981699}, {194562, 17981955}, | 
2585  |  |   {194563, 17982211}, {194564, 17982467}, {194565, 17608451}, {194566, 17982723}, | 
2586  |  |   {194567, 17982979}, {194568, 17983235}, {194569, 17983491}, {194570, 17608707}, | 
2587  |  |   {194571, 17983747}, {194572, 17984003}, {194573, 17984259}, {194574, 17608963}, | 
2588  |  |   {194575, 17984515}, {194576, 17984771}, {194577, 17985027}, {194578, 17985283}, | 
2589  |  |   {194579, 17985539}, {194580, 17985795}, {194581, 17968643}, {194582, 17986051}, | 
2590  |  |   {194583, 17986307}, {194584, 17986563}, {194585, 17986819}, {194586, 17987075}, | 
2591  |  |   {194587, 17623043}, {194588, 17987331}, {194589, 17145859}, {194590, 17987587}, | 
2592  |  |   {194591, 17987843}, {194592, 17988099}, {194593, 17988355}, {194594, 17973251}, | 
2593  |  |   {194595, 17988611}, {194596, 17988867}, {194597, 17624323}, {194598, 17609219}, | 
2594  |  |   {194599, 17609475}, {194600, 17624579}, {194601, 17989123}, {194602, 17989379}, | 
2595  |  |   {194603, 17562883}, {194604, 17989635}, {194605, 17609731}, {194606, 17989891}, | 
2596  |  |   {194607, 17990147}, {194608, 17990403}, {194609, 17990659}, {194612, 17990915}, | 
2597  |  |   {194613, 17991171}, {194614, 17991427}, {194615, 17991683}, {194616, 17991939}, | 
2598  |  |   {194617, 17992195}, {194618, 17992451}, {194619, 17992707}, {194620, 17992963}, | 
2599  |  |   {194621, 17993219}, {194622, 17993475}, {194623, 17993731}, {194624, 17993987}, | 
2600  |  |   {194625, 17994243}, {194626, 17994499}, {194627, 17994755}, {194628, 17995011}, | 
2601  |  |   {194629, 17995267}, {194631, 17625091}, {194632, 17995523}, {194633, 17995779}, | 
2602  |  |   {194634, 17996035}, {194635, 17996291}, {194636, 17610243}, {194637, 17996547}, | 
2603  |  |   {194638, 17996803}, {194639, 17997059}, {194640, 17600003}, {194641, 17997315}, | 
2604  |  |   {194642, 17997571}, {194643, 17997827}, {194644, 17998083}, {194645, 17998339}, | 
2605  |  |   {194646, 17998595}, {194647, 17998851}, {194648, 17999107}, {194649, 17999363}, | 
2606  |  |   {194650, 17999619}, {194651, 17999875}, {194652, 18000131}, {194653, 17966851}, | 
2607  |  |   {194654, 18000387}, {194655, 18000643}, {194656, 18000899}, {194657, 18001155}, | 
2608  |  |   {194658, 18001411}, {194659, 18001667}, {194660, 18001923}, {194661, 18002179}, | 
2609  |  |   {194662, 18002435}, {194663, 18002691}, {194664, 2}, {194665, 18002947}, | 
2610  |  |   {194666, 18003203}, {194668, 18003459}, {194669, 18003715}, {194670, 18003971}, | 
2611  |  |   {194671, 17561859}, {194672, 18004227}, {194673, 18004483}, {194674, 18004739}, | 
2612  |  |   {194675, 18004995}, {194676, 2}, {194677, 17152515}, {194678, 18005251}, | 
2613  |  |   {194679, 18005507}, {194680, 17153027}, {194681, 18005763}, {194682, 18006019}, | 
2614  |  |   {194683, 18006275}, {194684, 18006531}, {194685, 18006787}, {194686, 18007043}, | 
2615  |  |   {194687, 18007299}, {194688, 18007555}, {194689, 18007811}, {194690, 18008067}, | 
2616  |  |   {194691, 18008323}, {194692, 18008579}, {194693, 18008835}, {194694, 18009091}, | 
2617  |  |   {194695, 18009347}, {194696, 18009603}, {194697, 18009859}, {194698, 18010115}, | 
2618  |  |   {194699, 18010371}, {194700, 18010627}, {194701, 18010883}, {194702, 17548547}, | 
2619  |  |   {194703, 18011139}, {194704, 17155587}, {194705, 18011395}, {194707, 18011651}, | 
2620  |  |   {194708, 18011907}, {194710, 18012163}, {194711, 18012419}, {194712, 18012675}, | 
2621  |  |   {194713, 18012931}, {194714, 18013187}, {194715, 18013443}, {194716, 18013699}, | 
2622  |  |   {194717, 18013955}, {194718, 18014211}, {194719, 18014467}, {194720, 18014723}, | 
2623  |  |   {194721, 18014979}, {194722, 18015235}, {194723, 17611523}, {194724, 18015491}, | 
2624  |  |   {194725, 18015747}, {194726, 18016003}, {194727, 18016259}, {194728, 17628163}, | 
2625  |  |   {194729, 18016259}, {194730, 18016515}, {194731, 17612035}, {194732, 18016771}, | 
2626  |  |   {194733, 18017027}, {194734, 18017283}, {194735, 18017539}, {194736, 17612291}, | 
2627  |  |   {194737, 17541635}, {194738, 17414915}, {194739, 18017795}, {194740, 18018051}, | 
2628  |  |   {194741, 18018307}, {194742, 18018563}, {194743, 18018819}, {194744, 18019075}, | 
2629  |  |   {194745, 18019331}, {194746, 18019587}, {194747, 18019843}, {194748, 18020099}, | 
2630  |  |   {194749, 18020355}, {194750, 18020611}, {194751, 18020867}, {194752, 18021123}, | 
2631  |  |   {194753, 18021379}, {194754, 18021635}, {194755, 18021891}, {194756, 18022147}, | 
2632  |  |   {194757, 18022403}, {194758, 18022659}, {194759, 18022915}, {194760, 17612547}, | 
2633  |  |   {194761, 18023171}, {194762, 18023427}, {194763, 18023683}, {194764, 18023939}, | 
2634  |  |   {194765, 18024195}, {194766, 18024451}, {194767, 17613059}, {194768, 18024707}, | 
2635  |  |   {194769, 18024963}, {194770, 18025219}, {194771, 18025475}, {194772, 18025731}, | 
2636  |  |   {194773, 18025987}, {194774, 18026243}, {194775, 18026499}, {194776, 17548803}, | 
2637  |  |   {194777, 17630211}, {194778, 18026755}, {194779, 18027011}, {194780, 18027267}, | 
2638  |  |   {194781, 18027523}, {194782, 18027779}, {194783, 18028035}, {194784, 18028291}, | 
2639  |  |   {194785, 18028547}, {194786, 17613315}, {194787, 18028803}, {194788, 18029059}, | 
2640  |  |   {194789, 18029315}, {194790, 18029571}, {194791, 17640963}, {194792, 18029827}, | 
2641  |  |   {194793, 18030083}, {194794, 18030339}, {194795, 18030595}, {194796, 18030851}, | 
2642  |  |   {194797, 18031107}, {194798, 18031363}, {194799, 18031619}, {194800, 18031875}, | 
2643  |  |   {194801, 18032131}, {194802, 18032387}, {194803, 18032643}, {194804, 18032899}, | 
2644  |  |   {194805, 17566211}, {194806, 18033155}, {194807, 18033411}, {194808, 18033667}, | 
2645  |  |   {194809, 18033923}, {194810, 18034179}, {194811, 18034435}, {194812, 18034691}, | 
2646  |  |   {194813, 18034947}, {194814, 18035203}, {194815, 18035459}, {194816, 18035715}, | 
2647  |  |   {194817, 17613571}, {194818, 17587203}, {194819, 18035971}, {194820, 18036227}, | 
2648  |  |   {194821, 18036483}, {194822, 18036739}, {194823, 18036995}, {194824, 18037251}, | 
2649  |  |   {194825, 18037507}, {194826, 18037763}, {194827, 17630979}, {194828, 18038019}, | 
2650  |  |   {194829, 18038275}, {194830, 18038531}, {194831, 18038787}, {194832, 18039043}, | 
2651  |  |   {194833, 18039299}, {194834, 18039555}, {194835, 18039811}, {194836, 17631235}, | 
2652  |  |   {194837, 18040067}, {194838, 18040323}, {194839, 18040579}, {194840, 18040835}, | 
2653  |  |   {194841, 18041091}, {194842, 18041347}, {194843, 18041603}, {194844, 18041859}, | 
2654  |  |   {194845, 18042115}, {194846, 18042371}, {194847, 2}, {194848, 18042627}, | 
2655  |  |   {194849, 17631747}, {194850, 18042883}, {194851, 18043139}, {194852, 18043395}, | 
2656  |  |   {194853, 18043651}, {194854, 18043907}, {194855, 18044163}, {194856, 18044419}, | 
2657  |  |   {194857, 18044675}, {194858, 18044931}, {194859, 18045187}, {194860, 18045443}, | 
2658  |  |   {194862, 18045699}, {194863, 18045955}, {194864, 17632259}, {194865, 18046211}, | 
2659  |  |   {194866, 18046467}, {194867, 18046723}, {194868, 18046979}, {194869, 18047235}, | 
2660  |  |   {194870, 18047491}, {194871, 18047747}, {194872, 17562627}, {194873, 18048003}, | 
2661  |  |   {194874, 18048259}, {194875, 18048515}, {194876, 18048771}, {194877, 18049027}, | 
2662  |  |   {194878, 18049283}, {194879, 18049539}, {194880, 17633795}, {194881, 18049795}, | 
2663  |  |   {194882, 18050051}, {194883, 18050307}, {194884, 18050563}, {194885, 18050819}, | 
2664  |  |   {194886, 18051075}, {194888, 17634051}, {194889, 17641475}, {194890, 18051331}, | 
2665  |  |   {194891, 18051587}, {194892, 18051843}, {194893, 18052099}, {194894, 18052355}, | 
2666  |  |   {194895, 17553155}, {194896, 17634563}, {194897, 18052611}, {194898, 18052867}, | 
2667  |  |   {194899, 17616131}, {194900, 18053123}, {194901, 18053379}, {194902, 17605123}, | 
2668  |  |   {194903, 18053635}, {194904, 18053891}, {194905, 17616899}, {194906, 18054147}, | 
2669  |  |   {194907, 18054403}, {194908, 18054659}, {194909, 18054915}, {194911, 2}, | 
2670  |  |   {194912, 18055171}, {194913, 18055427}, {194914, 18055683}, {194915, 18055939}, | 
2671  |  |   {194916, 18056195}, {194917, 18056451}, {194918, 18056707}, {194919, 18056963}, | 
2672  |  |   {194920, 18057219}, {194921, 18057475}, {194922, 18057731}, {194923, 18057987}, | 
2673  |  |   {194924, 18058243}, {194925, 18058499}, {194926, 18058755}, {194927, 18059011}, | 
2674  |  |   {194928, 18059267}, {194929, 18059523}, {194930, 18059779}, {194931, 18060035}, | 
2675  |  |   {194932, 18060291}, {194933, 18060547}, {194934, 18060803}, {194935, 18061059}, | 
2676  |  |   {194936, 18061315}, {194937, 18061571}, {194938, 17618435}, {194939, 18061827}, | 
2677  |  |   {194940, 18062083}, {194941, 18062339}, {194942, 18062595}, {194943, 18062851}, | 
2678  |  |   {194944, 18063107}, {194945, 18063363}, {194946, 18063619}, {194947, 18063875}, | 
2679  |  |   {194948, 18064131}, {194949, 18064387}, {194950, 18064643}, {194951, 18064899}, | 
2680  |  |   {194952, 18065155}, {194953, 18065411}, {194954, 18065667}, {194955, 18011651}, | 
2681  |  |   {194956, 18065923}, {194957, 18066179}, {194958, 18066435}, {194959, 18066691}, | 
2682  |  |   {194960, 18066947}, {194961, 18067203}, {194962, 18067459}, {194963, 18067715}, | 
2683  |  |   {194964, 18067971}, {194965, 18068227}, {194966, 18068483}, {194967, 18068739}, | 
2684  |  |   {194968, 17566979}, {194969, 18068995}, {194970, 18069251}, {194971, 18069507}, | 
2685  |  |   {194972, 18069763}, {194973, 18070019}, {194974, 18070275}, {194975, 17619203}, | 
2686  |  |   {194976, 18070531}, {194977, 18070787}, {194978, 18071043}, {194979, 18071299}, | 
2687  |  |   {194980, 18071555}, {194981, 18071811}, {194982, 18072067}, {194983, 18072323}, | 
2688  |  |   {194984, 18072579}, {194985, 18072835}, {194986, 18073091}, {194987, 18073347}, | 
2689  |  |   {194988, 18073603}, {194989, 18073859}, {194990, 18074115}, {194991, 18074371}, | 
2690  |  |   {194992, 18074627}, {194993, 18074883}, {194994, 18075139}, {194995, 18075395}, | 
2691  |  |   {194996, 17551875}, {194997, 18075651}, {194998, 18075907}, {194999, 18076163}, | 
2692  |  |   {195000, 18076419}, {195001, 18076675}, {195002, 18076931}, {195003, 17636355}, | 
2693  |  |   {195004, 18077187}, {195005, 18077443}, {195006, 18077699}, {195007, 2}, | 
2694  |  |   {195008, 18077955}, {195009, 18078211}, {195010, 18078467}, {195011, 18078723}, | 
2695  |  |   {195012, 17178627}, {195013, 18078979}, {195014, 18079235}, {195015, 18079491}, | 
2696  |  |   {195016, 18079747}, {195017, 18080003}, {195018, 18080259}, {195019, 18080515}, | 
2697  |  |   {195020, 18080771}, {195021, 18081027}, {195022, 18081283}, {195023, 18081539}, | 
2698  |  |   {195024, 17637635}, {195025, 17637891}, {195026, 17180419}, {195027, 18081795}, | 
2699  |  |   {195028, 18082051}, {195029, 18082307}, {195030, 18082563}, {195031, 18082819}, | 
2700  |  |   {195032, 18083075}, {195033, 18083331}, {195034, 18083587}, {195035, 18083843}, | 
2701  |  |   {195036, 18084099}, {195037, 18084355}, {195038, 18084611}, {195039, 17638147}, | 
2702  |  |   {195040, 18084867}, {195041, 18085123}, {195042, 18085379}, {195043, 18085635}, | 
2703  |  |   {195044, 18085891}, {195045, 18086147}, {195046, 18086403}, {195047, 18086659}, | 
2704  |  |   {195048, 18086915}, {195049, 18087171}, {195050, 18087427}, {195051, 18087683}, | 
2705  |  |   {195052, 18087939}, {195053, 18088195}, {195054, 18088451}, {195055, 18088707}, | 
2706  |  |   {195056, 18088963}, {195057, 18089219}, {195058, 18089475}, {195059, 18089731}, | 
2707  |  |   {195060, 18089987}, {195061, 18090243}, {195062, 18090499}, {195063, 18090755}, | 
2708  |  |   {195064, 18091011}, {195065, 18091267}, {195066, 18091523}, {195067, 18091779}, | 
2709  |  |   {195068, 18092035}, {195069, 18092291}, {195070, 17639683}, {195072, 18092547}, | 
2710  |  |   {195073, 18092803}, {195074, 18093059}, {195075, 18093315}, {195076, 18093571}, | 
2711  |  |   {195077, 18093827}, {195078, 18094083}, {195079, 18094339}, {195080, 18094595}, | 
2712  |  |   {195081, 18094851}, {195082, 17639939}, {195083, 18095107}, {195084, 18095363}, | 
2713  |  |   {195085, 18095619}, {195086, 18095875}, {195087, 18096131}, {195088, 18096387}, | 
2714  |  |   {195089, 18096643}, {195090, 18096899}, {195091, 18097155}, {195092, 18097411}, | 
2715  |  |   {195093, 17192707}, {195094, 18097667}, {195095, 17193731}, {195096, 18097923}, | 
2716  |  |   {195097, 18098179}, {195098, 18098435}, {195099, 18098691}, {195100, 17195011}, | 
2717  |  |   {195101, 18098947}, {195102, 2}, {196608, 1}, {201547, 2}, | 
2718  |  |   {201552, 1}, {205744, 2}, {917760, 0}, {918000, 2} | 
2719  |  | };  | 
2720  |  |  | 
2721  |  |  | 
2722  |  | } // namespace ada::idna  | 
2723  |  | #endif // ADA_IDNA_TABLES_H  | 
2724  |  |  | 
2725  |  | /* end file src/mapping_tables.cpp */  | 
2726  |  |  | 
2727  |  | namespace ada::idna { | 
2728  |  |  | 
2729  |  | // This can be greatly accelerated. For now we just use a simply  | 
2730  |  | // binary search. In practice, you should *not* do that.  | 
2731  | 183k  | uint32_t find_range_index(uint32_t key) { | 
2732  |  |   ////////////////  | 
2733  |  |   // This could be implemented with std::lower_bound, but we roll our own  | 
2734  |  |   // because we want to allow further optimizations in the future.  | 
2735  |  |   ////////////////  | 
2736  | 183k  |   uint32_t len = std::size(table);  | 
2737  | 183k  |   uint32_t low = 0;  | 
2738  | 183k  |   uint32_t high = len - 1;  | 
2739  | 2.44M  |   while (low <= high) { | 
2740  | 2.31M  |     uint32_t middle_index = (low + high) >> 1;  // cannot overflow  | 
2741  | 2.31M  |     uint32_t middle_value = table[middle_index][0];  | 
2742  | 2.31M  |     if (middle_value < key) { | 
2743  | 646k  |       low = middle_index + 1;  | 
2744  | 1.67M  |     } else if (middle_value > key) { | 
2745  | 1.61M  |       high = middle_index - 1;  | 
2746  | 1.61M  |     } else { | 
2747  | 52.4k  |       return middle_index;  // perfect match  | 
2748  | 52.4k  |     }  | 
2749  | 2.31M  |   }  | 
2750  | 130k  |   return low == 0 ? 0 : low - 1;  | 
2751  | 183k  | }  | 
2752  |  |  | 
2753  | 0  | bool ascii_has_upper_case(char* input, size_t length) { | 
2754  | 0  |   auto broadcast = [](uint8_t v) -> uint64_t { | 
2755  | 0  |     return 0x101010101010101ull * v;  | 
2756  | 0  |   };  | 
2757  | 0  |   uint64_t broadcast_80 = broadcast(0x80);  | 
2758  | 0  |   uint64_t broadcast_Ap = broadcast(128 - 'A');  | 
2759  | 0  |   uint64_t broadcast_Zp = broadcast(128 - 'Z' - 1);  | 
2760  | 0  |   size_t i = 0;  | 
2761  |  | 
  | 
2762  | 0  |   uint64_t runner{0}; | 
2763  |  | 
  | 
2764  | 0  |   for (; i + 7 < length; i += 8) { | 
2765  | 0  |     uint64_t word{}; | 
2766  | 0  |     memcpy(&word, input + i, sizeof(word));  | 
2767  | 0  |     runner |= (((word + broadcast_Ap) ^ (word + broadcast_Zp)) & broadcast_80);  | 
2768  | 0  |   }  | 
2769  | 0  |   if (i < length) { | 
2770  | 0  |     uint64_t word{}; | 
2771  | 0  |     memcpy(&word, input + i, length - i);  | 
2772  | 0  |     runner |= (((word + broadcast_Ap) ^ (word + broadcast_Zp)) & broadcast_80);  | 
2773  | 0  |   }  | 
2774  | 0  |   return runner != 0;  | 
2775  | 0  | }  | 
2776  |  |  | 
2777  | 15.0k  | void ascii_map(char* input, size_t length) { | 
2778  | 45.2k  |   auto broadcast = [](uint8_t v) -> uint64_t { | 
2779  | 45.2k  |     return 0x101010101010101ull * v;  | 
2780  | 45.2k  |   };  | 
2781  | 15.0k  |   uint64_t broadcast_80 = broadcast(0x80);  | 
2782  | 15.0k  |   uint64_t broadcast_Ap = broadcast(128 - 'A');  | 
2783  | 15.0k  |   uint64_t broadcast_Zp = broadcast(128 - 'Z' - 1);  | 
2784  | 15.0k  |   size_t i = 0;  | 
2785  |  |  | 
2786  | 40.9k  |   for (; i + 7 < length; i += 8) { | 
2787  | 25.9k  |     uint64_t word{}; | 
2788  | 25.9k  |     memcpy(&word, input + i, sizeof(word));  | 
2789  | 25.9k  |     word ^=  | 
2790  | 25.9k  |         (((word + broadcast_Ap) ^ (word + broadcast_Zp)) & broadcast_80) >> 2;  | 
2791  | 25.9k  |     memcpy(input + i, &word, sizeof(word));  | 
2792  | 25.9k  |   }  | 
2793  | 15.0k  |   if (i < length) { | 
2794  | 13.1k  |     uint64_t word{}; | 
2795  | 13.1k  |     memcpy(&word, input + i, length - i);  | 
2796  | 13.1k  |     word ^=  | 
2797  | 13.1k  |         (((word + broadcast_Ap) ^ (word + broadcast_Zp)) & broadcast_80) >> 2;  | 
2798  | 13.1k  |     memcpy(input + i, &word, length - i);  | 
2799  | 13.1k  |   }  | 
2800  | 15.0k  | }  | 
2801  |  |  | 
2802  |  | // Map the characters according to IDNA, returning the empty string on error.  | 
2803  | 16.5k  | std::u32string map(std::u32string_view input) { | 
2804  |  |   //  [Map](https://www.unicode.org/reports/tr46/#ProcessingStepMap).  | 
2805  |  |   //  For each code point in the domain_name string, look up the status  | 
2806  |  |   //  value in Section 5, [IDNA Mapping  | 
2807  |  |   //  Table](https://www.unicode.org/reports/tr46/#IDNA_Mapping_Table),  | 
2808  |  |   //  and take the following actions:  | 
2809  |  |   //    * disallowed: Leave the code point unchanged in the string, and  | 
2810  |  |   //    record that there was an error.  | 
2811  |  |   //    * ignored: Remove the code point from the string. This is  | 
2812  |  |   //    equivalent to mapping the code point to an empty string.  | 
2813  |  |   //    * mapped: Replace the code point in the string by the value for  | 
2814  |  |   //    the mapping in Section 5, [IDNA Mapping  | 
2815  |  |   //    Table](https://www.unicode.org/reports/tr46/#IDNA_Mapping_Table).  | 
2816  |  |   //    * valid: Leave the code point unchanged in the string.  | 
2817  | 16.5k  |   static std::u32string error = U"";  | 
2818  | 16.5k  |   std::u32string answer;  | 
2819  | 16.5k  |   answer.reserve(input.size());  | 
2820  | 183k  |   for (char32_t x : input) { | 
2821  | 183k  |     size_t index = find_range_index(x);  | 
2822  | 183k  |     uint32_t descriptor = table[index][1];  | 
2823  | 183k  |     uint8_t code = uint8_t(descriptor);  | 
2824  | 183k  |     switch (code) { | 
2825  | 218  |       case 0:  | 
2826  | 218  |         break;  // nothing to do, ignored  | 
2827  | 138k  |       case 1:  | 
2828  | 138k  |         answer.push_back(x);  // valid, we just copy it to output  | 
2829  | 138k  |         break;  | 
2830  | 393  |       case 2:  | 
2831  | 393  |         return error;  // disallowed  | 
2832  | 0  |         break;  | 
2833  |  |  | 
2834  |  |       // case 3 :  | 
2835  | 44.5k  |       default:  | 
2836  |  |         // We have a mapping  | 
2837  | 44.5k  |         { | 
2838  | 44.5k  |           size_t char_count = (descriptor >> 24);  | 
2839  | 44.5k  |           uint16_t char_index = uint16_t(descriptor >> 8);  | 
2840  | 252k  |           for (size_t idx = char_index; idx < char_index + char_count; idx++) { | 
2841  | 208k  |             answer.push_back(mappings[idx]);  | 
2842  | 208k  |           }  | 
2843  | 44.5k  |         }  | 
2844  | 183k  |     }  | 
2845  | 183k  |   }  | 
2846  | 16.1k  |   return answer;  | 
2847  | 16.5k  | }  | 
2848  |  | }  // namespace ada::idna  | 
2849  |  | /* end file src/mapping.cpp */  | 
2850  |  | /* begin file src/normalization.cpp */  | 
2851  |  | /* begin file src/normalization_tables.cpp */  | 
2852  |  | // IDNA  15.0.0  | 
2853  |  |  | 
2854  |  | // clang-format off  | 
2855  |  | #ifndef ADA_IDNA_NORMALIZATION_TABLES_H  | 
2856  |  | #define ADA_IDNA_NORMALIZATION_TABLES_H  | 
2857  |  | #include <cstdint>  | 
2858  |  |  | 
2859  |  | /**  | 
2860  |  |  * Unicode Standard Annex #15  | 
2861  |  |  *  | 
2862  |  |  * UNICODE NORMALIZATION FORMS  | 
2863  |  |  * https://www.unicode.org/reports/tr15/  | 
2864  |  |  *  | 
2865  |  |  * See https://github.com/uni-algo/uni-algo/blob/c612968c5ed3ace39bde4c894c24286c5f2c7fe2/include/uni_algo/impl/data/data_norm.h for reference.  | 
2866  |  |  */  | 
2867  |  |  | 
2868  |  | namespace ada::idna { | 
2869  |  |  | 
2870  |  | const uint8_t decomposition_index[4352] = { | 
2871  |  |     0,  1,  2,  3,  4,  5,  6,  7,  7,  8,  9,  10, 11, 12, 13, 14, 15, 7,  7,  | 
2872  |  |     7,  7,  7,  7,  7,  7,  7,  7,  16, 7,  17, 18, 19, 20, 21, 22, 23, 24, 7,  | 
2873  |  |     7,  7,  7,  7,  25, 7,  26, 27, 28, 29, 30, 31, 32, 33, 7,  7,  7,  7,  7,  | 
2874  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2875  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2876  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2877  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2878  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2879  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  34, 35, 7,  7,  7,  | 
2880  |  |     36, 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2881  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2882  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2883  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2884  |  |     7,  7,  37, 38, 39, 40, 41, 42, 43, 7,  7,  7,  7,  7,  7,  7,  44, 7,  7,  | 
2885  |  |     7,  7,  7,  7,  7,  7,  45, 46, 7,  47, 48, 49, 7,  7,  7,  50, 7,  7,  7,  | 
2886  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2887  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2888  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2889  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2890  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2891  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2892  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2893  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2894  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2895  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  51, 7,  52, 53, 54, 55, 56, 7,  7,  7,  | 
2896  |  |     7,  7,  7,  7,  7,  57, 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  58,  | 
2897  |  |     59, 7,  60, 61, 62, 7,  7,  7,  7,  7,  7,  7,  7,  63, 7,  7,  7,  7,  7,  | 
2898  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2899  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2900  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2901  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2902  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2903  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2904  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2905  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2906  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2907  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2908  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2909  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2910  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2911  |  |     64, 65, 66, 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2912  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2913  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2914  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2915  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2916  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2917  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2918  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2919  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2920  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2921  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2922  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2923  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2924  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2925  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2926  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2927  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2928  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2929  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2930  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2931  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2932  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2933  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2934  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2935  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2936  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2937  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2938  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2939  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2940  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2941  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2942  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2943  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2944  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2945  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2946  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2947  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2948  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2949  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2950  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2951  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2952  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2953  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2954  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2955  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2956  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2957  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2958  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2959  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2960  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2961  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2962  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2963  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2964  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2965  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2966  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2967  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2968  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2969  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2970  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2971  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2972  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2973  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2974  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2975  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2976  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2977  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2978  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2979  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2980  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2981  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2982  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2983  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2984  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2985  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2986  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2987  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2988  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2989  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2990  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2991  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2992  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2993  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2994  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2995  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2996  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2997  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2998  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
2999  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3000  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3001  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3002  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3003  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3004  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3005  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3006  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3007  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3008  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3009  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3010  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3011  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3012  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3013  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3014  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3015  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3016  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3017  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3018  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3019  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3020  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3021  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3022  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3023  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3024  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3025  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3026  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3027  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3028  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3029  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3030  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3031  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3032  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3033  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3034  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3035  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3036  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3037  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3038  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3039  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3040  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3041  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3042  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3043  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3044  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3045  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3046  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3047  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3048  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3049  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3050  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3051  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3052  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3053  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3054  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3055  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3056  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3057  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3058  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3059  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3060  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3061  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3062  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3063  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3064  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3065  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3066  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3067  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3068  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3069  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3070  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3071  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3072  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3073  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3074  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3075  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3076  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3077  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3078  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3079  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3080  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3081  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3082  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3083  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3084  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3085  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3086  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3087  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3088  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3089  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3090  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3091  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3092  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3093  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3094  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3095  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3096  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3097  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3098  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3099  |  |     7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  | 
3100  |  |     7};  | 
3101  |  |  | 
3102  |  | const uint16_t decomposition_block[67][257] = { | 
3103  |  |     {4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4, | 
3104  |  |      4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,  | 
3105  |  |      4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,  | 
3106  |  |      4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,  | 
3107  |  |      4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,  | 
3108  |  |      4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,  | 
3109  |  |      4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,  | 
3110  |  |      4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,  | 
3111  |  |      4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,  | 
3112  |  |      4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,  | 
3113  |  |      4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   5,   8,   8,   8,   8,  | 
3114  |  |      8,   8,   8,   9,   16,  17,  20,  20,  20,  20,  21,  28,  28,  29,  33,  | 
3115  |  |      37,  45,  48,  48,  49,  57,  61,  64,  65,  77,  89,  100, 100, 108, 116,  | 
3116  |  |      124, 132, 140, 148, 148, 156, 164, 172, 180, 188, 196, 204, 212, 220, 220,  | 
3117  |  |      228, 236, 244, 252, 260, 268, 268, 268, 276, 284, 292, 300, 308, 308, 308,  | 
3118  |  |      316, 324, 332, 340, 348, 356, 356, 364, 372, 380, 388, 396, 404, 412, 420,  | 
3119  |  |      428, 428, 436, 444, 452, 460, 468, 476, 476, 476, 484, 492, 500, 508, 516,  | 
3120  |  |      516, 524},  | 
3121  |  |     {524,  532,  540,  548,  556,  564,  572,  580,  588,  596,  604,  612, | 
3122  |  |      620,  628,  636,  644,  652,  652,  652,  660,  668,  676,  684,  692,  | 
3123  |  |      700,  708,  716,  724,  732,  740,  748,  756,  764,  772,  780,  788,  | 
3124  |  |      796,  804,  812,  812,  812,  820,  828,  836,  844,  852,  860,  868,  | 
3125  |  |      876,  884,  885,  893,  900,  908,  916,  924,  932,  932,  940,  948,  | 
3126  |  |      956,  964,  972,  981,  989,  996,  996,  996,  1004, 1012, 1020, 1028,  | 
3127  |  |      1036, 1045, 1052, 1052, 1052, 1060, 1068, 1076, 1084, 1092, 1100, 1100,  | 
3128  |  |      1100, 1108, 1116, 1124, 1132, 1140, 1148, 1156, 1164, 1172, 1180, 1188,  | 
3129  |  |      1196, 1204, 1212, 1220, 1228, 1236, 1244, 1244, 1244, 1252, 1260, 1268,  | 
3130  |  |      1276, 1284, 1292, 1300, 1308, 1316, 1324, 1332, 1340, 1348, 1356, 1364,  | 
3131  |  |      1372, 1380, 1388, 1396, 1404, 1412, 1420, 1429, 1432, 1432, 1432, 1432,  | 
3132  |  |      1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432,  | 
3133  |  |      1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432,  | 
3134  |  |      1432, 1432, 1432, 1432, 1432, 1440, 1448, 1448, 1448, 1448, 1448, 1448,  | 
3135  |  |      1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1456, 1464, 1464, 1464,  | 
3136  |  |      1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464,  | 
3137  |  |      1464, 1464, 1464, 1464, 1465, 1477, 1489, 1501, 1509, 1517, 1525, 1533,  | 
3138  |  |      1541, 1548, 1556, 1564, 1572, 1580, 1588, 1596, 1604, 1612, 1624, 1636,  | 
3139  |  |      1648, 1660, 1672, 1684, 1696, 1708, 1708, 1720, 1732, 1744, 1756, 1764,  | 
3140  |  |      1772, 1772, 1772, 1780, 1788, 1796, 1804, 1812, 1820, 1832, 1844, 1852,  | 
3141  |  |      1860, 1869, 1877, 1885, 1892, 1900, 1908, 1908, 1908, 1916, 1924, 1936,  | 
3142  |  |      1948, 1956, 1964, 1972, 1980},  | 
3143  |  |     {1980, 1988, 1996, 2004, 2012, 2020, 2028, 2036, 2044, 2052, 2060, 2068, | 
3144  |  |      2076, 2084, 2092, 2100, 2108, 2116, 2124, 2132, 2140, 2148, 2156, 2164,  | 
3145  |  |      2172, 2180, 2188, 2196, 2204, 2204, 2204, 2212, 2220, 2220, 2220, 2220,  | 
3146  |  |      2220, 2220, 2220, 2228, 2236, 2244, 2252, 2264, 2276, 2288, 2300, 2308,  | 
3147  |  |      2316, 2328, 2340, 2348, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356,  | 
3148  |  |      2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356,  | 
3149  |  |      2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356,  | 
3150  |  |      2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356,  | 
3151  |  |      2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356,  | 
3152  |  |      2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356,  | 
3153  |  |      2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356,  | 
3154  |  |      2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356,  | 
3155  |  |      2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356,  | 
3156  |  |      2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356,  | 
3157  |  |      2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2357, 2361, 2365, 2369,  | 
3158  |  |      2373, 2377, 2381, 2385, 2389, 2392, 2392, 2392, 2392, 2392, 2392, 2392,  | 
3159  |  |      2392, 2392, 2392, 2392, 2392, 2392, 2392, 2392, 2392, 2392, 2392, 2392,  | 
3160  |  |      2392, 2392, 2392, 2392, 2392, 2392, 2392, 2392, 2392, 2392, 2392, 2392,  | 
3161  |  |      2393, 2401, 2409, 2417, 2425, 2433, 2440, 2440, 2441, 2445, 2449, 2453,  | 
3162  |  |      2457, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460,  | 
3163  |  |      2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460,  | 
3164  |  |      2460, 2460, 2460, 2460, 2460},  | 
3165  |  |     {2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, | 
3166  |  |      2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460,  | 
3167  |  |      2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460,  | 
3168  |  |      2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460,  | 
3169  |  |      2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460,  | 
3170  |  |      2460, 2460, 2460, 2460, 2460, 2464, 2468, 2468, 2472, 2480, 2480, 2480,  | 
3171  |  |      2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480,  | 
3172  |  |      2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480,  | 
3173  |  |      2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480,  | 
3174  |  |      2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2484, 2484, 2484,  | 
3175  |  |      2484, 2484, 2485, 2492, 2492, 2492, 2492, 2496, 2496, 2496, 2496, 2496,  | 
3176  |  |      2497, 2506, 2512, 2520, 2524, 2532, 2540, 2548, 2548, 2556, 2556, 2564,  | 
3177  |  |      2572, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584,  | 
3178  |  |      2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584,  | 
3179  |  |      2584, 2584, 2584, 2592, 2600, 2608, 2616, 2624, 2632, 2644, 2644, 2644,  | 
3180  |  |      2644, 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2644,  | 
3181  |  |      2644, 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2652,  | 
3182  |  |      2660, 2668, 2676, 2684, 2685, 2689, 2693, 2698, 2706, 2713, 2717, 2720,  | 
3183  |  |      2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720,  | 
3184  |  |      2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720,  | 
3185  |  |      2721, 2725, 2729, 2732, 2733, 2737, 2740, 2740, 2740, 2741, 2744, 2744,  | 
3186  |  |      2744, 2744, 2744, 2744, 2744},  | 
3187  |  |     {2744, 2752, 2760, 2760, 2768, 2768, 2768, 2768, 2776, 2776, 2776, 2776, | 
3188  |  |      2776, 2784, 2792, 2800, 2800, 2800, 2800, 2800, 2800, 2800, 2800, 2800,  | 
3189  |  |      2800, 2800, 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808,  | 
3190  |  |      2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808,  | 
3191  |  |      2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2816, 2816,  | 
3192  |  |      2816, 2816, 2816, 2816, 2816, 2816, 2816, 2816, 2816, 2816, 2816, 2816,  | 
3193  |  |      2816, 2816, 2816, 2816, 2816, 2816, 2816, 2816, 2816, 2824, 2832, 2832,  | 
3194  |  |      2840, 2840, 2840, 2840, 2848, 2848, 2848, 2848, 2848, 2856, 2864, 2872,  | 
3195  |  |      2872, 2872, 2872, 2872, 2872, 2872, 2872, 2872, 2872, 2872, 2872, 2872,  | 
3196  |  |      2872, 2872, 2872, 2872, 2872, 2872, 2872, 2872, 2872, 2872, 2872, 2880,  | 
3197  |  |      2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888,  | 
3198  |  |      2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888,  | 
3199  |  |      2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888,  | 
3200  |  |      2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888,  | 
3201  |  |      2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888,  | 
3202  |  |      2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888,  | 
3203  |  |      2888, 2888, 2896, 2904, 2904, 2904, 2904, 2904, 2904, 2904, 2904, 2904,  | 
3204  |  |      2904, 2904, 2904, 2904, 2904, 2912, 2920, 2928, 2936, 2936, 2936, 2944,  | 
3205  |  |      2952, 2952, 2952, 2960, 2968, 2976, 2984, 2992, 3000, 3000, 3000, 3008,  | 
3206  |  |      3016, 3024, 3032, 3040, 3048, 3048, 3048, 3056, 3064, 3072, 3080, 3088,  | 
3207  |  |      3096, 3104, 3112, 3120, 3128, 3136, 3144, 3144, 3144, 3152, 3160, 3160,  | 
3208  |  |      3160, 3160, 3160, 3160, 3160},  | 
3209  |  |     {3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, | 
3210  |  |      3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160,  | 
3211  |  |      3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160,  | 
3212  |  |      3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160,  | 
3213  |  |      3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160,  | 
3214  |  |      3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160,  | 
3215  |  |      3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160,  | 
3216  |  |      3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160,  | 
3217  |  |      3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160,  | 
3218  |  |      3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160,  | 
3219  |  |      3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160,  | 
3220  |  |      3160, 3160, 3160, 3161, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168,  | 
3221  |  |      3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168,  | 
3222  |  |      3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168,  | 
3223  |  |      3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168,  | 
3224  |  |      3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168,  | 
3225  |  |      3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168,  | 
3226  |  |      3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168,  | 
3227  |  |      3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168,  | 
3228  |  |      3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168,  | 
3229  |  |      3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168,  | 
3230  |  |      3168, 3168, 3168, 3168, 3168},  | 
3231  |  |     {3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, | 
3232  |  |      3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168,  | 
3233  |  |      3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3176,  | 
3234  |  |      3184, 3192, 3200, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208,  | 
3235  |  |      3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208,  | 
3236  |  |      3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208,  | 
3237  |  |      3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208,  | 
3238  |  |      3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208,  | 
3239  |  |      3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208,  | 
3240  |  |      3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3209, 3217, 3225,  | 
3241  |  |      3233, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240,  | 
3242  |  |      3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240,  | 
3243  |  |      3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240,  | 
3244  |  |      3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240,  | 
3245  |  |      3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240,  | 
3246  |  |      3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240,  | 
3247  |  |      3240, 3248, 3248, 3256, 3256, 3256, 3256, 3256, 3256, 3256, 3256, 3256,  | 
3248  |  |      3256, 3256, 3256, 3256, 3256, 3256, 3256, 3256, 3264, 3264, 3264, 3264,  | 
3249  |  |      3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264,  | 
3250  |  |      3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264,  | 
3251  |  |      3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264,  | 
3252  |  |      3264, 3264, 3264, 3264, 3264},  | 
3253  |  |     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
3254  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
3255  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
3256  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
3257  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
3258  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
3259  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
3260  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
3261  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
3262  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
3263  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  | 
3264  |  |     {3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, | 
3265  |  |      3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264,  | 
3266  |  |      3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264,  | 
3267  |  |      3264, 3264, 3264, 3264, 3264, 3264, 3272, 3272, 3272, 3272, 3272, 3272,  | 
3268  |  |      3272, 3272, 3280, 3280, 3280, 3288, 3288, 3288, 3288, 3288, 3288, 3288,  | 
3269  |  |      3288, 3288, 3288, 3288, 3288, 3288, 3288, 3288, 3288, 3288, 3288, 3288,  | 
3270  |  |      3288, 3288, 3288, 3288, 3288, 3288, 3288, 3288, 3288, 3288, 3288, 3288,  | 
3271  |  |      3288, 3288, 3288, 3288, 3288, 3296, 3304, 3312, 3320, 3328, 3336, 3344,  | 
3272  |  |      3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352,  | 
3273  |  |      3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352,  | 
3274  |  |      3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352,  | 
3275  |  |      3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352,  | 
3276  |  |      3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352,  | 
3277  |  |      3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352,  | 
3278  |  |      3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352,  | 
3279  |  |      3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352,  | 
3280  |  |      3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352,  | 
3281  |  |      3360, 3368, 3368, 3368, 3368, 3368, 3368, 3368, 3368, 3368, 3368, 3368,  | 
3282  |  |      3368, 3368, 3368, 3368, 3368, 3376, 3384, 3384, 3392, 3392, 3392, 3392,  | 
3283  |  |      3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392,  | 
3284  |  |      3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392,  | 
3285  |  |      3392, 3392, 3392, 3392, 3392},  | 
3286  |  |     {3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, | 
3287  |  |      3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392,  | 
3288  |  |      3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392,  | 
3289  |  |      3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392,  | 
3290  |  |      3392, 3392, 3392, 3392, 3400, 3400, 3400, 3408, 3408, 3408, 3408, 3408,  | 
3291  |  |      3408, 3408, 3408, 3408, 3408, 3408, 3408, 3408, 3408, 3408, 3408, 3408,  | 
3292  |  |      3408, 3408, 3408, 3408, 3408, 3408, 3408, 3408, 3408, 3408, 3408, 3408,  | 
3293  |  |      3408, 3408, 3408, 3408, 3408, 3408, 3416, 3424, 3432, 3432, 3432, 3440,  | 
3294  |  |      3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,  | 
3295  |  |      3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,  | 
3296  |  |      3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,  | 
3297  |  |      3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,  | 
3298  |  |      3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,  | 
3299  |  |      3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,  | 
3300  |  |      3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,  | 
3301  |  |      3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,  | 
3302  |  |      3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,  | 
3303  |  |      3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,  | 
3304  |  |      3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,  | 
3305  |  |      3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,  | 
3306  |  |      3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,  | 
3307  |  |      3440, 3440, 3440, 3440, 3440},  | 
3308  |  |     {3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, | 
3309  |  |      3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,  | 
3310  |  |      3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,  | 
3311  |  |      3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,  | 
3312  |  |      3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,  | 
3313  |  |      3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,  | 
3314  |  |      3440, 3448, 3448, 3448, 3456, 3464, 3464, 3464, 3464, 3464, 3464, 3464,  | 
3315  |  |      3464, 3464, 3464, 3464, 3464, 3464, 3464, 3464, 3464, 3472, 3480, 3480,  | 
3316  |  |      3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480,  | 
3317  |  |      3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480,  | 
3318  |  |      3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480,  | 
3319  |  |      3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480,  | 
3320  |  |      3480, 3480, 3480, 3480, 3480, 3488, 3488, 3488, 3488, 3488, 3488, 3488,  | 
3321  |  |      3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488,  | 
3322  |  |      3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488,  | 
3323  |  |      3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488,  | 
3324  |  |      3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3496,  | 
3325  |  |      3504, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512,  | 
3326  |  |      3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512,  | 
3327  |  |      3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512,  | 
3328  |  |      3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512,  | 
3329  |  |      3512, 3512, 3512, 3512, 3512},  | 
3330  |  |     {3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, | 
3331  |  |      3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512,  | 
3332  |  |      3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512,  | 
3333  |  |      3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512,  | 
3334  |  |      3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512,  | 
3335  |  |      3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512,  | 
3336  |  |      3512, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520,  | 
3337  |  |      3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520,  | 
3338  |  |      3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520,  | 
3339  |  |      3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520,  | 
3340  |  |      3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520,  | 
3341  |  |      3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520,  | 
3342  |  |      3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520,  | 
3343  |  |      3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520,  | 
3344  |  |      3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520,  | 
3345  |  |      3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520,  | 
3346  |  |      3520, 3528, 3528, 3528, 3528, 3528, 3528, 3528, 3536, 3544, 3544, 3552,  | 
3347  |  |      3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564,  | 
3348  |  |      3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564,  | 
3349  |  |      3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564,  | 
3350  |  |      3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564,  | 
3351  |  |      3564, 3564, 3564, 3564, 3564},  | 
3352  |  |     {3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, | 
3353  |  |      3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564,  | 
3354  |  |      3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564,  | 
3355  |  |      3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564,  | 
3356  |  |      3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564,  | 
3357  |  |      3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564,  | 
3358  |  |      3564, 3564, 3564, 3572, 3580, 3588, 3588, 3588, 3588, 3588, 3588, 3588,  | 
3359  |  |      3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588,  | 
3360  |  |      3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588,  | 
3361  |  |      3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588,  | 
3362  |  |      3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588,  | 
3363  |  |      3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588,  | 
3364  |  |      3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588,  | 
3365  |  |      3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588,  | 
3366  |  |      3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588,  | 
3367  |  |      3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588,  | 
3368  |  |      3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588,  | 
3369  |  |      3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588,  | 
3370  |  |      3588, 3588, 3588, 3596, 3596, 3604, 3616, 3624, 3624, 3624, 3624, 3624,  | 
3371  |  |      3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624,  | 
3372  |  |      3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624,  | 
3373  |  |      3624, 3624, 3624, 3624, 3624},  | 
3374  |  |     {3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, | 
3375  |  |      3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624,  | 
3376  |  |      3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624,  | 
3377  |  |      3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624,  | 
3378  |  |      3624, 3624, 3624, 3625, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632,  | 
3379  |  |      3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632,  | 
3380  |  |      3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632,  | 
3381  |  |      3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632,  | 
3382  |  |      3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632,  | 
3383  |  |      3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632,  | 
3384  |  |      3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632,  | 
3385  |  |      3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632,  | 
3386  |  |      3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632,  | 
3387  |  |      3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632,  | 
3388  |  |      3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3633,  | 
3389  |  |      3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640,  | 
3390  |  |      3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640,  | 
3391  |  |      3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640,  | 
3392  |  |      3640, 3640, 3640, 3640, 3641, 3649, 3656, 3656, 3656, 3656, 3656, 3656,  | 
3393  |  |      3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656,  | 
3394  |  |      3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656,  | 
3395  |  |      3656, 3656, 3656, 3656, 3656},  | 
3396  |  |     {3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, | 
3397  |  |      3657, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660,  | 
3398  |  |      3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660,  | 
3399  |  |      3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660,  | 
3400  |  |      3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660,  | 
3401  |  |      3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3668, 3668, 3668, 3668,  | 
3402  |  |      3668, 3668, 3668, 3668, 3668, 3668, 3676, 3676, 3676, 3676, 3676, 3684,  | 
3403  |  |      3684, 3684, 3684, 3684, 3692, 3692, 3692, 3692, 3692, 3700, 3700, 3700,  | 
3404  |  |      3700, 3700, 3700, 3700, 3700, 3700, 3700, 3700, 3700, 3700, 3708, 3708,  | 
3405  |  |      3708, 3708, 3708, 3708, 3708, 3708, 3708, 3708, 3716, 3716, 3724, 3733,  | 
3406  |  |      3744, 3753, 3764, 3764, 3764, 3764, 3764, 3764, 3764, 3764, 3772, 3772,  | 
3407  |  |      3772, 3772, 3772, 3772, 3772, 3772, 3772, 3772, 3772, 3772, 3772, 3772,  | 
3408  |  |      3772, 3772, 3772, 3772, 3780, 3780, 3780, 3780, 3780, 3780, 3780, 3780,  | 
3409  |  |      3780, 3780, 3788, 3788, 3788, 3788, 3788, 3796, 3796, 3796, 3796, 3796,  | 
3410  |  |      3804, 3804, 3804, 3804, 3804, 3812, 3812, 3812, 3812, 3812, 3812, 3812,  | 
3411  |  |      3812, 3812, 3812, 3812, 3812, 3812, 3820, 3820, 3820, 3820, 3820, 3820,  | 
3412  |  |      3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820,  | 
3413  |  |      3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820,  | 
3414  |  |      3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820,  | 
3415  |  |      3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820,  | 
3416  |  |      3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820,  | 
3417  |  |      3820, 3820, 3820, 3820, 3820},  | 
3418  |  |     {3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, | 
3419  |  |      3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820,  | 
3420  |  |      3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820,  | 
3421  |  |      3820, 3820, 3820, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,  | 
3422  |  |      3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,  | 
3423  |  |      3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,  | 
3424  |  |      3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,  | 
3425  |  |      3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,  | 
3426  |  |      3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,  | 
3427  |  |      3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,  | 
3428  |  |      3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,  | 
3429  |  |      3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,  | 
3430  |  |      3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,  | 
3431  |  |      3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,  | 
3432  |  |      3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,  | 
3433  |  |      3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,  | 
3434  |  |      3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,  | 
3435  |  |      3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,  | 
3436  |  |      3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,  | 
3437  |  |      3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,  | 
3438  |  |      3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,  | 
3439  |  |      3829, 3832, 3832, 3832, 3832},  | 
3440  |  |     {3832, 3832, 3832, 3832, 3832, 3832, 3832, 3840, 3840, 3848, 3848, 3856, | 
3441  |  |      3856, 3864, 3864, 3872, 3872, 3872, 3872, 3880, 3880, 3880, 3880, 3880,  | 
3442  |  |      3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880,  | 
3443  |  |      3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880,  | 
3444  |  |      3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880,  | 
3445  |  |      3888, 3888, 3896, 3896, 3896, 3904, 3912, 3912, 3920, 3920, 3920, 3920,  | 
3446  |  |      3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,  | 
3447  |  |      3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,  | 
3448  |  |      3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,  | 
3449  |  |      3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,  | 
3450  |  |      3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,  | 
3451  |  |      3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,  | 
3452  |  |      3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,  | 
3453  |  |      3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,  | 
3454  |  |      3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,  | 
3455  |  |      3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,  | 
3456  |  |      3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,  | 
3457  |  |      3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,  | 
3458  |  |      3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,  | 
3459  |  |      3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,  | 
3460  |  |      3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,  | 
3461  |  |      3920, 3920, 3920, 3920, 3920},  | 
3462  |  |     {3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, | 
3463  |  |      3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,  | 
3464  |  |      3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,  | 
3465  |  |      3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3921, 3925, 3929, 3932,  | 
3466  |  |      3933, 3937, 3941, 3945, 3949, 3953, 3957, 3961, 3965, 3969, 3973, 3976,  | 
3467  |  |      3977, 3981, 3985, 3989, 3993, 3997, 4001, 4005, 4009, 4013, 4017, 4021,  | 
3468  |  |      4025, 4029, 4033, 4037, 4041, 4045, 4048, 4049, 4053, 4057, 4061, 4065,  | 
3469  |  |      4069, 4073, 4077, 4081, 4085, 4089, 4093, 4097, 4101, 4105, 4109, 4113,  | 
3470  |  |      4117, 4121, 4125, 4129, 4133, 4137, 4141, 4145, 4149, 4153, 4157, 4160,  | 
3471  |  |      4160, 4160, 4160, 4160, 4160, 4160, 4160, 4160, 4160, 4160, 4160, 4160,  | 
3472  |  |      4161, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164,  | 
3473  |  |      4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164,  | 
3474  |  |      4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4165,  | 
3475  |  |      4169, 4173, 4177, 4181, 4185, 4189, 4193, 4197, 4201, 4205, 4209, 4213,  | 
3476  |  |      4217, 4221, 4225, 4229, 4233, 4237, 4241, 4245, 4249, 4253, 4257, 4261,  | 
3477  |  |      4265, 4269, 4273, 4277, 4281, 4285, 4289, 4293, 4297, 4301, 4305, 4309,  | 
3478  |  |      4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312,  | 
3479  |  |      4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312,  | 
3480  |  |      4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312,  | 
3481  |  |      4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312,  | 
3482  |  |      4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312,  | 
3483  |  |      4312, 4312, 4312, 4312, 4312},  | 
3484  |  |     {4312, 4320, 4328, 4336, 4344, 4352, 4360, 4368, 4376, 4388, 4400, 4408, | 
3485  |  |      4416, 4424, 4432, 4440, 4448, 4456, 4464, 4472, 4480, 4492, 4504, 4516,  | 
3486  |  |      4528, 4536, 4544, 4552, 4560, 4572, 4584, 4592, 4600, 4608, 4616, 4624,  | 
3487  |  |      4632, 4640, 4648, 4656, 4664, 4672, 4680, 4688, 4696, 4704, 4712, 4724,  | 
3488  |  |      4736, 4744, 4752, 4760, 4768, 4776, 4784, 4792, 4800, 4812, 4824, 4832,  | 
3489  |  |      4840, 4848, 4856, 4864, 4872, 4880, 4888, 4896, 4904, 4912, 4920, 4928,  | 
3490  |  |      4936, 4944, 4952, 4960, 4968, 4980, 4992, 5004, 5016, 5028, 5040, 5052,  | 
3491  |  |      5064, 5072, 5080, 5088, 5096, 5104, 5112, 5120, 5128, 5140, 5152, 5160,  | 
3492  |  |      5168, 5176, 5184, 5192, 5200, 5212, 5224, 5236, 5248, 5260, 5272, 5280,  | 
3493  |  |      5288, 5296, 5304, 5312, 5320, 5328, 5336, 5344, 5352, 5360, 5368, 5376,  | 
3494  |  |      5384, 5396, 5408, 5420, 5432, 5440, 5448, 5456, 5464, 5472, 5480, 5488,  | 
3495  |  |      5496, 5504, 5512, 5520, 5528, 5536, 5544, 5552, 5560, 5568, 5576, 5584,  | 
3496  |  |      5592, 5600, 5608, 5616, 5624, 5632, 5640, 5648, 5656, 5664, 5673, 5682,  | 
3497  |  |      5688, 5688, 5688, 5688, 5688, 5696, 5704, 5712, 5720, 5732, 5744, 5756,  | 
3498  |  |      5768, 5780, 5792, 5804, 5816, 5828, 5840, 5852, 5864, 5876, 5888, 5900,  | 
3499  |  |      5912, 5924, 5936, 5948, 5960, 5968, 5976, 5984, 5992, 6000, 6008, 6020,  | 
3500  |  |      6032, 6044, 6056, 6068, 6080, 6092, 6104, 6116, 6128, 6136, 6144, 6152,  | 
3501  |  |      6160, 6168, 6176, 6184, 6192, 6204, 6216, 6228, 6240, 6252, 6264, 6276,  | 
3502  |  |      6288, 6300, 6312, 6324, 6336, 6348, 6360, 6372, 6384, 6396, 6408, 6420,  | 
3503  |  |      6432, 6440, 6448, 6456, 6464, 6476, 6488, 6500, 6512, 6524, 6536, 6548,  | 
3504  |  |      6560, 6572, 6584, 6592, 6600, 6608, 6616, 6624, 6632, 6640, 6648, 6648,  | 
3505  |  |      6648, 6648, 6648, 6648, 6648},  | 
3506  |  |     {6648, 6656, 6664, 6676, 6688, 6700, 6712, 6724, 6736, 6744, 6752, 6764, | 
3507  |  |      6776, 6788, 6800, 6812, 6824, 6832, 6840, 6852, 6864, 6876, 6888, 6888,  | 
3508  |  |      6888, 6896, 6904, 6916, 6928, 6940, 6952, 6952, 6952, 6960, 6968, 6980,  | 
3509  |  |      6992, 7004, 7016, 7028, 7040, 7048, 7056, 7068, 7080, 7092, 7104, 7116,  | 
3510  |  |      7128, 7136, 7144, 7156, 7168, 7180, 7192, 7204, 7216, 7224, 7232, 7244,  | 
3511  |  |      7256, 7268, 7280, 7292, 7304, 7312, 7320, 7332, 7344, 7356, 7368, 7368,  | 
3512  |  |      7368, 7376, 7384, 7396, 7408, 7420, 7432, 7432, 7432, 7440, 7448, 7460,  | 
3513  |  |      7472, 7484, 7496, 7508, 7520, 7520, 7528, 7528, 7540, 7540, 7552, 7552,  | 
3514  |  |      7564, 7572, 7580, 7592, 7604, 7616, 7628, 7640, 7652, 7660, 7668, 7680,  | 
3515  |  |      7692, 7704, 7716, 7728, 7740, 7748, 7756, 7764, 7772, 7780, 7788, 7796,  | 
3516  |  |      7804, 7812, 7820, 7828, 7836, 7844, 7852, 7852, 7852, 7864, 7876, 7892,  | 
3517  |  |      7908, 7924, 7940, 7956, 7972, 7984, 7996, 8012, 8028, 8044, 8060, 8076,  | 
3518  |  |      8092, 8104, 8116, 8132, 8148, 8164, 8180, 8196, 8212, 8224, 8236, 8252,  | 
3519  |  |      8268, 8284, 8300, 8316, 8332, 8344, 8356, 8372, 8388, 8404, 8420, 8436,  | 
3520  |  |      8452, 8464, 8476, 8492, 8508, 8524, 8540, 8556, 8572, 8580, 8588, 8600,  | 
3521  |  |      8608, 8620, 8620, 8628, 8640, 8648, 8656, 8664, 8672, 8681, 8688, 8693,  | 
3522  |  |      8701, 8710, 8716, 8728, 8736, 8748, 8748, 8756, 8768, 8776, 8784, 8792,  | 
3523  |  |      8800, 8810, 8818, 8826, 8832, 8840, 8848, 8860, 8872, 8872, 8872, 8880,  | 
3524  |  |      8892, 8900, 8908, 8916, 8924, 8926, 8934, 8942, 8948, 8956, 8964, 8976,  | 
3525  |  |      8988, 8996, 9004, 9012, 9024, 9032, 9040, 9048, 9056, 9066, 9074, 9080,  | 
3526  |  |      9084, 9084, 9084, 9096, 9104, 9116, 9116, 9124, 9136, 9144, 9152, 9160,  | 
3527  |  |      9168, 9178, 9181, 9188, 9190},  | 
3528  |  |     {9190, 9194, 9197, 9201, 9205, 9209, 9213, 9217, 9221, 9225, 9229, 9232, | 
3529  |  |      9232, 9232, 9232, 9232, 9232, 9233, 9236, 9236, 9236, 9236, 9236, 9237,  | 
3530  |  |      9244, 9244, 9244, 9244, 9244, 9244, 9244, 9244, 9244, 9244, 9244, 9244,  | 
3531  |  |      9245, 9249, 9257, 9268, 9268, 9268, 9268, 9268, 9268, 9268, 9268, 9269,  | 
3532  |  |      9272, 9272, 9272, 9273, 9281, 9292, 9293, 9301, 9312, 9312, 9312, 9312,  | 
3533  |  |      9313, 9320, 9321, 9328, 9328, 9328, 9328, 9328, 9328, 9328, 9328, 9329,  | 
3534  |  |      9337, 9345, 9352, 9352, 9352, 9352, 9352, 9352, 9352, 9352, 9352, 9352,  | 
3535  |  |      9352, 9352, 9352, 9353, 9368, 9368, 9368, 9368, 9368, 9368, 9368, 9369,  | 
3536  |  |      9372, 9372, 9372, 9372, 9372, 9372, 9372, 9372, 9372, 9372, 9372, 9372,  | 
3537  |  |      9372, 9372, 9372, 9372, 9373, 9377, 9380, 9380, 9381, 9385, 9389, 9393,  | 
3538  |  |      9397, 9401, 9405, 9409, 9413, 9417, 9421, 9425, 9429, 9433, 9437, 9441,  | 
3539  |  |      9445, 9449, 9453, 9457, 9461, 9465, 9469, 9473, 9477, 9481, 9485, 9488,  | 
3540  |  |      9489, 9493, 9497, 9501, 9505, 9509, 9513, 9517, 9521, 9525, 9529, 9533,  | 
3541  |  |      9537, 9540, 9540, 9540, 9540, 9540, 9540, 9540, 9540, 9540, 9540, 9540,  | 
3542  |  |      9541, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548,  | 
3543  |  |      9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548,  | 
3544  |  |      9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548,  | 
3545  |  |      9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548,  | 
3546  |  |      9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548,  | 
3547  |  |      9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548,  | 
3548  |  |      9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548,  | 
3549  |  |      9548, 9548, 9548, 9548, 9549},  | 
3550  |  |     {9549,  9561,  9573,  9577,  9584,  9585,  9597,  9609,  9612,  9613, | 
3551  |  |      9621,  9625,  9629,  9633,  9637,  9641,  9645,  9649,  9653,  9657,  | 
3552  |  |      9660,  9661,  9665,  9672,  9672,  9673,  9677,  9681,  9685,  9689,  | 
3553  |  |      9692,  9692,  9693,  9701,  9713,  9720,  9721,  9724,  9724,  9728,  | 
3554  |  |      9729,  9732,  9732,  9736,  9745,  9749,  9752,  9753,  9757,  9761,  | 
3555  |  |      9764,  9765,  9769,  9773,  9777,  9781,  9785,  9789,  9792,  9793,  | 
3556  |  |      9805,  9809,  9813,  9817,  9821,  9824,  9824,  9824,  9824,  9825,  | 
3557  |  |      9829,  9833,  9837,  9841,  9844,  9844,  9844,  9844,  9844,  9844,  | 
3558  |  |      9845,  9857,  9869,  9885,  9897,  9909,  9921,  9933,  9945,  9957,  | 
3559  |  |      9969,  9981,  9993,  10005, 10017, 10029, 10037, 10041, 10049, 10061,  | 
3560  |  |      10069, 10073, 10081, 10093, 10109, 10117, 10121, 10129, 10141, 10145,  | 
3561  |  |      10149, 10153, 10157, 10161, 10169, 10181, 10189, 10193, 10201, 10213,  | 
3562  |  |      10229, 10237, 10241, 10249, 10261, 10265, 10269, 10273, 10276, 10276,  | 
3563  |  |      10276, 10276, 10276, 10276, 10276, 10276, 10276, 10277, 10288, 10288,  | 
3564  |  |      10288, 10288, 10288, 10288, 10288, 10288, 10288, 10288, 10288, 10288,  | 
3565  |  |      10288, 10288, 10288, 10288, 10288, 10296, 10304, 10304, 10304, 10304,  | 
3566  |  |      10304, 10304, 10304, 10304, 10304, 10304, 10304, 10304, 10304, 10304,  | 
3567  |  |      10304, 10304, 10304, 10304, 10304, 10312, 10312, 10312, 10312, 10312,  | 
3568  |  |      10312, 10312, 10312, 10312, 10312, 10312, 10312, 10312, 10312, 10312,  | 
3569  |  |      10312, 10312, 10312, 10312, 10312, 10312, 10312, 10312, 10312, 10312,  | 
3570  |  |      10312, 10312, 10312, 10312, 10312, 10312, 10320, 10328, 10336, 10336,  | 
3571  |  |      10336, 10336, 10336, 10336, 10336, 10336, 10336, 10336, 10336, 10336,  | 
3572  |  |      10336, 10336, 10336, 10336, 10336, 10336, 10336, 10336, 10336, 10336,  | 
3573  |  |      10336, 10336, 10336, 10336, 10336, 10336, 10336, 10336, 10336, 10336,  | 
3574  |  |      10336, 10336, 10336, 10336, 10336, 10336, 10336, 10336, 10336, 10336,  | 
3575  |  |      10336, 10336, 10336, 10336, 10336, 10336, 10336},  | 
3576  |  |     {10336, 10336, 10336, 10336, 10336, 10344, 10344, 10344, 10344, 10344, | 
3577  |  |      10352, 10352, 10352, 10360, 10360, 10360, 10360, 10360, 10360, 10360,  | 
3578  |  |      10360, 10360, 10360, 10360, 10360, 10360, 10360, 10360, 10360, 10360,  | 
3579  |  |      10360, 10360, 10360, 10360, 10360, 10360, 10360, 10368, 10368, 10376,  | 
3580  |  |      10376, 10376, 10376, 10376, 10377, 10385, 10396, 10397, 10405, 10416,  | 
3581  |  |      10416, 10416, 10416, 10416, 10416, 10416, 10416, 10416, 10416, 10416,  | 
3582  |  |      10416, 10416, 10416, 10416, 10416, 10416, 10424, 10424, 10424, 10432,  | 
3583  |  |      10432, 10432, 10440, 10440, 10448, 10448, 10448, 10448, 10448, 10448,  | 
3584  |  |      10448, 10448, 10448, 10448, 10448, 10448, 10448, 10448, 10448, 10448,  | 
3585  |  |      10448, 10448, 10448, 10448, 10448, 10448, 10448, 10456, 10456, 10464,  | 
3586  |  |      10464, 10464, 10464, 10464, 10464, 10464, 10464, 10464, 10464, 10464,  | 
3587  |  |      10472, 10480, 10488, 10496, 10504, 10504, 10504, 10512, 10520, 10520,  | 
3588  |  |      10520, 10528, 10536, 10536, 10536, 10536, 10536, 10536, 10536, 10544,  | 
3589  |  |      10552, 10552, 10552, 10560, 10568, 10568, 10568, 10576, 10584, 10584,  | 
3590  |  |      10584, 10584, 10584, 10584, 10584, 10584, 10584, 10584, 10584, 10584,  | 
3591  |  |      10584, 10584, 10584, 10584, 10584, 10584, 10584, 10584, 10584, 10584,  | 
3592  |  |      10584, 10584, 10584, 10584, 10584, 10584, 10584, 10584, 10584, 10584,  | 
3593  |  |      10584, 10584, 10584, 10592, 10600, 10608, 10616, 10616, 10616, 10616,  | 
3594  |  |      10616, 10616, 10616, 10616, 10616, 10616, 10616, 10616, 10616, 10616,  | 
3595  |  |      10616, 10616, 10616, 10616, 10616, 10616, 10616, 10616, 10616, 10616,  | 
3596  |  |      10616, 10616, 10616, 10616, 10616, 10616, 10616, 10616, 10616, 10616,  | 
3597  |  |      10616, 10616, 10616, 10616, 10616, 10616, 10616, 10616, 10616, 10616,  | 
3598  |  |      10616, 10616, 10616, 10616, 10616, 10624, 10632, 10640, 10648, 10648,  | 
3599  |  |      10648, 10648, 10648, 10648, 10648, 10656, 10664, 10672, 10680, 10680,  | 
3600  |  |      10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680,  | 
3601  |  |      10680, 10680, 10680, 10680, 10680, 10680, 10680},  | 
3602  |  |     {10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680, | 
3603  |  |      10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680,  | 
3604  |  |      10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680,  | 
3605  |  |      10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680,  | 
3606  |  |      10680, 10680, 10684, 10688, 10688, 10688, 10688, 10688, 10688, 10688,  | 
3607  |  |      10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,  | 
3608  |  |      10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,  | 
3609  |  |      10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,  | 
3610  |  |      10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,  | 
3611  |  |      10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,  | 
3612  |  |      10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,  | 
3613  |  |      10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,  | 
3614  |  |      10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,  | 
3615  |  |      10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,  | 
3616  |  |      10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,  | 
3617  |  |      10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,  | 
3618  |  |      10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,  | 
3619  |  |      10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,  | 
3620  |  |      10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,  | 
3621  |  |      10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,  | 
3622  |  |      10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,  | 
3623  |  |      10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,  | 
3624  |  |      10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,  | 
3625  |  |      10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,  | 
3626  |  |      10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,  | 
3627  |  |      10688, 10688, 10688, 10688, 10688, 10688, 10688},  | 
3628  |  |     {10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, | 
3629  |  |      10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,  | 
3630  |  |      10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,  | 
3631  |  |      10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,  | 
3632  |  |      10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,  | 
3633  |  |      10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,  | 
3634  |  |      10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,  | 
3635  |  |      10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,  | 
3636  |  |      10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,  | 
3637  |  |      10688, 10688, 10688, 10688, 10688, 10688, 10689, 10693, 10697, 10701,  | 
3638  |  |      10705, 10709, 10713, 10717, 10721, 10725, 10733, 10741, 10749, 10757,  | 
3639  |  |      10765, 10773, 10781, 10789, 10797, 10805, 10813, 10825, 10837, 10849,  | 
3640  |  |      10861, 10873, 10885, 10897, 10909, 10921, 10937, 10953, 10969, 10985,  | 
3641  |  |      11001, 11017, 11033, 11049, 11065, 11081, 11097, 11105, 11113, 11121,  | 
3642  |  |      11129, 11137, 11145, 11153, 11161, 11169, 11181, 11193, 11205, 11217,  | 
3643  |  |      11229, 11241, 11253, 11265, 11277, 11289, 11301, 11313, 11325, 11337,  | 
3644  |  |      11349, 11361, 11373, 11385, 11397, 11409, 11421, 11433, 11445, 11457,  | 
3645  |  |      11469, 11481, 11493, 11505, 11517, 11529, 11541, 11553, 11565, 11577,  | 
3646  |  |      11589, 11601, 11613, 11617, 11621, 11625, 11629, 11633, 11637, 11641,  | 
3647  |  |      11645, 11649, 11653, 11657, 11661, 11665, 11669, 11673, 11677, 11681,  | 
3648  |  |      11685, 11689, 11693, 11697, 11701, 11705, 11709, 11713, 11717, 11721,  | 
3649  |  |      11725, 11729, 11733, 11737, 11741, 11745, 11749, 11753, 11757, 11761,  | 
3650  |  |      11765, 11769, 11773, 11777, 11781, 11785, 11789, 11793, 11797, 11801,  | 
3651  |  |      11805, 11809, 11813, 11817, 11821, 11824, 11824, 11824, 11824, 11824,  | 
3652  |  |      11824, 11824, 11824, 11824, 11824, 11824, 11824, 11824, 11824, 11824,  | 
3653  |  |      11824, 11824, 11824, 11824, 11824, 11824, 11824},  | 
3654  |  |     {11824, 11824, 11824, 11824, 11824, 11824, 11824, 11824, 11824, 11824, | 
3655  |  |      11824, 11824, 11825, 11840, 11840, 11840, 11840, 11840, 11840, 11840,  | 
3656  |  |      11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840,  | 
3657  |  |      11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840,  | 
3658  |  |      11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840,  | 
3659  |  |      11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840,  | 
3660  |  |      11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840,  | 
3661  |  |      11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840,  | 
3662  |  |      11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840,  | 
3663  |  |      11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840,  | 
3664  |  |      11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840,  | 
3665  |  |      11840, 11840, 11840, 11840, 11840, 11840, 11841, 11853, 11861, 11872,  | 
3666  |  |      11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872,  | 
3667  |  |      11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872,  | 
3668  |  |      11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872,  | 
3669  |  |      11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872,  | 
3670  |  |      11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872,  | 
3671  |  |      11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872,  | 
3672  |  |      11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872,  | 
3673  |  |      11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872,  | 
3674  |  |      11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872,  | 
3675  |  |      11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872,  | 
3676  |  |      11872, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,  | 
3677  |  |      11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,  | 
3678  |  |      11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,  | 
3679  |  |      11880, 11880, 11880, 11880, 11880, 11880, 11880},  | 
3680  |  |     {11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, | 
3681  |  |      11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,  | 
3682  |  |      11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,  | 
3683  |  |      11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,  | 
3684  |  |      11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,  | 
3685  |  |      11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,  | 
3686  |  |      11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,  | 
3687  |  |      11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,  | 
3688  |  |      11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,  | 
3689  |  |      11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,  | 
3690  |  |      11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,  | 
3691  |  |      11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,  | 
3692  |  |      11880, 11880, 11880, 11880, 11881, 11885, 11888, 11888, 11888, 11888,  | 
3693  |  |      11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,  | 
3694  |  |      11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,  | 
3695  |  |      11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,  | 
3696  |  |      11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,  | 
3697  |  |      11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,  | 
3698  |  |      11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,  | 
3699  |  |      11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,  | 
3700  |  |      11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,  | 
3701  |  |      11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,  | 
3702  |  |      11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,  | 
3703  |  |      11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,  | 
3704  |  |      11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,  | 
3705  |  |      11888, 11888, 11888, 11888, 11888, 11888, 11888},  | 
3706  |  |     {11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, | 
3707  |  |      11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,  | 
3708  |  |      11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,  | 
3709  |  |      11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,  | 
3710  |  |      11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,  | 
3711  |  |      11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,  | 
3712  |  |      11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,  | 
3713  |  |      11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,  | 
3714  |  |      11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,  | 
3715  |  |      11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,  | 
3716  |  |      11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,  | 
3717  |  |      11888, 11889, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,  | 
3718  |  |      11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,  | 
3719  |  |      11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,  | 
3720  |  |      11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,  | 
3721  |  |      11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,  | 
3722  |  |      11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,  | 
3723  |  |      11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,  | 
3724  |  |      11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,  | 
3725  |  |      11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,  | 
3726  |  |      11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,  | 
3727  |  |      11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,  | 
3728  |  |      11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,  | 
3729  |  |      11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,  | 
3730  |  |      11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,  | 
3731  |  |      11892, 11892, 11892, 11892, 11892, 11892, 11892},  | 
3732  |  |     {11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, | 
3733  |  |      11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,  | 
3734  |  |      11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,  | 
3735  |  |      11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,  | 
3736  |  |      11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,  | 
3737  |  |      11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,  | 
3738  |  |      11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,  | 
3739  |  |      11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,  | 
3740  |  |      11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,  | 
3741  |  |      11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,  | 
3742  |  |      11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,  | 
3743  |  |      11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,  | 
3744  |  |      11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,  | 
3745  |  |      11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,  | 
3746  |  |      11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,  | 
3747  |  |      11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11893,  | 
3748  |  |      11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896,  | 
3749  |  |      11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896,  | 
3750  |  |      11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896,  | 
3751  |  |      11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896,  | 
3752  |  |      11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896,  | 
3753  |  |      11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896,  | 
3754  |  |      11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896,  | 
3755  |  |      11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896,  | 
3756  |  |      11896, 11896, 11896, 11897, 11900, 11900, 11900, 11900, 11900, 11900,  | 
3757  |  |      11900, 11900, 11900, 11900, 11900, 11900, 11901},  | 
3758  |  |     {11901, 11905, 11909, 11913, 11917, 11921, 11925, 11929, 11933, 11937, | 
3759  |  |      11941, 11945, 11949, 11953, 11957, 11961, 11965, 11969, 11973, 11977,  | 
3760  |  |      11981, 11985, 11989, 11993, 11997, 12001, 12005, 12009, 12013, 12017,  | 
3761  |  |      12021, 12025, 12029, 12033, 12037, 12041, 12045, 12049, 12053, 12057,  | 
3762  |  |      12061, 12065, 12069, 12073, 12077, 12081, 12085, 12089, 12093, 12097,  | 
3763  |  |      12101, 12105, 12109, 12113, 12117, 12121, 12125, 12129, 12133, 12137,  | 
3764  |  |      12141, 12145, 12149, 12153, 12157, 12161, 12165, 12169, 12173, 12177,  | 
3765  |  |      12181, 12185, 12189, 12193, 12197, 12201, 12205, 12209, 12213, 12217,  | 
3766  |  |      12221, 12225, 12229, 12233, 12237, 12241, 12245, 12249, 12253, 12257,  | 
3767  |  |      12261, 12265, 12269, 12273, 12277, 12281, 12285, 12289, 12293, 12297,  | 
3768  |  |      12301, 12305, 12309, 12313, 12317, 12321, 12325, 12329, 12333, 12337,  | 
3769  |  |      12341, 12345, 12349, 12353, 12357, 12361, 12365, 12369, 12373, 12377,  | 
3770  |  |      12381, 12385, 12389, 12393, 12397, 12401, 12405, 12409, 12413, 12417,  | 
3771  |  |      12421, 12425, 12429, 12433, 12437, 12441, 12445, 12449, 12453, 12457,  | 
3772  |  |      12461, 12465, 12469, 12473, 12477, 12481, 12485, 12489, 12493, 12497,  | 
3773  |  |      12501, 12505, 12509, 12513, 12517, 12521, 12525, 12529, 12533, 12537,  | 
3774  |  |      12541, 12545, 12549, 12553, 12557, 12561, 12565, 12569, 12573, 12577,  | 
3775  |  |      12581, 12585, 12589, 12593, 12597, 12601, 12605, 12609, 12613, 12617,  | 
3776  |  |      12621, 12625, 12629, 12633, 12637, 12641, 12645, 12649, 12653, 12657,  | 
3777  |  |      12661, 12665, 12669, 12673, 12677, 12681, 12685, 12689, 12693, 12697,  | 
3778  |  |      12701, 12705, 12709, 12713, 12717, 12721, 12725, 12729, 12733, 12737,  | 
3779  |  |      12741, 12745, 12749, 12753, 12756, 12756, 12756, 12756, 12756, 12756,  | 
3780  |  |      12756, 12756, 12756, 12756, 12756, 12756, 12756, 12756, 12756, 12756,  | 
3781  |  |      12756, 12756, 12756, 12756, 12756, 12756, 12756, 12756, 12756, 12756,  | 
3782  |  |      12756, 12756, 12756, 12756, 12756, 12756, 12756, 12756, 12756, 12756,  | 
3783  |  |      12756, 12756, 12756, 12756, 12756, 12756, 12757},  | 
3784  |  |     {12757, 12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760, | 
3785  |  |      12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760,  | 
3786  |  |      12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760,  | 
3787  |  |      12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760,  | 
3788  |  |      12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760,  | 
3789  |  |      12760, 12760, 12760, 12760, 12761, 12764, 12765, 12769, 12773, 12776,  | 
3790  |  |      12776, 12776, 12776, 12776, 12776, 12776, 12776, 12776, 12776, 12776,  | 
3791  |  |      12776, 12776, 12776, 12776, 12776, 12776, 12776, 12784, 12784, 12792,  | 
3792  |  |      12792, 12800, 12800, 12808, 12808, 12816, 12816, 12824, 12824, 12832,  | 
3793  |  |      12832, 12840, 12840, 12848, 12848, 12856, 12856, 12864, 12864, 12872,  | 
3794  |  |      12872, 12872, 12880, 12880, 12888, 12888, 12896, 12896, 12896, 12896,  | 
3795  |  |      12896, 12896, 12896, 12904, 12912, 12912, 12920, 12928, 12928, 12936,  | 
3796  |  |      12944, 12944, 12952, 12960, 12960, 12968, 12976, 12976, 12976, 12976,  | 
3797  |  |      12976, 12976, 12976, 12976, 12976, 12976, 12976, 12976, 12976, 12976,  | 
3798  |  |      12976, 12976, 12976, 12976, 12976, 12976, 12976, 12976, 12976, 12984,  | 
3799  |  |      12984, 12984, 12984, 12984, 12984, 12985, 12993, 13000, 13000, 13009,  | 
3800  |  |      13016, 13016, 13016, 13016, 13016, 13016, 13016, 13016, 13016, 13016,  | 
3801  |  |      13016, 13016, 13016, 13024, 13024, 13032, 13032, 13040, 13040, 13048,  | 
3802  |  |      13048, 13056, 13056, 13064, 13064, 13072, 13072, 13080, 13080, 13088,  | 
3803  |  |      13088, 13096, 13096, 13104, 13104, 13112, 13112, 13112, 13120, 13120,  | 
3804  |  |      13128, 13128, 13136, 13136, 13136, 13136, 13136, 13136, 13136, 13144,  | 
3805  |  |      13152, 13152, 13160, 13168, 13168, 13176, 13184, 13184, 13192, 13200,  | 
3806  |  |      13200, 13208, 13216, 13216, 13216, 13216, 13216, 13216, 13216, 13216,  | 
3807  |  |      13216, 13216, 13216, 13216, 13216, 13216, 13216, 13216, 13216, 13216,  | 
3808  |  |      13216, 13216, 13216, 13216, 13216, 13224, 13224, 13224, 13232, 13240,  | 
3809  |  |      13248, 13256, 13256, 13256, 13256, 13265, 13272},  | 
3810  |  |     {13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272, | 
3811  |  |      13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272,  | 
3812  |  |      13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272,  | 
3813  |  |      13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272,  | 
3814  |  |      13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272, 13273,  | 
3815  |  |      13277, 13281, 13285, 13289, 13293, 13297, 13301, 13305, 13309, 13313,  | 
3816  |  |      13317, 13321, 13325, 13329, 13333, 13337, 13341, 13345, 13349, 13353,  | 
3817  |  |      13357, 13361, 13365, 13369, 13373, 13377, 13381, 13385, 13389, 13393,  | 
3818  |  |      13397, 13401, 13405, 13409, 13413, 13417, 13421, 13425, 13429, 13433,  | 
3819  |  |      13437, 13441, 13445, 13449, 13453, 13457, 13461, 13465, 13469, 13473,  | 
3820  |  |      13477, 13481, 13485, 13489, 13493, 13497, 13501, 13505, 13509, 13513,  | 
3821  |  |      13517, 13521, 13525, 13529, 13533, 13537, 13541, 13545, 13549, 13553,  | 
3822  |  |      13557, 13561, 13565, 13569, 13573, 13577, 13581, 13585, 13589, 13593,  | 
3823  |  |      13597, 13601, 13605, 13609, 13613, 13617, 13621, 13625, 13629, 13633,  | 
3824  |  |      13637, 13641, 13645, 13648, 13648, 13648, 13649, 13653, 13657, 13661,  | 
3825  |  |      13665, 13669, 13673, 13677, 13681, 13685, 13689, 13693, 13697, 13701,  | 
3826  |  |      13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704,  | 
3827  |  |      13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704,  | 
3828  |  |      13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704,  | 
3829  |  |      13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704,  | 
3830  |  |      13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704,  | 
3831  |  |      13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704,  | 
3832  |  |      13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704,  | 
3833  |  |      13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704,  | 
3834  |  |      13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704,  | 
3835  |  |      13704, 13704, 13704, 13704, 13704, 13704, 13705},  | 
3836  |  |     {13705, 13717, 13729, 13741, 13753, 13765, 13777, 13789, 13801, 13813, | 
3837  |  |      13825, 13837, 13849, 13861, 13873, 13889, 13905, 13921, 13937, 13953,  | 
3838  |  |      13969, 13985, 14001, 14017, 14033, 14049, 14065, 14081, 14097, 14113,  | 
3839  |  |      14141, 14164, 14165, 14177, 14189, 14201, 14213, 14225, 14237, 14249,  | 
3840  |  |      14261, 14273, 14285, 14297, 14309, 14321, 14333, 14345, 14357, 14369,  | 
3841  |  |      14381, 14393, 14405, 14417, 14429, 14441, 14453, 14465, 14477, 14489,  | 
3842  |  |      14501, 14513, 14525, 14537, 14549, 14561, 14573, 14585, 14597, 14601,  | 
3843  |  |      14605, 14609, 14612, 14612, 14612, 14612, 14612, 14612, 14612, 14612,  | 
3844  |  |      14613, 14625, 14633, 14641, 14649, 14657, 14665, 14673, 14681, 14689,  | 
3845  |  |      14697, 14705, 14713, 14721, 14729, 14737, 14745, 14749, 14753, 14757,  | 
3846  |  |      14761, 14765, 14769, 14773, 14777, 14781, 14785, 14789, 14793, 14797,  | 
3847  |  |      14801, 14809, 14817, 14825, 14833, 14841, 14849, 14857, 14865, 14873,  | 
3848  |  |      14881, 14889, 14897, 14905, 14913, 14933, 14949, 14956, 14957, 14961,  | 
3849  |  |      14965, 14969, 14973, 14977, 14981, 14985, 14989, 14993, 14997, 15001,  | 
3850  |  |      15005, 15009, 15013, 15017, 15021, 15025, 15029, 15033, 15037, 15041,  | 
3851  |  |      15045, 15049, 15053, 15057, 15061, 15065, 15069, 15073, 15077, 15081,  | 
3852  |  |      15085, 15089, 15093, 15097, 15101, 15105, 15109, 15113, 15117, 15121,  | 
3853  |  |      15125, 15129, 15133, 15137, 15141, 15145, 15149, 15153, 15161, 15169,  | 
3854  |  |      15177, 15185, 15193, 15201, 15209, 15217, 15225, 15233, 15241, 15249,  | 
3855  |  |      15257, 15265, 15273, 15281, 15289, 15297, 15305, 15313, 15321, 15329,  | 
3856  |  |      15337, 15345, 15357, 15369, 15381, 15389, 15401, 15409, 15421, 15425,  | 
3857  |  |      15429, 15433, 15437, 15441, 15445, 15449, 15453, 15457, 15461, 15465,  | 
3858  |  |      15469, 15473, 15477, 15481, 15485, 15489, 15493, 15497, 15501, 15505,  | 
3859  |  |      15509, 15513, 15517, 15521, 15525, 15529, 15533, 15537, 15541, 15545,  | 
3860  |  |      15549, 15553, 15557, 15561, 15565, 15569, 15573, 15577, 15581, 15585,  | 
3861  |  |      15589, 15593, 15597, 15601, 15605, 15609, 15617},  | 
3862  |  |     {15617, 15637, 15653, 15673, 15685, 15705, 15717, 15729, 15753, 15769, | 
3863  |  |      15781, 15793, 15805, 15821, 15837, 15853, 15869, 15885, 15901, 15917,  | 
3864  |  |      15941, 15949, 15973, 15997, 16017, 16033, 16057, 16081, 16097, 16109,  | 
3865  |  |      16121, 16137, 16153, 16173, 16193, 16205, 16217, 16233, 16245, 16257,  | 
3866  |  |      16265, 16273, 16285, 16297, 16321, 16337, 16357, 16381, 16397, 16409,  | 
3867  |  |      16421, 16445, 16461, 16485, 16497, 16517, 16529, 16545, 16557, 16573,  | 
3868  |  |      16593, 16609, 16629, 16645, 16653, 16673, 16685, 16697, 16713, 16725,  | 
3869  |  |      16737, 16749, 16769, 16785, 16793, 16817, 16829, 16849, 16865, 16881,  | 
3870  |  |      16893, 16905, 16921, 16929, 16945, 16965, 16973, 16997, 17009, 17017,  | 
3871  |  |      17025, 17033, 17041, 17049, 17057, 17065, 17073, 17081, 17089, 17101,  | 
3872  |  |      17113, 17125, 17137, 17149, 17161, 17173, 17185, 17197, 17209, 17221,  | 
3873  |  |      17233, 17245, 17257, 17269, 17281, 17289, 17297, 17309, 17317, 17325,  | 
3874  |  |      17333, 17345, 17357, 17365, 17373, 17381, 17389, 17397, 17413, 17421,  | 
3875  |  |      17429, 17437, 17445, 17453, 17461, 17469, 17477, 17489, 17505, 17513,  | 
3876  |  |      17521, 17529, 17537, 17545, 17553, 17561, 17573, 17585, 17597, 17609,  | 
3877  |  |      17617, 17625, 17633, 17641, 17649, 17657, 17665, 17673, 17681, 17689,  | 
3878  |  |      17701, 17713, 17721, 17733, 17745, 17757, 17765, 17777, 17789, 17805,  | 
3879  |  |      17813, 17825, 17837, 17849, 17861, 17881, 17905, 17913, 17921, 17929,  | 
3880  |  |      17937, 17945, 17953, 17961, 17969, 17977, 17985, 17993, 18001, 18009,  | 
3881  |  |      18017, 18025, 18033, 18041, 18049, 18065, 18073, 18081, 18089, 18105,  | 
3882  |  |      18117, 18125, 18133, 18141, 18149, 18157, 18165, 18173, 18181, 18189,  | 
3883  |  |      18197, 18209, 18217, 18225, 18237, 18249, 18257, 18273, 18285, 18293,  | 
3884  |  |      18301, 18309, 18317, 18329, 18341, 18349, 18357, 18365, 18373, 18381,  | 
3885  |  |      18389, 18397, 18405, 18413, 18425, 18437, 18449, 18461, 18473, 18485,  | 
3886  |  |      18497, 18509, 18521, 18533, 18545, 18557, 18569, 18581, 18593, 18605,  | 
3887  |  |      18617, 18629, 18641, 18653, 18665, 18677, 18688},  | 
3888  |  |     {18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, | 
3889  |  |      18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,  | 
3890  |  |      18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,  | 
3891  |  |      18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,  | 
3892  |  |      18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,  | 
3893  |  |      18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,  | 
3894  |  |      18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,  | 
3895  |  |      18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,  | 
3896  |  |      18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,  | 
3897  |  |      18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,  | 
3898  |  |      18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,  | 
3899  |  |      18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,  | 
3900  |  |      18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,  | 
3901  |  |      18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,  | 
3902  |  |      18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,  | 
3903  |  |      18688, 18688, 18688, 18688, 18688, 18688, 18689, 18693, 18696, 18696,  | 
3904  |  |      18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,  | 
3905  |  |      18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,  | 
3906  |  |      18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,  | 
3907  |  |      18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,  | 
3908  |  |      18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,  | 
3909  |  |      18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,  | 
3910  |  |      18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,  | 
3911  |  |      18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,  | 
3912  |  |      18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,  | 
3913  |  |      18696, 18696, 18696, 18696, 18696, 18696, 18696},  | 
3914  |  |     {18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, | 
3915  |  |      18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,  | 
3916  |  |      18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,  | 
3917  |  |      18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,  | 
3918  |  |      18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,  | 
3919  |  |      18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,  | 
3920  |  |      18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,  | 
3921  |  |      18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,  | 
3922  |  |      18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,  | 
3923  |  |      18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,  | 
3924  |  |      18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,  | 
3925  |  |      18696, 18696, 18697, 18700, 18700, 18700, 18700, 18700, 18700, 18700,  | 
3926  |  |      18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700,  | 
3927  |  |      18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700,  | 
3928  |  |      18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700,  | 
3929  |  |      18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700,  | 
3930  |  |      18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700,  | 
3931  |  |      18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700,  | 
3932  |  |      18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700,  | 
3933  |  |      18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700,  | 
3934  |  |      18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700,  | 
3935  |  |      18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700,  | 
3936  |  |      18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700,  | 
3937  |  |      18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700,  | 
3938  |  |      18700, 18700, 18701, 18705, 18709, 18712, 18712, 18712, 18713, 18717,  | 
3939  |  |      18720, 18720, 18720, 18720, 18720, 18720, 18720},  | 
3940  |  |     {18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, | 
3941  |  |      18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720,  | 
3942  |  |      18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720,  | 
3943  |  |      18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720,  | 
3944  |  |      18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720,  | 
3945  |  |      18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720,  | 
3946  |  |      18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720,  | 
3947  |  |      18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720,  | 
3948  |  |      18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720,  | 
3949  |  |      18720, 18720, 18721, 18725, 18729, 18733, 18736, 18736, 18736, 18736,  | 
3950  |  |      18736, 18736, 18736, 18736, 18736, 18737, 18740, 18740, 18740, 18740,  | 
3951  |  |      18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,  | 
3952  |  |      18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,  | 
3953  |  |      18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,  | 
3954  |  |      18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,  | 
3955  |  |      18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,  | 
3956  |  |      18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,  | 
3957  |  |      18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,  | 
3958  |  |      18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,  | 
3959  |  |      18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,  | 
3960  |  |      18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,  | 
3961  |  |      18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,  | 
3962  |  |      18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,  | 
3963  |  |      18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,  | 
3964  |  |      18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,  | 
3965  |  |      18740, 18740, 18740, 18740, 18740, 18740, 18740},  | 
3966  |  |     {18740, 18744, 18748, 18752, 18756, 18760, 18764, 18768, 18772, 18776, | 
3967  |  |      18780, 18784, 18788, 18792, 18796, 18800, 18804, 18808, 18812, 18816,  | 
3968  |  |      18820, 18824, 18828, 18832, 18836, 18840, 18844, 18848, 18852, 18856,  | 
3969  |  |      18860, 18864, 18868, 18872, 18876, 18880, 18884, 18888, 18892, 18896,  | 
3970  |  |      18900, 18904, 18908, 18912, 18916, 18920, 18924, 18928, 18932, 18936,  | 
3971  |  |      18940, 18944, 18948, 18952, 18956, 18960, 18964, 18968, 18972, 18976,  | 
3972  |  |      18980, 18984, 18988, 18992, 18996, 19000, 19004, 19008, 19012, 19016,  | 
3973  |  |      19020, 19024, 19028, 19032, 19036, 19040, 19044, 19048, 19052, 19056,  | 
3974  |  |      19060, 19064, 19068, 19072, 19076, 19080, 19084, 19088, 19092, 19096,  | 
3975  |  |      19100, 19104, 19108, 19112, 19116, 19120, 19124, 19128, 19132, 19136,  | 
3976  |  |      19140, 19144, 19148, 19152, 19156, 19160, 19164, 19168, 19172, 19176,  | 
3977  |  |      19180, 19184, 19188, 19192, 19196, 19200, 19204, 19208, 19212, 19216,  | 
3978  |  |      19220, 19224, 19228, 19232, 19236, 19240, 19244, 19248, 19252, 19256,  | 
3979  |  |      19260, 19264, 19268, 19272, 19276, 19280, 19284, 19288, 19292, 19296,  | 
3980  |  |      19300, 19304, 19308, 19312, 19316, 19320, 19324, 19328, 19332, 19336,  | 
3981  |  |      19340, 19344, 19348, 19352, 19356, 19360, 19364, 19368, 19372, 19376,  | 
3982  |  |      19380, 19384, 19388, 19392, 19396, 19400, 19404, 19408, 19412, 19416,  | 
3983  |  |      19420, 19424, 19428, 19432, 19436, 19440, 19444, 19448, 19452, 19456,  | 
3984  |  |      19460, 19464, 19468, 19472, 19476, 19480, 19484, 19488, 19492, 19496,  | 
3985  |  |      19500, 19504, 19508, 19512, 19516, 19520, 19524, 19528, 19532, 19536,  | 
3986  |  |      19540, 19544, 19548, 19552, 19556, 19560, 19564, 19568, 19572, 19576,  | 
3987  |  |      19580, 19584, 19588, 19592, 19596, 19600, 19604, 19608, 19612, 19616,  | 
3988  |  |      19620, 19624, 19628, 19632, 19636, 19640, 19644, 19648, 19652, 19656,  | 
3989  |  |      19660, 19664, 19668, 19672, 19676, 19680, 19684, 19688, 19692, 19696,  | 
3990  |  |      19700, 19704, 19708, 19712, 19716, 19720, 19724, 19728, 19732, 19736,  | 
3991  |  |      19740, 19744, 19748, 19752, 19756, 19760, 19764},  | 
3992  |  |     {19764, 19768, 19772, 19776, 19780, 19784, 19788, 19792, 19796, 19800, | 
3993  |  |      19804, 19808, 19812, 19816, 19820, 19820, 19820, 19824, 19824, 19828,  | 
3994  |  |      19828, 19828, 19832, 19836, 19840, 19844, 19848, 19852, 19856, 19860,  | 
3995  |  |      19864, 19868, 19868, 19872, 19872, 19876, 19876, 19876, 19880, 19884,  | 
3996  |  |      19884, 19884, 19884, 19888, 19892, 19896, 19900, 19904, 19908, 19912,  | 
3997  |  |      19916, 19920, 19924, 19928, 19932, 19936, 19940, 19944, 19948, 19952,  | 
3998  |  |      19956, 19960, 19964, 19968, 19972, 19976, 19980, 19984, 19988, 19992,  | 
3999  |  |      19996, 20000, 20004, 20008, 20012, 20016, 20020, 20024, 20028, 20032,  | 
4000  |  |      20036, 20040, 20044, 20048, 20052, 20056, 20060, 20064, 20068, 20072,  | 
4001  |  |      20076, 20080, 20084, 20088, 20092, 20096, 20100, 20104, 20108, 20112,  | 
4002  |  |      20116, 20120, 20124, 20128, 20132, 20136, 20140, 20144, 20148, 20152,  | 
4003  |  |      20156, 20156, 20156, 20160, 20164, 20168, 20172, 20176, 20180, 20184,  | 
4004  |  |      20188, 20192, 20196, 20200, 20204, 20208, 20212, 20216, 20220, 20224,  | 
4005  |  |      20228, 20232, 20236, 20240, 20244, 20248, 20252, 20256, 20260, 20264,  | 
4006  |  |      20268, 20272, 20276, 20280, 20284, 20288, 20292, 20296, 20300, 20304,  | 
4007  |  |      20308, 20312, 20316, 20320, 20324, 20328, 20332, 20336, 20340, 20344,  | 
4008  |  |      20348, 20352, 20356, 20360, 20364, 20368, 20372, 20376, 20380, 20384,  | 
4009  |  |      20388, 20392, 20396, 20400, 20404, 20408, 20412, 20416, 20420, 20424,  | 
4010  |  |      20428, 20432, 20436, 20440, 20444, 20448, 20452, 20456, 20460, 20464,  | 
4011  |  |      20468, 20472, 20476, 20480, 20484, 20488, 20492, 20496, 20500, 20504,  | 
4012  |  |      20508, 20512, 20516, 20520, 20524, 20528, 20532, 20536, 20540, 20544,  | 
4013  |  |      20548, 20552, 20556, 20560, 20564, 20568, 20572, 20576, 20580, 20580,  | 
4014  |  |      20580, 20580, 20580, 20580, 20580, 20580, 20580, 20580, 20580, 20580,  | 
4015  |  |      20580, 20580, 20580, 20580, 20580, 20580, 20580, 20580, 20580, 20580,  | 
4016  |  |      20580, 20580, 20580, 20580, 20580, 20580, 20580, 20580, 20580, 20580,  | 
4017  |  |      20580, 20580, 20580, 20580, 20580, 20580, 20581},  | 
4018  |  |     {20581, 20589, 20597, 20605, 20617, 20629, 20637, 20644, 20644, 20644, | 
4019  |  |      20644, 20644, 20644, 20644, 20644, 20644, 20644, 20644, 20644, 20645,  | 
4020  |  |      20653, 20661, 20669, 20677, 20684, 20684, 20684, 20684, 20684, 20684,  | 
4021  |  |      20692, 20692, 20701, 20705, 20709, 20713, 20717, 20721, 20725, 20729,  | 
4022  |  |      20733, 20737, 20740, 20748, 20756, 20768, 20780, 20788, 20796, 20804,  | 
4023  |  |      20812, 20820, 20828, 20836, 20844, 20852, 20852, 20860, 20868, 20876,  | 
4024  |  |      20884, 20892, 20892, 20900, 20900, 20908, 20916, 20916, 20924, 20932,  | 
4025  |  |      20932, 20940, 20948, 20956, 20964, 20972, 20980, 20988, 20996, 21005,  | 
4026  |  |      21013, 21017, 21021, 21025, 21029, 21033, 21037, 21041, 21045, 21049,  | 
4027  |  |      21053, 21057, 21061, 21065, 21069, 21073, 21077, 21081, 21085, 21089,  | 
4028  |  |      21093, 21097, 21101, 21105, 21109, 21113, 21117, 21121, 21125, 21129,  | 
4029  |  |      21133, 21137, 21141, 21145, 21149, 21153, 21157, 21161, 21165, 21169,  | 
4030  |  |      21173, 21177, 21181, 21185, 21189, 21193, 21197, 21201, 21205, 21209,  | 
4031  |  |      21213, 21217, 21221, 21225, 21229, 21233, 21237, 21241, 21245, 21249,  | 
4032  |  |      21253, 21257, 21261, 21265, 21269, 21273, 21277, 21281, 21285, 21289,  | 
4033  |  |      21293, 21297, 21301, 21305, 21309, 21313, 21317, 21321, 21325, 21329,  | 
4034  |  |      21333, 21337, 21341, 21345, 21349, 21357, 21365, 21369, 21373, 21377,  | 
4035  |  |      21381, 21385, 21389, 21393, 21397, 21401, 21405, 21413, 21420, 21420,  | 
4036  |  |      21420, 21420, 21420, 21420, 21420, 21420, 21420, 21420, 21420, 21420,  | 
4037  |  |      21420, 21420, 21420, 21420, 21420, 21420, 21420, 21420, 21420, 21420,  | 
4038  |  |      21420, 21420, 21420, 21420, 21420, 21420, 21420, 21420, 21420, 21420,  | 
4039  |  |      21420, 21421, 21425, 21429, 21433, 21437, 21441, 21445, 21449, 21453,  | 
4040  |  |      21457, 21461, 21469, 21473, 21477, 21481, 21485, 21489, 21493, 21497,  | 
4041  |  |      21501, 21505, 21509, 21513, 21517, 21529, 21541, 21553, 21565, 21577,  | 
4042  |  |      21589, 21601, 21613, 21625, 21637, 21649, 21661, 21673, 21685, 21697,  | 
4043  |  |      21709, 21721, 21733, 21737, 21741, 21745, 21749},  | 
4044  |  |     {21749, 21761, 21773, 21785, 21797, 21809, 21817, 21825, 21833, 21841, | 
4045  |  |      21849, 21857, 21865, 21873, 21881, 21889, 21897, 21905, 21913, 21921,  | 
4046  |  |      21929, 21937, 21945, 21953, 21961, 21969, 21977, 21985, 21993, 22001,  | 
4047  |  |      22009, 22017, 22025, 22033, 22041, 22049, 22057, 22065, 22073, 22081,  | 
4048  |  |      22089, 22097, 22105, 22113, 22121, 22129, 22137, 22145, 22153, 22161,  | 
4049  |  |      22169, 22177, 22185, 22193, 22201, 22209, 22217, 22225, 22233, 22241,  | 
4050  |  |      22249, 22257, 22265, 22273, 22281, 22289, 22297, 22305, 22313, 22321,  | 
4051  |  |      22329, 22337, 22345, 22353, 22361, 22369, 22377, 22385, 22393, 22401,  | 
4052  |  |      22409, 22417, 22425, 22433, 22441, 22449, 22457, 22465, 22473, 22481,  | 
4053  |  |      22489, 22497, 22505, 22513, 22521, 22533, 22545, 22557, 22569, 22581,  | 
4054  |  |      22593, 22605, 22617, 22629, 22641, 22653, 22665, 22673, 22681, 22689,  | 
4055  |  |      22697, 22705, 22713, 22721, 22729, 22737, 22745, 22753, 22761, 22769,  | 
4056  |  |      22777, 22785, 22793, 22801, 22809, 22817, 22825, 22833, 22841, 22849,  | 
4057  |  |      22857, 22865, 22873, 22881, 22889, 22897, 22905, 22913, 22921, 22929,  | 
4058  |  |      22937, 22945, 22953, 22961, 22969, 22977, 22985, 22993, 23001, 23009,  | 
4059  |  |      23017, 23025, 23037, 23049, 23061, 23073, 23085, 23093, 23101, 23109,  | 
4060  |  |      23117, 23125, 23133, 23141, 23149, 23157, 23165, 23173, 23181, 23189,  | 
4061  |  |      23197, 23205, 23213, 23221, 23229, 23237, 23245, 23253, 23261, 23269,  | 
4062  |  |      23277, 23285, 23293, 23301, 23309, 23317, 23325, 23333, 23341, 23349,  | 
4063  |  |      23357, 23365, 23373, 23381, 23389, 23397, 23405, 23413, 23421, 23429,  | 
4064  |  |      23437, 23445, 23453, 23461, 23469, 23477, 23485, 23493, 23501, 23509,  | 
4065  |  |      23517, 23525, 23533, 23541, 23549, 23557, 23565, 23573, 23581, 23589,  | 
4066  |  |      23597, 23605, 23613, 23621, 23633, 23645, 23653, 23661, 23669, 23677,  | 
4067  |  |      23685, 23693, 23701, 23709, 23717, 23725, 23733, 23741, 23749, 23757,  | 
4068  |  |      23765, 23773, 23781, 23793, 23805, 23817, 23825, 23833, 23841, 23849,  | 
4069  |  |      23857, 23865, 23873, 23881, 23889, 23897, 23905},  | 
4070  |  |     {23905, 23913, 23921, 23929, 23937, 23945, 23953, 23961, 23969, 23977, | 
4071  |  |      23985, 23993, 24001, 24009, 24017, 24025, 24033, 24041, 24049, 24057,  | 
4072  |  |      24065, 24073, 24081, 24089, 24097, 24105, 24113, 24121, 24129, 24137,  | 
4073  |  |      24145, 24153, 24161, 24169, 24177, 24185, 24193, 24201, 24209, 24217,  | 
4074  |  |      24225, 24233, 24241, 24249, 24257, 24265, 24273, 24281, 24289, 24297,  | 
4075  |  |      24305, 24313, 24321, 24329, 24337, 24345, 24353, 24361, 24369, 24377,  | 
4076  |  |      24385, 24393, 24400, 24400, 24400, 24400, 24400, 24400, 24400, 24400,  | 
4077  |  |      24400, 24400, 24400, 24400, 24400, 24400, 24400, 24400, 24400, 24400,  | 
4078  |  |      24401, 24413, 24425, 24437, 24449, 24461, 24473, 24485, 24497, 24509,  | 
4079  |  |      24521, 24533, 24545, 24557, 24569, 24581, 24593, 24605, 24617, 24629,  | 
4080  |  |      24641, 24653, 24665, 24677, 24689, 24701, 24713, 24725, 24737, 24749,  | 
4081  |  |      24761, 24773, 24785, 24797, 24809, 24821, 24833, 24845, 24857, 24869,  | 
4082  |  |      24881, 24893, 24905, 24917, 24929, 24941, 24953, 24965, 24977, 24989,  | 
4083  |  |      25001, 25013, 25025, 25037, 25049, 25061, 25073, 25085, 25097, 25109,  | 
4084  |  |      25121, 25133, 25145, 25157, 25168, 25168, 25169, 25181, 25193, 25205,  | 
4085  |  |      25217, 25229, 25241, 25253, 25265, 25277, 25289, 25301, 25313, 25325,  | 
4086  |  |      25337, 25349, 25361, 25373, 25385, 25397, 25409, 25421, 25433, 25445,  | 
4087  |  |      25457, 25469, 25481, 25493, 25505, 25517, 25529, 25541, 25553, 25565,  | 
4088  |  |      25577, 25589, 25601, 25613, 25625, 25637, 25649, 25661, 25673, 25685,  | 
4089  |  |      25697, 25709, 25721, 25733, 25745, 25757, 25769, 25781, 25793, 25805,  | 
4090  |  |      25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816,  | 
4091  |  |      25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816,  | 
4092  |  |      25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816,  | 
4093  |  |      25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816,  | 
4094  |  |      25817, 25829, 25841, 25857, 25873, 25889, 25905, 25921, 25937, 25953,  | 
4095  |  |      25965, 26037, 26069, 26084, 26084, 26084, 26084},  | 
4096  |  |     {26084, 26084, 26084, 26084, 26084, 26084, 26084, 26084, 26084, 26084, | 
4097  |  |      26084, 26084, 26084, 26084, 26084, 26084, 26085, 26089, 26093, 26097,  | 
4098  |  |      26101, 26105, 26109, 26113, 26117, 26121, 26132, 26132, 26132, 26132,  | 
4099  |  |      26132, 26132, 26132, 26132, 26132, 26132, 26132, 26132, 26132, 26132,  | 
4100  |  |      26132, 26132, 26132, 26132, 26132, 26132, 26132, 26132, 26133, 26141,  | 
4101  |  |      26145, 26149, 26153, 26157, 26161, 26165, 26169, 26173, 26177, 26181,  | 
4102  |  |      26185, 26189, 26193, 26197, 26201, 26205, 26209, 26213, 26217, 26220,  | 
4103  |  |      26220, 26221, 26225, 26229, 26237, 26245, 26253, 26261, 26265, 26269,  | 
4104  |  |      26273, 26277, 26281, 26284, 26285, 26289, 26293, 26297, 26301, 26305,  | 
4105  |  |      26309, 26313, 26317, 26321, 26325, 26329, 26333, 26337, 26341, 26345,  | 
4106  |  |      26349, 26353, 26357, 26360, 26361, 26365, 26369, 26373, 26376, 26376,  | 
4107  |  |      26376, 26376, 26377, 26385, 26393, 26400, 26401, 26408, 26409, 26417,  | 
4108  |  |      26425, 26433, 26441, 26449, 26457, 26465, 26473, 26481, 26489, 26493,  | 
4109  |  |      26501, 26509, 26517, 26525, 26533, 26541, 26549, 26557, 26565, 26573,  | 
4110  |  |      26581, 26589, 26593, 26597, 26601, 26605, 26609, 26613, 26617, 26621,  | 
4111  |  |      26625, 26629, 26633, 26637, 26641, 26645, 26649, 26653, 26657, 26661,  | 
4112  |  |      26665, 26669, 26673, 26677, 26681, 26685, 26689, 26693, 26697, 26701,  | 
4113  |  |      26705, 26709, 26713, 26717, 26721, 26725, 26729, 26733, 26737, 26741,  | 
4114  |  |      26745, 26749, 26753, 26757, 26761, 26765, 26769, 26773, 26777, 26781,  | 
4115  |  |      26785, 26789, 26793, 26797, 26801, 26805, 26809, 26813, 26817, 26821,  | 
4116  |  |      26825, 26829, 26833, 26837, 26841, 26845, 26849, 26853, 26857, 26861,  | 
4117  |  |      26865, 26869, 26873, 26877, 26881, 26885, 26889, 26893, 26897, 26901,  | 
4118  |  |      26905, 26909, 26913, 26917, 26921, 26925, 26929, 26933, 26937, 26941,  | 
4119  |  |      26945, 26949, 26953, 26957, 26961, 26965, 26969, 26973, 26977, 26981,  | 
4120  |  |      26985, 26989, 26993, 26997, 27001, 27005, 27017, 27029, 27041, 27053,  | 
4121  |  |      27065, 27077, 27085, 27092, 27092, 27092, 27092},  | 
4122  |  |     {27092, 27093, 27097, 27101, 27105, 27109, 27113, 27117, 27121, 27125, | 
4123  |  |      27129, 27133, 27137, 27141, 27145, 27149, 27153, 27157, 27161, 27165,  | 
4124  |  |      27169, 27173, 27177, 27181, 27185, 27189, 27193, 27197, 27201, 27205,  | 
4125  |  |      27209, 27213, 27217, 27221, 27225, 27229, 27233, 27237, 27241, 27245,  | 
4126  |  |      27249, 27253, 27257, 27261, 27265, 27269, 27273, 27277, 27281, 27285,  | 
4127  |  |      27289, 27293, 27297, 27301, 27305, 27309, 27313, 27317, 27321, 27325,  | 
4128  |  |      27329, 27333, 27337, 27341, 27345, 27349, 27353, 27357, 27361, 27365,  | 
4129  |  |      27369, 27373, 27377, 27381, 27385, 27389, 27393, 27397, 27401, 27405,  | 
4130  |  |      27409, 27413, 27417, 27421, 27425, 27429, 27433, 27437, 27441, 27445,  | 
4131  |  |      27449, 27453, 27457, 27461, 27465, 27469, 27473, 27477, 27481, 27485,  | 
4132  |  |      27489, 27493, 27497, 27501, 27505, 27509, 27513, 27517, 27521, 27525,  | 
4133  |  |      27529, 27533, 27537, 27541, 27545, 27549, 27553, 27557, 27561, 27565,  | 
4134  |  |      27569, 27573, 27577, 27581, 27585, 27589, 27593, 27597, 27601, 27605,  | 
4135  |  |      27609, 27613, 27617, 27621, 27625, 27629, 27633, 27637, 27641, 27645,  | 
4136  |  |      27649, 27653, 27657, 27661, 27665, 27669, 27673, 27677, 27681, 27685,  | 
4137  |  |      27689, 27693, 27697, 27701, 27705, 27709, 27713, 27717, 27721, 27725,  | 
4138  |  |      27729, 27733, 27737, 27741, 27745, 27749, 27753, 27757, 27761, 27765,  | 
4139  |  |      27769, 27773, 27777, 27781, 27785, 27789, 27793, 27797, 27801, 27805,  | 
4140  |  |      27809, 27813, 27817, 27821, 27825, 27829, 27833, 27837, 27841, 27845,  | 
4141  |  |      27849, 27852, 27852, 27852, 27853, 27857, 27861, 27865, 27869, 27873,  | 
4142  |  |      27876, 27876, 27877, 27881, 27885, 27889, 27893, 27897, 27900, 27900,  | 
4143  |  |      27901, 27905, 27909, 27913, 27917, 27921, 27924, 27924, 27925, 27929,  | 
4144  |  |      27933, 27936, 27936, 27936, 27937, 27941, 27945, 27949, 27957, 27961,  | 
4145  |  |      27965, 27968, 27969, 27973, 27977, 27981, 27985, 27989, 27993, 27996,  | 
4146  |  |      27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996,  | 
4147  |  |      27996, 27996, 27996, 27996, 27996, 27996, 27996},  | 
4148  |  |     {27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, | 
4149  |  |      27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996,  | 
4150  |  |      27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996,  | 
4151  |  |      27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996,  | 
4152  |  |      27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996,  | 
4153  |  |      27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996,  | 
4154  |  |      27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996,  | 
4155  |  |      27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996,  | 
4156  |  |      27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996,  | 
4157  |  |      27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996,  | 
4158  |  |      27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996,  | 
4159  |  |      27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996,  | 
4160  |  |      27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27997,  | 
4161  |  |      28001, 28005, 28009, 28013, 28016, 28017, 28021, 28025, 28029, 28033,  | 
4162  |  |      28037, 28041, 28045, 28049, 28053, 28057, 28061, 28065, 28069, 28073,  | 
4163  |  |      28077, 28081, 28085, 28089, 28093, 28097, 28101, 28105, 28109, 28113,  | 
4164  |  |      28117, 28121, 28125, 28129, 28133, 28137, 28141, 28145, 28149, 28153,  | 
4165  |  |      28157, 28161, 28165, 28169, 28173, 28177, 28181, 28184, 28185, 28189,  | 
4166  |  |      28193, 28197, 28201, 28205, 28209, 28213, 28217, 28220, 28220, 28220,  | 
4167  |  |      28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,  | 
4168  |  |      28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,  | 
4169  |  |      28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,  | 
4170  |  |      28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,  | 
4171  |  |      28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,  | 
4172  |  |      28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,  | 
4173  |  |      28220, 28220, 28220, 28220, 28220, 28220, 28220},  | 
4174  |  |     {28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, | 
4175  |  |      28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,  | 
4176  |  |      28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,  | 
4177  |  |      28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,  | 
4178  |  |      28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,  | 
4179  |  |      28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,  | 
4180  |  |      28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,  | 
4181  |  |      28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,  | 
4182  |  |      28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,  | 
4183  |  |      28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,  | 
4184  |  |      28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,  | 
4185  |  |      28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,  | 
4186  |  |      28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,  | 
4187  |  |      28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,  | 
4188  |  |      28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,  | 
4189  |  |      28220, 28220, 28220, 28220, 28220, 28228, 28228, 28236, 28236, 28236,  | 
4190  |  |      28236, 28236, 28236, 28236, 28236, 28236, 28236, 28236, 28236, 28236,  | 
4191  |  |      28236, 28236, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244,  | 
4192  |  |      28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244,  | 
4193  |  |      28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244,  | 
4194  |  |      28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244,  | 
4195  |  |      28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244,  | 
4196  |  |      28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244,  | 
4197  |  |      28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244,  | 
4198  |  |      28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244,  | 
4199  |  |      28244, 28244, 28244, 28244, 28244, 28244, 28244},  | 
4200  |  |     {28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, | 
4201  |  |      28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244,  | 
4202  |  |      28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244,  | 
4203  |  |      28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244,  | 
4204  |  |      28244, 28244, 28244, 28244, 28244, 28244, 28244, 28252, 28260, 28260,  | 
4205  |  |      28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,  | 
4206  |  |      28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,  | 
4207  |  |      28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,  | 
4208  |  |      28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,  | 
4209  |  |      28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,  | 
4210  |  |      28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,  | 
4211  |  |      28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,  | 
4212  |  |      28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,  | 
4213  |  |      28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,  | 
4214  |  |      28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,  | 
4215  |  |      28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,  | 
4216  |  |      28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,  | 
4217  |  |      28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,  | 
4218  |  |      28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,  | 
4219  |  |      28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,  | 
4220  |  |      28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,  | 
4221  |  |      28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,  | 
4222  |  |      28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,  | 
4223  |  |      28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,  | 
4224  |  |      28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,  | 
4225  |  |      28260, 28260, 28260, 28260, 28260, 28260, 28260},  | 
4226  |  |     {28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, | 
4227  |  |      28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,  | 
4228  |  |      28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,  | 
4229  |  |      28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,  | 
4230  |  |      28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,  | 
4231  |  |      28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,  | 
4232  |  |      28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,  | 
4233  |  |      28260, 28260, 28260, 28260, 28260, 28260, 28268, 28276, 28276, 28276,  | 
4234  |  |      28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,  | 
4235  |  |      28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,  | 
4236  |  |      28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,  | 
4237  |  |      28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,  | 
4238  |  |      28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,  | 
4239  |  |      28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,  | 
4240  |  |      28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,  | 
4241  |  |      28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,  | 
4242  |  |      28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,  | 
4243  |  |      28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,  | 
4244  |  |      28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,  | 
4245  |  |      28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,  | 
4246  |  |      28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,  | 
4247  |  |      28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,  | 
4248  |  |      28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,  | 
4249  |  |      28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,  | 
4250  |  |      28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,  | 
4251  |  |      28276, 28276, 28276, 28276, 28276, 28276, 28276},  | 
4252  |  |     {28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, | 
4253  |  |      28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,  | 
4254  |  |      28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,  | 
4255  |  |      28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,  | 
4256  |  |      28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,  | 
4257  |  |      28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,  | 
4258  |  |      28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,  | 
4259  |  |      28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,  | 
4260  |  |      28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,  | 
4261  |  |      28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,  | 
4262  |  |      28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,  | 
4263  |  |      28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,  | 
4264  |  |      28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,  | 
4265  |  |      28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,  | 
4266  |  |      28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,  | 
4267  |  |      28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,  | 
4268  |  |      28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,  | 
4269  |  |      28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,  | 
4270  |  |      28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28284, 28292,  | 
4271  |  |      28292, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,  | 
4272  |  |      28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,  | 
4273  |  |      28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,  | 
4274  |  |      28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,  | 
4275  |  |      28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,  | 
4276  |  |      28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,  | 
4277  |  |      28300, 28300, 28300, 28300, 28300, 28300, 28300},  | 
4278  |  |     {28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, | 
4279  |  |      28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,  | 
4280  |  |      28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,  | 
4281  |  |      28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,  | 
4282  |  |      28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,  | 
4283  |  |      28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,  | 
4284  |  |      28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,  | 
4285  |  |      28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,  | 
4286  |  |      28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,  | 
4287  |  |      28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,  | 
4288  |  |      28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,  | 
4289  |  |      28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,  | 
4290  |  |      28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,  | 
4291  |  |      28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,  | 
4292  |  |      28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,  | 
4293  |  |      28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,  | 
4294  |  |      28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,  | 
4295  |  |      28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,  | 
4296  |  |      28300, 28300, 28300, 28300, 28300, 28300, 28300, 28308, 28316, 28316,  | 
4297  |  |      28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316,  | 
4298  |  |      28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316,  | 
4299  |  |      28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316,  | 
4300  |  |      28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316,  | 
4301  |  |      28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316,  | 
4302  |  |      28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316,  | 
4303  |  |      28316, 28316, 28316, 28316, 28316, 28316, 28316},  | 
4304  |  |     {28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, | 
4305  |  |      28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316,  | 
4306  |  |      28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316,  | 
4307  |  |      28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316,  | 
4308  |  |      28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316,  | 
4309  |  |      28316, 28316, 28316, 28316, 28316, 28316, 28316, 28324, 28324, 28324,  | 
4310  |  |      28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,  | 
4311  |  |      28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,  | 
4312  |  |      28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,  | 
4313  |  |      28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,  | 
4314  |  |      28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,  | 
4315  |  |      28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,  | 
4316  |  |      28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,  | 
4317  |  |      28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,  | 
4318  |  |      28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,  | 
4319  |  |      28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,  | 
4320  |  |      28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,  | 
4321  |  |      28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,  | 
4322  |  |      28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,  | 
4323  |  |      28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,  | 
4324  |  |      28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,  | 
4325  |  |      28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,  | 
4326  |  |      28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,  | 
4327  |  |      28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,  | 
4328  |  |      28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,  | 
4329  |  |      28324, 28324, 28324, 28324, 28324, 28324, 28324},  | 
4330  |  |     {28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, | 
4331  |  |      28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,  | 
4332  |  |      28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,  | 
4333  |  |      28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,  | 
4334  |  |      28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,  | 
4335  |  |      28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,  | 
4336  |  |      28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,  | 
4337  |  |      28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,  | 
4338  |  |      28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,  | 
4339  |  |      28324, 28324, 28324, 28324, 28324, 28332, 28340, 28352, 28364, 28376,  | 
4340  |  |      28388, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400,  | 
4341  |  |      28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400,  | 
4342  |  |      28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400,  | 
4343  |  |      28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400,  | 
4344  |  |      28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400,  | 
4345  |  |      28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400,  | 
4346  |  |      28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400,  | 
4347  |  |      28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400,  | 
4348  |  |      28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28408, 28416,  | 
4349  |  |      28428, 28440, 28452, 28464, 28464, 28464, 28464, 28464, 28464, 28464,  | 
4350  |  |      28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,  | 
4351  |  |      28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,  | 
4352  |  |      28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,  | 
4353  |  |      28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,  | 
4354  |  |      28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,  | 
4355  |  |      28464, 28464, 28464, 28464, 28464, 28464, 28464},  | 
4356  |  |     {28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, | 
4357  |  |      28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,  | 
4358  |  |      28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,  | 
4359  |  |      28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,  | 
4360  |  |      28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,  | 
4361  |  |      28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,  | 
4362  |  |      28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,  | 
4363  |  |      28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,  | 
4364  |  |      28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,  | 
4365  |  |      28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,  | 
4366  |  |      28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,  | 
4367  |  |      28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,  | 
4368  |  |      28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,  | 
4369  |  |      28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,  | 
4370  |  |      28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,  | 
4371  |  |      28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,  | 
4372  |  |      28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,  | 
4373  |  |      28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,  | 
4374  |  |      28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,  | 
4375  |  |      28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,  | 
4376  |  |      28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,  | 
4377  |  |      28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,  | 
4378  |  |      28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,  | 
4379  |  |      28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,  | 
4380  |  |      28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,  | 
4381  |  |      28464, 28464, 28464, 28464, 28464, 28464, 28465},  | 
4382  |  |     {28465, 28469, 28473, 28477, 28481, 28485, 28489, 28493, 28497, 28501, | 
4383  |  |      28505, 28509, 28513, 28517, 28521, 28525, 28529, 28533, 28537, 28541,  | 
4384  |  |      28545, 28549, 28553, 28557, 28561, 28565, 28569, 28573, 28577, 28581,  | 
4385  |  |      28585, 28589, 28593, 28597, 28601, 28605, 28609, 28613, 28617, 28621,  | 
4386  |  |      28625, 28629, 28633, 28637, 28641, 28645, 28649, 28653, 28657, 28661,  | 
4387  |  |      28665, 28669, 28673, 28677, 28681, 28685, 28689, 28693, 28697, 28701,  | 
4388  |  |      28705, 28709, 28713, 28717, 28721, 28725, 28729, 28733, 28737, 28741,  | 
4389  |  |      28745, 28749, 28753, 28757, 28761, 28765, 28769, 28773, 28777, 28781,  | 
4390  |  |      28785, 28789, 28793, 28797, 28801, 28804, 28805, 28809, 28813, 28817,  | 
4391  |  |      28821, 28825, 28829, 28833, 28837, 28841, 28845, 28849, 28853, 28857,  | 
4392  |  |      28861, 28865, 28869, 28873, 28877, 28881, 28885, 28889, 28893, 28897,  | 
4393  |  |      28901, 28905, 28909, 28913, 28917, 28921, 28925, 28929, 28933, 28937,  | 
4394  |  |      28941, 28945, 28949, 28953, 28957, 28961, 28965, 28969, 28973, 28977,  | 
4395  |  |      28981, 28985, 28989, 28993, 28997, 29001, 29005, 29009, 29013, 29017,  | 
4396  |  |      29021, 29025, 29029, 29033, 29037, 29041, 29045, 29049, 29053, 29057,  | 
4397  |  |      29061, 29065, 29069, 29073, 29077, 29081, 29085, 29088, 29089, 29093,  | 
4398  |  |      29096, 29096, 29097, 29100, 29100, 29101, 29105, 29108, 29108, 29109,  | 
4399  |  |      29113, 29117, 29121, 29124, 29125, 29129, 29133, 29137, 29141, 29145,  | 
4400  |  |      29149, 29153, 29157, 29161, 29165, 29169, 29172, 29173, 29176, 29177,  | 
4401  |  |      29181, 29185, 29189, 29193, 29197, 29201, 29204, 29205, 29209, 29213,  | 
4402  |  |      29217, 29221, 29225, 29229, 29233, 29237, 29241, 29245, 29249, 29253,  | 
4403  |  |      29257, 29261, 29265, 29269, 29273, 29277, 29281, 29285, 29289, 29293,  | 
4404  |  |      29297, 29301, 29305, 29309, 29313, 29317, 29321, 29325, 29329, 29333,  | 
4405  |  |      29337, 29341, 29345, 29349, 29353, 29357, 29361, 29365, 29369, 29373,  | 
4406  |  |      29377, 29381, 29385, 29389, 29393, 29397, 29401, 29405, 29409, 29413,  | 
4407  |  |      29417, 29421, 29425, 29429, 29433, 29437, 29441},  | 
4408  |  |     {29441, 29445, 29449, 29453, 29457, 29461, 29464, 29465, 29469, 29473, | 
4409  |  |      29477, 29480, 29480, 29481, 29485, 29489, 29493, 29497, 29501, 29505,  | 
4410  |  |      29509, 29512, 29513, 29517, 29521, 29525, 29529, 29533, 29537, 29540,  | 
4411  |  |      29541, 29545, 29549, 29553, 29557, 29561, 29565, 29569, 29573, 29577,  | 
4412  |  |      29581, 29585, 29589, 29593, 29597, 29601, 29605, 29609, 29613, 29617,  | 
4413  |  |      29621, 29625, 29629, 29633, 29637, 29641, 29645, 29649, 29652, 29653,  | 
4414  |  |      29657, 29661, 29665, 29668, 29669, 29673, 29677, 29681, 29685, 29688,  | 
4415  |  |      29689, 29692, 29692, 29692, 29693, 29697, 29701, 29705, 29709, 29713,  | 
4416  |  |      29717, 29720, 29721, 29725, 29729, 29733, 29737, 29741, 29745, 29749,  | 
4417  |  |      29753, 29757, 29761, 29765, 29769, 29773, 29777, 29781, 29785, 29789,  | 
4418  |  |      29793, 29797, 29801, 29805, 29809, 29813, 29817, 29821, 29825, 29829,  | 
4419  |  |      29833, 29837, 29841, 29845, 29849, 29853, 29857, 29861, 29865, 29869,  | 
4420  |  |      29873, 29877, 29881, 29885, 29889, 29893, 29897, 29901, 29905, 29909,  | 
4421  |  |      29913, 29917, 29921, 29925, 29929, 29933, 29937, 29941, 29945, 29949,  | 
4422  |  |      29953, 29957, 29961, 29965, 29969, 29973, 29977, 29981, 29985, 29989,  | 
4423  |  |      29993, 29997, 30001, 30005, 30009, 30013, 30017, 30021, 30025, 30029,  | 
4424  |  |      30033, 30037, 30041, 30045, 30049, 30053, 30057, 30061, 30065, 30069,  | 
4425  |  |      30073, 30077, 30081, 30085, 30089, 30093, 30097, 30101, 30105, 30109,  | 
4426  |  |      30113, 30117, 30121, 30125, 30129, 30133, 30137, 30141, 30145, 30149,  | 
4427  |  |      30153, 30157, 30161, 30165, 30169, 30173, 30177, 30181, 30185, 30189,  | 
4428  |  |      30193, 30197, 30201, 30205, 30209, 30213, 30217, 30221, 30225, 30229,  | 
4429  |  |      30233, 30237, 30241, 30245, 30249, 30253, 30257, 30261, 30265, 30269,  | 
4430  |  |      30273, 30277, 30281, 30285, 30289, 30293, 30297, 30301, 30305, 30309,  | 
4431  |  |      30313, 30317, 30321, 30325, 30329, 30333, 30337, 30341, 30345, 30349,  | 
4432  |  |      30353, 30357, 30361, 30365, 30369, 30373, 30377, 30381, 30385, 30389,  | 
4433  |  |      30393, 30397, 30401, 30405, 30409, 30413, 30417},  | 
4434  |  |     {30417, 30421, 30425, 30429, 30433, 30437, 30441, 30445, 30449, 30453, | 
4435  |  |      30457, 30461, 30465, 30469, 30473, 30477, 30481, 30485, 30489, 30493,  | 
4436  |  |      30497, 30501, 30505, 30509, 30513, 30517, 30521, 30525, 30529, 30533,  | 
4437  |  |      30537, 30541, 30545, 30549, 30553, 30557, 30561, 30565, 30569, 30573,  | 
4438  |  |      30577, 30581, 30585, 30589, 30593, 30597, 30601, 30605, 30609, 30613,  | 
4439  |  |      30617, 30621, 30625, 30629, 30633, 30637, 30641, 30645, 30649, 30653,  | 
4440  |  |      30657, 30661, 30665, 30669, 30673, 30677, 30681, 30685, 30689, 30693,  | 
4441  |  |      30697, 30701, 30705, 30709, 30713, 30717, 30721, 30725, 30729, 30733,  | 
4442  |  |      30737, 30741, 30745, 30749, 30753, 30757, 30761, 30765, 30769, 30773,  | 
4443  |  |      30777, 30781, 30785, 30789, 30793, 30797, 30801, 30805, 30809, 30813,  | 
4444  |  |      30817, 30821, 30825, 30829, 30833, 30837, 30841, 30845, 30849, 30853,  | 
4445  |  |      30857, 30861, 30865, 30869, 30873, 30877, 30881, 30885, 30889, 30893,  | 
4446  |  |      30897, 30901, 30905, 30909, 30913, 30917, 30921, 30925, 30929, 30933,  | 
4447  |  |      30937, 30941, 30945, 30949, 30953, 30957, 30961, 30965, 30969, 30973,  | 
4448  |  |      30977, 30981, 30985, 30989, 30993, 30997, 31001, 31005, 31009, 31013,  | 
4449  |  |      31017, 31021, 31025, 31029, 31033, 31037, 31041, 31045, 31049, 31053,  | 
4450  |  |      31057, 31061, 31065, 31069, 31073, 31077, 31080, 31080, 31081, 31085,  | 
4451  |  |      31089, 31093, 31097, 31101, 31105, 31109, 31113, 31117, 31121, 31125,  | 
4452  |  |      31129, 31133, 31137, 31141, 31145, 31149, 31153, 31157, 31161, 31165,  | 
4453  |  |      31169, 31173, 31177, 31181, 31185, 31189, 31193, 31197, 31201, 31205,  | 
4454  |  |      31209, 31213, 31217, 31221, 31225, 31229, 31233, 31237, 31241, 31245,  | 
4455  |  |      31249, 31253, 31257, 31261, 31265, 31269, 31273, 31277, 31281, 31285,  | 
4456  |  |      31289, 31293, 31297, 31301, 31305, 31309, 31313, 31317, 31321, 31325,  | 
4457  |  |      31329, 31333, 31337, 31341, 31345, 31349, 31353, 31357, 31361, 31365,  | 
4458  |  |      31369, 31373, 31377, 31381, 31385, 31389, 31393, 31397, 31401, 31405,  | 
4459  |  |      31409, 31413, 31417, 31421, 31425, 31429, 31433},  | 
4460  |  |     {31433, 31437, 31441, 31445, 31449, 31453, 31457, 31461, 31465, 31469, | 
4461  |  |      31473, 31477, 31481, 31485, 31489, 31493, 31497, 31501, 31505, 31509,  | 
4462  |  |      31513, 31517, 31521, 31525, 31529, 31533, 31537, 31541, 31545, 31549,  | 
4463  |  |      31553, 31557, 31561, 31565, 31569, 31573, 31577, 31581, 31585, 31589,  | 
4464  |  |      31593, 31597, 31601, 31605, 31609, 31613, 31617, 31621, 31625, 31629,  | 
4465  |  |      31633, 31637, 31641, 31645, 31649, 31653, 31657, 31661, 31665, 31669,  | 
4466  |  |      31673, 31677, 31681, 31685, 31689, 31693, 31697, 31701, 31705, 31709,  | 
4467  |  |      31713, 31717, 31721, 31725, 31729, 31733, 31737, 31741, 31745, 31749,  | 
4468  |  |      31753, 31757, 31761, 31765, 31769, 31773, 31777, 31781, 31785, 31789,  | 
4469  |  |      31793, 31797, 31801, 31805, 31809, 31813, 31817, 31821, 31825, 31829,  | 
4470  |  |      31833, 31837, 31841, 31845, 31849, 31853, 31857, 31861, 31865, 31869,  | 
4471  |  |      31873, 31877, 31881, 31885, 31889, 31893, 31897, 31901, 31905, 31909,  | 
4472  |  |      31913, 31917, 31921, 31925, 31929, 31933, 31937, 31941, 31945, 31949,  | 
4473  |  |      31953, 31957, 31961, 31965, 31969, 31973, 31977, 31981, 31985, 31989,  | 
4474  |  |      31993, 31997, 32001, 32005, 32009, 32013, 32017, 32021, 32025, 32029,  | 
4475  |  |      32033, 32037, 32041, 32045, 32049, 32053, 32057, 32061, 32065, 32069,  | 
4476  |  |      32073, 32077, 32081, 32085, 32089, 32093, 32097, 32101, 32105, 32109,  | 
4477  |  |      32113, 32117, 32121, 32125, 32129, 32133, 32137, 32141, 32145, 32149,  | 
4478  |  |      32153, 32157, 32161, 32165, 32169, 32173, 32177, 32181, 32185, 32189,  | 
4479  |  |      32193, 32197, 32201, 32205, 32209, 32213, 32217, 32221, 32225, 32229,  | 
4480  |  |      32233, 32237, 32241, 32245, 32248, 32248, 32249, 32253, 32257, 32261,  | 
4481  |  |      32265, 32269, 32273, 32277, 32281, 32285, 32289, 32293, 32297, 32301,  | 
4482  |  |      32305, 32309, 32313, 32317, 32321, 32325, 32329, 32333, 32337, 32341,  | 
4483  |  |      32345, 32349, 32353, 32357, 32361, 32365, 32369, 32373, 32377, 32381,  | 
4484  |  |      32385, 32389, 32393, 32397, 32401, 32405, 32409, 32413, 32417, 32421,  | 
4485  |  |      32425, 32429, 32433, 32437, 32441, 32445, 32448},  | 
4486  |  |     {32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448, | 
4487  |  |      32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448,  | 
4488  |  |      32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448,  | 
4489  |  |      32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448,  | 
4490  |  |      32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448, 32449, 32453,  | 
4491  |  |      32457, 32461, 32465, 32469, 32473, 32477, 32481, 32485, 32489, 32493,  | 
4492  |  |      32497, 32501, 32505, 32509, 32513, 32517, 32521, 32525, 32529, 32533,  | 
4493  |  |      32537, 32541, 32545, 32549, 32553, 32557, 32561, 32565, 32569, 32573,  | 
4494  |  |      32577, 32581, 32585, 32589, 32593, 32597, 32601, 32605, 32609, 32613,  | 
4495  |  |      32617, 32621, 32625, 32629, 32633, 32637, 32641, 32645, 32649, 32653,  | 
4496  |  |      32657, 32661, 32665, 32669, 32673, 32677, 32681, 32685, 32689, 32693,  | 
4497  |  |      32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,  | 
4498  |  |      32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,  | 
4499  |  |      32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,  | 
4500  |  |      32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,  | 
4501  |  |      32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,  | 
4502  |  |      32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,  | 
4503  |  |      32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,  | 
4504  |  |      32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,  | 
4505  |  |      32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,  | 
4506  |  |      32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,  | 
4507  |  |      32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,  | 
4508  |  |      32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,  | 
4509  |  |      32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,  | 
4510  |  |      32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,  | 
4511  |  |      32696, 32696, 32696, 32696, 32696, 32696, 32696},  | 
4512  |  |     {32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, | 
4513  |  |      32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,  | 
4514  |  |      32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,  | 
4515  |  |      32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,  | 
4516  |  |      32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,  | 
4517  |  |      32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,  | 
4518  |  |      32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,  | 
4519  |  |      32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,  | 
4520  |  |      32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,  | 
4521  |  |      32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,  | 
4522  |  |      32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,  | 
4523  |  |      32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,  | 
4524  |  |      32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,  | 
4525  |  |      32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,  | 
4526  |  |      32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,  | 
4527  |  |      32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,  | 
4528  |  |      32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,  | 
4529  |  |      32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,  | 
4530  |  |      32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,  | 
4531  |  |      32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,  | 
4532  |  |      32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,  | 
4533  |  |      32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,  | 
4534  |  |      32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,  | 
4535  |  |      32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,  | 
4536  |  |      32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,  | 
4537  |  |      32696, 32696, 32696, 32696, 32696, 32696, 32697},  | 
4538  |  |     {32697, 32701, 32705, 32709, 32712, 32713, 32717, 32721, 32725, 32729, | 
4539  |  |      32733, 32737, 32741, 32745, 32749, 32753, 32757, 32761, 32765, 32769,  | 
4540  |  |      32773, 32777, 32781, 32785, 32789, 32793, 32797, 32801, 32805, 32809,  | 
4541  |  |      32813, 32817, 32820, 32821, 32825, 32828, 32829, 32832, 32832, 32833,  | 
4542  |  |      32836, 32837, 32841, 32845, 32849, 32853, 32857, 32861, 32865, 32869,  | 
4543  |  |      32873, 32876, 32877, 32881, 32885, 32889, 32892, 32893, 32896, 32897,  | 
4544  |  |      32900, 32900, 32900, 32900, 32900, 32900, 32901, 32904, 32904, 32904,  | 
4545  |  |      32904, 32905, 32908, 32909, 32912, 32913, 32916, 32917, 32921, 32925,  | 
4546  |  |      32928, 32929, 32933, 32936, 32937, 32940, 32940, 32941, 32944, 32945,  | 
4547  |  |      32948, 32949, 32952, 32953, 32956, 32957, 32960, 32961, 32965, 32968,  | 
4548  |  |      32969, 32972, 32972, 32973, 32977, 32981, 32985, 32988, 32989, 32993,  | 
4549  |  |      32997, 33001, 33005, 33009, 33013, 33016, 33017, 33021, 33025, 33029,  | 
4550  |  |      33032, 33033, 33037, 33041, 33045, 33048, 33049, 33052, 33053, 33057,  | 
4551  |  |      33061, 33065, 33069, 33073, 33077, 33081, 33085, 33089, 33092, 33093,  | 
4552  |  |      33097, 33101, 33105, 33109, 33113, 33117, 33121, 33125, 33129, 33133,  | 
4553  |  |      33137, 33141, 33145, 33149, 33153, 33157, 33160, 33160, 33160, 33160,  | 
4554  |  |      33160, 33161, 33165, 33169, 33172, 33173, 33177, 33181, 33185, 33189,  | 
4555  |  |      33192, 33193, 33197, 33201, 33205, 33209, 33213, 33217, 33221, 33225,  | 
4556  |  |      33229, 33233, 33237, 33241, 33245, 33249, 33253, 33257, 33260, 33260,  | 
4557  |  |      33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,  | 
4558  |  |      33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,  | 
4559  |  |      33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,  | 
4560  |  |      33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,  | 
4561  |  |      33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,  | 
4562  |  |      33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,  | 
4563  |  |      33260, 33260, 33260, 33260, 33260, 33260, 33260},  | 
4564  |  |     {33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, | 
4565  |  |      33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,  | 
4566  |  |      33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,  | 
4567  |  |      33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,  | 
4568  |  |      33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,  | 
4569  |  |      33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,  | 
4570  |  |      33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,  | 
4571  |  |      33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,  | 
4572  |  |      33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,  | 
4573  |  |      33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,  | 
4574  |  |      33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,  | 
4575  |  |      33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,  | 
4576  |  |      33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,  | 
4577  |  |      33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,  | 
4578  |  |      33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,  | 
4579  |  |      33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,  | 
4580  |  |      33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,  | 
4581  |  |      33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,  | 
4582  |  |      33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,  | 
4583  |  |      33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,  | 
4584  |  |      33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,  | 
4585  |  |      33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,  | 
4586  |  |      33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,  | 
4587  |  |      33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,  | 
4588  |  |      33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,  | 
4589  |  |      33260, 33260, 33260, 33260, 33260, 33260, 33261},  | 
4590  |  |     {33261, 33269, 33277, 33285, 33293, 33301, 33309, 33317, 33325, 33333, | 
4591  |  |      33341, 33348, 33348, 33348, 33348, 33348, 33349, 33361, 33373, 33385,  | 
4592  |  |      33397, 33409, 33421, 33433, 33445, 33457, 33469, 33481, 33493, 33505,  | 
4593  |  |      33517, 33529, 33541, 33553, 33565, 33577, 33589, 33601, 33613, 33625,  | 
4594  |  |      33637, 33649, 33661, 33673, 33677, 33681, 33689, 33696, 33697, 33701,  | 
4595  |  |      33705, 33709, 33713, 33717, 33721, 33725, 33729, 33733, 33737, 33741,  | 
4596  |  |      33745, 33749, 33753, 33757, 33761, 33765, 33769, 33773, 33777, 33781,  | 
4597  |  |      33785, 33789, 33793, 33797, 33801, 33809, 33817, 33825, 33833, 33845,  | 
4598  |  |      33852, 33852, 33852, 33852, 33852, 33852, 33852, 33852, 33852, 33852,  | 
4599  |  |      33852, 33852, 33852, 33852, 33852, 33852, 33852, 33852, 33852, 33852,  | 
4600  |  |      33852, 33852, 33852, 33852, 33852, 33852, 33853, 33861, 33869, 33876,  | 
4601  |  |      33876, 33876, 33876, 33876, 33876, 33876, 33876, 33876, 33876, 33876,  | 
4602  |  |      33876, 33876, 33876, 33876, 33876, 33876, 33876, 33876, 33876, 33876,  | 
4603  |  |      33876, 33876, 33876, 33876, 33876, 33876, 33876, 33876, 33876, 33876,  | 
4604  |  |      33876, 33876, 33876, 33876, 33877, 33884, 33884, 33884, 33884, 33884,  | 
4605  |  |      33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884,  | 
4606  |  |      33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884,  | 
4607  |  |      33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884,  | 
4608  |  |      33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884,  | 
4609  |  |      33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884,  | 
4610  |  |      33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884,  | 
4611  |  |      33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884,  | 
4612  |  |      33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884,  | 
4613  |  |      33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884,  | 
4614  |  |      33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884,  | 
4615  |  |      33884, 33884, 33884, 33884, 33884, 33884, 33885},  | 
4616  |  |     {33885, 33893, 33901, 33904, 33904, 33904, 33904, 33904, 33904, 33904, | 
4617  |  |      33904, 33904, 33904, 33904, 33904, 33904, 33905, 33909, 33913, 33917,  | 
4618  |  |      33925, 33929, 33933, 33937, 33941, 33945, 33949, 33953, 33957, 33961,  | 
4619  |  |      33965, 33969, 33973, 33977, 33981, 33985, 33989, 33993, 33997, 34001,  | 
4620  |  |      34005, 34009, 34013, 34017, 34021, 34025, 34029, 34033, 34037, 34041,  | 
4621  |  |      34045, 34049, 34053, 34057, 34061, 34065, 34069, 34073, 34077, 34081,  | 
4622  |  |      34084, 34084, 34084, 34084, 34085, 34097, 34109, 34121, 34133, 34145,  | 
4623  |  |      34157, 34169, 34181, 34192, 34192, 34192, 34192, 34192, 34192, 34192,  | 
4624  |  |      34193, 34197, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,  | 
4625  |  |      34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,  | 
4626  |  |      34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,  | 
4627  |  |      34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,  | 
4628  |  |      34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,  | 
4629  |  |      34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,  | 
4630  |  |      34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,  | 
4631  |  |      34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,  | 
4632  |  |      34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,  | 
4633  |  |      34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,  | 
4634  |  |      34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,  | 
4635  |  |      34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,  | 
4636  |  |      34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,  | 
4637  |  |      34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,  | 
4638  |  |      34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,  | 
4639  |  |      34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,  | 
4640  |  |      34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,  | 
4641  |  |      34200, 34200, 34200, 34200, 34200, 34200, 34200},  | 
4642  |  |     {34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, | 
4643  |  |      34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,  | 
4644  |  |      34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,  | 
4645  |  |      34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,  | 
4646  |  |      34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,  | 
4647  |  |      34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,  | 
4648  |  |      34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,  | 
4649  |  |      34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,  | 
4650  |  |      34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,  | 
4651  |  |      34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,  | 
4652  |  |      34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,  | 
4653  |  |      34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,  | 
4654  |  |      34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,  | 
4655  |  |      34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,  | 
4656  |  |      34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,  | 
4657  |  |      34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,  | 
4658  |  |      34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,  | 
4659  |  |      34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,  | 
4660  |  |      34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,  | 
4661  |  |      34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,  | 
4662  |  |      34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,  | 
4663  |  |      34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,  | 
4664  |  |      34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,  | 
4665  |  |      34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,  | 
4666  |  |      34201, 34205, 34209, 34213, 34217, 34221, 34225, 34229, 34233, 34237,  | 
4667  |  |      34240, 34240, 34240, 34240, 34240, 34240, 34240},  | 
4668  |  |     {34240, 34244, 34248, 34252, 34256, 34260, 34264, 34268, 34272, 34276, | 
4669  |  |      34280, 34284, 34288, 34292, 34296, 34300, 34304, 34308, 34312, 34316,  | 
4670  |  |      34320, 34324, 34328, 34332, 34336, 34340, 34344, 34348, 34352, 34356,  | 
4671  |  |      34360, 34364, 34368, 34372, 34376, 34380, 34384, 34388, 34392, 34396,  | 
4672  |  |      34400, 34404, 34408, 34412, 34416, 34420, 34424, 34428, 34432, 34436,  | 
4673  |  |      34440, 34444, 34448, 34452, 34456, 34460, 34464, 34468, 34472, 34476,  | 
4674  |  |      34480, 34484, 34488, 34492, 34496, 34500, 34504, 34508, 34512, 34516,  | 
4675  |  |      34520, 34524, 34528, 34532, 34536, 34540, 34544, 34548, 34552, 34556,  | 
4676  |  |      34560, 34564, 34568, 34572, 34576, 34580, 34584, 34588, 34592, 34596,  | 
4677  |  |      34600, 34604, 34608, 34612, 34616, 34620, 34624, 34628, 34632, 34636,  | 
4678  |  |      34640, 34644, 34648, 34652, 34656, 34660, 34664, 34668, 34672, 34676,  | 
4679  |  |      34680, 34684, 34688, 34692, 34696, 34700, 34704, 34708, 34712, 34716,  | 
4680  |  |      34720, 34724, 34728, 34732, 34736, 34740, 34744, 34748, 34752, 34756,  | 
4681  |  |      34760, 34764, 34768, 34772, 34776, 34780, 34784, 34788, 34792, 34796,  | 
4682  |  |      34800, 34804, 34808, 34812, 34816, 34820, 34824, 34828, 34832, 34836,  | 
4683  |  |      34840, 34844, 34848, 34852, 34856, 34860, 34864, 34868, 34872, 34876,  | 
4684  |  |      34880, 34884, 34888, 34892, 34896, 34900, 34904, 34908, 34912, 34916,  | 
4685  |  |      34920, 34924, 34928, 34932, 34936, 34940, 34944, 34948, 34952, 34956,  | 
4686  |  |      34960, 34964, 34968, 34972, 34976, 34980, 34984, 34988, 34992, 34996,  | 
4687  |  |      35000, 35004, 35008, 35012, 35016, 35020, 35024, 35028, 35032, 35036,  | 
4688  |  |      35040, 35044, 35048, 35052, 35056, 35060, 35064, 35068, 35072, 35076,  | 
4689  |  |      35080, 35084, 35088, 35092, 35096, 35100, 35104, 35108, 35112, 35116,  | 
4690  |  |      35120, 35124, 35128, 35132, 35136, 35140, 35144, 35148, 35152, 35156,  | 
4691  |  |      35160, 35164, 35168, 35172, 35176, 35180, 35184, 35188, 35192, 35196,  | 
4692  |  |      35200, 35204, 35208, 35212, 35216, 35220, 35224, 35228, 35232, 35236,  | 
4693  |  |      35240, 35244, 35248, 35252, 35256, 35260, 35264},  | 
4694  |  |     {35264, 35268, 35272, 35276, 35280, 35284, 35288, 35292, 35296, 35300, | 
4695  |  |      35304, 35308, 35312, 35316, 35320, 35324, 35328, 35332, 35336, 35340,  | 
4696  |  |      35344, 35348, 35352, 35356, 35360, 35364, 35368, 35372, 35376, 35380,  | 
4697  |  |      35384, 35388, 35392, 35396, 35400, 35404, 35408, 35412, 35416, 35420,  | 
4698  |  |      35424, 35428, 35432, 35436, 35440, 35444, 35448, 35452, 35456, 35460,  | 
4699  |  |      35464, 35468, 35472, 35476, 35480, 35484, 35488, 35492, 35496, 35500,  | 
4700  |  |      35504, 35508, 35512, 35516, 35520, 35524, 35528, 35532, 35536, 35540,  | 
4701  |  |      35544, 35548, 35552, 35556, 35560, 35564, 35568, 35572, 35576, 35580,  | 
4702  |  |      35584, 35588, 35592, 35596, 35600, 35604, 35608, 35612, 35616, 35620,  | 
4703  |  |      35624, 35628, 35632, 35636, 35640, 35644, 35648, 35652, 35656, 35660,  | 
4704  |  |      35664, 35668, 35672, 35676, 35680, 35684, 35688, 35692, 35696, 35700,  | 
4705  |  |      35704, 35708, 35712, 35716, 35720, 35724, 35728, 35732, 35736, 35740,  | 
4706  |  |      35744, 35748, 35752, 35756, 35760, 35764, 35768, 35772, 35776, 35780,  | 
4707  |  |      35784, 35788, 35792, 35796, 35800, 35804, 35808, 35812, 35816, 35820,  | 
4708  |  |      35824, 35828, 35832, 35836, 35840, 35844, 35848, 35852, 35856, 35860,  | 
4709  |  |      35864, 35868, 35872, 35876, 35880, 35884, 35888, 35892, 35896, 35900,  | 
4710  |  |      35904, 35908, 35912, 35916, 35920, 35924, 35928, 35932, 35936, 35940,  | 
4711  |  |      35944, 35948, 35952, 35956, 35960, 35964, 35968, 35972, 35976, 35980,  | 
4712  |  |      35984, 35988, 35992, 35996, 36000, 36004, 36008, 36012, 36016, 36020,  | 
4713  |  |      36024, 36028, 36032, 36036, 36040, 36044, 36048, 36052, 36056, 36060,  | 
4714  |  |      36064, 36068, 36072, 36076, 36080, 36084, 36088, 36092, 36096, 36100,  | 
4715  |  |      36104, 36108, 36112, 36116, 36120, 36124, 36128, 36132, 36136, 36140,  | 
4716  |  |      36144, 36148, 36152, 36156, 36160, 36164, 36168, 36172, 36176, 36180,  | 
4717  |  |      36184, 36188, 36192, 36196, 36200, 36204, 36208, 36212, 36216, 36220,  | 
4718  |  |      36224, 36228, 36232, 36236, 36240, 36244, 36248, 36252, 36256, 36260,  | 
4719  |  |      36264, 36268, 36272, 36276, 36280, 36284, 36288},  | 
4720  |  |     {36288, 36292, 36296, 36300, 36304, 36308, 36312, 36316, 36320, 36324, | 
4721  |  |      36328, 36332, 36336, 36340, 36344, 36348, 36352, 36356, 36360, 36364,  | 
4722  |  |      36368, 36372, 36376, 36380, 36384, 36388, 36392, 36396, 36400, 36404,  | 
4723  |  |      36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,  | 
4724  |  |      36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,  | 
4725  |  |      36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,  | 
4726  |  |      36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,  | 
4727  |  |      36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,  | 
4728  |  |      36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,  | 
4729  |  |      36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,  | 
4730  |  |      36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,  | 
4731  |  |      36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,  | 
4732  |  |      36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,  | 
4733  |  |      36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,  | 
4734  |  |      36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,  | 
4735  |  |      36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,  | 
4736  |  |      36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,  | 
4737  |  |      36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,  | 
4738  |  |      36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,  | 
4739  |  |      36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,  | 
4740  |  |      36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,  | 
4741  |  |      36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,  | 
4742  |  |      36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,  | 
4743  |  |      36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,  | 
4744  |  |      36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,  | 
4745  |  |      36408, 36408, 36408, 36408, 36408, 36408, 36408}};  | 
4746  |  | const char32_t decomposition_data[9102] = { | 
4747  |  |     0,      32,     32,     776,    97,     32,     772,    50,     51,  | 
4748  |  |     32,     769,    956,    32,     807,    49,     111,    49,     8260,  | 
4749  |  |     52,     49,     8260,   50,     51,     8260,   52,     65,     768,  | 
4750  |  |     65,     769,    65,     770,    65,     771,    65,     776,    65,  | 
4751  |  |     778,    67,     807,    69,     768,    69,     769,    69,     770,  | 
4752  |  |     69,     776,    73,     768,    73,     769,    73,     770,    73,  | 
4753  |  |     776,    78,     771,    79,     768,    79,     769,    79,     770,  | 
4754  |  |     79,     771,    79,     776,    85,     768,    85,     769,    85,  | 
4755  |  |     770,    85,     776,    89,     769,    97,     768,    97,     769,  | 
4756  |  |     97,     770,    97,     771,    97,     776,    97,     778,    99,  | 
4757  |  |     807,    101,    768,    101,    769,    101,    770,    101,    776,  | 
4758  |  |     105,    768,    105,    769,    105,    770,    105,    776,    110,  | 
4759  |  |     771,    111,    768,    111,    769,    111,    770,    111,    771,  | 
4760  |  |     111,    776,    117,    768,    117,    769,    117,    770,    117,  | 
4761  |  |     776,    121,    769,    121,    776,    65,     772,    97,     772,  | 
4762  |  |     65,     774,    97,     774,    65,     808,    97,     808,    67,  | 
4763  |  |     769,    99,     769,    67,     770,    99,     770,    67,     775,  | 
4764  |  |     99,     775,    67,     780,    99,     780,    68,     780,    100,  | 
4765  |  |     780,    69,     772,    101,    772,    69,     774,    101,    774,  | 
4766  |  |     69,     775,    101,    775,    69,     808,    101,    808,    69,  | 
4767  |  |     780,    101,    780,    71,     770,    103,    770,    71,     774,  | 
4768  |  |     103,    774,    71,     775,    103,    775,    71,     807,    103,  | 
4769  |  |     807,    72,     770,    104,    770,    73,     771,    105,    771,  | 
4770  |  |     73,     772,    105,    772,    73,     774,    105,    774,    73,  | 
4771  |  |     808,    105,    808,    73,     775,    73,     74,     105,    106,  | 
4772  |  |     74,     770,    106,    770,    75,     807,    107,    807,    76,  | 
4773  |  |     769,    108,    769,    76,     807,    108,    807,    76,     780,  | 
4774  |  |     108,    780,    76,     183,    108,    183,    78,     769,    110,  | 
4775  |  |     769,    78,     807,    110,    807,    78,     780,    110,    780,  | 
4776  |  |     700,    110,    79,     772,    111,    772,    79,     774,    111,  | 
4777  |  |     774,    79,     779,    111,    779,    82,     769,    114,    769,  | 
4778  |  |     82,     807,    114,    807,    82,     780,    114,    780,    83,  | 
4779  |  |     769,    115,    769,    83,     770,    115,    770,    83,     807,  | 
4780  |  |     115,    807,    83,     780,    115,    780,    84,     807,    116,  | 
4781  |  |     807,    84,     780,    116,    780,    85,     771,    117,    771,  | 
4782  |  |     85,     772,    117,    772,    85,     774,    117,    774,    85,  | 
4783  |  |     778,    117,    778,    85,     779,    117,    779,    85,     808,  | 
4784  |  |     117,    808,    87,     770,    119,    770,    89,     770,    121,  | 
4785  |  |     770,    89,     776,    90,     769,    122,    769,    90,     775,  | 
4786  |  |     122,    775,    90,     780,    122,    780,    115,    79,     795,  | 
4787  |  |     111,    795,    85,     795,    117,    795,    68,     90,     780,  | 
4788  |  |     68,     122,    780,    100,    122,    780,    76,     74,     76,  | 
4789  |  |     106,    108,    106,    78,     74,     78,     106,    110,    106,  | 
4790  |  |     65,     780,    97,     780,    73,     780,    105,    780,    79,  | 
4791  |  |     780,    111,    780,    85,     780,    117,    780,    85,     776,  | 
4792  |  |     772,    117,    776,    772,    85,     776,    769,    117,    776,  | 
4793  |  |     769,    85,     776,    780,    117,    776,    780,    85,     776,  | 
4794  |  |     768,    117,    776,    768,    65,     776,    772,    97,     776,  | 
4795  |  |     772,    65,     775,    772,    97,     775,    772,    198,    772,  | 
4796  |  |     230,    772,    71,     780,    103,    780,    75,     780,    107,  | 
4797  |  |     780,    79,     808,    111,    808,    79,     808,    772,    111,  | 
4798  |  |     808,    772,    439,    780,    658,    780,    106,    780,    68,  | 
4799  |  |     90,     68,     122,    100,    122,    71,     769,    103,    769,  | 
4800  |  |     78,     768,    110,    768,    65,     778,    769,    97,     778,  | 
4801  |  |     769,    198,    769,    230,    769,    216,    769,    248,    769,  | 
4802  |  |     65,     783,    97,     783,    65,     785,    97,     785,    69,  | 
4803  |  |     783,    101,    783,    69,     785,    101,    785,    73,     783,  | 
4804  |  |     105,    783,    73,     785,    105,    785,    79,     783,    111,  | 
4805  |  |     783,    79,     785,    111,    785,    82,     783,    114,    783,  | 
4806  |  |     82,     785,    114,    785,    85,     783,    117,    783,    85,  | 
4807  |  |     785,    117,    785,    83,     806,    115,    806,    84,     806,  | 
4808  |  |     116,    806,    72,     780,    104,    780,    65,     775,    97,  | 
4809  |  |     775,    69,     807,    101,    807,    79,     776,    772,    111,  | 
4810  |  |     776,    772,    79,     771,    772,    111,    771,    772,    79,  | 
4811  |  |     775,    111,    775,    79,     775,    772,    111,    775,    772,  | 
4812  |  |     89,     772,    121,    772,    104,    614,    106,    114,    633,  | 
4813  |  |     635,    641,    119,    121,    32,     774,    32,     775,    32,  | 
4814  |  |     778,    32,     808,    32,     771,    32,     779,    611,    108,  | 
4815  |  |     115,    120,    661,    768,    769,    787,    776,    769,    697,  | 
4816  |  |     32,     837,    59,     32,     769,    168,    769,    913,    769,  | 
4817  |  |     183,    917,    769,    919,    769,    921,    769,    927,    769,  | 
4818  |  |     933,    769,    937,    769,    953,    776,    769,    921,    776,  | 
4819  |  |     933,    776,    945,    769,    949,    769,    951,    769,    953,  | 
4820  |  |     769,    965,    776,    769,    953,    776,    965,    776,    959,  | 
4821  |  |     769,    965,    769,    969,    769,    946,    952,    933,    978,  | 
4822  |  |     769,    978,    776,    966,    960,    954,    961,    962,    920,  | 
4823  |  |     949,    931,    1045,   768,    1045,   776,    1043,   769,    1030,  | 
4824  |  |     776,    1050,   769,    1048,   768,    1059,   774,    1048,   774,  | 
4825  |  |     1080,   774,    1077,   768,    1077,   776,    1075,   769,    1110,  | 
4826  |  |     776,    1082,   769,    1080,   768,    1091,   774,    1140,   783,  | 
4827  |  |     1141,   783,    1046,   774,    1078,   774,    1040,   774,    1072,  | 
4828  |  |     774,    1040,   776,    1072,   776,    1045,   774,    1077,   774,  | 
4829  |  |     1240,   776,    1241,   776,    1046,   776,    1078,   776,    1047,  | 
4830  |  |     776,    1079,   776,    1048,   772,    1080,   772,    1048,   776,  | 
4831  |  |     1080,   776,    1054,   776,    1086,   776,    1256,   776,    1257,  | 
4832  |  |     776,    1069,   776,    1101,   776,    1059,   772,    1091,   772,  | 
4833  |  |     1059,   776,    1091,   776,    1059,   779,    1091,   779,    1063,  | 
4834  |  |     776,    1095,   776,    1067,   776,    1099,   776,    1381,   1410,  | 
4835  |  |     1575,   1619,   1575,   1620,   1608,   1620,   1575,   1621,   1610,  | 
4836  |  |     1620,   1575,   1652,   1608,   1652,   1735,   1652,   1610,   1652,  | 
4837  |  |     1749,   1620,   1729,   1620,   1746,   1620,   2344,   2364,   2352,  | 
4838  |  |     2364,   2355,   2364,   2325,   2364,   2326,   2364,   2327,   2364,  | 
4839  |  |     2332,   2364,   2337,   2364,   2338,   2364,   2347,   2364,   2351,  | 
4840  |  |     2364,   2503,   2494,   2503,   2519,   2465,   2492,   2466,   2492,  | 
4841  |  |     2479,   2492,   2610,   2620,   2616,   2620,   2582,   2620,   2583,  | 
4842  |  |     2620,   2588,   2620,   2603,   2620,   2887,   2902,   2887,   2878,  | 
4843  |  |     2887,   2903,   2849,   2876,   2850,   2876,   2962,   3031,   3014,  | 
4844  |  |     3006,   3015,   3006,   3014,   3031,   3142,   3158,   3263,   3285,  | 
4845  |  |     3270,   3285,   3270,   3286,   3270,   3266,   3270,   3266,   3285,  | 
4846  |  |     3398,   3390,   3399,   3390,   3398,   3415,   3545,   3530,   3545,  | 
4847  |  |     3535,   3545,   3535,   3530,   3545,   3551,   3661,   3634,   3789,  | 
4848  |  |     3762,   3755,   3737,   3755,   3745,   3851,   3906,   4023,   3916,  | 
4849  |  |     4023,   3921,   4023,   3926,   4023,   3931,   4023,   3904,   4021,  | 
4850  |  |     3953,   3954,   3953,   3956,   4018,   3968,   4018,   3953,   3968,  | 
4851  |  |     4019,   3968,   4019,   3953,   3968,   3953,   3968,   3986,   4023,  | 
4852  |  |     3996,   4023,   4001,   4023,   4006,   4023,   4011,   4023,   3984,  | 
4853  |  |     4021,   4133,   4142,   4316,   6917,   6965,   6919,   6965,   6921,  | 
4854  |  |     6965,   6923,   6965,   6925,   6965,   6929,   6965,   6970,   6965,  | 
4855  |  |     6972,   6965,   6974,   6965,   6975,   6965,   6978,   6965,   65,  | 
4856  |  |     198,    66,     68,     69,     398,    71,     72,     73,     74,  | 
4857  |  |     75,     76,     77,     78,     79,     546,    80,     82,     84,  | 
4858  |  |     85,     87,     97,     592,    593,    7426,   98,     100,    101,  | 
4859  |  |     601,    603,    604,    103,    107,    109,    331,    111,    596,  | 
4860  |  |     7446,   7447,   112,    116,    117,    7453,   623,    118,    7461,  | 
4861  |  |     946,    947,    948,    966,    967,    105,    114,    117,    118,  | 
4862  |  |     946,    947,    961,    966,    967,    1085,   594,    99,     597,  | 
4863  |  |     240,    604,    102,    607,    609,    613,    616,    617,    618,  | 
4864  |  |     7547,   669,    621,    7557,   671,    625,    624,    626,    627,  | 
4865  |  |     628,    629,    632,    642,    643,    427,    649,    650,    7452,  | 
4866  |  |     651,    652,    122,    656,    657,    658,    952,    65,     805,  | 
4867  |  |     97,     805,    66,     775,    98,     775,    66,     803,    98,  | 
4868  |  |     803,    66,     817,    98,     817,    67,     807,    769,    99,  | 
4869  |  |     807,    769,    68,     775,    100,    775,    68,     803,    100,  | 
4870  |  |     803,    68,     817,    100,    817,    68,     807,    100,    807,  | 
4871  |  |     68,     813,    100,    813,    69,     772,    768,    101,    772,  | 
4872  |  |     768,    69,     772,    769,    101,    772,    769,    69,     813,  | 
4873  |  |     101,    813,    69,     816,    101,    816,    69,     807,    774,  | 
4874  |  |     101,    807,    774,    70,     775,    102,    775,    71,     772,  | 
4875  |  |     103,    772,    72,     775,    104,    775,    72,     803,    104,  | 
4876  |  |     803,    72,     776,    104,    776,    72,     807,    104,    807,  | 
4877  |  |     72,     814,    104,    814,    73,     816,    105,    816,    73,  | 
4878  |  |     776,    769,    105,    776,    769,    75,     769,    107,    769,  | 
4879  |  |     75,     803,    107,    803,    75,     817,    107,    817,    76,  | 
4880  |  |     803,    108,    803,    76,     803,    772,    108,    803,    772,  | 
4881  |  |     76,     817,    108,    817,    76,     813,    108,    813,    77,  | 
4882  |  |     769,    109,    769,    77,     775,    109,    775,    77,     803,  | 
4883  |  |     109,    803,    78,     775,    110,    775,    78,     803,    110,  | 
4884  |  |     803,    78,     817,    110,    817,    78,     813,    110,    813,  | 
4885  |  |     79,     771,    769,    111,    771,    769,    79,     771,    776,  | 
4886  |  |     111,    771,    776,    79,     772,    768,    111,    772,    768,  | 
4887  |  |     79,     772,    769,    111,    772,    769,    80,     769,    112,  | 
4888  |  |     769,    80,     775,    112,    775,    82,     775,    114,    775,  | 
4889  |  |     82,     803,    114,    803,    82,     803,    772,    114,    803,  | 
4890  |  |     772,    82,     817,    114,    817,    83,     775,    115,    775,  | 
4891  |  |     83,     803,    115,    803,    83,     769,    775,    115,    769,  | 
4892  |  |     775,    83,     780,    775,    115,    780,    775,    83,     803,  | 
4893  |  |     775,    115,    803,    775,    84,     775,    116,    775,    84,  | 
4894  |  |     803,    116,    803,    84,     817,    116,    817,    84,     813,  | 
4895  |  |     116,    813,    85,     804,    117,    804,    85,     816,    117,  | 
4896  |  |     816,    85,     813,    117,    813,    85,     771,    769,    117,  | 
4897  |  |     771,    769,    85,     772,    776,    117,    772,    776,    86,  | 
4898  |  |     771,    118,    771,    86,     803,    118,    803,    87,     768,  | 
4899  |  |     119,    768,    87,     769,    119,    769,    87,     776,    119,  | 
4900  |  |     776,    87,     775,    119,    775,    87,     803,    119,    803,  | 
4901  |  |     88,     775,    120,    775,    88,     776,    120,    776,    89,  | 
4902  |  |     775,    121,    775,    90,     770,    122,    770,    90,     803,  | 
4903  |  |     122,    803,    90,     817,    122,    817,    104,    817,    116,  | 
4904  |  |     776,    119,    778,    121,    778,    97,     702,    383,    775,  | 
4905  |  |     65,     803,    97,     803,    65,     777,    97,     777,    65,  | 
4906  |  |     770,    769,    97,     770,    769,    65,     770,    768,    97,  | 
4907  |  |     770,    768,    65,     770,    777,    97,     770,    777,    65,  | 
4908  |  |     770,    771,    97,     770,    771,    65,     803,    770,    97,  | 
4909  |  |     803,    770,    65,     774,    769,    97,     774,    769,    65,  | 
4910  |  |     774,    768,    97,     774,    768,    65,     774,    777,    97,  | 
4911  |  |     774,    777,    65,     774,    771,    97,     774,    771,    65,  | 
4912  |  |     803,    774,    97,     803,    774,    69,     803,    101,    803,  | 
4913  |  |     69,     777,    101,    777,    69,     771,    101,    771,    69,  | 
4914  |  |     770,    769,    101,    770,    769,    69,     770,    768,    101,  | 
4915  |  |     770,    768,    69,     770,    777,    101,    770,    777,    69,  | 
4916  |  |     770,    771,    101,    770,    771,    69,     803,    770,    101,  | 
4917  |  |     803,    770,    73,     777,    105,    777,    73,     803,    105,  | 
4918  |  |     803,    79,     803,    111,    803,    79,     777,    111,    777,  | 
4919  |  |     79,     770,    769,    111,    770,    769,    79,     770,    768,  | 
4920  |  |     111,    770,    768,    79,     770,    777,    111,    770,    777,  | 
4921  |  |     79,     770,    771,    111,    770,    771,    79,     803,    770,  | 
4922  |  |     111,    803,    770,    79,     795,    769,    111,    795,    769,  | 
4923  |  |     79,     795,    768,    111,    795,    768,    79,     795,    777,  | 
4924  |  |     111,    795,    777,    79,     795,    771,    111,    795,    771,  | 
4925  |  |     79,     795,    803,    111,    795,    803,    85,     803,    117,  | 
4926  |  |     803,    85,     777,    117,    777,    85,     795,    769,    117,  | 
4927  |  |     795,    769,    85,     795,    768,    117,    795,    768,    85,  | 
4928  |  |     795,    777,    117,    795,    777,    85,     795,    771,    117,  | 
4929  |  |     795,    771,    85,     795,    803,    117,    795,    803,    89,  | 
4930  |  |     768,    121,    768,    89,     803,    121,    803,    89,     777,  | 
4931  |  |     121,    777,    89,     771,    121,    771,    945,    787,    945,  | 
4932  |  |     788,    945,    787,    768,    945,    788,    768,    945,    787,  | 
4933  |  |     769,    945,    788,    769,    945,    787,    834,    945,    788,  | 
4934  |  |     834,    913,    787,    913,    788,    913,    787,    768,    913,  | 
4935  |  |     788,    768,    913,    787,    769,    913,    788,    769,    913,  | 
4936  |  |     787,    834,    913,    788,    834,    949,    787,    949,    788,  | 
4937  |  |     949,    787,    768,    949,    788,    768,    949,    787,    769,  | 
4938  |  |     949,    788,    769,    917,    787,    917,    788,    917,    787,  | 
4939  |  |     768,    917,    788,    768,    917,    787,    769,    917,    788,  | 
4940  |  |     769,    951,    787,    951,    788,    951,    787,    768,    951,  | 
4941  |  |     788,    768,    951,    787,    769,    951,    788,    769,    951,  | 
4942  |  |     787,    834,    951,    788,    834,    919,    787,    919,    788,  | 
4943  |  |     919,    787,    768,    919,    788,    768,    919,    787,    769,  | 
4944  |  |     919,    788,    769,    919,    787,    834,    919,    788,    834,  | 
4945  |  |     953,    787,    953,    788,    953,    787,    768,    953,    788,  | 
4946  |  |     768,    953,    787,    769,    953,    788,    769,    953,    787,  | 
4947  |  |     834,    953,    788,    834,    921,    787,    921,    788,    921,  | 
4948  |  |     787,    768,    921,    788,    768,    921,    787,    769,    921,  | 
4949  |  |     788,    769,    921,    787,    834,    921,    788,    834,    959,  | 
4950  |  |     787,    959,    788,    959,    787,    768,    959,    788,    768,  | 
4951  |  |     959,    787,    769,    959,    788,    769,    927,    787,    927,  | 
4952  |  |     788,    927,    787,    768,    927,    788,    768,    927,    787,  | 
4953  |  |     769,    927,    788,    769,    965,    787,    965,    788,    965,  | 
4954  |  |     787,    768,    965,    788,    768,    965,    787,    769,    965,  | 
4955  |  |     788,    769,    965,    787,    834,    965,    788,    834,    933,  | 
4956  |  |     788,    933,    788,    768,    933,    788,    769,    933,    788,  | 
4957  |  |     834,    969,    787,    969,    788,    969,    787,    768,    969,  | 
4958  |  |     788,    768,    969,    787,    769,    969,    788,    769,    969,  | 
4959  |  |     787,    834,    969,    788,    834,    937,    787,    937,    788,  | 
4960  |  |     937,    787,    768,    937,    788,    768,    937,    787,    769,  | 
4961  |  |     937,    788,    769,    937,    787,    834,    937,    788,    834,  | 
4962  |  |     945,    768,    945,    769,    949,    768,    949,    769,    951,  | 
4963  |  |     768,    951,    769,    953,    768,    953,    769,    959,    768,  | 
4964  |  |     959,    769,    965,    768,    965,    769,    969,    768,    969,  | 
4965  |  |     769,    945,    787,    837,    945,    788,    837,    945,    787,  | 
4966  |  |     768,    837,    945,    788,    768,    837,    945,    787,    769,  | 
4967  |  |     837,    945,    788,    769,    837,    945,    787,    834,    837,  | 
4968  |  |     945,    788,    834,    837,    913,    787,    837,    913,    788,  | 
4969  |  |     837,    913,    787,    768,    837,    913,    788,    768,    837,  | 
4970  |  |     913,    787,    769,    837,    913,    788,    769,    837,    913,  | 
4971  |  |     787,    834,    837,    913,    788,    834,    837,    951,    787,  | 
4972  |  |     837,    951,    788,    837,    951,    787,    768,    837,    951,  | 
4973  |  |     788,    768,    837,    951,    787,    769,    837,    951,    788,  | 
4974  |  |     769,    837,    951,    787,    834,    837,    951,    788,    834,  | 
4975  |  |     837,    919,    787,    837,    919,    788,    837,    919,    787,  | 
4976  |  |     768,    837,    919,    788,    768,    837,    919,    787,    769,  | 
4977  |  |     837,    919,    788,    769,    837,    919,    787,    834,    837,  | 
4978  |  |     919,    788,    834,    837,    969,    787,    837,    969,    788,  | 
4979  |  |     837,    969,    787,    768,    837,    969,    788,    768,    837,  | 
4980  |  |     969,    787,    769,    837,    969,    788,    769,    837,    969,  | 
4981  |  |     787,    834,    837,    969,    788,    834,    837,    937,    787,  | 
4982  |  |     837,    937,    788,    837,    937,    787,    768,    837,    937,  | 
4983  |  |     788,    768,    837,    937,    787,    769,    837,    937,    788,  | 
4984  |  |     769,    837,    937,    787,    834,    837,    937,    788,    834,  | 
4985  |  |     837,    945,    774,    945,    772,    945,    768,    837,    945,  | 
4986  |  |     837,    945,    769,    837,    945,    834,    945,    834,    837,  | 
4987  |  |     913,    774,    913,    772,    913,    768,    913,    769,    913,  | 
4988  |  |     837,    32,     787,    953,    32,     787,    32,     834,    168,  | 
4989  |  |     834,    951,    768,    837,    951,    837,    951,    769,    837,  | 
4990  |  |     951,    834,    951,    834,    837,    917,    768,    917,    769,  | 
4991  |  |     919,    768,    919,    769,    919,    837,    8127,   768,    8127,  | 
4992  |  |     769,    8127,   834,    953,    774,    953,    772,    953,    776,  | 
4993  |  |     768,    953,    776,    769,    953,    834,    953,    776,    834,  | 
4994  |  |     921,    774,    921,    772,    921,    768,    921,    769,    8190,  | 
4995  |  |     768,    8190,   769,    8190,   834,    965,    774,    965,    772,  | 
4996  |  |     965,    776,    768,    965,    776,    769,    961,    787,    961,  | 
4997  |  |     788,    965,    834,    965,    776,    834,    933,    774,    933,  | 
4998  |  |     772,    933,    768,    933,    769,    929,    788,    168,    768,  | 
4999  |  |     168,    769,    96,     969,    768,    837,    969,    837,    969,  | 
5000  |  |     769,    837,    969,    834,    969,    834,    837,    927,    768,  | 
5001  |  |     927,    769,    937,    768,    937,    769,    937,    837,    180,  | 
5002  |  |     32,     788,    8194,   8195,   32,     32,     32,     32,     32,  | 
5003  |  |     32,     32,     32,     32,     8208,   32,     819,    46,     46,  | 
5004  |  |     46,     46,     46,     46,     32,     8242,   8242,   8242,   8242,  | 
5005  |  |     8242,   8245,   8245,   8245,   8245,   8245,   33,     33,     32,  | 
5006  |  |     773,    63,     63,     63,     33,     33,     63,     8242,   8242,  | 
5007  |  |     8242,   8242,   32,     48,     105,    52,     53,     54,     55,  | 
5008  |  |     56,     57,     43,     8722,   61,     40,     41,     110,    48,  | 
5009  |  |     49,     50,     51,     52,     53,     54,     55,     56,     57,  | 
5010  |  |     43,     8722,   61,     40,     41,     97,     101,    111,    120,  | 
5011  |  |     601,    104,    107,    108,    109,    110,    112,    115,    116,  | 
5012  |  |     82,     115,    97,     47,     99,     97,     47,     115,    67,  | 
5013  |  |     176,    67,     99,     47,     111,    99,     47,     117,    400,  | 
5014  |  |     176,    70,     103,    72,     72,     72,     104,    295,    73,  | 
5015  |  |     73,     76,     108,    78,     78,     111,    80,     81,     82,  | 
5016  |  |     82,     82,     83,     77,     84,     69,     76,     84,     77,  | 
5017  |  |     90,     937,    90,     75,     65,     778,    66,     67,     101,  | 
5018  |  |     69,     70,     77,     111,    1488,   1489,   1490,   1491,   105,  | 
5019  |  |     70,     65,     88,     960,    947,    915,    928,    8721,   68,  | 
5020  |  |     100,    101,    105,    106,    49,     8260,   55,     49,     8260,  | 
5021  |  |     57,     49,     8260,   49,     48,     49,     8260,   51,     50,  | 
5022  |  |     8260,   51,     49,     8260,   53,     50,     8260,   53,     51,  | 
5023  |  |     8260,   53,     52,     8260,   53,     49,     8260,   54,     53,  | 
5024  |  |     8260,   54,     49,     8260,   56,     51,     8260,   56,     53,  | 
5025  |  |     8260,   56,     55,     8260,   56,     49,     8260,   73,     73,  | 
5026  |  |     73,     73,     73,     73,     73,     86,     86,     86,     73,  | 
5027  |  |     86,     73,     73,     86,     73,     73,     73,     73,     88,  | 
5028  |  |     88,     88,     73,     88,     73,     73,     76,     67,     68,  | 
5029  |  |     77,     105,    105,    105,    105,    105,    105,    105,    118,  | 
5030  |  |     118,    118,    105,    118,    105,    105,    118,    105,    105,  | 
5031  |  |     105,    105,    120,    120,    120,    105,    120,    105,    105,  | 
5032  |  |     108,    99,     100,    109,    48,     8260,   51,     8592,   824,  | 
5033  |  |     8594,   824,    8596,   824,    8656,   824,    8660,   824,    8658,  | 
5034  |  |     824,    8707,   824,    8712,   824,    8715,   824,    8739,   824,  | 
5035  |  |     8741,   824,    8747,   8747,   8747,   8747,   8747,   8750,   8750,  | 
5036  |  |     8750,   8750,   8750,   8764,   824,    8771,   824,    8773,   824,  | 
5037  |  |     8776,   824,    61,     824,    8801,   824,    8781,   824,    60,  | 
5038  |  |     824,    62,     824,    8804,   824,    8805,   824,    8818,   824,  | 
5039  |  |     8819,   824,    8822,   824,    8823,   824,    8826,   824,    8827,  | 
5040  |  |     824,    8834,   824,    8835,   824,    8838,   824,    8839,   824,  | 
5041  |  |     8866,   824,    8872,   824,    8873,   824,    8875,   824,    8828,  | 
5042  |  |     824,    8829,   824,    8849,   824,    8850,   824,    8882,   824,  | 
5043  |  |     8883,   824,    8884,   824,    8885,   824,    12296,  12297,  49,  | 
5044  |  |     50,     51,     52,     53,     54,     55,     56,     57,     49,  | 
5045  |  |     48,     49,     49,     49,     50,     49,     51,     49,     52,  | 
5046  |  |     49,     53,     49,     54,     49,     55,     49,     56,     49,  | 
5047  |  |     57,     50,     48,     40,     49,     41,     40,     50,     41,  | 
5048  |  |     40,     51,     41,     40,     52,     41,     40,     53,     41,  | 
5049  |  |     40,     54,     41,     40,     55,     41,     40,     56,     41,  | 
5050  |  |     40,     57,     41,     40,     49,     48,     41,     40,     49,  | 
5051  |  |     49,     41,     40,     49,     50,     41,     40,     49,     51,  | 
5052  |  |     41,     40,     49,     52,     41,     40,     49,     53,     41,  | 
5053  |  |     40,     49,     54,     41,     40,     49,     55,     41,     40,  | 
5054  |  |     49,     56,     41,     40,     49,     57,     41,     40,     50,  | 
5055  |  |     48,     41,     49,     46,     50,     46,     51,     46,     52,  | 
5056  |  |     46,     53,     46,     54,     46,     55,     46,     56,     46,  | 
5057  |  |     57,     46,     49,     48,     46,     49,     49,     46,     49,  | 
5058  |  |     50,     46,     49,     51,     46,     49,     52,     46,     49,  | 
5059  |  |     53,     46,     49,     54,     46,     49,     55,     46,     49,  | 
5060  |  |     56,     46,     49,     57,     46,     50,     48,     46,     40,  | 
5061  |  |     97,     41,     40,     98,     41,     40,     99,     41,     40,  | 
5062  |  |     100,    41,     40,     101,    41,     40,     102,    41,     40,  | 
5063  |  |     103,    41,     40,     104,    41,     40,     105,    41,     40,  | 
5064  |  |     106,    41,     40,     107,    41,     40,     108,    41,     40,  | 
5065  |  |     109,    41,     40,     110,    41,     40,     111,    41,     40,  | 
5066  |  |     112,    41,     40,     113,    41,     40,     114,    41,     40,  | 
5067  |  |     115,    41,     40,     116,    41,     40,     117,    41,     40,  | 
5068  |  |     118,    41,     40,     119,    41,     40,     120,    41,     40,  | 
5069  |  |     121,    41,     40,     122,    41,     65,     66,     67,     68,  | 
5070  |  |     69,     70,     71,     72,     73,     74,     75,     76,     77,  | 
5071  |  |     78,     79,     80,     81,     82,     83,     84,     85,     86,  | 
5072  |  |     87,     88,     89,     90,     97,     98,     99,     100,    101,  | 
5073  |  |     102,    103,    104,    105,    106,    107,    108,    109,    110,  | 
5074  |  |     111,    112,    113,    114,    115,    116,    117,    118,    119,  | 
5075  |  |     120,    121,    122,    48,     8747,   8747,   8747,   8747,   58,  | 
5076  |  |     58,     61,     61,     61,     61,     61,     61,     10973,  824,  | 
5077  |  |     106,    86,     11617,  27597,  40863,  19968,  20008,  20022,  20031,  | 
5078  |  |     20057,  20101,  20108,  20128,  20154,  20799,  20837,  20843,  20866,  | 
5079  |  |     20886,  20907,  20960,  20981,  20992,  21147,  21241,  21269,  21274,  | 
5080  |  |     21304,  21313,  21340,  21353,  21378,  21430,  21448,  21475,  22231,  | 
5081  |  |     22303,  22763,  22786,  22794,  22805,  22823,  22899,  23376,  23424,  | 
5082  |  |     23544,  23567,  23586,  23608,  23662,  23665,  24027,  24037,  24049,  | 
5083  |  |     24062,  24178,  24186,  24191,  24308,  24318,  24331,  24339,  24400,  | 
5084  |  |     24417,  24435,  24515,  25096,  25142,  25163,  25903,  25908,  25991,  | 
5085  |  |     26007,  26020,  26041,  26080,  26085,  26352,  26376,  26408,  27424,  | 
5086  |  |     27490,  27513,  27571,  27595,  27604,  27611,  27663,  27668,  27700,  | 
5087  |  |     28779,  29226,  29238,  29243,  29247,  29255,  29273,  29275,  29356,  | 
5088  |  |     29572,  29577,  29916,  29926,  29976,  29983,  29992,  30000,  30091,  | 
5089  |  |     30098,  30326,  30333,  30382,  30399,  30446,  30683,  30690,  30707,  | 
5090  |  |     31034,  31160,  31166,  31348,  31435,  31481,  31859,  31992,  32566,  | 
5091  |  |     32593,  32650,  32701,  32769,  32780,  32786,  32819,  32895,  32905,  | 
5092  |  |     33251,  33258,  33267,  33276,  33292,  33307,  33311,  33390,  33394,  | 
5093  |  |     33400,  34381,  34411,  34880,  34892,  34915,  35198,  35211,  35282,  | 
5094  |  |     35328,  35895,  35910,  35925,  35960,  35997,  36196,  36208,  36275,  | 
5095  |  |     36523,  36554,  36763,  36784,  36789,  37009,  37193,  37318,  37324,  | 
5096  |  |     37329,  38263,  38272,  38428,  38582,  38585,  38632,  38737,  38750,  | 
5097  |  |     38754,  38761,  38859,  38893,  38899,  38913,  39080,  39131,  39135,  | 
5098  |  |     39318,  39321,  39340,  39592,  39640,  39647,  39717,  39727,  39730,  | 
5099  |  |     39740,  39770,  40165,  40565,  40575,  40613,  40635,  40643,  40653,  | 
5100  |  |     40657,  40697,  40701,  40718,  40723,  40736,  40763,  40778,  40786,  | 
5101  |  |     40845,  40860,  40864,  32,     12306,  21313,  21316,  21317,  12363,  | 
5102  |  |     12441,  12365,  12441,  12367,  12441,  12369,  12441,  12371,  12441,  | 
5103  |  |     12373,  12441,  12375,  12441,  12377,  12441,  12379,  12441,  12381,  | 
5104  |  |     12441,  12383,  12441,  12385,  12441,  12388,  12441,  12390,  12441,  | 
5105  |  |     12392,  12441,  12399,  12441,  12399,  12442,  12402,  12441,  12402,  | 
5106  |  |     12442,  12405,  12441,  12405,  12442,  12408,  12441,  12408,  12442,  | 
5107  |  |     12411,  12441,  12411,  12442,  12358,  12441,  32,     12441,  32,  | 
5108  |  |     12442,  12445,  12441,  12424,  12426,  12459,  12441,  12461,  12441,  | 
5109  |  |     12463,  12441,  12465,  12441,  12467,  12441,  12469,  12441,  12471,  | 
5110  |  |     12441,  12473,  12441,  12475,  12441,  12477,  12441,  12479,  12441,  | 
5111  |  |     12481,  12441,  12484,  12441,  12486,  12441,  12488,  12441,  12495,  | 
5112  |  |     12441,  12495,  12442,  12498,  12441,  12498,  12442,  12501,  12441,  | 
5113  |  |     12501,  12442,  12504,  12441,  12504,  12442,  12507,  12441,  12507,  | 
5114  |  |     12442,  12454,  12441,  12527,  12441,  12528,  12441,  12529,  12441,  | 
5115  |  |     12530,  12441,  12541,  12441,  12467,  12488,  4352,   4353,   4522,  | 
5116  |  |     4354,   4524,   4525,   4355,   4356,   4357,   4528,   4529,   4530,  | 
5117  |  |     4531,   4532,   4533,   4378,   4358,   4359,   4360,   4385,   4361,  | 
5118  |  |     4362,   4363,   4364,   4365,   4366,   4367,   4368,   4369,   4370,  | 
5119  |  |     4449,   4450,   4451,   4452,   4453,   4454,   4455,   4456,   4457,  | 
5120  |  |     4458,   4459,   4460,   4461,   4462,   4463,   4464,   4465,   4466,  | 
5121  |  |     4467,   4468,   4469,   4448,   4372,   4373,   4551,   4552,   4556,  | 
5122  |  |     4558,   4563,   4567,   4569,   4380,   4573,   4575,   4381,   4382,  | 
5123  |  |     4384,   4386,   4387,   4391,   4393,   4395,   4396,   4397,   4398,  | 
5124  |  |     4399,   4402,   4406,   4416,   4423,   4428,   4593,   4594,   4439,  | 
5125  |  |     4440,   4441,   4484,   4485,   4488,   4497,   4498,   4500,   4510,  | 
5126  |  |     4513,   19968,  20108,  19977,  22235,  19978,  20013,  19979,  30002,  | 
5127  |  |     20057,  19993,  19969,  22825,  22320,  20154,  40,     4352,   41,  | 
5128  |  |     40,     4354,   41,     40,     4355,   41,     40,     4357,   41,  | 
5129  |  |     40,     4358,   41,     40,     4359,   41,     40,     4361,   41,  | 
5130  |  |     40,     4363,   41,     40,     4364,   41,     40,     4366,   41,  | 
5131  |  |     40,     4367,   41,     40,     4368,   41,     40,     4369,   41,  | 
5132  |  |     40,     4370,   41,     40,     4352,   4449,   41,     40,     4354,  | 
5133  |  |     4449,   41,     40,     4355,   4449,   41,     40,     4357,   4449,  | 
5134  |  |     41,     40,     4358,   4449,   41,     40,     4359,   4449,   41,  | 
5135  |  |     40,     4361,   4449,   41,     40,     4363,   4449,   41,     40,  | 
5136  |  |     4364,   4449,   41,     40,     4366,   4449,   41,     40,     4367,  | 
5137  |  |     4449,   41,     40,     4368,   4449,   41,     40,     4369,   4449,  | 
5138  |  |     41,     40,     4370,   4449,   41,     40,     4364,   4462,   41,  | 
5139  |  |     40,     4363,   4457,   4364,   4453,   4523,   41,     40,     4363,  | 
5140  |  |     4457,   4370,   4462,   41,     40,     19968,  41,     40,     20108,  | 
5141  |  |     41,     40,     19977,  41,     40,     22235,  41,     40,     20116,  | 
5142  |  |     41,     40,     20845,  41,     40,     19971,  41,     40,     20843,  | 
5143  |  |     41,     40,     20061,  41,     40,     21313,  41,     40,     26376,  | 
5144  |  |     41,     40,     28779,  41,     40,     27700,  41,     40,     26408,  | 
5145  |  |     41,     40,     37329,  41,     40,     22303,  41,     40,     26085,  | 
5146  |  |     41,     40,     26666,  41,     40,     26377,  41,     40,     31038,  | 
5147  |  |     41,     40,     21517,  41,     40,     29305,  41,     40,     36001,  | 
5148  |  |     41,     40,     31069,  41,     40,     21172,  41,     40,     20195,  | 
5149  |  |     41,     40,     21628,  41,     40,     23398,  41,     40,     30435,  | 
5150  |  |     41,     40,     20225,  41,     40,     36039,  41,     40,     21332,  | 
5151  |  |     41,     40,     31085,  41,     40,     20241,  41,     40,     33258,  | 
5152  |  |     41,     40,     33267,  41,     21839,  24188,  25991,  31631,  80,  | 
5153  |  |     84,     69,     50,     49,     50,     50,     50,     51,     50,  | 
5154  |  |     52,     50,     53,     50,     54,     50,     55,     50,     56,  | 
5155  |  |     50,     57,     51,     48,     51,     49,     51,     50,     51,  | 
5156  |  |     51,     51,     52,     51,     53,     4352,   4354,   4355,   4357,  | 
5157  |  |     4358,   4359,   4361,   4363,   4364,   4366,   4367,   4368,   4369,  | 
5158  |  |     4370,   4352,   4449,   4354,   4449,   4355,   4449,   4357,   4449,  | 
5159  |  |     4358,   4449,   4359,   4449,   4361,   4449,   4363,   4449,   4364,  | 
5160  |  |     4449,   4366,   4449,   4367,   4449,   4368,   4449,   4369,   4449,  | 
5161  |  |     4370,   4449,   4366,   4449,   4535,   4352,   4457,   4364,   4462,  | 
5162  |  |     4363,   4468,   4363,   4462,   19968,  20108,  19977,  22235,  20116,  | 
5163  |  |     20845,  19971,  20843,  20061,  21313,  26376,  28779,  27700,  26408,  | 
5164  |  |     37329,  22303,  26085,  26666,  26377,  31038,  21517,  29305,  36001,  | 
5165  |  |     31069,  21172,  31192,  30007,  22899,  36969,  20778,  21360,  27880,  | 
5166  |  |     38917,  20241,  20889,  27491,  19978,  20013,  19979,  24038,  21491,  | 
5167  |  |     21307,  23447,  23398,  30435,  20225,  36039,  21332,  22812,  51,  | 
5168  |  |     54,     51,     55,     51,     56,     51,     57,     52,     48,  | 
5169  |  |     52,     49,     52,     50,     52,     51,     52,     52,     52,  | 
5170  |  |     53,     52,     54,     52,     55,     52,     56,     52,     57,  | 
5171  |  |     53,     48,     49,     26376,  50,     26376,  51,     26376,  52,  | 
5172  |  |     26376,  53,     26376,  54,     26376,  55,     26376,  56,     26376,  | 
5173  |  |     57,     26376,  49,     48,     26376,  49,     49,     26376,  49,  | 
5174  |  |     50,     26376,  72,     103,    101,    114,    103,    101,    86,  | 
5175  |  |     76,     84,     68,     12450,  12452,  12454,  12456,  12458,  12459,  | 
5176  |  |     12461,  12463,  12465,  12467,  12469,  12471,  12473,  12475,  12477,  | 
5177  |  |     12479,  12481,  12484,  12486,  12488,  12490,  12491,  12492,  12493,  | 
5178  |  |     12494,  12495,  12498,  12501,  12504,  12507,  12510,  12511,  12512,  | 
5179  |  |     12513,  12514,  12516,  12518,  12520,  12521,  12522,  12523,  12524,  | 
5180  |  |     12525,  12527,  12528,  12529,  12530,  20196,  21644,  12450,  12495,  | 
5181  |  |     12442,  12540,  12488,  12450,  12523,  12501,  12449,  12450,  12531,  | 
5182  |  |     12504,  12442,  12450,  12450,  12540,  12523,  12452,  12491,  12531,  | 
5183  |  |     12463,  12441,  12452,  12531,  12481,  12454,  12457,  12531,  12456,  | 
5184  |  |     12473,  12463,  12540,  12488,  12441,  12456,  12540,  12459,  12540,  | 
5185  |  |     12458,  12531,  12473,  12458,  12540,  12512,  12459,  12452,  12522,  | 
5186  |  |     12459,  12521,  12483,  12488,  12459,  12525,  12522,  12540,  12459,  | 
5187  |  |     12441,  12525,  12531,  12459,  12441,  12531,  12510,  12461,  12441,  | 
5188  |  |     12459,  12441,  12461,  12441,  12491,  12540,  12461,  12517,  12522,  | 
5189  |  |     12540,  12461,  12441,  12523,  12479,  12441,  12540,  12461,  12525,  | 
5190  |  |     12461,  12525,  12463,  12441,  12521,  12512,  12461,  12525,  12513,  | 
5191  |  |     12540,  12488,  12523,  12461,  12525,  12527,  12483,  12488,  12463,  | 
5192  |  |     12441,  12521,  12512,  12463,  12441,  12521,  12512,  12488,  12531,  | 
5193  |  |     12463,  12523,  12475,  12441,  12452,  12525,  12463,  12525,  12540,  | 
5194  |  |     12493,  12465,  12540,  12473,  12467,  12523,  12490,  12467,  12540,  | 
5195  |  |     12507,  12442,  12469,  12452,  12463,  12523,  12469,  12531,  12481,  | 
5196  |  |     12540,  12512,  12471,  12522,  12531,  12463,  12441,  12475,  12531,  | 
5197  |  |     12481,  12475,  12531,  12488,  12479,  12441,  12540,  12473,  12486,  | 
5198  |  |     12441,  12471,  12488,  12441,  12523,  12488,  12531,  12490,  12494,  | 
5199  |  |     12494,  12483,  12488,  12495,  12452,  12484,  12495,  12442,  12540,  | 
5200  |  |     12475,  12531,  12488,  12495,  12442,  12540,  12484,  12495,  12441,  | 
5201  |  |     12540,  12524,  12523,  12498,  12442,  12450,  12473,  12488,  12523,  | 
5202  |  |     12498,  12442,  12463,  12523,  12498,  12442,  12467,  12498,  12441,  | 
5203  |  |     12523,  12501,  12449,  12521,  12483,  12488,  12441,  12501,  12451,  | 
5204  |  |     12540,  12488,  12501,  12441,  12483,  12471,  12455,  12523,  12501,  | 
5205  |  |     12521,  12531,  12504,  12463,  12479,  12540,  12523,  12504,  12442,  | 
5206  |  |     12477,  12504,  12442,  12491,  12498,  12504,  12523,  12484,  12504,  | 
5207  |  |     12442,  12531,  12473,  12504,  12442,  12540,  12471,  12441,  12504,  | 
5208  |  |     12441,  12540,  12479,  12507,  12442,  12452,  12531,  12488,  12507,  | 
5209  |  |     12441,  12523,  12488,  12507,  12531,  12507,  12442,  12531,  12488,  | 
5210  |  |     12441,  12507,  12540,  12523,  12507,  12540,  12531,  12510,  12452,  | 
5211  |  |     12463,  12525,  12510,  12452,  12523,  12510,  12483,  12495,  12510,  | 
5212  |  |     12523,  12463,  12510,  12531,  12471,  12519,  12531,  12511,  12463,  | 
5213  |  |     12525,  12531,  12511,  12522,  12511,  12522,  12495,  12441,  12540,  | 
5214  |  |     12523,  12513,  12459,  12441,  12513,  12459,  12441,  12488,  12531,  | 
5215  |  |     12513,  12540,  12488,  12523,  12516,  12540,  12488,  12441,  12516,  | 
5216  |  |     12540,  12523,  12518,  12450,  12531,  12522,  12483,  12488,  12523,  | 
5217  |  |     12522,  12521,  12523,  12498,  12442,  12540,  12523,  12540,  12501,  | 
5218  |  |     12441,  12523,  12524,  12512,  12524,  12531,  12488,  12465,  12441,  | 
5219  |  |     12531,  12527,  12483,  12488,  48,     28857,  49,     28857,  50,  | 
5220  |  |     28857,  51,     28857,  52,     28857,  53,     28857,  54,     28857,  | 
5221  |  |     55,     28857,  56,     28857,  57,     28857,  49,     48,     28857,  | 
5222  |  |     49,     49,     28857,  49,     50,     28857,  49,     51,     28857,  | 
5223  |  |     49,     52,     28857,  49,     53,     28857,  49,     54,     28857,  | 
5224  |  |     49,     55,     28857,  49,     56,     28857,  49,     57,     28857,  | 
5225  |  |     50,     48,     28857,  50,     49,     28857,  50,     50,     28857,  | 
5226  |  |     50,     51,     28857,  50,     52,     28857,  104,    80,     97,  | 
5227  |  |     100,    97,     65,     85,     98,     97,     114,    111,    86,  | 
5228  |  |     112,    99,     100,    109,    100,    109,    50,     100,    109,  | 
5229  |  |     51,     73,     85,     24179,  25104,  26157,  21644,  22823,  27491,  | 
5230  |  |     26126,  27835,  26666,  24335,  20250,  31038,  112,    65,     110,  | 
5231  |  |     65,     956,    65,     109,    65,     107,    65,     75,     66,  | 
5232  |  |     77,     66,     71,     66,     99,     97,     108,    107,    99,  | 
5233  |  |     97,     108,    112,    70,     110,    70,     956,    70,     956,  | 
5234  |  |     103,    109,    103,    107,    103,    72,     122,    107,    72,  | 
5235  |  |     122,    77,     72,     122,    71,     72,     122,    84,     72,  | 
5236  |  |     122,    956,    108,    109,    108,    100,    108,    107,    108,  | 
5237  |  |     102,    109,    110,    109,    956,    109,    109,    109,    99,  | 
5238  |  |     109,    107,    109,    109,    109,    50,     99,     109,    50,  | 
5239  |  |     109,    50,     107,    109,    50,     109,    109,    51,     99,  | 
5240  |  |     109,    51,     109,    51,     107,    109,    51,     109,    8725,  | 
5241  |  |     115,    109,    8725,   115,    50,     80,     97,     107,    80,  | 
5242  |  |     97,     77,     80,     97,     71,     80,     97,     114,    97,  | 
5243  |  |     100,    114,    97,     100,    8725,   115,    114,    97,     100,  | 
5244  |  |     8725,   115,    50,     112,    115,    110,    115,    956,    115,  | 
5245  |  |     109,    115,    112,    86,     110,    86,     956,    86,     109,  | 
5246  |  |     86,     107,    86,     77,     86,     112,    87,     110,    87,  | 
5247  |  |     956,    87,     109,    87,     107,    87,     77,     87,     107,  | 
5248  |  |     937,    77,     937,    97,     46,     109,    46,     66,     113,  | 
5249  |  |     99,     99,     99,     100,    67,     8725,   107,    103,    67,  | 
5250  |  |     111,    46,     100,    66,     71,     121,    104,    97,     72,  | 
5251  |  |     80,     105,    110,    75,     75,     75,     77,     107,    116,  | 
5252  |  |     108,    109,    108,    110,    108,    111,    103,    108,    120,  | 
5253  |  |     109,    98,     109,    105,    108,    109,    111,    108,    80,  | 
5254  |  |     72,     112,    46,     109,    46,     80,     80,     77,     80,  | 
5255  |  |     82,     115,    114,    83,     118,    87,     98,     86,     8725,  | 
5256  |  |     109,    65,     8725,   109,    49,     26085,  50,     26085,  51,  | 
5257  |  |     26085,  52,     26085,  53,     26085,  54,     26085,  55,     26085,  | 
5258  |  |     56,     26085,  57,     26085,  49,     48,     26085,  49,     49,  | 
5259  |  |     26085,  49,     50,     26085,  49,     51,     26085,  49,     52,  | 
5260  |  |     26085,  49,     53,     26085,  49,     54,     26085,  49,     55,  | 
5261  |  |     26085,  49,     56,     26085,  49,     57,     26085,  50,     48,  | 
5262  |  |     26085,  50,     49,     26085,  50,     50,     26085,  50,     51,  | 
5263  |  |     26085,  50,     52,     26085,  50,     53,     26085,  50,     54,  | 
5264  |  |     26085,  50,     55,     26085,  50,     56,     26085,  50,     57,  | 
5265  |  |     26085,  51,     48,     26085,  51,     49,     26085,  103,    97,  | 
5266  |  |     108,    1098,   1100,   42863,  67,     70,     81,     294,    339,  | 
5267  |  |     42791,  43831,  619,    43858,  653,    35912,  26356,  36554,  36040,  | 
5268  |  |     28369,  20018,  21477,  40860,  40860,  22865,  37329,  21895,  22856,  | 
5269  |  |     25078,  30313,  32645,  34367,  34746,  35064,  37007,  27138,  27931,  | 
5270  |  |     28889,  29662,  33853,  37226,  39409,  20098,  21365,  27396,  29211,  | 
5271  |  |     34349,  40478,  23888,  28651,  34253,  35172,  25289,  33240,  34847,  | 
5272  |  |     24266,  26391,  28010,  29436,  37070,  20358,  20919,  21214,  25796,  | 
5273  |  |     27347,  29200,  30439,  32769,  34310,  34396,  36335,  38706,  39791,  | 
5274  |  |     40442,  30860,  31103,  32160,  33737,  37636,  40575,  35542,  22751,  | 
5275  |  |     24324,  31840,  32894,  29282,  30922,  36034,  38647,  22744,  23650,  | 
5276  |  |     27155,  28122,  28431,  32047,  32311,  38475,  21202,  32907,  20956,  | 
5277  |  |     20940,  31260,  32190,  33777,  38517,  35712,  25295,  27138,  35582,  | 
5278  |  |     20025,  23527,  24594,  29575,  30064,  21271,  30971,  20415,  24489,  | 
5279  |  |     19981,  27852,  25976,  32034,  21443,  22622,  30465,  33865,  35498,  | 
5280  |  |     27578,  36784,  27784,  25342,  33509,  25504,  30053,  20142,  20841,  | 
5281  |  |     20937,  26753,  31975,  33391,  35538,  37327,  21237,  21570,  22899,  | 
5282  |  |     24300,  26053,  28670,  31018,  38317,  39530,  40599,  40654,  21147,  | 
5283  |  |     26310,  27511,  36706,  24180,  24976,  25088,  25754,  28451,  29001,  | 
5284  |  |     29833,  31178,  32244,  32879,  36646,  34030,  36899,  37706,  21015,  | 
5285  |  |     21155,  21693,  28872,  35010,  35498,  24265,  24565,  25467,  27566,  | 
5286  |  |     31806,  29557,  20196,  22265,  23527,  23994,  24604,  29618,  29801,  | 
5287  |  |     32666,  32838,  37428,  38646,  38728,  38936,  20363,  31150,  37300,  | 
5288  |  |     38584,  24801,  20102,  20698,  23534,  23615,  26009,  27138,  29134,  | 
5289  |  |     30274,  34044,  36988,  40845,  26248,  38446,  21129,  26491,  26611,  | 
5290  |  |     27969,  28316,  29705,  30041,  30827,  32016,  39006,  20845,  25134,  | 
5291  |  |     38520,  20523,  23833,  28138,  36650,  24459,  24900,  26647,  29575,  | 
5292  |  |     38534,  21033,  21519,  23653,  26131,  26446,  26792,  27877,  29702,  | 
5293  |  |     30178,  32633,  35023,  35041,  37324,  38626,  21311,  28346,  21533,  | 
5294  |  |     29136,  29848,  34298,  38563,  40023,  40607,  26519,  28107,  33256,  | 
5295  |  |     31435,  31520,  31890,  29376,  28825,  35672,  20160,  33590,  21050,  | 
5296  |  |     20999,  24230,  25299,  31958,  23429,  27934,  26292,  36667,  34892,  | 
5297  |  |     38477,  35211,  24275,  20800,  21952,  22618,  26228,  20958,  29482,  | 
5298  |  |     30410,  31036,  31070,  31077,  31119,  38742,  31934,  32701,  34322,  | 
5299  |  |     35576,  36920,  37117,  39151,  39164,  39208,  40372,  37086,  38583,  | 
5300  |  |     20398,  20711,  20813,  21193,  21220,  21329,  21917,  22022,  22120,  | 
5301  |  |     22592,  22696,  23652,  23662,  24724,  24936,  24974,  25074,  25935,  | 
5302  |  |     26082,  26257,  26757,  28023,  28186,  28450,  29038,  29227,  29730,  | 
5303  |  |     30865,  31038,  31049,  31048,  31056,  31062,  31069,  31117,  31118,  | 
5304  |  |     31296,  31361,  31680,  32244,  32265,  32321,  32626,  32773,  33261,  | 
5305  |  |     33401,  33401,  33879,  35088,  35222,  35585,  35641,  36051,  36104,  | 
5306  |  |     36790,  36920,  38627,  38911,  38971,  24693,  148206, 33304,  20006,  | 
5307  |  |     20917,  20840,  20352,  20805,  20864,  21191,  21242,  21917,  21845,  | 
5308  |  |     21913,  21986,  22618,  22707,  22852,  22868,  23138,  23336,  24274,  | 
5309  |  |     24281,  24425,  24493,  24792,  24910,  24840,  24974,  24928,  25074,  | 
5310  |  |     25140,  25540,  25628,  25682,  25942,  26228,  26391,  26395,  26454,  | 
5311  |  |     27513,  27578,  27969,  28379,  28363,  28450,  28702,  29038,  30631,  | 
5312  |  |     29237,  29359,  29482,  29809,  29958,  30011,  30237,  30239,  30410,  | 
5313  |  |     30427,  30452,  30538,  30528,  30924,  31409,  31680,  31867,  32091,  | 
5314  |  |     32244,  32574,  32773,  33618,  33775,  34681,  35137,  35206,  35222,  | 
5315  |  |     35519,  35576,  35531,  35585,  35582,  35565,  35641,  35722,  36104,  | 
5316  |  |     36664,  36978,  37273,  37494,  38524,  38627,  38742,  38875,  38911,  | 
5317  |  |     38923,  38971,  39698,  40860,  141386, 141380, 144341, 15261,  16408,  | 
5318  |  |     16441,  152137, 154832, 163539, 40771,  40846,  102,    102,    102,  | 
5319  |  |     105,    102,    108,    102,    102,    105,    102,    102,    108,  | 
5320  |  |     115,    116,    115,    116,    1396,   1398,   1396,   1381,   1396,  | 
5321  |  |     1387,   1406,   1398,   1396,   1389,   1497,   1460,   1522,   1463,  | 
5322  |  |     1506,   1488,   1491,   1492,   1499,   1500,   1501,   1512,   1514,  | 
5323  |  |     43,     1513,   1473,   1513,   1474,   1513,   1468,   1473,   1513,  | 
5324  |  |     1468,   1474,   1488,   1463,   1488,   1464,   1488,   1468,   1489,  | 
5325  |  |     1468,   1490,   1468,   1491,   1468,   1492,   1468,   1493,   1468,  | 
5326  |  |     1494,   1468,   1496,   1468,   1497,   1468,   1498,   1468,   1499,  | 
5327  |  |     1468,   1500,   1468,   1502,   1468,   1504,   1468,   1505,   1468,  | 
5328  |  |     1507,   1468,   1508,   1468,   1510,   1468,   1511,   1468,   1512,  | 
5329  |  |     1468,   1513,   1468,   1514,   1468,   1493,   1465,   1489,   1471,  | 
5330  |  |     1499,   1471,   1508,   1471,   1488,   1500,   1649,   1649,   1659,  | 
5331  |  |     1659,   1659,   1659,   1662,   1662,   1662,   1662,   1664,   1664,  | 
5332  |  |     1664,   1664,   1658,   1658,   1658,   1658,   1663,   1663,   1663,  | 
5333  |  |     1663,   1657,   1657,   1657,   1657,   1700,   1700,   1700,   1700,  | 
5334  |  |     1702,   1702,   1702,   1702,   1668,   1668,   1668,   1668,   1667,  | 
5335  |  |     1667,   1667,   1667,   1670,   1670,   1670,   1670,   1671,   1671,  | 
5336  |  |     1671,   1671,   1677,   1677,   1676,   1676,   1678,   1678,   1672,  | 
5337  |  |     1672,   1688,   1688,   1681,   1681,   1705,   1705,   1705,   1705,  | 
5338  |  |     1711,   1711,   1711,   1711,   1715,   1715,   1715,   1715,   1713,  | 
5339  |  |     1713,   1713,   1713,   1722,   1722,   1723,   1723,   1723,   1723,  | 
5340  |  |     1749,   1620,   1749,   1620,   1729,   1729,   1729,   1729,   1726,  | 
5341  |  |     1726,   1726,   1726,   1746,   1746,   1746,   1620,   1746,   1620,  | 
5342  |  |     1709,   1709,   1709,   1709,   1735,   1735,   1734,   1734,   1736,  | 
5343  |  |     1736,   1735,   1652,   1739,   1739,   1733,   1733,   1737,   1737,  | 
5344  |  |     1744,   1744,   1744,   1744,   1609,   1609,   1610,   1620,   1575,  | 
5345  |  |     1610,   1620,   1575,   1610,   1620,   1749,   1610,   1620,   1749,  | 
5346  |  |     1610,   1620,   1608,   1610,   1620,   1608,   1610,   1620,   1735,  | 
5347  |  |     1610,   1620,   1735,   1610,   1620,   1734,   1610,   1620,   1734,  | 
5348  |  |     1610,   1620,   1736,   1610,   1620,   1736,   1610,   1620,   1744,  | 
5349  |  |     1610,   1620,   1744,   1610,   1620,   1744,   1610,   1620,   1609,  | 
5350  |  |     1610,   1620,   1609,   1610,   1620,   1609,   1740,   1740,   1740,  | 
5351  |  |     1740,   1610,   1620,   1580,   1610,   1620,   1581,   1610,   1620,  | 
5352  |  |     1605,   1610,   1620,   1609,   1610,   1620,   1610,   1576,   1580,  | 
5353  |  |     1576,   1581,   1576,   1582,   1576,   1605,   1576,   1609,   1576,  | 
5354  |  |     1610,   1578,   1580,   1578,   1581,   1578,   1582,   1578,   1605,  | 
5355  |  |     1578,   1609,   1578,   1610,   1579,   1580,   1579,   1605,   1579,  | 
5356  |  |     1609,   1579,   1610,   1580,   1581,   1580,   1605,   1581,   1580,  | 
5357  |  |     1581,   1605,   1582,   1580,   1582,   1581,   1582,   1605,   1587,  | 
5358  |  |     1580,   1587,   1581,   1587,   1582,   1587,   1605,   1589,   1581,  | 
5359  |  |     1589,   1605,   1590,   1580,   1590,   1581,   1590,   1582,   1590,  | 
5360  |  |     1605,   1591,   1581,   1591,   1605,   1592,   1605,   1593,   1580,  | 
5361  |  |     1593,   1605,   1594,   1580,   1594,   1605,   1601,   1580,   1601,  | 
5362  |  |     1581,   1601,   1582,   1601,   1605,   1601,   1609,   1601,   1610,  | 
5363  |  |     1602,   1581,   1602,   1605,   1602,   1609,   1602,   1610,   1603,  | 
5364  |  |     1575,   1603,   1580,   1603,   1581,   1603,   1582,   1603,   1604,  | 
5365  |  |     1603,   1605,   1603,   1609,   1603,   1610,   1604,   1580,   1604,  | 
5366  |  |     1581,   1604,   1582,   1604,   1605,   1604,   1609,   1604,   1610,  | 
5367  |  |     1605,   1580,   1605,   1581,   1605,   1582,   1605,   1605,   1605,  | 
5368  |  |     1609,   1605,   1610,   1606,   1580,   1606,   1581,   1606,   1582,  | 
5369  |  |     1606,   1605,   1606,   1609,   1606,   1610,   1607,   1580,   1607,  | 
5370  |  |     1605,   1607,   1609,   1607,   1610,   1610,   1580,   1610,   1581,  | 
5371  |  |     1610,   1582,   1610,   1605,   1610,   1609,   1610,   1610,   1584,  | 
5372  |  |     1648,   1585,   1648,   1609,   1648,   32,     1612,   1617,   32,  | 
5373  |  |     1613,   1617,   32,     1614,   1617,   32,     1615,   1617,   32,  | 
5374  |  |     1616,   1617,   32,     1617,   1648,   1610,   1620,   1585,   1610,  | 
5375  |  |     1620,   1586,   1610,   1620,   1605,   1610,   1620,   1606,   1610,  | 
5376  |  |     1620,   1609,   1610,   1620,   1610,   1576,   1585,   1576,   1586,  | 
5377  |  |     1576,   1605,   1576,   1606,   1576,   1609,   1576,   1610,   1578,  | 
5378  |  |     1585,   1578,   1586,   1578,   1605,   1578,   1606,   1578,   1609,  | 
5379  |  |     1578,   1610,   1579,   1585,   1579,   1586,   1579,   1605,   1579,  | 
5380  |  |     1606,   1579,   1609,   1579,   1610,   1601,   1609,   1601,   1610,  | 
5381  |  |     1602,   1609,   1602,   1610,   1603,   1575,   1603,   1604,   1603,  | 
5382  |  |     1605,   1603,   1609,   1603,   1610,   1604,   1605,   1604,   1609,  | 
5383  |  |     1604,   1610,   1605,   1575,   1605,   1605,   1606,   1585,   1606,  | 
5384  |  |     1586,   1606,   1605,   1606,   1606,   1606,   1609,   1606,   1610,  | 
5385  |  |     1609,   1648,   1610,   1585,   1610,   1586,   1610,   1605,   1610,  | 
5386  |  |     1606,   1610,   1609,   1610,   1610,   1610,   1620,   1580,   1610,  | 
5387  |  |     1620,   1581,   1610,   1620,   1582,   1610,   1620,   1605,   1610,  | 
5388  |  |     1620,   1607,   1576,   1580,   1576,   1581,   1576,   1582,   1576,  | 
5389  |  |     1605,   1576,   1607,   1578,   1580,   1578,   1581,   1578,   1582,  | 
5390  |  |     1578,   1605,   1578,   1607,   1579,   1605,   1580,   1581,   1580,  | 
5391  |  |     1605,   1581,   1580,   1581,   1605,   1582,   1580,   1582,   1605,  | 
5392  |  |     1587,   1580,   1587,   1581,   1587,   1582,   1587,   1605,   1589,  | 
5393  |  |     1581,   1589,   1582,   1589,   1605,   1590,   1580,   1590,   1581,  | 
5394  |  |     1590,   1582,   1590,   1605,   1591,   1581,   1592,   1605,   1593,  | 
5395  |  |     1580,   1593,   1605,   1594,   1580,   1594,   1605,   1601,   1580,  | 
5396  |  |     1601,   1581,   1601,   1582,   1601,   1605,   1602,   1581,   1602,  | 
5397  |  |     1605,   1603,   1580,   1603,   1581,   1603,   1582,   1603,   1604,  | 
5398  |  |     1603,   1605,   1604,   1580,   1604,   1581,   1604,   1582,   1604,  | 
5399  |  |     1605,   1604,   1607,   1605,   1580,   1605,   1581,   1605,   1582,  | 
5400  |  |     1605,   1605,   1606,   1580,   1606,   1581,   1606,   1582,   1606,  | 
5401  |  |     1605,   1606,   1607,   1607,   1580,   1607,   1605,   1607,   1648,  | 
5402  |  |     1610,   1580,   1610,   1581,   1610,   1582,   1610,   1605,   1610,  | 
5403  |  |     1607,   1610,   1620,   1605,   1610,   1620,   1607,   1576,   1605,  | 
5404  |  |     1576,   1607,   1578,   1605,   1578,   1607,   1579,   1605,   1579,  | 
5405  |  |     1607,   1587,   1605,   1587,   1607,   1588,   1605,   1588,   1607,  | 
5406  |  |     1603,   1604,   1603,   1605,   1604,   1605,   1606,   1605,   1606,  | 
5407  |  |     1607,   1610,   1605,   1610,   1607,   1600,   1614,   1617,   1600,  | 
5408  |  |     1615,   1617,   1600,   1616,   1617,   1591,   1609,   1591,   1610,  | 
5409  |  |     1593,   1609,   1593,   1610,   1594,   1609,   1594,   1610,   1587,  | 
5410  |  |     1609,   1587,   1610,   1588,   1609,   1588,   1610,   1581,   1609,  | 
5411  |  |     1581,   1610,   1580,   1609,   1580,   1610,   1582,   1609,   1582,  | 
5412  |  |     1610,   1589,   1609,   1589,   1610,   1590,   1609,   1590,   1610,  | 
5413  |  |     1588,   1580,   1588,   1581,   1588,   1582,   1588,   1605,   1588,  | 
5414  |  |     1585,   1587,   1585,   1589,   1585,   1590,   1585,   1591,   1609,  | 
5415  |  |     1591,   1610,   1593,   1609,   1593,   1610,   1594,   1609,   1594,  | 
5416  |  |     1610,   1587,   1609,   1587,   1610,   1588,   1609,   1588,   1610,  | 
5417  |  |     1581,   1609,   1581,   1610,   1580,   1609,   1580,   1610,   1582,  | 
5418  |  |     1609,   1582,   1610,   1589,   1609,   1589,   1610,   1590,   1609,  | 
5419  |  |     1590,   1610,   1588,   1580,   1588,   1581,   1588,   1582,   1588,  | 
5420  |  |     1605,   1588,   1585,   1587,   1585,   1589,   1585,   1590,   1585,  | 
5421  |  |     1588,   1580,   1588,   1581,   1588,   1582,   1588,   1605,   1587,  | 
5422  |  |     1607,   1588,   1607,   1591,   1605,   1587,   1580,   1587,   1581,  | 
5423  |  |     1587,   1582,   1588,   1580,   1588,   1581,   1588,   1582,   1591,  | 
5424  |  |     1605,   1592,   1605,   1575,   1611,   1575,   1611,   1578,   1580,  | 
5425  |  |     1605,   1578,   1581,   1580,   1578,   1581,   1580,   1578,   1581,  | 
5426  |  |     1605,   1578,   1582,   1605,   1578,   1605,   1580,   1578,   1605,  | 
5427  |  |     1581,   1578,   1605,   1582,   1580,   1605,   1581,   1580,   1605,  | 
5428  |  |     1581,   1581,   1605,   1610,   1581,   1605,   1609,   1587,   1581,  | 
5429  |  |     1580,   1587,   1580,   1581,   1587,   1580,   1609,   1587,   1605,  | 
5430  |  |     1581,   1587,   1605,   1581,   1587,   1605,   1580,   1587,   1605,  | 
5431  |  |     1605,   1587,   1605,   1605,   1589,   1581,   1581,   1589,   1581,  | 
5432  |  |     1581,   1589,   1605,   1605,   1588,   1581,   1605,   1588,   1581,  | 
5433  |  |     1605,   1588,   1580,   1610,   1588,   1605,   1582,   1588,   1605,  | 
5434  |  |     1582,   1588,   1605,   1605,   1588,   1605,   1605,   1590,   1581,  | 
5435  |  |     1609,   1590,   1582,   1605,   1590,   1582,   1605,   1591,   1605,  | 
5436  |  |     1581,   1591,   1605,   1581,   1591,   1605,   1605,   1591,   1605,  | 
5437  |  |     1610,   1593,   1580,   1605,   1593,   1605,   1605,   1593,   1605,  | 
5438  |  |     1605,   1593,   1605,   1609,   1594,   1605,   1605,   1594,   1605,  | 
5439  |  |     1610,   1594,   1605,   1609,   1601,   1582,   1605,   1601,   1582,  | 
5440  |  |     1605,   1602,   1605,   1581,   1602,   1605,   1605,   1604,   1581,  | 
5441  |  |     1605,   1604,   1581,   1610,   1604,   1581,   1609,   1604,   1580,  | 
5442  |  |     1580,   1604,   1580,   1580,   1604,   1582,   1605,   1604,   1582,  | 
5443  |  |     1605,   1604,   1605,   1581,   1604,   1605,   1581,   1605,   1581,  | 
5444  |  |     1580,   1605,   1581,   1605,   1605,   1581,   1610,   1605,   1580,  | 
5445  |  |     1581,   1605,   1580,   1605,   1605,   1582,   1580,   1605,   1582,  | 
5446  |  |     1605,   1605,   1580,   1582,   1607,   1605,   1580,   1607,   1605,  | 
5447  |  |     1605,   1606,   1581,   1605,   1606,   1581,   1609,   1606,   1580,  | 
5448  |  |     1605,   1606,   1580,   1605,   1606,   1580,   1609,   1606,   1605,  | 
5449  |  |     1610,   1606,   1605,   1609,   1610,   1605,   1605,   1610,   1605,  | 
5450  |  |     1605,   1576,   1582,   1610,   1578,   1580,   1610,   1578,   1580,  | 
5451  |  |     1609,   1578,   1582,   1610,   1578,   1582,   1609,   1578,   1605,  | 
5452  |  |     1610,   1578,   1605,   1609,   1580,   1605,   1610,   1580,   1581,  | 
5453  |  |     1609,   1580,   1605,   1609,   1587,   1582,   1609,   1589,   1581,  | 
5454  |  |     1610,   1588,   1581,   1610,   1590,   1581,   1610,   1604,   1580,  | 
5455  |  |     1610,   1604,   1605,   1610,   1610,   1581,   1610,   1610,   1580,  | 
5456  |  |     1610,   1610,   1605,   1610,   1605,   1605,   1610,   1602,   1605,  | 
5457  |  |     1610,   1606,   1581,   1610,   1602,   1605,   1581,   1604,   1581,  | 
5458  |  |     1605,   1593,   1605,   1610,   1603,   1605,   1610,   1606,   1580,  | 
5459  |  |     1581,   1605,   1582,   1610,   1604,   1580,   1605,   1603,   1605,  | 
5460  |  |     1605,   1604,   1580,   1605,   1606,   1580,   1581,   1580,   1581,  | 
5461  |  |     1610,   1581,   1580,   1610,   1605,   1580,   1610,   1601,   1605,  | 
5462  |  |     1610,   1576,   1581,   1610,   1603,   1605,   1605,   1593,   1580,  | 
5463  |  |     1605,   1589,   1605,   1605,   1587,   1582,   1610,   1606,   1580,  | 
5464  |  |     1610,   1589,   1604,   1746,   1602,   1604,   1746,   1575,   1604,  | 
5465  |  |     1604,   1607,   1575,   1603,   1576,   1585,   1605,   1581,   1605,  | 
5466  |  |     1583,   1589,   1604,   1593,   1605,   1585,   1587,   1608,   1604,  | 
5467  |  |     1593,   1604,   1610,   1607,   1608,   1587,   1604,   1605,   1589,  | 
5468  |  |     1604,   1609,   1589,   1604,   1609,   32,     1575,   1604,   1604,  | 
5469  |  |     1607,   32,     1593,   1604,   1610,   1607,   32,     1608,   1587,  | 
5470  |  |     1604,   1605,   1580,   1604,   32,     1580,   1604,   1575,   1604,  | 
5471  |  |     1607,   1585,   1740,   1575,   1604,   44,     12289,  12290,  58,  | 
5472  |  |     59,     33,     63,     12310,  12311,  46,     46,     46,     46,  | 
5473  |  |     46,     8212,   8211,   95,     95,     40,     41,     123,    125,  | 
5474  |  |     12308,  12309,  12304,  12305,  12298,  12299,  12296,  12297,  12300,  | 
5475  |  |     12301,  12302,  12303,  91,     93,     32,     773,    32,     773,  | 
5476  |  |     32,     773,    32,     773,    95,     95,     95,     44,     12289,  | 
5477  |  |     46,     59,     58,     63,     33,     8212,   40,     41,     123,  | 
5478  |  |     125,    12308,  12309,  35,     38,     42,     43,     45,     60,  | 
5479  |  |     62,     61,     92,     36,     37,     64,     32,     1611,   1600,  | 
5480  |  |     1611,   32,     1612,   32,     1613,   32,     1614,   1600,   1614,  | 
5481  |  |     32,     1615,   1600,   1615,   32,     1616,   1600,   1616,   32,  | 
5482  |  |     1617,   1600,   1617,   32,     1618,   1600,   1618,   1569,   1575,  | 
5483  |  |     1619,   1575,   1619,   1575,   1620,   1575,   1620,   1608,   1620,  | 
5484  |  |     1608,   1620,   1575,   1621,   1575,   1621,   1610,   1620,   1610,  | 
5485  |  |     1620,   1610,   1620,   1610,   1620,   1575,   1575,   1576,   1576,  | 
5486  |  |     1576,   1576,   1577,   1577,   1578,   1578,   1578,   1578,   1579,  | 
5487  |  |     1579,   1579,   1579,   1580,   1580,   1580,   1580,   1581,   1581,  | 
5488  |  |     1581,   1581,   1582,   1582,   1582,   1582,   1583,   1583,   1584,  | 
5489  |  |     1584,   1585,   1585,   1586,   1586,   1587,   1587,   1587,   1587,  | 
5490  |  |     1588,   1588,   1588,   1588,   1589,   1589,   1589,   1589,   1590,  | 
5491  |  |     1590,   1590,   1590,   1591,   1591,   1591,   1591,   1592,   1592,  | 
5492  |  |     1592,   1592,   1593,   1593,   1593,   1593,   1594,   1594,   1594,  | 
5493  |  |     1594,   1601,   1601,   1601,   1601,   1602,   1602,   1602,   1602,  | 
5494  |  |     1603,   1603,   1603,   1603,   1604,   1604,   1604,   1604,   1605,  | 
5495  |  |     1605,   1605,   1605,   1606,   1606,   1606,   1606,   1607,   1607,  | 
5496  |  |     1607,   1607,   1608,   1608,   1609,   1609,   1610,   1610,   1610,  | 
5497  |  |     1610,   1604,   1575,   1619,   1604,   1575,   1619,   1604,   1575,  | 
5498  |  |     1620,   1604,   1575,   1620,   1604,   1575,   1621,   1604,   1575,  | 
5499  |  |     1621,   1604,   1575,   1604,   1575,   33,     34,     35,     36,  | 
5500  |  |     37,     38,     39,     40,     41,     42,     43,     44,     45,  | 
5501  |  |     46,     47,     48,     49,     50,     51,     52,     53,     54,  | 
5502  |  |     55,     56,     57,     58,     59,     60,     61,     62,     63,  | 
5503  |  |     64,     65,     66,     67,     68,     69,     70,     71,     72,  | 
5504  |  |     73,     74,     75,     76,     77,     78,     79,     80,     81,  | 
5505  |  |     82,     83,     84,     85,     86,     87,     88,     89,     90,  | 
5506  |  |     91,     92,     93,     94,     95,     96,     97,     98,     99,  | 
5507  |  |     100,    101,    102,    103,    104,    105,    106,    107,    108,  | 
5508  |  |     109,    110,    111,    112,    113,    114,    115,    116,    117,  | 
5509  |  |     118,    119,    120,    121,    122,    123,    124,    125,    126,  | 
5510  |  |     10629,  10630,  12290,  12300,  12301,  12289,  12539,  12530,  12449,  | 
5511  |  |     12451,  12453,  12455,  12457,  12515,  12517,  12519,  12483,  12540,  | 
5512  |  |     12450,  12452,  12454,  12456,  12458,  12459,  12461,  12463,  12465,  | 
5513  |  |     12467,  12469,  12471,  12473,  12475,  12477,  12479,  12481,  12484,  | 
5514  |  |     12486,  12488,  12490,  12491,  12492,  12493,  12494,  12495,  12498,  | 
5515  |  |     12501,  12504,  12507,  12510,  12511,  12512,  12513,  12514,  12516,  | 
5516  |  |     12518,  12520,  12521,  12522,  12523,  12524,  12525,  12527,  12531,  | 
5517  |  |     12441,  12442,  4448,   4352,   4353,   4522,   4354,   4524,   4525,  | 
5518  |  |     4355,   4356,   4357,   4528,   4529,   4530,   4531,   4532,   4533,  | 
5519  |  |     4378,   4358,   4359,   4360,   4385,   4361,   4362,   4363,   4364,  | 
5520  |  |     4365,   4366,   4367,   4368,   4369,   4370,   4449,   4450,   4451,  | 
5521  |  |     4452,   4453,   4454,   4455,   4456,   4457,   4458,   4459,   4460,  | 
5522  |  |     4461,   4462,   4463,   4464,   4465,   4466,   4467,   4468,   4469,  | 
5523  |  |     162,    163,    172,    32,     772,    166,    165,    8361,   9474,  | 
5524  |  |     8592,   8593,   8594,   8595,   9632,   9675,   720,    721,    230,  | 
5525  |  |     665,    595,    675,    43878,  677,    676,    598,    599,    7569,  | 
5526  |  |     600,    606,    681,    612,    610,    608,    667,    295,    668,  | 
5527  |  |     615,    644,    682,    683,    620,    122628, 42894,  622,    122629,  | 
5528  |  |     654,    122630, 248,    630,    631,    113,    634,    122632, 637,  | 
5529  |  |     638,    640,    680,    678,    43879,  679,    648,    11377,  655,  | 
5530  |  |     673,    674,    664,    448,    449,    450,    122634, 122654, 69785,  | 
5531  |  |     69818,  69787,  69818,  69797,  69818,  69937,  69927,  69938,  69927,  | 
5532  |  |     70471,  70462,  70471,  70487,  70841,  70842,  70841,  70832,  70841,  | 
5533  |  |     70845,  71096,  71087,  71097,  71087,  71989,  71984,  119127, 119141,  | 
5534  |  |     119128, 119141, 119128, 119141, 119150, 119128, 119141, 119151, 119128,  | 
5535  |  |     119141, 119152, 119128, 119141, 119153, 119128, 119141, 119154, 119225,  | 
5536  |  |     119141, 119226, 119141, 119225, 119141, 119150, 119226, 119141, 119150,  | 
5537  |  |     119225, 119141, 119151, 119226, 119141, 119151, 65,     66,     67,  | 
5538  |  |     68,     69,     70,     71,     72,     73,     74,     75,     76,  | 
5539  |  |     77,     78,     79,     80,     81,     82,     83,     84,     85,  | 
5540  |  |     86,     87,     88,     89,     90,     97,     98,     99,     100,  | 
5541  |  |     101,    102,    103,    104,    105,    106,    107,    108,    109,  | 
5542  |  |     110,    111,    112,    113,    114,    115,    116,    117,    118,  | 
5543  |  |     119,    120,    121,    122,    65,     66,     67,     68,     69,  | 
5544  |  |     70,     71,     72,     73,     74,     75,     76,     77,     78,  | 
5545  |  |     79,     80,     81,     82,     83,     84,     85,     86,     87,  | 
5546  |  |     88,     89,     90,     97,     98,     99,     100,    101,    102,  | 
5547  |  |     103,    105,    106,    107,    108,    109,    110,    111,    112,  | 
5548  |  |     113,    114,    115,    116,    117,    118,    119,    120,    121,  | 
5549  |  |     122,    65,     66,     67,     68,     69,     70,     71,     72,  | 
5550  |  |     73,     74,     75,     76,     77,     78,     79,     80,     81,  | 
5551  |  |     82,     83,     84,     85,     86,     87,     88,     89,     90,  | 
5552  |  |     97,     98,     99,     100,    101,    102,    103,    104,    105,  | 
5553  |  |     106,    107,    108,    109,    110,    111,    112,    113,    114,  | 
5554  |  |     115,    116,    117,    118,    119,    120,    121,    122,    65,  | 
5555  |  |     67,     68,     71,     74,     75,     78,     79,     80,     81,  | 
5556  |  |     83,     84,     85,     86,     87,     88,     89,     90,     97,  | 
5557  |  |     98,     99,     100,    102,    104,    105,    106,    107,    108,  | 
5558  |  |     109,    110,    112,    113,    114,    115,    116,    117,    118,  | 
5559  |  |     119,    120,    121,    122,    65,     66,     67,     68,     69,  | 
5560  |  |     70,     71,     72,     73,     74,     75,     76,     77,     78,  | 
5561  |  |     79,     80,     81,     82,     83,     84,     85,     86,     87,  | 
5562  |  |     88,     89,     90,     97,     98,     99,     100,    101,    102,  | 
5563  |  |     103,    104,    105,    106,    107,    108,    109,    110,    111,  | 
5564  |  |     112,    113,    114,    115,    116,    117,    118,    119,    120,  | 
5565  |  |     121,    122,    65,     66,     68,     69,     70,     71,     74,  | 
5566  |  |     75,     76,     77,     78,     79,     80,     81,     83,     84,  | 
5567  |  |     85,     86,     87,     88,     89,     97,     98,     99,     100,  | 
5568  |  |     101,    102,    103,    104,    105,    106,    107,    108,    109,  | 
5569  |  |     110,    111,    112,    113,    114,    115,    116,    117,    118,  | 
5570  |  |     119,    120,    121,    122,    65,     66,     68,     69,     70,  | 
5571  |  |     71,     73,     74,     75,     76,     77,     79,     83,     84,  | 
5572  |  |     85,     86,     87,     88,     89,     97,     98,     99,     100,  | 
5573  |  |     101,    102,    103,    104,    105,    106,    107,    108,    109,  | 
5574  |  |     110,    111,    112,    113,    114,    115,    116,    117,    118,  | 
5575  |  |     119,    120,    121,    122,    65,     66,     67,     68,     69,  | 
5576  |  |     70,     71,     72,     73,     74,     75,     76,     77,     78,  | 
5577  |  |     79,     80,     81,     82,     83,     84,     85,     86,     87,  | 
5578  |  |     88,     89,     90,     97,     98,     99,     100,    101,    102,  | 
5579  |  |     103,    104,    105,    106,    107,    108,    109,    110,    111,  | 
5580  |  |     112,    113,    114,    115,    116,    117,    118,    119,    120,  | 
5581  |  |     121,    122,    65,     66,     67,     68,     69,     70,     71,  | 
5582  |  |     72,     73,     74,     75,     76,     77,     78,     79,     80,  | 
5583  |  |     81,     82,     83,     84,     85,     86,     87,     88,     89,  | 
5584  |  |     90,     97,     98,     99,     100,    101,    102,    103,    104,  | 
5585  |  |     105,    106,    107,    108,    109,    110,    111,    112,    113,  | 
5586  |  |     114,    115,    116,    117,    118,    119,    120,    121,    122,  | 
5587  |  |     65,     66,     67,     68,     69,     70,     71,     72,     73,  | 
5588  |  |     74,     75,     76,     77,     78,     79,     80,     81,     82,  | 
5589  |  |     83,     84,     85,     86,     87,     88,     89,     90,     97,  | 
5590  |  |     98,     99,     100,    101,    102,    103,    104,    105,    106,  | 
5591  |  |     107,    108,    109,    110,    111,    112,    113,    114,    115,  | 
5592  |  |     116,    117,    118,    119,    120,    121,    122,    65,     66,  | 
5593  |  |     67,     68,     69,     70,     71,     72,     73,     74,     75,  | 
5594  |  |     76,     77,     78,     79,     80,     81,     82,     83,     84,  | 
5595  |  |     85,     86,     87,     88,     89,     90,     97,     98,     99,  | 
5596  |  |     100,    101,    102,    103,    104,    105,    106,    107,    108,  | 
5597  |  |     109,    110,    111,    112,    113,    114,    115,    116,    117,  | 
5598  |  |     118,    119,    120,    121,    122,    65,     66,     67,     68,  | 
5599  |  |     69,     70,     71,     72,     73,     74,     75,     76,     77,  | 
5600  |  |     78,     79,     80,     81,     82,     83,     84,     85,     86,  | 
5601  |  |     87,     88,     89,     90,     97,     98,     99,     100,    101,  | 
5602  |  |     102,    103,    104,    105,    106,    107,    108,    109,    110,  | 
5603  |  |     111,    112,    113,    114,    115,    116,    117,    118,    119,  | 
5604  |  |     120,    121,    122,    65,     66,     67,     68,     69,     70,  | 
5605  |  |     71,     72,     73,     74,     75,     76,     77,     78,     79,  | 
5606  |  |     80,     81,     82,     83,     84,     85,     86,     87,     88,  | 
5607  |  |     89,     90,     97,     98,     99,     100,    101,    102,    103,  | 
5608  |  |     104,    105,    106,    107,    108,    109,    110,    111,    112,  | 
5609  |  |     113,    114,    115,    116,    117,    118,    119,    120,    121,  | 
5610  |  |     122,    305,    567,    913,    914,    915,    916,    917,    918,  | 
5611  |  |     919,    920,    921,    922,    923,    924,    925,    926,    927,  | 
5612  |  |     928,    929,    920,    931,    932,    933,    934,    935,    936,  | 
5613  |  |     937,    8711,   945,    946,    947,    948,    949,    950,    951,  | 
5614  |  |     952,    953,    954,    955,    956,    957,    958,    959,    960,  | 
5615  |  |     961,    962,    963,    964,    965,    966,    967,    968,    969,  | 
5616  |  |     8706,   949,    952,    954,    966,    961,    960,    913,    914,  | 
5617  |  |     915,    916,    917,    918,    919,    920,    921,    922,    923,  | 
5618  |  |     924,    925,    926,    927,    928,    929,    920,    931,    932,  | 
5619  |  |     933,    934,    935,    936,    937,    8711,   945,    946,    947,  | 
5620  |  |     948,    949,    950,    951,    952,    953,    954,    955,    956,  | 
5621  |  |     957,    958,    959,    960,    961,    962,    963,    964,    965,  | 
5622  |  |     966,    967,    968,    969,    8706,   949,    952,    954,    966,  | 
5623  |  |     961,    960,    913,    914,    915,    916,    917,    918,    919,  | 
5624  |  |     920,    921,    922,    923,    924,    925,    926,    927,    928,  | 
5625  |  |     929,    920,    931,    932,    933,    934,    935,    936,    937,  | 
5626  |  |     8711,   945,    946,    947,    948,    949,    950,    951,    952,  | 
5627  |  |     953,    954,    955,    956,    957,    958,    959,    960,    961,  | 
5628  |  |     962,    963,    964,    965,    966,    967,    968,    969,    8706,  | 
5629  |  |     949,    952,    954,    966,    961,    960,    913,    914,    915,  | 
5630  |  |     916,    917,    918,    919,    920,    921,    922,    923,    924,  | 
5631  |  |     925,    926,    927,    928,    929,    920,    931,    932,    933,  | 
5632  |  |     934,    935,    936,    937,    8711,   945,    946,    947,    948,  | 
5633  |  |     949,    950,    951,    952,    953,    954,    955,    956,    957,  | 
5634  |  |     958,    959,    960,    961,    962,    963,    964,    965,    966,  | 
5635  |  |     967,    968,    969,    8706,   949,    952,    954,    966,    961,  | 
5636  |  |     960,    913,    914,    915,    916,    917,    918,    919,    920,  | 
5637  |  |     921,    922,    923,    924,    925,    926,    927,    928,    929,  | 
5638  |  |     920,    931,    932,    933,    934,    935,    936,    937,    8711,  | 
5639  |  |     945,    946,    947,    948,    949,    950,    951,    952,    953,  | 
5640  |  |     954,    955,    956,    957,    958,    959,    960,    961,    962,  | 
5641  |  |     963,    964,    965,    966,    967,    968,    969,    8706,   949,  | 
5642  |  |     952,    954,    966,    961,    960,    988,    989,    48,     49,  | 
5643  |  |     50,     51,     52,     53,     54,     55,     56,     57,     48,  | 
5644  |  |     49,     50,     51,     52,     53,     54,     55,     56,     57,  | 
5645  |  |     48,     49,     50,     51,     52,     53,     54,     55,     56,  | 
5646  |  |     57,     48,     49,     50,     51,     52,     53,     54,     55,  | 
5647  |  |     56,     57,     48,     49,     50,     51,     52,     53,     54,  | 
5648  |  |     55,     56,     57,     1072,   1073,   1074,   1075,   1076,   1077,  | 
5649  |  |     1078,   1079,   1080,   1082,   1083,   1084,   1086,   1087,   1088,  | 
5650  |  |     1089,   1090,   1091,   1092,   1093,   1094,   1095,   1096,   1099,  | 
5651  |  |     1101,   1102,   42633,  1241,   1110,   1112,   1257,   1199,   1231,  | 
5652  |  |     1072,   1073,   1074,   1075,   1076,   1077,   1078,   1079,   1080,  | 
5653  |  |     1082,   1083,   1086,   1087,   1089,   1091,   1092,   1093,   1094,  | 
5654  |  |     1095,   1096,   1098,   1099,   1169,   1110,   1109,   1119,   1195,  | 
5655  |  |     42577,  1201,   1575,   1576,   1580,   1583,   1608,   1586,   1581,  | 
5656  |  |     1591,   1610,   1603,   1604,   1605,   1606,   1587,   1593,   1601,  | 
5657  |  |     1589,   1602,   1585,   1588,   1578,   1579,   1582,   1584,   1590,  | 
5658  |  |     1592,   1594,   1646,   1722,   1697,   1647,   1576,   1580,   1607,  | 
5659  |  |     1581,   1610,   1603,   1604,   1605,   1606,   1587,   1593,   1601,  | 
5660  |  |     1589,   1602,   1588,   1578,   1579,   1582,   1590,   1594,   1580,  | 
5661  |  |     1581,   1610,   1604,   1606,   1587,   1593,   1589,   1602,   1588,  | 
5662  |  |     1582,   1590,   1594,   1722,   1647,   1576,   1580,   1607,   1581,  | 
5663  |  |     1591,   1610,   1603,   1605,   1606,   1587,   1593,   1601,   1589,  | 
5664  |  |     1602,   1588,   1578,   1579,   1582,   1590,   1592,   1594,   1646,  | 
5665  |  |     1697,   1575,   1576,   1580,   1583,   1607,   1608,   1586,   1581,  | 
5666  |  |     1591,   1610,   1604,   1605,   1606,   1587,   1593,   1601,   1589,  | 
5667  |  |     1602,   1585,   1588,   1578,   1579,   1582,   1584,   1590,   1592,  | 
5668  |  |     1594,   1576,   1580,   1583,   1608,   1586,   1581,   1591,   1610,  | 
5669  |  |     1604,   1605,   1606,   1587,   1593,   1601,   1589,   1602,   1585,  | 
5670  |  |     1588,   1578,   1579,   1582,   1584,   1590,   1592,   1594,   48,  | 
5671  |  |     46,     48,     44,     49,     44,     50,     44,     51,     44,  | 
5672  |  |     52,     44,     53,     44,     54,     44,     55,     44,     56,  | 
5673  |  |     44,     57,     44,     40,     65,     41,     40,     66,     41,  | 
5674  |  |     40,     67,     41,     40,     68,     41,     40,     69,     41,  | 
5675  |  |     40,     70,     41,     40,     71,     41,     40,     72,     41,  | 
5676  |  |     40,     73,     41,     40,     74,     41,     40,     75,     41,  | 
5677  |  |     40,     76,     41,     40,     77,     41,     40,     78,     41,  | 
5678  |  |     40,     79,     41,     40,     80,     41,     40,     81,     41,  | 
5679  |  |     40,     82,     41,     40,     83,     41,     40,     84,     41,  | 
5680  |  |     40,     85,     41,     40,     86,     41,     40,     87,     41,  | 
5681  |  |     40,     88,     41,     40,     89,     41,     40,     90,     41,  | 
5682  |  |     12308,  83,     12309,  67,     82,     67,     68,     87,     90,  | 
5683  |  |     65,     66,     67,     68,     69,     70,     71,     72,     73,  | 
5684  |  |     74,     75,     76,     77,     78,     79,     80,     81,     82,  | 
5685  |  |     83,     84,     85,     86,     87,     88,     89,     90,     72,  | 
5686  |  |     86,     77,     86,     83,     68,     83,     83,     80,     80,  | 
5687  |  |     86,     87,     67,     77,     67,     77,     68,     77,     82,  | 
5688  |  |     68,     74,     12411,  12363,  12467,  12467,  12469,  25163,  23383,  | 
5689  |  |     21452,  12486,  12441,  20108,  22810,  35299,  22825,  20132,  26144,  | 
5690  |  |     28961,  26009,  21069,  24460,  20877,  26032,  21021,  32066,  29983,  | 
5691  |  |     36009,  22768,  21561,  28436,  25237,  25429,  19968,  19977,  36938,  | 
5692  |  |     24038,  20013,  21491,  25351,  36208,  25171,  31105,  31354,  21512,  | 
5693  |  |     28288,  26377,  26376,  30003,  21106,  21942,  37197,  12308,  26412,  | 
5694  |  |     12309,  12308,  19977,  12309,  12308,  20108,  12309,  12308,  23433,  | 
5695  |  |     12309,  12308,  28857,  12309,  12308,  25171,  12309,  12308,  30423,  | 
5696  |  |     12309,  12308,  21213,  12309,  12308,  25943,  12309,  24471,  21487,  | 
5697  |  |     48,     49,     50,     51,     52,     53,     54,     55,     56,  | 
5698  |  |     57,     20029,  20024,  20033,  131362, 20320,  20398,  20411,  20482,  | 
5699  |  |     20602,  20633,  20711,  20687,  13470,  132666, 20813,  20820,  20836,  | 
5700  |  |     20855,  132380, 13497,  20839,  20877,  132427, 20887,  20900,  20172,  | 
5701  |  |     20908,  20917,  168415, 20981,  20995,  13535,  21051,  21062,  21106,  | 
5702  |  |     21111,  13589,  21191,  21193,  21220,  21242,  21253,  21254,  21271,  | 
5703  |  |     21321,  21329,  21338,  21363,  21373,  21375,  21375,  21375,  133676,  | 
5704  |  |     28784,  21450,  21471,  133987, 21483,  21489,  21510,  21662,  21560,  | 
5705  |  |     21576,  21608,  21666,  21750,  21776,  21843,  21859,  21892,  21892,  | 
5706  |  |     21913,  21931,  21939,  21954,  22294,  22022,  22295,  22097,  22132,  | 
5707  |  |     20999,  22766,  22478,  22516,  22541,  22411,  22578,  22577,  22700,  | 
5708  |  |     136420, 22770,  22775,  22790,  22810,  22818,  22882,  136872, 136938,  | 
5709  |  |     23020,  23067,  23079,  23000,  23142,  14062,  14076,  23304,  23358,  | 
5710  |  |     23358,  137672, 23491,  23512,  23527,  23539,  138008, 23551,  23558,  | 
5711  |  |     24403,  23586,  14209,  23648,  23662,  23744,  23693,  138724, 23875,  | 
5712  |  |     138726, 23918,  23915,  23932,  24033,  24034,  14383,  24061,  24104,  | 
5713  |  |     24125,  24169,  14434,  139651, 14460,  24240,  24243,  24246,  24266,  | 
5714  |  |     172946, 24318,  140081, 140081, 33281,  24354,  24354,  14535,  144056,  | 
5715  |  |     156122, 24418,  24427,  14563,  24474,  24525,  24535,  24569,  24705,  | 
5716  |  |     14650,  14620,  24724,  141012, 24775,  24904,  24908,  24910,  24908,  | 
5717  |  |     24954,  24974,  25010,  24996,  25007,  25054,  25074,  25078,  25104,  | 
5718  |  |     25115,  25181,  25265,  25300,  25424,  142092, 25405,  25340,  25448,  | 
5719  |  |     25475,  25572,  142321, 25634,  25541,  25513,  14894,  25705,  25726,  | 
5720  |  |     25757,  25719,  14956,  25935,  25964,  143370, 26083,  26360,  26185,  | 
5721  |  |     15129,  26257,  15112,  15076,  20882,  20885,  26368,  26268,  32941,  | 
5722  |  |     17369,  26391,  26395,  26401,  26462,  26451,  144323, 15177,  26618,  | 
5723  |  |     26501,  26706,  26757,  144493, 26766,  26655,  26900,  15261,  26946,  | 
5724  |  |     27043,  27114,  27304,  145059, 27355,  15384,  27425,  145575, 27476,  | 
5725  |  |     15438,  27506,  27551,  27578,  27579,  146061, 138507, 146170, 27726,  | 
5726  |  |     146620, 27839,  27853,  27751,  27926,  27966,  28023,  27969,  28009,  | 
5727  |  |     28024,  28037,  146718, 27956,  28207,  28270,  15667,  28363,  28359,  | 
5728  |  |     147153, 28153,  28526,  147294, 147342, 28614,  28729,  28702,  28699,  | 
5729  |  |     15766,  28746,  28797,  28791,  28845,  132389, 28997,  148067, 29084,  | 
5730  |  |     148395, 29224,  29237,  29264,  149000, 29312,  29333,  149301, 149524,  | 
5731  |  |     29562,  29579,  16044,  29605,  16056,  16056,  29767,  29788,  29809,  | 
5732  |  |     29829,  29898,  16155,  29988,  150582, 30014,  150674, 30064,  139679,  | 
5733  |  |     30224,  151457, 151480, 151620, 16380,  16392,  30452,  151795, 151794,  | 
5734  |  |     151833, 151859, 30494,  30495,  30495,  30538,  16441,  30603,  16454,  | 
5735  |  |     16534,  152605, 30798,  30860,  30924,  16611,  153126, 31062,  153242,  | 
5736  |  |     153285, 31119,  31211,  16687,  31296,  31306,  31311,  153980, 154279,  | 
5737  |  |     154279, 31470,  16898,  154539, 31686,  31689,  16935,  154752, 31954,  | 
5738  |  |     17056,  31976,  31971,  32000,  155526, 32099,  17153,  32199,  32258,  | 
5739  |  |     32325,  17204,  156200, 156231, 17241,  156377, 32634,  156478, 32661,  | 
5740  |  |     32762,  32773,  156890, 156963, 32864,  157096, 32880,  144223, 17365,  | 
5741  |  |     32946,  33027,  17419,  33086,  23221,  157607, 157621, 144275, 144284,  | 
5742  |  |     33281,  33284,  36766,  17515,  33425,  33419,  33437,  21171,  33457,  | 
5743  |  |     33459,  33469,  33510,  158524, 33509,  33565,  33635,  33709,  33571,  | 
5744  |  |     33725,  33767,  33879,  33619,  33738,  33740,  33756,  158774, 159083,  | 
5745  |  |     158933, 17707,  34033,  34035,  34070,  160714, 34148,  159532, 17757,  | 
5746  |  |     17761,  159665, 159954, 17771,  34384,  34396,  34407,  34409,  34473,  | 
5747  |  |     34440,  34574,  34530,  34681,  34600,  34667,  34694,  17879,  34785,  | 
5748  |  |     34817,  17913,  34912,  34915,  161383, 35031,  35038,  17973,  35066,  | 
5749  |  |     13499,  161966, 162150, 18110,  18119,  35488,  35565,  35722,  35925,  | 
5750  |  |     162984, 36011,  36033,  36123,  36215,  163631, 133124, 36299,  36284,  | 
5751  |  |     36336,  133342, 36564,  36664,  165330, 165357, 37012,  37105,  37137,  | 
5752  |  |     165678, 37147,  37432,  37591,  37592,  37500,  37881,  37909,  166906,  | 
5753  |  |     38283,  18837,  38327,  167287, 18918,  38595,  23986,  38691,  168261,  | 
5754  |  |     168474, 19054,  19062,  38880,  168970, 19122,  169110, 38923,  38923,  | 
5755  |  |     38953,  169398, 39138,  19251,  39209,  39335,  39362,  39422,  19406,  | 
5756  |  |     170800, 39698,  40000,  40189,  19662,  19693,  40295,  172238, 19704,  | 
5757  |  |     172293, 172558, 172689, 40635,  19798,  40697,  40702,  40709,  40719,  | 
5758  |  |     40726,  40763,  173568};  | 
5759  |  |  | 
5760  |  | const uint8_t canonical_combining_class_index[4352] = { | 
5761  |  |     0,  0,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 0,  0,  | 
5762  |  |     15, 0,  0,  0,  16, 17, 18, 19, 20, 21, 22, 0,  0,  23, 0,  0,  0,  0,  0,  | 
5763  |  |     0,  0,  0,  0,  0,  0,  24, 25, 0,  0,  26, 0,  0,  0,  0,  0,  0,  0,  0,  | 
5764  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5765  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5766  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5767  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5768  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5769  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  27, 0,  28, 29, 30,  | 
5770  |  |     31, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5771  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5772  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5773  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5774  |  |     0,  0,  0,  0,  32, 0,  0,  33, 0,  0,  34, 35, 36, 0,  0,  0,  0,  0,  0,  | 
5775  |  |     37, 0,  0,  38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0,  52,  | 
5776  |  |     53, 0,  54, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5777  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5778  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5779  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5780  |  |     0,  55, 56, 0,  0,  0,  57, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5781  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5782  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5783  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5784  |  |     0,  0,  0,  0,  0,  0,  0,  58, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5785  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  59, 60, 0,  0,  0,  0,  0,  0,  0,  0,  | 
5786  |  |     0,  0,  0,  0,  0,  61, 56, 62, 0,  63, 0,  0,  0,  64, 65, 0,  0,  0,  0,  | 
5787  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5788  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5789  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5790  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5791  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5792  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5793  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5794  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5795  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5796  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5797  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5798  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5799  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5800  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5801  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5802  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5803  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5804  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5805  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5806  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5807  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5808  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5809  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5810  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5811  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5812  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5813  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5814  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5815  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5816  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5817  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5818  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5819  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5820  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5821  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5822  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5823  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5824  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5825  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5826  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5827  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5828  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5829  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5830  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5831  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5832  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5833  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5834  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5835  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5836  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5837  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5838  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5839  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5840  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5841  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5842  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5843  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5844  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5845  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5846  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5847  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5848  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5849  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5850  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5851  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5852  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5853  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5854  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5855  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5856  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5857  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5858  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5859  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5860  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5861  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5862  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5863  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5864  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5865  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5866  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5867  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5868  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5869  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5870  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5871  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5872  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5873  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5874  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5875  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5876  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5877  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5878  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5879  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5880  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5881  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5882  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5883  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5884  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5885  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5886  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5887  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5888  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5889  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5890  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5891  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5892  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5893  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5894  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5895  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5896  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5897  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5898  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5899  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5900  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5901  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5902  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5903  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5904  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5905  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5906  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5907  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5908  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5909  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5910  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5911  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5912  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5913  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5914  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5915  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5916  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5917  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5918  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5919  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5920  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5921  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5922  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5923  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5924  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5925  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5926  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5927  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5928  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5929  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5930  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5931  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5932  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5933  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5934  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5935  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5936  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5937  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5938  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5939  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5940  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5941  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5942  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5943  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5944  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5945  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5946  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5947  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5948  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5949  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5950  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5951  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5952  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5953  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5954  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5955  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5956  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5957  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5958  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5959  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5960  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5961  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5962  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5963  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5964  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5965  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5966  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5967  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5968  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5969  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5970  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5971  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5972  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5973  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5974  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5975  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5976  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5977  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5978  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5979  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5980  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5981  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5982  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5983  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5984  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5985  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5986  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5987  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5988  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5989  |  |     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  | 
5990  |  |     0};  | 
5991  |  | const uint8_t canonical_combining_class_block[67][256] = { | 
5992  |  |     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
5993  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
5994  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
5995  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
5996  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
5997  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
5998  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
5999  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6000  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6001  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6002  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  | 
6003  |  |     {230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, | 
6004  |  |      230, 230, 230, 230, 230, 230, 232, 220, 220, 220, 220, 232, 216, 220, 220,  | 
6005  |  |      220, 220, 220, 202, 202, 220, 220, 220, 220, 202, 202, 220, 220, 220, 220,  | 
6006  |  |      220, 220, 220, 220, 220, 220, 220, 1,   1,   1,   1,   1,   220, 220, 220,  | 
6007  |  |      220, 230, 230, 230, 230, 230, 230, 230, 230, 240, 230, 220, 220, 220, 230,  | 
6008  |  |      230, 230, 220, 220, 0,   230, 230, 230, 220, 220, 220, 220, 230, 232, 220,  | 
6009  |  |      220, 230, 233, 234, 234, 233, 234, 234, 233, 230, 230, 230, 230, 230, 230,  | 
6010  |  |      230, 230, 230, 230, 230, 230, 230, 0,   0,   0,   0,   0,   0,   0,   0,  | 
6011  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6012  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6013  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6014  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6015  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6016  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6017  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6018  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6019  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6020  |  |      0},  | 
6021  |  |     {0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
6022  |  |      0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6023  |  |      0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6024  |  |      0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6025  |  |      0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6026  |  |      0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230,  | 
6027  |  |      230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6028  |  |      0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6029  |  |      0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6030  |  |      0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6031  |  |      0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6032  |  |      0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  | 
6033  |  |     {0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, | 
6034  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6035  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6036  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6037  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6038  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6039  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6040  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6041  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6042  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   220, 230, 230, 230, 230,  | 
6043  |  |      220, 230, 230, 230, 222, 220, 230, 230, 230, 230, 230, 230, 220, 220, 220,  | 
6044  |  |      220, 220, 220, 230, 230, 220, 230, 230, 222, 228, 230, 10,  11,  12,  13,  | 
6045  |  |      14,  15,  16,  17,  18,  19,  19,  20,  21,  22,  0,   23,  0,   24,  25,  | 
6046  |  |      0,   230, 220, 0,   18,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6047  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6048  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6049  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6050  |  |      0},  | 
6051  |  |     {0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, | 
6052  |  |      0,   230, 230, 230, 230, 230, 230, 230, 230, 30,  31,  32,  0,   0,   0,  | 
6053  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6054  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6055  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6056  |  |      27,  28,  29,  30,  31,  32,  33,  34,  230, 230, 220, 220, 230, 230, 230,  | 
6057  |  |      230, 230, 220, 230, 230, 220, 0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6058  |  |      0,   0,   0,   0,   0,   0,   0,   35,  0,   0,   0,   0,   0,   0,   0,  | 
6059  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6060  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6061  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6062  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6063  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6064  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6065  |  |      0,   0,   0,   0,   230, 230, 230, 230, 230, 230, 230, 0,   0,   230, 230,  | 
6066  |  |      230, 230, 220, 230, 0,   0,   230, 230, 0,   220, 230, 230, 220, 0,   0,  | 
6067  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6068  |  |      0},  | 
6069  |  |     {0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, | 
6070  |  |      0,   0,   36,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6071  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6072  |  |      0,   0,   0,   230, 220, 230, 230, 220, 230, 230, 220, 220, 220, 230, 220,  | 
6073  |  |      220, 230, 220, 230, 230, 230, 220, 230, 220, 230, 220, 230, 220, 230, 230,  | 
6074  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6075  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6076  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6077  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6078  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6079  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6080  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6081  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6082  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6083  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6084  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   230, 230, 230, 230, 230,  | 
6085  |  |      230, 230, 220, 230, 0,   0,   0,   0,   0,   0,   0,   0,   0,   220, 0,  | 
6086  |  |      0},  | 
6087  |  |     {0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, | 
6088  |  |      0,   0,   0,   0,   0,   0,   0,   230, 230, 230, 230, 0,   230, 230, 230,  | 
6089  |  |      230, 230, 230, 230, 230, 230, 0,   230, 230, 230, 0,   230, 230, 230, 230,  | 
6090  |  |      230, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6091  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6092  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   220,  | 
6093  |  |      220, 220, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6094  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6095  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6096  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6097  |  |      0,   0,   230, 220, 220, 220, 230, 230, 230, 230, 0,   0,   0,   0,   0,  | 
6098  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6099  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6100  |  |      0,   0,   0,   0,   0,   0,   0,   230, 230, 230, 230, 230, 220, 220, 220,  | 
6101  |  |      220, 220, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,  | 
6102  |  |      230, 0,   220, 230, 230, 220, 230, 230, 220, 230, 230, 230, 220, 220, 220,  | 
6103  |  |      27,  28,  29,  230, 230, 230, 220, 230, 230, 220, 220, 230, 230, 230, 230,  | 
6104  |  |      230},  | 
6105  |  |     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0,   0,   0,   0,   0, 0, 0, | 
6106  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0,   0,   0,   0,   0, 0, 0,  | 
6107  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0,   7,   0,   0,   0, 0, 0,  | 
6108  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0,   0, 0, 230, 220, 230, 230, 0, 0, 0,  | 
6109  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0,   0,   0,   0,   0, 0, 0,  | 
6110  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0,   0,   0,   0,   0, 0, 0,  | 
6111  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0,   0,   0,   0,   0, 0, 0,  | 
6112  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0,   0,   0,   0,   0, 0, 0,  | 
6113  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,   0, 0, 0,   0,   0,   0,   0, 0, 0,  | 
6114  |  |      0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0,   0, 0, 0,   0,   0,   0,   0, 0, 0,  | 
6115  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0,   0,   0,   0,   0, 0, 0,  | 
6116  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 0},  | 
6117  |  |     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
6118  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6119  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6120  |  |      0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6121  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6122  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6123  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6124  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0,  | 
6125  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6126  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6127  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  | 
6128  |  |     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
6129  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6130  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6131  |  |      0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6132  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6133  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6134  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6135  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6136  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6137  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6138  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  | 
6139  |  |     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0, | 
6140  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6141  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6142  |  |      0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 84, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6143  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6144  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6145  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6146  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0, 0, 0, 7, 0, 0, 0,  | 
6147  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6148  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6149  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0},  | 
6150  |  |     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
6151  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6152  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6153  |  |      0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6154  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6155  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6156  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6157  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6158  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6159  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6160  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  | 
6161  |  |     {0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
6162  |  |      0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6163  |  |      0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6164  |  |      0,   0,   103, 103, 9,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6165  |  |      107, 107, 107, 107, 0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6166  |  |      0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6167  |  |      0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6168  |  |      0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6169  |  |      0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6170  |  |      0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6171  |  |      0,   0,   0,   0,   118, 118, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6172  |  |      0,   0,   122, 122, 122, 122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6173  |  |      0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6174  |  |      0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6175  |  |      0,   0,   0,   0},  | 
6176  |  |     {0,   0, 0,   0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0, 0, | 
6177  |  |      0,   0, 0,   0,   0,   0,   0, 0, 0,   220, 220, 0,   0,   0, 0,  | 
6178  |  |      0,   0, 0,   0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0, 0,  | 
6179  |  |      0,   0, 0,   0,   0,   0,   0, 0, 220, 0,   220, 0,   216, 0, 0,  | 
6180  |  |      0,   0, 0,   0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0, 0,  | 
6181  |  |      0,   0, 0,   0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0, 0,  | 
6182  |  |      0,   0, 0,   0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0, 0,  | 
6183  |  |      0,   0, 0,   0,   0,   0,   0, 0, 129, 130, 0,   132, 0,   0, 0,  | 
6184  |  |      0,   0, 130, 130, 130, 130, 0, 0, 130, 0,   230, 230, 9,   0, 230,  | 
6185  |  |      230, 0, 0,   0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0, 0,  | 
6186  |  |      0,   0, 0,   0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0, 0,  | 
6187  |  |      0,   0, 0,   0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0, 0,  | 
6188  |  |      0,   0, 0,   0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0, 0,  | 
6189  |  |      0,   0, 0,   220, 0,   0,   0, 0, 0,   0,   0,   0,   0,   0, 0,  | 
6190  |  |      0,   0, 0,   0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0, 0,  | 
6191  |  |      0,   0, 0,   0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0, 0,  | 
6192  |  |      0,   0, 0,   0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0, 0,  | 
6193  |  |      0},  | 
6194  |  |     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, | 
6195  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0,  | 
6196  |  |      0, 0, 0, 0, 0, 0, 0, 7, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0,  | 
6197  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0,  | 
6198  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0,  | 
6199  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, 0,  | 
6200  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0,  | 
6201  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0,  | 
6202  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0,  | 
6203  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0,  | 
6204  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  | 
6205  |  |     {0, 0, 0, 0, 0, 0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
6206  |  |      0, 0, 0, 0, 0, 0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6207  |  |      0, 0, 0, 0, 0, 0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6208  |  |      0, 0, 0, 0, 0, 0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6209  |  |      0, 0, 0, 0, 0, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6210  |  |      0, 0, 0, 0, 0, 0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6211  |  |      0, 0, 0, 0, 0, 0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6212  |  |      0, 0, 0, 0, 0, 0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6213  |  |      0, 0, 0, 0, 0, 0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6214  |  |      0, 0, 0, 0, 0, 0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6215  |  |      0, 0, 0, 0, 0, 0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6216  |  |      0, 0, 0, 0, 0, 0,   0,   0,   0, 0, 0, 0, 0, 0},  | 
6217  |  |     {0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, | 
6218  |  |      0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6219  |  |      0, 0, 0, 0, 9, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6220  |  |      0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6221  |  |      0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6222  |  |      0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6223  |  |      0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6224  |  |      0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6225  |  |      0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0,  | 
6226  |  |      0, 0, 0, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6227  |  |      0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  | 
6228  |  |     {0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
6229  |  |      0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6230  |  |      0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6231  |  |      0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6232  |  |      0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6233  |  |      0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6234  |  |      0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6235  |  |      0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6236  |  |      0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6237  |  |      0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6238  |  |      0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  | 
6239  |  |     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0, 0, 0, 0, 0, 0, | 
6240  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0, 0, 0, 0, 0, 0,  | 
6241  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 222, 230, 220, 0, 0, 0, 0, 0, 0,  | 
6242  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0, 0, 0, 0, 0, 0,  | 
6243  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0, 0, 0, 0, 0, 0,  | 
6244  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0, 0, 0, 0, 0, 0,  | 
6245  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0, 0, 0, 0, 0, 0,  | 
6246  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0, 0, 0, 0, 0, 0,  | 
6247  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0, 0, 0, 0, 0, 0,  | 
6248  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0, 0, 0, 0, 0, 0,  | 
6249  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0, 0, 0, 0, 0, 0,  | 
6250  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  | 
6251  |  |     {0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, | 
6252  |  |      0,   0,   0,   0,   0,   0,   0,   0,   230, 220, 0,   0,   0,   0,   0,  | 
6253  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6254  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6255  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6256  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6257  |  |      0,   0,   0,   0,   0,   0,   9,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6258  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   230, 230, 230,  | 
6259  |  |      230, 230, 230, 230, 230, 0,   0,   220, 0,   0,   0,   0,   0,   0,   0,  | 
6260  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6261  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6262  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   230, 230, 230, 230,  | 
6263  |  |      230, 220, 220, 220, 220, 220, 220, 230, 230, 220, 0,   220, 220, 230, 230,  | 
6264  |  |      220, 220, 230, 230, 230, 230, 230, 220, 230, 230, 230, 230, 0,   0,   0,  | 
6265  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6266  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6267  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6268  |  |      0},  | 
6269  |  |     {0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0, | 
6270  |  |      0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,  | 
6271  |  |      0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   7,   0,   0,   0,   0,  | 
6272  |  |      0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0,   0,   0,   0,   0,   0,   0,  | 
6273  |  |      0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,  | 
6274  |  |      0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 220, 230, 230, 230, 230, 230,  | 
6275  |  |      230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,  | 
6276  |  |      0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,  | 
6277  |  |      0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   9,  | 
6278  |  |      9,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,  | 
6279  |  |      0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,  | 
6280  |  |      0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,  | 
6281  |  |      0,   0,   7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   9,   9,   0,   0,   0,  | 
6282  |  |      0,   0,   0, 0, 0, 0, 0, 0, 0},  | 
6283  |  |     {0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, | 
6284  |  |      0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6285  |  |      0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6286  |  |      0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   7,   0,   0,   0,   0,  | 
6287  |  |      0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6288  |  |      0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6289  |  |      0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6290  |  |      0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6291  |  |      0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6292  |  |      0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6293  |  |      0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6294  |  |      0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6295  |  |      0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6296  |  |      0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   230, 230,  | 
6297  |  |      230, 0, 1, 220, 220, 220, 220, 220, 230, 230, 220, 220, 220, 220, 230,  | 
6298  |  |      0,   1, 1, 1,   1,   1,   1,   1,   0,   0,   0,   0,   220, 0,   0,  | 
6299  |  |      0,   0, 0, 0,   230, 0,   0,   0,   230, 230, 0,   0,   0,   0,   0,  | 
6300  |  |      0},  | 
6301  |  |     {0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, | 
6302  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6303  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6304  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6305  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6306  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6307  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6308  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6309  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6310  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6311  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6312  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6313  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   230, 230, 220,  | 
6314  |  |      230, 230, 230, 230, 230, 230, 230, 220, 230, 230, 234, 214, 220, 202, 230,  | 
6315  |  |      230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,  | 
6316  |  |      230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,  | 
6317  |  |      230, 230, 230, 230, 230, 230, 232, 228, 228, 220, 218, 230, 233, 220, 230,  | 
6318  |  |      220},  | 
6319  |  |     {0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0, | 
6320  |  |      0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,  | 
6321  |  |      0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,  | 
6322  |  |      0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,  | 
6323  |  |      0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,  | 
6324  |  |      0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,  | 
6325  |  |      0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,  | 
6326  |  |      0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,  | 
6327  |  |      0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,  | 
6328  |  |      0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,  | 
6329  |  |      0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,  | 
6330  |  |      0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,  | 
6331  |  |      0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,  | 
6332  |  |      230, 230, 1, 1, 230, 230, 230, 230, 1,   1,   1, 230, 230, 0,   0,   0,  | 
6333  |  |      0,   230, 0, 0, 0,   1,   1,   230, 220, 230, 1, 1,   220, 220, 220, 220,  | 
6334  |  |      230, 0,   0, 0, 0,   0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0},  | 
6335  |  |     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, | 
6336  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,  | 
6337  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,  | 
6338  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,  | 
6339  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,  | 
6340  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,  | 
6341  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,  | 
6342  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,  | 
6343  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,  | 
6344  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,  | 
6345  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230,  | 
6346  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  | 
6347  |  |     {0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, | 
6348  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6349  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6350  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6351  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6352  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6353  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6354  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6355  |  |      0,   0,   0,   0,   0,   0,   0,   9,   0,   0,   0,   0,   0,   0,   0,  | 
6356  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6357  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6358  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6359  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6360  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6361  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   230,  | 
6362  |  |      230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,  | 
6363  |  |      230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,  | 
6364  |  |      230},  | 
6365  |  |     {0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
6366  |  |      0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6367  |  |      0, 0, 218, 228, 232, 222, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6368  |  |      0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6369  |  |      0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6370  |  |      0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6371  |  |      0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6372  |  |      0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0,  | 
6373  |  |      0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6374  |  |      0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6375  |  |      0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6376  |  |      0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6377  |  |      0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0},  | 
6378  |  |     {0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, | 
6379  |  |      0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6380  |  |      0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6381  |  |      0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6382  |  |      0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6383  |  |      0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6384  |  |      0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   230,  | 
6385  |  |      0,   0,   0, 0, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 0,   0,  | 
6386  |  |      0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6387  |  |      0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   230, 230,  | 
6388  |  |      0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6389  |  |      0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6390  |  |      0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6391  |  |      0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6392  |  |      0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6393  |  |      230, 230, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0},  | 
6394  |  |     {0,   0,   0,   0,   0,   0,   9,   0,   0,   0,   0,   0,   0,   0,   0, | 
6395  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6396  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   9,  | 
6397  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6398  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6399  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6400  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6401  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6402  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6403  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6404  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6405  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6406  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6407  |  |      0,   9,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6408  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   230,  | 
6409  |  |      230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,  | 
6410  |  |      230, 230, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6411  |  |      0},  | 
6412  |  |     {0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
6413  |  |      0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220,  | 
6414  |  |      220, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6415  |  |      0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0,  | 
6416  |  |      0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6417  |  |      0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6418  |  |      0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6419  |  |      0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6420  |  |      0,   0,   0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0,  | 
6421  |  |      0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6422  |  |      0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6423  |  |      0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  | 
6424  |  |     {0,   0,   0, 0,   0, 0,   0, 0,   0,   0,   0, 0, 0,   0,   0, 0, 0, 0, 0, | 
6425  |  |      0,   0,   0, 0,   0, 0,   0, 0,   0,   0,   0, 0, 0,   0,   0, 0, 0, 0, 0,  | 
6426  |  |      0,   0,   0, 0,   0, 0,   0, 0,   0,   0,   0, 0, 0,   0,   0, 0, 0, 0, 0,  | 
6427  |  |      0,   0,   0, 0,   0, 0,   0, 0,   0,   0,   0, 0, 0,   0,   0, 0, 0, 0, 0,  | 
6428  |  |      0,   0,   0, 0,   0, 0,   0, 0,   0,   0,   0, 0, 0,   0,   0, 0, 0, 0, 0,  | 
6429  |  |      0,   0,   0, 0,   0, 0,   0, 0,   0,   0,   0, 0, 0,   0,   0, 0, 0, 0, 0,  | 
6430  |  |      0,   0,   0, 0,   0, 0,   0, 0,   0,   0,   0, 0, 0,   0,   0, 0, 0, 0, 0,  | 
6431  |  |      0,   0,   0, 0,   0, 0,   0, 0,   0,   0,   0, 0, 0,   0,   0, 0, 0, 0, 0,  | 
6432  |  |      0,   0,   0, 0,   0, 0,   0, 0,   0,   0,   0, 0, 0,   0,   0, 0, 0, 0, 0,  | 
6433  |  |      0,   0,   0, 0,   0, 230, 0, 230, 230, 220, 0, 0, 230, 230, 0, 0, 0, 0, 0,  | 
6434  |  |      230, 230, 0, 230, 0, 0,   0, 0,   0,   0,   0, 0, 0,   0,   0, 0, 0, 0, 0,  | 
6435  |  |      0,   0,   0, 0,   0, 0,   0, 0,   0,   0,   0, 0, 0,   0,   0, 0, 0, 0, 0,  | 
6436  |  |      0,   0,   0, 0,   0, 0,   0, 0,   0,   0,   0, 0, 0,   0,   0, 0, 0, 0, 9,  | 
6437  |  |      0,   0,   0, 0,   0, 0,   0, 0,   0},  | 
6438  |  |     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
6439  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6440  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6441  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6442  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6443  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6444  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6445  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6446  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6447  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0,  | 
6448  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  | 
6449  |  |     {0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
6450  |  |      0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6451  |  |      0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6452  |  |      0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6453  |  |      0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6454  |  |      0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6455  |  |      0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6456  |  |      0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6457  |  |      0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6458  |  |      0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6459  |  |      0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0},  | 
6460  |  |     {0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, | 
6461  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6462  |  |      0,   0,   230, 230, 230, 230, 230, 230, 230, 220, 220, 220, 220, 220, 220,  | 
6463  |  |      220, 230, 230, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6464  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6465  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6466  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6467  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6468  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6469  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6470  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6471  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6472  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6473  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6474  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6475  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6476  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6477  |  |      0},  | 
6478  |  |     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
6479  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6480  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6481  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6482  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6483  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6484  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6485  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6486  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6487  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6488  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, 0},  | 
6489  |  |     {0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
6490  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6491  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6492  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6493  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6494  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6495  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6496  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6497  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6498  |  |      0, 0, 0, 0, 0, 0, 0, 0, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6499  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0},  | 
6500  |  |     {0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, | 
6501  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6502  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6503  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6504  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6505  |  |      0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6506  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6507  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6508  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6509  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6510  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6511  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0},  | 
6512  |  |     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 220, 0, 230, 0,   0, 0,   0, | 
6513  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0,   0, 0,   0,   0, 0,   0,  | 
6514  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0,   0, 0,   230, 1, 220, 0,  | 
6515  |  |      0, 0, 0, 9, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0,   0, 0,   0,   0, 0,   0,  | 
6516  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0,   0, 0,   0,   0, 0,   0,  | 
6517  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0,   0, 0,   0,   0, 0,   0,  | 
6518  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0,   0, 0,   0,   0, 0,   0,  | 
6519  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0,   0, 0,   0,   0, 0,   0,  | 
6520  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0,   0, 0,   0,   0, 0,   0,  | 
6521  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0,   0, 0,   0,   0, 0,   0,  | 
6522  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0,   0, 0,   0,   0, 0,   0,  | 
6523  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 220, 0, 0, 0,   0, 0,   0,   0, 0,   0,  | 
6524  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0,   0, 0},  | 
6525  |  |     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0, 0, 0, 0, | 
6526  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 0, 0, 0, 0,  | 
6527  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0, 0, 0, 0,  | 
6528  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0, 0, 0, 0,  | 
6529  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0, 0, 0, 0,  | 
6530  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0, 0, 0, 0,  | 
6531  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0, 0, 0, 0,  | 
6532  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0, 0, 0, 0,  | 
6533  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0, 0, 0, 0,  | 
6534  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0, 0, 0, 0,  | 
6535  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0, 0, 0, 0,  | 
6536  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  | 
6537  |  |     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,  0, 0, 0, 0,   0,   0, 0, 0, | 
6538  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,  0, 0, 0, 0,   0,   0, 0, 0,  | 
6539  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,  0, 0, 0, 0,   0,   0, 0, 0,  | 
6540  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,  0, 0, 0, 0,   0,   0, 0, 0,  | 
6541  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,  0, 0, 0, 0,   0,   0, 0, 0,  | 
6542  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,  0, 0, 0, 0,   0,   0, 0, 0,  | 
6543  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,  0, 0, 0, 0,   0,   0, 0, 0,  | 
6544  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,  0, 0, 0, 230, 230, 0, 0, 0,  | 
6545  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,  0, 0, 0, 0,   0,   0, 0, 0,  | 
6546  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,  0, 0, 0, 0,   0,   0, 0, 0,  | 
6547  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,  0, 0, 0, 0,   0,   0, 0, 0,  | 
6548  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 220, 220},  | 
6549  |  |     {0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0,   0, | 
6550  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0,   0,  | 
6551  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0,   0,  | 
6552  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 220, 220,  | 
6553  |  |      230, 230, 230, 220, 230, 220, 220, 220, 220, 0, 0, 0, 0, 0, 0, 0, 0,   0,  | 
6554  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0,   0,  | 
6555  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0,   0,  | 
6556  |  |      0,   0,   0,   0,   230, 220, 230, 220, 0,   0, 0, 0, 0, 0, 0, 0, 0,   0,  | 
6557  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0,   0,  | 
6558  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0,   0,  | 
6559  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0,   0,  | 
6560  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0,   0,  | 
6561  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0,   0,  | 
6562  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0,   0,  | 
6563  |  |      0,   0,   0,   0},  | 
6564  |  |     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
6565  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6566  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0,  | 
6567  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6568  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,  | 
6569  |  |      0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6570  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6571  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 7, 0, 0, 0, 0, 0,  | 
6572  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6573  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6574  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  | 
6575  |  |     {230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
6576  |  |      0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6577  |  |      0,   0,   0,   0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6578  |  |      0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6579  |  |      0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6580  |  |      0,   0,   0,   0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6581  |  |      0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6582  |  |      0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6583  |  |      0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0,  | 
6584  |  |      0,   0,   0,   0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6585  |  |      0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6586  |  |      0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  | 
6587  |  |     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
6588  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6589  |  |      0, 0, 0, 0, 0, 9, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6590  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6591  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6592  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6593  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6594  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6595  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6596  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 0, 0, 0, 0, 0,  | 
6597  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  | 
6598  |  |     {0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, | 
6599  |  |      0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0,  | 
6600  |  |      0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0,  | 
6601  |  |      0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,   7,   7,   0, 0, 0,  | 
6602  |  |      0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,   0,   0,   9, 0, 0,  | 
6603  |  |      0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0,  | 
6604  |  |      0,   0,   0,   0,   0,   0, 230, 230, 230, 230, 230, 230, 230, 0, 0, 0,  | 
6605  |  |      230, 230, 230, 230, 230, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0,  | 
6606  |  |      0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0,  | 
6607  |  |      0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0,  | 
6608  |  |      0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0,  | 
6609  |  |      0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0,  | 
6610  |  |      0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0,  | 
6611  |  |      0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0,  | 
6612  |  |      0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0,  | 
6613  |  |      0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0},  | 
6614  |  |     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, | 
6615  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,  | 
6616  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 7,   0,  | 
6617  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 0,  | 
6618  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,  | 
6619  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,  | 
6620  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,  | 
6621  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,  | 
6622  |  |      0, 0, 9, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,  | 
6623  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,  | 
6624  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  | 
6625  |  |     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
6626  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6627  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6628  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6629  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6630  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6631  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6632  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,  | 
6633  |  |      7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6634  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6635  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  | 
6636  |  |     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
6637  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6638  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6639  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6640  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6641  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6642  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6643  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 7, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6644  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6645  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6646  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  | 
6647  |  |     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
6648  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0,  | 
6649  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6650  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6651  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6652  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6653  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6654  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6655  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6656  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6657  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  | 
6658  |  |     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
6659  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6660  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6661  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6662  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6663  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6664  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6665  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6666  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6667  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6668  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  | 
6669  |  |     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
6670  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6671  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 7, 0, 0, 0, 0,  | 
6672  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6673  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6674  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6675  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6676  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6677  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6678  |  |      0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6679  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  | 
6680  |  |     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
6681  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6682  |  |      0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,  | 
6683  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6684  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6685  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6686  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6687  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6688  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6689  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6690  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  | 
6691  |  |     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
6692  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6693  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6694  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6695  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6696  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6697  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6698  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6699  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6700  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6701  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  | 
6702  |  |     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
6703  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6704  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 9, 9, 0, 0,  | 
6705  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6706  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6707  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6708  |  |      0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6709  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6710  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6711  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6712  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  | 
6713  |  |     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
6714  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6715  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0,  | 
6716  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6717  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6718  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6719  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6720  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6721  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6722  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6723  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  | 
6724  |  |     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
6725  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6726  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6727  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6728  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6729  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6730  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6731  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6732  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6733  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6734  |  |      1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  | 
6735  |  |     {0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, | 
6736  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0,  | 
6737  |  |      0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 230, 230, 230, 0, 0, 0, 0, 0,  | 
6738  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0,  | 
6739  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0,  | 
6740  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0,  | 
6741  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0,  | 
6742  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0,  | 
6743  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0,  | 
6744  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0,  | 
6745  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0,  | 
6746  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0,  | 
6747  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0},  | 
6748  |  |     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
6749  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6750  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6751  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6752  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6753  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6754  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6755  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6756  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6757  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6758  |  |      6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  | 
6759  |  |     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
6760  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6761  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6762  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6763  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6764  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6765  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6766  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6767  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6768  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6769  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  | 
6770  |  |     {0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, | 
6771  |  |      0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6772  |  |      0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6773  |  |      0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6774  |  |      0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6775  |  |      0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6776  |  |      0,   0,   0,   0, 0, 216, 216, 1,   1,   1,   0,   0,   0,   226, 216, 216,  | 
6777  |  |      216, 216, 216, 0, 0, 0,   0,   0,   0,   0,   0,   220, 220, 220, 220, 220,  | 
6778  |  |      220, 220, 220, 0, 0, 230, 230, 230, 230, 230, 220, 220, 0,   0,   0,   0,  | 
6779  |  |      0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6780  |  |      0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   230, 230, 230, 230, 0,   0,  | 
6781  |  |      0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6782  |  |      0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6783  |  |      0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6784  |  |      0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6785  |  |      0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0},  | 
6786  |  |     {0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
6787  |  |      0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6788  |  |      0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6789  |  |      230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6790  |  |      0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6791  |  |      0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6792  |  |      0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6793  |  |      0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6794  |  |      0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6795  |  |      0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6796  |  |      0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
6797  |  |      0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  | 
6798  |  |     {230, 230, 230, 230, 230, 230, 230, 0,   230, 230, 230, 230, 230, 230, 230, | 
6799  |  |      230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 0,   0,   230, 230, 230,  | 
6800  |  |      230, 230, 230, 230, 0,   230, 230, 0,   230, 230, 230, 230, 230, 0,   0,  | 
6801  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6802  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6803  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6804  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6805  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6806  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6807  |  |      0,   0,   0,   0,   0,   0,   0,   0,   230, 0,   0,   0,   0,   0,   0,  | 
6808  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6809  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6810  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6811  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6812  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6813  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6814  |  |      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  | 
6815  |  |      0},  | 
6816  |  |     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, | 
6817  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,  | 
6818  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,  | 
6819  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,  | 
6820  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,  | 
6821  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,  | 
6822  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,  | 
6823  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   230, 0,  | 
6824  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,  | 
6825  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,  | 
6826  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 0,   0,  | 
6827  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  | 
6828  |  |     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0, 0, | 
6829  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0, 0,  | 
6830  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0, 0,  | 
6831  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0, 0,  | 
6832  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0, 0,  | 
6833  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0, 0,  | 
6834  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0, 0,  | 
6835  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0, 0,  | 
6836  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0, 0,  | 
6837  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0, 0,  | 
6838  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 232, 232, 220, 230, 0, 0,  | 
6839  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  | 
6840  |  |     {0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, | 
6841  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0,  | 
6842  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0,  | 
6843  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0,  | 
6844  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0,  | 
6845  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0,  | 
6846  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0,  | 
6847  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0,  | 
6848  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0,  | 
6849  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0,  | 
6850  |  |      0, 0, 0, 0, 0, 0, 0, 0, 220, 220, 220, 220, 220, 220, 220, 0, 0, 0, 0, 0,  | 
6851  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0,  | 
6852  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0},  | 
6853  |  |     {0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, | 
6854  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,  | 
6855  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,  | 
6856  |  |      0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 230, 230, 7, 0, 0, 0, 0, 0,  | 
6857  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,  | 
6858  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,  | 
6859  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,  | 
6860  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,  | 
6861  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,  | 
6862  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,  | 
6863  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,  | 
6864  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,  | 
6865  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0, 0}};  | 
6866  |  |  | 
6867  |  | const uint8_t composition_index[4352] = { | 
6868  |  |     0, 1, 2, 3, 4,  5,  6, 5, 5,  7,  5, 8,  9,  10, 5, 5, 11, 5,  5, 5, 5, 5,  | 
6869  |  |     5, 5, 5, 5, 5,  12, 5, 5, 13, 14, 5, 15, 16, 5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6870  |  |     5, 5, 5, 5, 17, 5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6871  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6872  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6873  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6874  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6875  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6876  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6877  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6878  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6879  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6880  |  |     5, 5, 5, 5, 5,  5,  5, 5, 18, 19, 5, 20, 21, 22, 5, 5, 5,  23, 5, 5, 5, 5,  | 
6881  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6882  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6883  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6884  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6885  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6886  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6887  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6888  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6889  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6890  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6891  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6892  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6893  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6894  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6895  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6896  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6897  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6898  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6899  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6900  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6901  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6902  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6903  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6904  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6905  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6906  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6907  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6908  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6909  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6910  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6911  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6912  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6913  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6914  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6915  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6916  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6917  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6918  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6919  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6920  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6921  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6922  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6923  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6924  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6925  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6926  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6927  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6928  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6929  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6930  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6931  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6932  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6933  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6934  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6935  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6936  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6937  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6938  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6939  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6940  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6941  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6942  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6943  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6944  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6945  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6946  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6947  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6948  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6949  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6950  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6951  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6952  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6953  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6954  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6955  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6956  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6957  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6958  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6959  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6960  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6961  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6962  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6963  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6964  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6965  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6966  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6967  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6968  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6969  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6970  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6971  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6972  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6973  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6974  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6975  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6976  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6977  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6978  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6979  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6980  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6981  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6982  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6983  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6984  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6985  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6986  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6987  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6988  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6989  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6990  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6991  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6992  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6993  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6994  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6995  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6996  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6997  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6998  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
6999  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7000  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7001  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7002  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7003  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7004  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7005  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7006  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7007  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7008  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7009  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7010  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7011  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7012  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7013  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7014  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7015  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7016  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7017  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7018  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7019  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7020  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7021  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7022  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7023  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7024  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7025  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7026  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7027  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7028  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7029  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7030  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7031  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7032  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7033  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7034  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7035  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7036  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7037  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7038  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7039  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7040  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7041  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7042  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7043  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7044  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7045  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7046  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7047  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7048  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7049  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7050  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7051  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7052  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7053  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7054  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7055  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7056  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7057  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7058  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7059  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7060  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7061  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7062  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7063  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7064  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,  | 
7065  |  |     5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5};  | 
7066  |  | const uint16_t composition_block[67][257] = { | 
7067  |  |     {1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1, | 
7068  |  |      1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,  | 
7069  |  |      1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,  | 
7070  |  |      1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,  | 
7071  |  |      1,   3,   5,   7,   7,   7,   39,  45,  55,  67,  101, 103, 117, 131, 161,  | 
7072  |  |      163, 173, 185, 191, 209, 241, 245, 245, 261, 275, 289, 327, 331, 343, 347,  | 
7073  |  |      365, 377, 377, 377, 377, 377, 377, 377, 409, 415, 425, 437, 471, 473, 487,  | 
7074  |  |      503, 531, 535, 545, 557, 563, 581, 613, 617, 617, 633, 647, 663, 701, 705,  | 
7075  |  |      719, 723, 743, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755,  | 
7076  |  |      755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755,  | 
7077  |  |      755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755,  | 
7078  |  |      755, 755, 755, 755, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761,  | 
7079  |  |      761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761,  | 
7080  |  |      769, 769, 771, 773, 777, 779, 779, 779, 787, 787, 787, 787, 787, 789, 789,  | 
7081  |  |      789, 789, 789, 797, 803, 805, 805, 807, 807, 807, 807, 815, 815, 815, 815,  | 
7082  |  |      815, 815, 823, 823, 825, 827, 831, 833, 833, 833, 841, 841, 841, 841, 841,  | 
7083  |  |      843, 843, 843, 843, 843, 851, 857, 859, 859, 861, 861, 861, 861, 869, 869,  | 
7084  |  |      869, 869},  | 
7085  |  |     {869, 869, 869, 877, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, | 
7086  |  |      885, 885, 885, 885, 889, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893,  | 
7087  |  |      893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893,  | 
7088  |  |      893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893,  | 
7089  |  |      893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893,  | 
7090  |  |      893, 893, 897, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901,  | 
7091  |  |      901, 903, 905, 905, 905, 905, 905, 907, 909, 909, 909, 909, 909, 909, 909,  | 
7092  |  |      911, 913, 915, 917, 917, 917, 917, 917, 917, 917, 917, 917, 917, 917, 917,  | 
7093  |  |      917, 917, 917, 917, 917, 917, 917, 917, 919, 919, 919, 919, 919, 919, 919,  | 
7094  |  |      919, 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, 919,  | 
7095  |  |      919, 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, 929, 939, 939, 939,  | 
7096  |  |      939, 939, 939, 939, 939, 939, 939, 939, 939, 939, 939, 949, 959, 959, 959,  | 
7097  |  |      959, 959, 959, 959, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961,  | 
7098  |  |      961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961,  | 
7099  |  |      961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961,  | 
7100  |  |      961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 963, 965, 965, 965, 965,  | 
7101  |  |      965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965,  | 
7102  |  |      965, 965},  | 
7103  |  |     {965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, | 
7104  |  |      965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965,  | 
7105  |  |      965, 965, 965, 965, 965, 965, 965, 965, 965, 967, 969, 971, 973, 973, 973,  | 
7106  |  |      973, 973, 975, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977,  | 
7107  |  |      977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977,  | 
7108  |  |      977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977,  | 
7109  |  |      977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977,  | 
7110  |  |      977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977,  | 
7111  |  |      977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977,  | 
7112  |  |      977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 979, 979, 979,  | 
7113  |  |      979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979,  | 
7114  |  |      979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979,  | 
7115  |  |      979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979,  | 
7116  |  |      979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979,  | 
7117  |  |      979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979,  | 
7118  |  |      979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979,  | 
7119  |  |      979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979,  | 
7120  |  |      979, 979},  | 
7121  |  |     {979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979, | 
7122  |  |      979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  | 
7123  |  |      979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  | 
7124  |  |      979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  | 
7125  |  |      979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  | 
7126  |  |      979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  | 
7127  |  |      979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  | 
7128  |  |      979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  | 
7129  |  |      979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  | 
7130  |  |      979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  | 
7131  |  |      979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  | 
7132  |  |      979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  | 
7133  |  |      979,  979,  993,  993,  993,  993,  1001, 1001, 1011, 1011, 1025, 1025,  | 
7134  |  |      1025, 1025, 1025, 1025, 1033, 1033, 1035, 1035, 1035, 1035, 1047, 1047,  | 
7135  |  |      1047, 1047, 1057, 1057, 1057, 1059, 1059, 1061, 1061, 1061, 1077, 1077,  | 
7136  |  |      1077, 1077, 1085, 1085, 1097, 1097, 1113, 1113, 1113, 1113, 1113, 1113,  | 
7137  |  |      1121, 1121, 1125, 1125, 1125, 1125, 1141, 1141, 1141, 1141, 1153, 1159,  | 
7138  |  |      1165, 1165, 1165, 1167, 1167, 1167, 1167, 1171, 1171, 1171, 1171, 1171,  | 
7139  |  |      1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171,  | 
7140  |  |      1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171,  | 
7141  |  |      1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171,  | 
7142  |  |      1171, 1171, 1171, 1171, 1171},  | 
7143  |  |     {1171, 1171, 1171, 1171, 1171, 1171, 1171, 1173, 1173, 1173, 1173, 1173, | 
7144  |  |      1173, 1173, 1173, 1173, 1173, 1177, 1177, 1177, 1179, 1179, 1185, 1189,  | 
7145  |  |      1191, 1199, 1199, 1201, 1201, 1201, 1201, 1203, 1203, 1203, 1203, 1203,  | 
7146  |  |      1211, 1211, 1211, 1211, 1213, 1213, 1213, 1213, 1215, 1215, 1217, 1217,  | 
7147  |  |      1217, 1221, 1221, 1221, 1223, 1223, 1229, 1233, 1235, 1243, 1243, 1245,  | 
7148  |  |      1245, 1245, 1245, 1247, 1247, 1247, 1247, 1247, 1255, 1255, 1255, 1255,  | 
7149  |  |      1257, 1257, 1257, 1257, 1259, 1259, 1261, 1261, 1261, 1261, 1261, 1261,  | 
7150  |  |      1261, 1261, 1261, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263,  | 
7151  |  |      1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263,  | 
7152  |  |      1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1265, 1267, 1267,  | 
7153  |  |      1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267,  | 
7154  |  |      1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267,  | 
7155  |  |      1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267,  | 
7156  |  |      1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267,  | 
7157  |  |      1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267,  | 
7158  |  |      1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267,  | 
7159  |  |      1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267,  | 
7160  |  |      1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267,  | 
7161  |  |      1267, 1269, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271,  | 
7162  |  |      1271, 1271, 1271, 1271, 1271, 1273, 1275, 1275, 1275, 1275, 1275, 1275,  | 
7163  |  |      1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275,  | 
7164  |  |      1275, 1275, 1275, 1275, 1275},  | 
7165  |  |     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
7166  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
7167  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
7168  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
7169  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
7170  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
7171  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
7172  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
7173  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
7174  |  |      0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0},  | 
7176  |  |     {1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, | 
7177  |  |      1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275,  | 
7178  |  |      1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275,  | 
7179  |  |      1275, 1275, 1275, 1275, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281,  | 
7180  |  |      1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281,  | 
7181  |  |      1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281,  | 
7182  |  |      1281, 1283, 1283, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,  | 
7183  |  |      1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,  | 
7184  |  |      1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,  | 
7185  |  |      1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,  | 
7186  |  |      1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,  | 
7187  |  |      1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,  | 
7188  |  |      1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,  | 
7189  |  |      1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,  | 
7190  |  |      1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,  | 
7191  |  |      1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,  | 
7192  |  |      1285, 1285, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287,  | 
7193  |  |      1287, 1287, 1287, 1287, 1287, 1287, 1287, 1289, 1289, 1289, 1291, 1291,  | 
7194  |  |      1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291,  | 
7195  |  |      1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291,  | 
7196  |  |      1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291,  | 
7197  |  |      1291, 1291, 1291, 1291, 1291},  | 
7198  |  |     {1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, | 
7199  |  |      1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291,  | 
7200  |  |      1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291,  | 
7201  |  |      1291, 1291, 1291, 1291, 1291, 1293, 1293, 1293, 1293, 1293, 1293, 1293,  | 
7202  |  |      1293, 1295, 1295, 1295, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297,  | 
7203  |  |      1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297,  | 
7204  |  |      1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297,  | 
7205  |  |      1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297,  | 
7206  |  |      1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297,  | 
7207  |  |      1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297,  | 
7208  |  |      1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297,  | 
7209  |  |      1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297,  | 
7210  |  |      1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297,  | 
7211  |  |      1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297,  | 
7212  |  |      1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297,  | 
7213  |  |      1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297,  | 
7214  |  |      1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1301, 1301, 1301, 1301,  | 
7215  |  |      1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301,  | 
7216  |  |      1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301,  | 
7217  |  |      1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301,  | 
7218  |  |      1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301,  | 
7219  |  |      1301, 1301, 1301, 1301, 1301},  | 
7220  |  |     {1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, | 
7221  |  |      1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301,  | 
7222  |  |      1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301,  | 
7223  |  |      1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301,  | 
7224  |  |      1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301,  | 
7225  |  |      1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301,  | 
7226  |  |      1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307,  | 
7227  |  |      1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307,  | 
7228  |  |      1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307,  | 
7229  |  |      1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307,  | 
7230  |  |      1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307,  | 
7231  |  |      1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307,  | 
7232  |  |      1307, 1307, 1307, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,  | 
7233  |  |      1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,  | 
7234  |  |      1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,  | 
7235  |  |      1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,  | 
7236  |  |      1309, 1309, 1309, 1309, 1309, 1309, 1309, 1313, 1315, 1315, 1315, 1315,  | 
7237  |  |      1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315,  | 
7238  |  |      1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315,  | 
7239  |  |      1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315,  | 
7240  |  |      1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315,  | 
7241  |  |      1315, 1315, 1315, 1315, 1315},  | 
7242  |  |     {1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, | 
7243  |  |      1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315,  | 
7244  |  |      1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315,  | 
7245  |  |      1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315,  | 
7246  |  |      1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315,  | 
7247  |  |      1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1317,  | 
7248  |  |      1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317,  | 
7249  |  |      1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317,  | 
7250  |  |      1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317,  | 
7251  |  |      1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317,  | 
7252  |  |      1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317,  | 
7253  |  |      1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317,  | 
7254  |  |      1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317,  | 
7255  |  |      1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317,  | 
7256  |  |      1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317,  | 
7257  |  |      1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317,  | 
7258  |  |      1319, 1319, 1319, 1319, 1319, 1319, 1319, 1325, 1325, 1325, 1325, 1327,  | 
7259  |  |      1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327,  | 
7260  |  |      1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327,  | 
7261  |  |      1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327,  | 
7262  |  |      1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327,  | 
7263  |  |      1327, 1327, 1327, 1327, 1327},  | 
7264  |  |     {1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, | 
7265  |  |      1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327,  | 
7266  |  |      1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327,  | 
7267  |  |      1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327,  | 
7268  |  |      1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327,  | 
7269  |  |      1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1331,  | 
7270  |  |      1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333,  | 
7271  |  |      1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333,  | 
7272  |  |      1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333,  | 
7273  |  |      1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333,  | 
7274  |  |      1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333,  | 
7275  |  |      1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333,  | 
7276  |  |      1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333,  | 
7277  |  |      1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333,  | 
7278  |  |      1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333,  | 
7279  |  |      1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333,  | 
7280  |  |      1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333,  | 
7281  |  |      1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333,  | 
7282  |  |      1333, 1333, 1339, 1339, 1339, 1341, 1341, 1341, 1341, 1341, 1341, 1341,  | 
7283  |  |      1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341,  | 
7284  |  |      1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341,  | 
7285  |  |      1341, 1341, 1341, 1341, 1341},  | 
7286  |  |     {1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, | 
7287  |  |      1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341,  | 
7288  |  |      1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341,  | 
7289  |  |      1341, 1341, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,  | 
7290  |  |      1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,  | 
7291  |  |      1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,  | 
7292  |  |      1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,  | 
7293  |  |      1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,  | 
7294  |  |      1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,  | 
7295  |  |      1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,  | 
7296  |  |      1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,  | 
7297  |  |      1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,  | 
7298  |  |      1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,  | 
7299  |  |      1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,  | 
7300  |  |      1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,  | 
7301  |  |      1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,  | 
7302  |  |      1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,  | 
7303  |  |      1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,  | 
7304  |  |      1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,  | 
7305  |  |      1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,  | 
7306  |  |      1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,  | 
7307  |  |      1343, 1343, 1343, 1343, 1343},  | 
7308  |  |     {1343, 1343, 1343, 1343, 1343, 1343, 1345, 1345, 1347, 1347, 1349, 1349, | 
7309  |  |      1351, 1351, 1353, 1353, 1353, 1353, 1355, 1355, 1355, 1355, 1355, 1355,  | 
7310  |  |      1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355,  | 
7311  |  |      1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355,  | 
7312  |  |      1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1357,  | 
7313  |  |      1357, 1359, 1359, 1361, 1363, 1363, 1363, 1365, 1365, 1365, 1365, 1365,  | 
7314  |  |      1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,  | 
7315  |  |      1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,  | 
7316  |  |      1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,  | 
7317  |  |      1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,  | 
7318  |  |      1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,  | 
7319  |  |      1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,  | 
7320  |  |      1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,  | 
7321  |  |      1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,  | 
7322  |  |      1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,  | 
7323  |  |      1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,  | 
7324  |  |      1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,  | 
7325  |  |      1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,  | 
7326  |  |      1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,  | 
7327  |  |      1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,  | 
7328  |  |      1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,  | 
7329  |  |      1365, 1365, 1365, 1365, 1365},  | 
7330  |  |     {1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, | 
7331  |  |      1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,  | 
7332  |  |      1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,  | 
7333  |  |      1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,  | 
7334  |  |      1365, 1365, 1365, 1365, 1365, 1365, 1365, 1367, 1369, 1369, 1369, 1369,  | 
7335  |  |      1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369,  | 
7336  |  |      1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369,  | 
7337  |  |      1369, 1369, 1369, 1369, 1369, 1369, 1369, 1371, 1373, 1373, 1373, 1373,  | 
7338  |  |      1373, 1373, 1373, 1375, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377,  | 
7339  |  |      1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377,  | 
7340  |  |      1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377,  | 
7341  |  |      1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377,  | 
7342  |  |      1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377,  | 
7343  |  |      1377, 1377, 1377, 1377, 1377, 1381, 1385, 1385, 1385, 1385, 1385, 1385,  | 
7344  |  |      1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385,  | 
7345  |  |      1385, 1385, 1385, 1385, 1385, 1387, 1389, 1389, 1389, 1389, 1389, 1389,  | 
7346  |  |      1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389,  | 
7347  |  |      1389, 1391, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393,  | 
7348  |  |      1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393,  | 
7349  |  |      1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393,  | 
7350  |  |      1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393,  | 
7351  |  |      1393, 1393, 1393, 1393, 1393},  | 
7352  |  |     {1393, 1401, 1409, 1411, 1413, 1415, 1417, 1419, 1421, 1429, 1437, 1439, | 
7353  |  |      1441, 1443, 1445, 1447, 1449, 1453, 1457, 1457, 1457, 1457, 1457, 1457,  | 
7354  |  |      1457, 1461, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1473, 1481, 1483,  | 
7355  |  |      1485, 1487, 1489, 1491, 1493, 1501, 1509, 1511, 1513, 1515, 1517, 1519,  | 
7356  |  |      1521, 1527, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1539, 1545, 1545,  | 
7357  |  |      1545, 1545, 1545, 1545, 1545, 1549, 1553, 1553, 1553, 1553, 1553, 1553,  | 
7358  |  |      1553, 1557, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1567, 1573, 1573,  | 
7359  |  |      1573, 1573, 1573, 1573, 1573, 1573, 1579, 1579, 1579, 1579, 1579, 1579,  | 
7360  |  |      1579, 1587, 1595, 1597, 1599, 1601, 1603, 1605, 1607, 1615, 1623, 1625,  | 
7361  |  |      1627, 1629, 1631, 1633, 1635, 1637, 1637, 1637, 1637, 1639, 1639, 1639,  | 
7362  |  |      1639, 1639, 1639, 1639, 1639, 1641, 1641, 1641, 1641, 1641, 1641, 1641,  | 
7363  |  |      1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641,  | 
7364  |  |      1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641,  | 
7365  |  |      1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641,  | 
7366  |  |      1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641,  | 
7367  |  |      1641, 1641, 1641, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643,  | 
7368  |  |      1649, 1649, 1649, 1649, 1649, 1649, 1649, 1651, 1651, 1651, 1651, 1651,  | 
7369  |  |      1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651,  | 
7370  |  |      1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651,  | 
7371  |  |      1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651,  | 
7372  |  |      1651, 1651, 1651, 1651, 1651, 1651, 1651, 1653, 1653, 1653, 1653, 1653,  | 
7373  |  |      1653, 1653, 1653, 1659, 1659},  | 
7374  |  |     {1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, | 
7375  |  |      1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,  | 
7376  |  |      1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,  | 
7377  |  |      1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,  | 
7378  |  |      1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,  | 
7379  |  |      1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,  | 
7380  |  |      1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,  | 
7381  |  |      1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,  | 
7382  |  |      1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,  | 
7383  |  |      1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,  | 
7384  |  |      1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,  | 
7385  |  |      1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,  | 
7386  |  |      1659, 1661, 1661, 1663, 1663, 1665, 1665, 1665, 1665, 1665, 1665, 1665,  | 
7387  |  |      1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665,  | 
7388  |  |      1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665,  | 
7389  |  |      1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665,  | 
7390  |  |      1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665,  | 
7391  |  |      1665, 1665, 1665, 1665, 1665, 1667, 1667, 1669, 1669, 1671, 1671, 1671,  | 
7392  |  |      1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671,  | 
7393  |  |      1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671,  | 
7394  |  |      1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671,  | 
7395  |  |      1671, 1671, 1671, 1671, 1671},  | 
7396  |  |     {1671, 1671, 1671, 1671, 1673, 1673, 1673, 1673, 1673, 1675, 1675, 1675, | 
7397  |  |      1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677,  | 
7398  |  |      1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677,  | 
7399  |  |      1679, 1679, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,  | 
7400  |  |      1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,  | 
7401  |  |      1681, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1685, 1685, 1687, 1687,  | 
7402  |  |      1687, 1689, 1689, 1689, 1689, 1689, 1691, 1691, 1691, 1691, 1691, 1691,  | 
7403  |  |      1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691,  | 
7404  |  |      1691, 1691, 1693, 1693, 1693, 1695, 1697, 1697, 1697, 1697, 1697, 1697,  | 
7405  |  |      1697, 1697, 1697, 1697, 1697, 1697, 1697, 1699, 1701, 1701, 1701, 1703,  | 
7406  |  |      1705, 1705, 1705, 1707, 1709, 1711, 1713, 1713, 1713, 1713, 1713, 1715,  | 
7407  |  |      1717, 1717, 1717, 1719, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721,  | 
7408  |  |      1721, 1721, 1723, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725,  | 
7409  |  |      1725, 1725, 1725, 1725, 1725, 1725, 1725, 1727, 1727, 1727, 1727, 1727,  | 
7410  |  |      1727, 1729, 1731, 1731, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1735,  | 
7411  |  |      1737, 1739, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741,  | 
7412  |  |      1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741,  | 
7413  |  |      1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741,  | 
7414  |  |      1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741,  | 
7415  |  |      1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741,  | 
7416  |  |      1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741,  | 
7417  |  |      1741, 1741, 1741, 1741, 1741},  | 
7418  |  |     {1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, | 
7419  |  |      1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741,  | 
7420  |  |      1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741,  | 
7421  |  |      1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741,  | 
7422  |  |      1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741,  | 
7423  |  |      1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1743,  | 
7424  |  |      1743, 1743, 1743, 1743, 1745, 1745, 1747, 1747, 1749, 1749, 1751, 1751,  | 
7425  |  |      1753, 1753, 1755, 1755, 1757, 1757, 1759, 1759, 1761, 1761, 1763, 1763,  | 
7426  |  |      1765, 1765, 1767, 1767, 1767, 1769, 1769, 1771, 1771, 1773, 1773, 1773,  | 
7427  |  |      1773, 1773, 1773, 1773, 1777, 1777, 1777, 1781, 1781, 1781, 1785, 1785,  | 
7428  |  |      1785, 1789, 1789, 1789, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793,  | 
7429  |  |      1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793,  | 
7430  |  |      1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793,  | 
7431  |  |      1793, 1793, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1797,  | 
7432  |  |      1797, 1797, 1797, 1797, 1799, 1799, 1801, 1801, 1803, 1803, 1805, 1805,  | 
7433  |  |      1807, 1807, 1809, 1809, 1811, 1811, 1813, 1813, 1815, 1815, 1817, 1817,  | 
7434  |  |      1819, 1819, 1821, 1821, 1821, 1823, 1823, 1825, 1825, 1827, 1827, 1827,  | 
7435  |  |      1827, 1827, 1827, 1827, 1831, 1831, 1831, 1835, 1835, 1835, 1839, 1839,  | 
7436  |  |      1839, 1843, 1843, 1843, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847,  | 
7437  |  |      1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847,  | 
7438  |  |      1849, 1851, 1853, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855,  | 
7439  |  |      1855, 1855, 1857, 1857, 1857},  | 
7440  |  |     {1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, | 
7441  |  |      1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857,  | 
7442  |  |      1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857,  | 
7443  |  |      1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857,  | 
7444  |  |      1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857,  | 
7445  |  |      1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857,  | 
7446  |  |      1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857,  | 
7447  |  |      1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857,  | 
7448  |  |      1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857,  | 
7449  |  |      1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857,  | 
7450  |  |      1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857,  | 
7451  |  |      1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857,  | 
7452  |  |      1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1859, 1859,  | 
7453  |  |      1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1863, 1863,  | 
7454  |  |      1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863,  | 
7455  |  |      1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863,  | 
7456  |  |      1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863,  | 
7457  |  |      1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863,  | 
7458  |  |      1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863,  | 
7459  |  |      1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863,  | 
7460  |  |      1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863,  | 
7461  |  |      1863, 1863, 1863, 1863, 1863},  | 
7462  |  |     {1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, | 
7463  |  |      1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863,  | 
7464  |  |      1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863,  | 
7465  |  |      1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863,  | 
7466  |  |      1863, 1863, 1865, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,  | 
7467  |  |      1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,  | 
7468  |  |      1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,  | 
7469  |  |      1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,  | 
7470  |  |      1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,  | 
7471  |  |      1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,  | 
7472  |  |      1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,  | 
7473  |  |      1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,  | 
7474  |  |      1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,  | 
7475  |  |      1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,  | 
7476  |  |      1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,  | 
7477  |  |      1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,  | 
7478  |  |      1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,  | 
7479  |  |      1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,  | 
7480  |  |      1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,  | 
7481  |  |      1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,  | 
7482  |  |      1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,  | 
7483  |  |      1867, 1867, 1867, 1867, 1867},  | 
7484  |  |     {1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, | 
7485  |  |      1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,  | 
7486  |  |      1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,  | 
7487  |  |      1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,  | 
7488  |  |      1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,  | 
7489  |  |      1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,  | 
7490  |  |      1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,  | 
7491  |  |      1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,  | 
7492  |  |      1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,  | 
7493  |  |      1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,  | 
7494  |  |      1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,  | 
7495  |  |      1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,  | 
7496  |  |      1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,  | 
7497  |  |      1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,  | 
7498  |  |      1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,  | 
7499  |  |      1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,  | 
7500  |  |      1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,  | 
7501  |  |      1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,  | 
7502  |  |      1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,  | 
7503  |  |      1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,  | 
7504  |  |      1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,  | 
7505  |  |      1871, 1871, 1871, 1871, 1871},  | 
7506  |  |     {1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, | 
7507  |  |      1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,  | 
7508  |  |      1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,  | 
7509  |  |      1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,  | 
7510  |  |      1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,  | 
7511  |  |      1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,  | 
7512  |  |      1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,  | 
7513  |  |      1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,  | 
7514  |  |      1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,  | 
7515  |  |      1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,  | 
7516  |  |      1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,  | 
7517  |  |      1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,  | 
7518  |  |      1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,  | 
7519  |  |      1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,  | 
7520  |  |      1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,  | 
7521  |  |      1871, 1871, 1871, 1871, 1871, 1871, 1877, 1877, 1877, 1877, 1877, 1877,  | 
7522  |  |      1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,  | 
7523  |  |      1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,  | 
7524  |  |      1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,  | 
7525  |  |      1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,  | 
7526  |  |      1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,  | 
7527  |  |      1877, 1877, 1877, 1877, 1877},  | 
7528  |  |     {1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, | 
7529  |  |      1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,  | 
7530  |  |      1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,  | 
7531  |  |      1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,  | 
7532  |  |      1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,  | 
7533  |  |      1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,  | 
7534  |  |      1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,  | 
7535  |  |      1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,  | 
7536  |  |      1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,  | 
7537  |  |      1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,  | 
7538  |  |      1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,  | 
7539  |  |      1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,  | 
7540  |  |      1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,  | 
7541  |  |      1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,  | 
7542  |  |      1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,  | 
7543  |  |      1877, 1877, 1877, 1877, 1877, 1879, 1881, 1881, 1881, 1881, 1881, 1881,  | 
7544  |  |      1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881,  | 
7545  |  |      1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881,  | 
7546  |  |      1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881,  | 
7547  |  |      1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881,  | 
7548  |  |      1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881,  | 
7549  |  |      1881, 1881, 1881, 1881, 1881},  | 
7550  |  |     {1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, | 
7551  |  |      1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881,  | 
7552  |  |      1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881,  | 
7553  |  |      1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881,  | 
7554  |  |      1881, 1881, 1881, 1881, 1881, 1881, 1883, 1883, 1883, 1883, 1883, 1883,  | 
7555  |  |      1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,  | 
7556  |  |      1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,  | 
7557  |  |      1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,  | 
7558  |  |      1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,  | 
7559  |  |      1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,  | 
7560  |  |      1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,  | 
7561  |  |      1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,  | 
7562  |  |      1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,  | 
7563  |  |      1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,  | 
7564  |  |      1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,  | 
7565  |  |      1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,  | 
7566  |  |      1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,  | 
7567  |  |      1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,  | 
7568  |  |      1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,  | 
7569  |  |      1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,  | 
7570  |  |      1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,  | 
7571  |  |      1883, 1883, 1883, 1883, 1883}};  | 
7572  |  | const char32_t composition_data[1883] = { | 
7573  |  |     0,     824,   8814,  824,   8800,  824,   8815,  768,   192,   769,   193,  | 
7574  |  |     770,   194,   771,   195,   772,   256,   774,   258,   775,   550,   776,  | 
7575  |  |     196,   777,   7842,  778,   197,   780,   461,   783,   512,   785,   514,  | 
7576  |  |     803,   7840,  805,   7680,  808,   260,   775,   7682,  803,   7684,  817,  | 
7577  |  |     7686,  769,   262,   770,   264,   775,   266,   780,   268,   807,   199,  | 
7578  |  |     775,   7690,  780,   270,   803,   7692,  807,   7696,  813,   7698,  817,  | 
7579  |  |     7694,  768,   200,   769,   201,   770,   202,   771,   7868,  772,   274,  | 
7580  |  |     774,   276,   775,   278,   776,   203,   777,   7866,  780,   282,   783,  | 
7581  |  |     516,   785,   518,   803,   7864,  807,   552,   808,   280,   813,   7704,  | 
7582  |  |     816,   7706,  775,   7710,  769,   500,   770,   284,   772,   7712,  774,  | 
7583  |  |     286,   775,   288,   780,   486,   807,   290,   770,   292,   775,   7714,  | 
7584  |  |     776,   7718,  780,   542,   803,   7716,  807,   7720,  814,   7722,  768,  | 
7585  |  |     204,   769,   205,   770,   206,   771,   296,   772,   298,   774,   300,  | 
7586  |  |     775,   304,   776,   207,   777,   7880,  780,   463,   783,   520,   785,  | 
7587  |  |     522,   803,   7882,  808,   302,   816,   7724,  770,   308,   769,   7728,  | 
7588  |  |     780,   488,   803,   7730,  807,   310,   817,   7732,  769,   313,   780,  | 
7589  |  |     317,   803,   7734,  807,   315,   813,   7740,  817,   7738,  769,   7742,  | 
7590  |  |     775,   7744,  803,   7746,  768,   504,   769,   323,   771,   209,   775,  | 
7591  |  |     7748,  780,   327,   803,   7750,  807,   325,   813,   7754,  817,   7752,  | 
7592  |  |     768,   210,   769,   211,   770,   212,   771,   213,   772,   332,   774,  | 
7593  |  |     334,   775,   558,   776,   214,   777,   7886,  779,   336,   780,   465,  | 
7594  |  |     783,   524,   785,   526,   795,   416,   803,   7884,  808,   490,   769,  | 
7595  |  |     7764,  775,   7766,  769,   340,   775,   7768,  780,   344,   783,   528,  | 
7596  |  |     785,   530,   803,   7770,  807,   342,   817,   7774,  769,   346,   770,  | 
7597  |  |     348,   775,   7776,  780,   352,   803,   7778,  806,   536,   807,   350,  | 
7598  |  |     775,   7786,  780,   356,   803,   7788,  806,   538,   807,   354,   813,  | 
7599  |  |     7792,  817,   7790,  768,   217,   769,   218,   770,   219,   771,   360,  | 
7600  |  |     772,   362,   774,   364,   776,   220,   777,   7910,  778,   366,   779,  | 
7601  |  |     368,   780,   467,   783,   532,   785,   534,   795,   431,   803,   7908,  | 
7602  |  |     804,   7794,  808,   370,   813,   7798,  816,   7796,  771,   7804,  803,  | 
7603  |  |     7806,  768,   7808,  769,   7810,  770,   372,   775,   7814,  776,   7812,  | 
7604  |  |     803,   7816,  775,   7818,  776,   7820,  768,   7922,  769,   221,   770,  | 
7605  |  |     374,   771,   7928,  772,   562,   775,   7822,  776,   376,   777,   7926,  | 
7606  |  |     803,   7924,  769,   377,   770,   7824,  775,   379,   780,   381,   803,  | 
7607  |  |     7826,  817,   7828,  768,   224,   769,   225,   770,   226,   771,   227,  | 
7608  |  |     772,   257,   774,   259,   775,   551,   776,   228,   777,   7843,  778,  | 
7609  |  |     229,   780,   462,   783,   513,   785,   515,   803,   7841,  805,   7681,  | 
7610  |  |     808,   261,   775,   7683,  803,   7685,  817,   7687,  769,   263,   770,  | 
7611  |  |     265,   775,   267,   780,   269,   807,   231,   775,   7691,  780,   271,  | 
7612  |  |     803,   7693,  807,   7697,  813,   7699,  817,   7695,  768,   232,   769,  | 
7613  |  |     233,   770,   234,   771,   7869,  772,   275,   774,   277,   775,   279,  | 
7614  |  |     776,   235,   777,   7867,  780,   283,   783,   517,   785,   519,   803,  | 
7615  |  |     7865,  807,   553,   808,   281,   813,   7705,  816,   7707,  775,   7711,  | 
7616  |  |     769,   501,   770,   285,   772,   7713,  774,   287,   775,   289,   780,  | 
7617  |  |     487,   807,   291,   770,   293,   775,   7715,  776,   7719,  780,   543,  | 
7618  |  |     803,   7717,  807,   7721,  814,   7723,  817,   7830,  768,   236,   769,  | 
7619  |  |     237,   770,   238,   771,   297,   772,   299,   774,   301,   776,   239,  | 
7620  |  |     777,   7881,  780,   464,   783,   521,   785,   523,   803,   7883,  808,  | 
7621  |  |     303,   816,   7725,  770,   309,   780,   496,   769,   7729,  780,   489,  | 
7622  |  |     803,   7731,  807,   311,   817,   7733,  769,   314,   780,   318,   803,  | 
7623  |  |     7735,  807,   316,   813,   7741,  817,   7739,  769,   7743,  775,   7745,  | 
7624  |  |     803,   7747,  768,   505,   769,   324,   771,   241,   775,   7749,  780,  | 
7625  |  |     328,   803,   7751,  807,   326,   813,   7755,  817,   7753,  768,   242,  | 
7626  |  |     769,   243,   770,   244,   771,   245,   772,   333,   774,   335,   775,  | 
7627  |  |     559,   776,   246,   777,   7887,  779,   337,   780,   466,   783,   525,  | 
7628  |  |     785,   527,   795,   417,   803,   7885,  808,   491,   769,   7765,  775,  | 
7629  |  |     7767,  769,   341,   775,   7769,  780,   345,   783,   529,   785,   531,  | 
7630  |  |     803,   7771,  807,   343,   817,   7775,  769,   347,   770,   349,   775,  | 
7631  |  |     7777,  780,   353,   803,   7779,  806,   537,   807,   351,   775,   7787,  | 
7632  |  |     776,   7831,  780,   357,   803,   7789,  806,   539,   807,   355,   813,  | 
7633  |  |     7793,  817,   7791,  768,   249,   769,   250,   770,   251,   771,   361,  | 
7634  |  |     772,   363,   774,   365,   776,   252,   777,   7911,  778,   367,   779,  | 
7635  |  |     369,   780,   468,   783,   533,   785,   535,   795,   432,   803,   7909,  | 
7636  |  |     804,   7795,  808,   371,   813,   7799,  816,   7797,  771,   7805,  803,  | 
7637  |  |     7807,  768,   7809,  769,   7811,  770,   373,   775,   7815,  776,   7813,  | 
7638  |  |     778,   7832,  803,   7817,  775,   7819,  776,   7821,  768,   7923,  769,  | 
7639  |  |     253,   770,   375,   771,   7929,  772,   563,   775,   7823,  776,   255,  | 
7640  |  |     777,   7927,  778,   7833,  803,   7925,  769,   378,   770,   7825,  775,  | 
7641  |  |     380,   780,   382,   803,   7827,  817,   7829,  768,   8173,  769,   901,  | 
7642  |  |     834,   8129,  768,   7846,  769,   7844,  771,   7850,  777,   7848,  772,  | 
7643  |  |     478,   769,   506,   769,   508,   772,   482,   769,   7688,  768,   7872,  | 
7644  |  |     769,   7870,  771,   7876,  777,   7874,  769,   7726,  768,   7890,  769,  | 
7645  |  |     7888,  771,   7894,  777,   7892,  769,   7756,  772,   556,   776,   7758,  | 
7646  |  |     772,   554,   769,   510,   768,   475,   769,   471,   772,   469,   780,  | 
7647  |  |     473,   768,   7847,  769,   7845,  771,   7851,  777,   7849,  772,   479,  | 
7648  |  |     769,   507,   769,   509,   772,   483,   769,   7689,  768,   7873,  769,  | 
7649  |  |     7871,  771,   7877,  777,   7875,  769,   7727,  768,   7891,  769,   7889,  | 
7650  |  |     771,   7895,  777,   7893,  769,   7757,  772,   557,   776,   7759,  772,  | 
7651  |  |     555,   769,   511,   768,   476,   769,   472,   772,   470,   780,   474,  | 
7652  |  |     768,   7856,  769,   7854,  771,   7860,  777,   7858,  768,   7857,  769,  | 
7653  |  |     7855,  771,   7861,  777,   7859,  768,   7700,  769,   7702,  768,   7701,  | 
7654  |  |     769,   7703,  768,   7760,  769,   7762,  768,   7761,  769,   7763,  775,  | 
7655  |  |     7780,  775,   7781,  775,   7782,  775,   7783,  769,   7800,  769,   7801,  | 
7656  |  |     776,   7802,  776,   7803,  775,   7835,  768,   7900,  769,   7898,  771,  | 
7657  |  |     7904,  777,   7902,  803,   7906,  768,   7901,  769,   7899,  771,   7905,  | 
7658  |  |     777,   7903,  803,   7907,  768,   7914,  769,   7912,  771,   7918,  777,  | 
7659  |  |     7916,  803,   7920,  768,   7915,  769,   7913,  771,   7919,  777,   7917,  | 
7660  |  |     803,   7921,  780,   494,   772,   492,   772,   493,   772,   480,   772,  | 
7661  |  |     481,   774,   7708,  774,   7709,  772,   560,   772,   561,   780,   495,  | 
7662  |  |     768,   8122,  769,   902,   772,   8121,  774,   8120,  787,   7944,  788,  | 
7663  |  |     7945,  837,   8124,  768,   8136,  769,   904,   787,   7960,  788,   7961,  | 
7664  |  |     768,   8138,  769,   905,   787,   7976,  788,   7977,  837,   8140,  768,  | 
7665  |  |     8154,  769,   906,   772,   8153,  774,   8152,  776,   938,   787,   7992,  | 
7666  |  |     788,   7993,  768,   8184,  769,   908,   787,   8008,  788,   8009,  788,  | 
7667  |  |     8172,  768,   8170,  769,   910,   772,   8169,  774,   8168,  776,   939,  | 
7668  |  |     788,   8025,  768,   8186,  769,   911,   787,   8040,  788,   8041,  837,  | 
7669  |  |     8188,  837,   8116,  837,   8132,  768,   8048,  769,   940,   772,   8113,  | 
7670  |  |     774,   8112,  787,   7936,  788,   7937,  834,   8118,  837,   8115,  768,  | 
7671  |  |     8050,  769,   941,   787,   7952,  788,   7953,  768,   8052,  769,   942,  | 
7672  |  |     787,   7968,  788,   7969,  834,   8134,  837,   8131,  768,   8054,  769,  | 
7673  |  |     943,   772,   8145,  774,   8144,  776,   970,   787,   7984,  788,   7985,  | 
7674  |  |     834,   8150,  768,   8056,  769,   972,   787,   8000,  788,   8001,  787,  | 
7675  |  |     8164,  788,   8165,  768,   8058,  769,   973,   772,   8161,  774,   8160,  | 
7676  |  |     776,   971,   787,   8016,  788,   8017,  834,   8166,  768,   8060,  769,  | 
7677  |  |     974,   787,   8032,  788,   8033,  834,   8182,  837,   8179,  768,   8146,  | 
7678  |  |     769,   912,   834,   8151,  768,   8162,  769,   944,   834,   8167,  837,  | 
7679  |  |     8180,  769,   979,   776,   980,   776,   1031,  774,   1232,  776,   1234,  | 
7680  |  |     769,   1027,  768,   1024,  774,   1238,  776,   1025,  774,   1217,  776,  | 
7681  |  |     1244,  776,   1246,  768,   1037,  772,   1250,  774,   1049,  776,   1252,  | 
7682  |  |     769,   1036,  776,   1254,  772,   1262,  774,   1038,  776,   1264,  779,  | 
7683  |  |     1266,  776,   1268,  776,   1272,  776,   1260,  774,   1233,  776,   1235,  | 
7684  |  |     769,   1107,  768,   1104,  774,   1239,  776,   1105,  774,   1218,  776,  | 
7685  |  |     1245,  776,   1247,  768,   1117,  772,   1251,  774,   1081,  776,   1253,  | 
7686  |  |     769,   1116,  776,   1255,  772,   1263,  774,   1118,  776,   1265,  779,  | 
7687  |  |     1267,  776,   1269,  776,   1273,  776,   1261,  776,   1111,  783,   1142,  | 
7688  |  |     783,   1143,  776,   1242,  776,   1243,  776,   1258,  776,   1259,  1619,  | 
7689  |  |     1570,  1620,  1571,  1621,  1573,  1620,  1572,  1620,  1574,  1620,  1730,  | 
7690  |  |     1620,  1747,  1620,  1728,  2364,  2345,  2364,  2353,  2364,  2356,  2494,  | 
7691  |  |     2507,  2519,  2508,  2878,  2891,  2902,  2888,  2903,  2892,  3031,  2964,  | 
7692  |  |     3006,  3018,  3031,  3020,  3006,  3019,  3158,  3144,  3285,  3264,  3266,  | 
7693  |  |     3274,  3285,  3271,  3286,  3272,  3285,  3275,  3390,  3402,  3415,  3404,  | 
7694  |  |     3390,  3403,  3530,  3546,  3535,  3548,  3551,  3550,  3530,  3549,  4142,  | 
7695  |  |     4134,  6965,  6918,  6965,  6920,  6965,  6922,  6965,  6924,  6965,  6926,  | 
7696  |  |     6965,  6930,  6965,  6971,  6965,  6973,  6965,  6976,  6965,  6977,  6965,  | 
7697  |  |     6979,  772,   7736,  772,   7737,  772,   7772,  772,   7773,  775,   7784,  | 
7698  |  |     775,   7785,  770,   7852,  774,   7862,  770,   7853,  774,   7863,  770,  | 
7699  |  |     7878,  770,   7879,  770,   7896,  770,   7897,  768,   7938,  769,   7940,  | 
7700  |  |     834,   7942,  837,   8064,  768,   7939,  769,   7941,  834,   7943,  837,  | 
7701  |  |     8065,  837,   8066,  837,   8067,  837,   8068,  837,   8069,  837,   8070,  | 
7702  |  |     837,   8071,  768,   7946,  769,   7948,  834,   7950,  837,   8072,  768,  | 
7703  |  |     7947,  769,   7949,  834,   7951,  837,   8073,  837,   8074,  837,   8075,  | 
7704  |  |     837,   8076,  837,   8077,  837,   8078,  837,   8079,  768,   7954,  769,  | 
7705  |  |     7956,  768,   7955,  769,   7957,  768,   7962,  769,   7964,  768,   7963,  | 
7706  |  |     769,   7965,  768,   7970,  769,   7972,  834,   7974,  837,   8080,  768,  | 
7707  |  |     7971,  769,   7973,  834,   7975,  837,   8081,  837,   8082,  837,   8083,  | 
7708  |  |     837,   8084,  837,   8085,  837,   8086,  837,   8087,  768,   7978,  769,  | 
7709  |  |     7980,  834,   7982,  837,   8088,  768,   7979,  769,   7981,  834,   7983,  | 
7710  |  |     837,   8089,  837,   8090,  837,   8091,  837,   8092,  837,   8093,  837,  | 
7711  |  |     8094,  837,   8095,  768,   7986,  769,   7988,  834,   7990,  768,   7987,  | 
7712  |  |     769,   7989,  834,   7991,  768,   7994,  769,   7996,  834,   7998,  768,  | 
7713  |  |     7995,  769,   7997,  834,   7999,  768,   8002,  769,   8004,  768,   8003,  | 
7714  |  |     769,   8005,  768,   8010,  769,   8012,  768,   8011,  769,   8013,  768,  | 
7715  |  |     8018,  769,   8020,  834,   8022,  768,   8019,  769,   8021,  834,   8023,  | 
7716  |  |     768,   8027,  769,   8029,  834,   8031,  768,   8034,  769,   8036,  834,  | 
7717  |  |     8038,  837,   8096,  768,   8035,  769,   8037,  834,   8039,  837,   8097,  | 
7718  |  |     837,   8098,  837,   8099,  837,   8100,  837,   8101,  837,   8102,  837,  | 
7719  |  |     8103,  768,   8042,  769,   8044,  834,   8046,  837,   8104,  768,   8043,  | 
7720  |  |     769,   8045,  834,   8047,  837,   8105,  837,   8106,  837,   8107,  837,  | 
7721  |  |     8108,  837,   8109,  837,   8110,  837,   8111,  837,   8114,  837,   8130,  | 
7722  |  |     837,   8178,  837,   8119,  768,   8141,  769,   8142,  834,   8143,  837,  | 
7723  |  |     8135,  837,   8183,  768,   8157,  769,   8158,  834,   8159,  824,   8602,  | 
7724  |  |     824,   8603,  824,   8622,  824,   8653,  824,   8655,  824,   8654,  824,  | 
7725  |  |     8708,  824,   8713,  824,   8716,  824,   8740,  824,   8742,  824,   8769,  | 
7726  |  |     824,   8772,  824,   8775,  824,   8777,  824,   8813,  824,   8802,  824,  | 
7727  |  |     8816,  824,   8817,  824,   8820,  824,   8821,  824,   8824,  824,   8825,  | 
7728  |  |     824,   8832,  824,   8833,  824,   8928,  824,   8929,  824,   8836,  824,  | 
7729  |  |     8837,  824,   8840,  824,   8841,  824,   8930,  824,   8931,  824,   8876,  | 
7730  |  |     824,   8877,  824,   8878,  824,   8879,  824,   8938,  824,   8939,  824,  | 
7731  |  |     8940,  824,   8941,  12441, 12436, 12441, 12364, 12441, 12366, 12441, 12368,  | 
7732  |  |     12441, 12370, 12441, 12372, 12441, 12374, 12441, 12376, 12441, 12378, 12441,  | 
7733  |  |     12380, 12441, 12382, 12441, 12384, 12441, 12386, 12441, 12389, 12441, 12391,  | 
7734  |  |     12441, 12393, 12441, 12400, 12442, 12401, 12441, 12403, 12442, 12404, 12441,  | 
7735  |  |     12406, 12442, 12407, 12441, 12409, 12442, 12410, 12441, 12412, 12442, 12413,  | 
7736  |  |     12441, 12446, 12441, 12532, 12441, 12460, 12441, 12462, 12441, 12464, 12441,  | 
7737  |  |     12466, 12441, 12468, 12441, 12470, 12441, 12472, 12441, 12474, 12441, 12476,  | 
7738  |  |     12441, 12478, 12441, 12480, 12441, 12482, 12441, 12485, 12441, 12487, 12441,  | 
7739  |  |     12489, 12441, 12496, 12442, 12497, 12441, 12499, 12442, 12500, 12441, 12502,  | 
7740  |  |     12442, 12503, 12441, 12505, 12442, 12506, 12441, 12508, 12442, 12509, 12441,  | 
7741  |  |     12535, 12441, 12536, 12441, 12537, 12441, 12538, 12441, 12542, 69818, 69786,  | 
7742  |  |     69818, 69788, 69818, 69803, 69927, 69934, 69927, 69935, 70462, 70475, 70487,  | 
7743  |  |     70476, 70832, 70844, 70842, 70843, 70845, 70846, 71087, 71098, 71087, 71099,  | 
7744  |  |     71984, 71992};  | 
7745  |  |  | 
7746  |  | }  // namespace ada::idna  | 
7747  |  | #endif  // ADA_IDNA_NORMALIZATION_TABLES_H  | 
7748  |  | /* end file src/normalization_tables.cpp */  | 
7749  |  |  | 
7750  |  | namespace ada::idna { | 
7751  |  |  | 
7752  |  | // See  | 
7753  |  | // https://github.composition_count/uni-algo/uni-algo/blob/c612968c5ed3ace39bde4c894c24286c5f2c7fe2/include/uni_algo/impl/impl_norm.h#L467  | 
7754  |  | constexpr char32_t hangul_sbase = 0xAC00;  | 
7755  |  | constexpr char32_t hangul_tbase = 0x11A7;  | 
7756  |  | constexpr char32_t hangul_vbase = 0x1161;  | 
7757  |  | constexpr char32_t hangul_lbase = 0x1100;  | 
7758  |  | constexpr char32_t hangul_lcount = 19;  | 
7759  |  | constexpr char32_t hangul_vcount = 21;  | 
7760  |  | constexpr char32_t hangul_tcount = 28;  | 
7761  |  | constexpr char32_t hangul_ncount = hangul_vcount * hangul_tcount;  | 
7762  |  | constexpr char32_t hangul_scount =  | 
7763  |  |     hangul_lcount * hangul_vcount * hangul_tcount;  | 
7764  |  |  | 
7765  |  | std::pair<bool, size_t> compute_decomposition_length(  | 
7766  | 16.0k  |     const std::u32string_view input) noexcept { | 
7767  | 16.0k  |   bool decomposition_needed{false}; | 
7768  | 16.0k  |   size_t additional_elements{0}; | 
7769  | 318k  |   for (char32_t current_character : input) { | 
7770  | 318k  |     size_t decomposition_length{0}; | 
7771  |  |  | 
7772  | 318k  |     if (current_character >= hangul_sbase &&  | 
7773  | 318k  |         current_character < hangul_sbase + hangul_scount) { | 
7774  | 4.81k  |       decomposition_length = 2;  | 
7775  | 4.81k  |       if ((current_character - hangul_sbase) % hangul_tcount) { | 
7776  | 2.92k  |         decomposition_length = 3;  | 
7777  | 2.92k  |       }  | 
7778  | 313k  |     } else if (current_character < 0x110000) { | 
7779  | 313k  |       const uint8_t di = decomposition_index[current_character >> 8];  | 
7780  | 313k  |       const uint16_t* const decomposition =  | 
7781  | 313k  |           decomposition_block[di] + (current_character % 256);  | 
7782  | 313k  |       decomposition_length = (decomposition[1] >> 2) - (decomposition[0] >> 2);  | 
7783  | 313k  |       if ((decomposition_length > 0) && (decomposition[0] & 1)) { | 
7784  | 0  |         decomposition_length = 0;  | 
7785  | 0  |       }  | 
7786  | 313k  |     }  | 
7787  | 318k  |     if (decomposition_length != 0) { | 
7788  | 11.1k  |       decomposition_needed = true;  | 
7789  | 11.1k  |       additional_elements += decomposition_length - 1;  | 
7790  | 11.1k  |     }  | 
7791  | 318k  |   }  | 
7792  | 16.0k  |   return {decomposition_needed, additional_elements}; | 
7793  | 16.0k  | }  | 
7794  |  |  | 
7795  | 4.17k  | void decompose(std::u32string& input, size_t additional_elements) { | 
7796  | 4.17k  |   input.resize(input.size() + additional_elements);  | 
7797  | 4.17k  |   for (size_t descending_idx = input.size(),  | 
7798  | 4.17k  |               input_count = descending_idx - additional_elements;  | 
7799  | 78.1k  |        input_count--;) { | 
7800  | 74.0k  |     if (input[input_count] >= hangul_sbase &&  | 
7801  | 74.0k  |         input[input_count] < hangul_sbase + hangul_scount) { | 
7802  |  |       // Hangul decomposition.  | 
7803  | 4.81k  |       char32_t s_index = input[input_count] - hangul_sbase;  | 
7804  | 4.81k  |       if (s_index % hangul_tcount != 0) { | 
7805  | 2.92k  |         input[--descending_idx] = hangul_tbase + s_index % hangul_tcount;  | 
7806  | 2.92k  |       }  | 
7807  | 4.81k  |       input[--descending_idx] =  | 
7808  | 4.81k  |           hangul_vbase + (s_index % hangul_ncount) / hangul_tcount;  | 
7809  | 4.81k  |       input[--descending_idx] = hangul_lbase + s_index / hangul_ncount;  | 
7810  | 69.1k  |     } else if (input[input_count] < 0x110000) { | 
7811  |  |       // Check decomposition_data.  | 
7812  | 69.1k  |       const uint16_t* decomposition =  | 
7813  | 69.1k  |           decomposition_block[decomposition_index[input[input_count] >> 8]] +  | 
7814  | 69.1k  |           (input[input_count] % 256);  | 
7815  | 69.1k  |       uint16_t decomposition_length =  | 
7816  | 69.1k  |           (decomposition[1] >> 2) - (decomposition[0] >> 2);  | 
7817  | 69.1k  |       if (decomposition_length > 0 && (decomposition[0] & 1)) { | 
7818  | 0  |         decomposition_length = 0;  | 
7819  | 0  |       }  | 
7820  | 69.1k  |       if (decomposition_length > 0) { | 
7821  |  |         // Non-recursive decomposition.  | 
7822  | 20.2k  |         while (decomposition_length-- > 0) { | 
7823  | 13.9k  |           input[--descending_idx] = decomposition_data[(decomposition[0] >> 2) +  | 
7824  | 13.9k  |                                                        decomposition_length];  | 
7825  | 13.9k  |         }  | 
7826  | 62.8k  |       } else { | 
7827  |  |         // No decomposition.  | 
7828  | 62.8k  |         input[--descending_idx] = input[input_count];  | 
7829  | 62.8k  |       }  | 
7830  | 69.1k  |     } else { | 
7831  |  |       // Non-Unicode character.  | 
7832  | 0  |       input[--descending_idx] = input[input_count];  | 
7833  | 0  |     }  | 
7834  | 74.0k  |   }  | 
7835  | 4.17k  | }  | 
7836  |  |  | 
7837  | 636k  | uint8_t get_ccc(char32_t c) noexcept { | 
7838  | 636k  |   return c < 0x110000 ? canonical_combining_class_block  | 
7839  | 636k  |                             [canonical_combining_class_index[c >> 8]][c % 256]  | 
7840  | 636k  |                       : 0;  | 
7841  | 636k  | }  | 
7842  |  |  | 
7843  | 16.0k  | void sort_marks(std::u32string& input) { | 
7844  | 334k  |   for (size_t idx = 1; idx < input.size(); idx++) { | 
7845  | 318k  |     uint8_t ccc = get_ccc(input[idx]);  | 
7846  | 318k  |     if (ccc == 0) { | 
7847  | 306k  |       continue;  | 
7848  | 306k  |     }  // Skip non-combining characters.  | 
7849  | 11.7k  |     auto current_character = input[idx];  | 
7850  | 11.7k  |     size_t back_idx = idx;  | 
7851  | 12.8k  |     while (back_idx != 0 && get_ccc(input[back_idx - 1]) > ccc) { | 
7852  | 1.06k  |       input[back_idx] = input[back_idx - 1];  | 
7853  | 1.06k  |       back_idx--;  | 
7854  | 1.06k  |     }  | 
7855  | 11.7k  |     input[back_idx] = current_character;  | 
7856  | 11.7k  |   }  | 
7857  | 16.0k  | }  | 
7858  |  |  | 
7859  | 16.0k  | void decompose_nfc(std::u32string& input) { | 
7860  |  |   /**  | 
7861  |  |    * Decompose the domain_name string to Unicode Normalization Form C.  | 
7862  |  |    * @see https://www.unicode.org/reports/tr46/#ProcessingStepDecompose  | 
7863  |  |    */  | 
7864  | 16.0k  |   auto [decomposition_needed, additional_elements] =  | 
7865  | 16.0k  |       compute_decomposition_length(input);  | 
7866  | 16.0k  |   if (decomposition_needed) { | 
7867  | 4.17k  |     decompose(input, additional_elements);  | 
7868  | 4.17k  |   }  | 
7869  | 16.0k  |   sort_marks(input);  | 
7870  | 16.0k  | }  | 
7871  |  |  | 
7872  | 16.0k  | void compose(std::u32string& input) { | 
7873  |  |   /**  | 
7874  |  |    * Compose the domain_name string to Unicode Normalization Form C.  | 
7875  |  |    * @see https://www.unicode.org/reports/tr46/#ProcessingStepCompose  | 
7876  |  |    */  | 
7877  | 16.0k  |   size_t input_count{0}; | 
7878  | 16.0k  |   size_t composition_count{0}; | 
7879  | 330k  |   for (; input_count < input.size(); input_count++, composition_count++) { | 
7880  | 314k  |     input[composition_count] = input[input_count];  | 
7881  | 314k  |     if (input[input_count] >= hangul_lbase &&  | 
7882  | 314k  |         input[input_count] < hangul_lbase + hangul_lcount) { | 
7883  | 6.16k  |       if (input_count + 1 < input.size() &&  | 
7884  | 6.16k  |           input[input_count + 1] >= hangul_vbase &&  | 
7885  | 6.16k  |           input[input_count + 1] < hangul_vbase + hangul_vcount) { | 
7886  | 4.81k  |         input[composition_count] =  | 
7887  | 4.81k  |             hangul_sbase +  | 
7888  | 4.81k  |             ((input[input_count] - hangul_lbase) * hangul_vcount +  | 
7889  | 4.81k  |              input[input_count + 1] - hangul_vbase) *  | 
7890  | 4.81k  |                 hangul_tcount;  | 
7891  | 4.81k  |         input_count++;  | 
7892  | 4.81k  |         if (input_count + 1 < input.size() &&  | 
7893  | 4.81k  |             input[input_count + 1] > hangul_tbase &&  | 
7894  | 4.81k  |             input[input_count + 1] < hangul_tbase + hangul_tcount) { | 
7895  | 2.92k  |           input[composition_count] += input[++input_count] - hangul_tbase;  | 
7896  | 2.92k  |         }  | 
7897  | 4.81k  |       }  | 
7898  | 308k  |     } else if (input[input_count] >= hangul_sbase &&  | 
7899  | 308k  |                input[input_count] < hangul_sbase + hangul_scount) { | 
7900  | 0  |       if ((input[input_count] - hangul_sbase) % hangul_tcount &&  | 
7901  | 0  |           input_count + 1 < input.size() &&  | 
7902  | 0  |           input[input_count + 1] > hangul_tbase &&  | 
7903  | 0  |           input[input_count + 1] < hangul_tbase + hangul_tcount) { | 
7904  | 0  |         input[composition_count] += input[++input_count] - hangul_tbase;  | 
7905  | 0  |       }  | 
7906  | 308k  |     } else if (input[input_count] < 0x110000) { | 
7907  | 308k  |       const uint16_t* composition =  | 
7908  | 308k  |           &composition_block[composition_index[input[input_count] >> 8]]  | 
7909  | 308k  |                             [input[input_count] % 256];  | 
7910  | 308k  |       size_t initial_composition_count = composition_count;  | 
7911  | 319k  |       for (int32_t previous_ccc = -1; input_count + 1 < input.size();  | 
7912  | 308k  |            input_count++) { | 
7913  | 305k  |         uint8_t ccc = get_ccc(input[input_count + 1]);  | 
7914  |  |  | 
7915  | 305k  |         if (composition[1] != composition[0] && previous_ccc < ccc) { | 
7916  |  |           // Try finding a composition.  | 
7917  | 62.1k  |           uint16_t left = composition[0];  | 
7918  | 62.1k  |           uint16_t right = composition[1];  | 
7919  | 149k  |           while (left + 2 < right) { | 
7920  |  |             // mean without overflow  | 
7921  | 87.2k  |             uint16_t middle = left + (((right - left) >> 1) & ~1);  | 
7922  | 87.2k  |             if (composition_data[middle] <= input[input_count + 1]) { | 
7923  | 12.8k  |               left = middle;  | 
7924  | 12.8k  |             }  | 
7925  | 87.2k  |             if (composition_data[middle] >= input[input_count + 1]) { | 
7926  | 78.4k  |               right = middle;  | 
7927  | 78.4k  |             }  | 
7928  | 87.2k  |           }  | 
7929  | 62.1k  |           if (composition_data[left] == input[input_count + 1]) { | 
7930  | 7.60k  |             input[initial_composition_count] = composition_data[left + 1];  | 
7931  | 7.60k  |             composition =  | 
7932  | 7.60k  |                 &composition_block  | 
7933  | 7.60k  |                     [composition_index[composition_data[left + 1] >> 8]]  | 
7934  | 7.60k  |                     [composition_data[left + 1] % 256];  | 
7935  | 7.60k  |             continue;  | 
7936  | 7.60k  |           }  | 
7937  | 62.1k  |         }  | 
7938  |  |  | 
7939  | 298k  |         if (ccc == 0) { | 
7940  | 293k  |           break;  | 
7941  | 293k  |         }  // Not a combining character.  | 
7942  | 4.35k  |         previous_ccc = ccc;  | 
7943  | 4.35k  |         input[++composition_count] = input[input_count + 1];  | 
7944  | 4.35k  |       }  | 
7945  | 308k  |     }  | 
7946  | 314k  |   }  | 
7947  |  |  | 
7948  | 16.0k  |   if (composition_count < input_count) { | 
7949  | 4.19k  |     input.resize(composition_count);  | 
7950  | 4.19k  |   }  | 
7951  | 16.0k  | }  | 
7952  |  |  | 
7953  | 16.0k  | void normalize(std::u32string& input) { | 
7954  |  |   /**  | 
7955  |  |    * Normalize the domain_name string to Unicode Normalization Form C.  | 
7956  |  |    * @see https://www.unicode.org/reports/tr46/#ProcessingStepNormalize  | 
7957  |  |    */  | 
7958  | 16.0k  |   decompose_nfc(input);  | 
7959  | 16.0k  |   compose(input);  | 
7960  | 16.0k  | }  | 
7961  |  |  | 
7962  |  | }  // namespace ada::idna  | 
7963  |  | /* end file src/normalization.cpp */  | 
7964  |  | /* begin file src/punycode.cpp */  | 
7965  |  |  | 
7966  |  | #include <cstdint>  | 
7967  |  |  | 
7968  |  | namespace ada::idna { | 
7969  |  |  | 
7970  |  | constexpr int32_t base = 36;  | 
7971  |  | constexpr int32_t tmin = 1;  | 
7972  |  | constexpr int32_t tmax = 26;  | 
7973  |  | constexpr int32_t skew = 38;  | 
7974  |  | constexpr int32_t damp = 700;  | 
7975  |  | constexpr int32_t initial_bias = 72;  | 
7976  |  | constexpr uint32_t initial_n = 128;  | 
7977  |  |  | 
7978  | 93.7k  | static constexpr int32_t char_to_digit_value(char value) { | 
7979  | 93.7k  |   if (value >= 'a' && value <= 'z') return value - 'a';  | 
7980  | 24.8k  |   if (value >= '0' && value <= '9') return value - '0' + 26;  | 
7981  | 765  |   return -1;  | 
7982  | 24.8k  | }  | 
7983  |  |  | 
7984  | 336k  | static constexpr char digit_to_char(int32_t digit) { | 
7985  | 336k  |   return digit < 26 ? char(digit + 97) : char(digit + 22);  | 
7986  | 336k  | }  | 
7987  |  |  | 
7988  | 175k  | static constexpr int32_t adapt(int32_t d, int32_t n, bool firsttime) { | 
7989  | 175k  |   if (firsttime) { | 
7990  | 33.8k  |     d = d / damp;  | 
7991  | 141k  |   } else { | 
7992  | 141k  |     d = d / 2;  | 
7993  | 141k  |   }  | 
7994  | 175k  |   d += d / n;  | 
7995  | 175k  |   int32_t k = 0;  | 
7996  | 247k  |   while (d > ((base - tmin) * tmax) / 2) { | 
7997  | 72.0k  |     d /= base - tmin;  | 
7998  | 72.0k  |     k += base;  | 
7999  | 72.0k  |   }  | 
8000  | 175k  |   return k + (((base - tmin + 1) * d) / (d + skew));  | 
8001  | 175k  | }  | 
8002  |  |  | 
8003  | 11.4k  | bool punycode_to_utf32(std::string_view input, std::u32string &out) { | 
8004  | 11.4k  |   int32_t written_out{0}; | 
8005  | 11.4k  |   out.reserve(out.size() + input.size());  | 
8006  | 11.4k  |   uint32_t n = initial_n;  | 
8007  | 11.4k  |   int32_t i = 0;  | 
8008  | 11.4k  |   int32_t bias = initial_bias;  | 
8009  |  |   // grab ascii content  | 
8010  | 11.4k  |   size_t end_of_ascii = input.find_last_of('-'); | 
8011  | 11.4k  |   if (end_of_ascii != std::string_view::npos) { | 
8012  | 14.4k  |     for (uint8_t c : input.substr(0, end_of_ascii)) { | 
8013  | 14.4k  |       if (c >= 0x80) { | 
8014  | 0  |         return false;  | 
8015  | 0  |       }  | 
8016  | 14.4k  |       out.push_back(c);  | 
8017  | 14.4k  |       written_out++;  | 
8018  | 14.4k  |     }  | 
8019  | 3.96k  |     input.remove_prefix(end_of_ascii + 1);  | 
8020  | 3.96k  |   }  | 
8021  | 50.2k  |   while (!input.empty()) { | 
8022  | 39.0k  |     int32_t oldi = i;  | 
8023  | 39.0k  |     int32_t w = 1;  | 
8024  | 83.5k  |     for (int32_t k = base;; k += base) { | 
8025  | 83.5k  |       if (input.empty()) { | 
8026  | 112  |         return false;  | 
8027  | 112  |       }  | 
8028  | 83.4k  |       uint8_t code_point = input.front();  | 
8029  | 83.4k  |       input.remove_prefix(1);  | 
8030  | 83.4k  |       int32_t digit = char_to_digit_value(code_point);  | 
8031  | 83.4k  |       if (digit < 0) { | 
8032  | 102  |         return false;  | 
8033  | 102  |       }  | 
8034  | 83.3k  |       if (digit > (0x7fffffff - i) / w) { | 
8035  | 25  |         return false;  | 
8036  | 25  |       }  | 
8037  | 83.2k  |       i = i + digit * w;  | 
8038  | 83.2k  |       int32_t t = k <= bias ? tmin : k >= bias + tmax ? tmax : k - bias;  | 
8039  | 83.2k  |       if (digit < t) { | 
8040  | 38.8k  |         break;  | 
8041  | 38.8k  |       }  | 
8042  | 44.4k  |       if (w > 0x7fffffff / (base - t)) { | 
8043  | 0  |         return false;  | 
8044  | 0  |       }  | 
8045  | 44.4k  |       w = w * (base - t);  | 
8046  | 44.4k  |     }  | 
8047  | 38.8k  |     bias = adapt(i - oldi, written_out + 1, oldi == 0);  | 
8048  | 38.8k  |     if (i / (written_out + 1) > int32_t(0x7fffffff - n)) { | 
8049  | 38  |       return false;  | 
8050  | 38  |     }  | 
8051  | 38.7k  |     n = n + i / (written_out + 1);  | 
8052  | 38.7k  |     i = i % (written_out + 1);  | 
8053  | 38.7k  |     if (n < 0x80) { | 
8054  | 0  |       return false;  | 
8055  | 0  |     }  | 
8056  | 38.7k  |     out.insert(out.begin() + i, n);  | 
8057  | 38.7k  |     written_out++;  | 
8058  | 38.7k  |     ++i;  | 
8059  | 38.7k  |   }  | 
8060  |  |  | 
8061  | 11.2k  |   return true;  | 
8062  | 11.4k  | }  | 
8063  |  |  | 
8064  | 2.32k  | bool verify_punycode(std::string_view input) { | 
8065  | 2.32k  |   size_t written_out{0}; | 
8066  | 2.32k  |   uint32_t n = initial_n;  | 
8067  | 2.32k  |   int32_t i = 0;  | 
8068  | 2.32k  |   int32_t bias = initial_bias;  | 
8069  |  |   // grab ascii content  | 
8070  | 2.32k  |   size_t end_of_ascii = input.find_last_of('-'); | 
8071  | 2.32k  |   if (end_of_ascii != std::string_view::npos) { | 
8072  | 2.15k  |     for (uint8_t c : input.substr(0, end_of_ascii)) { | 
8073  | 2.15k  |       if (c >= 0x80) { | 
8074  | 0  |         return false;  | 
8075  | 0  |       }  | 
8076  | 2.15k  |       written_out++;  | 
8077  | 2.15k  |     }  | 
8078  | 650  |     input.remove_prefix(end_of_ascii + 1);  | 
8079  | 650  |   }  | 
8080  | 6.73k  |   while (!input.empty()) { | 
8081  | 5.30k  |     int32_t oldi = i;  | 
8082  | 5.30k  |     int32_t w = 1;  | 
8083  | 10.4k  |     for (int32_t k = base;; k += base) { | 
8084  | 10.4k  |       if (input.empty()) { | 
8085  | 128  |         return false;  | 
8086  | 128  |       }  | 
8087  | 10.3k  |       uint8_t code_point = input.front();  | 
8088  | 10.3k  |       input.remove_prefix(1);  | 
8089  | 10.3k  |       int32_t digit = char_to_digit_value(code_point);  | 
8090  | 10.3k  |       if (digit < 0) { | 
8091  | 663  |         return false;  | 
8092  | 663  |       }  | 
8093  | 9.65k  |       if (digit > (0x7fffffff - i) / w) { | 
8094  | 44  |         return false;  | 
8095  | 44  |       }  | 
8096  | 9.61k  |       i = i + digit * w;  | 
8097  | 9.61k  |       int32_t t = k <= bias ? tmin : k >= bias + tmax ? tmax : k - bias;  | 
8098  | 9.61k  |       if (digit < t) { | 
8099  | 4.46k  |         break;  | 
8100  | 4.46k  |       }  | 
8101  | 5.14k  |       if (w > 0x7fffffff / (base - t)) { | 
8102  | 0  |         return false;  | 
8103  | 0  |       }  | 
8104  | 5.14k  |       w = w * (base - t);  | 
8105  | 5.14k  |     }  | 
8106  | 4.46k  |     bias = adapt(i - oldi, int32_t(written_out + 1), oldi == 0);  | 
8107  | 4.46k  |     if (i / (written_out + 1) > 0x7fffffff - n) { | 
8108  | 57  |       return false;  | 
8109  | 57  |     }  | 
8110  | 4.41k  |     n = n + i / int32_t(written_out + 1);  | 
8111  | 4.41k  |     i = i % int32_t(written_out + 1);  | 
8112  | 4.41k  |     if (n < 0x80) { | 
8113  | 0  |       return false;  | 
8114  | 0  |     }  | 
8115  | 4.41k  |     written_out++;  | 
8116  | 4.41k  |     ++i;  | 
8117  | 4.41k  |   }  | 
8118  |  |  | 
8119  | 1.43k  |   return true;  | 
8120  | 2.32k  | }  | 
8121  |  |  | 
8122  | 24.4k  | bool utf32_to_punycode(std::u32string_view input, std::string &out) { | 
8123  | 24.4k  |   out.reserve(input.size() + out.size());  | 
8124  | 24.4k  |   uint32_t n = initial_n;  | 
8125  | 24.4k  |   int32_t d = 0;  | 
8126  | 24.4k  |   int32_t bias = initial_bias;  | 
8127  | 24.4k  |   size_t h = 0;  | 
8128  |  |   // first push the ascii content  | 
8129  | 169k  |   for (uint32_t c : input) { | 
8130  | 169k  |     if (c < 0x80) { | 
8131  | 37.5k  |       ++h;  | 
8132  | 37.5k  |       out.push_back(char(c));  | 
8133  | 37.5k  |     }  | 
8134  | 169k  |     if (c > 0x10ffff || (c >= 0xd880 && c < 0xe000)) { | 
8135  | 0  |       return false;  | 
8136  | 0  |     }  | 
8137  | 169k  |   }  | 
8138  | 24.4k  |   size_t b = h;  | 
8139  | 24.4k  |   if (b > 0) { | 
8140  | 7.16k  |     out.push_back('-'); | 
8141  | 7.16k  |   }  | 
8142  | 109k  |   while (h < input.size()) { | 
8143  | 84.6k  |     uint32_t m = 0x10FFFF;  | 
8144  | 1.30M  |     for (auto code_point : input) { | 
8145  | 1.30M  |       if (code_point >= n && code_point < m) m = code_point;  | 
8146  | 1.30M  |     }  | 
8147  |  |  | 
8148  | 84.6k  |     if ((m - n) > (0x7fffffff - d) / (h + 1)) { | 
8149  | 0  |       return false;  | 
8150  | 0  |     }  | 
8151  | 84.6k  |     d = d + int32_t((m - n) * (h + 1));  | 
8152  | 84.6k  |     n = m;  | 
8153  | 1.30M  |     for (auto c : input) { | 
8154  | 1.30M  |       if (c < n) { | 
8155  | 781k  |         if (d == 0x7fffffff) { | 
8156  | 0  |           return false;  | 
8157  | 0  |         }  | 
8158  | 781k  |         ++d;  | 
8159  | 781k  |       }  | 
8160  | 1.30M  |       if (c == n) { | 
8161  | 132k  |         int32_t q = d;  | 
8162  | 336k  |         for (int32_t k = base;; k += base) { | 
8163  | 336k  |           int32_t t = k <= bias ? tmin : k >= bias + tmax ? tmax : k - bias;  | 
8164  |  |  | 
8165  | 336k  |           if (q < t) { | 
8166  | 132k  |             break;  | 
8167  | 132k  |           }  | 
8168  | 204k  |           out.push_back(digit_to_char(t + ((q - t) % (base - t))));  | 
8169  | 204k  |           q = (q - t) / (base - t);  | 
8170  | 204k  |         }  | 
8171  | 132k  |         out.push_back(digit_to_char(q));  | 
8172  | 132k  |         bias = adapt(d, int32_t(h + 1), h == b);  | 
8173  | 132k  |         d = 0;  | 
8174  | 132k  |         ++h;  | 
8175  | 132k  |       }  | 
8176  | 1.30M  |     }  | 
8177  | 84.6k  |     ++d;  | 
8178  | 84.6k  |     ++n;  | 
8179  | 84.6k  |   }  | 
8180  | 24.4k  |   return true;  | 
8181  | 24.4k  | }  | 
8182  |  |  | 
8183  |  | }  // namespace ada::idna  | 
8184  |  | /* end file src/punycode.cpp */  | 
8185  |  | /* begin file src/validity.cpp */  | 
8186  |  | #include <algorithm>  | 
8187  |  | #include <string_view>  | 
8188  |  |  | 
8189  |  | namespace ada::idna { | 
8190  |  |  | 
8191  |  | enum direction : uint8_t { | 
8192  |  |   NONE,  | 
8193  |  |   BN,  | 
8194  |  |   CS,  | 
8195  |  |   ES,  | 
8196  |  |   ON,  | 
8197  |  |   EN,  | 
8198  |  |   L,  | 
8199  |  |   R,  | 
8200  |  |   NSM,  | 
8201  |  |   AL,  | 
8202  |  |   AN,  | 
8203  |  |   ET,  | 
8204  |  |   WS,  | 
8205  |  |   RLO,  | 
8206  |  |   LRO,  | 
8207  |  |   PDF,  | 
8208  |  |   RLE,  | 
8209  |  |   RLI,  | 
8210  |  |   FSI,  | 
8211  |  |   PDI,  | 
8212  |  |   LRI,  | 
8213  |  |   B,  | 
8214  |  |   S,  | 
8215  |  |   LRE  | 
8216  |  | };  | 
8217  |  |  | 
8218  |  | struct directions { | 
8219  |  |   uint32_t start_code;  | 
8220  |  |   uint32_t final_code;  | 
8221  |  |   direction direct;  | 
8222  |  | };  | 
8223  |  |  | 
8224  |  | static directions dir_table[] = { | 
8225  |  |     {0x0, 0x8, direction::BN},          {0x9, 0x9, direction::S}, | 
8226  |  |     {0xa, 0xa, direction::B},           {0xb, 0xb, direction::S}, | 
8227  |  |     {0xc, 0xc, direction::WS},          {0xd, 0xd, direction::B}, | 
8228  |  |     {0xe, 0x1b, direction::BN},         {0x1c, 0x1e, direction::B}, | 
8229  |  |     {0x1f, 0x1f, direction::S},         {0x20, 0x20, direction::WS}, | 
8230  |  |     {0x21, 0x22, direction::ON},        {0x23, 0x25, direction::ET}, | 
8231  |  |     {0x26, 0x2a, direction::ON},        {0x2b, 0x2b, direction::ES}, | 
8232  |  |     {0x2c, 0x2c, direction::CS},        {0x2d, 0x2d, direction::ES}, | 
8233  |  |     {0x2e, 0x2f, direction::CS},        {0x30, 0x39, direction::EN}, | 
8234  |  |     {0x3a, 0x3a, direction::CS},        {0x3b, 0x40, direction::ON}, | 
8235  |  |     {0x41, 0x5a, direction::L},         {0x5b, 0x60, direction::ON}, | 
8236  |  |     {0x61, 0x7a, direction::L},         {0x7b, 0x7e, direction::ON}, | 
8237  |  |     {0x7f, 0x84, direction::BN},        {0x85, 0x85, direction::B}, | 
8238  |  |     {0x86, 0x9f, direction::BN},        {0xa0, 0xa0, direction::CS}, | 
8239  |  |     {0xa1, 0xa1, direction::ON},        {0xa2, 0xa5, direction::ET}, | 
8240  |  |     {0xa6, 0xa9, direction::ON},        {0xaa, 0xaa, direction::L}, | 
8241  |  |     {0xab, 0xac, direction::ON},        {0xad, 0xad, direction::BN}, | 
8242  |  |     {0xae, 0xaf, direction::ON},        {0xb0, 0xb1, direction::ET}, | 
8243  |  |     {0xb2, 0xb3, direction::EN},        {0xb4, 0xb4, direction::ON}, | 
8244  |  |     {0xb5, 0xb5, direction::L},         {0xb6, 0xb8, direction::ON}, | 
8245  |  |     {0xb9, 0xb9, direction::EN},        {0xba, 0xba, direction::L}, | 
8246  |  |     {0xbb, 0xbf, direction::ON},        {0xc0, 0xd6, direction::L}, | 
8247  |  |     {0xd7, 0xd7, direction::ON},        {0xd8, 0xf6, direction::L}, | 
8248  |  |     {0xf7, 0xf7, direction::ON},        {0xf8, 0x2b8, direction::L}, | 
8249  |  |     {0x2b9, 0x2ba, direction::ON},      {0x2bb, 0x2c1, direction::L}, | 
8250  |  |     {0x2c2, 0x2cf, direction::ON},      {0x2d0, 0x2d1, direction::L}, | 
8251  |  |     {0x2d2, 0x2df, direction::ON},      {0x2e0, 0x2e4, direction::L}, | 
8252  |  |     {0x2e5, 0x2ed, direction::ON},      {0x2ee, 0x2ee, direction::L}, | 
8253  |  |     {0x2ef, 0x2ff, direction::ON},      {0x300, 0x36f, direction::NSM}, | 
8254  |  |     {0x370, 0x373, direction::L},       {0x374, 0x375, direction::ON}, | 
8255  |  |     {0x376, 0x377, direction::L},       {0x37a, 0x37d, direction::L}, | 
8256  |  |     {0x37e, 0x37e, direction::ON},      {0x37f, 0x37f, direction::L}, | 
8257  |  |     {0x384, 0x385, direction::ON},      {0x386, 0x386, direction::L}, | 
8258  |  |     {0x387, 0x387, direction::ON},      {0x388, 0x38a, direction::L}, | 
8259  |  |     {0x38c, 0x38c, direction::L},       {0x38e, 0x3a1, direction::L}, | 
8260  |  |     {0x3a3, 0x3f5, direction::L},       {0x3f6, 0x3f6, direction::ON}, | 
8261  |  |     {0x3f7, 0x482, direction::L},       {0x483, 0x489, direction::NSM}, | 
8262  |  |     {0x48a, 0x52f, direction::L},       {0x531, 0x556, direction::L}, | 
8263  |  |     {0x559, 0x589, direction::L},       {0x58a, 0x58a, direction::ON}, | 
8264  |  |     {0x58d, 0x58e, direction::ON},      {0x58f, 0x58f, direction::ET}, | 
8265  |  |     {0x591, 0x5bd, direction::NSM},     {0x5be, 0x5be, direction::R}, | 
8266  |  |     {0x5bf, 0x5bf, direction::NSM},     {0x5c0, 0x5c0, direction::R}, | 
8267  |  |     {0x5c1, 0x5c2, direction::NSM},     {0x5c3, 0x5c3, direction::R}, | 
8268  |  |     {0x5c4, 0x5c5, direction::NSM},     {0x5c6, 0x5c6, direction::R}, | 
8269  |  |     {0x5c7, 0x5c7, direction::NSM},     {0x5d0, 0x5ea, direction::R}, | 
8270  |  |     {0x5ef, 0x5f4, direction::R},       {0x600, 0x605, direction::AN}, | 
8271  |  |     {0x606, 0x607, direction::ON},      {0x608, 0x608, direction::AL}, | 
8272  |  |     {0x609, 0x60a, direction::ET},      {0x60b, 0x60b, direction::AL}, | 
8273  |  |     {0x60c, 0x60c, direction::CS},      {0x60d, 0x60d, direction::AL}, | 
8274  |  |     {0x60e, 0x60f, direction::ON},      {0x610, 0x61a, direction::NSM}, | 
8275  |  |     {0x61b, 0x61c, direction::AL},      {0x61e, 0x64a, direction::AL}, | 
8276  |  |     {0x64b, 0x65f, direction::NSM},     {0x660, 0x669, direction::AN}, | 
8277  |  |     {0x66a, 0x66a, direction::ET},      {0x66b, 0x66c, direction::AN}, | 
8278  |  |     {0x66d, 0x66f, direction::AL},      {0x670, 0x670, direction::NSM}, | 
8279  |  |     {0x671, 0x6d5, direction::AL},      {0x6d6, 0x6dc, direction::NSM}, | 
8280  |  |     {0x6dd, 0x6dd, direction::AN},      {0x6de, 0x6de, direction::ON}, | 
8281  |  |     {0x6df, 0x6e4, direction::NSM},     {0x6e5, 0x6e6, direction::AL}, | 
8282  |  |     {0x6e7, 0x6e8, direction::NSM},     {0x6e9, 0x6e9, direction::ON}, | 
8283  |  |     {0x6ea, 0x6ed, direction::NSM},     {0x6ee, 0x6ef, direction::AL}, | 
8284  |  |     {0x6f0, 0x6f9, direction::EN},      {0x6fa, 0x70d, direction::AL}, | 
8285  |  |     {0x70f, 0x710, direction::AL},      {0x711, 0x711, direction::NSM}, | 
8286  |  |     {0x712, 0x72f, direction::AL},      {0x730, 0x74a, direction::NSM}, | 
8287  |  |     {0x74d, 0x7a5, direction::AL},      {0x7a6, 0x7b0, direction::NSM}, | 
8288  |  |     {0x7b1, 0x7b1, direction::AL},      {0x7c0, 0x7ea, direction::R}, | 
8289  |  |     {0x7eb, 0x7f3, direction::NSM},     {0x7f4, 0x7f5, direction::R}, | 
8290  |  |     {0x7f6, 0x7f9, direction::ON},      {0x7fa, 0x7fa, direction::R}, | 
8291  |  |     {0x7fd, 0x7fd, direction::NSM},     {0x7fe, 0x815, direction::R}, | 
8292  |  |     {0x816, 0x819, direction::NSM},     {0x81a, 0x81a, direction::R}, | 
8293  |  |     {0x81b, 0x823, direction::NSM},     {0x824, 0x824, direction::R}, | 
8294  |  |     {0x825, 0x827, direction::NSM},     {0x828, 0x828, direction::R}, | 
8295  |  |     {0x829, 0x82d, direction::NSM},     {0x830, 0x83e, direction::R}, | 
8296  |  |     {0x840, 0x858, direction::R},       {0x859, 0x85b, direction::NSM}, | 
8297  |  |     {0x85e, 0x85e, direction::R},       {0x860, 0x86a, direction::AL}, | 
8298  |  |     {0x8a0, 0x8b4, direction::AL},      {0x8b6, 0x8c7, direction::AL}, | 
8299  |  |     {0x8d3, 0x8e1, direction::NSM},     {0x8e2, 0x8e2, direction::AN}, | 
8300  |  |     {0x8e3, 0x902, direction::NSM},     {0x903, 0x939, direction::L}, | 
8301  |  |     {0x93a, 0x93a, direction::NSM},     {0x93b, 0x93b, direction::L}, | 
8302  |  |     {0x93c, 0x93c, direction::NSM},     {0x93d, 0x940, direction::L}, | 
8303  |  |     {0x941, 0x948, direction::NSM},     {0x949, 0x94c, direction::L}, | 
8304  |  |     {0x94d, 0x94d, direction::NSM},     {0x94e, 0x950, direction::L}, | 
8305  |  |     {0x951, 0x957, direction::NSM},     {0x958, 0x961, direction::L}, | 
8306  |  |     {0x962, 0x963, direction::NSM},     {0x964, 0x980, direction::L}, | 
8307  |  |     {0x981, 0x981, direction::NSM},     {0x982, 0x983, direction::L}, | 
8308  |  |     {0x985, 0x98c, direction::L},       {0x98f, 0x990, direction::L}, | 
8309  |  |     {0x993, 0x9a8, direction::L},       {0x9aa, 0x9b0, direction::L}, | 
8310  |  |     {0x9b2, 0x9b2, direction::L},       {0x9b6, 0x9b9, direction::L}, | 
8311  |  |     {0x9bc, 0x9bc, direction::NSM},     {0x9bd, 0x9c0, direction::L}, | 
8312  |  |     {0x9c1, 0x9c4, direction::NSM},     {0x9c7, 0x9c8, direction::L}, | 
8313  |  |     {0x9cb, 0x9cc, direction::L},       {0x9cd, 0x9cd, direction::NSM}, | 
8314  |  |     {0x9ce, 0x9ce, direction::L},       {0x9d7, 0x9d7, direction::L}, | 
8315  |  |     {0x9dc, 0x9dd, direction::L},       {0x9df, 0x9e1, direction::L}, | 
8316  |  |     {0x9e2, 0x9e3, direction::NSM},     {0x9e6, 0x9f1, direction::L}, | 
8317  |  |     {0x9f2, 0x9f3, direction::ET},      {0x9f4, 0x9fa, direction::L}, | 
8318  |  |     {0x9fb, 0x9fb, direction::ET},      {0x9fc, 0x9fd, direction::L}, | 
8319  |  |     {0x9fe, 0x9fe, direction::NSM},     {0xa01, 0xa02, direction::NSM}, | 
8320  |  |     {0xa03, 0xa03, direction::L},       {0xa05, 0xa0a, direction::L}, | 
8321  |  |     {0xa0f, 0xa10, direction::L},       {0xa13, 0xa28, direction::L}, | 
8322  |  |     {0xa2a, 0xa30, direction::L},       {0xa32, 0xa33, direction::L}, | 
8323  |  |     {0xa35, 0xa36, direction::L},       {0xa38, 0xa39, direction::L}, | 
8324  |  |     {0xa3c, 0xa3c, direction::NSM},     {0xa3e, 0xa40, direction::L}, | 
8325  |  |     {0xa41, 0xa42, direction::NSM},     {0xa47, 0xa48, direction::NSM}, | 
8326  |  |     {0xa4b, 0xa4d, direction::NSM},     {0xa51, 0xa51, direction::NSM}, | 
8327  |  |     {0xa59, 0xa5c, direction::L},       {0xa5e, 0xa5e, direction::L}, | 
8328  |  |     {0xa66, 0xa6f, direction::L},       {0xa70, 0xa71, direction::NSM}, | 
8329  |  |     {0xa72, 0xa74, direction::L},       {0xa75, 0xa75, direction::NSM}, | 
8330  |  |     {0xa76, 0xa76, direction::L},       {0xa81, 0xa82, direction::NSM}, | 
8331  |  |     {0xa83, 0xa83, direction::L},       {0xa85, 0xa8d, direction::L}, | 
8332  |  |     {0xa8f, 0xa91, direction::L},       {0xa93, 0xaa8, direction::L}, | 
8333  |  |     {0xaaa, 0xab0, direction::L},       {0xab2, 0xab3, direction::L}, | 
8334  |  |     {0xab5, 0xab9, direction::L},       {0xabc, 0xabc, direction::NSM}, | 
8335  |  |     {0xabd, 0xac0, direction::L},       {0xac1, 0xac5, direction::NSM}, | 
8336  |  |     {0xac7, 0xac8, direction::NSM},     {0xac9, 0xac9, direction::L}, | 
8337  |  |     {0xacb, 0xacc, direction::L},       {0xacd, 0xacd, direction::NSM}, | 
8338  |  |     {0xad0, 0xad0, direction::L},       {0xae0, 0xae1, direction::L}, | 
8339  |  |     {0xae2, 0xae3, direction::NSM},     {0xae6, 0xaf0, direction::L}, | 
8340  |  |     {0xaf1, 0xaf1, direction::ET},      {0xaf9, 0xaf9, direction::L}, | 
8341  |  |     {0xafa, 0xaff, direction::NSM},     {0xb01, 0xb01, direction::NSM}, | 
8342  |  |     {0xb02, 0xb03, direction::L},       {0xb05, 0xb0c, direction::L}, | 
8343  |  |     {0xb0f, 0xb10, direction::L},       {0xb13, 0xb28, direction::L}, | 
8344  |  |     {0xb2a, 0xb30, direction::L},       {0xb32, 0xb33, direction::L}, | 
8345  |  |     {0xb35, 0xb39, direction::L},       {0xb3c, 0xb3c, direction::NSM}, | 
8346  |  |     {0xb3d, 0xb3e, direction::L},       {0xb3f, 0xb3f, direction::NSM}, | 
8347  |  |     {0xb40, 0xb40, direction::L},       {0xb41, 0xb44, direction::NSM}, | 
8348  |  |     {0xb47, 0xb48, direction::L},       {0xb4b, 0xb4c, direction::L}, | 
8349  |  |     {0xb4d, 0xb4d, direction::NSM},     {0xb55, 0xb56, direction::NSM}, | 
8350  |  |     {0xb57, 0xb57, direction::L},       {0xb5c, 0xb5d, direction::L}, | 
8351  |  |     {0xb5f, 0xb61, direction::L},       {0xb62, 0xb63, direction::NSM}, | 
8352  |  |     {0xb66, 0xb77, direction::L},       {0xb82, 0xb82, direction::NSM}, | 
8353  |  |     {0xb83, 0xb83, direction::L},       {0xb85, 0xb8a, direction::L}, | 
8354  |  |     {0xb8e, 0xb90, direction::L},       {0xb92, 0xb95, direction::L}, | 
8355  |  |     {0xb99, 0xb9a, direction::L},       {0xb9c, 0xb9c, direction::L}, | 
8356  |  |     {0xb9e, 0xb9f, direction::L},       {0xba3, 0xba4, direction::L}, | 
8357  |  |     {0xba8, 0xbaa, direction::L},       {0xbae, 0xbb9, direction::L}, | 
8358  |  |     {0xbbe, 0xbbf, direction::L},       {0xbc0, 0xbc0, direction::NSM}, | 
8359  |  |     {0xbc1, 0xbc2, direction::L},       {0xbc6, 0xbc8, direction::L}, | 
8360  |  |     {0xbca, 0xbcc, direction::L},       {0xbcd, 0xbcd, direction::NSM}, | 
8361  |  |     {0xbd0, 0xbd0, direction::L},       {0xbd7, 0xbd7, direction::L}, | 
8362  |  |     {0xbe6, 0xbf2, direction::L},       {0xbf3, 0xbf8, direction::ON}, | 
8363  |  |     {0xbf9, 0xbf9, direction::ET},      {0xbfa, 0xbfa, direction::ON}, | 
8364  |  |     {0xc00, 0xc00, direction::NSM},     {0xc01, 0xc03, direction::L}, | 
8365  |  |     {0xc04, 0xc04, direction::NSM},     {0xc05, 0xc0c, direction::L}, | 
8366  |  |     {0xc0e, 0xc10, direction::L},       {0xc12, 0xc28, direction::L}, | 
8367  |  |     {0xc2a, 0xc39, direction::L},       {0xc3d, 0xc3d, direction::L}, | 
8368  |  |     {0xc3e, 0xc40, direction::NSM},     {0xc41, 0xc44, direction::L}, | 
8369  |  |     {0xc46, 0xc48, direction::NSM},     {0xc4a, 0xc4d, direction::NSM}, | 
8370  |  |     {0xc55, 0xc56, direction::NSM},     {0xc58, 0xc5a, direction::L}, | 
8371  |  |     {0xc60, 0xc61, direction::L},       {0xc62, 0xc63, direction::NSM}, | 
8372  |  |     {0xc66, 0xc6f, direction::L},       {0xc77, 0xc77, direction::L}, | 
8373  |  |     {0xc78, 0xc7e, direction::ON},      {0xc7f, 0xc80, direction::L}, | 
8374  |  |     {0xc81, 0xc81, direction::NSM},     {0xc82, 0xc8c, direction::L}, | 
8375  |  |     {0xc8e, 0xc90, direction::L},       {0xc92, 0xca8, direction::L}, | 
8376  |  |     {0xcaa, 0xcb3, direction::L},       {0xcb5, 0xcb9, direction::L}, | 
8377  |  |     {0xcbc, 0xcbc, direction::NSM},     {0xcbd, 0xcc4, direction::L}, | 
8378  |  |     {0xcc6, 0xcc8, direction::L},       {0xcca, 0xccb, direction::L}, | 
8379  |  |     {0xccc, 0xccd, direction::NSM},     {0xcd5, 0xcd6, direction::L}, | 
8380  |  |     {0xcde, 0xcde, direction::L},       {0xce0, 0xce1, direction::L}, | 
8381  |  |     {0xce2, 0xce3, direction::NSM},     {0xce6, 0xcef, direction::L}, | 
8382  |  |     {0xcf1, 0xcf2, direction::L},       {0xd00, 0xd01, direction::NSM}, | 
8383  |  |     {0xd02, 0xd0c, direction::L},       {0xd0e, 0xd10, direction::L}, | 
8384  |  |     {0xd12, 0xd3a, direction::L},       {0xd3b, 0xd3c, direction::NSM}, | 
8385  |  |     {0xd3d, 0xd40, direction::L},       {0xd41, 0xd44, direction::NSM}, | 
8386  |  |     {0xd46, 0xd48, direction::L},       {0xd4a, 0xd4c, direction::L}, | 
8387  |  |     {0xd4d, 0xd4d, direction::NSM},     {0xd4e, 0xd4f, direction::L}, | 
8388  |  |     {0xd54, 0xd61, direction::L},       {0xd62, 0xd63, direction::NSM}, | 
8389  |  |     {0xd66, 0xd7f, direction::L},       {0xd81, 0xd81, direction::NSM}, | 
8390  |  |     {0xd82, 0xd83, direction::L},       {0xd85, 0xd96, direction::L}, | 
8391  |  |     {0xd9a, 0xdb1, direction::L},       {0xdb3, 0xdbb, direction::L}, | 
8392  |  |     {0xdbd, 0xdbd, direction::L},       {0xdc0, 0xdc6, direction::L}, | 
8393  |  |     {0xdca, 0xdca, direction::NSM},     {0xdcf, 0xdd1, direction::L}, | 
8394  |  |     {0xdd2, 0xdd4, direction::NSM},     {0xdd6, 0xdd6, direction::NSM}, | 
8395  |  |     {0xdd8, 0xddf, direction::L},       {0xde6, 0xdef, direction::L}, | 
8396  |  |     {0xdf2, 0xdf4, direction::L},       {0xe01, 0xe30, direction::L}, | 
8397  |  |     {0xe31, 0xe31, direction::NSM},     {0xe32, 0xe33, direction::L}, | 
8398  |  |     {0xe34, 0xe3a, direction::NSM},     {0xe3f, 0xe3f, direction::ET}, | 
8399  |  |     {0xe40, 0xe46, direction::L},       {0xe47, 0xe4e, direction::NSM}, | 
8400  |  |     {0xe4f, 0xe5b, direction::L},       {0xe81, 0xe82, direction::L}, | 
8401  |  |     {0xe84, 0xe84, direction::L},       {0xe86, 0xe8a, direction::L}, | 
8402  |  |     {0xe8c, 0xea3, direction::L},       {0xea5, 0xea5, direction::L}, | 
8403  |  |     {0xea7, 0xeb0, direction::L},       {0xeb1, 0xeb1, direction::NSM}, | 
8404  |  |     {0xeb2, 0xeb3, direction::L},       {0xeb4, 0xebc, direction::NSM}, | 
8405  |  |     {0xebd, 0xebd, direction::L},       {0xec0, 0xec4, direction::L}, | 
8406  |  |     {0xec6, 0xec6, direction::L},       {0xec8, 0xecd, direction::NSM}, | 
8407  |  |     {0xed0, 0xed9, direction::L},       {0xedc, 0xedf, direction::L}, | 
8408  |  |     {0xf00, 0xf17, direction::L},       {0xf18, 0xf19, direction::NSM}, | 
8409  |  |     {0xf1a, 0xf34, direction::L},       {0xf35, 0xf35, direction::NSM}, | 
8410  |  |     {0xf36, 0xf36, direction::L},       {0xf37, 0xf37, direction::NSM}, | 
8411  |  |     {0xf38, 0xf38, direction::L},       {0xf39, 0xf39, direction::NSM}, | 
8412  |  |     {0xf3a, 0xf3d, direction::ON},      {0xf3e, 0xf47, direction::L}, | 
8413  |  |     {0xf49, 0xf6c, direction::L},       {0xf71, 0xf7e, direction::NSM}, | 
8414  |  |     {0xf7f, 0xf7f, direction::L},       {0xf80, 0xf84, direction::NSM}, | 
8415  |  |     {0xf85, 0xf85, direction::L},       {0xf86, 0xf87, direction::NSM}, | 
8416  |  |     {0xf88, 0xf8c, direction::L},       {0xf8d, 0xf97, direction::NSM}, | 
8417  |  |     {0xf99, 0xfbc, direction::NSM},     {0xfbe, 0xfc5, direction::L}, | 
8418  |  |     {0xfc6, 0xfc6, direction::NSM},     {0xfc7, 0xfcc, direction::L}, | 
8419  |  |     {0xfce, 0xfda, direction::L},       {0x1000, 0x102c, direction::L}, | 
8420  |  |     {0x102d, 0x1030, direction::NSM},   {0x1031, 0x1031, direction::L}, | 
8421  |  |     {0x1032, 0x1037, direction::NSM},   {0x1038, 0x1038, direction::L}, | 
8422  |  |     {0x1039, 0x103a, direction::NSM},   {0x103b, 0x103c, direction::L}, | 
8423  |  |     {0x103d, 0x103e, direction::NSM},   {0x103f, 0x1057, direction::L}, | 
8424  |  |     {0x1058, 0x1059, direction::NSM},   {0x105a, 0x105d, direction::L}, | 
8425  |  |     {0x105e, 0x1060, direction::NSM},   {0x1061, 0x1070, direction::L}, | 
8426  |  |     {0x1071, 0x1074, direction::NSM},   {0x1075, 0x1081, direction::L}, | 
8427  |  |     {0x1082, 0x1082, direction::NSM},   {0x1083, 0x1084, direction::L}, | 
8428  |  |     {0x1085, 0x1086, direction::NSM},   {0x1087, 0x108c, direction::L}, | 
8429  |  |     {0x108d, 0x108d, direction::NSM},   {0x108e, 0x109c, direction::L}, | 
8430  |  |     {0x109d, 0x109d, direction::NSM},   {0x109e, 0x10c5, direction::L}, | 
8431  |  |     {0x10c7, 0x10c7, direction::L},     {0x10cd, 0x10cd, direction::L}, | 
8432  |  |     {0x10d0, 0x1248, direction::L},     {0x124a, 0x124d, direction::L}, | 
8433  |  |     {0x1250, 0x1256, direction::L},     {0x1258, 0x1258, direction::L}, | 
8434  |  |     {0x125a, 0x125d, direction::L},     {0x1260, 0x1288, direction::L}, | 
8435  |  |     {0x128a, 0x128d, direction::L},     {0x1290, 0x12b0, direction::L}, | 
8436  |  |     {0x12b2, 0x12b5, direction::L},     {0x12b8, 0x12be, direction::L}, | 
8437  |  |     {0x12c0, 0x12c0, direction::L},     {0x12c2, 0x12c5, direction::L}, | 
8438  |  |     {0x12c8, 0x12d6, direction::L},     {0x12d8, 0x1310, direction::L}, | 
8439  |  |     {0x1312, 0x1315, direction::L},     {0x1318, 0x135a, direction::L}, | 
8440  |  |     {0x135d, 0x135f, direction::NSM},   {0x1360, 0x137c, direction::L}, | 
8441  |  |     {0x1380, 0x138f, direction::L},     {0x1390, 0x1399, direction::ON}, | 
8442  |  |     {0x13a0, 0x13f5, direction::L},     {0x13f8, 0x13fd, direction::L}, | 
8443  |  |     {0x1400, 0x1400, direction::ON},    {0x1401, 0x167f, direction::L}, | 
8444  |  |     {0x1680, 0x1680, direction::WS},    {0x1681, 0x169a, direction::L}, | 
8445  |  |     {0x169b, 0x169c, direction::ON},    {0x16a0, 0x16f8, direction::L}, | 
8446  |  |     {0x1700, 0x170c, direction::L},     {0x170e, 0x1711, direction::L}, | 
8447  |  |     {0x1712, 0x1714, direction::NSM},   {0x1720, 0x1731, direction::L}, | 
8448  |  |     {0x1732, 0x1734, direction::NSM},   {0x1735, 0x1736, direction::L}, | 
8449  |  |     {0x1740, 0x1751, direction::L},     {0x1752, 0x1753, direction::NSM}, | 
8450  |  |     {0x1760, 0x176c, direction::L},     {0x176e, 0x1770, direction::L}, | 
8451  |  |     {0x1772, 0x1773, direction::NSM},   {0x1780, 0x17b3, direction::L}, | 
8452  |  |     {0x17b4, 0x17b5, direction::NSM},   {0x17b6, 0x17b6, direction::L}, | 
8453  |  |     {0x17b7, 0x17bd, direction::NSM},   {0x17be, 0x17c5, direction::L}, | 
8454  |  |     {0x17c6, 0x17c6, direction::NSM},   {0x17c7, 0x17c8, direction::L}, | 
8455  |  |     {0x17c9, 0x17d3, direction::NSM},   {0x17d4, 0x17da, direction::L}, | 
8456  |  |     {0x17db, 0x17db, direction::ET},    {0x17dc, 0x17dc, direction::L}, | 
8457  |  |     {0x17dd, 0x17dd, direction::NSM},   {0x17e0, 0x17e9, direction::L}, | 
8458  |  |     {0x17f0, 0x17f9, direction::ON},    {0x1800, 0x180a, direction::ON}, | 
8459  |  |     {0x180b, 0x180d, direction::NSM},   {0x180e, 0x180e, direction::BN}, | 
8460  |  |     {0x1810, 0x1819, direction::L},     {0x1820, 0x1878, direction::L}, | 
8461  |  |     {0x1880, 0x1884, direction::L},     {0x1885, 0x1886, direction::NSM}, | 
8462  |  |     {0x1887, 0x18a8, direction::L},     {0x18a9, 0x18a9, direction::NSM}, | 
8463  |  |     {0x18aa, 0x18aa, direction::L},     {0x18b0, 0x18f5, direction::L}, | 
8464  |  |     {0x1900, 0x191e, direction::L},     {0x1920, 0x1922, direction::NSM}, | 
8465  |  |     {0x1923, 0x1926, direction::L},     {0x1927, 0x1928, direction::NSM}, | 
8466  |  |     {0x1929, 0x192b, direction::L},     {0x1930, 0x1931, direction::L}, | 
8467  |  |     {0x1932, 0x1932, direction::NSM},   {0x1933, 0x1938, direction::L}, | 
8468  |  |     {0x1939, 0x193b, direction::NSM},   {0x1940, 0x1940, direction::ON}, | 
8469  |  |     {0x1944, 0x1945, direction::ON},    {0x1946, 0x196d, direction::L}, | 
8470  |  |     {0x1970, 0x1974, direction::L},     {0x1980, 0x19ab, direction::L}, | 
8471  |  |     {0x19b0, 0x19c9, direction::L},     {0x19d0, 0x19da, direction::L}, | 
8472  |  |     {0x19de, 0x19ff, direction::ON},    {0x1a00, 0x1a16, direction::L}, | 
8473  |  |     {0x1a17, 0x1a18, direction::NSM},   {0x1a19, 0x1a1a, direction::L}, | 
8474  |  |     {0x1a1b, 0x1a1b, direction::NSM},   {0x1a1e, 0x1a55, direction::L}, | 
8475  |  |     {0x1a56, 0x1a56, direction::NSM},   {0x1a57, 0x1a57, direction::L}, | 
8476  |  |     {0x1a58, 0x1a5e, direction::NSM},   {0x1a60, 0x1a60, direction::NSM}, | 
8477  |  |     {0x1a61, 0x1a61, direction::L},     {0x1a62, 0x1a62, direction::NSM}, | 
8478  |  |     {0x1a63, 0x1a64, direction::L},     {0x1a65, 0x1a6c, direction::NSM}, | 
8479  |  |     {0x1a6d, 0x1a72, direction::L},     {0x1a73, 0x1a7c, direction::NSM}, | 
8480  |  |     {0x1a7f, 0x1a7f, direction::NSM},   {0x1a80, 0x1a89, direction::L}, | 
8481  |  |     {0x1a90, 0x1a99, direction::L},     {0x1aa0, 0x1aad, direction::L}, | 
8482  |  |     {0x1ab0, 0x1ac0, direction::NSM},   {0x1b00, 0x1b03, direction::NSM}, | 
8483  |  |     {0x1b04, 0x1b33, direction::L},     {0x1b34, 0x1b34, direction::NSM}, | 
8484  |  |     {0x1b35, 0x1b35, direction::L},     {0x1b36, 0x1b3a, direction::NSM}, | 
8485  |  |     {0x1b3b, 0x1b3b, direction::L},     {0x1b3c, 0x1b3c, direction::NSM}, | 
8486  |  |     {0x1b3d, 0x1b41, direction::L},     {0x1b42, 0x1b42, direction::NSM}, | 
8487  |  |     {0x1b43, 0x1b4b, direction::L},     {0x1b50, 0x1b6a, direction::L}, | 
8488  |  |     {0x1b6b, 0x1b73, direction::NSM},   {0x1b74, 0x1b7c, direction::L}, | 
8489  |  |     {0x1b80, 0x1b81, direction::NSM},   {0x1b82, 0x1ba1, direction::L}, | 
8490  |  |     {0x1ba2, 0x1ba5, direction::NSM},   {0x1ba6, 0x1ba7, direction::L}, | 
8491  |  |     {0x1ba8, 0x1ba9, direction::NSM},   {0x1baa, 0x1baa, direction::L}, | 
8492  |  |     {0x1bab, 0x1bad, direction::NSM},   {0x1bae, 0x1be5, direction::L}, | 
8493  |  |     {0x1be6, 0x1be6, direction::NSM},   {0x1be7, 0x1be7, direction::L}, | 
8494  |  |     {0x1be8, 0x1be9, direction::NSM},   {0x1bea, 0x1bec, direction::L}, | 
8495  |  |     {0x1bed, 0x1bed, direction::NSM},   {0x1bee, 0x1bee, direction::L}, | 
8496  |  |     {0x1bef, 0x1bf1, direction::NSM},   {0x1bf2, 0x1bf3, direction::L}, | 
8497  |  |     {0x1bfc, 0x1c2b, direction::L},     {0x1c2c, 0x1c33, direction::NSM}, | 
8498  |  |     {0x1c34, 0x1c35, direction::L},     {0x1c36, 0x1c37, direction::NSM}, | 
8499  |  |     {0x1c3b, 0x1c49, direction::L},     {0x1c4d, 0x1c88, direction::L}, | 
8500  |  |     {0x1c90, 0x1cba, direction::L},     {0x1cbd, 0x1cc7, direction::L}, | 
8501  |  |     {0x1cd0, 0x1cd2, direction::NSM},   {0x1cd3, 0x1cd3, direction::L}, | 
8502  |  |     {0x1cd4, 0x1ce0, direction::NSM},   {0x1ce1, 0x1ce1, direction::L}, | 
8503  |  |     {0x1ce2, 0x1ce8, direction::NSM},   {0x1ce9, 0x1cec, direction::L}, | 
8504  |  |     {0x1ced, 0x1ced, direction::NSM},   {0x1cee, 0x1cf3, direction::L}, | 
8505  |  |     {0x1cf4, 0x1cf4, direction::NSM},   {0x1cf5, 0x1cf7, direction::L}, | 
8506  |  |     {0x1cf8, 0x1cf9, direction::NSM},   {0x1cfa, 0x1cfa, direction::L}, | 
8507  |  |     {0x1d00, 0x1dbf, direction::L},     {0x1dc0, 0x1df9, direction::NSM}, | 
8508  |  |     {0x1dfb, 0x1dff, direction::NSM},   {0x1e00, 0x1f15, direction::L}, | 
8509  |  |     {0x1f18, 0x1f1d, direction::L},     {0x1f20, 0x1f45, direction::L}, | 
8510  |  |     {0x1f48, 0x1f4d, direction::L},     {0x1f50, 0x1f57, direction::L}, | 
8511  |  |     {0x1f59, 0x1f59, direction::L},     {0x1f5b, 0x1f5b, direction::L}, | 
8512  |  |     {0x1f5d, 0x1f5d, direction::L},     {0x1f5f, 0x1f7d, direction::L}, | 
8513  |  |     {0x1f80, 0x1fb4, direction::L},     {0x1fb6, 0x1fbc, direction::L}, | 
8514  |  |     {0x1fbd, 0x1fbd, direction::ON},    {0x1fbe, 0x1fbe, direction::L}, | 
8515  |  |     {0x1fbf, 0x1fc1, direction::ON},    {0x1fc2, 0x1fc4, direction::L}, | 
8516  |  |     {0x1fc6, 0x1fcc, direction::L},     {0x1fcd, 0x1fcf, direction::ON}, | 
8517  |  |     {0x1fd0, 0x1fd3, direction::L},     {0x1fd6, 0x1fdb, direction::L}, | 
8518  |  |     {0x1fdd, 0x1fdf, direction::ON},    {0x1fe0, 0x1fec, direction::L}, | 
8519  |  |     {0x1fed, 0x1fef, direction::ON},    {0x1ff2, 0x1ff4, direction::L}, | 
8520  |  |     {0x1ff6, 0x1ffc, direction::L},     {0x1ffd, 0x1ffe, direction::ON}, | 
8521  |  |     {0x2000, 0x200a, direction::WS},    {0x200b, 0x200d, direction::BN}, | 
8522  |  |     {0x200e, 0x200e, direction::L},     {0x200f, 0x200f, direction::R}, | 
8523  |  |     {0x2010, 0x2027, direction::ON},    {0x2028, 0x2028, direction::WS}, | 
8524  |  |     {0x2029, 0x2029, direction::B},     {0x202a, 0x202a, direction::LRE}, | 
8525  |  |     {0x202b, 0x202b, direction::RLE},   {0x202c, 0x202c, direction::PDF}, | 
8526  |  |     {0x202d, 0x202d, direction::LRO},   {0x202e, 0x202e, direction::RLO}, | 
8527  |  |     {0x202f, 0x202f, direction::CS},    {0x2030, 0x2034, direction::ET}, | 
8528  |  |     {0x2035, 0x2043, direction::ON},    {0x2044, 0x2044, direction::CS}, | 
8529  |  |     {0x2045, 0x205e, direction::ON},    {0x205f, 0x205f, direction::WS}, | 
8530  |  |     {0x2060, 0x2064, direction::BN},    {0x2066, 0x2066, direction::LRI}, | 
8531  |  |     {0x2067, 0x2067, direction::RLI},   {0x2068, 0x2068, direction::FSI}, | 
8532  |  |     {0x2069, 0x2069, direction::PDI},   {0x206a, 0x206f, direction::BN}, | 
8533  |  |     {0x2070, 0x2070, direction::EN},    {0x2071, 0x2071, direction::L}, | 
8534  |  |     {0x2074, 0x2079, direction::EN},    {0x207a, 0x207b, direction::ES}, | 
8535  |  |     {0x207c, 0x207e, direction::ON},    {0x207f, 0x207f, direction::L}, | 
8536  |  |     {0x2080, 0x2089, direction::EN},    {0x208a, 0x208b, direction::ES}, | 
8537  |  |     {0x208c, 0x208e, direction::ON},    {0x2090, 0x209c, direction::L}, | 
8538  |  |     {0x20a0, 0x20bf, direction::ET},    {0x20d0, 0x20f0, direction::NSM}, | 
8539  |  |     {0x2100, 0x2101, direction::ON},    {0x2102, 0x2102, direction::L}, | 
8540  |  |     {0x2103, 0x2106, direction::ON},    {0x2107, 0x2107, direction::L}, | 
8541  |  |     {0x2108, 0x2109, direction::ON},    {0x210a, 0x2113, direction::L}, | 
8542  |  |     {0x2114, 0x2114, direction::ON},    {0x2115, 0x2115, direction::L}, | 
8543  |  |     {0x2116, 0x2118, direction::ON},    {0x2119, 0x211d, direction::L}, | 
8544  |  |     {0x211e, 0x2123, direction::ON},    {0x2124, 0x2124, direction::L}, | 
8545  |  |     {0x2125, 0x2125, direction::ON},    {0x2126, 0x2126, direction::L}, | 
8546  |  |     {0x2127, 0x2127, direction::ON},    {0x2128, 0x2128, direction::L}, | 
8547  |  |     {0x2129, 0x2129, direction::ON},    {0x212a, 0x212d, direction::L}, | 
8548  |  |     {0x212e, 0x212e, direction::ET},    {0x212f, 0x2139, direction::L}, | 
8549  |  |     {0x213a, 0x213b, direction::ON},    {0x213c, 0x213f, direction::L}, | 
8550  |  |     {0x2140, 0x2144, direction::ON},    {0x2145, 0x2149, direction::L}, | 
8551  |  |     {0x214a, 0x214d, direction::ON},    {0x214e, 0x214f, direction::L}, | 
8552  |  |     {0x2150, 0x215f, direction::ON},    {0x2160, 0x2188, direction::L}, | 
8553  |  |     {0x2189, 0x218b, direction::ON},    {0x2190, 0x2211, direction::ON}, | 
8554  |  |     {0x2212, 0x2212, direction::ES},    {0x2213, 0x2213, direction::ET}, | 
8555  |  |     {0x2214, 0x2335, direction::ON},    {0x2336, 0x237a, direction::L}, | 
8556  |  |     {0x237b, 0x2394, direction::ON},    {0x2395, 0x2395, direction::L}, | 
8557  |  |     {0x2396, 0x2426, direction::ON},    {0x2440, 0x244a, direction::ON}, | 
8558  |  |     {0x2460, 0x2487, direction::ON},    {0x2488, 0x249b, direction::EN}, | 
8559  |  |     {0x249c, 0x24e9, direction::L},     {0x24ea, 0x26ab, direction::ON}, | 
8560  |  |     {0x26ac, 0x26ac, direction::L},     {0x26ad, 0x27ff, direction::ON}, | 
8561  |  |     {0x2800, 0x28ff, direction::L},     {0x2900, 0x2b73, direction::ON}, | 
8562  |  |     {0x2b76, 0x2b95, direction::ON},    {0x2b97, 0x2bff, direction::ON}, | 
8563  |  |     {0x2c00, 0x2c2e, direction::L},     {0x2c30, 0x2c5e, direction::L}, | 
8564  |  |     {0x2c60, 0x2ce4, direction::L},     {0x2ce5, 0x2cea, direction::ON}, | 
8565  |  |     {0x2ceb, 0x2cee, direction::L},     {0x2cef, 0x2cf1, direction::NSM}, | 
8566  |  |     {0x2cf2, 0x2cf3, direction::L},     {0x2cf9, 0x2cff, direction::ON}, | 
8567  |  |     {0x2d00, 0x2d25, direction::L},     {0x2d27, 0x2d27, direction::L}, | 
8568  |  |     {0x2d2d, 0x2d2d, direction::L},     {0x2d30, 0x2d67, direction::L}, | 
8569  |  |     {0x2d6f, 0x2d70, direction::L},     {0x2d7f, 0x2d7f, direction::NSM}, | 
8570  |  |     {0x2d80, 0x2d96, direction::L},     {0x2da0, 0x2da6, direction::L}, | 
8571  |  |     {0x2da8, 0x2dae, direction::L},     {0x2db0, 0x2db6, direction::L}, | 
8572  |  |     {0x2db8, 0x2dbe, direction::L},     {0x2dc0, 0x2dc6, direction::L}, | 
8573  |  |     {0x2dc8, 0x2dce, direction::L},     {0x2dd0, 0x2dd6, direction::L}, | 
8574  |  |     {0x2dd8, 0x2dde, direction::L},     {0x2de0, 0x2dff, direction::NSM}, | 
8575  |  |     {0x2e00, 0x2e52, direction::ON},    {0x2e80, 0x2e99, direction::ON}, | 
8576  |  |     {0x2e9b, 0x2ef3, direction::ON},    {0x2f00, 0x2fd5, direction::ON}, | 
8577  |  |     {0x2ff0, 0x2ffb, direction::ON},    {0x3000, 0x3000, direction::WS}, | 
8578  |  |     {0x3001, 0x3004, direction::ON},    {0x3005, 0x3007, direction::L}, | 
8579  |  |     {0x3008, 0x3020, direction::ON},    {0x3021, 0x3029, direction::L}, | 
8580  |  |     {0x302a, 0x302d, direction::NSM},   {0x302e, 0x302f, direction::L}, | 
8581  |  |     {0x3030, 0x3030, direction::ON},    {0x3031, 0x3035, direction::L}, | 
8582  |  |     {0x3036, 0x3037, direction::ON},    {0x3038, 0x303c, direction::L}, | 
8583  |  |     {0x303d, 0x303f, direction::ON},    {0x3041, 0x3096, direction::L}, | 
8584  |  |     {0x3099, 0x309a, direction::NSM},   {0x309b, 0x309c, direction::ON}, | 
8585  |  |     {0x309d, 0x309f, direction::L},     {0x30a0, 0x30a0, direction::ON}, | 
8586  |  |     {0x30a1, 0x30fa, direction::L},     {0x30fb, 0x30fb, direction::ON}, | 
8587  |  |     {0x30fc, 0x30ff, direction::L},     {0x3105, 0x312f, direction::L}, | 
8588  |  |     {0x3131, 0x318e, direction::L},     {0x3190, 0x31bf, direction::L}, | 
8589  |  |     {0x31c0, 0x31e3, direction::ON},    {0x31f0, 0x321c, direction::L}, | 
8590  |  |     {0x321d, 0x321e, direction::ON},    {0x3220, 0x324f, direction::L}, | 
8591  |  |     {0x3250, 0x325f, direction::ON},    {0x3260, 0x327b, direction::L}, | 
8592  |  |     {0x327c, 0x327e, direction::ON},    {0x327f, 0x32b0, direction::L}, | 
8593  |  |     {0x32b1, 0x32bf, direction::ON},    {0x32c0, 0x32cb, direction::L}, | 
8594  |  |     {0x32cc, 0x32cf, direction::ON},    {0x32d0, 0x3376, direction::L}, | 
8595  |  |     {0x3377, 0x337a, direction::ON},    {0x337b, 0x33dd, direction::L}, | 
8596  |  |     {0x33de, 0x33df, direction::ON},    {0x33e0, 0x33fe, direction::L}, | 
8597  |  |     {0x33ff, 0x33ff, direction::ON},    {0x3400, 0x4dbf, direction::L}, | 
8598  |  |     {0x4dc0, 0x4dff, direction::ON},    {0x4e00, 0x9ffc, direction::L}, | 
8599  |  |     {0xa000, 0xa48c, direction::L},     {0xa490, 0xa4c6, direction::ON}, | 
8600  |  |     {0xa4d0, 0xa60c, direction::L},     {0xa60d, 0xa60f, direction::ON}, | 
8601  |  |     {0xa610, 0xa62b, direction::L},     {0xa640, 0xa66e, direction::L}, | 
8602  |  |     {0xa66f, 0xa672, direction::NSM},   {0xa673, 0xa673, direction::ON}, | 
8603  |  |     {0xa674, 0xa67d, direction::NSM},   {0xa67e, 0xa67f, direction::ON}, | 
8604  |  |     {0xa680, 0xa69d, direction::L},     {0xa69e, 0xa69f, direction::NSM}, | 
8605  |  |     {0xa6a0, 0xa6ef, direction::L},     {0xa6f0, 0xa6f1, direction::NSM}, | 
8606  |  |     {0xa6f2, 0xa6f7, direction::L},     {0xa700, 0xa721, direction::ON}, | 
8607  |  |     {0xa722, 0xa787, direction::L},     {0xa788, 0xa788, direction::ON}, | 
8608  |  |     {0xa789, 0xa7bf, direction::L},     {0xa7c2, 0xa7ca, direction::L}, | 
8609  |  |     {0xa7f5, 0xa801, direction::L},     {0xa802, 0xa802, direction::NSM}, | 
8610  |  |     {0xa803, 0xa805, direction::L},     {0xa806, 0xa806, direction::NSM}, | 
8611  |  |     {0xa807, 0xa80a, direction::L},     {0xa80b, 0xa80b, direction::NSM}, | 
8612  |  |     {0xa80c, 0xa824, direction::L},     {0xa825, 0xa826, direction::NSM}, | 
8613  |  |     {0xa827, 0xa827, direction::L},     {0xa828, 0xa82b, direction::ON}, | 
8614  |  |     {0xa82c, 0xa82c, direction::NSM},   {0xa830, 0xa837, direction::L}, | 
8615  |  |     {0xa838, 0xa839, direction::ET},    {0xa840, 0xa873, direction::L}, | 
8616  |  |     {0xa874, 0xa877, direction::ON},    {0xa880, 0xa8c3, direction::L}, | 
8617  |  |     {0xa8c4, 0xa8c5, direction::NSM},   {0xa8ce, 0xa8d9, direction::L}, | 
8618  |  |     {0xa8e0, 0xa8f1, direction::NSM},   {0xa8f2, 0xa8fe, direction::L}, | 
8619  |  |     {0xa8ff, 0xa8ff, direction::NSM},   {0xa900, 0xa925, direction::L}, | 
8620  |  |     {0xa926, 0xa92d, direction::NSM},   {0xa92e, 0xa946, direction::L}, | 
8621  |  |     {0xa947, 0xa951, direction::NSM},   {0xa952, 0xa953, direction::L}, | 
8622  |  |     {0xa95f, 0xa97c, direction::L},     {0xa980, 0xa982, direction::NSM}, | 
8623  |  |     {0xa983, 0xa9b2, direction::L},     {0xa9b3, 0xa9b3, direction::NSM}, | 
8624  |  |     {0xa9b4, 0xa9b5, direction::L},     {0xa9b6, 0xa9b9, direction::NSM}, | 
8625  |  |     {0xa9ba, 0xa9bb, direction::L},     {0xa9bc, 0xa9bd, direction::NSM}, | 
8626  |  |     {0xa9be, 0xa9cd, direction::L},     {0xa9cf, 0xa9d9, direction::L}, | 
8627  |  |     {0xa9de, 0xa9e4, direction::L},     {0xa9e5, 0xa9e5, direction::NSM}, | 
8628  |  |     {0xa9e6, 0xa9fe, direction::L},     {0xaa00, 0xaa28, direction::L}, | 
8629  |  |     {0xaa29, 0xaa2e, direction::NSM},   {0xaa2f, 0xaa30, direction::L}, | 
8630  |  |     {0xaa31, 0xaa32, direction::NSM},   {0xaa33, 0xaa34, direction::L}, | 
8631  |  |     {0xaa35, 0xaa36, direction::NSM},   {0xaa40, 0xaa42, direction::L}, | 
8632  |  |     {0xaa43, 0xaa43, direction::NSM},   {0xaa44, 0xaa4b, direction::L}, | 
8633  |  |     {0xaa4c, 0xaa4c, direction::NSM},   {0xaa4d, 0xaa4d, direction::L}, | 
8634  |  |     {0xaa50, 0xaa59, direction::L},     {0xaa5c, 0xaa7b, direction::L}, | 
8635  |  |     {0xaa7c, 0xaa7c, direction::NSM},   {0xaa7d, 0xaaaf, direction::L}, | 
8636  |  |     {0xaab0, 0xaab0, direction::NSM},   {0xaab1, 0xaab1, direction::L}, | 
8637  |  |     {0xaab2, 0xaab4, direction::NSM},   {0xaab5, 0xaab6, direction::L}, | 
8638  |  |     {0xaab7, 0xaab8, direction::NSM},   {0xaab9, 0xaabd, direction::L}, | 
8639  |  |     {0xaabe, 0xaabf, direction::NSM},   {0xaac0, 0xaac0, direction::L}, | 
8640  |  |     {0xaac1, 0xaac1, direction::NSM},   {0xaac2, 0xaac2, direction::L}, | 
8641  |  |     {0xaadb, 0xaaeb, direction::L},     {0xaaec, 0xaaed, direction::NSM}, | 
8642  |  |     {0xaaee, 0xaaf5, direction::L},     {0xaaf6, 0xaaf6, direction::NSM}, | 
8643  |  |     {0xab01, 0xab06, direction::L},     {0xab09, 0xab0e, direction::L}, | 
8644  |  |     {0xab11, 0xab16, direction::L},     {0xab20, 0xab26, direction::L}, | 
8645  |  |     {0xab28, 0xab2e, direction::L},     {0xab30, 0xab69, direction::L}, | 
8646  |  |     {0xab6a, 0xab6b, direction::ON},    {0xab70, 0xabe4, direction::L}, | 
8647  |  |     {0xabe5, 0xabe5, direction::NSM},   {0xabe6, 0xabe7, direction::L}, | 
8648  |  |     {0xabe8, 0xabe8, direction::NSM},   {0xabe9, 0xabec, direction::L}, | 
8649  |  |     {0xabed, 0xabed, direction::NSM},   {0xabf0, 0xabf9, direction::L}, | 
8650  |  |     {0xac00, 0xd7a3, direction::L},     {0xd7b0, 0xd7c6, direction::L}, | 
8651  |  |     {0xd7cb, 0xd7fb, direction::L},     {0xd800, 0xfa6d, direction::L}, | 
8652  |  |     {0xfa70, 0xfad9, direction::L},     {0xfb00, 0xfb06, direction::L}, | 
8653  |  |     {0xfb13, 0xfb17, direction::L},     {0xfb1d, 0xfb1d, direction::R}, | 
8654  |  |     {0xfb1e, 0xfb1e, direction::NSM},   {0xfb1f, 0xfb28, direction::R}, | 
8655  |  |     {0xfb29, 0xfb29, direction::ES},    {0xfb2a, 0xfb36, direction::R}, | 
8656  |  |     {0xfb38, 0xfb3c, direction::R},     {0xfb3e, 0xfb3e, direction::R}, | 
8657  |  |     {0xfb40, 0xfb41, direction::R},     {0xfb43, 0xfb44, direction::R}, | 
8658  |  |     {0xfb46, 0xfb4f, direction::R},     {0xfb50, 0xfbc1, direction::AL}, | 
8659  |  |     {0xfbd3, 0xfd3d, direction::AL},    {0xfd3e, 0xfd3f, direction::ON}, | 
8660  |  |     {0xfd50, 0xfd8f, direction::AL},    {0xfd92, 0xfdc7, direction::AL}, | 
8661  |  |     {0xfdf0, 0xfdfc, direction::AL},    {0xfdfd, 0xfdfd, direction::ON}, | 
8662  |  |     {0xfe00, 0xfe0f, direction::NSM},   {0xfe10, 0xfe19, direction::ON}, | 
8663  |  |     {0xfe20, 0xfe2f, direction::NSM},   {0xfe30, 0xfe4f, direction::ON}, | 
8664  |  |     {0xfe50, 0xfe50, direction::CS},    {0xfe51, 0xfe51, direction::ON}, | 
8665  |  |     {0xfe52, 0xfe52, direction::CS},    {0xfe54, 0xfe54, direction::ON}, | 
8666  |  |     {0xfe55, 0xfe55, direction::CS},    {0xfe56, 0xfe5e, direction::ON}, | 
8667  |  |     {0xfe5f, 0xfe5f, direction::ET},    {0xfe60, 0xfe61, direction::ON}, | 
8668  |  |     {0xfe62, 0xfe63, direction::ES},    {0xfe64, 0xfe66, direction::ON}, | 
8669  |  |     {0xfe68, 0xfe68, direction::ON},    {0xfe69, 0xfe6a, direction::ET}, | 
8670  |  |     {0xfe6b, 0xfe6b, direction::ON},    {0xfe70, 0xfe74, direction::AL}, | 
8671  |  |     {0xfe76, 0xfefc, direction::AL},    {0xfeff, 0xfeff, direction::BN}, | 
8672  |  |     {0xff01, 0xff02, direction::ON},    {0xff03, 0xff05, direction::ET}, | 
8673  |  |     {0xff06, 0xff0a, direction::ON},    {0xff0b, 0xff0b, direction::ES}, | 
8674  |  |     {0xff0c, 0xff0c, direction::CS},    {0xff0d, 0xff0d, direction::ES}, | 
8675  |  |     {0xff0e, 0xff0f, direction::CS},    {0xff10, 0xff19, direction::EN}, | 
8676  |  |     {0xff1a, 0xff1a, direction::CS},    {0xff1b, 0xff20, direction::ON}, | 
8677  |  |     {0xff21, 0xff3a, direction::L},     {0xff3b, 0xff40, direction::ON}, | 
8678  |  |     {0xff41, 0xff5a, direction::L},     {0xff5b, 0xff65, direction::ON}, | 
8679  |  |     {0xff66, 0xffbe, direction::L},     {0xffc2, 0xffc7, direction::L}, | 
8680  |  |     {0xffca, 0xffcf, direction::L},     {0xffd2, 0xffd7, direction::L}, | 
8681  |  |     {0xffda, 0xffdc, direction::L},     {0xffe0, 0xffe1, direction::ET}, | 
8682  |  |     {0xffe2, 0xffe4, direction::ON},    {0xffe5, 0xffe6, direction::ET}, | 
8683  |  |     {0xffe8, 0xffee, direction::ON},    {0xfff9, 0xfffd, direction::ON}, | 
8684  |  |     {0x10000, 0x1000b, direction::L},   {0x1000d, 0x10026, direction::L}, | 
8685  |  |     {0x10028, 0x1003a, direction::L},   {0x1003c, 0x1003d, direction::L}, | 
8686  |  |     {0x1003f, 0x1004d, direction::L},   {0x10050, 0x1005d, direction::L}, | 
8687  |  |     {0x10080, 0x100fa, direction::L},   {0x10100, 0x10100, direction::L}, | 
8688  |  |     {0x10101, 0x10101, direction::ON},  {0x10102, 0x10102, direction::L}, | 
8689  |  |     {0x10107, 0x10133, direction::L},   {0x10137, 0x1013f, direction::L}, | 
8690  |  |     {0x10140, 0x1018c, direction::ON},  {0x1018d, 0x1018e, direction::L}, | 
8691  |  |     {0x10190, 0x1019c, direction::ON},  {0x101a0, 0x101a0, direction::ON}, | 
8692  |  |     {0x101d0, 0x101fc, direction::L},   {0x101fd, 0x101fd, direction::NSM}, | 
8693  |  |     {0x10280, 0x1029c, direction::L},   {0x102a0, 0x102d0, direction::L}, | 
8694  |  |     {0x102e0, 0x102e0, direction::NSM}, {0x102e1, 0x102fb, direction::EN}, | 
8695  |  |     {0x10300, 0x10323, direction::L},   {0x1032d, 0x1034a, direction::L}, | 
8696  |  |     {0x10350, 0x10375, direction::L},   {0x10376, 0x1037a, direction::NSM}, | 
8697  |  |     {0x10380, 0x1039d, direction::L},   {0x1039f, 0x103c3, direction::L}, | 
8698  |  |     {0x103c8, 0x103d5, direction::L},   {0x10400, 0x1049d, direction::L}, | 
8699  |  |     {0x104a0, 0x104a9, direction::L},   {0x104b0, 0x104d3, direction::L}, | 
8700  |  |     {0x104d8, 0x104fb, direction::L},   {0x10500, 0x10527, direction::L}, | 
8701  |  |     {0x10530, 0x10563, direction::L},   {0x1056f, 0x1056f, direction::L}, | 
8702  |  |     {0x10600, 0x10736, direction::L},   {0x10740, 0x10755, direction::L}, | 
8703  |  |     {0x10760, 0x10767, direction::L},   {0x10800, 0x10805, direction::R}, | 
8704  |  |     {0x10808, 0x10808, direction::R},   {0x1080a, 0x10835, direction::R}, | 
8705  |  |     {0x10837, 0x10838, direction::R},   {0x1083c, 0x1083c, direction::R}, | 
8706  |  |     {0x1083f, 0x10855, direction::R},   {0x10857, 0x1089e, direction::R}, | 
8707  |  |     {0x108a7, 0x108af, direction::R},   {0x108e0, 0x108f2, direction::R}, | 
8708  |  |     {0x108f4, 0x108f5, direction::R},   {0x108fb, 0x1091b, direction::R}, | 
8709  |  |     {0x1091f, 0x1091f, direction::ON},  {0x10920, 0x10939, direction::R}, | 
8710  |  |     {0x1093f, 0x1093f, direction::R},   {0x10980, 0x109b7, direction::R}, | 
8711  |  |     {0x109bc, 0x109cf, direction::R},   {0x109d2, 0x10a00, direction::R}, | 
8712  |  |     {0x10a01, 0x10a03, direction::NSM}, {0x10a05, 0x10a06, direction::NSM}, | 
8713  |  |     {0x10a0c, 0x10a0f, direction::NSM}, {0x10a10, 0x10a13, direction::R}, | 
8714  |  |     {0x10a15, 0x10a17, direction::R},   {0x10a19, 0x10a35, direction::R}, | 
8715  |  |     {0x10a38, 0x10a3a, direction::NSM}, {0x10a3f, 0x10a3f, direction::NSM}, | 
8716  |  |     {0x10a40, 0x10a48, direction::R},   {0x10a50, 0x10a58, direction::R}, | 
8717  |  |     {0x10a60, 0x10a9f, direction::R},   {0x10ac0, 0x10ae4, direction::R}, | 
8718  |  |     {0x10ae5, 0x10ae6, direction::NSM}, {0x10aeb, 0x10af6, direction::R}, | 
8719  |  |     {0x10b00, 0x10b35, direction::R},   {0x10b39, 0x10b3f, direction::ON}, | 
8720  |  |     {0x10b40, 0x10b55, direction::R},   {0x10b58, 0x10b72, direction::R}, | 
8721  |  |     {0x10b78, 0x10b91, direction::R},   {0x10b99, 0x10b9c, direction::R}, | 
8722  |  |     {0x10ba9, 0x10baf, direction::R},   {0x10c00, 0x10c48, direction::R}, | 
8723  |  |     {0x10c80, 0x10cb2, direction::R},   {0x10cc0, 0x10cf2, direction::R}, | 
8724  |  |     {0x10cfa, 0x10cff, direction::R},   {0x10d00, 0x10d23, direction::AL}, | 
8725  |  |     {0x10d24, 0x10d27, direction::NSM}, {0x10d30, 0x10d39, direction::AN}, | 
8726  |  |     {0x10e60, 0x10e7e, direction::AN},  {0x10e80, 0x10ea9, direction::R}, | 
8727  |  |     {0x10eab, 0x10eac, direction::NSM}, {0x10ead, 0x10ead, direction::R}, | 
8728  |  |     {0x10eb0, 0x10eb1, direction::R},   {0x10f00, 0x10f27, direction::R}, | 
8729  |  |     {0x10f30, 0x10f45, direction::AL},  {0x10f46, 0x10f50, direction::NSM}, | 
8730  |  |     {0x10f51, 0x10f59, direction::AL},  {0x10fb0, 0x10fcb, direction::R}, | 
8731  |  |     {0x10fe0, 0x10ff6, direction::R},   {0x11000, 0x11000, direction::L}, | 
8732  |  |     {0x11001, 0x11001, direction::NSM}, {0x11002, 0x11037, direction::L}, | 
8733  |  |     {0x11038, 0x11046, direction::NSM}, {0x11047, 0x1104d, direction::L}, | 
8734  |  |     {0x11052, 0x11065, direction::ON},  {0x11066, 0x1106f, direction::L}, | 
8735  |  |     {0x1107f, 0x11081, direction::NSM}, {0x11082, 0x110b2, direction::L}, | 
8736  |  |     {0x110b3, 0x110b6, direction::NSM}, {0x110b7, 0x110b8, direction::L}, | 
8737  |  |     {0x110b9, 0x110ba, direction::NSM}, {0x110bb, 0x110c1, direction::L}, | 
8738  |  |     {0x110cd, 0x110cd, direction::L},   {0x110d0, 0x110e8, direction::L}, | 
8739  |  |     {0x110f0, 0x110f9, direction::L},   {0x11100, 0x11102, direction::NSM}, | 
8740  |  |     {0x11103, 0x11126, direction::L},   {0x11127, 0x1112b, direction::NSM}, | 
8741  |  |     {0x1112c, 0x1112c, direction::L},   {0x1112d, 0x11134, direction::NSM}, | 
8742  |  |     {0x11136, 0x11147, direction::L},   {0x11150, 0x11172, direction::L}, | 
8743  |  |     {0x11173, 0x11173, direction::NSM}, {0x11174, 0x11176, direction::L}, | 
8744  |  |     {0x11180, 0x11181, direction::NSM}, {0x11182, 0x111b5, direction::L}, | 
8745  |  |     {0x111b6, 0x111be, direction::NSM}, {0x111bf, 0x111c8, direction::L}, | 
8746  |  |     {0x111c9, 0x111cc, direction::NSM}, {0x111cd, 0x111ce, direction::L}, | 
8747  |  |     {0x111cf, 0x111cf, direction::NSM}, {0x111d0, 0x111df, direction::L}, | 
8748  |  |     {0x111e1, 0x111f4, direction::L},   {0x11200, 0x11211, direction::L}, | 
8749  |  |     {0x11213, 0x1122e, direction::L},   {0x1122f, 0x11231, direction::NSM}, | 
8750  |  |     {0x11232, 0x11233, direction::L},   {0x11234, 0x11234, direction::NSM}, | 
8751  |  |     {0x11235, 0x11235, direction::L},   {0x11236, 0x11237, direction::NSM}, | 
8752  |  |     {0x11238, 0x1123d, direction::L},   {0x1123e, 0x1123e, direction::NSM}, | 
8753  |  |     {0x11280, 0x11286, direction::L},   {0x11288, 0x11288, direction::L}, | 
8754  |  |     {0x1128a, 0x1128d, direction::L},   {0x1128f, 0x1129d, direction::L}, | 
8755  |  |     {0x1129f, 0x112a9, direction::L},   {0x112b0, 0x112de, direction::L}, | 
8756  |  |     {0x112df, 0x112df, direction::NSM}, {0x112e0, 0x112e2, direction::L}, | 
8757  |  |     {0x112e3, 0x112ea, direction::NSM}, {0x112f0, 0x112f9, direction::L}, | 
8758  |  |     {0x11300, 0x11301, direction::NSM}, {0x11302, 0x11303, direction::L}, | 
8759  |  |     {0x11305, 0x1130c, direction::L},   {0x1130f, 0x11310, direction::L}, | 
8760  |  |     {0x11313, 0x11328, direction::L},   {0x1132a, 0x11330, direction::L}, | 
8761  |  |     {0x11332, 0x11333, direction::L},   {0x11335, 0x11339, direction::L}, | 
8762  |  |     {0x1133b, 0x1133c, direction::NSM}, {0x1133d, 0x1133f, direction::L}, | 
8763  |  |     {0x11340, 0x11340, direction::NSM}, {0x11341, 0x11344, direction::L}, | 
8764  |  |     {0x11347, 0x11348, direction::L},   {0x1134b, 0x1134d, direction::L}, | 
8765  |  |     {0x11350, 0x11350, direction::L},   {0x11357, 0x11357, direction::L}, | 
8766  |  |     {0x1135d, 0x11363, direction::L},   {0x11366, 0x1136c, direction::NSM}, | 
8767  |  |     {0x11370, 0x11374, direction::NSM}, {0x11400, 0x11437, direction::L}, | 
8768  |  |     {0x11438, 0x1143f, direction::NSM}, {0x11440, 0x11441, direction::L}, | 
8769  |  |     {0x11442, 0x11444, direction::NSM}, {0x11445, 0x11445, direction::L}, | 
8770  |  |     {0x11446, 0x11446, direction::NSM}, {0x11447, 0x1145b, direction::L}, | 
8771  |  |     {0x1145d, 0x1145d, direction::L},   {0x1145e, 0x1145e, direction::NSM}, | 
8772  |  |     {0x1145f, 0x11461, direction::L},   {0x11480, 0x114b2, direction::L}, | 
8773  |  |     {0x114b3, 0x114b8, direction::NSM}, {0x114b9, 0x114b9, direction::L}, | 
8774  |  |     {0x114ba, 0x114ba, direction::NSM}, {0x114bb, 0x114be, direction::L}, | 
8775  |  |     {0x114bf, 0x114c0, direction::NSM}, {0x114c1, 0x114c1, direction::L}, | 
8776  |  |     {0x114c2, 0x114c3, direction::NSM}, {0x114c4, 0x114c7, direction::L}, | 
8777  |  |     {0x114d0, 0x114d9, direction::L},   {0x11580, 0x115b1, direction::L}, | 
8778  |  |     {0x115b2, 0x115b5, direction::NSM}, {0x115b8, 0x115bb, direction::L}, | 
8779  |  |     {0x115bc, 0x115bd, direction::NSM}, {0x115be, 0x115be, direction::L}, | 
8780  |  |     {0x115bf, 0x115c0, direction::NSM}, {0x115c1, 0x115db, direction::L}, | 
8781  |  |     {0x115dc, 0x115dd, direction::NSM}, {0x11600, 0x11632, direction::L}, | 
8782  |  |     {0x11633, 0x1163a, direction::NSM}, {0x1163b, 0x1163c, direction::L}, | 
8783  |  |     {0x1163d, 0x1163d, direction::NSM}, {0x1163e, 0x1163e, direction::L}, | 
8784  |  |     {0x1163f, 0x11640, direction::NSM}, {0x11641, 0x11644, direction::L}, | 
8785  |  |     {0x11650, 0x11659, direction::L},   {0x11660, 0x1166c, direction::ON}, | 
8786  |  |     {0x11680, 0x116aa, direction::L},   {0x116ab, 0x116ab, direction::NSM}, | 
8787  |  |     {0x116ac, 0x116ac, direction::L},   {0x116ad, 0x116ad, direction::NSM}, | 
8788  |  |     {0x116ae, 0x116af, direction::L},   {0x116b0, 0x116b5, direction::NSM}, | 
8789  |  |     {0x116b6, 0x116b6, direction::L},   {0x116b7, 0x116b7, direction::NSM}, | 
8790  |  |     {0x116b8, 0x116b8, direction::L},   {0x116c0, 0x116c9, direction::L}, | 
8791  |  |     {0x11700, 0x1171a, direction::L},   {0x1171d, 0x1171f, direction::NSM}, | 
8792  |  |     {0x11720, 0x11721, direction::L},   {0x11722, 0x11725, direction::NSM}, | 
8793  |  |     {0x11726, 0x11726, direction::L},   {0x11727, 0x1172b, direction::NSM}, | 
8794  |  |     {0x11730, 0x1173f, direction::L},   {0x11800, 0x1182e, direction::L}, | 
8795  |  |     {0x1182f, 0x11837, direction::NSM}, {0x11838, 0x11838, direction::L}, | 
8796  |  |     {0x11839, 0x1183a, direction::NSM}, {0x1183b, 0x1183b, direction::L}, | 
8797  |  |     {0x118a0, 0x118f2, direction::L},   {0x118ff, 0x11906, direction::L}, | 
8798  |  |     {0x11909, 0x11909, direction::L},   {0x1190c, 0x11913, direction::L}, | 
8799  |  |     {0x11915, 0x11916, direction::L},   {0x11918, 0x11935, direction::L}, | 
8800  |  |     {0x11937, 0x11938, direction::L},   {0x1193b, 0x1193c, direction::NSM}, | 
8801  |  |     {0x1193d, 0x1193d, direction::L},   {0x1193e, 0x1193e, direction::NSM}, | 
8802  |  |     {0x1193f, 0x11942, direction::L},   {0x11943, 0x11943, direction::NSM}, | 
8803  |  |     {0x11944, 0x11946, direction::L},   {0x11950, 0x11959, direction::L}, | 
8804  |  |     {0x119a0, 0x119a7, direction::L},   {0x119aa, 0x119d3, direction::L}, | 
8805  |  |     {0x119d4, 0x119d7, direction::NSM}, {0x119da, 0x119db, direction::NSM}, | 
8806  |  |     {0x119dc, 0x119df, direction::L},   {0x119e0, 0x119e0, direction::NSM}, | 
8807  |  |     {0x119e1, 0x119e4, direction::L},   {0x11a00, 0x11a00, direction::L}, | 
8808  |  |     {0x11a01, 0x11a06, direction::NSM}, {0x11a07, 0x11a08, direction::L}, | 
8809  |  |     {0x11a09, 0x11a0a, direction::NSM}, {0x11a0b, 0x11a32, direction::L}, | 
8810  |  |     {0x11a33, 0x11a38, direction::NSM}, {0x11a39, 0x11a3a, direction::L}, | 
8811  |  |     {0x11a3b, 0x11a3e, direction::NSM}, {0x11a3f, 0x11a46, direction::L}, | 
8812  |  |     {0x11a47, 0x11a47, direction::NSM}, {0x11a50, 0x11a50, direction::L}, | 
8813  |  |     {0x11a51, 0x11a56, direction::NSM}, {0x11a57, 0x11a58, direction::L}, | 
8814  |  |     {0x11a59, 0x11a5b, direction::NSM}, {0x11a5c, 0x11a89, direction::L}, | 
8815  |  |     {0x11a8a, 0x11a96, direction::NSM}, {0x11a97, 0x11a97, direction::L}, | 
8816  |  |     {0x11a98, 0x11a99, direction::NSM}, {0x11a9a, 0x11aa2, direction::L}, | 
8817  |  |     {0x11ac0, 0x11af8, direction::L},   {0x11c00, 0x11c08, direction::L}, | 
8818  |  |     {0x11c0a, 0x11c2f, direction::L},   {0x11c30, 0x11c36, direction::NSM}, | 
8819  |  |     {0x11c38, 0x11c3d, direction::NSM}, {0x11c3e, 0x11c45, direction::L}, | 
8820  |  |     {0x11c50, 0x11c6c, direction::L},   {0x11c70, 0x11c8f, direction::L}, | 
8821  |  |     {0x11c92, 0x11ca7, direction::NSM}, {0x11ca9, 0x11ca9, direction::L}, | 
8822  |  |     {0x11caa, 0x11cb0, direction::NSM}, {0x11cb1, 0x11cb1, direction::L}, | 
8823  |  |     {0x11cb2, 0x11cb3, direction::NSM}, {0x11cb4, 0x11cb4, direction::L}, | 
8824  |  |     {0x11cb5, 0x11cb6, direction::NSM}, {0x11d00, 0x11d06, direction::L}, | 
8825  |  |     {0x11d08, 0x11d09, direction::L},   {0x11d0b, 0x11d30, direction::L}, | 
8826  |  |     {0x11d31, 0x11d36, direction::NSM}, {0x11d3a, 0x11d3a, direction::NSM}, | 
8827  |  |     {0x11d3c, 0x11d3d, direction::NSM}, {0x11d3f, 0x11d45, direction::NSM}, | 
8828  |  |     {0x11d46, 0x11d46, direction::L},   {0x11d47, 0x11d47, direction::NSM}, | 
8829  |  |     {0x11d50, 0x11d59, direction::L},   {0x11d60, 0x11d65, direction::L}, | 
8830  |  |     {0x11d67, 0x11d68, direction::L},   {0x11d6a, 0x11d8e, direction::L}, | 
8831  |  |     {0x11d90, 0x11d91, direction::NSM}, {0x11d93, 0x11d94, direction::L}, | 
8832  |  |     {0x11d95, 0x11d95, direction::NSM}, {0x11d96, 0x11d96, direction::L}, | 
8833  |  |     {0x11d97, 0x11d97, direction::NSM}, {0x11d98, 0x11d98, direction::L}, | 
8834  |  |     {0x11da0, 0x11da9, direction::L},   {0x11ee0, 0x11ef2, direction::L}, | 
8835  |  |     {0x11ef3, 0x11ef4, direction::NSM}, {0x11ef5, 0x11ef8, direction::L}, | 
8836  |  |     {0x11fb0, 0x11fb0, direction::L},   {0x11fc0, 0x11fd4, direction::L}, | 
8837  |  |     {0x11fd5, 0x11fdc, direction::ON},  {0x11fdd, 0x11fe0, direction::ET}, | 
8838  |  |     {0x11fe1, 0x11ff1, direction::ON},  {0x11fff, 0x12399, direction::L}, | 
8839  |  |     {0x12400, 0x1246e, direction::L},   {0x12470, 0x12474, direction::L}, | 
8840  |  |     {0x12480, 0x12543, direction::L},   {0x13000, 0x1342e, direction::L}, | 
8841  |  |     {0x13430, 0x13438, direction::L},   {0x14400, 0x14646, direction::L}, | 
8842  |  |     {0x16800, 0x16a38, direction::L},   {0x16a40, 0x16a5e, direction::L}, | 
8843  |  |     {0x16a60, 0x16a69, direction::L},   {0x16a6e, 0x16a6f, direction::L}, | 
8844  |  |     {0x16ad0, 0x16aed, direction::L},   {0x16af0, 0x16af4, direction::NSM}, | 
8845  |  |     {0x16af5, 0x16af5, direction::L},   {0x16b00, 0x16b2f, direction::L}, | 
8846  |  |     {0x16b30, 0x16b36, direction::NSM}, {0x16b37, 0x16b45, direction::L}, | 
8847  |  |     {0x16b50, 0x16b59, direction::L},   {0x16b5b, 0x16b61, direction::L}, | 
8848  |  |     {0x16b63, 0x16b77, direction::L},   {0x16b7d, 0x16b8f, direction::L}, | 
8849  |  |     {0x16e40, 0x16e9a, direction::L},   {0x16f00, 0x16f4a, direction::L}, | 
8850  |  |     {0x16f4f, 0x16f4f, direction::NSM}, {0x16f50, 0x16f87, direction::L}, | 
8851  |  |     {0x16f8f, 0x16f92, direction::NSM}, {0x16f93, 0x16f9f, direction::L}, | 
8852  |  |     {0x16fe0, 0x16fe1, direction::L},   {0x16fe2, 0x16fe2, direction::ON}, | 
8853  |  |     {0x16fe3, 0x16fe3, direction::L},   {0x16fe4, 0x16fe4, direction::NSM}, | 
8854  |  |     {0x16ff0, 0x16ff1, direction::L},   {0x17000, 0x187f7, direction::L}, | 
8855  |  |     {0x18800, 0x18cd5, direction::L},   {0x18d00, 0x18d08, direction::L}, | 
8856  |  |     {0x1b000, 0x1b11e, direction::L},   {0x1b150, 0x1b152, direction::L}, | 
8857  |  |     {0x1b164, 0x1b167, direction::L},   {0x1b170, 0x1b2fb, direction::L}, | 
8858  |  |     {0x1bc00, 0x1bc6a, direction::L},   {0x1bc70, 0x1bc7c, direction::L}, | 
8859  |  |     {0x1bc80, 0x1bc88, direction::L},   {0x1bc90, 0x1bc99, direction::L}, | 
8860  |  |     {0x1bc9c, 0x1bc9c, direction::L},   {0x1bc9d, 0x1bc9e, direction::NSM}, | 
8861  |  |     {0x1bc9f, 0x1bc9f, direction::L},   {0x1bca0, 0x1bca3, direction::BN}, | 
8862  |  |     {0x1d000, 0x1d0f5, direction::L},   {0x1d100, 0x1d126, direction::L}, | 
8863  |  |     {0x1d129, 0x1d166, direction::L},   {0x1d167, 0x1d169, direction::NSM}, | 
8864  |  |     {0x1d16a, 0x1d172, direction::L},   {0x1d173, 0x1d17a, direction::BN}, | 
8865  |  |     {0x1d17b, 0x1d182, direction::NSM}, {0x1d183, 0x1d184, direction::L}, | 
8866  |  |     {0x1d185, 0x1d18b, direction::NSM}, {0x1d18c, 0x1d1a9, direction::L}, | 
8867  |  |     {0x1d1aa, 0x1d1ad, direction::NSM}, {0x1d1ae, 0x1d1e8, direction::L}, | 
8868  |  |     {0x1d200, 0x1d241, direction::ON},  {0x1d242, 0x1d244, direction::NSM}, | 
8869  |  |     {0x1d245, 0x1d245, direction::ON},  {0x1d2e0, 0x1d2f3, direction::L}, | 
8870  |  |     {0x1d300, 0x1d356, direction::ON},  {0x1d360, 0x1d378, direction::L}, | 
8871  |  |     {0x1d400, 0x1d454, direction::L},   {0x1d456, 0x1d49c, direction::L}, | 
8872  |  |     {0x1d49e, 0x1d49f, direction::L},   {0x1d4a2, 0x1d4a2, direction::L}, | 
8873  |  |     {0x1d4a5, 0x1d4a6, direction::L},   {0x1d4a9, 0x1d4ac, direction::L}, | 
8874  |  |     {0x1d4ae, 0x1d4b9, direction::L},   {0x1d4bb, 0x1d4bb, direction::L}, | 
8875  |  |     {0x1d4bd, 0x1d4c3, direction::L},   {0x1d4c5, 0x1d505, direction::L}, | 
8876  |  |     {0x1d507, 0x1d50a, direction::L},   {0x1d50d, 0x1d514, direction::L}, | 
8877  |  |     {0x1d516, 0x1d51c, direction::L},   {0x1d51e, 0x1d539, direction::L}, | 
8878  |  |     {0x1d53b, 0x1d53e, direction::L},   {0x1d540, 0x1d544, direction::L}, | 
8879  |  |     {0x1d546, 0x1d546, direction::L},   {0x1d54a, 0x1d550, direction::L}, | 
8880  |  |     {0x1d552, 0x1d6a5, direction::L},   {0x1d6a8, 0x1d6da, direction::L}, | 
8881  |  |     {0x1d6db, 0x1d6db, direction::ON},  {0x1d6dc, 0x1d714, direction::L}, | 
8882  |  |     {0x1d715, 0x1d715, direction::ON},  {0x1d716, 0x1d74e, direction::L}, | 
8883  |  |     {0x1d74f, 0x1d74f, direction::ON},  {0x1d750, 0x1d788, direction::L}, | 
8884  |  |     {0x1d789, 0x1d789, direction::ON},  {0x1d78a, 0x1d7c2, direction::L}, | 
8885  |  |     {0x1d7c3, 0x1d7c3, direction::ON},  {0x1d7c4, 0x1d7cb, direction::L}, | 
8886  |  |     {0x1d7ce, 0x1d7ff, direction::EN},  {0x1d800, 0x1d9ff, direction::L}, | 
8887  |  |     {0x1da00, 0x1da36, direction::NSM}, {0x1da37, 0x1da3a, direction::L}, | 
8888  |  |     {0x1da3b, 0x1da6c, direction::NSM}, {0x1da6d, 0x1da74, direction::L}, | 
8889  |  |     {0x1da75, 0x1da75, direction::NSM}, {0x1da76, 0x1da83, direction::L}, | 
8890  |  |     {0x1da84, 0x1da84, direction::NSM}, {0x1da85, 0x1da8b, direction::L}, | 
8891  |  |     {0x1da9b, 0x1da9f, direction::NSM}, {0x1daa1, 0x1daaf, direction::NSM}, | 
8892  |  |     {0x1e000, 0x1e006, direction::NSM}, {0x1e008, 0x1e018, direction::NSM}, | 
8893  |  |     {0x1e01b, 0x1e021, direction::NSM}, {0x1e023, 0x1e024, direction::NSM}, | 
8894  |  |     {0x1e026, 0x1e02a, direction::NSM}, {0x1e100, 0x1e12c, direction::L}, | 
8895  |  |     {0x1e130, 0x1e136, direction::NSM}, {0x1e137, 0x1e13d, direction::L}, | 
8896  |  |     {0x1e140, 0x1e149, direction::L},   {0x1e14e, 0x1e14f, direction::L}, | 
8897  |  |     {0x1e2c0, 0x1e2eb, direction::L},   {0x1e2ec, 0x1e2ef, direction::NSM}, | 
8898  |  |     {0x1e2f0, 0x1e2f9, direction::L},   {0x1e2ff, 0x1e2ff, direction::ET}, | 
8899  |  |     {0x1e800, 0x1e8c4, direction::R},   {0x1e8c7, 0x1e8cf, direction::R}, | 
8900  |  |     {0x1e8d0, 0x1e8d6, direction::NSM}, {0x1e900, 0x1e943, direction::R}, | 
8901  |  |     {0x1e944, 0x1e94a, direction::NSM}, {0x1e94b, 0x1e94b, direction::R}, | 
8902  |  |     {0x1e950, 0x1e959, direction::R},   {0x1e95e, 0x1e95f, direction::R}, | 
8903  |  |     {0x1ec71, 0x1ecb4, direction::AL},  {0x1ed01, 0x1ed3d, direction::AL}, | 
8904  |  |     {0x1ee00, 0x1ee03, direction::AL},  {0x1ee05, 0x1ee1f, direction::AL}, | 
8905  |  |     {0x1ee21, 0x1ee22, direction::AL},  {0x1ee24, 0x1ee24, direction::AL}, | 
8906  |  |     {0x1ee27, 0x1ee27, direction::AL},  {0x1ee29, 0x1ee32, direction::AL}, | 
8907  |  |     {0x1ee34, 0x1ee37, direction::AL},  {0x1ee39, 0x1ee39, direction::AL}, | 
8908  |  |     {0x1ee3b, 0x1ee3b, direction::AL},  {0x1ee42, 0x1ee42, direction::AL}, | 
8909  |  |     {0x1ee47, 0x1ee47, direction::AL},  {0x1ee49, 0x1ee49, direction::AL}, | 
8910  |  |     {0x1ee4b, 0x1ee4b, direction::AL},  {0x1ee4d, 0x1ee4f, direction::AL}, | 
8911  |  |     {0x1ee51, 0x1ee52, direction::AL},  {0x1ee54, 0x1ee54, direction::AL}, | 
8912  |  |     {0x1ee57, 0x1ee57, direction::AL},  {0x1ee59, 0x1ee59, direction::AL}, | 
8913  |  |     {0x1ee5b, 0x1ee5b, direction::AL},  {0x1ee5d, 0x1ee5d, direction::AL}, | 
8914  |  |     {0x1ee5f, 0x1ee5f, direction::AL},  {0x1ee61, 0x1ee62, direction::AL}, | 
8915  |  |     {0x1ee64, 0x1ee64, direction::AL},  {0x1ee67, 0x1ee6a, direction::AL}, | 
8916  |  |     {0x1ee6c, 0x1ee72, direction::AL},  {0x1ee74, 0x1ee77, direction::AL}, | 
8917  |  |     {0x1ee79, 0x1ee7c, direction::AL},  {0x1ee7e, 0x1ee7e, direction::AL}, | 
8918  |  |     {0x1ee80, 0x1ee89, direction::AL},  {0x1ee8b, 0x1ee9b, direction::AL}, | 
8919  |  |     {0x1eea1, 0x1eea3, direction::AL},  {0x1eea5, 0x1eea9, direction::AL}, | 
8920  |  |     {0x1eeab, 0x1eebb, direction::AL},  {0x1eef0, 0x1eef1, direction::ON}, | 
8921  |  |     {0x1f000, 0x1f02b, direction::ON},  {0x1f030, 0x1f093, direction::ON}, | 
8922  |  |     {0x1f0a0, 0x1f0ae, direction::ON},  {0x1f0b1, 0x1f0bf, direction::ON}, | 
8923  |  |     {0x1f0c1, 0x1f0cf, direction::ON},  {0x1f0d1, 0x1f0f5, direction::ON}, | 
8924  |  |     {0x1f100, 0x1f10a, direction::EN},  {0x1f10b, 0x1f10f, direction::ON}, | 
8925  |  |     {0x1f110, 0x1f12e, direction::L},   {0x1f12f, 0x1f12f, direction::ON}, | 
8926  |  |     {0x1f130, 0x1f169, direction::L},   {0x1f16a, 0x1f16f, direction::ON}, | 
8927  |  |     {0x1f170, 0x1f1ac, direction::L},   {0x1f1ad, 0x1f1ad, direction::ON}, | 
8928  |  |     {0x1f1e6, 0x1f202, direction::L},   {0x1f210, 0x1f23b, direction::L}, | 
8929  |  |     {0x1f240, 0x1f248, direction::L},   {0x1f250, 0x1f251, direction::L}, | 
8930  |  |     {0x1f260, 0x1f265, direction::ON},  {0x1f300, 0x1f6d7, direction::ON}, | 
8931  |  |     {0x1f6e0, 0x1f6ec, direction::ON},  {0x1f6f0, 0x1f6fc, direction::ON}, | 
8932  |  |     {0x1f700, 0x1f773, direction::ON},  {0x1f780, 0x1f7d8, direction::ON}, | 
8933  |  |     {0x1f7e0, 0x1f7eb, direction::ON},  {0x1f800, 0x1f80b, direction::ON}, | 
8934  |  |     {0x1f810, 0x1f847, direction::ON},  {0x1f850, 0x1f859, direction::ON}, | 
8935  |  |     {0x1f860, 0x1f887, direction::ON},  {0x1f890, 0x1f8ad, direction::ON}, | 
8936  |  |     {0x1f8b0, 0x1f8b1, direction::ON},  {0x1f900, 0x1f978, direction::ON}, | 
8937  |  |     {0x1f97a, 0x1f9cb, direction::ON},  {0x1f9cd, 0x1fa53, direction::ON}, | 
8938  |  |     {0x1fa60, 0x1fa6d, direction::ON},  {0x1fa70, 0x1fa74, direction::ON}, | 
8939  |  |     {0x1fa78, 0x1fa7a, direction::ON},  {0x1fa80, 0x1fa86, direction::ON}, | 
8940  |  |     {0x1fa90, 0x1faa8, direction::ON},  {0x1fab0, 0x1fab6, direction::ON}, | 
8941  |  |     {0x1fac0, 0x1fac2, direction::ON},  {0x1fad0, 0x1fad6, direction::ON}, | 
8942  |  |     {0x1fb00, 0x1fb92, direction::ON},  {0x1fb94, 0x1fbca, direction::ON}, | 
8943  |  |     {0x1fbf0, 0x1fbf9, direction::EN},  {0x20000, 0x2a6dd, direction::L}, | 
8944  |  |     {0x2a700, 0x2b734, direction::L},   {0x2b740, 0x2b81d, direction::L}, | 
8945  |  |     {0x2b820, 0x2cea1, direction::L},   {0x2ceb0, 0x2ebe0, direction::L}, | 
8946  |  |     {0x2f800, 0x2fa1d, direction::L},   {0x30000, 0x3134a, direction::L}, | 
8947  |  |     {0xe0001, 0xe0001, direction::BN},  {0xe0020, 0xe007f, direction::BN}, | 
8948  |  |     {0xe0100, 0xe01ef, direction::NSM}, {0xf0000, 0xffffd, direction::L}, | 
8949  |  |     {0x100000, 0x10fffd, direction::L}}; | 
8950  |  |  | 
8951  |  | // CheckJoiners and CheckBidi are true for URL specification.  | 
8952  |  |  | 
8953  | 230k  | inline static direction find_direction(uint32_t code_point) noexcept { | 
8954  | 230k  |   auto it = std::lower_bound(  | 
8955  | 230k  |       std::begin(dir_table), std::end(dir_table), code_point,  | 
8956  | 2.36M  |       [](const directions& d, uint32_t c) { return d.final_code < c; }); | 
8957  |  |  | 
8958  |  |   // next check is almost surely in vain, but we use it for safety.  | 
8959  | 230k  |   if (it == std::end(dir_table)) { | 
8960  | 0  |     return direction::NONE;  | 
8961  | 0  |   }  | 
8962  |  |   // We have that d.final_code >= c.  | 
8963  | 230k  |   if (code_point >= it->start_code) { | 
8964  | 229k  |     return it->direct;  | 
8965  | 229k  |   }  | 
8966  | 1.48k  |   return direction::NONE;  | 
8967  | 230k  | }  | 
8968  |  |  | 
8969  |  | inline static size_t find_last_not_of_nsm(  | 
8970  | 32.2k  |     const std::u32string_view label) noexcept { | 
8971  | 33.3k  |   for (int i = label.size() - 1; i >= 0; i--)  | 
8972  | 33.3k  |     if (find_direction(label[i]) != direction::NSM) return i;  | 
8973  |  |  | 
8974  | 0  |   return std::u32string_view::npos;  | 
8975  | 32.2k  | }  | 
8976  |  |  | 
8977  |  | // An RTL label is a label that contains at least one character of type R, AL,  | 
8978  |  | // or AN. https://www.rfc-editor.org/rfc/rfc5893#section-2  | 
8979  | 32.2k  | inline static bool is_rtl_label(const std::u32string_view label) noexcept { | 
8980  | 32.2k  |   const size_t mask =  | 
8981  | 32.2k  |       (1u << direction::R) | (1u << direction::AL) | (1u << direction::AN);  | 
8982  |  |  | 
8983  | 32.2k  |   size_t directions = 0;  | 
8984  | 217k  |   for (size_t i = 0; i < label.size(); i++) { | 
8985  | 185k  |     directions |= 1u << find_direction(label[i]);  | 
8986  | 185k  |   }  | 
8987  | 32.2k  |   return (directions & mask) != 0;  | 
8988  | 32.2k  | }  | 
8989  |  |  | 
8990  | 34.4k  | bool is_label_valid(const std::u32string_view label) { | 
8991  | 34.4k  |   if (label.empty()) { | 
8992  | 0  |     return true;  | 
8993  | 0  |   }  | 
8994  |  |  | 
8995  |  |   ///////////////  | 
8996  |  |   // We have a normalization step which ensures that we are in NFC.  | 
8997  |  |   // If we receive punycode, we normalize and check that the normalized  | 
8998  |  |   // version matches the original.  | 
8999  |  |   // --------------------------------------  | 
9000  |  |   // The label must be in Unicode Normalization Form NFC.  | 
9001  |  |  | 
9002  |  |   // Current URL standard indicatest that CheckHyphens is set to false.  | 
9003  |  |   // ---------------------------------------  | 
9004  |  |   // If CheckHyphens, the label must not contain a U+002D HYPHEN-MINUS character  | 
9005  |  |   // in both the third and fourth positions. If CheckHyphens, the label must  | 
9006  |  |   // neither begin nor end with a U+002D HYPHEN-MINUS character.  | 
9007  |  |  | 
9008  |  |   // This is not necessary because we segment the  | 
9009  |  |   // labels by '.'.  | 
9010  |  |   // ---------------------------------------  | 
9011  |  |   // The label must not contain a U+002E ( . ) FULL STOP.  | 
9012  |  |   // if (label.find('.') != std::string_view::npos) return false; | 
9013  |  |  | 
9014  |  |   // The label must not begin with a combining mark, that is:  | 
9015  |  |   // General_Category=Mark.  | 
9016  | 34.4k  |   constexpr static uint32_t combining[] = { | 
9017  | 34.4k  |       0x300,   0x301,   0x302,   0x303,   0x304,   0x305,   0x306,   0x307,  | 
9018  | 34.4k  |       0x308,   0x309,   0x30a,   0x30b,   0x30c,   0x30d,   0x30e,   0x30f,  | 
9019  | 34.4k  |       0x310,   0x311,   0x312,   0x313,   0x314,   0x315,   0x316,   0x317,  | 
9020  | 34.4k  |       0x318,   0x319,   0x31a,   0x31b,   0x31c,   0x31d,   0x31e,   0x31f,  | 
9021  | 34.4k  |       0x320,   0x321,   0x322,   0x323,   0x324,   0x325,   0x326,   0x327,  | 
9022  | 34.4k  |       0x328,   0x329,   0x32a,   0x32b,   0x32c,   0x32d,   0x32e,   0x32f,  | 
9023  | 34.4k  |       0x330,   0x331,   0x332,   0x333,   0x334,   0x335,   0x336,   0x337,  | 
9024  | 34.4k  |       0x338,   0x339,   0x33a,   0x33b,   0x33c,   0x33d,   0x33e,   0x33f,  | 
9025  | 34.4k  |       0x340,   0x341,   0x342,   0x343,   0x344,   0x345,   0x346,   0x347,  | 
9026  | 34.4k  |       0x348,   0x349,   0x34a,   0x34b,   0x34c,   0x34d,   0x34e,   0x34f,  | 
9027  | 34.4k  |       0x350,   0x351,   0x352,   0x353,   0x354,   0x355,   0x356,   0x357,  | 
9028  | 34.4k  |       0x358,   0x359,   0x35a,   0x35b,   0x35c,   0x35d,   0x35e,   0x35f,  | 
9029  | 34.4k  |       0x360,   0x361,   0x362,   0x363,   0x364,   0x365,   0x366,   0x367,  | 
9030  | 34.4k  |       0x368,   0x369,   0x36a,   0x36b,   0x36c,   0x36d,   0x36e,   0x36f,  | 
9031  | 34.4k  |       0x483,   0x484,   0x485,   0x486,   0x487,   0x488,   0x489,   0x591,  | 
9032  | 34.4k  |       0x592,   0x593,   0x594,   0x595,   0x596,   0x597,   0x598,   0x599,  | 
9033  | 34.4k  |       0x59a,   0x59b,   0x59c,   0x59d,   0x59e,   0x59f,   0x5a0,   0x5a1,  | 
9034  | 34.4k  |       0x5a2,   0x5a3,   0x5a4,   0x5a5,   0x5a6,   0x5a7,   0x5a8,   0x5a9,  | 
9035  | 34.4k  |       0x5aa,   0x5ab,   0x5ac,   0x5ad,   0x5ae,   0x5af,   0x5b0,   0x5b1,  | 
9036  | 34.4k  |       0x5b2,   0x5b3,   0x5b4,   0x5b5,   0x5b6,   0x5b7,   0x5b8,   0x5b9,  | 
9037  | 34.4k  |       0x5ba,   0x5bb,   0x5bc,   0x5bd,   0x5bf,   0x5c1,   0x5c2,   0x5c4,  | 
9038  | 34.4k  |       0x5c5,   0x5c7,   0x610,   0x611,   0x612,   0x613,   0x614,   0x615,  | 
9039  | 34.4k  |       0x616,   0x617,   0x618,   0x619,   0x61a,   0x64b,   0x64c,   0x64d,  | 
9040  | 34.4k  |       0x64e,   0x64f,   0x650,   0x651,   0x652,   0x653,   0x654,   0x655,  | 
9041  | 34.4k  |       0x656,   0x657,   0x658,   0x659,   0x65a,   0x65b,   0x65c,   0x65d,  | 
9042  | 34.4k  |       0x65e,   0x65f,   0x670,   0x6d6,   0x6d7,   0x6d8,   0x6d9,   0x6da,  | 
9043  | 34.4k  |       0x6db,   0x6dc,   0x6df,   0x6e0,   0x6e1,   0x6e2,   0x6e3,   0x6e4,  | 
9044  | 34.4k  |       0x6e7,   0x6e8,   0x6ea,   0x6eb,   0x6ec,   0x6ed,   0x711,   0x730,  | 
9045  | 34.4k  |       0x731,   0x732,   0x733,   0x734,   0x735,   0x736,   0x737,   0x738,  | 
9046  | 34.4k  |       0x739,   0x73a,   0x73b,   0x73c,   0x73d,   0x73e,   0x73f,   0x740,  | 
9047  | 34.4k  |       0x741,   0x742,   0x743,   0x744,   0x745,   0x746,   0x747,   0x748,  | 
9048  | 34.4k  |       0x749,   0x74a,   0x7a6,   0x7a7,   0x7a8,   0x7a9,   0x7aa,   0x7ab,  | 
9049  | 34.4k  |       0x7ac,   0x7ad,   0x7ae,   0x7af,   0x7b0,   0x7eb,   0x7ec,   0x7ed,  | 
9050  | 34.4k  |       0x7ee,   0x7ef,   0x7f0,   0x7f1,   0x7f2,   0x7f3,   0x7fd,   0x816,  | 
9051  | 34.4k  |       0x817,   0x818,   0x819,   0x81b,   0x81c,   0x81d,   0x81e,   0x81f,  | 
9052  | 34.4k  |       0x820,   0x821,   0x822,   0x823,   0x825,   0x826,   0x827,   0x829,  | 
9053  | 34.4k  |       0x82a,   0x82b,   0x82c,   0x82d,   0x859,   0x85a,   0x85b,   0x8d3,  | 
9054  | 34.4k  |       0x8d4,   0x8d5,   0x8d6,   0x8d7,   0x8d8,   0x8d9,   0x8da,   0x8db,  | 
9055  | 34.4k  |       0x8dc,   0x8dd,   0x8de,   0x8df,   0x8e0,   0x8e1,   0x8e3,   0x8e4,  | 
9056  | 34.4k  |       0x8e5,   0x8e6,   0x8e7,   0x8e8,   0x8e9,   0x8ea,   0x8eb,   0x8ec,  | 
9057  | 34.4k  |       0x8ed,   0x8ee,   0x8ef,   0x8f0,   0x8f1,   0x8f2,   0x8f3,   0x8f4,  | 
9058  | 34.4k  |       0x8f5,   0x8f6,   0x8f7,   0x8f8,   0x8f9,   0x8fa,   0x8fb,   0x8fc,  | 
9059  | 34.4k  |       0x8fd,   0x8fe,   0x8ff,   0x900,   0x901,   0x902,   0x903,   0x93a,  | 
9060  | 34.4k  |       0x93b,   0x93c,   0x93e,   0x93f,   0x940,   0x941,   0x942,   0x943,  | 
9061  | 34.4k  |       0x944,   0x945,   0x946,   0x947,   0x948,   0x949,   0x94a,   0x94b,  | 
9062  | 34.4k  |       0x94c,   0x94d,   0x94e,   0x94f,   0x951,   0x952,   0x953,   0x954,  | 
9063  | 34.4k  |       0x955,   0x956,   0x957,   0x962,   0x963,   0x981,   0x982,   0x983,  | 
9064  | 34.4k  |       0x9bc,   0x9be,   0x9bf,   0x9c0,   0x9c1,   0x9c2,   0x9c3,   0x9c4,  | 
9065  | 34.4k  |       0x9c7,   0x9c8,   0x9cb,   0x9cc,   0x9cd,   0x9d7,   0x9e2,   0x9e3,  | 
9066  | 34.4k  |       0x9fe,   0xa01,   0xa02,   0xa03,   0xa3c,   0xa3e,   0xa3f,   0xa40,  | 
9067  | 34.4k  |       0xa41,   0xa42,   0xa47,   0xa48,   0xa4b,   0xa4c,   0xa4d,   0xa51,  | 
9068  | 34.4k  |       0xa70,   0xa71,   0xa75,   0xa81,   0xa82,   0xa83,   0xabc,   0xabe,  | 
9069  | 34.4k  |       0xabf,   0xac0,   0xac1,   0xac2,   0xac3,   0xac4,   0xac5,   0xac7,  | 
9070  | 34.4k  |       0xac8,   0xac9,   0xacb,   0xacc,   0xacd,   0xae2,   0xae3,   0xafa,  | 
9071  | 34.4k  |       0xafb,   0xafc,   0xafd,   0xafe,   0xaff,   0xb01,   0xb02,   0xb03,  | 
9072  | 34.4k  |       0xb3c,   0xb3e,   0xb3f,   0xb40,   0xb41,   0xb42,   0xb43,   0xb44,  | 
9073  | 34.4k  |       0xb47,   0xb48,   0xb4b,   0xb4c,   0xb4d,   0xb55,   0xb56,   0xb57,  | 
9074  | 34.4k  |       0xb62,   0xb63,   0xb82,   0xbbe,   0xbbf,   0xbc0,   0xbc1,   0xbc2,  | 
9075  | 34.4k  |       0xbc6,   0xbc7,   0xbc8,   0xbca,   0xbcb,   0xbcc,   0xbcd,   0xbd7,  | 
9076  | 34.4k  |       0xc00,   0xc01,   0xc02,   0xc03,   0xc04,   0xc3e,   0xc3f,   0xc40,  | 
9077  | 34.4k  |       0xc41,   0xc42,   0xc43,   0xc44,   0xc46,   0xc47,   0xc48,   0xc4a,  | 
9078  | 34.4k  |       0xc4b,   0xc4c,   0xc4d,   0xc55,   0xc56,   0xc62,   0xc63,   0xc81,  | 
9079  | 34.4k  |       0xc82,   0xc83,   0xcbc,   0xcbe,   0xcbf,   0xcc0,   0xcc1,   0xcc2,  | 
9080  | 34.4k  |       0xcc3,   0xcc4,   0xcc6,   0xcc7,   0xcc8,   0xcca,   0xccb,   0xccc,  | 
9081  | 34.4k  |       0xccd,   0xcd5,   0xcd6,   0xce2,   0xce3,   0xd00,   0xd01,   0xd02,  | 
9082  | 34.4k  |       0xd03,   0xd3b,   0xd3c,   0xd3e,   0xd3f,   0xd40,   0xd41,   0xd42,  | 
9083  | 34.4k  |       0xd43,   0xd44,   0xd46,   0xd47,   0xd48,   0xd4a,   0xd4b,   0xd4c,  | 
9084  | 34.4k  |       0xd4d,   0xd57,   0xd62,   0xd63,   0xd81,   0xd82,   0xd83,   0xdca,  | 
9085  | 34.4k  |       0xdcf,   0xdd0,   0xdd1,   0xdd2,   0xdd3,   0xdd4,   0xdd6,   0xdd8,  | 
9086  | 34.4k  |       0xdd9,   0xdda,   0xddb,   0xddc,   0xddd,   0xdde,   0xddf,   0xdf2,  | 
9087  | 34.4k  |       0xdf3,   0xe31,   0xe34,   0xe35,   0xe36,   0xe37,   0xe38,   0xe39,  | 
9088  | 34.4k  |       0xe3a,   0xe47,   0xe48,   0xe49,   0xe4a,   0xe4b,   0xe4c,   0xe4d,  | 
9089  | 34.4k  |       0xe4e,   0xeb1,   0xeb4,   0xeb5,   0xeb6,   0xeb7,   0xeb8,   0xeb9,  | 
9090  | 34.4k  |       0xeba,   0xebb,   0xebc,   0xec8,   0xec9,   0xeca,   0xecb,   0xecc,  | 
9091  | 34.4k  |       0xecd,   0xf18,   0xf19,   0xf35,   0xf37,   0xf39,   0xf3e,   0xf3f,  | 
9092  | 34.4k  |       0xf71,   0xf72,   0xf73,   0xf74,   0xf75,   0xf76,   0xf77,   0xf78,  | 
9093  | 34.4k  |       0xf79,   0xf7a,   0xf7b,   0xf7c,   0xf7d,   0xf7e,   0xf7f,   0xf80,  | 
9094  | 34.4k  |       0xf81,   0xf82,   0xf83,   0xf84,   0xf86,   0xf87,   0xf8d,   0xf8e,  | 
9095  | 34.4k  |       0xf8f,   0xf90,   0xf91,   0xf92,   0xf93,   0xf94,   0xf95,   0xf96,  | 
9096  | 34.4k  |       0xf97,   0xf99,   0xf9a,   0xf9b,   0xf9c,   0xf9d,   0xf9e,   0xf9f,  | 
9097  | 34.4k  |       0xfa0,   0xfa1,   0xfa2,   0xfa3,   0xfa4,   0xfa5,   0xfa6,   0xfa7,  | 
9098  | 34.4k  |       0xfa8,   0xfa9,   0xfaa,   0xfab,   0xfac,   0xfad,   0xfae,   0xfaf,  | 
9099  | 34.4k  |       0xfb0,   0xfb1,   0xfb2,   0xfb3,   0xfb4,   0xfb5,   0xfb6,   0xfb7,  | 
9100  | 34.4k  |       0xfb8,   0xfb9,   0xfba,   0xfbb,   0xfbc,   0xfc6,   0x102b,  0x102c,  | 
9101  | 34.4k  |       0x102d,  0x102e,  0x102f,  0x1030,  0x1031,  0x1032,  0x1033,  0x1034,  | 
9102  | 34.4k  |       0x1035,  0x1036,  0x1037,  0x1038,  0x1039,  0x103a,  0x103b,  0x103c,  | 
9103  | 34.4k  |       0x103d,  0x103e,  0x1056,  0x1057,  0x1058,  0x1059,  0x105e,  0x105f,  | 
9104  | 34.4k  |       0x1060,  0x1062,  0x1063,  0x1064,  0x1067,  0x1068,  0x1069,  0x106a,  | 
9105  | 34.4k  |       0x106b,  0x106c,  0x106d,  0x1071,  0x1072,  0x1073,  0x1074,  0x1082,  | 
9106  | 34.4k  |       0x1083,  0x1084,  0x1085,  0x1086,  0x1087,  0x1088,  0x1089,  0x108a,  | 
9107  | 34.4k  |       0x108b,  0x108c,  0x108d,  0x108f,  0x109a,  0x109b,  0x109c,  0x109d,  | 
9108  | 34.4k  |       0x135d,  0x135e,  0x135f,  0x1712,  0x1713,  0x1714,  0x1732,  0x1733,  | 
9109  | 34.4k  |       0x1734,  0x1752,  0x1753,  0x1772,  0x1773,  0x17b4,  0x17b5,  0x17b6,  | 
9110  | 34.4k  |       0x17b7,  0x17b8,  0x17b9,  0x17ba,  0x17bb,  0x17bc,  0x17bd,  0x17be,  | 
9111  | 34.4k  |       0x17bf,  0x17c0,  0x17c1,  0x17c2,  0x17c3,  0x17c4,  0x17c5,  0x17c6,  | 
9112  | 34.4k  |       0x17c7,  0x17c8,  0x17c9,  0x17ca,  0x17cb,  0x17cc,  0x17cd,  0x17ce,  | 
9113  | 34.4k  |       0x17cf,  0x17d0,  0x17d1,  0x17d2,  0x17d3,  0x17dd,  0x180b,  0x180c,  | 
9114  | 34.4k  |       0x180d,  0x1885,  0x1886,  0x18a9,  0x1920,  0x1921,  0x1922,  0x1923,  | 
9115  | 34.4k  |       0x1924,  0x1925,  0x1926,  0x1927,  0x1928,  0x1929,  0x192a,  0x192b,  | 
9116  | 34.4k  |       0x1930,  0x1931,  0x1932,  0x1933,  0x1934,  0x1935,  0x1936,  0x1937,  | 
9117  | 34.4k  |       0x1938,  0x1939,  0x193a,  0x193b,  0x1a17,  0x1a18,  0x1a19,  0x1a1a,  | 
9118  | 34.4k  |       0x1a1b,  0x1a55,  0x1a56,  0x1a57,  0x1a58,  0x1a59,  0x1a5a,  0x1a5b,  | 
9119  | 34.4k  |       0x1a5c,  0x1a5d,  0x1a5e,  0x1a60,  0x1a61,  0x1a62,  0x1a63,  0x1a64,  | 
9120  | 34.4k  |       0x1a65,  0x1a66,  0x1a67,  0x1a68,  0x1a69,  0x1a6a,  0x1a6b,  0x1a6c,  | 
9121  | 34.4k  |       0x1a6d,  0x1a6e,  0x1a6f,  0x1a70,  0x1a71,  0x1a72,  0x1a73,  0x1a74,  | 
9122  | 34.4k  |       0x1a75,  0x1a76,  0x1a77,  0x1a78,  0x1a79,  0x1a7a,  0x1a7b,  0x1a7c,  | 
9123  | 34.4k  |       0x1a7f,  0x1ab0,  0x1ab1,  0x1ab2,  0x1ab3,  0x1ab4,  0x1ab5,  0x1ab6,  | 
9124  | 34.4k  |       0x1ab7,  0x1ab8,  0x1ab9,  0x1aba,  0x1abb,  0x1abc,  0x1abd,  0x1abe,  | 
9125  | 34.4k  |       0x1abf,  0x1ac0,  0x1b00,  0x1b01,  0x1b02,  0x1b03,  0x1b04,  0x1b34,  | 
9126  | 34.4k  |       0x1b35,  0x1b36,  0x1b37,  0x1b38,  0x1b39,  0x1b3a,  0x1b3b,  0x1b3c,  | 
9127  | 34.4k  |       0x1b3d,  0x1b3e,  0x1b3f,  0x1b40,  0x1b41,  0x1b42,  0x1b43,  0x1b44,  | 
9128  | 34.4k  |       0x1b6b,  0x1b6c,  0x1b6d,  0x1b6e,  0x1b6f,  0x1b70,  0x1b71,  0x1b72,  | 
9129  | 34.4k  |       0x1b73,  0x1b80,  0x1b81,  0x1b82,  0x1ba1,  0x1ba2,  0x1ba3,  0x1ba4,  | 
9130  | 34.4k  |       0x1ba5,  0x1ba6,  0x1ba7,  0x1ba8,  0x1ba9,  0x1baa,  0x1bab,  0x1bac,  | 
9131  | 34.4k  |       0x1bad,  0x1be6,  0x1be7,  0x1be8,  0x1be9,  0x1bea,  0x1beb,  0x1bec,  | 
9132  | 34.4k  |       0x1bed,  0x1bee,  0x1bef,  0x1bf0,  0x1bf1,  0x1bf2,  0x1bf3,  0x1c24,  | 
9133  | 34.4k  |       0x1c25,  0x1c26,  0x1c27,  0x1c28,  0x1c29,  0x1c2a,  0x1c2b,  0x1c2c,  | 
9134  | 34.4k  |       0x1c2d,  0x1c2e,  0x1c2f,  0x1c30,  0x1c31,  0x1c32,  0x1c33,  0x1c34,  | 
9135  | 34.4k  |       0x1c35,  0x1c36,  0x1c37,  0x1cd0,  0x1cd1,  0x1cd2,  0x1cd4,  0x1cd5,  | 
9136  | 34.4k  |       0x1cd6,  0x1cd7,  0x1cd8,  0x1cd9,  0x1cda,  0x1cdb,  0x1cdc,  0x1cdd,  | 
9137  | 34.4k  |       0x1cde,  0x1cdf,  0x1ce0,  0x1ce1,  0x1ce2,  0x1ce3,  0x1ce4,  0x1ce5,  | 
9138  | 34.4k  |       0x1ce6,  0x1ce7,  0x1ce8,  0x1ced,  0x1cf4,  0x1cf7,  0x1cf8,  0x1cf9,  | 
9139  | 34.4k  |       0x1dc0,  0x1dc1,  0x1dc2,  0x1dc3,  0x1dc4,  0x1dc5,  0x1dc6,  0x1dc7,  | 
9140  | 34.4k  |       0x1dc8,  0x1dc9,  0x1dca,  0x1dcb,  0x1dcc,  0x1dcd,  0x1dce,  0x1dcf,  | 
9141  | 34.4k  |       0x1dd0,  0x1dd1,  0x1dd2,  0x1dd3,  0x1dd4,  0x1dd5,  0x1dd6,  0x1dd7,  | 
9142  | 34.4k  |       0x1dd8,  0x1dd9,  0x1dda,  0x1ddb,  0x1ddc,  0x1ddd,  0x1dde,  0x1ddf,  | 
9143  | 34.4k  |       0x1de0,  0x1de1,  0x1de2,  0x1de3,  0x1de4,  0x1de5,  0x1de6,  0x1de7,  | 
9144  | 34.4k  |       0x1de8,  0x1de9,  0x1dea,  0x1deb,  0x1dec,  0x1ded,  0x1dee,  0x1def,  | 
9145  | 34.4k  |       0x1df0,  0x1df1,  0x1df2,  0x1df3,  0x1df4,  0x1df5,  0x1df6,  0x1df7,  | 
9146  | 34.4k  |       0x1df8,  0x1df9,  0x1dfb,  0x1dfc,  0x1dfd,  0x1dfe,  0x1dff,  0x20d0,  | 
9147  | 34.4k  |       0x20d1,  0x20d2,  0x20d3,  0x20d4,  0x20d5,  0x20d6,  0x20d7,  0x20d8,  | 
9148  | 34.4k  |       0x20d9,  0x20da,  0x20db,  0x20dc,  0x20dd,  0x20de,  0x20df,  0x20e0,  | 
9149  | 34.4k  |       0x20e1,  0x20e2,  0x20e3,  0x20e4,  0x20e5,  0x20e6,  0x20e7,  0x20e8,  | 
9150  | 34.4k  |       0x20e9,  0x20ea,  0x20eb,  0x20ec,  0x20ed,  0x20ee,  0x20ef,  0x20f0,  | 
9151  | 34.4k  |       0x2cef,  0x2cf0,  0x2cf1,  0x2d7f,  0x2de0,  0x2de1,  0x2de2,  0x2de3,  | 
9152  | 34.4k  |       0x2de4,  0x2de5,  0x2de6,  0x2de7,  0x2de8,  0x2de9,  0x2dea,  0x2deb,  | 
9153  | 34.4k  |       0x2dec,  0x2ded,  0x2dee,  0x2def,  0x2df0,  0x2df1,  0x2df2,  0x2df3,  | 
9154  | 34.4k  |       0x2df4,  0x2df5,  0x2df6,  0x2df7,  0x2df8,  0x2df9,  0x2dfa,  0x2dfb,  | 
9155  | 34.4k  |       0x2dfc,  0x2dfd,  0x2dfe,  0x2dff,  0x302a,  0x302b,  0x302c,  0x302d,  | 
9156  | 34.4k  |       0x302e,  0x302f,  0x3099,  0x309a,  0xa66f,  0xa670,  0xa671,  0xa672,  | 
9157  | 34.4k  |       0xa674,  0xa675,  0xa676,  0xa677,  0xa678,  0xa679,  0xa67a,  0xa67b,  | 
9158  | 34.4k  |       0xa67c,  0xa67d,  0xa69e,  0xa69f,  0xa6f0,  0xa6f1,  0xa802,  0xa806,  | 
9159  | 34.4k  |       0xa80b,  0xa823,  0xa824,  0xa825,  0xa826,  0xa827,  0xa82c,  0xa880,  | 
9160  | 34.4k  |       0xa881,  0xa8b4,  0xa8b5,  0xa8b6,  0xa8b7,  0xa8b8,  0xa8b9,  0xa8ba,  | 
9161  | 34.4k  |       0xa8bb,  0xa8bc,  0xa8bd,  0xa8be,  0xa8bf,  0xa8c0,  0xa8c1,  0xa8c2,  | 
9162  | 34.4k  |       0xa8c3,  0xa8c4,  0xa8c5,  0xa8e0,  0xa8e1,  0xa8e2,  0xa8e3,  0xa8e4,  | 
9163  | 34.4k  |       0xa8e5,  0xa8e6,  0xa8e7,  0xa8e8,  0xa8e9,  0xa8ea,  0xa8eb,  0xa8ec,  | 
9164  | 34.4k  |       0xa8ed,  0xa8ee,  0xa8ef,  0xa8f0,  0xa8f1,  0xa8ff,  0xa926,  0xa927,  | 
9165  | 34.4k  |       0xa928,  0xa929,  0xa92a,  0xa92b,  0xa92c,  0xa92d,  0xa947,  0xa948,  | 
9166  | 34.4k  |       0xa949,  0xa94a,  0xa94b,  0xa94c,  0xa94d,  0xa94e,  0xa94f,  0xa950,  | 
9167  | 34.4k  |       0xa951,  0xa952,  0xa953,  0xa980,  0xa981,  0xa982,  0xa983,  0xa9b3,  | 
9168  | 34.4k  |       0xa9b4,  0xa9b5,  0xa9b6,  0xa9b7,  0xa9b8,  0xa9b9,  0xa9ba,  0xa9bb,  | 
9169  | 34.4k  |       0xa9bc,  0xa9bd,  0xa9be,  0xa9bf,  0xa9c0,  0xa9e5,  0xaa29,  0xaa2a,  | 
9170  | 34.4k  |       0xaa2b,  0xaa2c,  0xaa2d,  0xaa2e,  0xaa2f,  0xaa30,  0xaa31,  0xaa32,  | 
9171  | 34.4k  |       0xaa33,  0xaa34,  0xaa35,  0xaa36,  0xaa43,  0xaa4c,  0xaa4d,  0xaa7b,  | 
9172  | 34.4k  |       0xaa7c,  0xaa7d,  0xaab0,  0xaab2,  0xaab3,  0xaab4,  0xaab7,  0xaab8,  | 
9173  | 34.4k  |       0xaabe,  0xaabf,  0xaac1,  0xaaeb,  0xaaec,  0xaaed,  0xaaee,  0xaaef,  | 
9174  | 34.4k  |       0xaaf5,  0xaaf6,  0xabe3,  0xabe4,  0xabe5,  0xabe6,  0xabe7,  0xabe8,  | 
9175  | 34.4k  |       0xabe9,  0xabea,  0xabec,  0xabed,  0xfb1e,  0xfe00,  0xfe01,  0xfe02,  | 
9176  | 34.4k  |       0xfe03,  0xfe04,  0xfe05,  0xfe06,  0xfe07,  0xfe08,  0xfe09,  0xfe0a,  | 
9177  | 34.4k  |       0xfe0b,  0xfe0c,  0xfe0d,  0xfe0e,  0xfe0f,  0xfe20,  0xfe21,  0xfe22,  | 
9178  | 34.4k  |       0xfe23,  0xfe24,  0xfe25,  0xfe26,  0xfe27,  0xfe28,  0xfe29,  0xfe2a,  | 
9179  | 34.4k  |       0xfe2b,  0xfe2c,  0xfe2d,  0xfe2e,  0xfe2f,  0x101fd, 0x102e0, 0x10376,  | 
9180  | 34.4k  |       0x10377, 0x10378, 0x10379, 0x1037a, 0x10a01, 0x10a02, 0x10a03, 0x10a05,  | 
9181  | 34.4k  |       0x10a06, 0x10a0c, 0x10a0d, 0x10a0e, 0x10a0f, 0x10a38, 0x10a39, 0x10a3a,  | 
9182  | 34.4k  |       0x10a3f, 0x10ae5, 0x10ae6, 0x10d24, 0x10d25, 0x10d26, 0x10d27, 0x10eab,  | 
9183  | 34.4k  |       0x10eac, 0x10f46, 0x10f47, 0x10f48, 0x10f49, 0x10f4a, 0x10f4b, 0x10f4c,  | 
9184  | 34.4k  |       0x10f4d, 0x10f4e, 0x10f4f, 0x10f50, 0x11000, 0x11001, 0x11002, 0x11038,  | 
9185  | 34.4k  |       0x11039, 0x1103a, 0x1103b, 0x1103c, 0x1103d, 0x1103e, 0x1103f, 0x11040,  | 
9186  | 34.4k  |       0x11041, 0x11042, 0x11043, 0x11044, 0x11045, 0x11046, 0x1107f, 0x11080,  | 
9187  | 34.4k  |       0x11081, 0x11082, 0x110b0, 0x110b1, 0x110b2, 0x110b3, 0x110b4, 0x110b5,  | 
9188  | 34.4k  |       0x110b6, 0x110b7, 0x110b8, 0x110b9, 0x110ba, 0x11100, 0x11101, 0x11102,  | 
9189  | 34.4k  |       0x11127, 0x11128, 0x11129, 0x1112a, 0x1112b, 0x1112c, 0x1112d, 0x1112e,  | 
9190  | 34.4k  |       0x1112f, 0x11130, 0x11131, 0x11132, 0x11133, 0x11134, 0x11145, 0x11146,  | 
9191  | 34.4k  |       0x11173, 0x11180, 0x11181, 0x11182, 0x111b3, 0x111b4, 0x111b5, 0x111b6,  | 
9192  | 34.4k  |       0x111b7, 0x111b8, 0x111b9, 0x111ba, 0x111bb, 0x111bc, 0x111bd, 0x111be,  | 
9193  | 34.4k  |       0x111bf, 0x111c0, 0x111c9, 0x111ca, 0x111cb, 0x111cc, 0x111ce, 0x111cf,  | 
9194  | 34.4k  |       0x1122c, 0x1122d, 0x1122e, 0x1122f, 0x11230, 0x11231, 0x11232, 0x11233,  | 
9195  | 34.4k  |       0x11234, 0x11235, 0x11236, 0x11237, 0x1123e, 0x112df, 0x112e0, 0x112e1,  | 
9196  | 34.4k  |       0x112e2, 0x112e3, 0x112e4, 0x112e5, 0x112e6, 0x112e7, 0x112e8, 0x112e9,  | 
9197  | 34.4k  |       0x112ea, 0x11300, 0x11301, 0x11302, 0x11303, 0x1133b, 0x1133c, 0x1133e,  | 
9198  | 34.4k  |       0x1133f, 0x11340, 0x11341, 0x11342, 0x11343, 0x11344, 0x11347, 0x11348,  | 
9199  | 34.4k  |       0x1134b, 0x1134c, 0x1134d, 0x11357, 0x11362, 0x11363, 0x11366, 0x11367,  | 
9200  | 34.4k  |       0x11368, 0x11369, 0x1136a, 0x1136b, 0x1136c, 0x11370, 0x11371, 0x11372,  | 
9201  | 34.4k  |       0x11373, 0x11374, 0x11435, 0x11436, 0x11437, 0x11438, 0x11439, 0x1143a,  | 
9202  | 34.4k  |       0x1143b, 0x1143c, 0x1143d, 0x1143e, 0x1143f, 0x11440, 0x11441, 0x11442,  | 
9203  | 34.4k  |       0x11443, 0x11444, 0x11445, 0x11446, 0x1145e, 0x114b0, 0x114b1, 0x114b2,  | 
9204  | 34.4k  |       0x114b3, 0x114b4, 0x114b5, 0x114b6, 0x114b7, 0x114b8, 0x114b9, 0x114ba,  | 
9205  | 34.4k  |       0x114bb, 0x114bc, 0x114bd, 0x114be, 0x114bf, 0x114c0, 0x114c1, 0x114c2,  | 
9206  | 34.4k  |       0x114c3, 0x115af, 0x115b0, 0x115b1, 0x115b2, 0x115b3, 0x115b4, 0x115b5,  | 
9207  | 34.4k  |       0x115b8, 0x115b9, 0x115ba, 0x115bb, 0x115bc, 0x115bd, 0x115be, 0x115bf,  | 
9208  | 34.4k  |       0x115c0, 0x115dc, 0x115dd, 0x11630, 0x11631, 0x11632, 0x11633, 0x11634,  | 
9209  | 34.4k  |       0x11635, 0x11636, 0x11637, 0x11638, 0x11639, 0x1163a, 0x1163b, 0x1163c,  | 
9210  | 34.4k  |       0x1163d, 0x1163e, 0x1163f, 0x11640, 0x116ab, 0x116ac, 0x116ad, 0x116ae,  | 
9211  | 34.4k  |       0x116af, 0x116b0, 0x116b1, 0x116b2, 0x116b3, 0x116b4, 0x116b5, 0x116b6,  | 
9212  | 34.4k  |       0x116b7, 0x1171d, 0x1171e, 0x1171f, 0x11720, 0x11721, 0x11722, 0x11723,  | 
9213  | 34.4k  |       0x11724, 0x11725, 0x11726, 0x11727, 0x11728, 0x11729, 0x1172a, 0x1172b,  | 
9214  | 34.4k  |       0x1182c, 0x1182d, 0x1182e, 0x1182f, 0x11830, 0x11831, 0x11832, 0x11833,  | 
9215  | 34.4k  |       0x11834, 0x11835, 0x11836, 0x11837, 0x11838, 0x11839, 0x1183a, 0x11930,  | 
9216  | 34.4k  |       0x11931, 0x11932, 0x11933, 0x11934, 0x11935, 0x11937, 0x11938, 0x1193b,  | 
9217  | 34.4k  |       0x1193c, 0x1193d, 0x1193e, 0x11940, 0x11942, 0x11943, 0x119d1, 0x119d2,  | 
9218  | 34.4k  |       0x119d3, 0x119d4, 0x119d5, 0x119d6, 0x119d7, 0x119da, 0x119db, 0x119dc,  | 
9219  | 34.4k  |       0x119dd, 0x119de, 0x119df, 0x119e0, 0x119e4, 0x11a01, 0x11a02, 0x11a03,  | 
9220  | 34.4k  |       0x11a04, 0x11a05, 0x11a06, 0x11a07, 0x11a08, 0x11a09, 0x11a0a, 0x11a33,  | 
9221  | 34.4k  |       0x11a34, 0x11a35, 0x11a36, 0x11a37, 0x11a38, 0x11a39, 0x11a3b, 0x11a3c,  | 
9222  | 34.4k  |       0x11a3d, 0x11a3e, 0x11a47, 0x11a51, 0x11a52, 0x11a53, 0x11a54, 0x11a55,  | 
9223  | 34.4k  |       0x11a56, 0x11a57, 0x11a58, 0x11a59, 0x11a5a, 0x11a5b, 0x11a8a, 0x11a8b,  | 
9224  | 34.4k  |       0x11a8c, 0x11a8d, 0x11a8e, 0x11a8f, 0x11a90, 0x11a91, 0x11a92, 0x11a93,  | 
9225  | 34.4k  |       0x11a94, 0x11a95, 0x11a96, 0x11a97, 0x11a98, 0x11a99, 0x11c2f, 0x11c30,  | 
9226  | 34.4k  |       0x11c31, 0x11c32, 0x11c33, 0x11c34, 0x11c35, 0x11c36, 0x11c38, 0x11c39,  | 
9227  | 34.4k  |       0x11c3a, 0x11c3b, 0x11c3c, 0x11c3d, 0x11c3e, 0x11c3f, 0x11c92, 0x11c93,  | 
9228  | 34.4k  |       0x11c94, 0x11c95, 0x11c96, 0x11c97, 0x11c98, 0x11c99, 0x11c9a, 0x11c9b,  | 
9229  | 34.4k  |       0x11c9c, 0x11c9d, 0x11c9e, 0x11c9f, 0x11ca0, 0x11ca1, 0x11ca2, 0x11ca3,  | 
9230  | 34.4k  |       0x11ca4, 0x11ca5, 0x11ca6, 0x11ca7, 0x11ca9, 0x11caa, 0x11cab, 0x11cac,  | 
9231  | 34.4k  |       0x11cad, 0x11cae, 0x11caf, 0x11cb0, 0x11cb1, 0x11cb2, 0x11cb3, 0x11cb4,  | 
9232  | 34.4k  |       0x11cb5, 0x11cb6, 0x11d31, 0x11d32, 0x11d33, 0x11d34, 0x11d35, 0x11d36,  | 
9233  | 34.4k  |       0x11d3a, 0x11d3c, 0x11d3d, 0x11d3f, 0x11d40, 0x11d41, 0x11d42, 0x11d43,  | 
9234  | 34.4k  |       0x11d44, 0x11d45, 0x11d47, 0x11d8a, 0x11d8b, 0x11d8c, 0x11d8d, 0x11d8e,  | 
9235  | 34.4k  |       0x11d90, 0x11d91, 0x11d93, 0x11d94, 0x11d95, 0x11d96, 0x11d97, 0x11ef3,  | 
9236  | 34.4k  |       0x11ef4, 0x11ef5, 0x11ef6, 0x16af0, 0x16af1, 0x16af2, 0x16af3, 0x16af4,  | 
9237  | 34.4k  |       0x16b30, 0x16b31, 0x16b32, 0x16b33, 0x16b34, 0x16b35, 0x16b36, 0x16f4f,  | 
9238  | 34.4k  |       0x16f51, 0x16f52, 0x16f53, 0x16f54, 0x16f55, 0x16f56, 0x16f57, 0x16f58,  | 
9239  | 34.4k  |       0x16f59, 0x16f5a, 0x16f5b, 0x16f5c, 0x16f5d, 0x16f5e, 0x16f5f, 0x16f60,  | 
9240  | 34.4k  |       0x16f61, 0x16f62, 0x16f63, 0x16f64, 0x16f65, 0x16f66, 0x16f67, 0x16f68,  | 
9241  | 34.4k  |       0x16f69, 0x16f6a, 0x16f6b, 0x16f6c, 0x16f6d, 0x16f6e, 0x16f6f, 0x16f70,  | 
9242  | 34.4k  |       0x16f71, 0x16f72, 0x16f73, 0x16f74, 0x16f75, 0x16f76, 0x16f77, 0x16f78,  | 
9243  | 34.4k  |       0x16f79, 0x16f7a, 0x16f7b, 0x16f7c, 0x16f7d, 0x16f7e, 0x16f7f, 0x16f80,  | 
9244  | 34.4k  |       0x16f81, 0x16f82, 0x16f83, 0x16f84, 0x16f85, 0x16f86, 0x16f87, 0x16f8f,  | 
9245  | 34.4k  |       0x16f90, 0x16f91, 0x16f92, 0x16fe4, 0x16ff0, 0x16ff1, 0x1bc9d, 0x1bc9e,  | 
9246  | 34.4k  |       0x1d165, 0x1d166, 0x1d167, 0x1d168, 0x1d169, 0x1d16d, 0x1d16e, 0x1d16f,  | 
9247  | 34.4k  |       0x1d170, 0x1d171, 0x1d172, 0x1d17b, 0x1d17c, 0x1d17d, 0x1d17e, 0x1d17f,  | 
9248  | 34.4k  |       0x1d180, 0x1d181, 0x1d182, 0x1d185, 0x1d186, 0x1d187, 0x1d188, 0x1d189,  | 
9249  | 34.4k  |       0x1d18a, 0x1d18b, 0x1d1aa, 0x1d1ab, 0x1d1ac, 0x1d1ad, 0x1d242, 0x1d243,  | 
9250  | 34.4k  |       0x1d244, 0x1da00, 0x1da01, 0x1da02, 0x1da03, 0x1da04, 0x1da05, 0x1da06,  | 
9251  | 34.4k  |       0x1da07, 0x1da08, 0x1da09, 0x1da0a, 0x1da0b, 0x1da0c, 0x1da0d, 0x1da0e,  | 
9252  | 34.4k  |       0x1da0f, 0x1da10, 0x1da11, 0x1da12, 0x1da13, 0x1da14, 0x1da15, 0x1da16,  | 
9253  | 34.4k  |       0x1da17, 0x1da18, 0x1da19, 0x1da1a, 0x1da1b, 0x1da1c, 0x1da1d, 0x1da1e,  | 
9254  | 34.4k  |       0x1da1f, 0x1da20, 0x1da21, 0x1da22, 0x1da23, 0x1da24, 0x1da25, 0x1da26,  | 
9255  | 34.4k  |       0x1da27, 0x1da28, 0x1da29, 0x1da2a, 0x1da2b, 0x1da2c, 0x1da2d, 0x1da2e,  | 
9256  | 34.4k  |       0x1da2f, 0x1da30, 0x1da31, 0x1da32, 0x1da33, 0x1da34, 0x1da35, 0x1da36,  | 
9257  | 34.4k  |       0x1da3b, 0x1da3c, 0x1da3d, 0x1da3e, 0x1da3f, 0x1da40, 0x1da41, 0x1da42,  | 
9258  | 34.4k  |       0x1da43, 0x1da44, 0x1da45, 0x1da46, 0x1da47, 0x1da48, 0x1da49, 0x1da4a,  | 
9259  | 34.4k  |       0x1da4b, 0x1da4c, 0x1da4d, 0x1da4e, 0x1da4f, 0x1da50, 0x1da51, 0x1da52,  | 
9260  | 34.4k  |       0x1da53, 0x1da54, 0x1da55, 0x1da56, 0x1da57, 0x1da58, 0x1da59, 0x1da5a,  | 
9261  | 34.4k  |       0x1da5b, 0x1da5c, 0x1da5d, 0x1da5e, 0x1da5f, 0x1da60, 0x1da61, 0x1da62,  | 
9262  | 34.4k  |       0x1da63, 0x1da64, 0x1da65, 0x1da66, 0x1da67, 0x1da68, 0x1da69, 0x1da6a,  | 
9263  | 34.4k  |       0x1da6b, 0x1da6c, 0x1da75, 0x1da84, 0x1da9b, 0x1da9c, 0x1da9d, 0x1da9e,  | 
9264  | 34.4k  |       0x1da9f, 0x1daa1, 0x1daa2, 0x1daa3, 0x1daa4, 0x1daa5, 0x1daa6, 0x1daa7,  | 
9265  | 34.4k  |       0x1daa8, 0x1daa9, 0x1daaa, 0x1daab, 0x1daac, 0x1daad, 0x1daae, 0x1daaf,  | 
9266  | 34.4k  |       0x1e000, 0x1e001, 0x1e002, 0x1e003, 0x1e004, 0x1e005, 0x1e006, 0x1e008,  | 
9267  | 34.4k  |       0x1e009, 0x1e00a, 0x1e00b, 0x1e00c, 0x1e00d, 0x1e00e, 0x1e00f, 0x1e010,  | 
9268  | 34.4k  |       0x1e011, 0x1e012, 0x1e013, 0x1e014, 0x1e015, 0x1e016, 0x1e017, 0x1e018,  | 
9269  | 34.4k  |       0x1e01b, 0x1e01c, 0x1e01d, 0x1e01e, 0x1e01f, 0x1e020, 0x1e021, 0x1e023,  | 
9270  | 34.4k  |       0x1e024, 0x1e026, 0x1e027, 0x1e028, 0x1e029, 0x1e02a, 0x1e130, 0x1e131,  | 
9271  | 34.4k  |       0x1e132, 0x1e133, 0x1e134, 0x1e135, 0x1e136, 0x1e2ec, 0x1e2ed, 0x1e2ee,  | 
9272  | 34.4k  |       0x1e2ef, 0x1e8d0, 0x1e8d1, 0x1e8d2, 0x1e8d3, 0x1e8d4, 0x1e8d5, 0x1e8d6,  | 
9273  | 34.4k  |       0x1e944, 0x1e945, 0x1e946, 0x1e947, 0x1e948, 0x1e949, 0x1e94a, 0xe0100,  | 
9274  | 34.4k  |       0xe0101, 0xe0102, 0xe0103, 0xe0104, 0xe0105, 0xe0106, 0xe0107, 0xe0108,  | 
9275  | 34.4k  |       0xe0109, 0xe010a, 0xe010b, 0xe010c, 0xe010d, 0xe010e, 0xe010f, 0xe0110,  | 
9276  | 34.4k  |       0xe0111, 0xe0112, 0xe0113, 0xe0114, 0xe0115, 0xe0116, 0xe0117, 0xe0118,  | 
9277  | 34.4k  |       0xe0119, 0xe011a, 0xe011b, 0xe011c, 0xe011d, 0xe011e, 0xe011f, 0xe0120,  | 
9278  | 34.4k  |       0xe0121, 0xe0122, 0xe0123, 0xe0124, 0xe0125, 0xe0126, 0xe0127, 0xe0128,  | 
9279  | 34.4k  |       0xe0129, 0xe012a, 0xe012b, 0xe012c, 0xe012d, 0xe012e, 0xe012f, 0xe0130,  | 
9280  | 34.4k  |       0xe0131, 0xe0132, 0xe0133, 0xe0134, 0xe0135, 0xe0136, 0xe0137, 0xe0138,  | 
9281  | 34.4k  |       0xe0139, 0xe013a, 0xe013b, 0xe013c, 0xe013d, 0xe013e, 0xe013f, 0xe0140,  | 
9282  | 34.4k  |       0xe0141, 0xe0142, 0xe0143, 0xe0144, 0xe0145, 0xe0146, 0xe0147, 0xe0148,  | 
9283  | 34.4k  |       0xe0149, 0xe014a, 0xe014b, 0xe014c, 0xe014d, 0xe014e, 0xe014f, 0xe0150,  | 
9284  | 34.4k  |       0xe0151, 0xe0152, 0xe0153, 0xe0154, 0xe0155, 0xe0156, 0xe0157, 0xe0158,  | 
9285  | 34.4k  |       0xe0159, 0xe015a, 0xe015b, 0xe015c, 0xe015d, 0xe015e, 0xe015f, 0xe0160,  | 
9286  | 34.4k  |       0xe0161, 0xe0162, 0xe0163, 0xe0164, 0xe0165, 0xe0166, 0xe0167, 0xe0168,  | 
9287  | 34.4k  |       0xe0169, 0xe016a, 0xe016b, 0xe016c, 0xe016d, 0xe016e, 0xe016f, 0xe0170,  | 
9288  | 34.4k  |       0xe0171, 0xe0172, 0xe0173, 0xe0174, 0xe0175, 0xe0176, 0xe0177, 0xe0178,  | 
9289  | 34.4k  |       0xe0179, 0xe017a, 0xe017b, 0xe017c, 0xe017d, 0xe017e, 0xe017f, 0xe0180,  | 
9290  | 34.4k  |       0xe0181, 0xe0182, 0xe0183, 0xe0184, 0xe0185, 0xe0186, 0xe0187, 0xe0188,  | 
9291  | 34.4k  |       0xe0189, 0xe018a, 0xe018b, 0xe018c, 0xe018d, 0xe018e, 0xe018f, 0xe0190,  | 
9292  | 34.4k  |       0xe0191, 0xe0192, 0xe0193, 0xe0194, 0xe0195, 0xe0196, 0xe0197, 0xe0198,  | 
9293  | 34.4k  |       0xe0199, 0xe019a, 0xe019b, 0xe019c, 0xe019d, 0xe019e, 0xe019f, 0xe01a0,  | 
9294  | 34.4k  |       0xe01a1, 0xe01a2, 0xe01a3, 0xe01a4, 0xe01a5, 0xe01a6, 0xe01a7, 0xe01a8,  | 
9295  | 34.4k  |       0xe01a9, 0xe01aa, 0xe01ab, 0xe01ac, 0xe01ad, 0xe01ae, 0xe01af, 0xe01b0,  | 
9296  | 34.4k  |       0xe01b1, 0xe01b2, 0xe01b3, 0xe01b4, 0xe01b5, 0xe01b6, 0xe01b7, 0xe01b8,  | 
9297  | 34.4k  |       0xe01b9, 0xe01ba, 0xe01bb, 0xe01bc, 0xe01bd, 0xe01be, 0xe01bf, 0xe01c0,  | 
9298  | 34.4k  |       0xe01c1, 0xe01c2, 0xe01c3, 0xe01c4, 0xe01c5, 0xe01c6, 0xe01c7, 0xe01c8,  | 
9299  | 34.4k  |       0xe01c9, 0xe01ca, 0xe01cb, 0xe01cc, 0xe01cd, 0xe01ce, 0xe01cf, 0xe01d0,  | 
9300  | 34.4k  |       0xe01d1, 0xe01d2, 0xe01d3, 0xe01d4, 0xe01d5, 0xe01d6, 0xe01d7, 0xe01d8,  | 
9301  | 34.4k  |       0xe01d9, 0xe01da, 0xe01db, 0xe01dc, 0xe01dd, 0xe01de, 0xe01df, 0xe01e0,  | 
9302  | 34.4k  |       0xe01e1, 0xe01e2, 0xe01e3, 0xe01e4, 0xe01e5, 0xe01e6, 0xe01e7, 0xe01e8,  | 
9303  | 34.4k  |       0xe01e9, 0xe01ea, 0xe01eb, 0xe01ec, 0xe01ed, 0xe01ee, 0xe01ef};  | 
9304  | 34.4k  |   if (std::binary_search(std::begin(combining), std::end(combining),  | 
9305  | 34.4k  |                          label.front())) { | 
9306  | 76  |     return false;  | 
9307  | 76  |   }  | 
9308  |  |   // We verify this next step as part of the mapping:  | 
9309  |  |   // ---------------------------------------------  | 
9310  |  |   // Each code point in the label must only have certain status values  | 
9311  |  |   // according to Section 5, IDNA Mapping Table:  | 
9312  |  |   // - For Transitional Processing, each value must be valid.  | 
9313  |  |   // - For Nontransitional Processing, each value must be either valid or  | 
9314  |  |   // deviation.  | 
9315  |  |  | 
9316  |  |   // If CheckJoiners, the label must satisfy the ContextJ rules from Appendix  | 
9317  |  |   // A, in The Unicode Code Points and Internationalized Domain Names for  | 
9318  |  |   // Applications (IDNA) [IDNA2008].  | 
9319  | 34.3k  |   constexpr static uint32_t virama[] = { | 
9320  | 34.3k  |       0x094D,  0x09CD,  0x0A4D,  0x0ACD,  0x0B4D,  0x0BCD,  0x0C4D,  0x0CCD,  | 
9321  | 34.3k  |       0x0D3B,  0x0D3C,  0x0D4D,  0x0DCA,  0x0E3A,  0x0EBA,  0x0F84,  0x1039,  | 
9322  | 34.3k  |       0x103A,  0x1714,  0x1734,  0x17D2,  0x1A60,  0x1B44,  0x1BAA,  0x1BAB,  | 
9323  | 34.3k  |       0x1BF2,  0x1BF3,  0x2D7F,  0xA806,  0xA82C,  0xA8C4,  0xA953,  0xA9C0,  | 
9324  | 34.3k  |       0xAAF6,  0xABED,  0x10A3F, 0x11046, 0x1107F, 0x110B9, 0x11133, 0x11134,  | 
9325  | 34.3k  |       0x111C0, 0x11235, 0x112EA, 0x1134D, 0x11442, 0x114C2, 0x115BF, 0x1163F,  | 
9326  | 34.3k  |       0x116B6, 0x1172B, 0x11839, 0x1193D, 0x1193E, 0x119E0, 0x11A34, 0x11A47,  | 
9327  | 34.3k  |       0x11A99, 0x11C3F, 0x11D44, 0x11D45, 0x11D97};  | 
9328  | 34.3k  |   constexpr static uint32_t R[] = { | 
9329  | 34.3k  |       0x622, 0x623, 0x624, 0x625, 0x627, 0x629, 0x62f, 0x630, 0x631,  | 
9330  | 34.3k  |       0x632, 0x648, 0x671, 0x672, 0x673, 0x675, 0x676, 0x677, 0x688,  | 
9331  | 34.3k  |       0x689, 0x68a, 0x68b, 0x68c, 0x68d, 0x68e, 0x68f, 0x690, 0x691,  | 
9332  | 34.3k  |       0x692, 0x693, 0x694, 0x695, 0x696, 0x697, 0x698, 0x699, 0x6c0,  | 
9333  | 34.3k  |       0x6c3, 0x6c4, 0x6c5, 0x6c6, 0x6c7, 0x6c8, 0x6c9, 0x6ca, 0x6cb,  | 
9334  | 34.3k  |       0x6cd, 0x6cf, 0x6d2, 0x6d3, 0x6d5, 0x6ee, 0x6ef, 0x710, 0x715,  | 
9335  | 34.3k  |       0x716, 0x717, 0x718, 0x719, 0x71e, 0x728, 0x72a, 0x72c, 0x72f,  | 
9336  | 34.3k  |       0x74d, 0x759, 0x75a, 0x75b, 0x854, 0x8aa, 0x8ab, 0x8ac};  | 
9337  | 34.3k  |   constexpr static uint32_t L[] = {0xa872}; | 
9338  | 34.3k  |   constexpr static uint32_t D[] = { | 
9339  | 34.3k  |       0x620,  0x626,  0x628,  0x62a,  0x62b,  0x62c,  0x62d,  0x62e,  0x633,  | 
9340  | 34.3k  |       0x634,  0x635,  0x636,  0x637,  0x638,  0x639,  0x63a,  0x63b,  0x63c,  | 
9341  | 34.3k  |       0x63d,  0x63e,  0x63f,  0x641,  0x642,  0x643,  0x644,  0x645,  0x646,  | 
9342  | 34.3k  |       0x647,  0x649,  0x64a,  0x66e,  0x66f,  0x678,  0x679,  0x67a,  0x67b,  | 
9343  | 34.3k  |       0x67c,  0x67d,  0x67e,  0x67f,  0x680,  0x681,  0x682,  0x683,  0x684,  | 
9344  | 34.3k  |       0x685,  0x686,  0x687,  0x69a,  0x69b,  0x69c,  0x69d,  0x69e,  0x69f,  | 
9345  | 34.3k  |       0x6a0,  0x6a1,  0x6a2,  0x6a3,  0x6a4,  0x6a5,  0x6a6,  0x6a7,  0x6a8,  | 
9346  | 34.3k  |       0x6a9,  0x6aa,  0x6ab,  0x6ac,  0x6ad,  0x6ae,  0x6af,  0x6b0,  0x6b1,  | 
9347  | 34.3k  |       0x6b2,  0x6b3,  0x6b4,  0x6b5,  0x6b6,  0x6b7,  0x6b8,  0x6b9,  0x6ba,  | 
9348  | 34.3k  |       0x6bb,  0x6bc,  0x6bd,  0x6be,  0x6bf,  0x6c1,  0x6c2,  0x6cc,  0x6ce,  | 
9349  | 34.3k  |       0x6d0,  0x6d1,  0x6fa,  0x6fb,  0x6fc,  0x6ff,  0x712,  0x713,  0x714,  | 
9350  | 34.3k  |       0x71a,  0x71b,  0x71c,  0x71d,  0x71f,  0x720,  0x721,  0x722,  0x723,  | 
9351  | 34.3k  |       0x724,  0x725,  0x726,  0x727,  0x729,  0x72b,  0x72d,  0x72e,  0x74e,  | 
9352  | 34.3k  |       0x74f,  0x750,  0x751,  0x752,  0x753,  0x754,  0x755,  0x756,  0x757,  | 
9353  | 34.3k  |       0x758,  0x75c,  0x75d,  0x75e,  0x75f,  0x760,  0x761,  0x762,  0x763,  | 
9354  | 34.3k  |       0x764,  0x765,  0x766,  0x850,  0x851,  0x852,  0x853,  0x855,  0x8a0,  | 
9355  | 34.3k  |       0x8a2,  0x8a3,  0x8a4,  0x8a5,  0x8a6,  0x8a7,  0x8a8,  0x8a9,  0x1807,  | 
9356  | 34.3k  |       0x1820, 0x1821, 0x1822, 0x1823, 0x1824, 0x1825, 0x1826, 0x1827, 0x1828,  | 
9357  | 34.3k  |       0x1829, 0x182a, 0x182b, 0x182c, 0x182d, 0x182e, 0x182f, 0x1830, 0x1831,  | 
9358  | 34.3k  |       0x1832, 0x1833, 0x1834, 0x1835, 0x1836, 0x1837, 0x1838, 0x1839, 0x183a,  | 
9359  | 34.3k  |       0x183b, 0x183c, 0x183d, 0x183e, 0x183f, 0x1840, 0x1841, 0x1842, 0x1843,  | 
9360  | 34.3k  |       0x1844, 0x1845, 0x1846, 0x1847, 0x1848, 0x1849, 0x184a, 0x184b, 0x184c,  | 
9361  | 34.3k  |       0x184d, 0x184e, 0x184f, 0x1850, 0x1851, 0x1852, 0x1853, 0x1854, 0x1855,  | 
9362  | 34.3k  |       0x1856, 0x1857, 0x1858, 0x1859, 0x185a, 0x185b, 0x185c, 0x185d, 0x185e,  | 
9363  | 34.3k  |       0x185f, 0x1860, 0x1861, 0x1862, 0x1863, 0x1864, 0x1865, 0x1866, 0x1867,  | 
9364  | 34.3k  |       0x1868, 0x1869, 0x186a, 0x186b, 0x186c, 0x186d, 0x186e, 0x186f, 0x1870,  | 
9365  | 34.3k  |       0x1871, 0x1872, 0x1873, 0x1874, 0x1875, 0x1876, 0x1877, 0x1887, 0x1888,  | 
9366  | 34.3k  |       0x1889, 0x188a, 0x188b, 0x188c, 0x188d, 0x188e, 0x188f, 0x1890, 0x1891,  | 
9367  | 34.3k  |       0x1892, 0x1893, 0x1894, 0x1895, 0x1896, 0x1897, 0x1898, 0x1899, 0x189a,  | 
9368  | 34.3k  |       0x189b, 0x189c, 0x189d, 0x189e, 0x189f, 0x18a0, 0x18a1, 0x18a2, 0x18a3,  | 
9369  | 34.3k  |       0x18a4, 0x18a5, 0x18a6, 0x18a7, 0x18a8, 0x18aa, 0xa840, 0xa841, 0xa842,  | 
9370  | 34.3k  |       0xa843, 0xa844, 0xa845, 0xa846, 0xa847, 0xa848, 0xa849, 0xa84a, 0xa84b,  | 
9371  | 34.3k  |       0xa84c, 0xa84d, 0xa84e, 0xa84f, 0xa850, 0xa851, 0xa852, 0xa853, 0xa854,  | 
9372  | 34.3k  |       0xa855, 0xa856, 0xa857, 0xa858, 0xa859, 0xa85a, 0xa85b, 0xa85c, 0xa85d,  | 
9373  | 34.3k  |       0xa85e, 0xa85f, 0xa860, 0xa861, 0xa862, 0xa863, 0xa864, 0xa865, 0xa866,  | 
9374  | 34.3k  |       0xa867, 0xa868, 0xa869, 0xa86a, 0xa86b, 0xa86c, 0xa86d, 0xa86e, 0xa86f,  | 
9375  | 34.3k  |       0xa870, 0xa871};  | 
9376  |  |  | 
9377  | 247k  |   for (size_t i = 0; i < label.size(); i++) { | 
9378  | 215k  |     uint32_t c = label[i];  | 
9379  | 215k  |     if (c == 0x200c) { | 
9380  | 1.43k  |       if (i > 0) { | 
9381  | 1.41k  |         if (std::binary_search(std::begin(virama), std::end(virama),  | 
9382  | 1.41k  |                                label[i - 1])) { | 
9383  | 247  |           return true;  | 
9384  | 247  |         }  | 
9385  | 1.41k  |       }  | 
9386  | 1.18k  |       if ((i == 0) || (i + 1 >= label.size())) { | 
9387  | 131  |         return false;  | 
9388  | 131  |       }  | 
9389  |  |       // we go backward looking for L or D  | 
9390  | 2.35k  |       auto is_l_or_d = [](uint32_t code) { | 
9391  | 2.35k  |         return std::binary_search(std::begin(L), std::end(L), code) ||  | 
9392  | 2.35k  |                std::binary_search(std::begin(D), std::end(D), code);  | 
9393  | 2.35k  |       };  | 
9394  | 1.84k  |       auto is_r_or_d = [](uint32_t code) { | 
9395  | 1.84k  |         return std::binary_search(std::begin(R), std::end(R), code) ||  | 
9396  | 1.84k  |                std::binary_search(std::begin(D), std::end(D), code);  | 
9397  | 1.84k  |       };  | 
9398  | 1.05k  |       std::u32string_view before = label.substr(0, i);  | 
9399  | 1.05k  |       std::u32string_view after = label.substr(i + 1);  | 
9400  | 1.05k  |       return (std::find_if(before.begin(), before.end(), is_l_or_d) !=  | 
9401  | 1.05k  |               before.end()) &&  | 
9402  | 1.05k  |              (std::find_if(after.begin(), after.end(), is_r_or_d) !=  | 
9403  | 926  |               after.end());  | 
9404  | 213k  |     } else if (c == 0x200d) { | 
9405  | 689  |       if (i > 0) { | 
9406  | 675  |         if (std::binary_search(std::begin(virama), std::end(virama),  | 
9407  | 675  |                                label[i - 1])) { | 
9408  | 583  |           return true;  | 
9409  | 583  |         }  | 
9410  | 675  |       }  | 
9411  | 106  |       return false;  | 
9412  | 689  |     }  | 
9413  | 215k  |   }  | 
9414  |  |  | 
9415  |  |   // If CheckBidi, and if the domain name is a  Bidi domain name, then the label  | 
9416  |  |   // must satisfy all six of the numbered conditions in [IDNA2008] RFC 5893,  | 
9417  |  |   // Section 2.  | 
9418  |  |  | 
9419  |  |   // The following rule, consisting of six conditions, applies to labels  | 
9420  |  |   // in Bidi domain names.  The requirements that this rule satisfies are  | 
9421  |  |   // described in Section 3.  All of the conditions must be satisfied for  | 
9422  |  |   // the rule to be satisfied.  | 
9423  |  |   //  | 
9424  |  |   //  1.  The first character must be a character with Bidi property L, R,  | 
9425  |  |   //     or AL.  If it has the R or AL property, it is an RTL label; if it  | 
9426  |  |   //     has the L property, it is an LTR label.  | 
9427  |  |   //  | 
9428  |  |   //  2.  In an RTL label, only characters with the Bidi properties R, AL,  | 
9429  |  |   //      AN, EN, ES, CS, ET, ON, BN, or NSM are allowed.  | 
9430  |  |   //  | 
9431  |  |   //   3.  In an RTL label, the end of the label must be a character with  | 
9432  |  |   //       Bidi property R, AL, EN, or AN, followed by zero or more  | 
9433  |  |   //       characters with Bidi property NSM.  | 
9434  |  |   //  | 
9435  |  |   //   4.  In an RTL label, if an EN is present, no AN may be present, and  | 
9436  |  |   //       vice versa.  | 
9437  |  |   //  | 
9438  |  |   //  5.  In an LTR label, only characters with the Bidi properties L, EN,  | 
9439  |  |   //       ES, CS, ET, ON, BN, or NSM are allowed.  | 
9440  |  |   //  | 
9441  |  |   //   6.  In an LTR label, the end of the label must be a character with  | 
9442  |  |   //       Bidi property L or EN, followed by zero or more characters with  | 
9443  |  |   //       Bidi property NSM.  | 
9444  |  |  | 
9445  | 32.2k  |   size_t last_non_nsm_char = find_last_not_of_nsm(label);  | 
9446  | 32.2k  |   if (last_non_nsm_char == std::u32string_view::npos) { | 
9447  | 0  |     return false;  | 
9448  | 0  |   }  | 
9449  |  |  | 
9450  |  |   // A "Bidi domain name" is a domain name that contains at least one RTL label.  | 
9451  |  |   // The following rule, consisting of six conditions, applies to labels in Bidi  | 
9452  |  |   // domain names.  | 
9453  | 32.2k  |   if (is_rtl_label(label)) { | 
9454  |  |     // The first character must be a character with Bidi property L, R,  | 
9455  |  |     // or AL. If it has the R or AL property, it is an RTL label; if it  | 
9456  |  |     // has the L property, it is an LTR label.  | 
9457  |  |  | 
9458  | 2.75k  |     if (find_direction(label[0]) == direction::L) { | 
9459  |  |       // Eval as LTR  | 
9460  |  |  | 
9461  |  |       // In an LTR label, only characters with the Bidi properties L, EN,  | 
9462  |  |       // ES, CS, ET, ON, BN, or NSM are allowed.  | 
9463  | 3.79k  |       for (size_t i = 0; i < last_non_nsm_char; i++) { | 
9464  | 3.32k  |         const direction d = find_direction(label[i]);  | 
9465  | 3.32k  |         if (!(d == direction::L || d == direction::EN || d == direction::ES ||  | 
9466  | 3.32k  |               d == direction::CS || d == direction::ET || d == direction::ON ||  | 
9467  | 3.32k  |               d == direction::BN || d == direction::NSM)) { | 
9468  | 137  |           return false;  | 
9469  | 137  |         }  | 
9470  |  |  | 
9471  | 3.19k  |         if ((i == last_non_nsm_char) &&  | 
9472  | 3.19k  |             !(d == direction::L || d == direction::EN)) { | 
9473  | 0  |           return false;  | 
9474  | 0  |         }  | 
9475  | 3.19k  |       }  | 
9476  |  |  | 
9477  | 461  |       return true;  | 
9478  |  |  | 
9479  | 2.15k  |     } else { | 
9480  |  |       // Eval as RTL  | 
9481  |  |  | 
9482  | 2.15k  |       bool has_an = false;  | 
9483  | 2.15k  |       bool has_en = false;  | 
9484  | 7.48k  |       for (size_t i = 0; i <= last_non_nsm_char; i++) { | 
9485  | 5.57k  |         const direction d = find_direction(label[i]);  | 
9486  |  |  | 
9487  |  |         // In an RTL label, if an EN is present, no AN may be present, and vice  | 
9488  |  |         // versa.  | 
9489  | 5.57k  |         if ((d == direction::EN && ((has_en = true) && has_an)) ||  | 
9490  | 5.57k  |             (d == direction::AN && ((has_an = true) && has_en))) { | 
9491  | 20  |           return false;  | 
9492  | 20  |         }  | 
9493  |  |  | 
9494  | 5.55k  |         if (!(d == direction::R || d == direction::AL || d == direction::AN ||  | 
9495  | 5.55k  |               d == direction::EN || d == direction::ES || d == direction::CS ||  | 
9496  | 5.55k  |               d == direction::ET || d == direction::ON || d == direction::BN ||  | 
9497  | 5.55k  |               d == direction::NSM)) { | 
9498  | 164  |           return false;  | 
9499  | 164  |         }  | 
9500  |  |  | 
9501  | 5.39k  |         if (i == last_non_nsm_char &&  | 
9502  | 5.39k  |             !(d == direction::R || d == direction::AL || d == direction::AN ||  | 
9503  | 1.97k  |               d == direction::EN)) { | 
9504  | 65  |           return false;  | 
9505  | 65  |         }  | 
9506  | 5.39k  |       }  | 
9507  |  |  | 
9508  | 1.90k  |       return true;  | 
9509  | 2.15k  |     }  | 
9510  | 2.75k  |   }  | 
9511  |  |  | 
9512  | 29.5k  |   return true;  | 
9513  | 32.2k  | }  | 
9514  |  |  | 
9515  |  | }  // namespace ada::idna  | 
9516  |  | /* end file src/validity.cpp */  | 
9517  |  | /* begin file src/to_ascii.cpp */  | 
9518  |  |  | 
9519  |  | #include <algorithm>  | 
9520  |  | #include <cstdint>  | 
9521  |  |  | 
9522  |  |  | 
9523  |  | namespace ada::idna { | 
9524  |  |  | 
9525  |  | bool constexpr begins_with(std::u32string_view view,  | 
9526  | 30.6k  |                            std::u32string_view prefix) { | 
9527  | 30.6k  |   if (view.size() < prefix.size()) { | 
9528  | 8.34k  |     return false;  | 
9529  | 8.34k  |   }  | 
9530  | 22.2k  |   return view.substr(0, prefix.size()) == prefix;  | 
9531  | 30.6k  | }  | 
9532  |  |  | 
9533  | 56.6k  | bool constexpr begins_with(std::string_view view, std::string_view prefix) { | 
9534  | 56.6k  |   if (view.size() < prefix.size()) { | 
9535  | 26.8k  |     return false;  | 
9536  | 26.8k  |   }  | 
9537  | 29.8k  |   return view.substr(0, prefix.size()) == prefix;  | 
9538  | 56.6k  | }  | 
9539  |  |  | 
9540  | 28.5k  | bool constexpr is_ascii(std::u32string_view view) { | 
9541  | 60.0k  |   for (uint32_t c : view) { | 
9542  | 60.0k  |     if (c >= 0x80) { | 
9543  | 25.4k  |       return false;  | 
9544  | 25.4k  |     }  | 
9545  | 60.0k  |   }  | 
9546  | 3.15k  |   return true;  | 
9547  | 28.5k  | }  | 
9548  |  |  | 
9549  | 27.3k  | bool constexpr is_ascii(std::string_view view) { | 
9550  | 342k  |   for (uint8_t c : view) { | 
9551  | 342k  |     if (c >= 0x80) { | 
9552  | 9.93k  |       return false;  | 
9553  | 9.93k  |     }  | 
9554  | 342k  |   }  | 
9555  | 17.3k  |   return true;  | 
9556  | 27.3k  | }  | 
9557  |  |  | 
9558  |  | constexpr static uint8_t is_forbidden_domain_code_point_table[] = { | 
9559  |  |     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  | 
9560  |  |     1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,  | 
9561  |  |     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,  | 
9562  |  |     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,  | 
9563  |  |     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
9564  |  |     0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  | 
9565  |  |     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  | 
9566  |  |     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  | 
9567  |  |     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  | 
9568  |  |     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  | 
9569  |  |     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};  | 
9570  |  |  | 
9571  |  | static_assert(sizeof(is_forbidden_domain_code_point_table) == 256);  | 
9572  |  |  | 
9573  | 0  | inline bool is_forbidden_domain_code_point(const char c) noexcept { | 
9574  | 0  |   return is_forbidden_domain_code_point_table[uint8_t(c)];  | 
9575  | 0  | }  | 
9576  |  |  | 
9577  | 0  | bool contains_forbidden_domain_code_point(std::string_view view) { | 
9578  | 0  |   return (  | 
9579  | 0  |       std::any_of(view.begin(), view.end(), is_forbidden_domain_code_point));  | 
9580  | 0  | }  | 
9581  |  |  | 
9582  |  | // We return "" on error.  | 
9583  | 15.0k  | static std::string from_ascii_to_ascii(std::string_view ut8_string) { | 
9584  | 15.0k  |   static const std::string error = "";  | 
9585  |  |   // copy and map  | 
9586  |  |   // we could be more efficient by avoiding the copy when unnecessary.  | 
9587  | 15.0k  |   std::string mapped_string = std::string(ut8_string);  | 
9588  | 15.0k  |   ascii_map(mapped_string.data(), mapped_string.size());  | 
9589  | 15.0k  |   std::string out;  | 
9590  | 15.0k  |   size_t label_start = 0;  | 
9591  |  |  | 
9592  | 44.9k  |   while (label_start != mapped_string.size()) { | 
9593  | 30.7k  |     size_t loc_dot = mapped_string.find('.', label_start); | 
9594  | 30.7k  |     bool is_last_label = (loc_dot == std::string_view::npos);  | 
9595  | 30.7k  |     size_t label_size = is_last_label ? mapped_string.size() - label_start  | 
9596  | 30.7k  |                                       : loc_dot - label_start;  | 
9597  | 30.7k  |     size_t label_size_with_dot = is_last_label ? label_size : label_size + 1;  | 
9598  | 30.7k  |     std::string_view label_view(mapped_string.data() + label_start, label_size);  | 
9599  | 30.7k  |     label_start += label_size_with_dot;  | 
9600  | 30.7k  |     if (label_size == 0) { | 
9601  |  |       // empty label? Nothing to do.  | 
9602  | 26.1k  |     } else if (begins_with(label_view, "xn--")) { | 
9603  |  |       // The xn-- part is the expensive game.  | 
9604  | 8.03k  |       out.append(label_view);  | 
9605  | 8.03k  |       std::string_view puny_segment_ascii(  | 
9606  | 8.03k  |           out.data() + out.size() - label_view.size() + 4,  | 
9607  | 8.03k  |           label_view.size() - 4);  | 
9608  | 8.03k  |       std::u32string tmp_buffer;  | 
9609  | 8.03k  |       bool is_ok = ada::idna::punycode_to_utf32(puny_segment_ascii, tmp_buffer);  | 
9610  | 8.03k  |       if (!is_ok) { | 
9611  | 208  |         return error;  | 
9612  | 208  |       }  | 
9613  | 7.82k  |       std::u32string post_map = ada::idna::map(tmp_buffer);  | 
9614  | 7.82k  |       if (tmp_buffer != post_map) { | 
9615  | 378  |         return error;  | 
9616  | 378  |       }  | 
9617  | 7.44k  |       std::u32string pre_normal = post_map;  | 
9618  | 7.44k  |       normalize(post_map);  | 
9619  | 7.44k  |       if (post_map != pre_normal) { | 
9620  | 57  |         return error;  | 
9621  | 57  |       }  | 
9622  | 7.39k  |       if (post_map.empty()) { | 
9623  | 134  |         return error;  | 
9624  | 134  |       }  | 
9625  | 7.25k  |       if (!is_label_valid(post_map)) { | 
9626  | 27  |         return error;  | 
9627  | 27  |       }  | 
9628  | 18.1k  |     } else { | 
9629  | 18.1k  |       out.append(label_view);  | 
9630  | 18.1k  |     }  | 
9631  | 29.9k  |     if (!is_last_label) { | 
9632  | 17.6k  |       out.push_back('.'); | 
9633  | 17.6k  |     }  | 
9634  | 29.9k  |   }  | 
9635  | 14.2k  |   return out;  | 
9636  | 15.0k  | }  | 
9637  |  |  | 
9638  |  | // We return "" on error.  | 
9639  | 24.8k  | std::string to_ascii(std::string_view ut8_string) { | 
9640  | 24.8k  |   if (is_ascii(ut8_string)) { | 
9641  | 15.0k  |     return from_ascii_to_ascii(ut8_string);  | 
9642  | 15.0k  |   }  | 
9643  | 9.77k  |   static const std::string error = "";  | 
9644  |  |   // We convert to UTF-32  | 
9645  | 9.77k  |   size_t utf32_length =  | 
9646  | 9.77k  |       ada::idna::utf32_length_from_utf8(ut8_string.data(), ut8_string.size());  | 
9647  | 9.77k  |   std::u32string utf32(utf32_length, '\0');  | 
9648  | 9.77k  |   size_t actual_utf32_length = ada::idna::utf8_to_utf32(  | 
9649  | 9.77k  |       ut8_string.data(), ut8_string.size(), utf32.data());  | 
9650  | 9.77k  |   if (actual_utf32_length == 0) { | 
9651  | 3.02k  |     return error;  | 
9652  | 3.02k  |   }  | 
9653  |  |   // mapping  | 
9654  | 6.75k  |   utf32 = ada::idna::map(utf32);  | 
9655  | 6.75k  |   normalize(utf32);  | 
9656  | 6.75k  |   std::string out;  | 
9657  | 6.75k  |   size_t label_start = 0;  | 
9658  |  |  | 
9659  | 39.7k  |   while (label_start != utf32.size()) { | 
9660  | 34.2k  |     size_t loc_dot = utf32.find('.', label_start); | 
9661  | 34.2k  |     bool is_last_label = (loc_dot == std::string_view::npos);  | 
9662  | 34.2k  |     size_t label_size =  | 
9663  | 34.2k  |         is_last_label ? utf32.size() - label_start : loc_dot - label_start;  | 
9664  | 34.2k  |     size_t label_size_with_dot = is_last_label ? label_size : label_size + 1;  | 
9665  | 34.2k  |     std::u32string_view label_view(utf32.data() + label_start, label_size);  | 
9666  | 34.2k  |     label_start += label_size_with_dot;  | 
9667  | 34.2k  |     if (label_size == 0) { | 
9668  |  |       // empty label? Nothing to do.  | 
9669  | 30.6k  |     } else if (begins_with(label_view, U"xn--")) { | 
9670  |  |       // we do not need to check, e.g., Xn-- because mapping goes to lower case  | 
9671  | 21.4k  |       for (char32_t c : label_view) { | 
9672  | 21.4k  |         if (c >= 0x80) { | 
9673  | 28  |           return error;  | 
9674  | 28  |         }  | 
9675  | 21.4k  |         out += (unsigned char)(c);  | 
9676  | 21.4k  |       }  | 
9677  | 2.01k  |       std::string_view puny_segment_ascii(  | 
9678  | 2.01k  |           out.data() + out.size() - label_view.size() + 4,  | 
9679  | 2.01k  |           label_view.size() - 4);  | 
9680  | 2.01k  |       std::u32string tmp_buffer;  | 
9681  | 2.01k  |       bool is_ok = ada::idna::punycode_to_utf32(puny_segment_ascii, tmp_buffer);  | 
9682  | 2.01k  |       if (!is_ok) { | 
9683  | 69  |         return error;  | 
9684  | 69  |       }  | 
9685  | 1.94k  |       std::u32string post_map = ada::idna::map(tmp_buffer);  | 
9686  | 1.94k  |       if (tmp_buffer != post_map) { | 
9687  | 70  |         return error;  | 
9688  | 70  |       }  | 
9689  | 1.87k  |       std::u32string pre_normal = post_map;  | 
9690  | 1.87k  |       normalize(post_map);  | 
9691  | 1.87k  |       if (post_map != pre_normal) { | 
9692  | 36  |         return error;  | 
9693  | 36  |       }  | 
9694  | 1.83k  |       if (post_map.empty()) { | 
9695  | 59  |         return error;  | 
9696  | 59  |       }  | 
9697  | 1.77k  |       if (!is_label_valid(post_map)) { | 
9698  | 12  |         return error;  | 
9699  | 12  |       }  | 
9700  | 28.5k  |     } else { | 
9701  |  |       // The fast path here is an ascii label.  | 
9702  | 28.5k  |       if (is_ascii(label_view)) { | 
9703  |  |         // no validation needed.  | 
9704  | 21.6k  |         for (char32_t c : label_view) { | 
9705  | 21.6k  |           out += (unsigned char)(c);  | 
9706  | 21.6k  |         }  | 
9707  | 25.4k  |       } else { | 
9708  |  |         // slow path.  | 
9709  |  |         // first check validity.  | 
9710  | 25.4k  |         if (!is_label_valid(label_view)) { | 
9711  | 961  |           return error;  | 
9712  | 961  |         }  | 
9713  |  |         // It is valid! So now we must encode it as punycode...  | 
9714  | 24.4k  |         out.append("xn--"); | 
9715  | 24.4k  |         bool is_ok = ada::idna::utf32_to_punycode(label_view, out);  | 
9716  | 24.4k  |         if (!is_ok) { | 
9717  | 0  |           return error;  | 
9718  | 0  |         }  | 
9719  | 24.4k  |       }  | 
9720  | 28.5k  |     }  | 
9721  | 33.0k  |     if (!is_last_label) { | 
9722  | 27.9k  |       out.push_back('.'); | 
9723  | 27.9k  |     }  | 
9724  | 33.0k  |   }  | 
9725  | 5.52k  |   return out;  | 
9726  | 6.75k  | }  | 
9727  |  | }  // namespace ada::idna  | 
9728  |  | /* end file src/to_ascii.cpp */  | 
9729  |  | /* begin file src/to_unicode.cpp */  | 
9730  |  |  | 
9731  |  | #include <algorithm>  | 
9732  |  | #include <string>  | 
9733  |  |  | 
9734  |  |  | 
9735  |  | namespace ada::idna { | 
9736  | 14.1k  | std::string to_unicode(std::string_view input) { | 
9737  | 14.1k  |   std::string output;  | 
9738  | 14.1k  |   output.reserve(input.size());  | 
9739  |  |  | 
9740  | 14.1k  |   size_t label_start = 0;  | 
9741  | 44.5k  |   while (label_start < input.size()) { | 
9742  | 30.4k  |     size_t loc_dot = input.find('.', label_start); | 
9743  | 30.4k  |     bool is_last_label = (loc_dot == std::string_view::npos);  | 
9744  | 30.4k  |     size_t label_size =  | 
9745  | 30.4k  |         is_last_label ? input.size() - label_start : loc_dot - label_start;  | 
9746  | 30.4k  |     auto label_view = std::string_view(input.data() + label_start, label_size);  | 
9747  |  |  | 
9748  | 30.4k  |     if (ada::idna::begins_with(label_view, "xn--") &&  | 
9749  | 30.4k  |         ada::idna::is_ascii(label_view)) { | 
9750  | 2.32k  |       label_view.remove_prefix(4);  | 
9751  | 2.32k  |       if (ada::idna::verify_punycode(label_view)) { | 
9752  | 1.43k  |         std::u32string tmp_buffer;  | 
9753  | 1.43k  |         if (ada::idna::punycode_to_utf32(label_view, tmp_buffer)) { | 
9754  | 1.43k  |           auto utf8_size = ada::idna::utf8_length_from_utf32(tmp_buffer.data(),  | 
9755  | 1.43k  |                                                              tmp_buffer.size());  | 
9756  | 1.43k  |           std::string final_utf8(utf8_size, '\0');  | 
9757  | 1.43k  |           ada::idna::utf32_to_utf8(tmp_buffer.data(), tmp_buffer.size(),  | 
9758  | 1.43k  |                                    final_utf8.data());  | 
9759  | 1.43k  |           output.append(final_utf8);  | 
9760  | 1.43k  |         } else { | 
9761  |  |           // ToUnicode never fails.  If any step fails, then the original input  | 
9762  |  |           // sequence is returned immediately in that step.  | 
9763  | 0  |           output.append(  | 
9764  | 0  |               std::string_view(input.data() + label_start, label_size));  | 
9765  | 0  |         }  | 
9766  | 1.43k  |       } else { | 
9767  | 892  |         output.append(std::string_view(input.data() + label_start, label_size));  | 
9768  | 892  |       }  | 
9769  | 28.1k  |     } else { | 
9770  | 28.1k  |       output.append(label_view);  | 
9771  | 28.1k  |     }  | 
9772  |  |  | 
9773  | 30.4k  |     if (!is_last_label) { | 
9774  | 18.2k  |       output.push_back('.'); | 
9775  | 18.2k  |     }  | 
9776  |  |  | 
9777  | 30.4k  |     label_start += label_size + 1;  | 
9778  | 30.4k  |   }  | 
9779  |  |  | 
9780  | 14.1k  |   return output;  | 
9781  | 14.1k  | }  | 
9782  |  | }  // namespace ada::idna  | 
9783  |  | /* end file src/to_unicode.cpp */  | 
9784  |  | /* end file src/idna.cpp */  | 
9785  |  | /* end file src/ada_idna.cpp */  | 
9786  |  | ADA_POP_DISABLE_WARNINGS  | 
9787  |  |  | 
9788  |  | #include <algorithm>  | 
9789  |  | #if ADA_NEON  | 
9790  |  | #include <arm_neon.h>  | 
9791  |  | #elif ADA_SSE2  | 
9792  |  | #include <emmintrin.h>  | 
9793  |  | #endif  | 
9794  |  |  | 
9795  |  | namespace ada::unicode { | 
9796  |  |  | 
9797  | 28.3k  | constexpr bool to_lower_ascii(char* input, size_t length) noexcept { | 
9798  | 84.9k  |   auto broadcast = [](uint8_t v) -> uint64_t { | 
9799  | 84.9k  |     return 0x101010101010101ull * v;  | 
9800  | 84.9k  |   };  | 
9801  | 28.3k  |   uint64_t broadcast_80 = broadcast(0x80);  | 
9802  | 28.3k  |   uint64_t broadcast_Ap = broadcast(128 - 'A');  | 
9803  | 28.3k  |   uint64_t broadcast_Zp = broadcast(128 - 'Z' - 1);  | 
9804  | 28.3k  |   uint64_t non_ascii = 0;  | 
9805  | 28.3k  |   size_t i = 0;  | 
9806  |  |  | 
9807  | 45.9k  |   for (; i + 7 < length; i += 8) { | 
9808  | 17.6k  |     uint64_t word{}; | 
9809  | 17.6k  |     memcpy(&word, input + i, sizeof(word));  | 
9810  | 17.6k  |     non_ascii |= (word & broadcast_80);  | 
9811  | 17.6k  |     word ^=  | 
9812  | 17.6k  |         (((word + broadcast_Ap) ^ (word + broadcast_Zp)) & broadcast_80) >> 2;  | 
9813  | 17.6k  |     memcpy(input + i, &word, sizeof(word));  | 
9814  | 17.6k  |   }  | 
9815  | 28.3k  |   if (i < length) { | 
9816  | 27.7k  |     uint64_t word{}; | 
9817  | 27.7k  |     memcpy(&word, input + i, length - i);  | 
9818  | 27.7k  |     non_ascii |= (word & broadcast_80);  | 
9819  | 27.7k  |     word ^=  | 
9820  | 27.7k  |         (((word + broadcast_Ap) ^ (word + broadcast_Zp)) & broadcast_80) >> 2;  | 
9821  | 27.7k  |     memcpy(input + i, &word, length - i);  | 
9822  | 27.7k  |   }  | 
9823  | 28.3k  |   return non_ascii == 0;  | 
9824  | 28.3k  | }  | 
9825  |  | #if ADA_NEON  | 
9826  |  | ada_really_inline bool has_tabs_or_newline(  | 
9827  |  |     std::string_view user_input) noexcept { | 
9828  |  |   size_t i = 0;  | 
9829  |  |   const uint8x16_t mask1 = vmovq_n_u8('\r'); | 
9830  |  |   const uint8x16_t mask2 = vmovq_n_u8('\n'); | 
9831  |  |   const uint8x16_t mask3 = vmovq_n_u8('\t'); | 
9832  |  |   uint8x16_t running{0}; | 
9833  |  |   for (; i + 15 < user_input.size(); i += 16) { | 
9834  |  |     uint8x16_t word = vld1q_u8((const uint8_t*)user_input.data() + i);  | 
9835  |  |     running = vorrq_u8(vorrq_u8(running, vorrq_u8(vceqq_u8(word, mask1),  | 
9836  |  |                                                   vceqq_u8(word, mask2))),  | 
9837  |  |                        vceqq_u8(word, mask3));  | 
9838  |  |   }  | 
9839  |  |   if (i < user_input.size()) { | 
9840  |  |     uint8_t buffer[16]{}; | 
9841  |  |     memcpy(buffer, user_input.data() + i, user_input.size() - i);  | 
9842  |  |     uint8x16_t word = vld1q_u8((const uint8_t*)user_input.data() + i);  | 
9843  |  |     running = vorrq_u8(vorrq_u8(running, vorrq_u8(vceqq_u8(word, mask1),  | 
9844  |  |                                                   vceqq_u8(word, mask2))),  | 
9845  |  |                        vceqq_u8(word, mask3));  | 
9846  |  |   }  | 
9847  |  |   return vmaxvq_u8(running) != 0;  | 
9848  |  | }  | 
9849  |  | #elif ADA_SSE2  | 
9850  |  | ada_really_inline bool has_tabs_or_newline(  | 
9851  | 88.4k  |     std::string_view user_input) noexcept { | 
9852  | 88.4k  |   size_t i = 0;  | 
9853  | 88.4k  |   const __m128i mask1 = _mm_set1_epi8('\r'); | 
9854  | 88.4k  |   const __m128i mask2 = _mm_set1_epi8('\n'); | 
9855  | 88.4k  |   const __m128i mask3 = _mm_set1_epi8('\t'); | 
9856  | 88.4k  |   __m128i running{0}; | 
9857  | 147k  |   for (; i + 15 < user_input.size(); i += 16) { | 
9858  | 59.1k  |     __m128i word = _mm_loadu_si128((const __m128i*)(user_input.data() + i));  | 
9859  | 59.1k  |     running = _mm_or_si128(  | 
9860  | 59.1k  |         _mm_or_si128(running, _mm_or_si128(_mm_cmpeq_epi8(word, mask1),  | 
9861  | 59.1k  |                                            _mm_cmpeq_epi8(word, mask2))),  | 
9862  | 59.1k  |         _mm_cmpeq_epi8(word, mask3));  | 
9863  | 59.1k  |   }  | 
9864  | 88.4k  |   if (i < user_input.size()) { | 
9865  | 60.3k  |     alignas(16) uint8_t buffer[16]{}; | 
9866  | 60.3k  |     memcpy(buffer, user_input.data() + i, user_input.size() - i);  | 
9867  | 60.3k  |     __m128i word = _mm_load_si128((const __m128i*)buffer);  | 
9868  | 60.3k  |     running = _mm_or_si128(  | 
9869  | 60.3k  |         _mm_or_si128(running, _mm_or_si128(_mm_cmpeq_epi8(word, mask1),  | 
9870  | 60.3k  |                                            _mm_cmpeq_epi8(word, mask2))),  | 
9871  | 60.3k  |         _mm_cmpeq_epi8(word, mask3));  | 
9872  | 60.3k  |   }  | 
9873  | 88.4k  |   return _mm_movemask_epi8(running) != 0;  | 
9874  | 88.4k  | }  | 
9875  |  | #else  | 
9876  |  | ada_really_inline bool has_tabs_or_newline(  | 
9877  |  |     std::string_view user_input) noexcept { | 
9878  |  |   auto has_zero_byte = [](uint64_t v) { | 
9879  |  |     return ((v - 0x0101010101010101) & ~(v)&0x8080808080808080);  | 
9880  |  |   };  | 
9881  |  |   auto broadcast = [](uint8_t v) -> uint64_t { | 
9882  |  |     return 0x101010101010101ull * v;  | 
9883  |  |   };  | 
9884  |  |   size_t i = 0;  | 
9885  |  |   uint64_t mask1 = broadcast('\r'); | 
9886  |  |   uint64_t mask2 = broadcast('\n'); | 
9887  |  |   uint64_t mask3 = broadcast('\t'); | 
9888  |  |   uint64_t running{0}; | 
9889  |  |   for (; i + 7 < user_input.size(); i += 8) { | 
9890  |  |     uint64_t word{}; | 
9891  |  |     memcpy(&word, user_input.data() + i, sizeof(word));  | 
9892  |  |     uint64_t xor1 = word ^ mask1;  | 
9893  |  |     uint64_t xor2 = word ^ mask2;  | 
9894  |  |     uint64_t xor3 = word ^ mask3;  | 
9895  |  |     running |= has_zero_byte(xor1) | has_zero_byte(xor2) | has_zero_byte(xor3);  | 
9896  |  |   }  | 
9897  |  |   if (i < user_input.size()) { | 
9898  |  |     uint64_t word{}; | 
9899  |  |     memcpy(&word, user_input.data() + i, user_input.size() - i);  | 
9900  |  |     uint64_t xor1 = word ^ mask1;  | 
9901  |  |     uint64_t xor2 = word ^ mask2;  | 
9902  |  |     uint64_t xor3 = word ^ mask3;  | 
9903  |  |     running |= has_zero_byte(xor1) | has_zero_byte(xor2) | has_zero_byte(xor3);  | 
9904  |  |   }  | 
9905  |  |   return running;  | 
9906  |  | }  | 
9907  |  | #endif  | 
9908  |  |  | 
9909  |  | // A forbidden host code point is U+0000 NULL, U+0009 TAB, U+000A LF, U+000D CR,  | 
9910  |  | // U+0020 SPACE, U+0023 (#), U+002F (/), U+003A (:), U+003C (<), U+003E (>),  | 
9911  |  | // U+003F (?), U+0040 (@), U+005B ([), U+005C (\), U+005D (]), U+005E (^), or  | 
9912  |  | // U+007C (|).  | 
9913  |  | constexpr static bool is_forbidden_host_code_point_table[] = { | 
9914  |  |     1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
9915  |  |     0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,  | 
9916  |  |     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,  | 
9917  |  |     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,  | 
9918  |  |     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
9919  |  |     0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
9920  |  |     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
9921  |  |     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
9922  |  |     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
9923  |  |     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
9924  |  |     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};  | 
9925  |  | static_assert(sizeof(is_forbidden_host_code_point_table) == 256);  | 
9926  |  |  | 
9927  |  | ada_really_inline constexpr bool is_forbidden_host_code_point(  | 
9928  | 33.1k  |     const char c) noexcept { | 
9929  | 33.1k  |   return is_forbidden_host_code_point_table[uint8_t(c)];  | 
9930  | 33.1k  | }  | 
9931  |  |  | 
9932  |  | static_assert(unicode::is_forbidden_host_code_point('\0')); | 
9933  |  | static_assert(unicode::is_forbidden_host_code_point('\t')); | 
9934  |  | static_assert(unicode::is_forbidden_host_code_point('\n')); | 
9935  |  | static_assert(unicode::is_forbidden_host_code_point('\r')); | 
9936  |  | static_assert(unicode::is_forbidden_host_code_point(' ')); | 
9937  |  | static_assert(unicode::is_forbidden_host_code_point('#')); | 
9938  |  | static_assert(unicode::is_forbidden_host_code_point('/')); | 
9939  |  | static_assert(unicode::is_forbidden_host_code_point(':')); | 
9940  |  | static_assert(unicode::is_forbidden_host_code_point('?')); | 
9941  |  | static_assert(unicode::is_forbidden_host_code_point('@')); | 
9942  |  | static_assert(unicode::is_forbidden_host_code_point('[')); | 
9943  |  | static_assert(unicode::is_forbidden_host_code_point('?')); | 
9944  |  | static_assert(unicode::is_forbidden_host_code_point('<')); | 
9945  |  | static_assert(unicode::is_forbidden_host_code_point('>')); | 
9946  |  | static_assert(unicode::is_forbidden_host_code_point('\\')); | 
9947  |  | static_assert(unicode::is_forbidden_host_code_point(']')); | 
9948  |  | static_assert(unicode::is_forbidden_host_code_point('^')); | 
9949  |  | static_assert(unicode::is_forbidden_host_code_point('|')); | 
9950  |  |  | 
9951  |  | constexpr static uint8_t is_forbidden_domain_code_point_table[] = { | 
9952  |  |     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  | 
9953  |  |     1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,  | 
9954  |  |     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,  | 
9955  |  |     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,  | 
9956  |  |     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
9957  |  |     0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  | 
9958  |  |     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  | 
9959  |  |     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  | 
9960  |  |     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  | 
9961  |  |     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  | 
9962  |  |     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};  | 
9963  |  |  | 
9964  |  | static_assert(sizeof(is_forbidden_domain_code_point_table) == 256);  | 
9965  |  |  | 
9966  |  | ada_really_inline constexpr bool is_forbidden_domain_code_point(  | 
9967  | 499k  |     const char c) noexcept { | 
9968  | 499k  |   return is_forbidden_domain_code_point_table[uint8_t(c)];  | 
9969  | 499k  | }  | 
9970  |  |  | 
9971  |  | ada_really_inline constexpr bool contains_forbidden_domain_code_point(  | 
9972  | 16.7k  |     const char* input, size_t length) noexcept { | 
9973  | 16.7k  |   size_t i = 0;  | 
9974  | 16.7k  |   uint8_t accumulator{}; | 
9975  | 183k  |   for (; i + 4 <= length; i += 4) { | 
9976  | 166k  |     accumulator |= is_forbidden_domain_code_point_table[uint8_t(input[i])];  | 
9977  | 166k  |     accumulator |= is_forbidden_domain_code_point_table[uint8_t(input[i + 1])];  | 
9978  | 166k  |     accumulator |= is_forbidden_domain_code_point_table[uint8_t(input[i + 2])];  | 
9979  | 166k  |     accumulator |= is_forbidden_domain_code_point_table[uint8_t(input[i + 3])];  | 
9980  | 166k  |   }  | 
9981  | 41.6k  |   for (; i < length; i++) { | 
9982  | 24.9k  |     accumulator |= is_forbidden_domain_code_point_table[uint8_t(input[i])];  | 
9983  | 24.9k  |   }  | 
9984  | 16.7k  |   return accumulator;  | 
9985  | 16.7k  | }  | 
9986  |  |  | 
9987  |  | constexpr static uint8_t is_forbidden_domain_code_point_table_or_upper[] = { | 
9988  |  |     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  | 
9989  |  |     1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,  | 
9990  |  |     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,  | 
9991  |  |     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 0,  | 
9992  |  |     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
9993  |  |     0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  | 
9994  |  |     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  | 
9995  |  |     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  | 
9996  |  |     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  | 
9997  |  |     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  | 
9998  |  |     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};  | 
9999  |  |  | 
10000  |  | static_assert(sizeof(is_forbidden_domain_code_point_table_or_upper) == 256);  | 
10001  |  | static_assert(is_forbidden_domain_code_point_table_or_upper[uint8_t('A')] == 2); | 
10002  |  | static_assert(is_forbidden_domain_code_point_table_or_upper[uint8_t('Z')] == 2); | 
10003  |  |  | 
10004  |  | ada_really_inline constexpr uint8_t  | 
10005  |  | contains_forbidden_domain_code_point_or_upper(const char* input,  | 
10006  | 15.4k  |                                               size_t length) noexcept { | 
10007  | 15.4k  |   size_t i = 0;  | 
10008  | 15.4k  |   uint8_t accumulator{}; | 
10009  | 87.7k  |   for (; i + 4 <= length; i += 4) { | 
10010  | 72.3k  |     accumulator |=  | 
10011  | 72.3k  |         is_forbidden_domain_code_point_table_or_upper[uint8_t(input[i])];  | 
10012  | 72.3k  |     accumulator |=  | 
10013  | 72.3k  |         is_forbidden_domain_code_point_table_or_upper[uint8_t(input[i + 1])];  | 
10014  | 72.3k  |     accumulator |=  | 
10015  | 72.3k  |         is_forbidden_domain_code_point_table_or_upper[uint8_t(input[i + 2])];  | 
10016  | 72.3k  |     accumulator |=  | 
10017  | 72.3k  |         is_forbidden_domain_code_point_table_or_upper[uint8_t(input[i + 3])];  | 
10018  | 72.3k  |   }  | 
10019  | 37.6k  |   for (; i < length; i++) { | 
10020  | 22.1k  |     accumulator |=  | 
10021  | 22.1k  |         is_forbidden_domain_code_point_table_or_upper[uint8_t(input[i])];  | 
10022  | 22.1k  |   }  | 
10023  | 15.4k  |   return accumulator;  | 
10024  | 15.4k  | }  | 
10025  |  |  | 
10026  |  | static_assert(unicode::is_forbidden_domain_code_point('%')); | 
10027  |  | static_assert(unicode::is_forbidden_domain_code_point('\x7f')); | 
10028  |  | static_assert(unicode::is_forbidden_domain_code_point('\0')); | 
10029  |  | static_assert(unicode::is_forbidden_domain_code_point('\t')); | 
10030  |  | static_assert(unicode::is_forbidden_domain_code_point('\n')); | 
10031  |  | static_assert(unicode::is_forbidden_domain_code_point('\r')); | 
10032  |  | static_assert(unicode::is_forbidden_domain_code_point(' ')); | 
10033  |  | static_assert(unicode::is_forbidden_domain_code_point('#')); | 
10034  |  | static_assert(unicode::is_forbidden_domain_code_point('/')); | 
10035  |  | static_assert(unicode::is_forbidden_domain_code_point(':')); | 
10036  |  | static_assert(unicode::is_forbidden_domain_code_point('?')); | 
10037  |  | static_assert(unicode::is_forbidden_domain_code_point('@')); | 
10038  |  | static_assert(unicode::is_forbidden_domain_code_point('[')); | 
10039  |  | static_assert(unicode::is_forbidden_domain_code_point('?')); | 
10040  |  | static_assert(unicode::is_forbidden_domain_code_point('<')); | 
10041  |  | static_assert(unicode::is_forbidden_domain_code_point('>')); | 
10042  |  | static_assert(unicode::is_forbidden_domain_code_point('\\')); | 
10043  |  | static_assert(unicode::is_forbidden_domain_code_point(']')); | 
10044  |  | static_assert(unicode::is_forbidden_domain_code_point('^')); | 
10045  |  | static_assert(unicode::is_forbidden_domain_code_point('|')); | 
10046  |  |  | 
10047  |  | constexpr static bool is_alnum_plus_table[] = { | 
10048  |  |     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
10049  |  |     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0,  | 
10050  |  |     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,  | 
10051  |  |     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,  | 
10052  |  |     0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  | 
10053  |  |     1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
10054  |  |     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
10055  |  |     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
10056  |  |     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
10057  |  |     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
10058  |  |     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};  | 
10059  |  |  | 
10060  |  | static_assert(sizeof(is_alnum_plus_table) == 256);  | 
10061  |  |  | 
10062  | 134k  | ada_really_inline constexpr bool is_alnum_plus(const char c) noexcept { | 
10063  | 134k  |   return is_alnum_plus_table[uint8_t(c)];  | 
10064  |  |   // A table is almost surely much faster than the  | 
10065  |  |   // following under most compilers: return  | 
10066  |  |   // return (std::isalnum(c) || c == '+' || c == '-' || c == '.');  | 
10067  | 134k  | }  | 
10068  |  | static_assert(unicode::is_alnum_plus('+')); | 
10069  |  | static_assert(unicode::is_alnum_plus('-')); | 
10070  |  | static_assert(unicode::is_alnum_plus('.')); | 
10071  |  | static_assert(unicode::is_alnum_plus('0')); | 
10072  |  | static_assert(unicode::is_alnum_plus('1')); | 
10073  |  | static_assert(unicode::is_alnum_plus('a')); | 
10074  |  | static_assert(unicode::is_alnum_plus('b')); | 
10075  |  |  | 
10076  | 37.9k  | ada_really_inline constexpr bool is_ascii_hex_digit(const char c) noexcept { | 
10077  | 37.9k  |   return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') ||  | 
10078  | 37.9k  |          (c >= 'a' && c <= 'f');  | 
10079  | 37.9k  | }  | 
10080  |  |  | 
10081  | 98.4k  | ada_really_inline constexpr bool is_c0_control_or_space(const char c) noexcept { | 
10082  | 98.4k  |   return (unsigned char)c <= ' ';  | 
10083  | 98.4k  | }  | 
10084  |  |  | 
10085  |  | ada_really_inline constexpr bool is_ascii_tab_or_newline(  | 
10086  | 827k  |     const char c) noexcept { | 
10087  | 827k  |   return c == '\t' || c == '\n' || c == '\r';  | 
10088  | 827k  | }  | 
10089  |  |  | 
10090  |  | constexpr std::string_view table_is_double_dot_path_segment[] = { | 
10091  |  |     "..", "%2e.", ".%2e", "%2e%2e"};  | 
10092  |  |  | 
10093  |  | ada_really_inline ada_constexpr bool is_double_dot_path_segment(  | 
10094  | 71.6k  |     std::string_view input) noexcept { | 
10095  |  |   // This will catch most cases:  | 
10096  |  |   // The length must be 2,4 or 6.  | 
10097  |  |   // We divide by two and require  | 
10098  |  |   // that the result be between 1 and 3 inclusively.  | 
10099  | 71.6k  |   uint64_t half_length = uint64_t(input.size()) / 2;  | 
10100  | 71.6k  |   if (half_length - 1 > 2) { | 
10101  | 39.6k  |     return false;  | 
10102  | 39.6k  |   }  | 
10103  |  |   // We have a string of length 2, 4 or 6.  | 
10104  |  |   // We now check the first character:  | 
10105  | 31.9k  |   if ((input[0] != '.') && (input[0] != '%')) { | 
10106  | 7.05k  |     return false;  | 
10107  | 7.05k  |   }  | 
10108  |  |   // We are unlikely the get beyond this point.  | 
10109  | 24.8k  |   int hash_value = (input.size() + (unsigned)(input[0])) & 3;  | 
10110  | 24.8k  |   const std::string_view target = table_is_double_dot_path_segment[hash_value];  | 
10111  | 24.8k  |   if (target.size() != input.size()) { | 
10112  | 7.86k  |     return false;  | 
10113  | 7.86k  |   }  | 
10114  |  |   // We almost never get here.  | 
10115  |  |   // Optimizing the rest is relatively unimportant.  | 
10116  | 17.0k  |   auto prefix_equal_unsafe = [](std::string_view a, std::string_view b) { | 
10117  | 17.0k  |     uint16_t A, B;  | 
10118  | 17.0k  |     memcpy(&A, a.data(), sizeof(A));  | 
10119  | 17.0k  |     memcpy(&B, b.data(), sizeof(B));  | 
10120  | 17.0k  |     return A == B;  | 
10121  | 17.0k  |   };  | 
10122  | 17.0k  |   if (!prefix_equal_unsafe(input, target)) { | 
10123  | 1.58k  |     return false;  | 
10124  | 1.58k  |   }  | 
10125  | 21.7k  |   for (size_t i = 2; i < input.size(); i++) { | 
10126  | 9.48k  |     char c = input[i];  | 
10127  | 9.48k  |     if ((uint8_t((c | 0x20) - 0x61) <= 25 ? (c | 0x20) : c) != target[i]) { | 
10128  | 3.15k  |       return false;  | 
10129  | 3.15k  |     }  | 
10130  | 9.48k  |   }  | 
10131  | 12.2k  |   return true;  | 
10132  |  |   // The above code might be a bit better than the code below. Compilers  | 
10133  |  |   // are not stupid and may use the fact that these strings have length 2,4 and  | 
10134  |  |   // 6 and other tricks.  | 
10135  |  |   // return input == ".." ||  | 
10136  |  |   //  input == ".%2e" || input == ".%2E" ||  | 
10137  |  |   //  input == "%2e." || input == "%2E." ||  | 
10138  |  |   //  input == "%2e%2e" || input == "%2E%2E" || input == "%2E%2e" || input ==  | 
10139  |  |   //  "%2e%2E";  | 
10140  | 15.4k  | }  | 
10141  |  |  | 
10142  |  | ada_really_inline constexpr bool is_single_dot_path_segment(  | 
10143  | 118k  |     std::string_view input) noexcept { | 
10144  | 118k  |   return input == "." || input == "%2e" || input == "%2E";  | 
10145  | 118k  | }  | 
10146  |  |  | 
10147  | 35.5k  | ada_really_inline constexpr bool is_lowercase_hex(const char c) noexcept { | 
10148  | 35.5k  |   return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f');  | 
10149  | 35.5k  | }  | 
10150  |  |  | 
10151  | 34.1k  | unsigned constexpr convert_hex_to_binary(const char c) noexcept { | 
10152  |  |   // this code can be optimized.  | 
10153  | 34.1k  |   if (c <= '9') { | 
10154  | 17.0k  |     return c - '0';  | 
10155  | 17.0k  |   }  | 
10156  | 17.0k  |   char del = c >= 'a' ? 'a' : 'A';  | 
10157  | 17.0k  |   return 10 + (c - del);  | 
10158  | 34.1k  | }  | 
10159  |  |  | 
10160  | 1.15k  | std::string percent_decode(const std::string_view input, size_t first_percent) { | 
10161  |  |   // next line is for safety only, we expect users to avoid calling  | 
10162  |  |   // percent_decode when first_percent is outside the range.  | 
10163  | 1.15k  |   if (first_percent == std::string_view::npos) { | 
10164  | 0  |     return std::string(input);  | 
10165  | 0  |   }  | 
10166  | 1.15k  |   std::string dest(input.substr(0, first_percent));  | 
10167  | 1.15k  |   dest.reserve(input.length());  | 
10168  | 1.15k  |   const char* pointer = input.data() + first_percent;  | 
10169  | 1.15k  |   const char* end = input.data() + input.size();  | 
10170  |  |   // Optimization opportunity: if the following code gets  | 
10171  |  |   // called often, it can be optimized quite a bit.  | 
10172  | 26.9k  |   while (pointer < end) { | 
10173  | 25.7k  |     const char ch = pointer[0];  | 
10174  | 25.7k  |     size_t remaining = end - pointer - 1;  | 
10175  | 25.7k  |     if (ch != '%' || remaining < 2 ||  | 
10176  | 25.7k  |         (  // ch == '%' && // It is unnecessary to check that ch == '%'.  | 
10177  | 15.8k  |             (!is_ascii_hex_digit(pointer[1]) ||  | 
10178  | 15.8k  |              !is_ascii_hex_digit(pointer[2])))) { | 
10179  | 11.1k  |       dest += ch;  | 
10180  | 11.1k  |       pointer++;  | 
10181  | 11.1k  |       continue;  | 
10182  | 14.6k  |     } else { | 
10183  | 14.6k  |       unsigned a = convert_hex_to_binary(pointer[1]);  | 
10184  | 14.6k  |       unsigned b = convert_hex_to_binary(pointer[2]);  | 
10185  | 14.6k  |       char c = static_cast<char>(a * 16 + b);  | 
10186  | 14.6k  |       dest += c;  | 
10187  | 14.6k  |       pointer += 3;  | 
10188  | 14.6k  |     }  | 
10189  | 25.7k  |   }  | 
10190  | 1.15k  |   return dest;  | 
10191  | 1.15k  | }  | 
10192  |  |  | 
10193  |  | std::string percent_encode(const std::string_view input,  | 
10194  | 30.2k  |                            const uint8_t character_set[]) { | 
10195  | 30.2k  |   auto pointer =  | 
10196  | 152k  |       std::find_if(input.begin(), input.end(), [character_set](const char c) { | 
10197  | 152k  |         return character_sets::bit_at(character_set, c);  | 
10198  | 152k  |       });  | 
10199  |  |   // Optimization: Don't iterate if percent encode is not required  | 
10200  | 30.2k  |   if (pointer == input.end()) { | 
10201  | 21.9k  |     return std::string(input);  | 
10202  | 21.9k  |   }  | 
10203  |  |  | 
10204  | 8.31k  |   std::string result(input.substr(0, std::distance(input.begin(), pointer)));  | 
10205  | 8.31k  |   result.reserve(input.length());  // in the worst case, percent encoding might  | 
10206  |  |                                    // produce 3 characters.  | 
10207  |  |  | 
10208  | 237k  |   for (; pointer != input.end(); pointer++) { | 
10209  | 229k  |     if (character_sets::bit_at(character_set, *pointer)) { | 
10210  | 165k  |       result.append(character_sets::hex + uint8_t(*pointer) * 4, 3);  | 
10211  | 165k  |     } else { | 
10212  | 64.0k  |       result += *pointer;  | 
10213  | 64.0k  |     }  | 
10214  | 229k  |   }  | 
10215  |  |  | 
10216  | 8.31k  |   return result;  | 
10217  | 30.2k  | }  | 
10218  |  |  | 
10219  |  | template <bool append>  | 
10220  |  | bool percent_encode(const std::string_view input, const uint8_t character_set[],  | 
10221  | 43.1k  |                     std::string& out) { | 
10222  | 43.1k  |   ada_log("percent_encode ", input, " to output string while ", | 
10223  | 43.1k  |           append ? "appending" : "overwriting");  | 
10224  | 43.1k  |   auto pointer =  | 
10225  | 101k  |       std::find_if(input.begin(), input.end(), [character_set](const char c) { | 
10226  | 101k  |         return character_sets::bit_at(character_set, c);  | 
10227  | 101k  |       }); 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) constLine  | Count  | Source  |  10225  | 70.2k  |       std::find_if(input.begin(), input.end(), [character_set](const char c) { |  10226  | 70.2k  |         return character_sets::bit_at(character_set, c);  |  10227  | 70.2k  |       });  |  
 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) constLine  | Count  | Source  |  10225  | 31.5k  |       std::find_if(input.begin(), input.end(), [character_set](const char c) { |  10226  | 31.5k  |         return character_sets::bit_at(character_set, c);  |  10227  | 31.5k  |       });  |  
  | 
10228  | 43.1k  |   ada_log("percent_encode done checking, moved to ", | 
10229  | 43.1k  |           std::distance(input.begin(), pointer));  | 
10230  |  |  | 
10231  |  |   // Optimization: Don't iterate if percent encode is not required  | 
10232  | 43.1k  |   if (pointer == input.end()) { | 
10233  | 24.8k  |     ada_log("percent_encode encoding not needed."); | 
10234  | 24.8k  |     return false;  | 
10235  | 24.8k  |   }  | 
10236  | 18.3k  |   if (!append) { | 
10237  | 16.8k  |     out.clear();  | 
10238  | 16.8k  |   }  | 
10239  | 18.3k  |   ada_log("percent_encode appending ", std::distance(input.begin(), pointer), | 
10240  | 18.3k  |           " bytes");  | 
10241  | 18.3k  |   out.append(input.data(), std::distance(input.begin(), pointer));  | 
10242  | 18.3k  |   ada_log("percent_encode processing ", std::distance(pointer, input.end()), | 
10243  | 18.3k  |           " bytes");  | 
10244  | 274k  |   for (; pointer != input.end(); pointer++) { | 
10245  | 256k  |     if (character_sets::bit_at(character_set, *pointer)) { | 
10246  | 203k  |       out.append(character_sets::hex + uint8_t(*pointer) * 4, 3);  | 
10247  | 203k  |     } else { | 
10248  | 52.9k  |       out += *pointer;  | 
10249  | 52.9k  |     }  | 
10250  | 256k  |   }  | 
10251  | 18.3k  |   return true;  | 
10252  | 43.1k  | } 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> >&) Line  | Count  | Source  |  10221  | 38.7k  |                     std::string& out) { |  10222  | 38.7k  |   ada_log("percent_encode ", input, " to output string while ", |  10223  | 38.7k  |           append ? "appending" : "overwriting");  |  10224  | 38.7k  |   auto pointer =  |  10225  | 38.7k  |       std::find_if(input.begin(), input.end(), [character_set](const char c) { |  10226  | 38.7k  |         return character_sets::bit_at(character_set, c);  |  10227  | 38.7k  |       });  |  10228  | 38.7k  |   ada_log("percent_encode done checking, moved to ", |  10229  | 38.7k  |           std::distance(input.begin(), pointer));  |  10230  |  |  |  10231  |  |   // Optimization: Don't iterate if percent encode is not required  |  10232  | 38.7k  |   if (pointer == input.end()) { |  10233  | 21.9k  |     ada_log("percent_encode encoding not needed."); |  10234  | 21.9k  |     return false;  |  10235  | 21.9k  |   }  |  10236  | 16.8k  |   if (!append) { |  10237  | 16.8k  |     out.clear();  |  10238  | 16.8k  |   }  |  10239  | 16.8k  |   ada_log("percent_encode appending ", std::distance(input.begin(), pointer), |  10240  | 16.8k  |           " bytes");  |  10241  | 16.8k  |   out.append(input.data(), std::distance(input.begin(), pointer));  |  10242  | 16.8k  |   ada_log("percent_encode processing ", std::distance(pointer, input.end()), |  10243  | 16.8k  |           " bytes");  |  10244  | 210k  |   for (; pointer != input.end(); pointer++) { |  10245  | 193k  |     if (character_sets::bit_at(character_set, *pointer)) { |  10246  | 156k  |       out.append(character_sets::hex + uint8_t(*pointer) * 4, 3);  |  10247  | 156k  |     } else { |  10248  | 37.2k  |       out += *pointer;  |  10249  | 37.2k  |     }  |  10250  | 193k  |   }  |  10251  | 16.8k  |   return true;  |  10252  | 38.7k  | }  |  
 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> >&) Line  | Count  | Source  |  10221  | 4.44k  |                     std::string& out) { |  10222  | 4.44k  |   ada_log("percent_encode ", input, " to output string while ", |  10223  | 4.44k  |           append ? "appending" : "overwriting");  |  10224  | 4.44k  |   auto pointer =  |  10225  | 4.44k  |       std::find_if(input.begin(), input.end(), [character_set](const char c) { |  10226  | 4.44k  |         return character_sets::bit_at(character_set, c);  |  10227  | 4.44k  |       });  |  10228  | 4.44k  |   ada_log("percent_encode done checking, moved to ", |  10229  | 4.44k  |           std::distance(input.begin(), pointer));  |  10230  |  |  |  10231  |  |   // Optimization: Don't iterate if percent encode is not required  |  10232  | 4.44k  |   if (pointer == input.end()) { |  10233  | 2.95k  |     ada_log("percent_encode encoding not needed."); |  10234  | 2.95k  |     return false;  |  10235  | 2.95k  |   }  |  10236  | 1.48k  |   if (!append) { |  10237  | 0  |     out.clear();  |  10238  | 0  |   }  |  10239  | 1.48k  |   ada_log("percent_encode appending ", std::distance(input.begin(), pointer), |  10240  | 1.48k  |           " bytes");  |  10241  | 1.48k  |   out.append(input.data(), std::distance(input.begin(), pointer));  |  10242  | 1.48k  |   ada_log("percent_encode processing ", std::distance(pointer, input.end()), |  10243  | 1.48k  |           " bytes");  |  10244  | 63.5k  |   for (; pointer != input.end(); pointer++) { |  10245  | 62.0k  |     if (character_sets::bit_at(character_set, *pointer)) { |  10246  | 46.3k  |       out.append(character_sets::hex + uint8_t(*pointer) * 4, 3);  |  10247  | 46.3k  |     } else { |  10248  | 15.7k  |       out += *pointer;  |  10249  | 15.7k  |     }  |  10250  | 62.0k  |   }  |  10251  | 1.48k  |   return true;  |  10252  | 4.44k  | }  |  
  | 
10253  |  |  | 
10254  |  | bool to_ascii(std::optional<std::string>& out, const std::string_view plain,  | 
10255  | 10.7k  |               size_t first_percent) { | 
10256  | 10.7k  |   std::string percent_decoded_buffer;  | 
10257  | 10.7k  |   std::string_view input = plain;  | 
10258  | 10.7k  |   if (first_percent != std::string_view::npos) { | 
10259  | 1.15k  |     percent_decoded_buffer = unicode::percent_decode(plain, first_percent);  | 
10260  | 1.15k  |     input = percent_decoded_buffer;  | 
10261  | 1.15k  |   }  | 
10262  |  |   // input is a non-empty UTF-8 string, must be percent decoded  | 
10263  | 10.7k  |   std::string idna_ascii = ada::idna::to_ascii(input);  | 
10264  | 10.7k  |   if (idna_ascii.empty() || contains_forbidden_domain_code_point(  | 
10265  | 8.39k  |                                 idna_ascii.data(), idna_ascii.size())) { | 
10266  | 3.55k  |     return false;  | 
10267  | 3.55k  |   }  | 
10268  | 7.16k  |   out = std::move(idna_ascii);  | 
10269  | 7.16k  |   return true;  | 
10270  | 10.7k  | }  | 
10271  |  |  | 
10272  |  | std::string percent_encode(const std::string_view input,  | 
10273  | 1.56k  |                            const uint8_t character_set[], size_t index) { | 
10274  | 1.56k  |   std::string out;  | 
10275  | 1.56k  |   out.append(input.data(), index);  | 
10276  | 1.56k  |   auto pointer = input.begin() + index;  | 
10277  | 66.7k  |   for (; pointer != input.end(); pointer++) { | 
10278  | 65.1k  |     if (character_sets::bit_at(character_set, *pointer)) { | 
10279  | 55.5k  |       out.append(character_sets::hex + uint8_t(*pointer) * 4, 3);  | 
10280  | 55.5k  |     } else { | 
10281  | 9.63k  |       out += *pointer;  | 
10282  | 9.63k  |     }  | 
10283  | 65.1k  |   }  | 
10284  | 1.56k  |   return out;  | 
10285  | 1.56k  | }  | 
10286  |  |  | 
10287  | 0  | std::string to_unicode(std::string_view input) { | 
10288  | 0  |   return ada::idna::to_unicode(input);  | 
10289  | 0  | }  | 
10290  |  |  | 
10291  |  | }  // namespace ada::unicode  | 
10292  |  | /* end file src/unicode.cpp */  | 
10293  |  | /* begin file src/serializers.cpp */  | 
10294  |  |  | 
10295  |  | #include <array>  | 
10296  |  | #include <string>  | 
10297  |  |  | 
10298  |  | namespace ada::serializers { | 
10299  |  |  | 
10300  |  | void find_longest_sequence_of_ipv6_pieces(  | 
10301  |  |     const std::array<uint16_t, 8>& address, size_t& compress,  | 
10302  | 600  |     size_t& compress_length) noexcept { | 
10303  | 2.33k  |   for (size_t i = 0; i < 8; i++) { | 
10304  | 1.93k  |     if (address[i] == 0) { | 
10305  | 751  |       size_t next = i + 1;  | 
10306  | 3.34k  |       while (next != 8 && address[next] == 0) ++next;  | 
10307  | 751  |       const size_t count = next - i;  | 
10308  | 751  |       if (compress_length < count) { | 
10309  | 564  |         compress_length = count;  | 
10310  | 564  |         compress = i;  | 
10311  | 564  |         if (next == 8) break;  | 
10312  | 362  |         i = next;  | 
10313  | 362  |       }  | 
10314  | 751  |     }  | 
10315  | 1.93k  |   }  | 
10316  | 600  | }  | 
10317  |  |  | 
10318  | 600  | std::string ipv6(const std::array<uint16_t, 8>& address) noexcept { | 
10319  | 600  |   size_t compress_length = 0;  // The length of a long sequence of zeros.  | 
10320  | 600  |   size_t compress = 0;         // The start of a long sequence of zeros.  | 
10321  | 600  |   find_longest_sequence_of_ipv6_pieces(address, compress, compress_length);  | 
10322  |  |  | 
10323  | 600  |   if (compress_length <= 1) { | 
10324  |  |     // Optimization opportunity: Find a faster way then snprintf for imploding  | 
10325  |  |     // and return here.  | 
10326  | 112  |     compress = compress_length = 8;  | 
10327  | 112  |   }  | 
10328  |  |  | 
10329  | 600  |   std::string output(4 * 8 + 7 + 2, '\0');  | 
10330  | 600  |   size_t piece_index = 0;  | 
10331  | 600  |   char* point = output.data();  | 
10332  | 600  |   char* point_end = output.data() + output.size();  | 
10333  | 600  |   *point++ = '[';  | 
10334  | 2.01k  |   while (true) { | 
10335  | 2.01k  |     if (piece_index == compress) { | 
10336  | 488  |       *point++ = ':';  | 
10337  |  |       // If we skip a value initially, we need to write '::', otherwise  | 
10338  |  |       // a single ':' will do since it follows a previous ':'.  | 
10339  | 488  |       if (piece_index == 0) { | 
10340  | 301  |         *point++ = ':';  | 
10341  | 301  |       }  | 
10342  | 488  |       piece_index += compress_length;  | 
10343  | 488  |       if (piece_index == 8) { | 
10344  | 198  |         break;  | 
10345  | 198  |       }  | 
10346  | 488  |     }  | 
10347  | 1.81k  |     point = std::to_chars(point, point_end, address[piece_index], 16).ptr;  | 
10348  | 1.81k  |     piece_index++;  | 
10349  | 1.81k  |     if (piece_index == 8) { | 
10350  | 402  |       break;  | 
10351  | 402  |     }  | 
10352  | 1.41k  |     *point++ = ':';  | 
10353  | 1.41k  |   }  | 
10354  | 600  |   *point++ = ']';  | 
10355  | 600  |   output.resize(point - output.data());  | 
10356  | 600  |   return output;  | 
10357  | 600  | }  | 
10358  |  |  | 
10359  | 4.37k  | std::string ipv4(const uint64_t address) noexcept { | 
10360  | 4.37k  |   std::string output(15, '\0');  | 
10361  | 4.37k  |   char* point = output.data();  | 
10362  | 4.37k  |   char* point_end = output.data() + output.size();  | 
10363  | 4.37k  |   point = std::to_chars(point, point_end, uint8_t(address >> 24)).ptr;  | 
10364  | 17.4k  |   for (int i = 2; i >= 0; i--) { | 
10365  | 13.1k  |     *point++ = '.';  | 
10366  | 13.1k  |     point = std::to_chars(point, point_end, uint8_t(address >> (i * 8))).ptr;  | 
10367  | 13.1k  |   }  | 
10368  | 4.37k  |   output.resize(point - output.data());  | 
10369  | 4.37k  |   return output;  | 
10370  | 4.37k  | }  | 
10371  |  |  | 
10372  |  | }  // namespace ada::serializers  | 
10373  |  | /* end file src/serializers.cpp */  | 
10374  |  | /* begin file src/implementation.cpp */  | 
10375  |  | #include <string_view>  | 
10376  |  |  | 
10377  |  |  | 
10378  |  | namespace ada { | 
10379  |  |  | 
10380  |  | template <class result_type>  | 
10381  |  | ada_warn_unused tl::expected<result_type, ada::errors> parse(  | 
10382  | 59.9k  |     std::string_view input, const result_type* base_url) { | 
10383  | 59.9k  |   result_type u = ada::parser::parse_url<result_type>(input, base_url);  | 
10384  | 59.9k  |   if (!u.is_valid) { | 
10385  | 29.9k  |     return tl::unexpected(errors::generic_error);  | 
10386  | 29.9k  |   }  | 
10387  | 29.9k  |   return u;  | 
10388  | 59.9k  | } tl::expected<ada::url, ada::errors> ada::parse<ada::url>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url const*) Line  | Count  | Source  |  10382  | 14.5k  |     std::string_view input, const result_type* base_url) { |  10383  | 14.5k  |   result_type u = ada::parser::parse_url<result_type>(input, base_url);  |  10384  | 14.5k  |   if (!u.is_valid) { |  10385  | 6.10k  |     return tl::unexpected(errors::generic_error);  |  10386  | 6.10k  |   }  |  10387  | 8.40k  |   return u;  |  10388  | 14.5k  | }  |  
 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*) Line  | Count  | Source  |  10382  | 45.4k  |     std::string_view input, const result_type* base_url) { |  10383  | 45.4k  |   result_type u = ada::parser::parse_url<result_type>(input, base_url);  |  10384  | 45.4k  |   if (!u.is_valid) { |  10385  | 23.8k  |     return tl::unexpected(errors::generic_error);  |  10386  | 23.8k  |   }  |  10387  | 21.5k  |   return u;  |  10388  | 45.4k  | }  |  
  | 
10389  |  |  | 
10390  |  | template ada::result<url> parse<url>(std::string_view input,  | 
10391  |  |                                      const url* base_url = nullptr);  | 
10392  |  | template ada::result<url_aggregator> parse<url_aggregator>(  | 
10393  |  |     std::string_view input, const url_aggregator* base_url = nullptr);  | 
10394  |  |  | 
10395  | 14.1k  | std::string href_from_file(std::string_view input) { | 
10396  |  |   // This is going to be much faster than constructing a URL.  | 
10397  | 14.1k  |   std::string tmp_buffer;  | 
10398  | 14.1k  |   std::string_view internal_input;  | 
10399  | 14.1k  |   if (unicode::has_tabs_or_newline(input)) { | 
10400  | 202  |     tmp_buffer = input;  | 
10401  | 202  |     helpers::remove_ascii_tab_or_newline(tmp_buffer);  | 
10402  | 202  |     internal_input = tmp_buffer;  | 
10403  | 13.9k  |   } else { | 
10404  | 13.9k  |     internal_input = input;  | 
10405  | 13.9k  |   }  | 
10406  | 14.1k  |   std::string path;  | 
10407  | 14.1k  |   if (internal_input.empty()) { | 
10408  | 969  |     path = "/";  | 
10409  | 13.1k  |   } else if ((internal_input[0] == '/') || (internal_input[0] == '\\')) { | 
10410  | 776  |     helpers::parse_prepared_path(internal_input.substr(1),  | 
10411  | 776  |                                  ada::scheme::type::FILE, path);  | 
10412  | 12.3k  |   } else { | 
10413  | 12.3k  |     helpers::parse_prepared_path(internal_input, ada::scheme::type::FILE, path);  | 
10414  | 12.3k  |   }  | 
10415  | 14.1k  |   return "file://" + path;  | 
10416  | 14.1k  | }  | 
10417  |  |  | 
10418  | 28.2k  | bool can_parse(std::string_view input, const std::string_view* base_input) { | 
10419  | 28.2k  |   ada::result<ada::url_aggregator> base;  | 
10420  | 28.2k  |   ada::url_aggregator* base_pointer = nullptr;  | 
10421  | 28.2k  |   if (base_input != nullptr) { | 
10422  | 14.1k  |     base = ada::parse<url_aggregator>(*base_input);  | 
10423  | 14.1k  |     if (!base) { | 
10424  | 11.4k  |       return false;  | 
10425  | 11.4k  |     }  | 
10426  | 2.66k  |     base_pointer = &base.value();  | 
10427  | 2.66k  |   }  | 
10428  | 16.7k  |   return ada::parse<url_aggregator>(input, base_pointer).has_value();  | 
10429  | 28.2k  | }  | 
10430  |  |  | 
10431  | 0  | ada_warn_unused std::string to_string(ada::encoding_type type) { | 
10432  | 0  |   switch (type) { | 
10433  | 0  |     case ada::encoding_type::UTF8:  | 
10434  | 0  |       return "UTF-8";  | 
10435  | 0  |     case ada::encoding_type::UTF_16LE:  | 
10436  | 0  |       return "UTF-16LE";  | 
10437  | 0  |     case ada::encoding_type::UTF_16BE:  | 
10438  | 0  |       return "UTF-16BE";  | 
10439  | 0  |     default:  | 
10440  | 0  |       unreachable();  | 
10441  | 0  |   }  | 
10442  | 0  | }  | 
10443  |  |  | 
10444  |  | }  // namespace ada  | 
10445  |  | /* end file src/implementation.cpp */  | 
10446  |  | /* begin file src/helpers.cpp */  | 
10447  |  |  | 
10448  |  | #include <algorithm>  | 
10449  |  | #include <charconv>  | 
10450  |  | #include <cstring>  | 
10451  |  | #include <sstream>  | 
10452  |  |  | 
10453  |  | namespace ada::helpers { | 
10454  |  |  | 
10455  |  | template <typename out_iter>  | 
10456  | 0  | void encode_json(std::string_view view, out_iter out) { | 
10457  |  |   // trivial implementation. could be faster.  | 
10458  | 0  |   const char* hexvalues =  | 
10459  | 0  |       "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f";  | 
10460  | 0  |   for (uint8_t c : view) { | 
10461  | 0  |     if (c == '\\') { | 
10462  | 0  |       *out++ = '\\';  | 
10463  | 0  |       *out++ = '\\';  | 
10464  | 0  |     } else if (c == '"') { | 
10465  | 0  |       *out++ = '\\';  | 
10466  | 0  |       *out++ = '"';  | 
10467  | 0  |     } else if (c <= 0x1f) { | 
10468  | 0  |       *out++ = '\\';  | 
10469  | 0  |       *out++ = 'u';  | 
10470  | 0  |       *out++ = '0';  | 
10471  | 0  |       *out++ = '0';  | 
10472  | 0  |       *out++ = hexvalues[2 * c];  | 
10473  | 0  |       *out++ = hexvalues[2 * c + 1];  | 
10474  | 0  |     } else { | 
10475  | 0  |       *out++ = c;  | 
10476  | 0  |     }  | 
10477  | 0  |   }  | 
10478  | 0  | }  | 
10479  |  |  | 
10480  | 0  | ada_unused std::string get_state(ada::state s) { | 
10481  | 0  |   switch (s) { | 
10482  | 0  |     case ada::state::AUTHORITY:  | 
10483  | 0  |       return "Authority";  | 
10484  | 0  |     case ada::state::SCHEME_START:  | 
10485  | 0  |       return "Scheme Start";  | 
10486  | 0  |     case ada::state::SCHEME:  | 
10487  | 0  |       return "Scheme";  | 
10488  | 0  |     case ada::state::HOST:  | 
10489  | 0  |       return "Host";  | 
10490  | 0  |     case ada::state::NO_SCHEME:  | 
10491  | 0  |       return "No Scheme";  | 
10492  | 0  |     case ada::state::FRAGMENT:  | 
10493  | 0  |       return "Fragment";  | 
10494  | 0  |     case ada::state::RELATIVE_SCHEME:  | 
10495  | 0  |       return "Relative Scheme";  | 
10496  | 0  |     case ada::state::RELATIVE_SLASH:  | 
10497  | 0  |       return "Relative Slash";  | 
10498  | 0  |     case ada::state::FILE:  | 
10499  | 0  |       return "File";  | 
10500  | 0  |     case ada::state::FILE_HOST:  | 
10501  | 0  |       return "File Host";  | 
10502  | 0  |     case ada::state::FILE_SLASH:  | 
10503  | 0  |       return "File Slash";  | 
10504  | 0  |     case ada::state::PATH_OR_AUTHORITY:  | 
10505  | 0  |       return "Path or Authority";  | 
10506  | 0  |     case ada::state::SPECIAL_AUTHORITY_IGNORE_SLASHES:  | 
10507  | 0  |       return "Special Authority Ignore Slashes";  | 
10508  | 0  |     case ada::state::SPECIAL_AUTHORITY_SLASHES:  | 
10509  | 0  |       return "Special Authority Slashes";  | 
10510  | 0  |     case ada::state::SPECIAL_RELATIVE_OR_AUTHORITY:  | 
10511  | 0  |       return "Special Relative or Authority";  | 
10512  | 0  |     case ada::state::QUERY:  | 
10513  | 0  |       return "Query";  | 
10514  | 0  |     case ada::state::PATH:  | 
10515  | 0  |       return "Path";  | 
10516  | 0  |     case ada::state::PATH_START:  | 
10517  | 0  |       return "Path Start";  | 
10518  | 0  |     case ada::state::OPAQUE_PATH:  | 
10519  | 0  |       return "Opaque Path";  | 
10520  | 0  |     case ada::state::PORT:  | 
10521  | 0  |       return "Port";  | 
10522  | 0  |     default:  | 
10523  | 0  |       return "unknown state";  | 
10524  | 0  |   }  | 
10525  | 0  | }  | 
10526  |  |  | 
10527  |  | ada_really_inline std::optional<std::string_view> prune_hash(  | 
10528  | 59.9k  |     std::string_view& input) noexcept { | 
10529  |  |   // compiles down to 20--30 instructions including a class to memchr (C  | 
10530  |  |   // function). this function should be quite fast.  | 
10531  | 59.9k  |   size_t location_of_first = input.find('#'); | 
10532  | 59.9k  |   if (location_of_first == std::string_view::npos) { | 
10533  | 58.5k  |     return std::nullopt;  | 
10534  | 58.5k  |   }  | 
10535  | 1.32k  |   std::string_view hash = input;  | 
10536  | 1.32k  |   hash.remove_prefix(location_of_first + 1);  | 
10537  | 1.32k  |   input.remove_suffix(input.size() - location_of_first);  | 
10538  | 1.32k  |   return hash;  | 
10539  | 59.9k  | }  | 
10540  |  |  | 
10541  |  | ada_really_inline bool shorten_path(std::string& path,  | 
10542  | 12.2k  |                                     ada::scheme::type type) noexcept { | 
10543  | 12.2k  |   size_t first_delimiter = path.find_first_of('/', 1); | 
10544  |  |  | 
10545  |  |   // Let path be url’s path.  | 
10546  |  |   // If url’s scheme is "file", path’s size is 1, and path[0] is a normalized  | 
10547  |  |   // Windows drive letter, then return.  | 
10548  | 12.2k  |   if (type == ada::scheme::type::FILE &&  | 
10549  | 12.2k  |       first_delimiter == std::string_view::npos && !path.empty()) { | 
10550  | 5.97k  |     if (checkers::is_normalized_windows_drive_letter(  | 
10551  | 5.97k  |             helpers::substring(path, 1))) { | 
10552  | 1.64k  |       return false;  | 
10553  | 1.64k  |     }  | 
10554  | 5.97k  |   }  | 
10555  |  |  | 
10556  |  |   // Remove path’s last item, if any.  | 
10557  | 10.6k  |   size_t last_delimiter = path.rfind('/'); | 
10558  | 10.6k  |   if (last_delimiter != std::string::npos) { | 
10559  | 6.16k  |     path.erase(last_delimiter);  | 
10560  | 6.16k  |     return true;  | 
10561  | 6.16k  |   }  | 
10562  |  |  | 
10563  | 4.47k  |   return false;  | 
10564  | 10.6k  | }  | 
10565  |  |  | 
10566  |  | ada_really_inline bool shorten_path(std::string_view& path,  | 
10567  | 326  |                                     ada::scheme::type type) noexcept { | 
10568  | 326  |   size_t first_delimiter = path.find_first_of('/', 1); | 
10569  |  |  | 
10570  |  |   // Let path be url’s path.  | 
10571  |  |   // If url’s scheme is "file", path’s size is 1, and path[0] is a normalized  | 
10572  |  |   // Windows drive letter, then return.  | 
10573  | 326  |   if (type == ada::scheme::type::FILE &&  | 
10574  | 326  |       first_delimiter == std::string_view::npos && !path.empty()) { | 
10575  | 75  |     if (checkers::is_normalized_windows_drive_letter(  | 
10576  | 75  |             helpers::substring(path, 1))) { | 
10577  | 8  |       return false;  | 
10578  | 8  |     }  | 
10579  | 75  |   }  | 
10580  |  |  | 
10581  |  |   // Remove path’s last item, if any.  | 
10582  | 318  |   if (!path.empty()) { | 
10583  | 308  |     size_t slash_loc = path.rfind('/'); | 
10584  | 308  |     if (slash_loc != std::string_view::npos) { | 
10585  | 282  |       path.remove_suffix(path.size() - slash_loc);  | 
10586  | 282  |       return true;  | 
10587  | 282  |     }  | 
10588  | 308  |   }  | 
10589  |  |  | 
10590  | 36  |   return false;  | 
10591  | 318  | }  | 
10592  |  |  | 
10593  |  | ada_really_inline void remove_ascii_tab_or_newline(  | 
10594  | 66.0k  |     std::string& input) noexcept { | 
10595  |  |   // if this ever becomes a performance issue, we could use an approach similar  | 
10596  |  |   // to has_tabs_or_newline  | 
10597  | 66.0k  |   input.erase(std::remove_if(input.begin(), input.end(),  | 
10598  | 827k  |                              [](char c) { | 
10599  | 827k  |                                return ada::unicode::is_ascii_tab_or_newline(c);  | 
10600  | 827k  |                              }),  | 
10601  | 66.0k  |               input.end());  | 
10602  | 66.0k  | }  | 
10603  |  |  | 
10604  |  | ada_really_inline std::string_view substring(std::string_view input,  | 
10605  | 82.4k  |                                              size_t pos) noexcept { | 
10606  | 82.4k  |   ADA_ASSERT_TRUE(pos <= input.size());  | 
10607  |  |   // The following is safer but unneeded if we have the above line:  | 
10608  |  |   // return pos > input.size() ? std::string_view() : input.substr(pos);  | 
10609  | 82.4k  |   return input.substr(pos);  | 
10610  | 82.4k  | }  | 
10611  |  |  | 
10612  | 12  | ada_really_inline void resize(std::string_view& input, size_t pos) noexcept { | 
10613  | 12  |   ADA_ASSERT_TRUE(pos <= input.size());  | 
10614  | 12  |   input.remove_suffix(input.size() - pos);  | 
10615  | 12  | }  | 
10616  |  |  | 
10617  |  | // Reverse the byte order.  | 
10618  | 0  | ada_really_inline uint64_t swap_bytes(uint64_t val) noexcept { | 
10619  | 0  |   // performance: this often compiles to a single instruction (e.g., bswap)  | 
10620  | 0  |   return ((((val)&0xff00000000000000ull) >> 56) |  | 
10621  | 0  |           (((val)&0x00ff000000000000ull) >> 40) |  | 
10622  | 0  |           (((val)&0x0000ff0000000000ull) >> 24) |  | 
10623  | 0  |           (((val)&0x000000ff00000000ull) >> 8) |  | 
10624  | 0  |           (((val)&0x00000000ff000000ull) << 8) |  | 
10625  | 0  |           (((val)&0x0000000000ff0000ull) << 24) |  | 
10626  | 0  |           (((val)&0x000000000000ff00ull) << 40) |  | 
10627  | 0  |           (((val)&0x00000000000000ffull) << 56));  | 
10628  | 0  | }  | 
10629  |  |  | 
10630  | 88.7k  | ada_really_inline uint64_t swap_bytes_if_big_endian(uint64_t val) noexcept { | 
10631  |  |   // performance: under little-endian systems (most systems), this function  | 
10632  |  |   // is free (just returns the input).  | 
10633  |  | #if ADA_IS_BIG_ENDIAN  | 
10634  |  |   return swap_bytes(val);  | 
10635  |  | #else  | 
10636  | 88.7k  |   return val;  // unchanged (trivial)  | 
10637  | 88.7k  | #endif  | 
10638  | 88.7k  | }  | 
10639  |  |  | 
10640  |  | // starting at index location, this finds the next location of a character  | 
10641  |  | // :, /, \\, ? or [. If none is found, view.size() is returned.  | 
10642  |  | // For use within get_host_delimiter_location.  | 
10643  |  | ada_really_inline size_t find_next_host_delimiter_special(  | 
10644  | 39.4k  |     std::string_view view, size_t location) noexcept { | 
10645  |  |   // performance: if you plan to call find_next_host_delimiter more than once,  | 
10646  |  |   // you *really* want find_next_host_delimiter to be inlined, because  | 
10647  |  |   // otherwise, the constants may get reloaded each time (bad).  | 
10648  | 307k  |   auto has_zero_byte = [](uint64_t v) { | 
10649  | 307k  |     return ((v - 0x0101010101010101) & ~(v)&0x8080808080808080);  | 
10650  | 307k  |   };  | 
10651  | 39.4k  |   auto index_of_first_set_byte = [](uint64_t v) { | 
10652  | 10.8k  |     return ((((v - 1) & 0x101010101010101) * 0x101010101010101) >> 56) - 1;  | 
10653  | 10.8k  |   };  | 
10654  | 197k  |   auto broadcast = [](uint8_t v) -> uint64_t { | 
10655  | 197k  |     return 0x101010101010101ull * v;  | 
10656  | 197k  |   };  | 
10657  | 39.4k  |   size_t i = location;  | 
10658  | 39.4k  |   uint64_t mask1 = broadcast(':'); | 
10659  | 39.4k  |   uint64_t mask2 = broadcast('/'); | 
10660  | 39.4k  |   uint64_t mask3 = broadcast('\\'); | 
10661  | 39.4k  |   uint64_t mask4 = broadcast('?'); | 
10662  | 39.4k  |   uint64_t mask5 = broadcast('['); | 
10663  |  |   // This loop will get autovectorized under many optimizing compilers,  | 
10664  |  |   // so you get actually SIMD!  | 
10665  | 74.3k  |   for (; i + 7 < view.size(); i += 8) { | 
10666  | 40.4k  |     uint64_t word{}; | 
10667  |  |     // performance: the next memcpy translates into a single CPU instruction.  | 
10668  | 40.4k  |     memcpy(&word, view.data() + i, sizeof(word));  | 
10669  |  |     // performance: on little-endian systems (most systems), this next line is  | 
10670  |  |     // free.  | 
10671  | 40.4k  |     word = swap_bytes_if_big_endian(word);  | 
10672  | 40.4k  |     uint64_t xor1 = word ^ mask1;  | 
10673  | 40.4k  |     uint64_t xor2 = word ^ mask2;  | 
10674  | 40.4k  |     uint64_t xor3 = word ^ mask3;  | 
10675  | 40.4k  |     uint64_t xor4 = word ^ mask4;  | 
10676  | 40.4k  |     uint64_t xor5 = word ^ mask5;  | 
10677  | 40.4k  |     uint64_t is_match = has_zero_byte(xor1) | has_zero_byte(xor2) |  | 
10678  | 40.4k  |                         has_zero_byte(xor3) | has_zero_byte(xor4) |  | 
10679  | 40.4k  |                         has_zero_byte(xor5);  | 
10680  | 40.4k  |     if (is_match) { | 
10681  | 5.61k  |       return size_t(i + index_of_first_set_byte(is_match));  | 
10682  | 5.61k  |     }  | 
10683  | 40.4k  |   }  | 
10684  | 33.8k  |   if (i < view.size()) { | 
10685  | 21.0k  |     uint64_t word{}; | 
10686  |  |     // performance: the next memcpy translates into a function call, but  | 
10687  |  |     // that is difficult to avoid. Might be a bit expensive.  | 
10688  | 21.0k  |     memcpy(&word, view.data() + i, view.size() - i);  | 
10689  | 21.0k  |     word = swap_bytes_if_big_endian(word);  | 
10690  | 21.0k  |     uint64_t xor1 = word ^ mask1;  | 
10691  | 21.0k  |     uint64_t xor2 = word ^ mask2;  | 
10692  | 21.0k  |     uint64_t xor3 = word ^ mask3;  | 
10693  | 21.0k  |     uint64_t xor4 = word ^ mask4;  | 
10694  | 21.0k  |     uint64_t xor5 = word ^ mask5;  | 
10695  | 21.0k  |     uint64_t is_match = has_zero_byte(xor1) | has_zero_byte(xor2) |  | 
10696  | 21.0k  |                         has_zero_byte(xor3) | has_zero_byte(xor4) |  | 
10697  | 21.0k  |                         has_zero_byte(xor5);  | 
10698  | 21.0k  |     if (is_match) { | 
10699  | 5.24k  |       return size_t(i + index_of_first_set_byte(is_match));  | 
10700  | 5.24k  |     }  | 
10701  | 21.0k  |   }  | 
10702  | 28.6k  |   return view.size();  | 
10703  | 33.8k  | }  | 
10704  |  |  | 
10705  |  | // starting at index location, this finds the next location of a character  | 
10706  |  | // :, /, ? or [. If none is found, view.size() is returned.  | 
10707  |  | // For use within get_host_delimiter_location.  | 
10708  |  | ada_really_inline size_t find_next_host_delimiter(std::string_view view,  | 
10709  | 11.3k  |                                                   size_t location) noexcept { | 
10710  |  |   // performance: if you plan to call find_next_host_delimiter more than once,  | 
10711  |  |   // you *really* want find_next_host_delimiter to be inlined, because  | 
10712  |  |   // otherwise, the constants may get reloaded each time (bad).  | 
10713  | 47.1k  |   auto has_zero_byte = [](uint64_t v) { | 
10714  | 47.1k  |     return ((v - 0x0101010101010101) & ~(v)&0x8080808080808080);  | 
10715  | 47.1k  |   };  | 
10716  | 11.3k  |   auto index_of_first_set_byte = [](uint64_t v) { | 
10717  | 5.14k  |     return ((((v - 1) & 0x101010101010101) * 0x101010101010101) >> 56) - 1;  | 
10718  | 5.14k  |   };  | 
10719  | 45.2k  |   auto broadcast = [](uint8_t v) -> uint64_t { | 
10720  | 45.2k  |     return 0x101010101010101ull * v;  | 
10721  | 45.2k  |   };  | 
10722  | 11.3k  |   size_t i = location;  | 
10723  | 11.3k  |   uint64_t mask1 = broadcast(':'); | 
10724  | 11.3k  |   uint64_t mask2 = broadcast('/'); | 
10725  | 11.3k  |   uint64_t mask4 = broadcast('?'); | 
10726  | 11.3k  |   uint64_t mask5 = broadcast('['); | 
10727  |  |   // This loop will get autovectorized under many optimizing compilers,  | 
10728  |  |   // so you get actually SIMD!  | 
10729  | 16.6k  |   for (; i + 7 < view.size(); i += 8) { | 
10730  | 8.93k  |     uint64_t word{}; | 
10731  |  |     // performance: the next memcpy translates into a single CPU instruction.  | 
10732  | 8.93k  |     memcpy(&word, view.data() + i, sizeof(word));  | 
10733  |  |     // performance: on little-endian systems (most systems), this next line is  | 
10734  |  |     // free.  | 
10735  | 8.93k  |     word = swap_bytes_if_big_endian(word);  | 
10736  | 8.93k  |     uint64_t xor1 = word ^ mask1;  | 
10737  | 8.93k  |     uint64_t xor2 = word ^ mask2;  | 
10738  | 8.93k  |     uint64_t xor4 = word ^ mask4;  | 
10739  | 8.93k  |     uint64_t xor5 = word ^ mask5;  | 
10740  | 8.93k  |     uint64_t is_match = has_zero_byte(xor1) | has_zero_byte(xor2) |  | 
10741  | 8.93k  |                         has_zero_byte(xor4) | has_zero_byte(xor5);  | 
10742  | 8.93k  |     if (is_match) { | 
10743  | 3.62k  |       return size_t(i + index_of_first_set_byte(is_match));  | 
10744  | 3.62k  |     }  | 
10745  | 8.93k  |   }  | 
10746  | 7.68k  |   if (i < view.size()) { | 
10747  | 2.85k  |     uint64_t word{}; | 
10748  |  |     // performance: the next memcpy translates into a function call, but  | 
10749  |  |     // that is difficult to avoid. Might be a bit expensive.  | 
10750  | 2.85k  |     memcpy(&word, view.data() + i, view.size() - i);  | 
10751  |  |     // performance: on little-endian systems (most systems), this next line is  | 
10752  |  |     // free.  | 
10753  | 2.85k  |     word = swap_bytes_if_big_endian(word);  | 
10754  | 2.85k  |     uint64_t xor1 = word ^ mask1;  | 
10755  | 2.85k  |     uint64_t xor2 = word ^ mask2;  | 
10756  | 2.85k  |     uint64_t xor4 = word ^ mask4;  | 
10757  | 2.85k  |     uint64_t xor5 = word ^ mask5;  | 
10758  | 2.85k  |     uint64_t is_match = has_zero_byte(xor1) | has_zero_byte(xor2) |  | 
10759  | 2.85k  |                         has_zero_byte(xor4) | has_zero_byte(xor5);  | 
10760  | 2.85k  |     if (is_match) { | 
10761  | 1.52k  |       return size_t(i + index_of_first_set_byte(is_match));  | 
10762  | 1.52k  |     }  | 
10763  | 2.85k  |   }  | 
10764  | 6.16k  |   return view.size();  | 
10765  | 7.68k  | }  | 
10766  |  |  | 
10767  |  | ada_really_inline std::pair<size_t, bool> get_host_delimiter_location(  | 
10768  | 42.5k  |     const bool is_special, std::string_view& view) noexcept { | 
10769  |  |   /**  | 
10770  |  |    * The spec at https://url.spec.whatwg.org/#hostname-state expects us to  | 
10771  |  |    * compute a variable called insideBrackets but this variable is only used  | 
10772  |  |    * once, to check whether a ':' character was found outside brackets. Exact  | 
10773  |  |    * text: "Otherwise, if c is U+003A (:) and insideBrackets is false, then:".  | 
10774  |  |    * It is conceptually simpler and arguably more efficient to just return a  | 
10775  |  |    * Boolean indicating whether ':' was found outside brackets.  | 
10776  |  |    */  | 
10777  | 42.5k  |   const size_t view_size = view.size();  | 
10778  | 42.5k  |   size_t location = 0;  | 
10779  | 42.5k  |   bool found_colon = false;  | 
10780  |  |   /**  | 
10781  |  |    * Performance analysis:  | 
10782  |  |    *  | 
10783  |  |    * We are basically seeking the end of the hostname which can be indicated  | 
10784  |  |    * by the end of the view, or by one of the characters ':', '/', '?', '\\'  | 
10785  |  |    * (where '\\' is only applicable for special URLs). However, these must  | 
10786  |  |    * appear outside a bracket range. E.g., if you have [something?]fd: then the  | 
10787  |  |    * '?' does not count.  | 
10788  |  |    *  | 
10789  |  |    * So we can skip ahead to the next delimiter, as long as we include '[' in  | 
10790  |  |    * the set of delimiters, and that we handle it first.  | 
10791  |  |    *  | 
10792  |  |    * So the trick is to have a fast function that locates the next delimiter.  | 
10793  |  |    * Unless we find '[', then it only needs to be called once! Ideally, such a  | 
10794  |  |    * function would be provided by the C++ standard library, but it seems that  | 
10795  |  |    * find_first_of is not very fast, so we are forced to roll our own.  | 
10796  |  |    *  | 
10797  |  |    * We do not break into two loops for speed, but for clarity.  | 
10798  |  |    */  | 
10799  | 42.5k  |   if (is_special) { | 
10800  |  |     // We move to the next delimiter.  | 
10801  | 34.5k  |     location = find_next_host_delimiter_special(view, location);  | 
10802  |  |     // Unless we find '[' then we are going only going to have to call  | 
10803  |  |     // find_next_host_delimiter_special once.  | 
10804  | 39.4k  |     for (; location < view_size;  | 
10805  | 34.5k  |          location = find_next_host_delimiter_special(view, location)) { | 
10806  | 10.8k  |       if (view[location] == '[') { | 
10807  | 5.24k  |         location = view.find(']', location); | 
10808  | 5.24k  |         if (location == std::string_view::npos) { | 
10809  |  |           // performance: view.find might get translated to a memchr, which  | 
10810  |  |           // has no notion of std::string_view::npos, so the code does not  | 
10811  |  |           // reflect the assembly.  | 
10812  | 308  |           location = view_size;  | 
10813  | 308  |           break;  | 
10814  | 308  |         }  | 
10815  | 5.61k  |       } else { | 
10816  | 5.61k  |         found_colon = view[location] == ':';  | 
10817  | 5.61k  |         break;  | 
10818  | 5.61k  |       }  | 
10819  | 10.8k  |     }  | 
10820  | 34.5k  |   } else { | 
10821  |  |     // We move to the next delimiter.  | 
10822  | 7.95k  |     location = find_next_host_delimiter(view, location);  | 
10823  |  |     // Unless we find '[' then we are going only going to have to call  | 
10824  |  |     // find_next_host_delimiter_special once.  | 
10825  | 11.3k  |     for (; location < view_size;  | 
10826  | 7.95k  |          location = find_next_host_delimiter(view, location)) { | 
10827  | 5.14k  |       if (view[location] == '[') { | 
10828  | 3.53k  |         location = view.find(']', location); | 
10829  | 3.53k  |         if (location == std::string_view::npos) { | 
10830  |  |           // performance: view.find might get translated to a memchr, which  | 
10831  |  |           // has no notion of std::string_view::npos, so the code does not  | 
10832  |  |           // reflect the assembly.  | 
10833  | 186  |           location = view_size;  | 
10834  | 186  |           break;  | 
10835  | 186  |         }  | 
10836  | 3.53k  |       } else { | 
10837  | 1.60k  |         found_colon = view[location] == ':';  | 
10838  | 1.60k  |         break;  | 
10839  | 1.60k  |       }  | 
10840  | 5.14k  |     }  | 
10841  | 7.95k  |   }  | 
10842  |  |   // performance: remove_suffix may translate into a single instruction.  | 
10843  | 42.5k  |   view.remove_suffix(view_size - location);  | 
10844  | 42.5k  |   return {location, found_colon}; | 
10845  | 42.5k  | }  | 
10846  |  |  | 
10847  | 59.9k  | ada_really_inline void trim_c0_whitespace(std::string_view& input) noexcept { | 
10848  | 63.2k  |   while (!input.empty() &&  | 
10849  | 63.2k  |          ada::unicode::is_c0_control_or_space(input.front())) { | 
10850  | 3.36k  |     input.remove_prefix(1);  | 
10851  | 3.36k  |   }  | 
10852  | 62.1k  |   while (!input.empty() && ada::unicode::is_c0_control_or_space(input.back())) { | 
10853  | 2.27k  |     input.remove_suffix(1);  | 
10854  | 2.27k  |   }  | 
10855  | 59.9k  | }  | 
10856  |  |  | 
10857  |  | ada_really_inline void parse_prepared_path(std::string_view input,  | 
10858  |  |                                            ada::scheme::type type,  | 
10859  | 19.0k  |                                            std::string& path) { | 
10860  | 19.0k  |   ada_log("parse_prepared_path ", input); | 
10861  | 19.0k  |   uint8_t accumulator = checkers::path_signature(input);  | 
10862  |  |   // Let us first detect a trivial case.  | 
10863  |  |   // If it is special, we check that we have no dot, no %,  no \ and no  | 
10864  |  |   // character needing percent encoding. Otherwise, we check that we have no %,  | 
10865  |  |   // no dot, and no character needing percent encoding.  | 
10866  | 19.0k  |   constexpr uint8_t need_encoding = 1;  | 
10867  | 19.0k  |   constexpr uint8_t backslash_char = 2;  | 
10868  | 19.0k  |   constexpr uint8_t dot_char = 4;  | 
10869  | 19.0k  |   constexpr uint8_t percent_char = 8;  | 
10870  | 19.0k  |   bool special = type != ada::scheme::NOT_SPECIAL;  | 
10871  | 19.0k  |   bool may_need_slow_file_handling = (type == ada::scheme::type::FILE &&  | 
10872  | 19.0k  |                                       checkers::is_windows_drive_letter(input));  | 
10873  | 19.0k  |   bool trivial_path =  | 
10874  | 19.0k  |       (special ? (accumulator == 0)  | 
10875  | 19.0k  |                : ((accumulator & (need_encoding | dot_char | percent_char)) ==  | 
10876  | 2.27k  |                   0)) &&  | 
10877  | 19.0k  |       (!may_need_slow_file_handling);  | 
10878  | 19.0k  |   if (accumulator == dot_char && !may_need_slow_file_handling) { | 
10879  |  |     // '4' means that we have at least one dot, but nothing that requires  | 
10880  |  |     // percent encoding or decoding. The only part that is not trivial is  | 
10881  |  |     // that we may have single dots and double dots path segments.  | 
10882  |  |     // If we have such segments, then we either have a path that begins  | 
10883  |  |     // with '.' (easy to check), or we have the sequence './'.  | 
10884  |  |     // Note: input cannot be empty, it must at least contain one character ('.') | 
10885  |  |     // Note: we know that '\' is not present.  | 
10886  | 2.62k  |     if (input[0] != '.') { | 
10887  | 2.04k  |       size_t slashdot = input.find("/."); | 
10888  | 2.04k  |       if (slashdot == std::string_view::npos) {  // common case | 
10889  | 1.23k  |         trivial_path = true;  | 
10890  | 1.23k  |       } else {  // uncommon | 
10891  |  |         // only three cases matter: /./, /.. or a final /  | 
10892  | 811  |         trivial_path =  | 
10893  | 811  |             !(slashdot + 2 == input.size() || input[slashdot + 2] == '.' ||  | 
10894  | 811  |               input[slashdot + 2] == '/');  | 
10895  | 811  |       }  | 
10896  | 2.04k  |     }  | 
10897  | 2.62k  |   }  | 
10898  | 19.0k  |   if (trivial_path) { | 
10899  | 8.48k  |     ada_log("parse_path trivial"); | 
10900  | 8.48k  |     path += '/';  | 
10901  | 8.48k  |     path += input;  | 
10902  | 8.48k  |     return;  | 
10903  | 8.48k  |   }  | 
10904  |  |   // We are going to need to look a bit at the path, but let us see if we can  | 
10905  |  |   // ignore percent encoding *and* backslashes *and* percent characters.  | 
10906  |  |   // Except for the trivial case, this is likely to capture 99% of paths out  | 
10907  |  |   // there.  | 
10908  | 10.5k  |   bool fast_path =  | 
10909  | 10.5k  |       (special &&  | 
10910  | 10.5k  |        (accumulator & (need_encoding | backslash_char | percent_char)) == 0) &&  | 
10911  | 10.5k  |       (type != ada::scheme::type::FILE);  | 
10912  | 10.5k  |   if (fast_path) { | 
10913  | 500  |     ada_log("parse_prepared_path fast"); | 
10914  |  |     // Here we don't need to worry about \ or percent encoding.  | 
10915  |  |     // We also do not have a file protocol. We might have dots, however,  | 
10916  |  |     // but dots must as appear as '.', and they cannot be encoded because  | 
10917  |  |     // the symbol '%' is not present.  | 
10918  | 500  |     size_t previous_location = 0;  // We start at 0.  | 
10919  | 4.89k  |     do { | 
10920  | 4.89k  |       size_t new_location = input.find('/', previous_location); | 
10921  |  |       // std::string_view path_view = input;  | 
10922  |  |       //  We process the last segment separately:  | 
10923  | 4.89k  |       if (new_location == std::string_view::npos) { | 
10924  | 500  |         std::string_view path_view = input.substr(previous_location);  | 
10925  | 500  |         if (path_view == "..") {  // The path ends with .. | 
10926  |  |           // e.g., if you receive ".." with an empty path, you go to "/".  | 
10927  | 32  |           if (path.empty()) { | 
10928  | 12  |             path = '/';  | 
10929  | 12  |             return;  | 
10930  | 12  |           }  | 
10931  |  |           // Fast case where we have nothing to do:  | 
10932  | 20  |           if (path.back() == '/') { | 
10933  | 9  |             return;  | 
10934  | 9  |           }  | 
10935  |  |           // If you have the path "/joe/myfriend",  | 
10936  |  |           // then you delete 'myfriend'.  | 
10937  | 11  |           path.resize(path.rfind('/') + 1); | 
10938  | 11  |           return;  | 
10939  | 20  |         }  | 
10940  | 468  |         path += '/';  | 
10941  | 468  |         if (path_view != ".") { | 
10942  | 323  |           path.append(path_view);  | 
10943  | 323  |         }  | 
10944  | 468  |         return;  | 
10945  | 4.39k  |       } else { | 
10946  |  |         // This is a non-final segment.  | 
10947  | 4.39k  |         std::string_view path_view =  | 
10948  | 4.39k  |             input.substr(previous_location, new_location - previous_location);  | 
10949  | 4.39k  |         previous_location = new_location + 1;  | 
10950  | 4.39k  |         if (path_view == "..") { | 
10951  | 620  |           size_t last_delimiter = path.rfind('/'); | 
10952  | 620  |           if (last_delimiter != std::string::npos) { | 
10953  | 334  |             path.erase(last_delimiter);  | 
10954  | 334  |           }  | 
10955  | 3.77k  |         } else if (path_view != ".") { | 
10956  | 3.23k  |           path += '/';  | 
10957  | 3.23k  |           path.append(path_view);  | 
10958  | 3.23k  |         }  | 
10959  | 4.39k  |       }  | 
10960  | 4.89k  |     } while (true);  | 
10961  | 10.0k  |   } else { | 
10962  | 10.0k  |     ada_log("parse_path slow"); | 
10963  |  |     // we have reached the general case  | 
10964  | 10.0k  |     bool needs_percent_encoding = (accumulator & 1);  | 
10965  | 10.0k  |     std::string path_buffer_tmp;  | 
10966  | 51.2k  |     do { | 
10967  | 51.2k  |       size_t location = (special && (accumulator & 2))  | 
10968  | 51.2k  |                             ? input.find_first_of("/\\") | 
10969  | 51.2k  |                             : input.find('/'); | 
10970  | 51.2k  |       std::string_view path_view = input;  | 
10971  | 51.2k  |       if (location != std::string_view::npos) { | 
10972  | 41.2k  |         path_view.remove_suffix(path_view.size() - location);  | 
10973  | 41.2k  |         input.remove_prefix(location + 1);  | 
10974  | 41.2k  |       }  | 
10975  |  |       // path_buffer is either path_view or it might point at a percent encoded  | 
10976  |  |       // temporary file.  | 
10977  | 51.2k  |       std::string_view path_buffer =  | 
10978  | 51.2k  |           (needs_percent_encoding &&  | 
10979  | 51.2k  |            ada::unicode::percent_encode<false>(  | 
10980  | 26.8k  |                path_view, character_sets::PATH_PERCENT_ENCODE, path_buffer_tmp))  | 
10981  | 51.2k  |               ? path_buffer_tmp  | 
10982  | 51.2k  |               : path_view;  | 
10983  | 51.2k  |       if (unicode::is_double_dot_path_segment(path_buffer)) { | 
10984  | 7.75k  |         if ((helpers::shorten_path(path, type) || special) &&  | 
10985  | 7.75k  |             location == std::string_view::npos) { | 
10986  | 623  |           path += '/';  | 
10987  | 623  |         }  | 
10988  | 43.4k  |       } else if (unicode::is_single_dot_path_segment(path_buffer) &&  | 
10989  | 43.4k  |                  (location == std::string_view::npos)) { | 
10990  | 315  |         path += '/';  | 
10991  | 315  |       }  | 
10992  |  |       // Otherwise, if path_buffer is not a single-dot path segment, then:  | 
10993  | 43.1k  |       else if (!unicode::is_single_dot_path_segment(path_buffer)) { | 
10994  |  |         // If url’s scheme is "file", url’s path is empty, and path_buffer is a  | 
10995  |  |         // Windows drive letter, then replace the second code point in  | 
10996  |  |         // path_buffer with U+003A (:).  | 
10997  | 39.3k  |         if (type == ada::scheme::type::FILE && path.empty() &&  | 
10998  | 39.3k  |             checkers::is_windows_drive_letter(path_buffer)) { | 
10999  | 2.15k  |           path += '/';  | 
11000  | 2.15k  |           path += path_buffer[0];  | 
11001  | 2.15k  |           path += ':';  | 
11002  | 2.15k  |           path_buffer.remove_prefix(2);  | 
11003  | 2.15k  |           path.append(path_buffer);  | 
11004  | 37.1k  |         } else { | 
11005  |  |           // Append path_buffer to url’s path.  | 
11006  | 37.1k  |           path += '/';  | 
11007  | 37.1k  |           path.append(path_buffer);  | 
11008  | 37.1k  |         }  | 
11009  | 39.3k  |       }  | 
11010  | 51.2k  |       if (location == std::string_view::npos) { | 
11011  | 10.0k  |         return;  | 
11012  | 10.0k  |       }  | 
11013  | 51.2k  |     } while (true);  | 
11014  | 10.0k  |   }  | 
11015  | 10.5k  | }  | 
11016  |  |  | 
11017  | 0  | bool overlaps(std::string_view input1, const std::string& input2) noexcept { | 
11018  | 0  |   ada_log("helpers::overlaps check if string_view '", input1, "' [", | 
11019  | 0  |           input1.size(), " bytes] is part of string '", input2, "' [",  | 
11020  | 0  |           input2.size(), " bytes]");  | 
11021  | 0  |   return !input1.empty() && !input2.empty() && input1.data() >= input2.data() &&  | 
11022  | 0  |          input1.data() < input2.data() + input2.size();  | 
11023  | 0  | }  | 
11024  |  |  | 
11025  |  | template <class url_type>  | 
11026  |  | ada_really_inline void strip_trailing_spaces_from_opaque_path(  | 
11027  | 23.8k  |     url_type& url) noexcept { | 
11028  | 23.8k  |   ada_log("helpers::strip_trailing_spaces_from_opaque_path"); | 
11029  | 23.8k  |   if (!url.has_opaque_path) return;  | 
11030  | 3.61k  |   if (url.has_hash()) return;  | 
11031  | 3.45k  |   if (url.has_search()) return;  | 
11032  |  |  | 
11033  | 3.45k  |   auto path = std::string(url.get_pathname());  | 
11034  | 5.19k  |   while (!path.empty() && path.back() == ' ') { | 
11035  | 1.73k  |     path.resize(path.size() - 1);  | 
11036  | 1.73k  |   }  | 
11037  | 3.45k  |   url.update_base_pathname(path);  | 
11038  | 3.45k  | } void ada::helpers::strip_trailing_spaces_from_opaque_path<ada::url>(ada::url&) Line  | Count  | Source  |  11027  | 10.4k  |     url_type& url) noexcept { |  11028  | 10.4k  |   ada_log("helpers::strip_trailing_spaces_from_opaque_path"); |  11029  | 10.4k  |   if (!url.has_opaque_path) return;  |  11030  | 1.82k  |   if (url.has_hash()) return;  |  11031  | 1.73k  |   if (url.has_search()) return;  |  11032  |  |  |  11033  | 1.73k  |   auto path = std::string(url.get_pathname());  |  11034  | 2.60k  |   while (!path.empty() && path.back() == ' ') { |  11035  | 868  |     path.resize(path.size() - 1);  |  11036  | 868  |   }  |  11037  | 1.73k  |   url.update_base_pathname(path);  |  11038  | 1.73k  | }  |  
 void ada::helpers::strip_trailing_spaces_from_opaque_path<ada::url_aggregator>(ada::url_aggregator&) Line  | Count  | Source  |  11027  | 13.3k  |     url_type& url) noexcept { |  11028  | 13.3k  |   ada_log("helpers::strip_trailing_spaces_from_opaque_path"); |  11029  | 13.3k  |   if (!url.has_opaque_path) return;  |  11030  | 1.79k  |   if (url.has_hash()) return;  |  11031  | 1.72k  |   if (url.has_search()) return;  |  11032  |  |  |  11033  | 1.72k  |   auto path = std::string(url.get_pathname());  |  11034  | 2.59k  |   while (!path.empty() && path.back() == ' ') { |  11035  | 868  |     path.resize(path.size() - 1);  |  11036  | 868  |   }  |  11037  | 1.72k  |   url.update_base_pathname(path);  |  11038  | 1.72k  | }  |  
  | 
11039  |  |  | 
11040  |  | ada_really_inline size_t  | 
11041  | 9.03k  | find_authority_delimiter_special(std::string_view view) noexcept { | 
11042  | 51.1k  |   auto has_zero_byte = [](uint64_t v) { | 
11043  | 51.1k  |     return ((v - 0x0101010101010101) & ~(v)&0x8080808080808080);  | 
11044  | 51.1k  |   };  | 
11045  | 9.03k  |   auto index_of_first_set_byte = [](uint64_t v) { | 
11046  | 8.00k  |     return ((((v - 1) & 0x101010101010101) * 0x101010101010101) >> 56) - 1;  | 
11047  | 8.00k  |   };  | 
11048  | 36.1k  |   auto broadcast = [](uint8_t v) -> uint64_t { | 
11049  | 36.1k  |     return 0x101010101010101ull * v;  | 
11050  | 36.1k  |   };  | 
11051  | 9.03k  |   size_t i = 0;  | 
11052  | 9.03k  |   uint64_t mask1 = broadcast('@'); | 
11053  | 9.03k  |   uint64_t mask2 = broadcast('/'); | 
11054  | 9.03k  |   uint64_t mask3 = broadcast('?'); | 
11055  | 9.03k  |   uint64_t mask4 = broadcast('\\'); | 
11056  |  |  | 
11057  | 13.4k  |   for (; i + 7 < view.size(); i += 8) { | 
11058  | 9.96k  |     uint64_t word{}; | 
11059  | 9.96k  |     memcpy(&word, view.data() + i, sizeof(word));  | 
11060  | 9.96k  |     word = swap_bytes_if_big_endian(word);  | 
11061  | 9.96k  |     uint64_t xor1 = word ^ mask1;  | 
11062  | 9.96k  |     uint64_t xor2 = word ^ mask2;  | 
11063  | 9.96k  |     uint64_t xor3 = word ^ mask3;  | 
11064  | 9.96k  |     uint64_t xor4 = word ^ mask4;  | 
11065  | 9.96k  |     uint64_t is_match = has_zero_byte(xor1) | has_zero_byte(xor2) |  | 
11066  | 9.96k  |                         has_zero_byte(xor3) | has_zero_byte(xor4);  | 
11067  | 9.96k  |     if (is_match) { | 
11068  | 5.57k  |       return size_t(i + index_of_first_set_byte(is_match));  | 
11069  | 5.57k  |     }  | 
11070  | 9.96k  |   }  | 
11071  |  |  | 
11072  | 3.46k  |   if (i < view.size()) { | 
11073  | 2.83k  |     uint64_t word{}; | 
11074  | 2.83k  |     memcpy(&word, view.data() + i, view.size() - i);  | 
11075  | 2.83k  |     word = swap_bytes_if_big_endian(word);  | 
11076  | 2.83k  |     uint64_t xor1 = word ^ mask1;  | 
11077  | 2.83k  |     uint64_t xor2 = word ^ mask2;  | 
11078  | 2.83k  |     uint64_t xor3 = word ^ mask3;  | 
11079  | 2.83k  |     uint64_t xor4 = word ^ mask4;  | 
11080  | 2.83k  |     uint64_t is_match = has_zero_byte(xor1) | has_zero_byte(xor2) |  | 
11081  | 2.83k  |                         has_zero_byte(xor3) | has_zero_byte(xor4);  | 
11082  | 2.83k  |     if (is_match) { | 
11083  | 2.43k  |       return size_t(i + index_of_first_set_byte(is_match));  | 
11084  | 2.43k  |     }  | 
11085  | 2.83k  |   }  | 
11086  |  |  | 
11087  | 1.03k  |   return view.size();  | 
11088  | 3.46k  | }  | 
11089  |  |  | 
11090  |  | ada_really_inline size_t  | 
11091  | 1.72k  | find_authority_delimiter(std::string_view view) noexcept { | 
11092  | 7.93k  |   auto has_zero_byte = [](uint64_t v) { | 
11093  | 7.93k  |     return ((v - 0x0101010101010101) & ~(v)&0x8080808080808080);  | 
11094  | 7.93k  |   };  | 
11095  | 1.72k  |   auto index_of_first_set_byte = [](uint64_t v) { | 
11096  | 1.54k  |     return ((((v - 1) & 0x101010101010101) * 0x101010101010101) >> 56) - 1;  | 
11097  | 1.54k  |   };  | 
11098  | 5.17k  |   auto broadcast = [](uint8_t v) -> uint64_t { | 
11099  | 5.17k  |     return 0x101010101010101ull * v;  | 
11100  | 5.17k  |   };  | 
11101  | 1.72k  |   size_t i = 0;  | 
11102  | 1.72k  |   uint64_t mask1 = broadcast('@'); | 
11103  | 1.72k  |   uint64_t mask2 = broadcast('/'); | 
11104  | 1.72k  |   uint64_t mask3 = broadcast('?'); | 
11105  |  |  | 
11106  | 2.75k  |   for (; i + 7 < view.size(); i += 8) { | 
11107  | 2.19k  |     uint64_t word{}; | 
11108  | 2.19k  |     memcpy(&word, view.data() + i, sizeof(word));  | 
11109  | 2.19k  |     word = swap_bytes_if_big_endian(word);  | 
11110  | 2.19k  |     uint64_t xor1 = word ^ mask1;  | 
11111  | 2.19k  |     uint64_t xor2 = word ^ mask2;  | 
11112  | 2.19k  |     uint64_t xor3 = word ^ mask3;  | 
11113  | 2.19k  |     uint64_t is_match =  | 
11114  | 2.19k  |         has_zero_byte(xor1) | has_zero_byte(xor2) | has_zero_byte(xor3);  | 
11115  | 2.19k  |     if (is_match) { | 
11116  | 1.16k  |       return size_t(i + index_of_first_set_byte(is_match));  | 
11117  | 1.16k  |     }  | 
11118  | 2.19k  |   }  | 
11119  |  |  | 
11120  | 564  |   if (i < view.size()) { | 
11121  | 455  |     uint64_t word{}; | 
11122  | 455  |     memcpy(&word, view.data() + i, view.size() - i);  | 
11123  | 455  |     word = swap_bytes_if_big_endian(word);  | 
11124  | 455  |     uint64_t xor1 = word ^ mask1;  | 
11125  | 455  |     uint64_t xor2 = word ^ mask2;  | 
11126  | 455  |     uint64_t xor3 = word ^ mask3;  | 
11127  | 455  |     uint64_t is_match =  | 
11128  | 455  |         has_zero_byte(xor1) | has_zero_byte(xor2) | has_zero_byte(xor3);  | 
11129  | 455  |     if (is_match) { | 
11130  | 384  |       return size_t(i + index_of_first_set_byte(is_match));  | 
11131  | 384  |     }  | 
11132  | 455  |   }  | 
11133  |  |  | 
11134  | 180  |   return view.size();  | 
11135  | 564  | }  | 
11136  |  |  | 
11137  |  | }  // namespace ada::helpers  | 
11138  |  |  | 
11139  |  | namespace ada { | 
11140  | 0  | ada_warn_unused std::string to_string(ada::state state) { | 
11141  | 0  |   return ada::helpers::get_state(state);  | 
11142  | 0  | }  | 
11143  |  | }  // namespace ada  | 
11144  |  | /* end file src/helpers.cpp */  | 
11145  |  | /* begin file src/url.cpp */  | 
11146  |  |  | 
11147  |  | #include <numeric>  | 
11148  |  | #include <algorithm>  | 
11149  |  | #include <string>  | 
11150  |  |  | 
11151  |  | namespace ada { | 
11152  |  |  | 
11153  | 1.00k  | bool url::parse_opaque_host(std::string_view input) { | 
11154  | 1.00k  |   ada_log("parse_opaque_host ", input, "[", input.size(), " bytes]"); | 
11155  | 1.00k  |   if (std::any_of(input.begin(), input.end(),  | 
11156  | 1.00k  |                   ada::unicode::is_forbidden_host_code_point)) { | 
11157  | 132  |     return is_valid = false;  | 
11158  | 132  |   }  | 
11159  |  |  | 
11160  |  |   // Return the result of running UTF-8 percent-encode on input using the C0  | 
11161  |  |   // control percent-encode set.  | 
11162  | 876  |   host = ada::unicode::percent_encode(  | 
11163  | 876  |       input, ada::character_sets::C0_CONTROL_PERCENT_ENCODE);  | 
11164  | 876  |   return true;  | 
11165  | 1.00k  | }  | 
11166  |  |  | 
11167  | 2.15k  | bool url::parse_ipv4(std::string_view input) { | 
11168  | 2.15k  |   ada_log("parse_ipv4 ", input, "[", input.size(), " bytes]"); | 
11169  | 2.15k  |   if (input.back() == '.') { | 
11170  | 34  |     input.remove_suffix(1);  | 
11171  | 34  |   }  | 
11172  | 2.15k  |   size_t digit_count{0}; | 
11173  | 2.15k  |   int pure_decimal_count = 0;  // entries that are decimal  | 
11174  | 2.15k  |   std::string_view original_input =  | 
11175  | 2.15k  |       input;  // we might use this if pure_decimal_count == 4.  | 
11176  | 2.15k  |   uint64_t ipv4{0}; | 
11177  |  |   // we could unroll for better performance?  | 
11178  | 2.67k  |   for (; (digit_count < 4) && !(input.empty()); digit_count++) { | 
11179  | 2.65k  |     uint32_t  | 
11180  | 2.65k  |         segment_result{};  // If any number exceeds 32 bits, we have an error. | 
11181  | 2.65k  |     bool is_hex = checkers::has_hex_prefix(input);  | 
11182  | 2.65k  |     if (is_hex && ((input.length() == 2) ||  | 
11183  | 691  |                    ((input.length() > 2) && (input[2] == '.')))) { | 
11184  |  |       // special case  | 
11185  | 59  |       segment_result = 0;  | 
11186  | 59  |       input.remove_prefix(2);  | 
11187  | 2.59k  |     } else { | 
11188  | 2.59k  |       std::from_chars_result r;  | 
11189  | 2.59k  |       if (is_hex) { | 
11190  | 632  |         r = std::from_chars(input.data() + 2, input.data() + input.size(),  | 
11191  | 632  |                             segment_result, 16);  | 
11192  | 1.96k  |       } else if ((input.length() >= 2) && input[0] == '0' &&  | 
11193  | 1.96k  |                  checkers::is_digit(input[1])) { | 
11194  | 347  |         r = std::from_chars(input.data() + 1, input.data() + input.size(),  | 
11195  | 347  |                             segment_result, 8);  | 
11196  | 1.61k  |       } else { | 
11197  | 1.61k  |         pure_decimal_count++;  | 
11198  | 1.61k  |         r = std::from_chars(input.data(), input.data() + input.size(),  | 
11199  | 1.61k  |                             segment_result, 10);  | 
11200  | 1.61k  |       }  | 
11201  | 2.59k  |       if (r.ec != std::errc()) { | 
11202  | 436  |         return is_valid = false;  | 
11203  | 436  |       }  | 
11204  | 2.15k  |       input.remove_prefix(r.ptr - input.data());  | 
11205  | 2.15k  |     }  | 
11206  | 2.21k  |     if (input.empty()) { | 
11207  |  |       // We have the last value.  | 
11208  |  |       // At this stage, ipv4 contains digit_count*8 bits.  | 
11209  |  |       // So we have 32-digit_count*8 bits left.  | 
11210  | 1.57k  |       if (segment_result > (uint64_t(1) << (32 - digit_count * 8))) { | 
11211  | 13  |         return is_valid = false;  | 
11212  | 13  |       }  | 
11213  | 1.55k  |       ipv4 <<= (32 - digit_count * 8);  | 
11214  | 1.55k  |       ipv4 |= segment_result;  | 
11215  | 1.55k  |       goto final;  | 
11216  | 1.57k  |     } else { | 
11217  |  |       // There is more, so that the value must no be larger than 255  | 
11218  |  |       // and we must have a '.'.  | 
11219  | 645  |       if ((segment_result > 255) || (input[0] != '.')) { | 
11220  | 123  |         return is_valid = false;  | 
11221  | 123  |       }  | 
11222  | 522  |       ipv4 <<= 8;  | 
11223  | 522  |       ipv4 |= segment_result;  | 
11224  | 522  |       input.remove_prefix(1);  // remove '.'  | 
11225  | 522  |     }  | 
11226  | 2.21k  |   }  | 
11227  | 26  |   if ((digit_count != 4) || (!input.empty())) { | 
11228  | 26  |     return is_valid = false;  | 
11229  | 26  |   }  | 
11230  | 1.55k  | final:  | 
11231  |  |   // We could also check r.ptr to see where the parsing ended.  | 
11232  | 1.55k  |   if (pure_decimal_count == 4) { | 
11233  | 43  |     host = original_input;  // The original input was already all decimal and we  | 
11234  |  |                             // validated it.  | 
11235  | 1.51k  |   } else { | 
11236  | 1.51k  |     host = ada::serializers::ipv4(ipv4);  // We have to reserialize the address.  | 
11237  | 1.51k  |   }  | 
11238  | 1.55k  |   return true;  | 
11239  | 26  | }  | 
11240  |  |  | 
11241  | 532  | bool url::parse_ipv6(std::string_view input) { | 
11242  | 532  |   ada_log("parse_ipv6 ", input, "[", input.size(), " bytes]"); | 
11243  |  |  | 
11244  | 532  |   if (input.empty()) { | 
11245  | 24  |     return is_valid = false;  | 
11246  | 24  |   }  | 
11247  |  |   // Let address be a new IPv6 address whose IPv6 pieces are all 0.  | 
11248  | 508  |   std::array<uint16_t, 8> address{}; | 
11249  |  |  | 
11250  |  |   // Let pieceIndex be 0.  | 
11251  | 508  |   int piece_index = 0;  | 
11252  |  |  | 
11253  |  |   // Let compress be null.  | 
11254  | 508  |   std::optional<int> compress{}; | 
11255  |  |  | 
11256  |  |   // Let pointer be a pointer for input.  | 
11257  | 508  |   std::string_view::iterator pointer = input.begin();  | 
11258  |  |  | 
11259  |  |   // If c is U+003A (:), then:  | 
11260  | 508  |   if (input[0] == ':') { | 
11261  |  |     // If remaining does not start with U+003A (:), validation error, return  | 
11262  |  |     // failure.  | 
11263  | 119  |     if (input.size() == 1 || input[1] != ':') { | 
11264  | 10  |       ada_log("parse_ipv6 starts with : but the rest does not start with :"); | 
11265  | 10  |       return is_valid = false;  | 
11266  | 10  |     }  | 
11267  |  |  | 
11268  |  |     // Increase pointer by 2.  | 
11269  | 109  |     pointer += 2;  | 
11270  |  |  | 
11271  |  |     // Increase pieceIndex by 1 and then set compress to pieceIndex.  | 
11272  | 109  |     compress = ++piece_index;  | 
11273  | 109  |   }  | 
11274  |  |  | 
11275  |  |   // While c is not the EOF code point:  | 
11276  | 1.41k  |   while (pointer != input.end()) { | 
11277  |  |     // If pieceIndex is 8, validation error, return failure.  | 
11278  | 1.17k  |     if (piece_index == 8) { | 
11279  | 7  |       ada_log("parse_ipv6 piece_index == 8"); | 
11280  | 7  |       return is_valid = false;  | 
11281  | 7  |     }  | 
11282  |  |  | 
11283  |  |     // If c is U+003A (:), then:  | 
11284  | 1.17k  |     if (*pointer == ':') { | 
11285  |  |       // If compress is non-null, validation error, return failure.  | 
11286  | 82  |       if (compress.has_value()) { | 
11287  | 6  |         ada_log("parse_ipv6 compress is non-null"); | 
11288  | 6  |         return is_valid = false;  | 
11289  | 6  |       }  | 
11290  |  |  | 
11291  |  |       // Increase pointer and pieceIndex by 1, set compress to pieceIndex, and  | 
11292  |  |       // then continue.  | 
11293  | 76  |       pointer++;  | 
11294  | 76  |       compress = ++piece_index;  | 
11295  | 76  |       continue;  | 
11296  | 82  |     }  | 
11297  |  |  | 
11298  |  |     // Let value and length be 0.  | 
11299  | 1.08k  |     uint16_t value = 0, length = 0;  | 
11300  |  |  | 
11301  |  |     // While length is less than 4 and c is an ASCII hex digit,  | 
11302  |  |     // set value to value × 0x10 + c interpreted as hexadecimal number, and  | 
11303  |  |     // increase pointer and length by 1.  | 
11304  | 2.84k  |     while (length < 4 && pointer != input.end() &&  | 
11305  | 2.84k  |            unicode::is_ascii_hex_digit(*pointer)) { | 
11306  |  |       // https://stackoverflow.com/questions/39060852/why-does-the-addition-of-two-shorts-return-an-int  | 
11307  | 1.75k  |       value = uint16_t(value * 0x10 + unicode::convert_hex_to_binary(*pointer));  | 
11308  | 1.75k  |       pointer++;  | 
11309  | 1.75k  |       length++;  | 
11310  | 1.75k  |     }  | 
11311  |  |  | 
11312  |  |     // If c is U+002E (.), then:  | 
11313  | 1.08k  |     if (pointer != input.end() && *pointer == '.') { | 
11314  |  |       // If length is 0, validation error, return failure.  | 
11315  | 119  |       if (length == 0) { | 
11316  | 6  |         ada_log("parse_ipv6 length is 0"); | 
11317  | 6  |         return is_valid = false;  | 
11318  | 6  |       }  | 
11319  |  |  | 
11320  |  |       // Decrease pointer by length.  | 
11321  | 113  |       pointer -= length;  | 
11322  |  |  | 
11323  |  |       // If pieceIndex is greater than 6, validation error, return failure.  | 
11324  | 113  |       if (piece_index > 6) { | 
11325  | 4  |         ada_log("parse_ipv6 piece_index > 6"); | 
11326  | 4  |         return is_valid = false;  | 
11327  | 4  |       }  | 
11328  |  |  | 
11329  |  |       // Let numbersSeen be 0.  | 
11330  | 109  |       int numbers_seen = 0;  | 
11331  |  |  | 
11332  |  |       // While c is not the EOF code point:  | 
11333  | 341  |       while (pointer != input.end()) { | 
11334  |  |         // Let ipv4Piece be null.  | 
11335  | 300  |         std::optional<uint16_t> ipv4_piece{}; | 
11336  |  |  | 
11337  |  |         // If numbersSeen is greater than 0, then:  | 
11338  | 300  |         if (numbers_seen > 0) { | 
11339  |  |           // If c is a U+002E (.) and numbersSeen is less than 4, then increase  | 
11340  |  |           // pointer by 1.  | 
11341  | 191  |           if (*pointer == '.' && numbers_seen < 4) { | 
11342  | 169  |             pointer++;  | 
11343  | 169  |           }  | 
11344  |  |           // Otherwise, validation error, return failure.  | 
11345  | 22  |           else { | 
11346  | 22  |             ada_log("parse_ipv6 Otherwise, validation error, return failure"); | 
11347  | 22  |             return is_valid = false;  | 
11348  | 22  |           }  | 
11349  | 191  |         }  | 
11350  |  |  | 
11351  |  |         // If c is not an ASCII digit, validation error, return failure.  | 
11352  | 278  |         if (pointer == input.end() || !checkers::is_digit(*pointer)) { | 
11353  | 28  |           ada_log(  | 
11354  | 28  |               "parse_ipv6 If c is not an ASCII digit, validation error, return "  | 
11355  | 28  |               "failure");  | 
11356  | 28  |           return is_valid = false;  | 
11357  | 28  |         }  | 
11358  |  |  | 
11359  |  |         // While c is an ASCII digit:  | 
11360  | 615  |         while (pointer != input.end() && checkers::is_digit(*pointer)) { | 
11361  |  |           // Let number be c interpreted as decimal number.  | 
11362  | 383  |           int number = *pointer - '0';  | 
11363  |  |  | 
11364  |  |           // If ipv4Piece is null, then set ipv4Piece to number.  | 
11365  | 383  |           if (!ipv4_piece.has_value()) { | 
11366  | 250  |             ipv4_piece = number;  | 
11367  | 250  |           }  | 
11368  |  |           // Otherwise, if ipv4Piece is 0, validation error, return failure.  | 
11369  | 133  |           else if (ipv4_piece == 0) { | 
11370  | 4  |             ada_log("parse_ipv6 if ipv4Piece is 0, validation error"); | 
11371  | 4  |             return is_valid = false;  | 
11372  | 4  |           }  | 
11373  |  |           // Otherwise, set ipv4Piece to ipv4Piece × 10 + number.  | 
11374  | 129  |           else { | 
11375  | 129  |             ipv4_piece = *ipv4_piece * 10 + number;  | 
11376  | 129  |           }  | 
11377  |  |  | 
11378  |  |           // If ipv4Piece is greater than 255, validation error, return failure.  | 
11379  | 379  |           if (ipv4_piece > 255) { | 
11380  | 14  |             ada_log("parse_ipv6 ipv4_piece > 255"); | 
11381  | 14  |             return is_valid = false;  | 
11382  | 14  |           }  | 
11383  |  |  | 
11384  |  |           // Increase pointer by 1.  | 
11385  | 365  |           pointer++;  | 
11386  | 365  |         }  | 
11387  |  |  | 
11388  |  |         // Set address[pieceIndex] to address[pieceIndex] × 0x100 + ipv4Piece.  | 
11389  |  |         // https://stackoverflow.com/questions/39060852/why-does-the-addition-of-two-shorts-return-an-int  | 
11390  | 232  |         address[piece_index] =  | 
11391  | 232  |             uint16_t(address[piece_index] * 0x100 + *ipv4_piece);  | 
11392  |  |  | 
11393  |  |         // Increase numbersSeen by 1.  | 
11394  | 232  |         numbers_seen++;  | 
11395  |  |  | 
11396  |  |         // If numbersSeen is 2 or 4, then increase pieceIndex by 1.  | 
11397  | 232  |         if (numbers_seen == 2 || numbers_seen == 4) { | 
11398  | 97  |           piece_index++;  | 
11399  | 97  |         }  | 
11400  | 232  |       }  | 
11401  |  |  | 
11402  |  |       // If numbersSeen is not 4, validation error, return failure.  | 
11403  | 41  |       if (numbers_seen != 4) { | 
11404  | 15  |         return is_valid = false;  | 
11405  | 15  |       }  | 
11406  |  |  | 
11407  |  |       // Break.  | 
11408  | 26  |       break;  | 
11409  | 41  |     }  | 
11410  |  |     // Otherwise, if c is U+003A (:):  | 
11411  | 970  |     else if ((pointer != input.end()) && (*pointer == ':')) { | 
11412  |  |       // Increase pointer by 1.  | 
11413  | 671  |       pointer++;  | 
11414  |  |  | 
11415  |  |       // If c is the EOF code point, validation error, return failure.  | 
11416  | 671  |       if (pointer == input.end()) { | 
11417  | 8  |         ada_log(  | 
11418  | 8  |             "parse_ipv6 If c is the EOF code point, validation error, return "  | 
11419  | 8  |             "failure");  | 
11420  | 8  |         return is_valid = false;  | 
11421  | 8  |       }  | 
11422  | 671  |     }  | 
11423  |  |     // Otherwise, if c is not the EOF code point, validation error, return  | 
11424  |  |     // failure.  | 
11425  | 299  |     else if (pointer != input.end()) { | 
11426  | 117  |       ada_log(  | 
11427  | 117  |           "parse_ipv6 Otherwise, if c is not the EOF code point, validation "  | 
11428  | 117  |           "error, return failure");  | 
11429  | 117  |       return is_valid = false;  | 
11430  | 117  |     }  | 
11431  |  |  | 
11432  |  |     // Set address[pieceIndex] to value.  | 
11433  | 845  |     address[piece_index] = value;  | 
11434  |  |  | 
11435  |  |     // Increase pieceIndex by 1.  | 
11436  | 845  |     piece_index++;  | 
11437  | 845  |   }  | 
11438  |  |  | 
11439  |  |   // If compress is non-null, then:  | 
11440  | 267  |   if (compress.has_value()) { | 
11441  |  |     // Let swaps be pieceIndex − compress.  | 
11442  | 167  |     int swaps = piece_index - *compress;  | 
11443  |  |  | 
11444  |  |     // Set pieceIndex to 7.  | 
11445  | 167  |     piece_index = 7;  | 
11446  |  |  | 
11447  |  |     // While pieceIndex is not 0 and swaps is greater than 0,  | 
11448  |  |     // swap address[pieceIndex] with address[compress + swaps − 1], and then  | 
11449  |  |     // decrease both pieceIndex and swaps by 1.  | 
11450  | 460  |     while (piece_index != 0 && swaps > 0) { | 
11451  | 293  |       std::swap(address[piece_index], address[*compress + swaps - 1]);  | 
11452  | 293  |       piece_index--;  | 
11453  | 293  |       swaps--;  | 
11454  | 293  |     }  | 
11455  | 167  |   }  | 
11456  |  |   // Otherwise, if compress is null and pieceIndex is not 8, validation error,  | 
11457  |  |   // return failure.  | 
11458  | 100  |   else if (piece_index != 8) { | 
11459  | 79  |     ada_log(  | 
11460  | 79  |         "parse_ipv6 if compress is null and pieceIndex is not 8, validation "  | 
11461  | 79  |         "error, return failure");  | 
11462  | 79  |     return is_valid = false;  | 
11463  | 79  |   }  | 
11464  | 188  |   host = ada::serializers::ipv6(address);  | 
11465  | 188  |   ada_log("parse_ipv6 ", *host); | 
11466  | 188  |   return true;  | 
11467  | 267  | }  | 
11468  |  |  | 
11469  |  | template <bool has_state_override>  | 
11470  | 10.5k  | ada_really_inline bool url::parse_scheme(const std::string_view input) { | 
11471  | 10.5k  |   auto parsed_type = ada::scheme::get_scheme_type(input);  | 
11472  | 10.5k  |   bool is_input_special = (parsed_type != ada::scheme::NOT_SPECIAL);  | 
11473  |  |   /**  | 
11474  |  |    * In the common case, we will immediately recognize a special scheme (e.g.,  | 
11475  |  |    *http, https), in which case, we can go really fast.  | 
11476  |  |    **/  | 
11477  | 10.5k  |   if (is_input_special) {  // fast path!!! | 
11478  | 4.56k  |     if (has_state_override) { | 
11479  |  |       // If url’s scheme is not a special scheme and buffer is a special scheme,  | 
11480  |  |       // then return.  | 
11481  | 55  |       if (is_special() != is_input_special) { | 
11482  | 1  |         return true;  | 
11483  | 1  |       }  | 
11484  |  |  | 
11485  |  |       // If url includes credentials or has a non-null port, and buffer is  | 
11486  |  |       // "file", then return.  | 
11487  | 54  |       if ((has_credentials() || port.has_value()) &&  | 
11488  | 54  |           parsed_type == ada::scheme::type::FILE) { | 
11489  | 1  |         return true;  | 
11490  | 1  |       }  | 
11491  |  |  | 
11492  |  |       // If url’s scheme is "file" and its host is an empty host, then return.  | 
11493  |  |       // An empty host is the empty string.  | 
11494  | 53  |       if (type == ada::scheme::type::FILE && host.has_value() &&  | 
11495  | 53  |           host.value().empty()) { | 
11496  | 1  |         return true;  | 
11497  | 1  |       }  | 
11498  | 53  |     }  | 
11499  |  |  | 
11500  | 4.56k  |     type = parsed_type;  | 
11501  |  |  | 
11502  | 4.56k  |     if (has_state_override) { | 
11503  |  |       // This is uncommon.  | 
11504  | 52  |       uint16_t urls_scheme_port = get_special_port();  | 
11505  |  |  | 
11506  | 52  |       if (urls_scheme_port) { | 
11507  |  |         // If url’s port is url’s scheme’s default port, then set url’s port to  | 
11508  |  |         // null.  | 
11509  | 24  |         if (port.has_value() && *port == urls_scheme_port) { | 
11510  | 1  |           port = std::nullopt;  | 
11511  | 1  |         }  | 
11512  | 24  |       }  | 
11513  | 52  |     }  | 
11514  | 6.01k  |   } else {  // slow path | 
11515  | 6.01k  |     std::string _buffer = std::string(input);  | 
11516  |  |     // Next function is only valid if the input is ASCII and returns false  | 
11517  |  |     // otherwise, but it seems that we always have ascii content so we do not  | 
11518  |  |     // need to check the return value.  | 
11519  |  |     // bool is_ascii =  | 
11520  | 6.01k  |     unicode::to_lower_ascii(_buffer.data(), _buffer.size());  | 
11521  |  |  | 
11522  | 6.01k  |     if (has_state_override) { | 
11523  |  |       // If url’s scheme is a special scheme and buffer is not a special scheme,  | 
11524  |  |       // then return. If url’s scheme is not a special scheme and buffer is a  | 
11525  |  |       // special scheme, then return.  | 
11526  | 305  |       if (is_special() != ada::scheme::is_special(_buffer)) { | 
11527  | 162  |         return true;  | 
11528  | 162  |       }  | 
11529  |  |  | 
11530  |  |       // If url includes credentials or has a non-null port, and buffer is  | 
11531  |  |       // "file", then return.  | 
11532  | 143  |       if ((has_credentials() || port.has_value()) && _buffer == "file") { | 
11533  | 1  |         return true;  | 
11534  | 1  |       }  | 
11535  |  |  | 
11536  |  |       // If url’s scheme is "file" and its host is an empty host, then return.  | 
11537  |  |       // An empty host is the empty string.  | 
11538  | 142  |       if (type == ada::scheme::type::FILE && host.has_value() &&  | 
11539  | 142  |           host.value().empty()) { | 
11540  | 1  |         return true;  | 
11541  | 1  |       }  | 
11542  | 142  |     }  | 
11543  |  |  | 
11544  | 5.85k  |     set_scheme(std::move(_buffer));  | 
11545  |  |  | 
11546  | 5.85k  |     if (has_state_override) { | 
11547  |  |       // This is uncommon.  | 
11548  | 141  |       uint16_t urls_scheme_port = get_special_port();  | 
11549  |  |  | 
11550  | 141  |       if (urls_scheme_port) { | 
11551  |  |         // If url’s port is url’s scheme’s default port, then set url’s port to  | 
11552  |  |         // null.  | 
11553  | 26  |         if (port.has_value() && *port == urls_scheme_port) { | 
11554  | 1  |           port = std::nullopt;  | 
11555  | 1  |         }  | 
11556  | 26  |       }  | 
11557  | 141  |     }  | 
11558  | 5.85k  |   }  | 
11559  |  |  | 
11560  | 10.4k  |   return true;  | 
11561  | 10.5k  | } bool ada::url::parse_scheme<true>(std::__1::basic_string_view<char, std::__1::char_traits<char> >) Line  | Count  | Source  |  11470  | 360  | ada_really_inline bool url::parse_scheme(const std::string_view input) { |  11471  | 360  |   auto parsed_type = ada::scheme::get_scheme_type(input);  |  11472  | 360  |   bool is_input_special = (parsed_type != ada::scheme::NOT_SPECIAL);  |  11473  |  |   /**  |  11474  |  |    * In the common case, we will immediately recognize a special scheme (e.g.,  |  11475  |  |    *http, https), in which case, we can go really fast.  |  11476  |  |    **/  |  11477  | 360  |   if (is_input_special) {  // fast path!!! |  11478  | 55  |     if (has_state_override) { |  11479  |  |       // If url’s scheme is not a special scheme and buffer is a special scheme,  |  11480  |  |       // then return.  |  11481  | 55  |       if (is_special() != is_input_special) { |  11482  | 1  |         return true;  |  11483  | 1  |       }  |  11484  |  |  |  11485  |  |       // If url includes credentials or has a non-null port, and buffer is  |  11486  |  |       // "file", then return.  |  11487  | 54  |       if ((has_credentials() || port.has_value()) &&  |  11488  | 54  |           parsed_type == ada::scheme::type::FILE) { |  11489  | 1  |         return true;  |  11490  | 1  |       }  |  11491  |  |  |  11492  |  |       // If url’s scheme is "file" and its host is an empty host, then return.  |  11493  |  |       // An empty host is the empty string.  |  11494  | 53  |       if (type == ada::scheme::type::FILE && host.has_value() &&  |  11495  | 53  |           host.value().empty()) { |  11496  | 1  |         return true;  |  11497  | 1  |       }  |  11498  | 53  |     }  |  11499  |  |  |  11500  | 52  |     type = parsed_type;  |  11501  |  |  |  11502  | 52  |     if (has_state_override) { |  11503  |  |       // This is uncommon.  |  11504  | 52  |       uint16_t urls_scheme_port = get_special_port();  |  11505  |  |  |  11506  | 52  |       if (urls_scheme_port) { |  11507  |  |         // If url’s port is url’s scheme’s default port, then set url’s port to  |  11508  |  |         // null.  |  11509  | 24  |         if (port.has_value() && *port == urls_scheme_port) { |  11510  | 1  |           port = std::nullopt;  |  11511  | 1  |         }  |  11512  | 24  |       }  |  11513  | 52  |     }  |  11514  | 305  |   } else {  // slow path |  11515  | 305  |     std::string _buffer = std::string(input);  |  11516  |  |     // Next function is only valid if the input is ASCII and returns false  |  11517  |  |     // otherwise, but it seems that we always have ascii content so we do not  |  11518  |  |     // need to check the return value.  |  11519  |  |     // bool is_ascii =  |  11520  | 305  |     unicode::to_lower_ascii(_buffer.data(), _buffer.size());  |  11521  |  |  |  11522  | 305  |     if (has_state_override) { |  11523  |  |       // If url’s scheme is a special scheme and buffer is not a special scheme,  |  11524  |  |       // then return. If url’s scheme is not a special scheme and buffer is a  |  11525  |  |       // special scheme, then return.  |  11526  | 305  |       if (is_special() != ada::scheme::is_special(_buffer)) { |  11527  | 162  |         return true;  |  11528  | 162  |       }  |  11529  |  |  |  11530  |  |       // If url includes credentials or has a non-null port, and buffer is  |  11531  |  |       // "file", then return.  |  11532  | 143  |       if ((has_credentials() || port.has_value()) && _buffer == "file") { |  11533  | 1  |         return true;  |  11534  | 1  |       }  |  11535  |  |  |  11536  |  |       // If url’s scheme is "file" and its host is an empty host, then return.  |  11537  |  |       // An empty host is the empty string.  |  11538  | 142  |       if (type == ada::scheme::type::FILE && host.has_value() &&  |  11539  | 142  |           host.value().empty()) { |  11540  | 1  |         return true;  |  11541  | 1  |       }  |  11542  | 142  |     }  |  11543  |  |  |  11544  | 141  |     set_scheme(std::move(_buffer));  |  11545  |  |  |  11546  | 141  |     if (has_state_override) { |  11547  |  |       // This is uncommon.  |  11548  | 141  |       uint16_t urls_scheme_port = get_special_port();  |  11549  |  |  |  11550  | 141  |       if (urls_scheme_port) { |  11551  |  |         // If url’s port is url’s scheme’s default port, then set url’s port to  |  11552  |  |         // null.  |  11553  | 26  |         if (port.has_value() && *port == urls_scheme_port) { |  11554  | 1  |           port = std::nullopt;  |  11555  | 1  |         }  |  11556  | 26  |       }  |  11557  | 141  |     }  |  11558  | 141  |   }  |  11559  |  |  |  11560  | 193  |   return true;  |  11561  | 360  | }  |  
 bool ada::url::parse_scheme<false>(std::__1::basic_string_view<char, std::__1::char_traits<char> >) Line  | Count  | Source  |  11470  | 10.2k  | ada_really_inline bool url::parse_scheme(const std::string_view input) { |  11471  | 10.2k  |   auto parsed_type = ada::scheme::get_scheme_type(input);  |  11472  | 10.2k  |   bool is_input_special = (parsed_type != ada::scheme::NOT_SPECIAL);  |  11473  |  |   /**  |  11474  |  |    * In the common case, we will immediately recognize a special scheme (e.g.,  |  11475  |  |    *http, https), in which case, we can go really fast.  |  11476  |  |    **/  |  11477  | 10.2k  |   if (is_input_special) {  // fast path!!! |  11478  | 4.51k  |     if (has_state_override) { |  11479  |  |       // If url’s scheme is not a special scheme and buffer is a special scheme,  |  11480  |  |       // then return.  |  11481  | 0  |       if (is_special() != is_input_special) { |  11482  | 0  |         return true;  |  11483  | 0  |       }  |  11484  |  |  |  11485  |  |       // If url includes credentials or has a non-null port, and buffer is  |  11486  |  |       // "file", then return.  |  11487  | 0  |       if ((has_credentials() || port.has_value()) &&  |  11488  | 0  |           parsed_type == ada::scheme::type::FILE) { |  11489  | 0  |         return true;  |  11490  | 0  |       }  |  11491  |  |  |  11492  |  |       // If url’s scheme is "file" and its host is an empty host, then return.  |  11493  |  |       // An empty host is the empty string.  |  11494  | 0  |       if (type == ada::scheme::type::FILE && host.has_value() &&  |  11495  | 0  |           host.value().empty()) { |  11496  | 0  |         return true;  |  11497  | 0  |       }  |  11498  | 0  |     }  |  11499  |  |  |  11500  | 4.51k  |     type = parsed_type;  |  11501  |  |  |  11502  | 4.51k  |     if (has_state_override) { |  11503  |  |       // This is uncommon.  |  11504  | 0  |       uint16_t urls_scheme_port = get_special_port();  |  11505  |  | 
  |  11506  | 0  |       if (urls_scheme_port) { |  11507  |  |         // If url’s port is url’s scheme’s default port, then set url’s port to  |  11508  |  |         // null.  |  11509  | 0  |         if (port.has_value() && *port == urls_scheme_port) { |  11510  | 0  |           port = std::nullopt;  |  11511  | 0  |         }  |  11512  | 0  |       }  |  11513  | 0  |     }  |  11514  | 5.71k  |   } else {  // slow path |  11515  | 5.71k  |     std::string _buffer = std::string(input);  |  11516  |  |     // Next function is only valid if the input is ASCII and returns false  |  11517  |  |     // otherwise, but it seems that we always have ascii content so we do not  |  11518  |  |     // need to check the return value.  |  11519  |  |     // bool is_ascii =  |  11520  | 5.71k  |     unicode::to_lower_ascii(_buffer.data(), _buffer.size());  |  11521  |  |  |  11522  | 5.71k  |     if (has_state_override) { |  11523  |  |       // If url’s scheme is a special scheme and buffer is not a special scheme,  |  11524  |  |       // then return. If url’s scheme is not a special scheme and buffer is a  |  11525  |  |       // special scheme, then return.  |  11526  | 0  |       if (is_special() != ada::scheme::is_special(_buffer)) { |  11527  | 0  |         return true;  |  11528  | 0  |       }  |  11529  |  |  |  11530  |  |       // If url includes credentials or has a non-null port, and buffer is  |  11531  |  |       // "file", then return.  |  11532  | 0  |       if ((has_credentials() || port.has_value()) && _buffer == "file") { |  11533  | 0  |         return true;  |  11534  | 0  |       }  |  11535  |  |  |  11536  |  |       // If url’s scheme is "file" and its host is an empty host, then return.  |  11537  |  |       // An empty host is the empty string.  |  11538  | 0  |       if (type == ada::scheme::type::FILE && host.has_value() &&  |  11539  | 0  |           host.value().empty()) { |  11540  | 0  |         return true;  |  11541  | 0  |       }  |  11542  | 0  |     }  |  11543  |  |  |  11544  | 5.71k  |     set_scheme(std::move(_buffer));  |  11545  |  |  |  11546  | 5.71k  |     if (has_state_override) { |  11547  |  |       // This is uncommon.  |  11548  | 0  |       uint16_t urls_scheme_port = get_special_port();  |  11549  |  | 
  |  11550  | 0  |       if (urls_scheme_port) { |  11551  |  |         // If url’s port is url’s scheme’s default port, then set url’s port to  |  11552  |  |         // null.  |  11553  | 0  |         if (port.has_value() && *port == urls_scheme_port) { |  11554  | 0  |           port = std::nullopt;  |  11555  | 0  |         }  |  11556  | 0  |       }  |  11557  | 0  |     }  |  11558  | 5.71k  |   }  |  11559  |  |  |  11560  | 10.2k  |   return true;  |  11561  | 10.2k  | }  |  
  | 
11562  |  |  | 
11563  | 10.1k  | ada_really_inline bool url::parse_host(std::string_view input) { | 
11564  | 10.1k  |   ada_log("parse_host ", input, "[", input.size(), " bytes]"); | 
11565  | 10.1k  |   if (input.empty()) { | 
11566  | 13  |     return is_valid = false;  | 
11567  | 13  |   }  // technically unnecessary.  | 
11568  |  |   // If input starts with U+005B ([), then:  | 
11569  | 10.1k  |   if (input[0] == '[') { | 
11570  |  |     // If input does not end with U+005D (]), validation error, return failure.  | 
11571  | 786  |     if (input.back() != ']') { | 
11572  | 254  |       return is_valid = false;  | 
11573  | 254  |     }  | 
11574  | 532  |     ada_log("parse_host ipv6"); | 
11575  |  |  | 
11576  |  |     // Return the result of IPv6 parsing input with its leading U+005B ([) and  | 
11577  |  |     // trailing U+005D (]) removed.  | 
11578  | 532  |     input.remove_prefix(1);  | 
11579  | 532  |     input.remove_suffix(1);  | 
11580  | 532  |     return parse_ipv6(input);  | 
11581  | 786  |   }  | 
11582  |  |  | 
11583  |  |   // If isNotSpecial is true, then return the result of opaque-host parsing  | 
11584  |  |   // input.  | 
11585  | 9.36k  |   if (!is_special()) { | 
11586  | 1.00k  |     return parse_opaque_host(input);  | 
11587  | 1.00k  |   }  | 
11588  |  |   // Let domain be the result of running UTF-8 decode without BOM on the  | 
11589  |  |   // percent-decoding of input. Let asciiDomain be the result of running domain  | 
11590  |  |   // to ASCII with domain and false. The most common case is an ASCII input, in  | 
11591  |  |   // which case we do not need to call the expensive 'to_ascii' if a few  | 
11592  |  |   // conditions are met: no '%' and no 'xn-' subsequence.  | 
11593  | 8.35k  |   std::string buffer = std::string(input);  | 
11594  |  |   // This next function checks that the result is ascii, but we are going to  | 
11595  |  |   // to check anyhow with is_forbidden.  | 
11596  |  |   // bool is_ascii =  | 
11597  | 8.35k  |   unicode::to_lower_ascii(buffer.data(), buffer.size());  | 
11598  | 8.35k  |   bool is_forbidden = unicode::contains_forbidden_domain_code_point(  | 
11599  | 8.35k  |       buffer.data(), buffer.size());  | 
11600  | 8.35k  |   if (is_forbidden == 0 && buffer.find("xn-") == std::string_view::npos) { | 
11601  |  |     // fast path  | 
11602  | 5.18k  |     host = std::move(buffer);  | 
11603  | 5.18k  |     if (checkers::is_ipv4(host.value())) { | 
11604  | 1.93k  |       ada_log("parse_host fast path ipv4"); | 
11605  | 1.93k  |       return parse_ipv4(host.value());  | 
11606  | 1.93k  |     }  | 
11607  | 3.25k  |     ada_log("parse_host fast path ", *host); | 
11608  | 3.25k  |     return true;  | 
11609  | 5.18k  |   }  | 
11610  | 3.17k  |   ada_log("parse_host calling to_ascii"); | 
11611  | 3.17k  |   is_valid = ada::unicode::to_ascii(host, input, input.find('%')); | 
11612  | 3.17k  |   if (!is_valid) { | 
11613  | 1.56k  |     ada_log("parse_host to_ascii returns false"); | 
11614  | 1.56k  |     return is_valid = false;  | 
11615  | 1.56k  |   }  | 
11616  |  |  | 
11617  | 1.61k  |   if (std::any_of(host.value().begin(), host.value().end(),  | 
11618  | 1.61k  |                   ada::unicode::is_forbidden_domain_code_point)) { | 
11619  | 0  |     host = std::nullopt;  | 
11620  | 0  |     return is_valid = false;  | 
11621  | 0  |   }  | 
11622  |  |  | 
11623  |  |   // If asciiDomain ends in a number, then return the result of IPv4 parsing  | 
11624  |  |   // asciiDomain.  | 
11625  | 1.61k  |   if (checkers::is_ipv4(host.value())) { | 
11626  | 226  |     ada_log("parse_host got ipv4", *host); | 
11627  | 226  |     return parse_ipv4(host.value());  | 
11628  | 226  |   }  | 
11629  |  |  | 
11630  | 1.38k  |   return true;  | 
11631  | 1.61k  | }  | 
11632  |  |  | 
11633  | 7.20k  | ada_really_inline void url::parse_path(std::string_view input) { | 
11634  | 7.20k  |   ada_log("parse_path ", input); | 
11635  | 7.20k  |   std::string tmp_buffer;  | 
11636  | 7.20k  |   std::string_view internal_input;  | 
11637  | 7.20k  |   if (unicode::has_tabs_or_newline(input)) { | 
11638  | 103  |     tmp_buffer = input;  | 
11639  |  |     // Optimization opportunity: Instead of copying and then pruning, we could  | 
11640  |  |     // just directly build the string from user_input.  | 
11641  | 103  |     helpers::remove_ascii_tab_or_newline(tmp_buffer);  | 
11642  | 103  |     internal_input = tmp_buffer;  | 
11643  | 7.10k  |   } else { | 
11644  | 7.10k  |     internal_input = input;  | 
11645  | 7.10k  |   }  | 
11646  |  |  | 
11647  |  |   // If url is special, then:  | 
11648  | 7.20k  |   if (is_special()) { | 
11649  | 5.52k  |     if (internal_input.empty()) { | 
11650  | 3.45k  |       path = "/";  | 
11651  | 3.45k  |     } else if ((internal_input[0] == '/') || (internal_input[0] == '\\')) { | 
11652  | 530  |       helpers::parse_prepared_path(internal_input.substr(1), type, path);  | 
11653  | 530  |       return;  | 
11654  | 1.53k  |     } else { | 
11655  | 1.53k  |       helpers::parse_prepared_path(internal_input, type, path);  | 
11656  | 1.53k  |       return;  | 
11657  | 1.53k  |     }  | 
11658  | 5.52k  |   } else if (!internal_input.empty()) { | 
11659  | 767  |     if (internal_input[0] == '/') { | 
11660  | 252  |       helpers::parse_prepared_path(internal_input.substr(1), type, path);  | 
11661  | 252  |       return;  | 
11662  | 515  |     } else { | 
11663  | 515  |       helpers::parse_prepared_path(internal_input, type, path);  | 
11664  | 515  |       return;  | 
11665  | 515  |     }  | 
11666  | 913  |   } else { | 
11667  | 913  |     if (!host.has_value()) { | 
11668  | 0  |       path = "/";  | 
11669  | 0  |     }  | 
11670  | 913  |   }  | 
11671  | 4.37k  |   return;  | 
11672  | 7.20k  | }  | 
11673  |  |  | 
11674  | 0  | std::string url::to_string() const { | 
11675  | 0  |   if (!is_valid) { | 
11676  | 0  |     return "null";  | 
11677  | 0  |   }  | 
11678  | 0  |   std::string answer;  | 
11679  | 0  |   auto back = std::back_insert_iterator(answer);  | 
11680  | 0  |   answer.append("{\n"); | 
11681  | 0  |   answer.append("\t\"protocol\":\""); | 
11682  | 0  |   helpers::encode_json(get_protocol(), back);  | 
11683  | 0  |   answer.append("\",\n"); | 
11684  | 0  |   if (has_credentials()) { | 
11685  | 0  |     answer.append("\t\"username\":\""); | 
11686  | 0  |     helpers::encode_json(username, back);  | 
11687  | 0  |     answer.append("\",\n"); | 
11688  | 0  |     answer.append("\t\"password\":\""); | 
11689  | 0  |     helpers::encode_json(password, back);  | 
11690  | 0  |     answer.append("\",\n"); | 
11691  | 0  |   }  | 
11692  | 0  |   if (host.has_value()) { | 
11693  | 0  |     answer.append("\t\"host\":\""); | 
11694  | 0  |     helpers::encode_json(host.value(), back);  | 
11695  | 0  |     answer.append("\",\n"); | 
11696  | 0  |   }  | 
11697  | 0  |   if (port.has_value()) { | 
11698  | 0  |     answer.append("\t\"port\":\""); | 
11699  | 0  |     answer.append(std::to_string(port.value()));  | 
11700  | 0  |     answer.append("\",\n"); | 
11701  | 0  |   }  | 
11702  | 0  |   answer.append("\t\"path\":\""); | 
11703  | 0  |   helpers::encode_json(path, back);  | 
11704  | 0  |   answer.append("\",\n"); | 
11705  | 0  |   answer.append("\t\"opaque path\":"); | 
11706  | 0  |   answer.append((has_opaque_path ? "true" : "false"));  | 
11707  | 0  |   if (has_search()) { | 
11708  | 0  |     answer.append(",\n"); | 
11709  | 0  |     answer.append("\t\"query\":\""); | 
11710  | 0  |     helpers::encode_json(query.value(), back);  | 
11711  | 0  |     answer.append("\""); | 
11712  | 0  |   }  | 
11713  | 0  |   if (hash.has_value()) { | 
11714  | 0  |     answer.append(",\n"); | 
11715  | 0  |     answer.append("\t\"hash\":\""); | 
11716  | 0  |     helpers::encode_json(hash.value(), back);  | 
11717  | 0  |     answer.append("\""); | 
11718  | 0  |   }  | 
11719  | 0  |   answer.append("\n}"); | 
11720  | 0  |   return answer;  | 
11721  | 0  | }  | 
11722  |  |  | 
11723  | 0  | [[nodiscard]] bool url::has_valid_domain() const noexcept { | 
11724  | 0  |   if (!host.has_value()) { | 
11725  | 0  |     return false;  | 
11726  | 0  |   }  | 
11727  | 0  |   return checkers::verify_dns_length(host.value());  | 
11728  | 0  | }  | 
11729  |  |  | 
11730  |  | }  // namespace ada  | 
11731  |  | /* end file src/url.cpp */  | 
11732  |  | /* begin file src/url-getters.cpp */  | 
11733  |  | /**  | 
11734  |  |  * @file url-getters.cpp  | 
11735  |  |  * Includes all the getters of `ada::url`  | 
11736  |  |  */  | 
11737  |  |  | 
11738  |  | #include <algorithm>  | 
11739  |  | #include <string>  | 
11740  |  |  | 
11741  |  | namespace ada { | 
11742  | 8.27k  | [[nodiscard]] std::string url::get_origin() const noexcept { | 
11743  | 8.27k  |   if (is_special()) { | 
11744  |  |     // Return a new opaque origin.  | 
11745  | 5.52k  |     if (type == scheme::FILE) { | 
11746  | 1.48k  |       return "null";  | 
11747  | 1.48k  |     }  | 
11748  | 4.03k  |     return ada::helpers::concat(get_protocol(), "//", get_host());  | 
11749  | 5.52k  |   }  | 
11750  |  |  | 
11751  | 2.74k  |   if (non_special_scheme == "blob") { | 
11752  | 398  |     if (!path.empty()) { | 
11753  | 385  |       auto result = ada::parse<ada::url>(path);  | 
11754  | 385  |       if (result &&  | 
11755  | 385  |           (result->type == scheme::HTTP || result->type == scheme::HTTPS)) { | 
11756  |  |         // If pathURL’s scheme is not "http" and not "https", then return a  | 
11757  |  |         // new opaque origin.  | 
11758  | 10  |         return ada::helpers::concat(result->get_protocol(), "//",  | 
11759  | 10  |                                     result->get_host());  | 
11760  | 10  |       }  | 
11761  | 385  |     }  | 
11762  | 398  |   }  | 
11763  |  |  | 
11764  |  |   // Return a new opaque origin.  | 
11765  | 2.73k  |   return "null";  | 
11766  | 2.74k  | }  | 
11767  |  |  | 
11768  | 12.3k  | [[nodiscard]] std::string url::get_protocol() const noexcept { | 
11769  | 12.3k  |   if (is_special()) { | 
11770  | 9.57k  |     return helpers::concat(ada::scheme::details::is_special_list[type], ":");  | 
11771  | 9.57k  |   }  | 
11772  |  |   // We only move the 'scheme' if it is non-special.  | 
11773  | 2.74k  |   return helpers::concat(non_special_scheme, ":");  | 
11774  | 12.3k  | }  | 
11775  |  |  | 
11776  | 12.3k  | [[nodiscard]] std::string url::get_host() const noexcept { | 
11777  |  |   // If url’s host is null, then return the empty string.  | 
11778  |  |   // If url’s port is null, return url’s host, serialized.  | 
11779  |  |   // Return url’s host, serialized, followed by U+003A (:) and url’s port,  | 
11780  |  |   // serialized.  | 
11781  | 12.3k  |   if (!host.has_value()) { | 
11782  | 1.21k  |     return "";  | 
11783  | 1.21k  |   }  | 
11784  | 11.1k  |   if (port.has_value()) { | 
11785  | 467  |     return host.value() + ":" + get_port();  | 
11786  | 467  |   }  | 
11787  | 10.6k  |   return host.value();  | 
11788  | 11.1k  | }  | 
11789  |  |  | 
11790  | 8.27k  | [[nodiscard]] std::string url::get_hostname() const noexcept { | 
11791  | 8.27k  |   return host.value_or(""); | 
11792  | 8.27k  | }  | 
11793  |  |  | 
11794  | 10.0k  | [[nodiscard]] const std::string_view url::get_pathname() const noexcept { | 
11795  | 10.0k  |   return path;  | 
11796  | 10.0k  | }  | 
11797  |  |  | 
11798  | 8.27k  | [[nodiscard]] std::string url::get_search() const noexcept { | 
11799  |  |   // If this’s URL’s query is either null or the empty string, then return the  | 
11800  |  |   // empty string. Return U+003F (?), followed by this’s URL’s query.  | 
11801  | 8.27k  |   return (!query.has_value() || (query.value().empty())) ? ""  | 
11802  | 8.27k  |                                                          : "?" + query.value();  | 
11803  | 8.27k  | }  | 
11804  |  |  | 
11805  | 8.27k  | [[nodiscard]] const std::string& url::get_username() const noexcept { | 
11806  | 8.27k  |   return username;  | 
11807  | 8.27k  | }  | 
11808  |  |  | 
11809  | 8.27k  | [[nodiscard]] const std::string& url::get_password() const noexcept { | 
11810  | 8.27k  |   return password;  | 
11811  | 8.27k  | }  | 
11812  |  |  | 
11813  | 8.73k  | [[nodiscard]] std::string url::get_port() const noexcept { | 
11814  | 8.73k  |   return port.has_value() ? std::to_string(port.value()) : "";  | 
11815  | 8.73k  | }  | 
11816  |  |  | 
11817  | 8.27k  | [[nodiscard]] std::string url::get_hash() const noexcept { | 
11818  |  |   // If this’s URL’s fragment is either null or the empty string, then return  | 
11819  |  |   // the empty string. Return U+0023 (#), followed by this’s URL’s fragment.  | 
11820  | 8.27k  |   return (!hash.has_value() || (hash.value().empty())) ? ""  | 
11821  | 8.27k  |                                                        : "#" + hash.value();  | 
11822  | 8.27k  | }  | 
11823  |  |  | 
11824  |  | }  // namespace ada  | 
11825  |  | /* end file src/url-getters.cpp */  | 
11826  |  | /* begin file src/url-setters.cpp */  | 
11827  |  | /**  | 
11828  |  |  * @file url-setters.cpp  | 
11829  |  |  * Includes all the setters of `ada::url`  | 
11830  |  |  */  | 
11831  |  |  | 
11832  |  | #include <optional>  | 
11833  |  | #include <string>  | 
11834  |  |  | 
11835  |  | namespace ada { | 
11836  |  |  | 
11837  |  | template <bool override_hostname>  | 
11838  | 16.5k  | bool url::set_host_or_hostname(const std::string_view input) { | 
11839  | 16.5k  |   if (has_opaque_path) { | 
11840  | 2.13k  |     return false;  | 
11841  | 2.13k  |   }  | 
11842  |  |  | 
11843  | 14.4k  |   std::optional<std::string> previous_host = host;  | 
11844  | 14.4k  |   std::optional<uint16_t> previous_port = port;  | 
11845  |  |  | 
11846  | 14.4k  |   size_t host_end_pos = input.find('#'); | 
11847  | 14.4k  |   std::string _host(input.data(), host_end_pos != std::string_view::npos  | 
11848  | 14.4k  |                                       ? host_end_pos  | 
11849  | 14.4k  |                                       : input.size());  | 
11850  | 14.4k  |   helpers::remove_ascii_tab_or_newline(_host);  | 
11851  | 14.4k  |   std::string_view new_host(_host);  | 
11852  |  |  | 
11853  |  |   // If url's scheme is "file", then set state to file host state, instead of  | 
11854  |  |   // host state.  | 
11855  | 14.4k  |   if (type != ada::scheme::type::FILE) { | 
11856  | 11.4k  |     std::string_view host_view(_host.data(), _host.length());  | 
11857  | 11.4k  |     auto [location, found_colon] =  | 
11858  | 11.4k  |         helpers::get_host_delimiter_location(is_special(), host_view);  | 
11859  |  |  | 
11860  |  |     // Otherwise, if c is U+003A (:) and insideBrackets is false, then:  | 
11861  |  |     // Note: the 'found_colon' value is true if and only if a colon was  | 
11862  |  |     // encountered while not inside brackets.  | 
11863  | 11.4k  |     if (found_colon) { | 
11864  | 222  |       if (override_hostname) { | 
11865  | 111  |         return false;  | 
11866  | 111  |       }  | 
11867  | 111  |       std::string_view buffer = new_host.substr(location + 1);  | 
11868  | 111  |       if (!buffer.empty()) { | 
11869  | 99  |         set_port(buffer);  | 
11870  | 99  |       }  | 
11871  | 111  |     }  | 
11872  |  |     // If url is special and host_view is the empty string, validation error,  | 
11873  |  |     // return failure. Otherwise, if state override is given, host_view is the  | 
11874  |  |     // empty string, and either url includes credentials or url’s port is  | 
11875  |  |     // non-null, return.  | 
11876  | 11.2k  |     else if (host_view.empty() &&  | 
11877  | 11.2k  |              (is_special() || has_credentials() || port.has_value())) { | 
11878  | 6.09k  |       return false;  | 
11879  | 6.09k  |     }  | 
11880  |  |  | 
11881  |  |     // Let host be the result of host parsing host_view with url is not special.  | 
11882  | 5.22k  |     if (host_view.empty()) { | 
11883  | 2.23k  |       host = "";  | 
11884  | 2.23k  |       return true;  | 
11885  | 2.23k  |     }  | 
11886  |  |  | 
11887  | 2.99k  |     bool succeeded = parse_host(host_view);  | 
11888  | 2.99k  |     if (!succeeded) { | 
11889  | 1.05k  |       host = previous_host;  | 
11890  | 1.05k  |       update_base_port(previous_port);  | 
11891  | 1.05k  |     }  | 
11892  | 2.99k  |     return succeeded;  | 
11893  | 5.22k  |   }  | 
11894  |  |  | 
11895  | 2.97k  |   size_t location = new_host.find_first_of("/\\?"); | 
11896  | 2.97k  |   if (location != std::string_view::npos) { | 
11897  | 592  |     new_host.remove_suffix(new_host.length() - location);  | 
11898  | 592  |   }  | 
11899  |  |  | 
11900  | 2.97k  |   if (new_host.empty()) { | 
11901  |  |     // Set url’s host to the empty string.  | 
11902  | 2.03k  |     host = "";  | 
11903  | 2.03k  |   } else { | 
11904  |  |     // Let host be the result of host parsing buffer with url is not special.  | 
11905  | 944  |     if (!parse_host(new_host)) { | 
11906  | 386  |       host = previous_host;  | 
11907  | 386  |       update_base_port(previous_port);  | 
11908  | 386  |       return false;  | 
11909  | 386  |     }  | 
11910  |  |  | 
11911  |  |     // If host is "localhost", then set host to the empty string.  | 
11912  | 558  |     if (host.has_value() && host.value() == "localhost") { | 
11913  | 2  |       host = "";  | 
11914  | 2  |     }  | 
11915  | 558  |   }  | 
11916  | 2.58k  |   return true;  | 
11917  | 2.97k  | } bool ada::url::set_host_or_hostname<false>(std::__1::basic_string_view<char, std::__1::char_traits<char> >) Line  | Count  | Source  |  11838  | 8.27k  | bool url::set_host_or_hostname(const std::string_view input) { |  11839  | 8.27k  |   if (has_opaque_path) { |  11840  | 1.06k  |     return false;  |  11841  | 1.06k  |   }  |  11842  |  |  |  11843  | 7.20k  |   std::optional<std::string> previous_host = host;  |  11844  | 7.20k  |   std::optional<uint16_t> previous_port = port;  |  11845  |  |  |  11846  | 7.20k  |   size_t host_end_pos = input.find('#'); |  11847  | 7.20k  |   std::string _host(input.data(), host_end_pos != std::string_view::npos  |  11848  | 7.20k  |                                       ? host_end_pos  |  11849  | 7.20k  |                                       : input.size());  |  11850  | 7.20k  |   helpers::remove_ascii_tab_or_newline(_host);  |  11851  | 7.20k  |   std::string_view new_host(_host);  |  11852  |  |  |  11853  |  |   // If url's scheme is "file", then set state to file host state, instead of  |  11854  |  |   // host state.  |  11855  | 7.20k  |   if (type != ada::scheme::type::FILE) { |  11856  | 5.71k  |     std::string_view host_view(_host.data(), _host.length());  |  11857  | 5.71k  |     auto [location, found_colon] =  |  11858  | 5.71k  |         helpers::get_host_delimiter_location(is_special(), host_view);  |  11859  |  |  |  11860  |  |     // Otherwise, if c is U+003A (:) and insideBrackets is false, then:  |  11861  |  |     // Note: the 'found_colon' value is true if and only if a colon was  |  11862  |  |     // encountered while not inside brackets.  |  11863  | 5.71k  |     if (found_colon) { |  11864  | 111  |       if (override_hostname) { |  11865  | 0  |         return false;  |  11866  | 0  |       }  |  11867  | 111  |       std::string_view buffer = new_host.substr(location + 1);  |  11868  | 111  |       if (!buffer.empty()) { |  11869  | 99  |         set_port(buffer);  |  11870  | 99  |       }  |  11871  | 111  |     }  |  11872  |  |     // If url is special and host_view is the empty string, validation error,  |  11873  |  |     // return failure. Otherwise, if state override is given, host_view is the  |  11874  |  |     // empty string, and either url includes credentials or url’s port is  |  11875  |  |     // non-null, return.  |  11876  | 5.60k  |     else if (host_view.empty() &&  |  11877  | 5.60k  |              (is_special() || has_credentials() || port.has_value())) { |  11878  | 3.04k  |       return false;  |  11879  | 3.04k  |     }  |  11880  |  |  |  11881  |  |     // Let host be the result of host parsing host_view with url is not special.  |  11882  | 2.67k  |     if (host_view.empty()) { |  11883  | 1.13k  |       host = "";  |  11884  | 1.13k  |       return true;  |  11885  | 1.13k  |     }  |  11886  |  |  |  11887  | 1.53k  |     bool succeeded = parse_host(host_view);  |  11888  | 1.53k  |     if (!succeeded) { |  11889  | 538  |       host = previous_host;  |  11890  | 538  |       update_base_port(previous_port);  |  11891  | 538  |     }  |  11892  | 1.53k  |     return succeeded;  |  11893  | 2.67k  |   }  |  11894  |  |  |  11895  | 1.48k  |   size_t location = new_host.find_first_of("/\\?"); |  11896  | 1.48k  |   if (location != std::string_view::npos) { |  11897  | 296  |     new_host.remove_suffix(new_host.length() - location);  |  11898  | 296  |   }  |  11899  |  |  |  11900  | 1.48k  |   if (new_host.empty()) { |  11901  |  |     // Set url’s host to the empty string.  |  11902  | 1.01k  |     host = "";  |  11903  | 1.01k  |   } else { |  11904  |  |     // Let host be the result of host parsing buffer with url is not special.  |  11905  | 472  |     if (!parse_host(new_host)) { |  11906  | 193  |       host = previous_host;  |  11907  | 193  |       update_base_port(previous_port);  |  11908  | 193  |       return false;  |  11909  | 193  |     }  |  11910  |  |  |  11911  |  |     // If host is "localhost", then set host to the empty string.  |  11912  | 279  |     if (host.has_value() && host.value() == "localhost") { |  11913  | 1  |       host = "";  |  11914  | 1  |     }  |  11915  | 279  |   }  |  11916  | 1.29k  |   return true;  |  11917  | 1.48k  | }  |  
 bool ada::url::set_host_or_hostname<true>(std::__1::basic_string_view<char, std::__1::char_traits<char> >) Line  | Count  | Source  |  11838  | 8.27k  | bool url::set_host_or_hostname(const std::string_view input) { |  11839  | 8.27k  |   if (has_opaque_path) { |  11840  | 1.06k  |     return false;  |  11841  | 1.06k  |   }  |  11842  |  |  |  11843  | 7.20k  |   std::optional<std::string> previous_host = host;  |  11844  | 7.20k  |   std::optional<uint16_t> previous_port = port;  |  11845  |  |  |  11846  | 7.20k  |   size_t host_end_pos = input.find('#'); |  11847  | 7.20k  |   std::string _host(input.data(), host_end_pos != std::string_view::npos  |  11848  | 7.20k  |                                       ? host_end_pos  |  11849  | 7.20k  |                                       : input.size());  |  11850  | 7.20k  |   helpers::remove_ascii_tab_or_newline(_host);  |  11851  | 7.20k  |   std::string_view new_host(_host);  |  11852  |  |  |  11853  |  |   // If url's scheme is "file", then set state to file host state, instead of  |  11854  |  |   // host state.  |  11855  | 7.20k  |   if (type != ada::scheme::type::FILE) { |  11856  | 5.71k  |     std::string_view host_view(_host.data(), _host.length());  |  11857  | 5.71k  |     auto [location, found_colon] =  |  11858  | 5.71k  |         helpers::get_host_delimiter_location(is_special(), host_view);  |  11859  |  |  |  11860  |  |     // Otherwise, if c is U+003A (:) and insideBrackets is false, then:  |  11861  |  |     // Note: the 'found_colon' value is true if and only if a colon was  |  11862  |  |     // encountered while not inside brackets.  |  11863  | 5.71k  |     if (found_colon) { |  11864  | 111  |       if (override_hostname) { |  11865  | 111  |         return false;  |  11866  | 111  |       }  |  11867  | 0  |       std::string_view buffer = new_host.substr(location + 1);  |  11868  | 0  |       if (!buffer.empty()) { |  11869  | 0  |         set_port(buffer);  |  11870  | 0  |       }  |  11871  | 0  |     }  |  11872  |  |     // If url is special and host_view is the empty string, validation error,  |  11873  |  |     // return failure. Otherwise, if state override is given, host_view is the  |  11874  |  |     // empty string, and either url includes credentials or url’s port is  |  11875  |  |     // non-null, return.  |  11876  | 5.60k  |     else if (host_view.empty() &&  |  11877  | 5.60k  |              (is_special() || has_credentials() || port.has_value())) { |  11878  | 3.04k  |       return false;  |  11879  | 3.04k  |     }  |  11880  |  |  |  11881  |  |     // Let host be the result of host parsing host_view with url is not special.  |  11882  | 2.55k  |     if (host_view.empty()) { |  11883  | 1.09k  |       host = "";  |  11884  | 1.09k  |       return true;  |  11885  | 1.09k  |     }  |  11886  |  |  |  11887  | 1.46k  |     bool succeeded = parse_host(host_view);  |  11888  | 1.46k  |     if (!succeeded) { |  11889  | 519  |       host = previous_host;  |  11890  | 519  |       update_base_port(previous_port);  |  11891  | 519  |     }  |  11892  | 1.46k  |     return succeeded;  |  11893  | 2.55k  |   }  |  11894  |  |  |  11895  | 1.48k  |   size_t location = new_host.find_first_of("/\\?"); |  11896  | 1.48k  |   if (location != std::string_view::npos) { |  11897  | 296  |     new_host.remove_suffix(new_host.length() - location);  |  11898  | 296  |   }  |  11899  |  |  |  11900  | 1.48k  |   if (new_host.empty()) { |  11901  |  |     // Set url’s host to the empty string.  |  11902  | 1.01k  |     host = "";  |  11903  | 1.01k  |   } else { |  11904  |  |     // Let host be the result of host parsing buffer with url is not special.  |  11905  | 472  |     if (!parse_host(new_host)) { |  11906  | 193  |       host = previous_host;  |  11907  | 193  |       update_base_port(previous_port);  |  11908  | 193  |       return false;  |  11909  | 193  |     }  |  11910  |  |  |  11911  |  |     // If host is "localhost", then set host to the empty string.  |  11912  | 279  |     if (host.has_value() && host.value() == "localhost") { |  11913  | 1  |       host = "";  |  11914  | 1  |     }  |  11915  | 279  |   }  |  11916  | 1.29k  |   return true;  |  11917  | 1.48k  | }  |  
  | 
11918  |  |  | 
11919  | 8.27k  | bool url::set_host(const std::string_view input) { | 
11920  | 8.27k  |   return set_host_or_hostname<false>(input);  | 
11921  | 8.27k  | }  | 
11922  |  |  | 
11923  | 8.27k  | bool url::set_hostname(const std::string_view input) { | 
11924  | 8.27k  |   return set_host_or_hostname<true>(input);  | 
11925  | 8.27k  | }  | 
11926  |  |  | 
11927  | 8.27k  | bool url::set_username(const std::string_view input) { | 
11928  | 8.27k  |   if (cannot_have_credentials_or_port()) { | 
11929  | 4.03k  |     return false;  | 
11930  | 4.03k  |   }  | 
11931  | 4.23k  |   username = ada::unicode::percent_encode(  | 
11932  | 4.23k  |       input, character_sets::USERINFO_PERCENT_ENCODE);  | 
11933  | 4.23k  |   return true;  | 
11934  | 8.27k  | }  | 
11935  |  |  | 
11936  | 8.27k  | bool url::set_password(const std::string_view input) { | 
11937  | 8.27k  |   if (cannot_have_credentials_or_port()) { | 
11938  | 4.03k  |     return false;  | 
11939  | 4.03k  |   }  | 
11940  | 4.23k  |   password = ada::unicode::percent_encode(  | 
11941  | 4.23k  |       input, character_sets::USERINFO_PERCENT_ENCODE);  | 
11942  | 4.23k  |   return true;  | 
11943  | 8.27k  | }  | 
11944  |  |  | 
11945  | 8.37k  | bool url::set_port(const std::string_view input) { | 
11946  | 8.37k  |   if (cannot_have_credentials_or_port()) { | 
11947  | 3.87k  |     return false;  | 
11948  | 3.87k  |   }  | 
11949  | 4.49k  |   std::string trimmed(input);  | 
11950  | 4.49k  |   helpers::remove_ascii_tab_or_newline(trimmed);  | 
11951  | 4.49k  |   if (trimmed.empty()) { | 
11952  | 2.65k  |     port = std::nullopt;  | 
11953  | 2.65k  |     return true;  | 
11954  | 2.65k  |   }  | 
11955  |  |   // Input should not start with control characters.  | 
11956  | 1.84k  |   if (ada::unicode::is_c0_control_or_space(trimmed.front())) { | 
11957  | 79  |     return false;  | 
11958  | 79  |   }  | 
11959  |  |   // Input should contain at least one ascii digit.  | 
11960  | 1.76k  |   if (input.find_first_of("0123456789") == std::string_view::npos) { | 
11961  | 1.05k  |     return false;  | 
11962  | 1.05k  |   }  | 
11963  |  |  | 
11964  |  |   // Revert changes if parse_port fails.  | 
11965  | 712  |   std::optional<uint16_t> previous_port = port;  | 
11966  | 712  |   parse_port(trimmed);  | 
11967  | 712  |   if (is_valid) { | 
11968  | 522  |     return true;  | 
11969  | 522  |   }  | 
11970  | 190  |   port = previous_port;  | 
11971  | 190  |   is_valid = true;  | 
11972  | 190  |   return false;  | 
11973  | 712  | }  | 
11974  |  |  | 
11975  | 8.27k  | void url::set_hash(const std::string_view input) { | 
11976  | 8.27k  |   if (input.empty()) { | 
11977  | 5.24k  |     hash = std::nullopt;  | 
11978  | 5.24k  |     helpers::strip_trailing_spaces_from_opaque_path(*this);  | 
11979  | 5.24k  |     return;  | 
11980  | 5.24k  |   }  | 
11981  |  |  | 
11982  | 3.02k  |   std::string new_value;  | 
11983  | 3.02k  |   new_value = input[0] == '#' ? input.substr(1) : input;  | 
11984  | 3.02k  |   helpers::remove_ascii_tab_or_newline(new_value);  | 
11985  | 3.02k  |   hash = unicode::percent_encode(new_value,  | 
11986  | 3.02k  |                                  ada::character_sets::FRAGMENT_PERCENT_ENCODE);  | 
11987  | 3.02k  |   return;  | 
11988  | 8.27k  | }  | 
11989  |  |  | 
11990  | 8.27k  | void url::set_search(const std::string_view input) { | 
11991  | 8.27k  |   if (input.empty()) { | 
11992  | 5.24k  |     query = std::nullopt;  | 
11993  | 5.24k  |     helpers::strip_trailing_spaces_from_opaque_path(*this);  | 
11994  | 5.24k  |     return;  | 
11995  | 5.24k  |   }  | 
11996  |  |  | 
11997  | 3.02k  |   std::string new_value;  | 
11998  | 3.02k  |   new_value = input[0] == '?' ? input.substr(1) : input;  | 
11999  | 3.02k  |   helpers::remove_ascii_tab_or_newline(new_value);  | 
12000  |  |  | 
12001  | 3.02k  |   auto query_percent_encode_set =  | 
12002  | 3.02k  |       is_special() ? ada::character_sets::SPECIAL_QUERY_PERCENT_ENCODE  | 
12003  | 3.02k  |                    : ada::character_sets::QUERY_PERCENT_ENCODE;  | 
12004  |  |  | 
12005  | 3.02k  |   query = ada::unicode::percent_encode(std::string_view(new_value),  | 
12006  | 3.02k  |                                        query_percent_encode_set);  | 
12007  | 3.02k  | }  | 
12008  |  |  | 
12009  | 8.27k  | bool url::set_pathname(const std::string_view input) { | 
12010  | 8.27k  |   if (has_opaque_path) { | 
12011  | 1.06k  |     return false;  | 
12012  | 1.06k  |   }  | 
12013  | 7.20k  |   path = "";  | 
12014  | 7.20k  |   parse_path(input);  | 
12015  | 7.20k  |   return true;  | 
12016  | 8.27k  | }  | 
12017  |  |  | 
12018  | 8.27k  | bool url::set_protocol(const std::string_view input) { | 
12019  | 8.27k  |   std::string view(input);  | 
12020  | 8.27k  |   helpers::remove_ascii_tab_or_newline(view);  | 
12021  | 8.27k  |   if (view.empty()) { | 
12022  | 5.29k  |     return true;  | 
12023  | 5.29k  |   }  | 
12024  |  |  | 
12025  |  |   // Schemes should start with alpha values.  | 
12026  | 2.97k  |   if (!checkers::is_alpha(view[0])) { | 
12027  | 2.41k  |     return false;  | 
12028  | 2.41k  |   }  | 
12029  |  |  | 
12030  | 564  |   view.append(":"); | 
12031  |  |  | 
12032  | 564  |   std::string::iterator pointer =  | 
12033  | 564  |       std::find_if_not(view.begin(), view.end(), unicode::is_alnum_plus);  | 
12034  |  |  | 
12035  | 564  |   if (pointer != view.end() && *pointer == ':') { | 
12036  | 360  |     return parse_scheme<true>(  | 
12037  | 360  |         std::string_view(view.data(), pointer - view.begin()));  | 
12038  | 360  |   }  | 
12039  | 204  |   return false;  | 
12040  | 564  | }  | 
12041  |  |  | 
12042  | 0  | bool url::set_href(const std::string_view input) { | 
12043  | 0  |   ada::result<ada::url> out = ada::parse<ada::url>(input);  | 
12044  |  | 
  | 
12045  | 0  |   if (out) { | 
12046  | 0  |     username = out->username;  | 
12047  | 0  |     password = out->password;  | 
12048  | 0  |     host = out->host;  | 
12049  | 0  |     port = out->port;  | 
12050  | 0  |     path = out->path;  | 
12051  | 0  |     query = out->query;  | 
12052  | 0  |     hash = out->hash;  | 
12053  | 0  |     type = out->type;  | 
12054  | 0  |     non_special_scheme = out->non_special_scheme;  | 
12055  | 0  |     has_opaque_path = out->has_opaque_path;  | 
12056  | 0  |   }  | 
12057  |  | 
  | 
12058  | 0  |   return out.has_value();  | 
12059  | 0  | }  | 
12060  |  |  | 
12061  |  | }  // namespace ada  | 
12062  |  | /* end file src/url-setters.cpp */  | 
12063  |  | /* begin file src/parser.cpp */  | 
12064  |  |  | 
12065  |  | #include <numeric>  | 
12066  |  | #include <limits>  | 
12067  |  |  | 
12068  |  | namespace ada::parser { | 
12069  |  |  | 
12070  |  | template <class result_type>  | 
12071  |  | result_type parse_url(std::string_view user_input,  | 
12072  | 59.9k  |                       const result_type* base_url) { | 
12073  |  |   // We can specialize the implementation per type.  | 
12074  |  |   // Important: result_type_is_ada_url is evaluated at *compile time*. This  | 
12075  |  |   // means that doing if constexpr(result_type_is_ada_url) { something } else { | 
12076  |  |   // something else } is free (at runtime). This means that ada::url_aggregator  | 
12077  |  |   // and ada::url **do not have to support the exact same API**.  | 
12078  | 59.9k  |   constexpr bool result_type_is_ada_url =  | 
12079  | 59.9k  |       std::is_same<ada::url, result_type>::value;  | 
12080  | 59.9k  |   constexpr bool result_type_is_ada_url_aggregator =  | 
12081  | 59.9k  |       std::is_same<ada::url_aggregator, result_type>::value;  | 
12082  | 59.9k  |   static_assert(result_type_is_ada_url ||  | 
12083  | 59.9k  |                 result_type_is_ada_url_aggregator);  // We don't support  | 
12084  |  |                                                      // anything else for now.  | 
12085  |  |  | 
12086  | 59.9k  |   ada_log("ada::parser::parse_url('", user_input, "' [", user_input.size(), | 
12087  | 59.9k  |           " bytes],", (base_url != nullptr ? base_url->to_string() : "null"),  | 
12088  | 59.9k  |           ")");  | 
12089  |  |  | 
12090  | 59.9k  |   ada::state state = ada::state::SCHEME_START;  | 
12091  | 59.9k  |   result_type url{}; | 
12092  |  |  | 
12093  |  |   // We refuse to parse URL strings that exceed 4GB. Such strings are almost  | 
12094  |  |   // surely the result of a bug or are otherwise a security concern.  | 
12095  | 59.9k  |   if (user_input.size() > std::numeric_limits<uint32_t>::max()) { | 
12096  | 2  |     url.is_valid = false;  | 
12097  | 2  |   }  | 
12098  |  |   // Going forward, user_input.size() is in [0,  | 
12099  |  |   // std::numeric_limits<uint32_t>::max). If we are provided with an invalid  | 
12100  |  |   // base, or the optional_url was invalid, we must return.  | 
12101  | 59.9k  |   if (base_url != nullptr) { | 
12102  | 2.66k  |     url.is_valid &= base_url->is_valid;  | 
12103  | 2.66k  |   }  | 
12104  | 59.9k  |   if (!url.is_valid) { | 
12105  | 2  |     return url;  | 
12106  | 2  |   }  | 
12107  | 59.9k  |   if constexpr (result_type_is_ada_url_aggregator) { | 
12108  |  |     // Most of the time, we just need user_input.size().  | 
12109  |  |     // In some instances, we may need a bit more.  | 
12110  |  |     ///////////////////////////  | 
12111  |  |     // This is *very* important. This line should be removed  | 
12112  |  |     // hastily. There are principled reasons why reserve is important  | 
12113  |  |     // for performance. If you have a benchmark with small inputs,  | 
12114  |  |     // it may not matter, but in other instances, it could.  | 
12115  |  |     ////  | 
12116  |  |     // This rounds up to the next power of two.  | 
12117  |  |     // We know that user_input.size() is in [0,  | 
12118  |  |     // std::numeric_limits<uint32_t>::max).  | 
12119  | 45.4k  |     uint32_t reserve_capacity =  | 
12120  | 45.4k  |         (0xFFFFFFFF >>  | 
12121  | 45.4k  |          helpers::leading_zeroes(uint32_t(1 | user_input.size()))) +  | 
12122  | 45.4k  |         1;  | 
12123  | 45.4k  |     url.reserve(reserve_capacity);  | 
12124  |  |     //  | 
12125  |  |     //  | 
12126  |  |     //  | 
12127  | 45.4k  |   }  | 
12128  | 59.9k  |   std::string tmp_buffer;  | 
12129  | 59.9k  |   std::string_view internal_input;  | 
12130  | 59.9k  |   if (unicode::has_tabs_or_newline(user_input)) { | 
12131  | 670  |     tmp_buffer = user_input;  | 
12132  |  |     // Optimization opportunity: Instead of copying and then pruning, we could  | 
12133  |  |     // just directly build the string from user_input.  | 
12134  | 670  |     helpers::remove_ascii_tab_or_newline(tmp_buffer);  | 
12135  | 670  |     internal_input = tmp_buffer;  | 
12136  | 59.2k  |   } else { | 
12137  | 59.2k  |     internal_input = user_input;  | 
12138  | 59.2k  |   }  | 
12139  |  |  | 
12140  |  |   // Leading and trailing control characters are uncommon and easy to deal with  | 
12141  |  |   // (no performance concern).  | 
12142  | 59.9k  |   std::string_view url_data = internal_input;  | 
12143  | 59.9k  |   helpers::trim_c0_whitespace(url_data);  | 
12144  |  |  | 
12145  |  |   // Optimization opportunity. Most websites do not have fragment.  | 
12146  | 59.9k  |   std::optional<std::string_view> fragment = helpers::prune_hash(url_data);  | 
12147  |  |   // We add it last so that an implementation like ada::url_aggregator  | 
12148  |  |   // can append it last to its internal buffer, thus improving performance.  | 
12149  |  |  | 
12150  |  |   // Here url_data no longer has its fragment.  | 
12151  |  |   // We are going to access the data from url_data (it is immutable).  | 
12152  |  |   // At any given time, we are pointing at byte 'input_position' in url_data.  | 
12153  |  |   // The input_position variable should range from 0 to input_size.  | 
12154  |  |   // It is illegal to access url_data at input_size.  | 
12155  | 59.9k  |   size_t input_position = 0;  | 
12156  | 59.9k  |   const size_t input_size = url_data.size();  | 
12157  |  |   // Keep running the following state machine by switching on state.  | 
12158  |  |   // If after a run pointer points to the EOF code point, go to the next step.  | 
12159  |  |   // Otherwise, increase pointer by 1 and continue with the state machine.  | 
12160  |  |   // We never decrement input_position.  | 
12161  | 244k  |   while (input_position <= input_size) { | 
12162  | 229k  |     ada_log("In parsing at ", input_position, " out of ", input_size, | 
12163  | 229k  |             " in state ", ada::to_string(state));  | 
12164  | 229k  |     switch (state) { | 
12165  | 59.9k  |       case ada::state::SCHEME_START: { | 
12166  | 59.9k  |         ada_log("SCHEME_START ", helpers::substring(url_data, input_position)); | 
12167  |  |         // If c is an ASCII alpha, append c, lowercased, to buffer, and set  | 
12168  |  |         // state to scheme state.  | 
12169  | 59.9k  |         if ((input_position != input_size) &&  | 
12170  | 59.9k  |             checkers::is_alpha(url_data[input_position])) { | 
12171  | 37.6k  |           state = ada::state::SCHEME;  | 
12172  | 37.6k  |           input_position++;  | 
12173  | 37.6k  |         } else { | 
12174  |  |           // Otherwise, if state override is not given, set state to no scheme  | 
12175  |  |           // state and decrease pointer by 1.  | 
12176  | 22.2k  |           state = ada::state::NO_SCHEME;  | 
12177  | 22.2k  |         }  | 
12178  | 59.9k  |         break;  | 
12179  | 0  |       }  | 
12180  | 37.6k  |       case ada::state::SCHEME: { | 
12181  | 37.6k  |         ada_log("SCHEME ", helpers::substring(url_data, input_position)); | 
12182  |  |         // If c is an ASCII alphanumeric, U+002B (+), U+002D (-), or U+002E (.),  | 
12183  |  |         // append c, lowercased, to buffer.  | 
12184  | 125k  |         while ((input_position != input_size) &&  | 
12185  | 125k  |                (ada::unicode::is_alnum_plus(url_data[input_position]))) { | 
12186  | 88.0k  |           input_position++;  | 
12187  | 88.0k  |         }  | 
12188  |  |         // Otherwise, if c is U+003A (:), then:  | 
12189  | 37.6k  |         if ((input_position != input_size) &&  | 
12190  | 37.6k  |             (url_data[input_position] == ':')) { | 
12191  | 34.4k  |           ada_log("SCHEME the scheme should be ", | 
12192  | 34.4k  |                   url_data.substr(0, input_position));  | 
12193  | 34.4k  |           if constexpr (result_type_is_ada_url) { | 
12194  | 24.2k  |             if (!url.parse_scheme(url_data.substr(0, input_position))) { | 
12195  | 0  |               return url;  | 
12196  | 0  |             }  | 
12197  | 24.2k  |           } else { | 
12198  |  |             // we pass the colon along instead of painfully adding it back.  | 
12199  | 24.2k  |             if (!url.parse_scheme_with_colon(  | 
12200  | 24.2k  |                     url_data.substr(0, input_position + 1))) { | 
12201  | 0  |               return url;  | 
12202  | 0  |             }  | 
12203  | 24.2k  |           }  | 
12204  | 34.4k  |           ada_log("SCHEME the scheme is ", url.get_protocol()); | 
12205  |  |  | 
12206  |  |           // If url’s scheme is "file", then:  | 
12207  | 34.4k  |           if (url.type == ada::scheme::type::FILE) { | 
12208  |  |             // Set state to file state.  | 
12209  | 5.74k  |             state = ada::state::FILE;  | 
12210  | 5.74k  |           }  | 
12211  |  |           // Otherwise, if url is special, base is non-null, and base’s scheme  | 
12212  |  |           // is url’s scheme: Note: Doing base_url->scheme is unsafe if base_url  | 
12213  |  |           // != nullptr is false.  | 
12214  | 28.7k  |           else if (url.is_special() && base_url != nullptr &&  | 
12215  | 28.7k  |                    base_url->type == url.type) { | 
12216  |  |             // Set state to special relative or authority state.  | 
12217  | 120  |             state = ada::state::SPECIAL_RELATIVE_OR_AUTHORITY;  | 
12218  | 120  |           }  | 
12219  |  |           // Otherwise, if url is special, set state to special authority  | 
12220  |  |           // slashes state.  | 
12221  | 28.6k  |           else if (url.is_special()) { | 
12222  | 18.4k  |             state = ada::state::SPECIAL_AUTHORITY_SLASHES;  | 
12223  | 18.4k  |           }  | 
12224  |  |           // Otherwise, if remaining starts with an U+002F (/), set state to  | 
12225  |  |           // path or authority state and increase pointer by 1.  | 
12226  | 10.2k  |           else if (input_position + 1 < input_size &&  | 
12227  | 10.2k  |                    url_data[input_position + 1] == '/') { | 
12228  | 5.76k  |             state = ada::state::PATH_OR_AUTHORITY;  | 
12229  | 5.76k  |             input_position++;  | 
12230  | 5.76k  |           }  | 
12231  |  |           // Otherwise, set url’s path to the empty string and set state to  | 
12232  |  |           // opaque path state.  | 
12233  | 4.43k  |           else { | 
12234  | 4.43k  |             state = ada::state::OPAQUE_PATH;  | 
12235  | 4.43k  |           }  | 
12236  | 34.4k  |         }  | 
12237  |  |         // Otherwise, if state override is not given, set buffer to the empty  | 
12238  |  |         // string, state to no scheme state, and start over (from the first code  | 
12239  |  |         // point in input).  | 
12240  | 3.15k  |         else { | 
12241  | 3.15k  |           state = ada::state::NO_SCHEME;  | 
12242  | 3.15k  |           input_position = 0;  | 
12243  | 3.15k  |           break;  | 
12244  | 3.15k  |         }  | 
12245  | 34.4k  |         input_position++;  | 
12246  | 34.4k  |         break;  | 
12247  | 37.6k  |       }  | 
12248  | 25.4k  |       case ada::state::NO_SCHEME: { | 
12249  | 25.4k  |         ada_log("NO_SCHEME ", helpers::substring(url_data, input_position)); | 
12250  |  |         // If base is null, or base has an opaque path and c is not U+0023 (#),  | 
12251  |  |         // validation error, return failure.  | 
12252  | 25.4k  |         if (base_url == nullptr ||  | 
12253  | 25.4k  |             (base_url->has_opaque_path && !fragment.has_value())) { | 
12254  | 24.1k  |           ada_log("NO_SCHEME validation error"); | 
12255  | 24.1k  |           url.is_valid = false;  | 
12256  | 24.1k  |           return url;  | 
12257  | 24.1k  |         }  | 
12258  |  |         // Otherwise, if base has an opaque path and c is U+0023 (#),  | 
12259  |  |         // set url’s scheme to base’s scheme, url’s path to base’s path, url’s  | 
12260  |  |         // query to base’s query, and set state to fragment state.  | 
12261  | 1.24k  |         else if (base_url->has_opaque_path && fragment.has_value() &&  | 
12262  | 1.24k  |                  input_position == input_size) { | 
12263  | 28  |           ada_log("NO_SCHEME opaque base with fragment"); | 
12264  | 28  |           url.copy_scheme(*base_url);  | 
12265  | 28  |           url.has_opaque_path = base_url->has_opaque_path;  | 
12266  |  |  | 
12267  | 28  |           if constexpr (result_type_is_ada_url) { | 
12268  | 28  |             url.path = base_url->path;  | 
12269  | 28  |             url.query = base_url->query;  | 
12270  | 28  |           } else { | 
12271  | 28  |             url.update_base_pathname(base_url->get_pathname());  | 
12272  | 28  |             url.update_base_search(base_url->get_search());  | 
12273  | 28  |           }  | 
12274  | 28  |           url.update_unencoded_base_hash(*fragment);  | 
12275  | 28  |           return url;  | 
12276  | 28  |         }  | 
12277  |  |         // Otherwise, if base’s scheme is not "file", set state to relative  | 
12278  |  |         // state and decrease pointer by 1.  | 
12279  | 1.21k  |         else if (base_url->type != ada::scheme::type::FILE) { | 
12280  | 657  |           ada_log("NO_SCHEME non-file relative path"); | 
12281  | 657  |           state = ada::state::RELATIVE_SCHEME;  | 
12282  | 657  |         }  | 
12283  |  |         // Otherwise, set state to file state and decrease pointer by 1.  | 
12284  | 562  |         else { | 
12285  | 562  |           ada_log("NO_SCHEME file base type"); | 
12286  | 562  |           state = ada::state::FILE;  | 
12287  | 562  |         }  | 
12288  | 1.21k  |         break;  | 
12289  | 25.4k  |       }  | 
12290  | 19.6k  |       case ada::state::AUTHORITY: { | 
12291  | 19.6k  |         ada_log("AUTHORITY ", helpers::substring(url_data, input_position)); | 
12292  |  |         // most URLs have no @. Having no @ tells us that we don't have to worry  | 
12293  |  |         // about AUTHORITY. Of course, we could have @ and still not have to  | 
12294  |  |         // worry about AUTHORITY.  | 
12295  |  |         // TODO: Instead of just collecting a bool, collect the location of the  | 
12296  |  |         // '@' and do something useful with it.  | 
12297  |  |         // TODO: We could do various processing early on, using a single pass  | 
12298  |  |         // over the string to collect information about it, e.g., telling us  | 
12299  |  |         // whether there is a @ and if so, where (or how many).  | 
12300  | 19.6k  |         const bool contains_ampersand =  | 
12301  | 19.6k  |             (url_data.find('@', input_position) != std::string_view::npos); | 
12302  |  |  | 
12303  | 19.6k  |         if (!contains_ampersand) { | 
12304  | 18.2k  |           state = ada::state::HOST;  | 
12305  | 18.2k  |           break;  | 
12306  | 18.2k  |         }  | 
12307  | 1.40k  |         bool at_sign_seen{false}; | 
12308  | 1.40k  |         bool password_token_seen{false}; | 
12309  |  |         /**  | 
12310  |  |          * We expect something of the sort...  | 
12311  |  |          * https://user:pass@example.com:1234/foo/bar?baz#quux  | 
12312  |  |          * --------^  | 
12313  |  |          */  | 
12314  | 10.7k  |         do { | 
12315  | 10.7k  |           std::string_view view = helpers::substring(url_data, input_position);  | 
12316  |  |           // The delimiters are @, /, ? \\.  | 
12317  | 10.7k  |           size_t location =  | 
12318  | 10.7k  |               url.is_special() ? helpers::find_authority_delimiter_special(view)  | 
12319  | 10.7k  |                                : helpers::find_authority_delimiter(view);  | 
12320  | 10.7k  |           std::string_view authority_view(view.data(), location);  | 
12321  | 10.7k  |           size_t end_of_authority = input_position + authority_view.size();  | 
12322  |  |           // If c is U+0040 (@), then:  | 
12323  | 10.7k  |           if ((end_of_authority != input_size) &&  | 
12324  | 10.7k  |               (url_data[end_of_authority] == '@')) { | 
12325  |  |             // If atSignSeen is true, then prepend "%40" to buffer.  | 
12326  | 9.36k  |             if (at_sign_seen) { | 
12327  | 8.01k  |               if (password_token_seen) { | 
12328  | 1.95k  |                 if constexpr (result_type_is_ada_url) { | 
12329  | 1.37k  |                   url.password += "%40";  | 
12330  | 1.37k  |                 } else { | 
12331  | 1.37k  |                   url.append_base_password("%40"); | 
12332  | 1.37k  |                 }  | 
12333  | 6.06k  |               } else { | 
12334  | 6.06k  |                 if constexpr (result_type_is_ada_url) { | 
12335  | 4.25k  |                   url.username += "%40";  | 
12336  | 4.25k  |                 } else { | 
12337  | 4.25k  |                   url.append_base_username("%40"); | 
12338  | 4.25k  |                 }  | 
12339  | 6.06k  |               }  | 
12340  | 8.01k  |             }  | 
12341  |  |  | 
12342  | 9.36k  |             at_sign_seen = true;  | 
12343  |  |  | 
12344  | 9.36k  |             if (!password_token_seen) { | 
12345  | 7.40k  |               size_t password_token_location = authority_view.find(':'); | 
12346  | 7.40k  |               password_token_seen =  | 
12347  | 7.40k  |                   password_token_location != std::string_view::npos;  | 
12348  |  |  | 
12349  | 7.40k  |               if (!password_token_seen) { | 
12350  | 6.94k  |                 if constexpr (result_type_is_ada_url) { | 
12351  | 4.85k  |                   url.username += unicode::percent_encode(  | 
12352  | 4.85k  |                       authority_view, character_sets::USERINFO_PERCENT_ENCODE);  | 
12353  | 4.85k  |                 } else { | 
12354  | 4.85k  |                   url.append_base_username(unicode::percent_encode(  | 
12355  | 4.85k  |                       authority_view, character_sets::USERINFO_PERCENT_ENCODE));  | 
12356  | 4.85k  |                 }  | 
12357  | 6.94k  |               } else { | 
12358  | 465  |                 if constexpr (result_type_is_ada_url) { | 
12359  | 325  |                   url.username += unicode::percent_encode(  | 
12360  | 325  |                       authority_view.substr(0, password_token_location),  | 
12361  | 325  |                       character_sets::USERINFO_PERCENT_ENCODE);  | 
12362  | 325  |                   url.password += unicode::percent_encode(  | 
12363  | 325  |                       authority_view.substr(password_token_location + 1),  | 
12364  | 325  |                       character_sets::USERINFO_PERCENT_ENCODE);  | 
12365  | 325  |                 } else { | 
12366  | 325  |                   url.append_base_username(unicode::percent_encode(  | 
12367  | 325  |                       authority_view.substr(0, password_token_location),  | 
12368  | 325  |                       character_sets::USERINFO_PERCENT_ENCODE));  | 
12369  | 325  |                   url.append_base_password(unicode::percent_encode(  | 
12370  | 325  |                       authority_view.substr(password_token_location + 1),  | 
12371  | 325  |                       character_sets::USERINFO_PERCENT_ENCODE));  | 
12372  | 325  |                 }  | 
12373  | 465  |               }  | 
12374  | 7.40k  |             } else { | 
12375  | 1.95k  |               if constexpr (result_type_is_ada_url) { | 
12376  | 1.37k  |                 url.password += unicode::percent_encode(  | 
12377  | 1.37k  |                     authority_view, character_sets::USERINFO_PERCENT_ENCODE);  | 
12378  | 1.37k  |               } else { | 
12379  | 1.37k  |                 url.append_base_password(unicode::percent_encode(  | 
12380  | 1.37k  |                     authority_view, character_sets::USERINFO_PERCENT_ENCODE));  | 
12381  | 1.37k  |               }  | 
12382  | 1.95k  |             }  | 
12383  | 9.36k  |           }  | 
12384  |  |           // Otherwise, if one of the following is true:  | 
12385  |  |           // - c is the EOF code point, U+002F (/), U+003F (?), or U+0023 (#)  | 
12386  |  |           // - url is special and c is U+005C (\)  | 
12387  | 1.40k  |           else if (end_of_authority == input_size ||  | 
12388  | 1.40k  |                    url_data[end_of_authority] == '/' ||  | 
12389  | 1.40k  |                    url_data[end_of_authority] == '?' ||  | 
12390  | 1.40k  |                    (url.is_special() && url_data[end_of_authority] == '\\')) { | 
12391  |  |             // If atSignSeen is true and authority_view is the empty string,  | 
12392  |  |             // validation error, return failure.  | 
12393  | 1.40k  |             if (at_sign_seen && authority_view.empty()) { | 
12394  | 745  |               url.is_valid = false;  | 
12395  | 745  |               return url;  | 
12396  | 745  |             }  | 
12397  | 656  |             state = ada::state::HOST;  | 
12398  | 656  |             break;  | 
12399  | 1.40k  |           }  | 
12400  | 9.36k  |           if (end_of_authority == input_size) { | 
12401  | 0  |             if (fragment.has_value()) { | 
12402  | 0  |               url.update_unencoded_base_hash(*fragment);  | 
12403  | 0  |             }  | 
12404  | 0  |             return url;  | 
12405  | 0  |           }  | 
12406  | 9.36k  |           input_position = end_of_authority + 1;  | 
12407  | 9.36k  |         } while (true);  | 
12408  |  |  | 
12409  | 656  |         break;  | 
12410  | 1.40k  |       }  | 
12411  | 656  |       case ada::state::SPECIAL_RELATIVE_OR_AUTHORITY: { | 
12412  | 120  |         ada_log("SPECIAL_RELATIVE_OR_AUTHORITY ", | 
12413  | 120  |                 helpers::substring(url_data, input_position));  | 
12414  |  |  | 
12415  |  |         // If c is U+002F (/) and remaining starts with U+002F (/),  | 
12416  |  |         // then set state to special authority ignore slashes state and increase  | 
12417  |  |         // pointer by 1.  | 
12418  | 120  |         std::string_view view = helpers::substring(url_data, input_position);  | 
12419  | 120  |         if (ada::checkers::begins_with(view, "//")) { | 
12420  | 2  |           state = ada::state::SPECIAL_AUTHORITY_IGNORE_SLASHES;  | 
12421  | 2  |           input_position += 2;  | 
12422  | 118  |         } else { | 
12423  |  |           // Otherwise, validation error, set state to relative state and  | 
12424  |  |           // decrease pointer by 1.  | 
12425  | 118  |           state = ada::state::RELATIVE_SCHEME;  | 
12426  | 118  |         }  | 
12427  |  |  | 
12428  | 120  |         break;  | 
12429  | 1.40k  |       }  | 
12430  | 5.76k  |       case ada::state::PATH_OR_AUTHORITY: { | 
12431  | 5.76k  |         ada_log("PATH_OR_AUTHORITY ", | 
12432  | 5.76k  |                 helpers::substring(url_data, input_position));  | 
12433  |  |  | 
12434  |  |         // If c is U+002F (/), then set state to authority state.  | 
12435  | 5.76k  |         if ((input_position != input_size) &&  | 
12436  | 5.76k  |             (url_data[input_position] == '/')) { | 
12437  | 1.17k  |           state = ada::state::AUTHORITY;  | 
12438  | 1.17k  |           input_position++;  | 
12439  | 4.59k  |         } else { | 
12440  |  |           // Otherwise, set state to path state, and decrease pointer by 1.  | 
12441  | 4.59k  |           state = ada::state::PATH;  | 
12442  | 4.59k  |         }  | 
12443  |  |  | 
12444  | 5.76k  |         break;  | 
12445  | 1.40k  |       }  | 
12446  | 775  |       case ada::state::RELATIVE_SCHEME: { | 
12447  | 775  |         ada_log("RELATIVE_SCHEME ", | 
12448  | 775  |                 helpers::substring(url_data, input_position));  | 
12449  |  |  | 
12450  |  |         // Set url’s scheme to base’s scheme.  | 
12451  | 775  |         url.copy_scheme(*base_url);  | 
12452  |  |  | 
12453  |  |         // If c is U+002F (/), then set state to relative slash state.  | 
12454  | 775  |         if ((input_position != input_size) &&  | 
12455  | 775  |             (url_data[input_position] == '/')) { | 
12456  | 43  |           ada_log(  | 
12457  | 43  |               "RELATIVE_SCHEME if c is U+002F (/), then set state to relative "  | 
12458  | 43  |               "slash state");  | 
12459  | 43  |           state = ada::state::RELATIVE_SLASH;  | 
12460  | 732  |         } else if (url.is_special() && (input_position != input_size) &&  | 
12461  | 732  |                    (url_data[input_position] == '\\')) { | 
12462  |  |           // Otherwise, if url is special and c is U+005C (\), validation error,  | 
12463  |  |           // set state to relative slash state.  | 
12464  | 1  |           ada_log(  | 
12465  | 1  |               "RELATIVE_SCHEME  if url is special and c is U+005C, validation "  | 
12466  | 1  |               "error, set state to relative slash state");  | 
12467  | 1  |           state = ada::state::RELATIVE_SLASH;  | 
12468  | 731  |         } else { | 
12469  | 731  |           ada_log("RELATIVE_SCHEME otherwise"); | 
12470  |  |           // Set url’s username to base’s username, url’s password to base’s  | 
12471  |  |           // password, url’s host to base’s host, url’s port to base’s port,  | 
12472  |  |           // url’s path to a clone of base’s path, and url’s query to base’s  | 
12473  |  |           // query.  | 
12474  | 731  |           if constexpr (result_type_is_ada_url) { | 
12475  | 731  |             url.username = base_url->username;  | 
12476  | 731  |             url.password = base_url->password;  | 
12477  | 731  |             url.host = base_url->host;  | 
12478  | 731  |             url.port = base_url->port;  | 
12479  |  |             // cloning the base path includes cloning the has_opaque_path flag  | 
12480  | 0  |             url.has_opaque_path = base_url->has_opaque_path;  | 
12481  | 0  |             url.path = base_url->path;  | 
12482  | 0  |             url.query = base_url->query;  | 
12483  | 731  |           } else { | 
12484  | 731  |             url.update_base_authority(base_url->get_href(),  | 
12485  | 731  |                                       base_url->get_components());  | 
12486  |  |             // TODO: Get rid of set_hostname and replace it with  | 
12487  |  |             // update_base_hostname  | 
12488  | 731  |             url.set_hostname(base_url->get_hostname());  | 
12489  | 731  |             url.update_base_port(base_url->retrieve_base_port());  | 
12490  |  |             // cloning the base path includes cloning the has_opaque_path flag  | 
12491  | 731  |             url.has_opaque_path = base_url->has_opaque_path;  | 
12492  | 731  |             url.update_base_pathname(base_url->get_pathname());  | 
12493  | 731  |             url.update_base_search(base_url->get_search());  | 
12494  | 731  |           }  | 
12495  |  |  | 
12496  | 731  |           url.has_opaque_path = base_url->has_opaque_path;  | 
12497  |  |  | 
12498  |  |           // If c is U+003F (?), then set url’s query to the empty string, and  | 
12499  |  |           // state to query state.  | 
12500  | 731  |           if ((input_position != input_size) &&  | 
12501  | 731  |               (url_data[input_position] == '?')) { | 
12502  | 5  |             state = ada::state::QUERY;  | 
12503  | 5  |           }  | 
12504  |  |           // Otherwise, if c is not the EOF code point:  | 
12505  | 726  |           else if (input_position != input_size) { | 
12506  |  |             // Set url’s query to null.  | 
12507  | 233  |             url.clear_search();  | 
12508  | 233  |             if constexpr (result_type_is_ada_url) { | 
12509  |  |               // Shorten url’s path.  | 
12510  | 0  |               helpers::shorten_path(url.path, url.type);  | 
12511  | 233  |             } else { | 
12512  | 233  |               std::string_view path = url.get_pathname();  | 
12513  | 233  |               if (helpers::shorten_path(path, url.type)) { | 
12514  | 197  |                 url.update_base_pathname(std::string(path));  | 
12515  | 197  |               }  | 
12516  | 233  |             }  | 
12517  |  |             // Set state to path state and decrease pointer by 1.  | 
12518  | 233  |             state = ada::state::PATH;  | 
12519  | 233  |             break;  | 
12520  | 233  |           }  | 
12521  | 731  |         }  | 
12522  | 542  |         input_position++;  | 
12523  | 542  |         break;  | 
12524  | 775  |       }  | 
12525  | 44  |       case ada::state::RELATIVE_SLASH: { | 
12526  | 44  |         ada_log("RELATIVE_SLASH ", | 
12527  | 44  |                 helpers::substring(url_data, input_position));  | 
12528  |  |  | 
12529  |  |         // If url is special and c is U+002F (/) or U+005C (\), then:  | 
12530  | 44  |         if (url.is_special() && (input_position != input_size) &&  | 
12531  | 44  |             (url_data[input_position] == '/' ||  | 
12532  | 18  |              url_data[input_position] == '\\')) { | 
12533  |  |           // Set state to special authority ignore slashes state.  | 
12534  | 3  |           state = ada::state::SPECIAL_AUTHORITY_IGNORE_SLASHES;  | 
12535  | 3  |         }  | 
12536  |  |         // Otherwise, if c is U+002F (/), then set state to authority state.  | 
12537  | 41  |         else if ((input_position != input_size) &&  | 
12538  | 41  |                  (url_data[input_position] == '/')) { | 
12539  | 5  |           state = ada::state::AUTHORITY;  | 
12540  | 5  |         }  | 
12541  |  |         // Otherwise, set  | 
12542  |  |         // - url’s username to base’s username,  | 
12543  |  |         // - url’s password to base’s password,  | 
12544  |  |         // - url’s host to base’s host,  | 
12545  |  |         // - url’s port to base’s port,  | 
12546  |  |         // - state to path state, and then, decrease pointer by 1.  | 
12547  | 36  |         else { | 
12548  | 36  |           if constexpr (result_type_is_ada_url) { | 
12549  | 36  |             url.username = base_url->username;  | 
12550  | 36  |             url.password = base_url->password;  | 
12551  | 36  |             url.host = base_url->host;  | 
12552  | 36  |             url.port = base_url->port;  | 
12553  | 36  |           } else { | 
12554  | 36  |             url.update_base_authority(base_url->get_href(),  | 
12555  | 36  |                                       base_url->get_components());  | 
12556  |  |             // TODO: Get rid of set_hostname and replace it with  | 
12557  |  |             // update_base_hostname  | 
12558  | 36  |             url.set_hostname(base_url->get_hostname());  | 
12559  | 36  |             url.update_base_port(base_url->retrieve_base_port());  | 
12560  | 36  |           }  | 
12561  | 36  |           state = ada::state::PATH;  | 
12562  | 36  |           break;  | 
12563  | 36  |         }  | 
12564  |  |  | 
12565  | 8  |         input_position++;  | 
12566  | 8  |         break;  | 
12567  | 44  |       }  | 
12568  | 18.4k  |       case ada::state::SPECIAL_AUTHORITY_SLASHES: { | 
12569  | 18.4k  |         ada_log("SPECIAL_AUTHORITY_SLASHES ", | 
12570  | 18.4k  |                 helpers::substring(url_data, input_position));  | 
12571  |  |  | 
12572  |  |         // If c is U+002F (/) and remaining starts with U+002F (/),  | 
12573  |  |         // then set state to special authority ignore slashes state and increase  | 
12574  |  |         // pointer by 1.  | 
12575  | 18.4k  |         state = ada::state::SPECIAL_AUTHORITY_IGNORE_SLASHES;  | 
12576  | 18.4k  |         std::string_view view = helpers::substring(url_data, input_position);  | 
12577  | 18.4k  |         if (ada::checkers::begins_with(view, "//")) { | 
12578  | 48  |           input_position += 2;  | 
12579  | 48  |         }  | 
12580  |  |  | 
12581  | 18.4k  |         [[fallthrough]];  | 
12582  | 18.4k  |       }  | 
12583  | 18.4k  |       case ada::state::SPECIAL_AUTHORITY_IGNORE_SLASHES: { | 
12584  | 18.4k  |         ada_log("SPECIAL_AUTHORITY_IGNORE_SLASHES ", | 
12585  | 18.4k  |                 helpers::substring(url_data, input_position));  | 
12586  |  |  | 
12587  |  |         // If c is neither U+002F (/) nor U+005C (\), then set state to  | 
12588  |  |         // authority state and decrease pointer by 1.  | 
12589  | 20.1k  |         while ((input_position != input_size) &&  | 
12590  | 20.1k  |                ((url_data[input_position] == '/') ||  | 
12591  | 19.9k  |                 (url_data[input_position] == '\\'))) { | 
12592  | 1.68k  |           input_position++;  | 
12593  | 1.68k  |         }  | 
12594  | 18.4k  |         state = ada::state::AUTHORITY;  | 
12595  |  |  | 
12596  | 18.4k  |         break;  | 
12597  | 18.4k  |       }  | 
12598  | 955  |       case ada::state::QUERY: { | 
12599  | 955  |         ada_log("QUERY ", helpers::substring(url_data, input_position)); | 
12600  |  |         // Let queryPercentEncodeSet be the special-query percent-encode set if  | 
12601  |  |         // url is special; otherwise the query percent-encode set.  | 
12602  | 955  |         const uint8_t* query_percent_encode_set =  | 
12603  | 955  |             url.is_special() ? ada::character_sets::SPECIAL_QUERY_PERCENT_ENCODE  | 
12604  | 955  |                              : ada::character_sets::QUERY_PERCENT_ENCODE;  | 
12605  |  |  | 
12606  |  |         // Percent-encode after encoding, with encoding, buffer, and  | 
12607  |  |         // queryPercentEncodeSet, and append the result to url’s query.  | 
12608  | 955  |         url.update_base_search(helpers::substring(url_data, input_position),  | 
12609  | 955  |                                query_percent_encode_set);  | 
12610  | 955  |         ada_log("QUERY update_base_search completed "); | 
12611  | 955  |         if (fragment.has_value()) { | 
12612  | 106  |           url.update_unencoded_base_hash(*fragment);  | 
12613  | 106  |         }  | 
12614  | 955  |         return url;  | 
12615  | 18.4k  |       }  | 
12616  | 18.8k  |       case ada::state::HOST: { | 
12617  | 18.8k  |         ada_log("HOST ", helpers::substring(url_data, input_position)); | 
12618  |  |  | 
12619  | 18.8k  |         std::string_view host_view =  | 
12620  | 18.8k  |             helpers::substring(url_data, input_position);  | 
12621  | 18.8k  |         auto [location, found_colon] =  | 
12622  | 18.8k  |             helpers::get_host_delimiter_location(url.is_special(), host_view);  | 
12623  | 18.8k  |         input_position = (location != std::string_view::npos)  | 
12624  | 18.8k  |                              ? input_position + location  | 
12625  | 18.8k  |                              : input_size;  | 
12626  |  |         // Otherwise, if c is U+003A (:) and insideBrackets is false, then:  | 
12627  |  |         // Note: the 'found_colon' value is true if and only if a colon was  | 
12628  |  |         // encountered while not inside brackets.  | 
12629  | 18.8k  |         if (found_colon) { | 
12630  |  |           // If buffer is the empty string, validation error, return failure.  | 
12631  |  |           // Let host be the result of host parsing buffer with url is not  | 
12632  |  |           // special.  | 
12633  | 2.81k  |           ada_log("HOST parsing ", host_view); | 
12634  | 2.81k  |           if (!url.parse_host(host_view)) { | 
12635  | 434  |             return url;  | 
12636  | 434  |           }  | 
12637  | 2.37k  |           ada_log("HOST parsing results in ", url.get_hostname()); | 
12638  |  |           // Set url’s host to host, buffer to the empty string, and state to  | 
12639  |  |           // port state.  | 
12640  | 2.37k  |           state = ada::state::PORT;  | 
12641  | 2.37k  |           input_position++;  | 
12642  | 2.37k  |         }  | 
12643  |  |         // Otherwise, if one of the following is true:  | 
12644  |  |         // - c is the EOF code point, U+002F (/), U+003F (?), or U+0023 (#)  | 
12645  |  |         // - url is special and c is U+005C (\)  | 
12646  |  |         // The get_host_delimiter_location function either brings us to  | 
12647  |  |         // the colon outside of the bracket, or to one of those characters.  | 
12648  | 16.0k  |         else { | 
12649  |  |           // If url is special and host_view is the empty string, validation  | 
12650  |  |           // error, return failure.  | 
12651  | 16.0k  |           if (url.is_special() && host_view.empty()) { | 
12652  | 143  |             url.is_valid = false;  | 
12653  | 143  |             return url;  | 
12654  | 143  |           }  | 
12655  | 15.9k  |           ada_log("HOST parsing ", host_view, " href=", url.get_href()); | 
12656  |  |           // Let host be the result of host parsing host_view with url is not  | 
12657  |  |           // special.  | 
12658  | 15.9k  |           if (host_view.empty()) { | 
12659  | 103  |             url.update_base_hostname(""); | 
12660  | 15.8k  |           } else if (!url.parse_host(host_view)) { | 
12661  | 3.79k  |             return url;  | 
12662  | 3.79k  |           }  | 
12663  | 12.1k  |           ada_log("HOST parsing results in ", url.get_hostname(), | 
12664  | 12.1k  |                   " href=", url.get_href());  | 
12665  |  |  | 
12666  |  |           // Set url’s host to host, and state to path start state.  | 
12667  | 12.1k  |           state = ada::state::PATH_START;  | 
12668  | 12.1k  |         }  | 
12669  |  |  | 
12670  | 14.4k  |         break;  | 
12671  | 18.8k  |       }  | 
12672  | 14.4k  |       case ada::state::OPAQUE_PATH: { | 
12673  | 4.43k  |         ada_log("OPAQUE_PATH ", helpers::substring(url_data, input_position)); | 
12674  | 4.43k  |         std::string_view view = helpers::substring(url_data, input_position);  | 
12675  |  |         // If c is U+003F (?), then set url’s query to the empty string and  | 
12676  |  |         // state to query state.  | 
12677  | 4.43k  |         size_t location = view.find('?'); | 
12678  | 4.43k  |         if (location != std::string_view::npos) { | 
12679  | 310  |           view.remove_suffix(view.size() - location);  | 
12680  | 310  |           state = ada::state::QUERY;  | 
12681  | 310  |           input_position += location + 1;  | 
12682  | 4.12k  |         } else { | 
12683  | 4.12k  |           input_position = input_size + 1;  | 
12684  | 4.12k  |         }  | 
12685  | 4.43k  |         url.has_opaque_path = true;  | 
12686  |  |         // This is a really unlikely scenario in real world. We should not seek  | 
12687  |  |         // to optimize it.  | 
12688  | 4.43k  |         url.update_base_pathname(unicode::percent_encode(  | 
12689  | 4.43k  |             view, character_sets::C0_CONTROL_PERCENT_ENCODE));  | 
12690  | 4.43k  |         break;  | 
12691  | 18.8k  |       }  | 
12692  | 2.37k  |       case ada::state::PORT: { | 
12693  | 2.37k  |         ada_log("PORT ", helpers::substring(url_data, input_position)); | 
12694  | 2.37k  |         std::string_view port_view =  | 
12695  | 2.37k  |             helpers::substring(url_data, input_position);  | 
12696  | 2.37k  |         size_t consumed_bytes = url.parse_port(port_view, true);  | 
12697  | 2.37k  |         input_position += consumed_bytes;  | 
12698  | 2.37k  |         if (!url.is_valid) { | 
12699  | 271  |           return url;  | 
12700  | 271  |         }  | 
12701  | 2.10k  |         state = state::PATH_START;  | 
12702  | 2.10k  |         [[fallthrough]];  | 
12703  | 2.10k  |       }  | 
12704  | 15.8k  |       case ada::state::PATH_START: { | 
12705  | 15.8k  |         ada_log("PATH_START ", helpers::substring(url_data, input_position)); | 
12706  |  |  | 
12707  |  |         // If url is special, then:  | 
12708  | 15.8k  |         if (url.is_special()) { | 
12709  |  |           // Set state to path state.  | 
12710  | 15.0k  |           state = ada::state::PATH;  | 
12711  |  |  | 
12712  |  |           // Optimization: Avoiding going into PATH state improves the  | 
12713  |  |           // performance of urls ending with /.  | 
12714  | 15.0k  |           if (input_position == input_size) { | 
12715  | 13.7k  |             url.update_base_pathname("/"); | 
12716  | 13.7k  |             if (fragment.has_value()) { | 
12717  | 256  |               url.update_unencoded_base_hash(*fragment);  | 
12718  | 256  |             }  | 
12719  | 13.7k  |             return url;  | 
12720  | 13.7k  |           }  | 
12721  |  |           // If c is neither U+002F (/) nor U+005C (\), then decrease pointer  | 
12722  |  |           // by 1. We know that (input_position == input_size) is impossible  | 
12723  |  |           // here, because of the previous if-check.  | 
12724  | 1.36k  |           if ((url_data[input_position] != '/') &&  | 
12725  | 1.36k  |               (url_data[input_position] != '\\')) { | 
12726  | 289  |             break;  | 
12727  | 289  |           }  | 
12728  | 1.36k  |         }  | 
12729  |  |         // Otherwise, if state override is not given and c is U+003F (?),  | 
12730  |  |         // set url’s query to the empty string and state to query state.  | 
12731  | 829  |         else if ((input_position != input_size) &&  | 
12732  | 829  |                  (url_data[input_position] == '?')) { | 
12733  | 86  |           state = ada::state::QUERY;  | 
12734  | 86  |         }  | 
12735  |  |         // Otherwise, if c is not the EOF code point:  | 
12736  | 743  |         else if (input_position != input_size) { | 
12737  |  |           // Set state to path state.  | 
12738  | 93  |           state = ada::state::PATH;  | 
12739  |  |  | 
12740  |  |           // If c is not U+002F (/), then decrease pointer by 1.  | 
12741  | 93  |           if (url_data[input_position] != '/') { | 
12742  | 0  |             break;  | 
12743  | 0  |           }  | 
12744  | 93  |         }  | 
12745  |  |  | 
12746  | 1.90k  |         input_position++;  | 
12747  | 1.90k  |         break;  | 
12748  | 15.8k  |       }  | 
12749  | 10.2k  |       case ada::state::PATH: { | 
12750  | 10.2k  |         std::string_view view = helpers::substring(url_data, input_position);  | 
12751  | 10.2k  |         ada_log("PATH ", helpers::substring(url_data, input_position)); | 
12752  |  |  | 
12753  |  |         // Most time, we do not need percent encoding.  | 
12754  |  |         // Furthermore, we can immediately locate the '?'.  | 
12755  | 10.2k  |         size_t locofquestionmark = view.find('?'); | 
12756  | 10.2k  |         if (locofquestionmark != std::string_view::npos) { | 
12757  | 552  |           state = ada::state::QUERY;  | 
12758  | 552  |           view.remove_suffix(view.size() - locofquestionmark);  | 
12759  | 552  |           input_position += locofquestionmark + 1;  | 
12760  | 9.72k  |         } else { | 
12761  | 9.72k  |           input_position = input_size + 1;  | 
12762  | 9.72k  |         }  | 
12763  | 10.2k  |         if constexpr (result_type_is_ada_url) { | 
12764  | 7.26k  |           helpers::parse_prepared_path(view, url.type, url.path);  | 
12765  | 7.26k  |         } else { | 
12766  | 7.26k  |           url.consume_prepared_path(view);  | 
12767  | 7.26k  |           ADA_ASSERT_TRUE(url.validate());  | 
12768  | 7.26k  |         }  | 
12769  | 10.2k  |         break;  | 
12770  | 15.8k  |       }  | 
12771  | 2.53k  |       case ada::state::FILE_SLASH: { | 
12772  | 2.53k  |         ada_log("FILE_SLASH ", helpers::substring(url_data, input_position)); | 
12773  |  |  | 
12774  |  |         // If c is U+002F (/) or U+005C (\), then:  | 
12775  | 2.53k  |         if ((input_position != input_size) &&  | 
12776  | 2.53k  |             (url_data[input_position] == '/' ||  | 
12777  | 2.20k  |              url_data[input_position] == '\\')) { | 
12778  | 2.10k  |           ada_log("FILE_SLASH c is U+002F or U+005C"); | 
12779  |  |           // Set state to file host state.  | 
12780  | 2.10k  |           state = ada::state::FILE_HOST;  | 
12781  | 2.10k  |           input_position++;  | 
12782  | 2.10k  |         } else { | 
12783  | 429  |           ada_log("FILE_SLASH otherwise"); | 
12784  |  |           // If base is non-null and base’s scheme is "file", then:  | 
12785  |  |           // Note: it is unsafe to do base_url->scheme unless you know that  | 
12786  |  |           // base_url_has_value() is true.  | 
12787  | 429  |           if (base_url != nullptr &&  | 
12788  | 429  |               base_url->type == ada::scheme::type::FILE) { | 
12789  |  |             // Set url’s host to base’s host.  | 
12790  | 261  |             if constexpr (result_type_is_ada_url) { | 
12791  | 261  |               url.host = base_url->host;  | 
12792  | 261  |             } else { | 
12793  |  |               // TODO: Optimization opportunity.  | 
12794  | 261  |               url.set_host(base_url->get_host());  | 
12795  | 261  |             }  | 
12796  |  |             // If the code point substring from pointer to the end of input does  | 
12797  |  |             // not start with a Windows drive letter and base’s path[0] is a  | 
12798  |  |             // normalized Windows drive letter, then append base’s path[0] to  | 
12799  |  |             // url’s path.  | 
12800  | 261  |             if (!base_url->get_pathname().empty()) { | 
12801  | 261  |               if (!checkers::is_windows_drive_letter(  | 
12802  | 261  |                       helpers::substring(url_data, input_position))) { | 
12803  | 256  |                 std::string_view first_base_url_path =  | 
12804  | 256  |                     base_url->get_pathname().substr(1);  | 
12805  | 256  |                 size_t loc = first_base_url_path.find('/'); | 
12806  | 256  |                 if (loc != std::string_view::npos) { | 
12807  | 12  |                   helpers::resize(first_base_url_path, loc);  | 
12808  | 12  |                 }  | 
12809  | 256  |                 if (checkers::is_normalized_windows_drive_letter(  | 
12810  | 256  |                         first_base_url_path)) { | 
12811  | 3  |                   if constexpr (result_type_is_ada_url) { | 
12812  | 3  |                     url.path += '/';  | 
12813  | 3  |                     url.path += first_base_url_path;  | 
12814  | 3  |                   } else { | 
12815  | 3  |                     url.append_base_pathname(  | 
12816  | 3  |                         helpers::concat("/", first_base_url_path)); | 
12817  | 3  |                   }  | 
12818  | 3  |                 }  | 
12819  | 256  |               }  | 
12820  | 261  |             }  | 
12821  | 261  |           }  | 
12822  |  |  | 
12823  |  |           // Set state to path state, and decrease pointer by 1.  | 
12824  | 429  |           state = ada::state::PATH;  | 
12825  | 429  |         }  | 
12826  |  |  | 
12827  | 2.53k  |         break;  | 
12828  | 15.8k  |       }  | 
12829  | 2.10k  |       case ada::state::FILE_HOST: { | 
12830  | 2.10k  |         std::string_view view = helpers::substring(url_data, input_position);  | 
12831  | 2.10k  |         ada_log("FILE_HOST ", helpers::substring(url_data, input_position)); | 
12832  |  |  | 
12833  | 2.10k  |         size_t location = view.find_first_of("/\\?"); | 
12834  | 2.10k  |         std::string_view file_host_buffer(  | 
12835  | 2.10k  |             view.data(),  | 
12836  | 2.10k  |             (location != std::string_view::npos) ? location : view.size());  | 
12837  |  |  | 
12838  | 2.10k  |         if (checkers::is_windows_drive_letter(file_host_buffer)) { | 
12839  | 29  |           state = ada::state::PATH;  | 
12840  | 2.07k  |         } else if (file_host_buffer.empty()) { | 
12841  |  |           // Set url’s host to the empty string.  | 
12842  | 57  |           if constexpr (result_type_is_ada_url) { | 
12843  | 43  |             url.host = "";  | 
12844  | 43  |           } else { | 
12845  | 43  |             url.update_base_hostname(""); | 
12846  | 43  |           }  | 
12847  |  |           // Set state to path start state.  | 
12848  | 57  |           state = ada::state::PATH_START;  | 
12849  | 2.02k  |         } else { | 
12850  | 2.02k  |           size_t consumed_bytes = file_host_buffer.size();  | 
12851  | 2.02k  |           input_position += consumed_bytes;  | 
12852  |  |           // Let host be the result of host parsing buffer with url is not  | 
12853  |  |           // special.  | 
12854  | 2.02k  |           if (!url.parse_host(file_host_buffer)) { | 
12855  | 392  |             return url;  | 
12856  | 392  |           }  | 
12857  |  |  | 
12858  | 1.62k  |           if constexpr (result_type_is_ada_url) { | 
12859  |  |             // If host is "localhost", then set host to the empty string.  | 
12860  | 1.26k  |             if (url.host.has_value() && url.host.value() == "localhost") { | 
12861  | 3  |               url.host = "";  | 
12862  | 3  |             }  | 
12863  | 1.26k  |           } else { | 
12864  | 1.26k  |             if (url.get_hostname() == "localhost") { | 
12865  | 10  |               url.update_base_hostname(""); | 
12866  | 10  |             }  | 
12867  | 1.26k  |           }  | 
12868  |  |  | 
12869  |  |           // Set buffer to the empty string and state to path start state.  | 
12870  | 1.62k  |           state = ada::state::PATH_START;  | 
12871  | 1.62k  |         }  | 
12872  |  |  | 
12873  | 1.71k  |         break;  | 
12874  | 2.10k  |       }  | 
12875  | 6.31k  |       case ada::state::FILE: { | 
12876  | 6.31k  |         ada_log("FILE ", helpers::substring(url_data, input_position)); | 
12877  | 6.31k  |         std::string_view file_view =  | 
12878  | 6.31k  |             helpers::substring(url_data, input_position);  | 
12879  |  |  | 
12880  | 6.31k  |         url.set_protocol_as_file();  | 
12881  | 6.31k  |         if constexpr (result_type_is_ada_url) { | 
12882  |  |           // Set url’s host to the empty string.  | 
12883  | 1.61k  |           url.host = "";  | 
12884  | 4.69k  |         } else { | 
12885  | 4.69k  |           url.update_base_hostname(""); | 
12886  | 4.69k  |         }  | 
12887  |  |         // If c is U+002F (/) or U+005C (\), then:  | 
12888  | 6.31k  |         if (input_position != input_size &&  | 
12889  | 6.31k  |             (url_data[input_position] == '/' ||  | 
12890  | 3.83k  |              url_data[input_position] == '\\')) { | 
12891  | 2.53k  |           ada_log("FILE c is U+002F or U+005C"); | 
12892  |  |           // Set state to file slash state.  | 
12893  | 2.53k  |           state = ada::state::FILE_SLASH;  | 
12894  | 2.53k  |         }  | 
12895  |  |         // Otherwise, if base is non-null and base’s scheme is "file":  | 
12896  | 3.77k  |         else if (base_url != nullptr &&  | 
12897  | 3.77k  |                  base_url->type == ada::scheme::type::FILE) { | 
12898  |  |           // Set url’s host to base’s host, url’s path to a clone of base’s  | 
12899  |  |           // path, and url’s query to base’s query.  | 
12900  | 380  |           ada_log("FILE base non-null"); | 
12901  | 380  |           if constexpr (result_type_is_ada_url) { | 
12902  | 380  |             url.host = base_url->host;  | 
12903  | 380  |             url.path = base_url->path;  | 
12904  | 380  |             url.query = base_url->query;  | 
12905  | 380  |           } else { | 
12906  |  |             // TODO: Get rid of set_hostname and replace it with  | 
12907  |  |             // update_base_hostname  | 
12908  | 380  |             url.set_hostname(base_url->get_hostname());  | 
12909  | 380  |             url.update_base_pathname(base_url->get_pathname());  | 
12910  | 380  |             url.update_base_search(base_url->get_search());  | 
12911  | 380  |           }  | 
12912  | 380  |           url.has_opaque_path = base_url->has_opaque_path;  | 
12913  |  |  | 
12914  |  |           // If c is U+003F (?), then set url’s query to the empty string and  | 
12915  |  |           // state to query state.  | 
12916  | 380  |           if (input_position != input_size && url_data[input_position] == '?') { | 
12917  | 2  |             state = ada::state::QUERY;  | 
12918  | 2  |           }  | 
12919  |  |           // Otherwise, if c is not the EOF code point:  | 
12920  | 378  |           else if (input_position != input_size) { | 
12921  |  |             // Set url’s query to null.  | 
12922  | 105  |             url.clear_search();  | 
12923  |  |             // If the code point substring from pointer to the end of input does  | 
12924  |  |             // not start with a Windows drive letter, then shorten url’s path.  | 
12925  | 105  |             if (!checkers::is_windows_drive_letter(file_view)) { | 
12926  | 93  |               if constexpr (result_type_is_ada_url) { | 
12927  | 93  |                 helpers::shorten_path(url.path, url.type);  | 
12928  | 93  |               } else { | 
12929  | 93  |                 std::string_view path = url.get_pathname();  | 
12930  | 93  |                 if (helpers::shorten_path(path, url.type)) { | 
12931  | 85  |                   url.update_base_pathname(std::string(path));  | 
12932  | 85  |                 }  | 
12933  | 93  |               }  | 
12934  | 93  |             }  | 
12935  |  |             // Otherwise:  | 
12936  | 12  |             else { | 
12937  |  |               // Set url’s path to an empty list.  | 
12938  | 12  |               url.clear_pathname();  | 
12939  | 12  |               url.has_opaque_path = true;  | 
12940  | 12  |             }  | 
12941  |  |  | 
12942  |  |             // Set state to path state and decrease pointer by 1.  | 
12943  | 105  |             state = ada::state::PATH;  | 
12944  | 105  |             break;  | 
12945  | 105  |           }  | 
12946  | 380  |         }  | 
12947  |  |         // Otherwise, set state to path state, and decrease pointer by 1.  | 
12948  | 3.39k  |         else { | 
12949  | 3.39k  |           ada_log("FILE go to path"); | 
12950  | 3.39k  |           state = ada::state::PATH;  | 
12951  | 3.39k  |           break;  | 
12952  | 3.39k  |         }  | 
12953  |  |  | 
12954  | 2.81k  |         input_position++;  | 
12955  | 2.81k  |         break;  | 
12956  | 6.31k  |       }  | 
12957  | 0  |       default:  | 
12958  | 0  |         ada::unreachable();  | 
12959  | 229k  |     }  | 
12960  | 229k  |   }  | 
12961  | 15.2k  |   if (fragment.has_value()) { | 
12962  | 565  |     url.update_unencoded_base_hash(*fragment);  | 
12963  | 565  |   }  | 
12964  | 15.2k  |   return url;  | 
12965  | 59.9k  | } ada::url ada::parser::parse_url<ada::url>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url const*) Line  | Count  | Source  |  12072  | 14.5k  |                       const result_type* base_url) { |  12073  |  |   // We can specialize the implementation per type.  |  12074  |  |   // Important: result_type_is_ada_url is evaluated at *compile time*. This  |  12075  |  |   // means that doing if constexpr(result_type_is_ada_url) { something } else { |  12076  |  |   // something else } is free (at runtime). This means that ada::url_aggregator  |  12077  |  |   // and ada::url **do not have to support the exact same API**.  |  12078  | 14.5k  |   constexpr bool result_type_is_ada_url =  |  12079  | 14.5k  |       std::is_same<ada::url, result_type>::value;  |  12080  | 14.5k  |   constexpr bool result_type_is_ada_url_aggregator =  |  12081  | 14.5k  |       std::is_same<ada::url_aggregator, result_type>::value;  |  12082  | 14.5k  |   static_assert(result_type_is_ada_url ||  |  12083  | 14.5k  |                 result_type_is_ada_url_aggregator);  // We don't support  |  12084  |  |                                                      // anything else for now.  |  12085  |  |  |  12086  | 14.5k  |   ada_log("ada::parser::parse_url('", user_input, "' [", user_input.size(), |  12087  | 14.5k  |           " bytes],", (base_url != nullptr ? base_url->to_string() : "null"),  |  12088  | 14.5k  |           ")");  |  12089  |  |  |  12090  | 14.5k  |   ada::state state = ada::state::SCHEME_START;  |  12091  | 14.5k  |   result_type url{}; |  12092  |  |  |  12093  |  |   // We refuse to parse URL strings that exceed 4GB. Such strings are almost  |  12094  |  |   // surely the result of a bug or are otherwise a security concern.  |  12095  | 14.5k  |   if (user_input.size() > std::numeric_limits<uint32_t>::max()) { |  12096  | 0  |     url.is_valid = false;  |  12097  | 0  |   }  |  12098  |  |   // Going forward, user_input.size() is in [0,  |  12099  |  |   // std::numeric_limits<uint32_t>::max). If we are provided with an invalid  |  12100  |  |   // base, or the optional_url was invalid, we must return.  |  12101  | 14.5k  |   if (base_url != nullptr) { |  12102  | 0  |     url.is_valid &= base_url->is_valid;  |  12103  | 0  |   }  |  12104  | 14.5k  |   if (!url.is_valid) { |  12105  | 0  |     return url;  |  12106  | 0  |   }  |  12107  | 14.5k  |   if constexpr (result_type_is_ada_url_aggregator) { |  12108  |  |     // Most of the time, we just need user_input.size().  |  12109  |  |     // In some instances, we may need a bit more.  |  12110  |  |     ///////////////////////////  |  12111  |  |     // This is *very* important. This line should be removed  |  12112  |  |     // hastily. There are principled reasons why reserve is important  |  12113  |  |     // for performance. If you have a benchmark with small inputs,  |  12114  |  |     // it may not matter, but in other instances, it could.  |  12115  |  |     ////  |  12116  |  |     // This rounds up to the next power of two.  |  12117  |  |     // We know that user_input.size() is in [0,  |  12118  |  |     // std::numeric_limits<uint32_t>::max).  |  12119  | 14.5k  |     uint32_t reserve_capacity =  |  12120  | 14.5k  |         (0xFFFFFFFF >>  |  12121  | 14.5k  |          helpers::leading_zeroes(uint32_t(1 | user_input.size()))) +  |  12122  | 14.5k  |         1;  |  12123  | 14.5k  |     url.reserve(reserve_capacity);  |  12124  |  |     //  |  12125  |  |     //  |  12126  |  |     //  |  12127  | 14.5k  |   }  |  12128  | 14.5k  |   std::string tmp_buffer;  |  12129  | 14.5k  |   std::string_view internal_input;  |  12130  | 14.5k  |   if (unicode::has_tabs_or_newline(user_input)) { |  12131  | 202  |     tmp_buffer = user_input;  |  12132  |  |     // Optimization opportunity: Instead of copying and then pruning, we could  |  12133  |  |     // just directly build the string from user_input.  |  12134  | 202  |     helpers::remove_ascii_tab_or_newline(tmp_buffer);  |  12135  | 202  |     internal_input = tmp_buffer;  |  12136  | 14.3k  |   } else { |  12137  | 14.3k  |     internal_input = user_input;  |  12138  | 14.3k  |   }  |  12139  |  |  |  12140  |  |   // Leading and trailing control characters are uncommon and easy to deal with  |  12141  |  |   // (no performance concern).  |  12142  | 14.5k  |   std::string_view url_data = internal_input;  |  12143  | 14.5k  |   helpers::trim_c0_whitespace(url_data);  |  12144  |  |  |  12145  |  |   // Optimization opportunity. Most websites do not have fragment.  |  12146  | 14.5k  |   std::optional<std::string_view> fragment = helpers::prune_hash(url_data);  |  12147  |  |   // We add it last so that an implementation like ada::url_aggregator  |  12148  |  |   // can append it last to its internal buffer, thus improving performance.  |  12149  |  |  |  12150  |  |   // Here url_data no longer has its fragment.  |  12151  |  |   // We are going to access the data from url_data (it is immutable).  |  12152  |  |   // At any given time, we are pointing at byte 'input_position' in url_data.  |  12153  |  |   // The input_position variable should range from 0 to input_size.  |  12154  |  |   // It is illegal to access url_data at input_size.  |  12155  | 14.5k  |   size_t input_position = 0;  |  12156  | 14.5k  |   const size_t input_size = url_data.size();  |  12157  |  |   // Keep running the following state machine by switching on state.  |  12158  |  |   // If after a run pointer points to the EOF code point, go to the next step.  |  12159  |  |   // Otherwise, increase pointer by 1 and continue with the state machine.  |  12160  |  |   // We never decrement input_position.  |  12161  | 65.3k  |   while (input_position <= input_size) { |  12162  | 61.2k  |     ada_log("In parsing at ", input_position, " out of ", input_size, |  12163  | 61.2k  |             " in state ", ada::to_string(state));  |  12164  | 61.2k  |     switch (state) { |  12165  | 14.5k  |       case ada::state::SCHEME_START: { |  12166  | 14.5k  |         ada_log("SCHEME_START ", helpers::substring(url_data, input_position)); |  12167  |  |         // If c is an ASCII alpha, append c, lowercased, to buffer, and set  |  12168  |  |         // state to scheme state.  |  12169  | 14.5k  |         if ((input_position != input_size) &&  |  12170  | 14.5k  |             checkers::is_alpha(url_data[input_position])) { |  12171  | 11.2k  |           state = ada::state::SCHEME;  |  12172  | 11.2k  |           input_position++;  |  12173  | 11.2k  |         } else { |  12174  |  |           // Otherwise, if state override is not given, set state to no scheme  |  12175  |  |           // state and decrease pointer by 1.  |  12176  | 3.27k  |           state = ada::state::NO_SCHEME;  |  12177  | 3.27k  |         }  |  12178  | 14.5k  |         break;  |  12179  | 0  |       }  |  12180  | 11.2k  |       case ada::state::SCHEME: { |  12181  | 11.2k  |         ada_log("SCHEME ", helpers::substring(url_data, input_position)); |  12182  |  |         // If c is an ASCII alphanumeric, U+002B (+), U+002D (-), or U+002E (.),  |  12183  |  |         // append c, lowercased, to buffer.  |  12184  | 38.6k  |         while ((input_position != input_size) &&  |  12185  | 38.6k  |                (ada::unicode::is_alnum_plus(url_data[input_position]))) { |  12186  | 27.3k  |           input_position++;  |  12187  | 27.3k  |         }  |  12188  |  |         // Otherwise, if c is U+003A (:), then:  |  12189  | 11.2k  |         if ((input_position != input_size) &&  |  12190  | 11.2k  |             (url_data[input_position] == ':')) { |  12191  | 10.2k  |           ada_log("SCHEME the scheme should be ", |  12192  | 10.2k  |                   url_data.substr(0, input_position));  |  12193  | 10.2k  |           if constexpr (result_type_is_ada_url) { |  12194  | 10.2k  |             if (!url.parse_scheme(url_data.substr(0, input_position))) { |  12195  | 0  |               return url;  |  12196  | 0  |             }  |  12197  | 10.2k  |           } else { |  12198  |  |             // we pass the colon along instead of painfully adding it back.  |  12199  | 10.2k  |             if (!url.parse_scheme_with_colon(  |  12200  | 10.2k  |                     url_data.substr(0, input_position + 1))) { |  12201  | 10.2k  |               return url;  |  12202  | 10.2k  |             }  |  12203  | 10.2k  |           }  |  12204  | 10.2k  |           ada_log("SCHEME the scheme is ", url.get_protocol()); |  12205  |  |  |  12206  |  |           // If url’s scheme is "file", then:  |  12207  | 10.2k  |           if (url.type == ada::scheme::type::FILE) { |  12208  |  |             // Set state to file state.  |  12209  | 1.61k  |             state = ada::state::FILE;  |  12210  | 1.61k  |           }  |  12211  |  |           // Otherwise, if url is special, base is non-null, and base’s scheme  |  12212  |  |           // is url’s scheme: Note: Doing base_url->scheme is unsafe if base_url  |  12213  |  |           // != nullptr is false.  |  12214  | 8.60k  |           else if (url.is_special() && base_url != nullptr &&  |  12215  | 8.60k  |                    base_url->type == url.type) { |  12216  |  |             // Set state to special relative or authority state.  |  12217  | 0  |             state = ada::state::SPECIAL_RELATIVE_OR_AUTHORITY;  |  12218  | 0  |           }  |  12219  |  |           // Otherwise, if url is special, set state to special authority  |  12220  |  |           // slashes state.  |  12221  | 8.60k  |           else if (url.is_special()) { |  12222  | 5.66k  |             state = ada::state::SPECIAL_AUTHORITY_SLASHES;  |  12223  | 5.66k  |           }  |  12224  |  |           // Otherwise, if remaining starts with an U+002F (/), set state to  |  12225  |  |           // path or authority state and increase pointer by 1.  |  12226  | 2.94k  |           else if (input_position + 1 < input_size &&  |  12227  | 2.94k  |                    url_data[input_position + 1] == '/') { |  12228  | 1.85k  |             state = ada::state::PATH_OR_AUTHORITY;  |  12229  | 1.85k  |             input_position++;  |  12230  | 1.85k  |           }  |  12231  |  |           // Otherwise, set url’s path to the empty string and set state to  |  12232  |  |           // opaque path state.  |  12233  | 1.09k  |           else { |  12234  | 1.09k  |             state = ada::state::OPAQUE_PATH;  |  12235  | 1.09k  |           }  |  12236  | 10.2k  |         }  |  12237  |  |         // Otherwise, if state override is not given, set buffer to the empty  |  12238  |  |         // string, state to no scheme state, and start over (from the first code  |  12239  |  |         // point in input).  |  12240  | 1.00k  |         else { |  12241  | 1.00k  |           state = ada::state::NO_SCHEME;  |  12242  | 1.00k  |           input_position = 0;  |  12243  | 1.00k  |           break;  |  12244  | 1.00k  |         }  |  12245  | 10.2k  |         input_position++;  |  12246  | 10.2k  |         break;  |  12247  | 11.2k  |       }  |  12248  | 4.28k  |       case ada::state::NO_SCHEME: { |  12249  | 4.28k  |         ada_log("NO_SCHEME ", helpers::substring(url_data, input_position)); |  12250  |  |         // If base is null, or base has an opaque path and c is not U+0023 (#),  |  12251  |  |         // validation error, return failure.  |  12252  | 4.28k  |         if (base_url == nullptr ||  |  12253  | 4.28k  |             (base_url->has_opaque_path && !fragment.has_value())) { |  12254  | 4.28k  |           ada_log("NO_SCHEME validation error"); |  12255  | 4.28k  |           url.is_valid = false;  |  12256  | 4.28k  |           return url;  |  12257  | 4.28k  |         }  |  12258  |  |         // Otherwise, if base has an opaque path and c is U+0023 (#),  |  12259  |  |         // set url’s scheme to base’s scheme, url’s path to base’s path, url’s  |  12260  |  |         // query to base’s query, and set state to fragment state.  |  12261  | 0  |         else if (base_url->has_opaque_path && fragment.has_value() &&  |  12262  | 0  |                  input_position == input_size) { |  12263  | 0  |           ada_log("NO_SCHEME opaque base with fragment"); |  12264  | 0  |           url.copy_scheme(*base_url);  |  12265  | 0  |           url.has_opaque_path = base_url->has_opaque_path;  |  12266  |  | 
  |  12267  | 0  |           if constexpr (result_type_is_ada_url) { |  12268  | 0  |             url.path = base_url->path;  |  12269  | 0  |             url.query = base_url->query;  |  12270  | 0  |           } else { |  12271  | 0  |             url.update_base_pathname(base_url->get_pathname());  |  12272  | 0  |             url.update_base_search(base_url->get_search());  |  12273  | 0  |           }  |  12274  | 0  |           url.update_unencoded_base_hash(*fragment);  |  12275  | 0  |           return url;  |  12276  | 0  |         }  |  12277  |  |         // Otherwise, if base’s scheme is not "file", set state to relative  |  12278  |  |         // state and decrease pointer by 1.  |  12279  | 0  |         else if (base_url->type != ada::scheme::type::FILE) { |  12280  | 0  |           ada_log("NO_SCHEME non-file relative path"); |  12281  | 0  |           state = ada::state::RELATIVE_SCHEME;  |  12282  | 0  |         }  |  12283  |  |         // Otherwise, set state to file state and decrease pointer by 1.  |  12284  | 0  |         else { |  12285  | 0  |           ada_log("NO_SCHEME file base type"); |  12286  | 0  |           state = ada::state::FILE;  |  12287  | 0  |         }  |  12288  | 0  |         break;  |  12289  | 4.28k  |       }  |  12290  | 6.03k  |       case ada::state::AUTHORITY: { |  12291  | 6.03k  |         ada_log("AUTHORITY ", helpers::substring(url_data, input_position)); |  12292  |  |         // most URLs have no @. Having no @ tells us that we don't have to worry  |  12293  |  |         // about AUTHORITY. Of course, we could have @ and still not have to  |  12294  |  |         // worry about AUTHORITY.  |  12295  |  |         // TODO: Instead of just collecting a bool, collect the location of the  |  12296  |  |         // '@' and do something useful with it.  |  12297  |  |         // TODO: We could do various processing early on, using a single pass  |  12298  |  |         // over the string to collect information about it, e.g., telling us  |  12299  |  |         // whether there is a @ and if so, where (or how many).  |  12300  | 6.03k  |         const bool contains_ampersand =  |  12301  | 6.03k  |             (url_data.find('@', input_position) != std::string_view::npos); |  12302  |  |  |  12303  | 6.03k  |         if (!contains_ampersand) { |  12304  | 5.60k  |           state = ada::state::HOST;  |  12305  | 5.60k  |           break;  |  12306  | 5.60k  |         }  |  12307  | 431  |         bool at_sign_seen{false}; |  12308  | 431  |         bool password_token_seen{false}; |  12309  |  |         /**  |  12310  |  |          * We expect something of the sort...  |  12311  |  |          * https://user:pass@example.com:1234/foo/bar?baz#quux  |  12312  |  |          * --------^  |  12313  |  |          */  |  12314  | 3.23k  |         do { |  12315  | 3.23k  |           std::string_view view = helpers::substring(url_data, input_position);  |  12316  |  |           // The delimiters are @, /, ? \\.  |  12317  | 3.23k  |           size_t location =  |  12318  | 3.23k  |               url.is_special() ? helpers::find_authority_delimiter_special(view)  |  12319  | 3.23k  |                                : helpers::find_authority_delimiter(view);  |  12320  | 3.23k  |           std::string_view authority_view(view.data(), location);  |  12321  | 3.23k  |           size_t end_of_authority = input_position + authority_view.size();  |  12322  |  |           // If c is U+0040 (@), then:  |  12323  | 3.23k  |           if ((end_of_authority != input_size) &&  |  12324  | 3.23k  |               (url_data[end_of_authority] == '@')) { |  12325  |  |             // If atSignSeen is true, then prepend "%40" to buffer.  |  12326  | 2.80k  |             if (at_sign_seen) { |  12327  | 2.39k  |               if (password_token_seen) { |  12328  | 580  |                 if constexpr (result_type_is_ada_url) { |  12329  | 580  |                   url.password += "%40";  |  12330  | 580  |                 } else { |  12331  | 580  |                   url.append_base_password("%40"); |  12332  | 580  |                 }  |  12333  | 1.81k  |               } else { |  12334  | 1.81k  |                 if constexpr (result_type_is_ada_url) { |  12335  | 1.81k  |                   url.username += "%40";  |  12336  | 1.81k  |                 } else { |  12337  | 1.81k  |                   url.append_base_username("%40"); |  12338  | 1.81k  |                 }  |  12339  | 1.81k  |               }  |  12340  | 2.39k  |             }  |  12341  |  |  |  12342  | 2.80k  |             at_sign_seen = true;  |  12343  |  |  |  12344  | 2.80k  |             if (!password_token_seen) { |  12345  | 2.22k  |               size_t password_token_location = authority_view.find(':'); |  12346  | 2.22k  |               password_token_seen =  |  12347  | 2.22k  |                   password_token_location != std::string_view::npos;  |  12348  |  |  |  12349  | 2.22k  |               if (!password_token_seen) { |  12350  | 2.08k  |                 if constexpr (result_type_is_ada_url) { |  12351  | 2.08k  |                   url.username += unicode::percent_encode(  |  12352  | 2.08k  |                       authority_view, character_sets::USERINFO_PERCENT_ENCODE);  |  12353  | 2.08k  |                 } else { |  12354  | 2.08k  |                   url.append_base_username(unicode::percent_encode(  |  12355  | 2.08k  |                       authority_view, character_sets::USERINFO_PERCENT_ENCODE));  |  12356  | 2.08k  |                 }  |  12357  | 2.08k  |               } else { |  12358  | 140  |                 if constexpr (result_type_is_ada_url) { |  12359  | 140  |                   url.username += unicode::percent_encode(  |  12360  | 140  |                       authority_view.substr(0, password_token_location),  |  12361  | 140  |                       character_sets::USERINFO_PERCENT_ENCODE);  |  12362  | 140  |                   url.password += unicode::percent_encode(  |  12363  | 140  |                       authority_view.substr(password_token_location + 1),  |  12364  | 140  |                       character_sets::USERINFO_PERCENT_ENCODE);  |  12365  | 140  |                 } else { |  12366  | 140  |                   url.append_base_username(unicode::percent_encode(  |  12367  | 140  |                       authority_view.substr(0, password_token_location),  |  12368  | 140  |                       character_sets::USERINFO_PERCENT_ENCODE));  |  12369  | 140  |                   url.append_base_password(unicode::percent_encode(  |  12370  | 140  |                       authority_view.substr(password_token_location + 1),  |  12371  | 140  |                       character_sets::USERINFO_PERCENT_ENCODE));  |  12372  | 140  |                 }  |  12373  | 140  |               }  |  12374  | 2.22k  |             } else { |  12375  | 580  |               if constexpr (result_type_is_ada_url) { |  12376  | 580  |                 url.password += unicode::percent_encode(  |  12377  | 580  |                     authority_view, character_sets::USERINFO_PERCENT_ENCODE);  |  12378  | 580  |               } else { |  12379  | 580  |                 url.append_base_password(unicode::percent_encode(  |  12380  | 580  |                     authority_view, character_sets::USERINFO_PERCENT_ENCODE));  |  12381  | 580  |               }  |  12382  | 580  |             }  |  12383  | 2.80k  |           }  |  12384  |  |           // Otherwise, if one of the following is true:  |  12385  |  |           // - c is the EOF code point, U+002F (/), U+003F (?), or U+0023 (#)  |  12386  |  |           // - url is special and c is U+005C (\)  |  12387  | 431  |           else if (end_of_authority == input_size ||  |  12388  | 431  |                    url_data[end_of_authority] == '/' ||  |  12389  | 431  |                    url_data[end_of_authority] == '?' ||  |  12390  | 431  |                    (url.is_special() && url_data[end_of_authority] == '\\')) { |  12391  |  |             // If atSignSeen is true and authority_view is the empty string,  |  12392  |  |             // validation error, return failure.  |  12393  | 431  |             if (at_sign_seen && authority_view.empty()) { |  12394  | 232  |               url.is_valid = false;  |  12395  | 232  |               return url;  |  12396  | 232  |             }  |  12397  | 199  |             state = ada::state::HOST;  |  12398  | 199  |             break;  |  12399  | 431  |           }  |  12400  | 2.80k  |           if (end_of_authority == input_size) { |  12401  | 0  |             if (fragment.has_value()) { |  12402  | 0  |               url.update_unencoded_base_hash(*fragment);  |  12403  | 0  |             }  |  12404  | 0  |             return url;  |  12405  | 0  |           }  |  12406  | 2.80k  |           input_position = end_of_authority + 1;  |  12407  | 2.80k  |         } while (true);  |  12408  |  |  |  12409  | 199  |         break;  |  12410  | 431  |       }  |  12411  | 199  |       case ada::state::SPECIAL_RELATIVE_OR_AUTHORITY: { |  12412  | 0  |         ada_log("SPECIAL_RELATIVE_OR_AUTHORITY ", |  12413  | 0  |                 helpers::substring(url_data, input_position));  |  12414  |  |  |  12415  |  |         // If c is U+002F (/) and remaining starts with U+002F (/),  |  12416  |  |         // then set state to special authority ignore slashes state and increase  |  12417  |  |         // pointer by 1.  |  12418  | 0  |         std::string_view view = helpers::substring(url_data, input_position);  |  12419  | 0  |         if (ada::checkers::begins_with(view, "//")) { |  12420  | 0  |           state = ada::state::SPECIAL_AUTHORITY_IGNORE_SLASHES;  |  12421  | 0  |           input_position += 2;  |  12422  | 0  |         } else { |  12423  |  |           // Otherwise, validation error, set state to relative state and  |  12424  |  |           // decrease pointer by 1.  |  12425  | 0  |           state = ada::state::RELATIVE_SCHEME;  |  12426  | 0  |         }  |  12427  |  | 
  |  12428  | 0  |         break;  |  12429  | 431  |       }  |  12430  | 1.85k  |       case ada::state::PATH_OR_AUTHORITY: { |  12431  | 1.85k  |         ada_log("PATH_OR_AUTHORITY ", |  12432  | 1.85k  |                 helpers::substring(url_data, input_position));  |  12433  |  |  |  12434  |  |         // If c is U+002F (/), then set state to authority state.  |  12435  | 1.85k  |         if ((input_position != input_size) &&  |  12436  | 1.85k  |             (url_data[input_position] == '/')) { |  12437  | 372  |           state = ada::state::AUTHORITY;  |  12438  | 372  |           input_position++;  |  12439  | 1.47k  |         } else { |  12440  |  |           // Otherwise, set state to path state, and decrease pointer by 1.  |  12441  | 1.47k  |           state = ada::state::PATH;  |  12442  | 1.47k  |         }  |  12443  |  |  |  12444  | 1.85k  |         break;  |  12445  | 431  |       }  |  12446  | 0  |       case ada::state::RELATIVE_SCHEME: { |  12447  | 0  |         ada_log("RELATIVE_SCHEME ", |  12448  | 0  |                 helpers::substring(url_data, input_position));  |  12449  |  |  |  12450  |  |         // Set url’s scheme to base’s scheme.  |  12451  | 0  |         url.copy_scheme(*base_url);  |  12452  |  |  |  12453  |  |         // If c is U+002F (/), then set state to relative slash state.  |  12454  | 0  |         if ((input_position != input_size) &&  |  12455  | 0  |             (url_data[input_position] == '/')) { |  12456  | 0  |           ada_log(  |  12457  | 0  |               "RELATIVE_SCHEME if c is U+002F (/), then set state to relative "  |  12458  | 0  |               "slash state");  |  12459  | 0  |           state = ada::state::RELATIVE_SLASH;  |  12460  | 0  |         } else if (url.is_special() && (input_position != input_size) &&  |  12461  | 0  |                    (url_data[input_position] == '\\')) { |  12462  |  |           // Otherwise, if url is special and c is U+005C (\), validation error,  |  12463  |  |           // set state to relative slash state.  |  12464  | 0  |           ada_log(  |  12465  | 0  |               "RELATIVE_SCHEME  if url is special and c is U+005C, validation "  |  12466  | 0  |               "error, set state to relative slash state");  |  12467  | 0  |           state = ada::state::RELATIVE_SLASH;  |  12468  | 0  |         } else { |  12469  | 0  |           ada_log("RELATIVE_SCHEME otherwise"); |  12470  |  |           // Set url’s username to base’s username, url’s password to base’s  |  12471  |  |           // password, url’s host to base’s host, url’s port to base’s port,  |  12472  |  |           // url’s path to a clone of base’s path, and url’s query to base’s  |  12473  |  |           // query.  |  12474  | 0  |           if constexpr (result_type_is_ada_url) { |  12475  | 0  |             url.username = base_url->username;  |  12476  | 0  |             url.password = base_url->password;  |  12477  | 0  |             url.host = base_url->host;  |  12478  | 0  |             url.port = base_url->port;  |  12479  |  |             // cloning the base path includes cloning the has_opaque_path flag  |  12480  | 0  |             url.has_opaque_path = base_url->has_opaque_path;  |  12481  | 0  |             url.path = base_url->path;  |  12482  | 0  |             url.query = base_url->query;  |  12483  | 0  |           } else { |  12484  | 0  |             url.update_base_authority(base_url->get_href(),  |  12485  | 0  |                                       base_url->get_components());  |  12486  |  |             // TODO: Get rid of set_hostname and replace it with  |  12487  |  |             // update_base_hostname  |  12488  | 0  |             url.set_hostname(base_url->get_hostname());  |  12489  | 0  |             url.update_base_port(base_url->retrieve_base_port());  |  12490  |  |             // cloning the base path includes cloning the has_opaque_path flag  |  12491  | 0  |             url.has_opaque_path = base_url->has_opaque_path;  |  12492  | 0  |             url.update_base_pathname(base_url->get_pathname());  |  12493  | 0  |             url.update_base_search(base_url->get_search());  |  12494  | 0  |           }  |  12495  |  | 
  |  12496  | 0  |           url.has_opaque_path = base_url->has_opaque_path;  |  12497  |  |  |  12498  |  |           // If c is U+003F (?), then set url’s query to the empty string, and  |  12499  |  |           // state to query state.  |  12500  | 0  |           if ((input_position != input_size) &&  |  12501  | 0  |               (url_data[input_position] == '?')) { |  12502  | 0  |             state = ada::state::QUERY;  |  12503  | 0  |           }  |  12504  |  |           // Otherwise, if c is not the EOF code point:  |  12505  | 0  |           else if (input_position != input_size) { |  12506  |  |             // Set url’s query to null.  |  12507  | 0  |             url.clear_search();  |  12508  | 0  |             if constexpr (result_type_is_ada_url) { |  12509  |  |               // Shorten url’s path.  |  12510  | 0  |               helpers::shorten_path(url.path, url.type);  |  12511  | 0  |             } else { |  12512  | 0  |               std::string_view path = url.get_pathname();  |  12513  | 0  |               if (helpers::shorten_path(path, url.type)) { |  12514  | 0  |                 url.update_base_pathname(std::string(path));  |  12515  | 0  |               }  |  12516  | 0  |             }  |  12517  |  |             // Set state to path state and decrease pointer by 1.  |  12518  | 0  |             state = ada::state::PATH;  |  12519  | 0  |             break;  |  12520  | 0  |           }  |  12521  | 0  |         }  |  12522  | 0  |         input_position++;  |  12523  | 0  |         break;  |  12524  | 0  |       }  |  12525  | 0  |       case ada::state::RELATIVE_SLASH: { |  12526  | 0  |         ada_log("RELATIVE_SLASH ", |  12527  | 0  |                 helpers::substring(url_data, input_position));  |  12528  |  |  |  12529  |  |         // If url is special and c is U+002F (/) or U+005C (\), then:  |  12530  | 0  |         if (url.is_special() && (input_position != input_size) &&  |  12531  | 0  |             (url_data[input_position] == '/' ||  |  12532  | 0  |              url_data[input_position] == '\\')) { |  12533  |  |           // Set state to special authority ignore slashes state.  |  12534  | 0  |           state = ada::state::SPECIAL_AUTHORITY_IGNORE_SLASHES;  |  12535  | 0  |         }  |  12536  |  |         // Otherwise, if c is U+002F (/), then set state to authority state.  |  12537  | 0  |         else if ((input_position != input_size) &&  |  12538  | 0  |                  (url_data[input_position] == '/')) { |  12539  | 0  |           state = ada::state::AUTHORITY;  |  12540  | 0  |         }  |  12541  |  |         // Otherwise, set  |  12542  |  |         // - url’s username to base’s username,  |  12543  |  |         // - url’s password to base’s password,  |  12544  |  |         // - url’s host to base’s host,  |  12545  |  |         // - url’s port to base’s port,  |  12546  |  |         // - state to path state, and then, decrease pointer by 1.  |  12547  | 0  |         else { |  12548  | 0  |           if constexpr (result_type_is_ada_url) { |  12549  | 0  |             url.username = base_url->username;  |  12550  | 0  |             url.password = base_url->password;  |  12551  | 0  |             url.host = base_url->host;  |  12552  | 0  |             url.port = base_url->port;  |  12553  | 0  |           } else { |  12554  | 0  |             url.update_base_authority(base_url->get_href(),  |  12555  | 0  |                                       base_url->get_components());  |  12556  |  |             // TODO: Get rid of set_hostname and replace it with  |  12557  |  |             // update_base_hostname  |  12558  | 0  |             url.set_hostname(base_url->get_hostname());  |  12559  | 0  |             url.update_base_port(base_url->retrieve_base_port());  |  12560  | 0  |           }  |  12561  | 0  |           state = ada::state::PATH;  |  12562  | 0  |           break;  |  12563  | 0  |         }  |  12564  |  |  |  12565  | 0  |         input_position++;  |  12566  | 0  |         break;  |  12567  | 0  |       }  |  12568  | 5.66k  |       case ada::state::SPECIAL_AUTHORITY_SLASHES: { |  12569  | 5.66k  |         ada_log("SPECIAL_AUTHORITY_SLASHES ", |  12570  | 5.66k  |                 helpers::substring(url_data, input_position));  |  12571  |  |  |  12572  |  |         // If c is U+002F (/) and remaining starts with U+002F (/),  |  12573  |  |         // then set state to special authority ignore slashes state and increase  |  12574  |  |         // pointer by 1.  |  12575  | 5.66k  |         state = ada::state::SPECIAL_AUTHORITY_IGNORE_SLASHES;  |  12576  | 5.66k  |         std::string_view view = helpers::substring(url_data, input_position);  |  12577  | 5.66k  |         if (ada::checkers::begins_with(view, "//")) { |  12578  | 14  |           input_position += 2;  |  12579  | 14  |         }  |  12580  |  |  |  12581  | 5.66k  |         [[fallthrough]];  |  12582  | 5.66k  |       }  |  12583  | 5.66k  |       case ada::state::SPECIAL_AUTHORITY_IGNORE_SLASHES: { |  12584  | 5.66k  |         ada_log("SPECIAL_AUTHORITY_IGNORE_SLASHES ", |  12585  | 5.66k  |                 helpers::substring(url_data, input_position));  |  12586  |  |  |  12587  |  |         // If c is neither U+002F (/) nor U+005C (\), then set state to  |  12588  |  |         // authority state and decrease pointer by 1.  |  12589  | 6.18k  |         while ((input_position != input_size) &&  |  12590  | 6.18k  |                ((url_data[input_position] == '/') ||  |  12591  | 6.15k  |                 (url_data[input_position] == '\\'))) { |  12592  | 526  |           input_position++;  |  12593  | 526  |         }  |  12594  | 5.66k  |         state = ada::state::AUTHORITY;  |  12595  |  |  |  12596  | 5.66k  |         break;  |  12597  | 5.66k  |       }  |  12598  | 268  |       case ada::state::QUERY: { |  12599  | 268  |         ada_log("QUERY ", helpers::substring(url_data, input_position)); |  12600  |  |         // Let queryPercentEncodeSet be the special-query percent-encode set if  |  12601  |  |         // url is special; otherwise the query percent-encode set.  |  12602  | 268  |         const uint8_t* query_percent_encode_set =  |  12603  | 268  |             url.is_special() ? ada::character_sets::SPECIAL_QUERY_PERCENT_ENCODE  |  12604  | 268  |                              : ada::character_sets::QUERY_PERCENT_ENCODE;  |  12605  |  |  |  12606  |  |         // Percent-encode after encoding, with encoding, buffer, and  |  12607  |  |         // queryPercentEncodeSet, and append the result to url’s query.  |  12608  | 268  |         url.update_base_search(helpers::substring(url_data, input_position),  |  12609  | 268  |                                query_percent_encode_set);  |  12610  | 268  |         ada_log("QUERY update_base_search completed "); |  12611  | 268  |         if (fragment.has_value()) { |  12612  | 26  |           url.update_unencoded_base_hash(*fragment);  |  12613  | 26  |         }  |  12614  | 268  |         return url;  |  12615  | 5.66k  |       }  |  12616  | 5.80k  |       case ada::state::HOST: { |  12617  | 5.80k  |         ada_log("HOST ", helpers::substring(url_data, input_position)); |  12618  |  |  |  12619  | 5.80k  |         std::string_view host_view =  |  12620  | 5.80k  |             helpers::substring(url_data, input_position);  |  12621  | 5.80k  |         auto [location, found_colon] =  |  12622  | 5.80k  |             helpers::get_host_delimiter_location(url.is_special(), host_view);  |  12623  | 5.80k  |         input_position = (location != std::string_view::npos)  |  12624  | 5.80k  |                              ? input_position + location  |  12625  | 5.80k  |                              : input_size;  |  12626  |  |         // Otherwise, if c is U+003A (:) and insideBrackets is false, then:  |  12627  |  |         // Note: the 'found_colon' value is true if and only if a colon was  |  12628  |  |         // encountered while not inside brackets.  |  12629  | 5.80k  |         if (found_colon) { |  12630  |  |           // If buffer is the empty string, validation error, return failure.  |  12631  |  |           // Let host be the result of host parsing buffer with url is not  |  12632  |  |           // special.  |  12633  | 867  |           ada_log("HOST parsing ", host_view); |  12634  | 867  |           if (!url.parse_host(host_view)) { |  12635  | 139  |             return url;  |  12636  | 139  |           }  |  12637  | 728  |           ada_log("HOST parsing results in ", url.get_hostname()); |  12638  |  |           // Set url’s host to host, buffer to the empty string, and state to  |  12639  |  |           // port state.  |  12640  | 728  |           state = ada::state::PORT;  |  12641  | 728  |           input_position++;  |  12642  | 728  |         }  |  12643  |  |         // Otherwise, if one of the following is true:  |  12644  |  |         // - c is the EOF code point, U+002F (/), U+003F (?), or U+0023 (#)  |  12645  |  |         // - url is special and c is U+005C (\)  |  12646  |  |         // The get_host_delimiter_location function either brings us to  |  12647  |  |         // the colon outside of the bracket, or to one of those characters.  |  12648  | 4.93k  |         else { |  12649  |  |           // If url is special and host_view is the empty string, validation  |  12650  |  |           // error, return failure.  |  12651  | 4.93k  |           if (url.is_special() && host_view.empty()) { |  12652  | 40  |             url.is_valid = false;  |  12653  | 40  |             return url;  |  12654  | 40  |           }  |  12655  | 4.89k  |           ada_log("HOST parsing ", host_view, " href=", url.get_href()); |  12656  |  |           // Let host be the result of host parsing host_view with url is not  |  12657  |  |           // special.  |  12658  | 4.89k  |           if (host_view.empty()) { |  12659  | 28  |             url.update_base_hostname(""); |  12660  | 4.86k  |           } else if (!url.parse_host(host_view)) { |  12661  | 1.19k  |             return url;  |  12662  | 1.19k  |           }  |  12663  | 3.70k  |           ada_log("HOST parsing results in ", url.get_hostname(), |  12664  | 3.70k  |                   " href=", url.get_href());  |  12665  |  |  |  12666  |  |           // Set url’s host to host, and state to path start state.  |  12667  | 3.70k  |           state = ada::state::PATH_START;  |  12668  | 3.70k  |         }  |  12669  |  |  |  12670  | 4.42k  |         break;  |  12671  | 5.80k  |       }  |  12672  | 4.42k  |       case ada::state::OPAQUE_PATH: { |  12673  | 1.09k  |         ada_log("OPAQUE_PATH ", helpers::substring(url_data, input_position)); |  12674  | 1.09k  |         std::string_view view = helpers::substring(url_data, input_position);  |  12675  |  |         // If c is U+003F (?), then set url’s query to the empty string and  |  12676  |  |         // state to query state.  |  12677  | 1.09k  |         size_t location = view.find('?'); |  12678  | 1.09k  |         if (location != std::string_view::npos) { |  12679  | 86  |           view.remove_suffix(view.size() - location);  |  12680  | 86  |           state = ada::state::QUERY;  |  12681  | 86  |           input_position += location + 1;  |  12682  | 1.00k  |         } else { |  12683  | 1.00k  |           input_position = input_size + 1;  |  12684  | 1.00k  |         }  |  12685  | 1.09k  |         url.has_opaque_path = true;  |  12686  |  |         // This is a really unlikely scenario in real world. We should not seek  |  12687  |  |         // to optimize it.  |  12688  | 1.09k  |         url.update_base_pathname(unicode::percent_encode(  |  12689  | 1.09k  |             view, character_sets::C0_CONTROL_PERCENT_ENCODE));  |  12690  | 1.09k  |         break;  |  12691  | 5.80k  |       }  |  12692  | 728  |       case ada::state::PORT: { |  12693  | 728  |         ada_log("PORT ", helpers::substring(url_data, input_position)); |  12694  | 728  |         std::string_view port_view =  |  12695  | 728  |             helpers::substring(url_data, input_position);  |  12696  | 728  |         size_t consumed_bytes = url.parse_port(port_view, true);  |  12697  | 728  |         input_position += consumed_bytes;  |  12698  | 728  |         if (!url.is_valid) { |  12699  | 84  |           return url;  |  12700  | 84  |         }  |  12701  | 644  |         state = state::PATH_START;  |  12702  | 644  |         [[fallthrough]];  |  12703  | 644  |       }  |  12704  | 4.72k  |       case ada::state::PATH_START: { |  12705  | 4.72k  |         ada_log("PATH_START ", helpers::substring(url_data, input_position)); |  12706  |  |  |  12707  |  |         // If url is special, then:  |  12708  | 4.72k  |         if (url.is_special()) { |  12709  |  |           // Set state to path state.  |  12710  | 4.46k  |           state = ada::state::PATH;  |  12711  |  |  |  12712  |  |           // Optimization: Avoiding going into PATH state improves the  |  12713  |  |           // performance of urls ending with /.  |  12714  | 4.46k  |           if (input_position == input_size) { |  12715  | 4.05k  |             url.update_base_pathname("/"); |  12716  | 4.05k  |             if (fragment.has_value()) { |  12717  | 80  |               url.update_unencoded_base_hash(*fragment);  |  12718  | 80  |             }  |  12719  | 4.05k  |             return url;  |  12720  | 4.05k  |           }  |  12721  |  |           // If c is neither U+002F (/) nor U+005C (\), then decrease pointer  |  12722  |  |           // by 1. We know that (input_position == input_size) is impossible  |  12723  |  |           // here, because of the previous if-check.  |  12724  | 404  |           if ((url_data[input_position] != '/') &&  |  12725  | 404  |               (url_data[input_position] != '\\')) { |  12726  | 87  |             break;  |  12727  | 87  |           }  |  12728  | 404  |         }  |  12729  |  |         // Otherwise, if state override is not given and c is U+003F (?),  |  12730  |  |         // set url’s query to the empty string and state to query state.  |  12731  | 259  |         else if ((input_position != input_size) &&  |  12732  | 259  |                  (url_data[input_position] == '?')) { |  12733  | 27  |           state = ada::state::QUERY;  |  12734  | 27  |         }  |  12735  |  |         // Otherwise, if c is not the EOF code point:  |  12736  | 232  |         else if (input_position != input_size) { |  12737  |  |           // Set state to path state.  |  12738  | 29  |           state = ada::state::PATH;  |  12739  |  |  |  12740  |  |           // If c is not U+002F (/), then decrease pointer by 1.  |  12741  | 29  |           if (url_data[input_position] != '/') { |  12742  | 0  |             break;  |  12743  | 0  |           }  |  12744  | 29  |         }  |  12745  |  |  |  12746  | 576  |         input_position++;  |  12747  | 576  |         break;  |  12748  | 4.72k  |       }  |  12749  | 3.01k  |       case ada::state::PATH: { |  12750  | 3.01k  |         std::string_view view = helpers::substring(url_data, input_position);  |  12751  | 3.01k  |         ada_log("PATH ", helpers::substring(url_data, input_position)); |  12752  |  |  |  12753  |  |         // Most time, we do not need percent encoding.  |  12754  |  |         // Furthermore, we can immediately locate the '?'.  |  12755  | 3.01k  |         size_t locofquestionmark = view.find('?'); |  12756  | 3.01k  |         if (locofquestionmark != std::string_view::npos) { |  12757  | 155  |           state = ada::state::QUERY;  |  12758  | 155  |           view.remove_suffix(view.size() - locofquestionmark);  |  12759  | 155  |           input_position += locofquestionmark + 1;  |  12760  | 2.86k  |         } else { |  12761  | 2.86k  |           input_position = input_size + 1;  |  12762  | 2.86k  |         }  |  12763  | 3.01k  |         if constexpr (result_type_is_ada_url) { |  12764  | 3.01k  |           helpers::parse_prepared_path(view, url.type, url.path);  |  12765  | 3.01k  |         } else { |  12766  | 3.01k  |           url.consume_prepared_path(view);  |  12767  | 3.01k  |           ADA_ASSERT_TRUE(url.validate());  |  12768  | 3.01k  |         }  |  12769  | 3.01k  |         break;  |  12770  | 4.72k  |       }  |  12771  | 570  |       case ada::state::FILE_SLASH: { |  12772  | 570  |         ada_log("FILE_SLASH ", helpers::substring(url_data, input_position)); |  12773  |  |  |  12774  |  |         // If c is U+002F (/) or U+005C (\), then:  |  12775  | 570  |         if ((input_position != input_size) &&  |  12776  | 570  |             (url_data[input_position] == '/' ||  |  12777  | 533  |              url_data[input_position] == '\\')) { |  12778  | 517  |           ada_log("FILE_SLASH c is U+002F or U+005C"); |  12779  |  |           // Set state to file host state.  |  12780  | 517  |           state = ada::state::FILE_HOST;  |  12781  | 517  |           input_position++;  |  12782  | 517  |         } else { |  12783  | 53  |           ada_log("FILE_SLASH otherwise"); |  12784  |  |           // If base is non-null and base’s scheme is "file", then:  |  12785  |  |           // Note: it is unsafe to do base_url->scheme unless you know that  |  12786  |  |           // base_url_has_value() is true.  |  12787  | 53  |           if (base_url != nullptr &&  |  12788  | 53  |               base_url->type == ada::scheme::type::FILE) { |  12789  |  |             // Set url’s host to base’s host.  |  12790  | 0  |             if constexpr (result_type_is_ada_url) { |  12791  | 0  |               url.host = base_url->host;  |  12792  | 0  |             } else { |  12793  |  |               // TODO: Optimization opportunity.  |  12794  | 0  |               url.set_host(base_url->get_host());  |  12795  | 0  |             }  |  12796  |  |             // If the code point substring from pointer to the end of input does  |  12797  |  |             // not start with a Windows drive letter and base’s path[0] is a  |  12798  |  |             // normalized Windows drive letter, then append base’s path[0] to  |  12799  |  |             // url’s path.  |  12800  | 0  |             if (!base_url->get_pathname().empty()) { |  12801  | 0  |               if (!checkers::is_windows_drive_letter(  |  12802  | 0  |                       helpers::substring(url_data, input_position))) { |  12803  | 0  |                 std::string_view first_base_url_path =  |  12804  | 0  |                     base_url->get_pathname().substr(1);  |  12805  | 0  |                 size_t loc = first_base_url_path.find('/'); |  12806  | 0  |                 if (loc != std::string_view::npos) { |  12807  | 0  |                   helpers::resize(first_base_url_path, loc);  |  12808  | 0  |                 }  |  12809  | 0  |                 if (checkers::is_normalized_windows_drive_letter(  |  12810  | 0  |                         first_base_url_path)) { |  12811  | 0  |                   if constexpr (result_type_is_ada_url) { |  12812  | 0  |                     url.path += '/';  |  12813  | 0  |                     url.path += first_base_url_path;  |  12814  | 0  |                   } else { |  12815  | 0  |                     url.append_base_pathname(  |  12816  | 0  |                         helpers::concat("/", first_base_url_path)); |  12817  | 0  |                   }  |  12818  | 0  |                 }  |  12819  | 0  |               }  |  12820  | 0  |             }  |  12821  | 0  |           }  |  12822  |  |  |  12823  |  |           // Set state to path state, and decrease pointer by 1.  |  12824  | 53  |           state = ada::state::PATH;  |  12825  | 53  |         }  |  12826  |  |  |  12827  | 570  |         break;  |  12828  | 4.72k  |       }  |  12829  | 517  |       case ada::state::FILE_HOST: { |  12830  | 517  |         std::string_view view = helpers::substring(url_data, input_position);  |  12831  | 517  |         ada_log("FILE_HOST ", helpers::substring(url_data, input_position)); |  12832  |  |  |  12833  | 517  |         size_t location = view.find_first_of("/\\?"); |  12834  | 517  |         std::string_view file_host_buffer(  |  12835  | 517  |             view.data(),  |  12836  | 517  |             (location != std::string_view::npos) ? location : view.size());  |  12837  |  |  |  12838  | 517  |         if (checkers::is_windows_drive_letter(file_host_buffer)) { |  12839  | 7  |           state = ada::state::PATH;  |  12840  | 510  |         } else if (file_host_buffer.empty()) { |  12841  |  |           // Set url’s host to the empty string.  |  12842  | 14  |           if constexpr (result_type_is_ada_url) { |  12843  | 14  |             url.host = "";  |  12844  | 14  |           } else { |  12845  | 14  |             url.update_base_hostname(""); |  12846  | 14  |           }  |  12847  |  |           // Set state to path start state.  |  12848  | 14  |           state = ada::state::PATH_START;  |  12849  | 496  |         } else { |  12850  | 496  |           size_t consumed_bytes = file_host_buffer.size();  |  12851  | 496  |           input_position += consumed_bytes;  |  12852  |  |           // Let host be the result of host parsing buffer with url is not  |  12853  |  |           // special.  |  12854  | 496  |           if (!url.parse_host(file_host_buffer)) { |  12855  | 133  |             return url;  |  12856  | 133  |           }  |  12857  |  |  |  12858  | 363  |           if constexpr (result_type_is_ada_url) { |  12859  |  |             // If host is "localhost", then set host to the empty string.  |  12860  | 363  |             if (url.host.has_value() && url.host.value() == "localhost") { |  12861  | 3  |               url.host = "";  |  12862  | 3  |             }  |  12863  | 363  |           } else { |  12864  | 363  |             if (url.get_hostname() == "localhost") { |  12865  | 363  |               url.update_base_hostname(""); |  12866  | 363  |             }  |  12867  | 363  |           }  |  12868  |  |  |  12869  |  |           // Set buffer to the empty string and state to path start state.  |  12870  | 363  |           state = ada::state::PATH_START;  |  12871  | 363  |         }  |  12872  |  |  |  12873  | 384  |         break;  |  12874  | 517  |       }  |  12875  | 1.61k  |       case ada::state::FILE: { |  12876  | 1.61k  |         ada_log("FILE ", helpers::substring(url_data, input_position)); |  12877  | 1.61k  |         std::string_view file_view =  |  12878  | 1.61k  |             helpers::substring(url_data, input_position);  |  12879  |  |  |  12880  | 1.61k  |         url.set_protocol_as_file();  |  12881  | 1.61k  |         if constexpr (result_type_is_ada_url) { |  12882  |  |           // Set url’s host to the empty string.  |  12883  | 1.61k  |           url.host = "";  |  12884  | 1.61k  |         } else { |  12885  | 1.61k  |           url.update_base_hostname(""); |  12886  | 1.61k  |         }  |  12887  |  |         // If c is U+002F (/) or U+005C (\), then:  |  12888  | 1.61k  |         if (input_position != input_size &&  |  12889  | 1.61k  |             (url_data[input_position] == '/' ||  |  12890  | 909  |              url_data[input_position] == '\\')) { |  12891  | 570  |           ada_log("FILE c is U+002F or U+005C"); |  12892  |  |           // Set state to file slash state.  |  12893  | 570  |           state = ada::state::FILE_SLASH;  |  12894  | 570  |         }  |  12895  |  |         // Otherwise, if base is non-null and base’s scheme is "file":  |  12896  | 1.04k  |         else if (base_url != nullptr &&  |  12897  | 1.04k  |                  base_url->type == ada::scheme::type::FILE) { |  12898  |  |           // Set url’s host to base’s host, url’s path to a clone of base’s  |  12899  |  |           // path, and url’s query to base’s query.  |  12900  | 0  |           ada_log("FILE base non-null"); |  12901  | 0  |           if constexpr (result_type_is_ada_url) { |  12902  | 0  |             url.host = base_url->host;  |  12903  | 0  |             url.path = base_url->path;  |  12904  | 0  |             url.query = base_url->query;  |  12905  | 0  |           } else { |  12906  |  |             // TODO: Get rid of set_hostname and replace it with  |  12907  |  |             // update_base_hostname  |  12908  | 0  |             url.set_hostname(base_url->get_hostname());  |  12909  | 0  |             url.update_base_pathname(base_url->get_pathname());  |  12910  | 0  |             url.update_base_search(base_url->get_search());  |  12911  | 0  |           }  |  12912  | 0  |           url.has_opaque_path = base_url->has_opaque_path;  |  12913  |  |  |  12914  |  |           // If c is U+003F (?), then set url’s query to the empty string and  |  12915  |  |           // state to query state.  |  12916  | 0  |           if (input_position != input_size && url_data[input_position] == '?') { |  12917  | 0  |             state = ada::state::QUERY;  |  12918  | 0  |           }  |  12919  |  |           // Otherwise, if c is not the EOF code point:  |  12920  | 0  |           else if (input_position != input_size) { |  12921  |  |             // Set url’s query to null.  |  12922  | 0  |             url.clear_search();  |  12923  |  |             // If the code point substring from pointer to the end of input does  |  12924  |  |             // not start with a Windows drive letter, then shorten url’s path.  |  12925  | 0  |             if (!checkers::is_windows_drive_letter(file_view)) { |  12926  | 0  |               if constexpr (result_type_is_ada_url) { |  12927  | 0  |                 helpers::shorten_path(url.path, url.type);  |  12928  | 0  |               } else { |  12929  | 0  |                 std::string_view path = url.get_pathname();  |  12930  | 0  |                 if (helpers::shorten_path(path, url.type)) { |  12931  | 0  |                   url.update_base_pathname(std::string(path));  |  12932  | 0  |                 }  |  12933  | 0  |               }  |  12934  | 0  |             }  |  12935  |  |             // Otherwise:  |  12936  | 0  |             else { |  12937  |  |               // Set url’s path to an empty list.  |  12938  | 0  |               url.clear_pathname();  |  12939  | 0  |               url.has_opaque_path = true;  |  12940  | 0  |             }  |  12941  |  |  |  12942  |  |             // Set state to path state and decrease pointer by 1.  |  12943  | 0  |             state = ada::state::PATH;  |  12944  | 0  |             break;  |  12945  | 0  |           }  |  12946  | 0  |         }  |  12947  |  |         // Otherwise, set state to path state, and decrease pointer by 1.  |  12948  | 1.04k  |         else { |  12949  | 1.04k  |           ada_log("FILE go to path"); |  12950  | 1.04k  |           state = ada::state::PATH;  |  12951  | 1.04k  |           break;  |  12952  | 1.04k  |         }  |  12953  |  |  |  12954  | 570  |         input_position++;  |  12955  | 570  |         break;  |  12956  | 1.61k  |       }  |  12957  | 0  |       default:  |  12958  | 0  |         ada::unreachable();  |  12959  | 61.2k  |     }  |  12960  | 61.2k  |   }  |  12961  | 4.07k  |   if (fragment.has_value()) { |  12962  | 157  |     url.update_unencoded_base_hash(*fragment);  |  12963  | 157  |   }  |  12964  | 4.07k  |   return url;  |  12965  | 14.5k  | }  |  
 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*) Line  | Count  | Source  |  12072  | 45.4k  |                       const result_type* base_url) { |  12073  |  |   // We can specialize the implementation per type.  |  12074  |  |   // Important: result_type_is_ada_url is evaluated at *compile time*. This  |  12075  |  |   // means that doing if constexpr(result_type_is_ada_url) { something } else { |  12076  |  |   // something else } is free (at runtime). This means that ada::url_aggregator  |  12077  |  |   // and ada::url **do not have to support the exact same API**.  |  12078  | 45.4k  |   constexpr bool result_type_is_ada_url =  |  12079  | 45.4k  |       std::is_same<ada::url, result_type>::value;  |  12080  | 45.4k  |   constexpr bool result_type_is_ada_url_aggregator =  |  12081  | 45.4k  |       std::is_same<ada::url_aggregator, result_type>::value;  |  12082  | 45.4k  |   static_assert(result_type_is_ada_url ||  |  12083  | 45.4k  |                 result_type_is_ada_url_aggregator);  // We don't support  |  12084  |  |                                                      // anything else for now.  |  12085  |  |  |  12086  | 45.4k  |   ada_log("ada::parser::parse_url('", user_input, "' [", user_input.size(), |  12087  | 45.4k  |           " bytes],", (base_url != nullptr ? base_url->to_string() : "null"),  |  12088  | 45.4k  |           ")");  |  12089  |  |  |  12090  | 45.4k  |   ada::state state = ada::state::SCHEME_START;  |  12091  | 45.4k  |   result_type url{}; |  12092  |  |  |  12093  |  |   // We refuse to parse URL strings that exceed 4GB. Such strings are almost  |  12094  |  |   // surely the result of a bug or are otherwise a security concern.  |  12095  | 45.4k  |   if (user_input.size() > std::numeric_limits<uint32_t>::max()) { |  12096  | 2  |     url.is_valid = false;  |  12097  | 2  |   }  |  12098  |  |   // Going forward, user_input.size() is in [0,  |  12099  |  |   // std::numeric_limits<uint32_t>::max). If we are provided with an invalid  |  12100  |  |   // base, or the optional_url was invalid, we must return.  |  12101  | 45.4k  |   if (base_url != nullptr) { |  12102  | 2.66k  |     url.is_valid &= base_url->is_valid;  |  12103  | 2.66k  |   }  |  12104  | 45.4k  |   if (!url.is_valid) { |  12105  | 2  |     return url;  |  12106  | 2  |   }  |  12107  | 45.4k  |   if constexpr (result_type_is_ada_url_aggregator) { |  12108  |  |     // Most of the time, we just need user_input.size().  |  12109  |  |     // In some instances, we may need a bit more.  |  12110  |  |     ///////////////////////////  |  12111  |  |     // This is *very* important. This line should be removed  |  12112  |  |     // hastily. There are principled reasons why reserve is important  |  12113  |  |     // for performance. If you have a benchmark with small inputs,  |  12114  |  |     // it may not matter, but in other instances, it could.  |  12115  |  |     ////  |  12116  |  |     // This rounds up to the next power of two.  |  12117  |  |     // We know that user_input.size() is in [0,  |  12118  |  |     // std::numeric_limits<uint32_t>::max).  |  12119  | 45.4k  |     uint32_t reserve_capacity =  |  12120  | 45.4k  |         (0xFFFFFFFF >>  |  12121  | 45.4k  |          helpers::leading_zeroes(uint32_t(1 | user_input.size()))) +  |  12122  | 45.4k  |         1;  |  12123  | 45.4k  |     url.reserve(reserve_capacity);  |  12124  |  |     //  |  12125  |  |     //  |  12126  |  |     //  |  12127  | 45.4k  |   }  |  12128  | 45.4k  |   std::string tmp_buffer;  |  12129  | 45.4k  |   std::string_view internal_input;  |  12130  | 45.4k  |   if (unicode::has_tabs_or_newline(user_input)) { |  12131  | 468  |     tmp_buffer = user_input;  |  12132  |  |     // Optimization opportunity: Instead of copying and then pruning, we could  |  12133  |  |     // just directly build the string from user_input.  |  12134  | 468  |     helpers::remove_ascii_tab_or_newline(tmp_buffer);  |  12135  | 468  |     internal_input = tmp_buffer;  |  12136  | 44.9k  |   } else { |  12137  | 44.9k  |     internal_input = user_input;  |  12138  | 44.9k  |   }  |  12139  |  |  |  12140  |  |   // Leading and trailing control characters are uncommon and easy to deal with  |  12141  |  |   // (no performance concern).  |  12142  | 45.4k  |   std::string_view url_data = internal_input;  |  12143  | 45.4k  |   helpers::trim_c0_whitespace(url_data);  |  12144  |  |  |  12145  |  |   // Optimization opportunity. Most websites do not have fragment.  |  12146  | 45.4k  |   std::optional<std::string_view> fragment = helpers::prune_hash(url_data);  |  12147  |  |   // We add it last so that an implementation like ada::url_aggregator  |  12148  |  |   // can append it last to its internal buffer, thus improving performance.  |  12149  |  |  |  12150  |  |   // Here url_data no longer has its fragment.  |  12151  |  |   // We are going to access the data from url_data (it is immutable).  |  12152  |  |   // At any given time, we are pointing at byte 'input_position' in url_data.  |  12153  |  |   // The input_position variable should range from 0 to input_size.  |  12154  |  |   // It is illegal to access url_data at input_size.  |  12155  | 45.4k  |   size_t input_position = 0;  |  12156  | 45.4k  |   const size_t input_size = url_data.size();  |  12157  |  |   // Keep running the following state machine by switching on state.  |  12158  |  |   // If after a run pointer points to the EOF code point, go to the next step.  |  12159  |  |   // Otherwise, increase pointer by 1 and continue with the state machine.  |  12160  |  |   // We never decrement input_position.  |  12161  | 179k  |   while (input_position <= input_size) { |  12162  | 168k  |     ada_log("In parsing at ", input_position, " out of ", input_size, |  12163  | 168k  |             " in state ", ada::to_string(state));  |  12164  | 168k  |     switch (state) { |  12165  | 45.4k  |       case ada::state::SCHEME_START: { |  12166  | 45.4k  |         ada_log("SCHEME_START ", helpers::substring(url_data, input_position)); |  12167  |  |         // If c is an ASCII alpha, append c, lowercased, to buffer, and set  |  12168  |  |         // state to scheme state.  |  12169  | 45.4k  |         if ((input_position != input_size) &&  |  12170  | 45.4k  |             checkers::is_alpha(url_data[input_position])) { |  12171  | 26.4k  |           state = ada::state::SCHEME;  |  12172  | 26.4k  |           input_position++;  |  12173  | 26.4k  |         } else { |  12174  |  |           // Otherwise, if state override is not given, set state to no scheme  |  12175  |  |           // state and decrease pointer by 1.  |  12176  | 18.9k  |           state = ada::state::NO_SCHEME;  |  12177  | 18.9k  |         }  |  12178  | 45.4k  |         break;  |  12179  | 0  |       }  |  12180  | 26.4k  |       case ada::state::SCHEME: { |  12181  | 26.4k  |         ada_log("SCHEME ", helpers::substring(url_data, input_position)); |  12182  |  |         // If c is an ASCII alphanumeric, U+002B (+), U+002D (-), or U+002E (.),  |  12183  |  |         // append c, lowercased, to buffer.  |  12184  | 87.0k  |         while ((input_position != input_size) &&  |  12185  | 87.0k  |                (ada::unicode::is_alnum_plus(url_data[input_position]))) { |  12186  | 60.6k  |           input_position++;  |  12187  | 60.6k  |         }  |  12188  |  |         // Otherwise, if c is U+003A (:), then:  |  12189  | 26.4k  |         if ((input_position != input_size) &&  |  12190  | 26.4k  |             (url_data[input_position] == ':')) { |  12191  | 24.2k  |           ada_log("SCHEME the scheme should be ", |  12192  | 24.2k  |                   url_data.substr(0, input_position));  |  12193  | 24.2k  |           if constexpr (result_type_is_ada_url) { |  12194  | 24.2k  |             if (!url.parse_scheme(url_data.substr(0, input_position))) { |  12195  | 24.2k  |               return url;  |  12196  | 24.2k  |             }  |  12197  | 24.2k  |           } else { |  12198  |  |             // we pass the colon along instead of painfully adding it back.  |  12199  | 24.2k  |             if (!url.parse_scheme_with_colon(  |  12200  | 24.2k  |                     url_data.substr(0, input_position + 1))) { |  12201  | 0  |               return url;  |  12202  | 0  |             }  |  12203  | 24.2k  |           }  |  12204  | 24.2k  |           ada_log("SCHEME the scheme is ", url.get_protocol()); |  12205  |  |  |  12206  |  |           // If url’s scheme is "file", then:  |  12207  | 24.2k  |           if (url.type == ada::scheme::type::FILE) { |  12208  |  |             // Set state to file state.  |  12209  | 4.13k  |             state = ada::state::FILE;  |  12210  | 4.13k  |           }  |  12211  |  |           // Otherwise, if url is special, base is non-null, and base’s scheme  |  12212  |  |           // is url’s scheme: Note: Doing base_url->scheme is unsafe if base_url  |  12213  |  |           // != nullptr is false.  |  12214  | 20.1k  |           else if (url.is_special() && base_url != nullptr &&  |  12215  | 20.1k  |                    base_url->type == url.type) { |  12216  |  |             // Set state to special relative or authority state.  |  12217  | 120  |             state = ada::state::SPECIAL_RELATIVE_OR_AUTHORITY;  |  12218  | 120  |           }  |  12219  |  |           // Otherwise, if url is special, set state to special authority  |  12220  |  |           // slashes state.  |  12221  | 20.0k  |           else if (url.is_special()) { |  12222  | 12.7k  |             state = ada::state::SPECIAL_AUTHORITY_SLASHES;  |  12223  | 12.7k  |           }  |  12224  |  |           // Otherwise, if remaining starts with an U+002F (/), set state to  |  12225  |  |           // path or authority state and increase pointer by 1.  |  12226  | 7.25k  |           else if (input_position + 1 < input_size &&  |  12227  | 7.25k  |                    url_data[input_position + 1] == '/') { |  12228  | 3.91k  |             state = ada::state::PATH_OR_AUTHORITY;  |  12229  | 3.91k  |             input_position++;  |  12230  | 3.91k  |           }  |  12231  |  |           // Otherwise, set url’s path to the empty string and set state to  |  12232  |  |           // opaque path state.  |  12233  | 3.34k  |           else { |  12234  | 3.34k  |             state = ada::state::OPAQUE_PATH;  |  12235  | 3.34k  |           }  |  12236  | 24.2k  |         }  |  12237  |  |         // Otherwise, if state override is not given, set buffer to the empty  |  12238  |  |         // string, state to no scheme state, and start over (from the first code  |  12239  |  |         // point in input).  |  12240  | 2.15k  |         else { |  12241  | 2.15k  |           state = ada::state::NO_SCHEME;  |  12242  | 2.15k  |           input_position = 0;  |  12243  | 2.15k  |           break;  |  12244  | 2.15k  |         }  |  12245  | 24.2k  |         input_position++;  |  12246  | 24.2k  |         break;  |  12247  | 26.4k  |       }  |  12248  | 21.1k  |       case ada::state::NO_SCHEME: { |  12249  | 21.1k  |         ada_log("NO_SCHEME ", helpers::substring(url_data, input_position)); |  12250  |  |         // If base is null, or base has an opaque path and c is not U+0023 (#),  |  12251  |  |         // validation error, return failure.  |  12252  | 21.1k  |         if (base_url == nullptr ||  |  12253  | 21.1k  |             (base_url->has_opaque_path && !fragment.has_value())) { |  12254  | 19.8k  |           ada_log("NO_SCHEME validation error"); |  12255  | 19.8k  |           url.is_valid = false;  |  12256  | 19.8k  |           return url;  |  12257  | 19.8k  |         }  |  12258  |  |         // Otherwise, if base has an opaque path and c is U+0023 (#),  |  12259  |  |         // set url’s scheme to base’s scheme, url’s path to base’s path, url’s  |  12260  |  |         // query to base’s query, and set state to fragment state.  |  12261  | 1.24k  |         else if (base_url->has_opaque_path && fragment.has_value() &&  |  12262  | 1.24k  |                  input_position == input_size) { |  12263  | 28  |           ada_log("NO_SCHEME opaque base with fragment"); |  12264  | 28  |           url.copy_scheme(*base_url);  |  12265  | 28  |           url.has_opaque_path = base_url->has_opaque_path;  |  12266  |  |  |  12267  | 28  |           if constexpr (result_type_is_ada_url) { |  12268  | 28  |             url.path = base_url->path;  |  12269  | 28  |             url.query = base_url->query;  |  12270  | 28  |           } else { |  12271  | 28  |             url.update_base_pathname(base_url->get_pathname());  |  12272  | 28  |             url.update_base_search(base_url->get_search());  |  12273  | 28  |           }  |  12274  | 28  |           url.update_unencoded_base_hash(*fragment);  |  12275  | 28  |           return url;  |  12276  | 28  |         }  |  12277  |  |         // Otherwise, if base’s scheme is not "file", set state to relative  |  12278  |  |         // state and decrease pointer by 1.  |  12279  | 1.21k  |         else if (base_url->type != ada::scheme::type::FILE) { |  12280  | 657  |           ada_log("NO_SCHEME non-file relative path"); |  12281  | 657  |           state = ada::state::RELATIVE_SCHEME;  |  12282  | 657  |         }  |  12283  |  |         // Otherwise, set state to file state and decrease pointer by 1.  |  12284  | 562  |         else { |  12285  | 562  |           ada_log("NO_SCHEME file base type"); |  12286  | 562  |           state = ada::state::FILE;  |  12287  | 562  |         }  |  12288  | 1.21k  |         break;  |  12289  | 21.1k  |       }  |  12290  | 13.5k  |       case ada::state::AUTHORITY: { |  12291  | 13.5k  |         ada_log("AUTHORITY ", helpers::substring(url_data, input_position)); |  12292  |  |         // most URLs have no @. Having no @ tells us that we don't have to worry  |  12293  |  |         // about AUTHORITY. Of course, we could have @ and still not have to  |  12294  |  |         // worry about AUTHORITY.  |  12295  |  |         // TODO: Instead of just collecting a bool, collect the location of the  |  12296  |  |         // '@' and do something useful with it.  |  12297  |  |         // TODO: We could do various processing early on, using a single pass  |  12298  |  |         // over the string to collect information about it, e.g., telling us  |  12299  |  |         // whether there is a @ and if so, where (or how many).  |  12300  | 13.5k  |         const bool contains_ampersand =  |  12301  | 13.5k  |             (url_data.find('@', input_position) != std::string_view::npos); |  12302  |  |  |  12303  | 13.5k  |         if (!contains_ampersand) { |  12304  | 12.6k  |           state = ada::state::HOST;  |  12305  | 12.6k  |           break;  |  12306  | 12.6k  |         }  |  12307  | 970  |         bool at_sign_seen{false}; |  12308  | 970  |         bool password_token_seen{false}; |  12309  |  |         /**  |  12310  |  |          * We expect something of the sort...  |  12311  |  |          * https://user:pass@example.com:1234/foo/bar?baz#quux  |  12312  |  |          * --------^  |  12313  |  |          */  |  12314  | 7.52k  |         do { |  12315  | 7.52k  |           std::string_view view = helpers::substring(url_data, input_position);  |  12316  |  |           // The delimiters are @, /, ? \\.  |  12317  | 7.52k  |           size_t location =  |  12318  | 7.52k  |               url.is_special() ? helpers::find_authority_delimiter_special(view)  |  12319  | 7.52k  |                                : helpers::find_authority_delimiter(view);  |  12320  | 7.52k  |           std::string_view authority_view(view.data(), location);  |  12321  | 7.52k  |           size_t end_of_authority = input_position + authority_view.size();  |  12322  |  |           // If c is U+0040 (@), then:  |  12323  | 7.52k  |           if ((end_of_authority != input_size) &&  |  12324  | 7.52k  |               (url_data[end_of_authority] == '@')) { |  12325  |  |             // If atSignSeen is true, then prepend "%40" to buffer.  |  12326  | 6.55k  |             if (at_sign_seen) { |  12327  | 5.62k  |               if (password_token_seen) { |  12328  | 1.37k  |                 if constexpr (result_type_is_ada_url) { |  12329  | 1.37k  |                   url.password += "%40";  |  12330  | 1.37k  |                 } else { |  12331  | 1.37k  |                   url.append_base_password("%40"); |  12332  | 1.37k  |                 }  |  12333  | 4.25k  |               } else { |  12334  | 4.25k  |                 if constexpr (result_type_is_ada_url) { |  12335  | 4.25k  |                   url.username += "%40";  |  12336  | 4.25k  |                 } else { |  12337  | 4.25k  |                   url.append_base_username("%40"); |  12338  | 4.25k  |                 }  |  12339  | 4.25k  |               }  |  12340  | 5.62k  |             }  |  12341  |  |  |  12342  | 6.55k  |             at_sign_seen = true;  |  12343  |  |  |  12344  | 6.55k  |             if (!password_token_seen) { |  12345  | 5.18k  |               size_t password_token_location = authority_view.find(':'); |  12346  | 5.18k  |               password_token_seen =  |  12347  | 5.18k  |                   password_token_location != std::string_view::npos;  |  12348  |  |  |  12349  | 5.18k  |               if (!password_token_seen) { |  12350  | 4.85k  |                 if constexpr (result_type_is_ada_url) { |  12351  | 4.85k  |                   url.username += unicode::percent_encode(  |  12352  | 4.85k  |                       authority_view, character_sets::USERINFO_PERCENT_ENCODE);  |  12353  | 4.85k  |                 } else { |  12354  | 4.85k  |                   url.append_base_username(unicode::percent_encode(  |  12355  | 4.85k  |                       authority_view, character_sets::USERINFO_PERCENT_ENCODE));  |  12356  | 4.85k  |                 }  |  12357  | 4.85k  |               } else { |  12358  | 325  |                 if constexpr (result_type_is_ada_url) { |  12359  | 325  |                   url.username += unicode::percent_encode(  |  12360  | 325  |                       authority_view.substr(0, password_token_location),  |  12361  | 325  |                       character_sets::USERINFO_PERCENT_ENCODE);  |  12362  | 325  |                   url.password += unicode::percent_encode(  |  12363  | 325  |                       authority_view.substr(password_token_location + 1),  |  12364  | 325  |                       character_sets::USERINFO_PERCENT_ENCODE);  |  12365  | 325  |                 } else { |  12366  | 325  |                   url.append_base_username(unicode::percent_encode(  |  12367  | 325  |                       authority_view.substr(0, password_token_location),  |  12368  | 325  |                       character_sets::USERINFO_PERCENT_ENCODE));  |  12369  | 325  |                   url.append_base_password(unicode::percent_encode(  |  12370  | 325  |                       authority_view.substr(password_token_location + 1),  |  12371  | 325  |                       character_sets::USERINFO_PERCENT_ENCODE));  |  12372  | 325  |                 }  |  12373  | 325  |               }  |  12374  | 5.18k  |             } else { |  12375  | 1.37k  |               if constexpr (result_type_is_ada_url) { |  12376  | 1.37k  |                 url.password += unicode::percent_encode(  |  12377  | 1.37k  |                     authority_view, character_sets::USERINFO_PERCENT_ENCODE);  |  12378  | 1.37k  |               } else { |  12379  | 1.37k  |                 url.append_base_password(unicode::percent_encode(  |  12380  | 1.37k  |                     authority_view, character_sets::USERINFO_PERCENT_ENCODE));  |  12381  | 1.37k  |               }  |  12382  | 1.37k  |             }  |  12383  | 6.55k  |           }  |  12384  |  |           // Otherwise, if one of the following is true:  |  12385  |  |           // - c is the EOF code point, U+002F (/), U+003F (?), or U+0023 (#)  |  12386  |  |           // - url is special and c is U+005C (\)  |  12387  | 970  |           else if (end_of_authority == input_size ||  |  12388  | 970  |                    url_data[end_of_authority] == '/' ||  |  12389  | 970  |                    url_data[end_of_authority] == '?' ||  |  12390  | 970  |                    (url.is_special() && url_data[end_of_authority] == '\\')) { |  12391  |  |             // If atSignSeen is true and authority_view is the empty string,  |  12392  |  |             // validation error, return failure.  |  12393  | 970  |             if (at_sign_seen && authority_view.empty()) { |  12394  | 513  |               url.is_valid = false;  |  12395  | 513  |               return url;  |  12396  | 513  |             }  |  12397  | 457  |             state = ada::state::HOST;  |  12398  | 457  |             break;  |  12399  | 970  |           }  |  12400  | 6.55k  |           if (end_of_authority == input_size) { |  12401  | 0  |             if (fragment.has_value()) { |  12402  | 0  |               url.update_unencoded_base_hash(*fragment);  |  12403  | 0  |             }  |  12404  | 0  |             return url;  |  12405  | 0  |           }  |  12406  | 6.55k  |           input_position = end_of_authority + 1;  |  12407  | 6.55k  |         } while (true);  |  12408  |  |  |  12409  | 457  |         break;  |  12410  | 970  |       }  |  12411  | 457  |       case ada::state::SPECIAL_RELATIVE_OR_AUTHORITY: { |  12412  | 120  |         ada_log("SPECIAL_RELATIVE_OR_AUTHORITY ", |  12413  | 120  |                 helpers::substring(url_data, input_position));  |  12414  |  |  |  12415  |  |         // If c is U+002F (/) and remaining starts with U+002F (/),  |  12416  |  |         // then set state to special authority ignore slashes state and increase  |  12417  |  |         // pointer by 1.  |  12418  | 120  |         std::string_view view = helpers::substring(url_data, input_position);  |  12419  | 120  |         if (ada::checkers::begins_with(view, "//")) { |  12420  | 2  |           state = ada::state::SPECIAL_AUTHORITY_IGNORE_SLASHES;  |  12421  | 2  |           input_position += 2;  |  12422  | 118  |         } else { |  12423  |  |           // Otherwise, validation error, set state to relative state and  |  12424  |  |           // decrease pointer by 1.  |  12425  | 118  |           state = ada::state::RELATIVE_SCHEME;  |  12426  | 118  |         }  |  12427  |  |  |  12428  | 120  |         break;  |  12429  | 970  |       }  |  12430  | 3.91k  |       case ada::state::PATH_OR_AUTHORITY: { |  12431  | 3.91k  |         ada_log("PATH_OR_AUTHORITY ", |  12432  | 3.91k  |                 helpers::substring(url_data, input_position));  |  12433  |  |  |  12434  |  |         // If c is U+002F (/), then set state to authority state.  |  12435  | 3.91k  |         if ((input_position != input_size) &&  |  12436  | 3.91k  |             (url_data[input_position] == '/')) { |  12437  | 800  |           state = ada::state::AUTHORITY;  |  12438  | 800  |           input_position++;  |  12439  | 3.11k  |         } else { |  12440  |  |           // Otherwise, set state to path state, and decrease pointer by 1.  |  12441  | 3.11k  |           state = ada::state::PATH;  |  12442  | 3.11k  |         }  |  12443  |  |  |  12444  | 3.91k  |         break;  |  12445  | 970  |       }  |  12446  | 775  |       case ada::state::RELATIVE_SCHEME: { |  12447  | 775  |         ada_log("RELATIVE_SCHEME ", |  12448  | 775  |                 helpers::substring(url_data, input_position));  |  12449  |  |  |  12450  |  |         // Set url’s scheme to base’s scheme.  |  12451  | 775  |         url.copy_scheme(*base_url);  |  12452  |  |  |  12453  |  |         // If c is U+002F (/), then set state to relative slash state.  |  12454  | 775  |         if ((input_position != input_size) &&  |  12455  | 775  |             (url_data[input_position] == '/')) { |  12456  | 43  |           ada_log(  |  12457  | 43  |               "RELATIVE_SCHEME if c is U+002F (/), then set state to relative "  |  12458  | 43  |               "slash state");  |  12459  | 43  |           state = ada::state::RELATIVE_SLASH;  |  12460  | 732  |         } else if (url.is_special() && (input_position != input_size) &&  |  12461  | 732  |                    (url_data[input_position] == '\\')) { |  12462  |  |           // Otherwise, if url is special and c is U+005C (\), validation error,  |  12463  |  |           // set state to relative slash state.  |  12464  | 1  |           ada_log(  |  12465  | 1  |               "RELATIVE_SCHEME  if url is special and c is U+005C, validation "  |  12466  | 1  |               "error, set state to relative slash state");  |  12467  | 1  |           state = ada::state::RELATIVE_SLASH;  |  12468  | 731  |         } else { |  12469  | 731  |           ada_log("RELATIVE_SCHEME otherwise"); |  12470  |  |           // Set url’s username to base’s username, url’s password to base’s  |  12471  |  |           // password, url’s host to base’s host, url’s port to base’s port,  |  12472  |  |           // url’s path to a clone of base’s path, and url’s query to base’s  |  12473  |  |           // query.  |  12474  | 731  |           if constexpr (result_type_is_ada_url) { |  12475  | 731  |             url.username = base_url->username;  |  12476  | 731  |             url.password = base_url->password;  |  12477  | 731  |             url.host = base_url->host;  |  12478  | 731  |             url.port = base_url->port;  |  12479  |  |             // cloning the base path includes cloning the has_opaque_path flag  |  12480  | 731  |             url.has_opaque_path = base_url->has_opaque_path;  |  12481  | 731  |             url.path = base_url->path;  |  12482  | 731  |             url.query = base_url->query;  |  12483  | 731  |           } else { |  12484  | 731  |             url.update_base_authority(base_url->get_href(),  |  12485  | 731  |                                       base_url->get_components());  |  12486  |  |             // TODO: Get rid of set_hostname and replace it with  |  12487  |  |             // update_base_hostname  |  12488  | 731  |             url.set_hostname(base_url->get_hostname());  |  12489  | 731  |             url.update_base_port(base_url->retrieve_base_port());  |  12490  |  |             // cloning the base path includes cloning the has_opaque_path flag  |  12491  | 731  |             url.has_opaque_path = base_url->has_opaque_path;  |  12492  | 731  |             url.update_base_pathname(base_url->get_pathname());  |  12493  | 731  |             url.update_base_search(base_url->get_search());  |  12494  | 731  |           }  |  12495  |  |  |  12496  | 731  |           url.has_opaque_path = base_url->has_opaque_path;  |  12497  |  |  |  12498  |  |           // If c is U+003F (?), then set url’s query to the empty string, and  |  12499  |  |           // state to query state.  |  12500  | 731  |           if ((input_position != input_size) &&  |  12501  | 731  |               (url_data[input_position] == '?')) { |  12502  | 5  |             state = ada::state::QUERY;  |  12503  | 5  |           }  |  12504  |  |           // Otherwise, if c is not the EOF code point:  |  12505  | 726  |           else if (input_position != input_size) { |  12506  |  |             // Set url’s query to null.  |  12507  | 233  |             url.clear_search();  |  12508  | 233  |             if constexpr (result_type_is_ada_url) { |  12509  |  |               // Shorten url’s path.  |  12510  | 233  |               helpers::shorten_path(url.path, url.type);  |  12511  | 233  |             } else { |  12512  | 233  |               std::string_view path = url.get_pathname();  |  12513  | 233  |               if (helpers::shorten_path(path, url.type)) { |  12514  | 197  |                 url.update_base_pathname(std::string(path));  |  12515  | 197  |               }  |  12516  | 233  |             }  |  12517  |  |             // Set state to path state and decrease pointer by 1.  |  12518  | 233  |             state = ada::state::PATH;  |  12519  | 233  |             break;  |  12520  | 233  |           }  |  12521  | 731  |         }  |  12522  | 542  |         input_position++;  |  12523  | 542  |         break;  |  12524  | 775  |       }  |  12525  | 44  |       case ada::state::RELATIVE_SLASH: { |  12526  | 44  |         ada_log("RELATIVE_SLASH ", |  12527  | 44  |                 helpers::substring(url_data, input_position));  |  12528  |  |  |  12529  |  |         // If url is special and c is U+002F (/) or U+005C (\), then:  |  12530  | 44  |         if (url.is_special() && (input_position != input_size) &&  |  12531  | 44  |             (url_data[input_position] == '/' ||  |  12532  | 18  |              url_data[input_position] == '\\')) { |  12533  |  |           // Set state to special authority ignore slashes state.  |  12534  | 3  |           state = ada::state::SPECIAL_AUTHORITY_IGNORE_SLASHES;  |  12535  | 3  |         }  |  12536  |  |         // Otherwise, if c is U+002F (/), then set state to authority state.  |  12537  | 41  |         else if ((input_position != input_size) &&  |  12538  | 41  |                  (url_data[input_position] == '/')) { |  12539  | 5  |           state = ada::state::AUTHORITY;  |  12540  | 5  |         }  |  12541  |  |         // Otherwise, set  |  12542  |  |         // - url’s username to base’s username,  |  12543  |  |         // - url’s password to base’s password,  |  12544  |  |         // - url’s host to base’s host,  |  12545  |  |         // - url’s port to base’s port,  |  12546  |  |         // - state to path state, and then, decrease pointer by 1.  |  12547  | 36  |         else { |  12548  | 36  |           if constexpr (result_type_is_ada_url) { |  12549  | 36  |             url.username = base_url->username;  |  12550  | 36  |             url.password = base_url->password;  |  12551  | 36  |             url.host = base_url->host;  |  12552  | 36  |             url.port = base_url->port;  |  12553  | 36  |           } else { |  12554  | 36  |             url.update_base_authority(base_url->get_href(),  |  12555  | 36  |                                       base_url->get_components());  |  12556  |  |             // TODO: Get rid of set_hostname and replace it with  |  12557  |  |             // update_base_hostname  |  12558  | 36  |             url.set_hostname(base_url->get_hostname());  |  12559  | 36  |             url.update_base_port(base_url->retrieve_base_port());  |  12560  | 36  |           }  |  12561  | 36  |           state = ada::state::PATH;  |  12562  | 36  |           break;  |  12563  | 36  |         }  |  12564  |  |  |  12565  | 8  |         input_position++;  |  12566  | 8  |         break;  |  12567  | 44  |       }  |  12568  | 12.7k  |       case ada::state::SPECIAL_AUTHORITY_SLASHES: { |  12569  | 12.7k  |         ada_log("SPECIAL_AUTHORITY_SLASHES ", |  12570  | 12.7k  |                 helpers::substring(url_data, input_position));  |  12571  |  |  |  12572  |  |         // If c is U+002F (/) and remaining starts with U+002F (/),  |  12573  |  |         // then set state to special authority ignore slashes state and increase  |  12574  |  |         // pointer by 1.  |  12575  | 12.7k  |         state = ada::state::SPECIAL_AUTHORITY_IGNORE_SLASHES;  |  12576  | 12.7k  |         std::string_view view = helpers::substring(url_data, input_position);  |  12577  | 12.7k  |         if (ada::checkers::begins_with(view, "//")) { |  12578  | 34  |           input_position += 2;  |  12579  | 34  |         }  |  12580  |  |  |  12581  | 12.7k  |         [[fallthrough]];  |  12582  | 12.7k  |       }  |  12583  | 12.7k  |       case ada::state::SPECIAL_AUTHORITY_IGNORE_SLASHES: { |  12584  | 12.7k  |         ada_log("SPECIAL_AUTHORITY_IGNORE_SLASHES ", |  12585  | 12.7k  |                 helpers::substring(url_data, input_position));  |  12586  |  |  |  12587  |  |         // If c is neither U+002F (/) nor U+005C (\), then set state to  |  12588  |  |         // authority state and decrease pointer by 1.  |  12589  | 13.9k  |         while ((input_position != input_size) &&  |  12590  | 13.9k  |                ((url_data[input_position] == '/') ||  |  12591  | 13.8k  |                 (url_data[input_position] == '\\'))) { |  12592  | 1.16k  |           input_position++;  |  12593  | 1.16k  |         }  |  12594  | 12.7k  |         state = ada::state::AUTHORITY;  |  12595  |  |  |  12596  | 12.7k  |         break;  |  12597  | 12.7k  |       }  |  12598  | 687  |       case ada::state::QUERY: { |  12599  | 687  |         ada_log("QUERY ", helpers::substring(url_data, input_position)); |  12600  |  |         // Let queryPercentEncodeSet be the special-query percent-encode set if  |  12601  |  |         // url is special; otherwise the query percent-encode set.  |  12602  | 687  |         const uint8_t* query_percent_encode_set =  |  12603  | 687  |             url.is_special() ? ada::character_sets::SPECIAL_QUERY_PERCENT_ENCODE  |  12604  | 687  |                              : ada::character_sets::QUERY_PERCENT_ENCODE;  |  12605  |  |  |  12606  |  |         // Percent-encode after encoding, with encoding, buffer, and  |  12607  |  |         // queryPercentEncodeSet, and append the result to url’s query.  |  12608  | 687  |         url.update_base_search(helpers::substring(url_data, input_position),  |  12609  | 687  |                                query_percent_encode_set);  |  12610  | 687  |         ada_log("QUERY update_base_search completed "); |  12611  | 687  |         if (fragment.has_value()) { |  12612  | 80  |           url.update_unencoded_base_hash(*fragment);  |  12613  | 80  |         }  |  12614  | 687  |         return url;  |  12615  | 12.7k  |       }  |  12616  | 13.0k  |       case ada::state::HOST: { |  12617  | 13.0k  |         ada_log("HOST ", helpers::substring(url_data, input_position)); |  12618  |  |  |  12619  | 13.0k  |         std::string_view host_view =  |  12620  | 13.0k  |             helpers::substring(url_data, input_position);  |  12621  | 13.0k  |         auto [location, found_colon] =  |  12622  | 13.0k  |             helpers::get_host_delimiter_location(url.is_special(), host_view);  |  12623  | 13.0k  |         input_position = (location != std::string_view::npos)  |  12624  | 13.0k  |                              ? input_position + location  |  12625  | 13.0k  |                              : input_size;  |  12626  |  |         // Otherwise, if c is U+003A (:) and insideBrackets is false, then:  |  12627  |  |         // Note: the 'found_colon' value is true if and only if a colon was  |  12628  |  |         // encountered while not inside brackets.  |  12629  | 13.0k  |         if (found_colon) { |  12630  |  |           // If buffer is the empty string, validation error, return failure.  |  12631  |  |           // Let host be the result of host parsing buffer with url is not  |  12632  |  |           // special.  |  12633  | 1.94k  |           ada_log("HOST parsing ", host_view); |  12634  | 1.94k  |           if (!url.parse_host(host_view)) { |  12635  | 295  |             return url;  |  12636  | 295  |           }  |  12637  | 1.64k  |           ada_log("HOST parsing results in ", url.get_hostname()); |  12638  |  |           // Set url’s host to host, buffer to the empty string, and state to  |  12639  |  |           // port state.  |  12640  | 1.64k  |           state = ada::state::PORT;  |  12641  | 1.64k  |           input_position++;  |  12642  | 1.64k  |         }  |  12643  |  |         // Otherwise, if one of the following is true:  |  12644  |  |         // - c is the EOF code point, U+002F (/), U+003F (?), or U+0023 (#)  |  12645  |  |         // - url is special and c is U+005C (\)  |  12646  |  |         // The get_host_delimiter_location function either brings us to  |  12647  |  |         // the colon outside of the bracket, or to one of those characters.  |  12648  | 11.1k  |         else { |  12649  |  |           // If url is special and host_view is the empty string, validation  |  12650  |  |           // error, return failure.  |  12651  | 11.1k  |           if (url.is_special() && host_view.empty()) { |  12652  | 103  |             url.is_valid = false;  |  12653  | 103  |             return url;  |  12654  | 103  |           }  |  12655  | 11.0k  |           ada_log("HOST parsing ", host_view, " href=", url.get_href()); |  12656  |  |           // Let host be the result of host parsing host_view with url is not  |  12657  |  |           // special.  |  12658  | 11.0k  |           if (host_view.empty()) { |  12659  | 75  |             url.update_base_hostname(""); |  12660  | 10.9k  |           } else if (!url.parse_host(host_view)) { |  12661  | 2.60k  |             return url;  |  12662  | 2.60k  |           }  |  12663  | 8.40k  |           ada_log("HOST parsing results in ", url.get_hostname(), |  12664  | 8.40k  |                   " href=", url.get_href());  |  12665  |  |  |  12666  |  |           // Set url’s host to host, and state to path start state.  |  12667  | 8.40k  |           state = ada::state::PATH_START;  |  12668  | 8.40k  |         }  |  12669  |  |  |  12670  | 10.0k  |         break;  |  12671  | 13.0k  |       }  |  12672  | 10.0k  |       case ada::state::OPAQUE_PATH: { |  12673  | 3.34k  |         ada_log("OPAQUE_PATH ", helpers::substring(url_data, input_position)); |  12674  | 3.34k  |         std::string_view view = helpers::substring(url_data, input_position);  |  12675  |  |         // If c is U+003F (?), then set url’s query to the empty string and  |  12676  |  |         // state to query state.  |  12677  | 3.34k  |         size_t location = view.find('?'); |  12678  | 3.34k  |         if (location != std::string_view::npos) { |  12679  | 224  |           view.remove_suffix(view.size() - location);  |  12680  | 224  |           state = ada::state::QUERY;  |  12681  | 224  |           input_position += location + 1;  |  12682  | 3.11k  |         } else { |  12683  | 3.11k  |           input_position = input_size + 1;  |  12684  | 3.11k  |         }  |  12685  | 3.34k  |         url.has_opaque_path = true;  |  12686  |  |         // This is a really unlikely scenario in real world. We should not seek  |  12687  |  |         // to optimize it.  |  12688  | 3.34k  |         url.update_base_pathname(unicode::percent_encode(  |  12689  | 3.34k  |             view, character_sets::C0_CONTROL_PERCENT_ENCODE));  |  12690  | 3.34k  |         break;  |  12691  | 13.0k  |       }  |  12692  | 1.64k  |       case ada::state::PORT: { |  12693  | 1.64k  |         ada_log("PORT ", helpers::substring(url_data, input_position)); |  12694  | 1.64k  |         std::string_view port_view =  |  12695  | 1.64k  |             helpers::substring(url_data, input_position);  |  12696  | 1.64k  |         size_t consumed_bytes = url.parse_port(port_view, true);  |  12697  | 1.64k  |         input_position += consumed_bytes;  |  12698  | 1.64k  |         if (!url.is_valid) { |  12699  | 187  |           return url;  |  12700  | 187  |         }  |  12701  | 1.46k  |         state = state::PATH_START;  |  12702  | 1.46k  |         [[fallthrough]];  |  12703  | 1.46k  |       }  |  12704  | 11.1k  |       case ada::state::PATH_START: { |  12705  | 11.1k  |         ada_log("PATH_START ", helpers::substring(url_data, input_position)); |  12706  |  |  |  12707  |  |         // If url is special, then:  |  12708  | 11.1k  |         if (url.is_special()) { |  12709  |  |           // Set state to path state.  |  12710  | 10.6k  |           state = ada::state::PATH;  |  12711  |  |  |  12712  |  |           // Optimization: Avoiding going into PATH state improves the  |  12713  |  |           // performance of urls ending with /.  |  12714  | 10.6k  |           if (input_position == input_size) { |  12715  | 9.64k  |             url.update_base_pathname("/"); |  12716  | 9.64k  |             if (fragment.has_value()) { |  12717  | 176  |               url.update_unencoded_base_hash(*fragment);  |  12718  | 176  |             }  |  12719  | 9.64k  |             return url;  |  12720  | 9.64k  |           }  |  12721  |  |           // If c is neither U+002F (/) nor U+005C (\), then decrease pointer  |  12722  |  |           // by 1. We know that (input_position == input_size) is impossible  |  12723  |  |           // here, because of the previous if-check.  |  12724  | 961  |           if ((url_data[input_position] != '/') &&  |  12725  | 961  |               (url_data[input_position] != '\\')) { |  12726  | 202  |             break;  |  12727  | 202  |           }  |  12728  | 961  |         }  |  12729  |  |         // Otherwise, if state override is not given and c is U+003F (?),  |  12730  |  |         // set url’s query to the empty string and state to query state.  |  12731  | 570  |         else if ((input_position != input_size) &&  |  12732  | 570  |                  (url_data[input_position] == '?')) { |  12733  | 59  |           state = ada::state::QUERY;  |  12734  | 59  |         }  |  12735  |  |         // Otherwise, if c is not the EOF code point:  |  12736  | 511  |         else if (input_position != input_size) { |  12737  |  |           // Set state to path state.  |  12738  | 64  |           state = ada::state::PATH;  |  12739  |  |  |  12740  |  |           // If c is not U+002F (/), then decrease pointer by 1.  |  12741  | 64  |           if (url_data[input_position] != '/') { |  12742  | 0  |             break;  |  12743  | 0  |           }  |  12744  | 64  |         }  |  12745  |  |  |  12746  | 1.32k  |         input_position++;  |  12747  | 1.32k  |         break;  |  12748  | 11.1k  |       }  |  12749  | 7.26k  |       case ada::state::PATH: { |  12750  | 7.26k  |         std::string_view view = helpers::substring(url_data, input_position);  |  12751  | 7.26k  |         ada_log("PATH ", helpers::substring(url_data, input_position)); |  12752  |  |  |  12753  |  |         // Most time, we do not need percent encoding.  |  12754  |  |         // Furthermore, we can immediately locate the '?'.  |  12755  | 7.26k  |         size_t locofquestionmark = view.find('?'); |  12756  | 7.26k  |         if (locofquestionmark != std::string_view::npos) { |  12757  | 397  |           state = ada::state::QUERY;  |  12758  | 397  |           view.remove_suffix(view.size() - locofquestionmark);  |  12759  | 397  |           input_position += locofquestionmark + 1;  |  12760  | 6.86k  |         } else { |  12761  | 6.86k  |           input_position = input_size + 1;  |  12762  | 6.86k  |         }  |  12763  | 7.26k  |         if constexpr (result_type_is_ada_url) { |  12764  | 7.26k  |           helpers::parse_prepared_path(view, url.type, url.path);  |  12765  | 7.26k  |         } else { |  12766  | 7.26k  |           url.consume_prepared_path(view);  |  12767  | 7.26k  |           ADA_ASSERT_TRUE(url.validate());  |  12768  | 7.26k  |         }  |  12769  | 7.26k  |         break;  |  12770  | 11.1k  |       }  |  12771  | 1.96k  |       case ada::state::FILE_SLASH: { |  12772  | 1.96k  |         ada_log("FILE_SLASH ", helpers::substring(url_data, input_position)); |  12773  |  |  |  12774  |  |         // If c is U+002F (/) or U+005C (\), then:  |  12775  | 1.96k  |         if ((input_position != input_size) &&  |  12776  | 1.96k  |             (url_data[input_position] == '/' ||  |  12777  | 1.67k  |              url_data[input_position] == '\\')) { |  12778  | 1.58k  |           ada_log("FILE_SLASH c is U+002F or U+005C"); |  12779  |  |           // Set state to file host state.  |  12780  | 1.58k  |           state = ada::state::FILE_HOST;  |  12781  | 1.58k  |           input_position++;  |  12782  | 1.58k  |         } else { |  12783  | 376  |           ada_log("FILE_SLASH otherwise"); |  12784  |  |           // If base is non-null and base’s scheme is "file", then:  |  12785  |  |           // Note: it is unsafe to do base_url->scheme unless you know that  |  12786  |  |           // base_url_has_value() is true.  |  12787  | 376  |           if (base_url != nullptr &&  |  12788  | 376  |               base_url->type == ada::scheme::type::FILE) { |  12789  |  |             // Set url’s host to base’s host.  |  12790  | 261  |             if constexpr (result_type_is_ada_url) { |  12791  | 261  |               url.host = base_url->host;  |  12792  | 261  |             } else { |  12793  |  |               // TODO: Optimization opportunity.  |  12794  | 261  |               url.set_host(base_url->get_host());  |  12795  | 261  |             }  |  12796  |  |             // If the code point substring from pointer to the end of input does  |  12797  |  |             // not start with a Windows drive letter and base’s path[0] is a  |  12798  |  |             // normalized Windows drive letter, then append base’s path[0] to  |  12799  |  |             // url’s path.  |  12800  | 261  |             if (!base_url->get_pathname().empty()) { |  12801  | 261  |               if (!checkers::is_windows_drive_letter(  |  12802  | 261  |                       helpers::substring(url_data, input_position))) { |  12803  | 256  |                 std::string_view first_base_url_path =  |  12804  | 256  |                     base_url->get_pathname().substr(1);  |  12805  | 256  |                 size_t loc = first_base_url_path.find('/'); |  12806  | 256  |                 if (loc != std::string_view::npos) { |  12807  | 12  |                   helpers::resize(first_base_url_path, loc);  |  12808  | 12  |                 }  |  12809  | 256  |                 if (checkers::is_normalized_windows_drive_letter(  |  12810  | 256  |                         first_base_url_path)) { |  12811  | 3  |                   if constexpr (result_type_is_ada_url) { |  12812  | 3  |                     url.path += '/';  |  12813  | 3  |                     url.path += first_base_url_path;  |  12814  | 3  |                   } else { |  12815  | 3  |                     url.append_base_pathname(  |  12816  | 3  |                         helpers::concat("/", first_base_url_path)); |  12817  | 3  |                   }  |  12818  | 3  |                 }  |  12819  | 256  |               }  |  12820  | 261  |             }  |  12821  | 261  |           }  |  12822  |  |  |  12823  |  |           // Set state to path state, and decrease pointer by 1.  |  12824  | 376  |           state = ada::state::PATH;  |  12825  | 376  |         }  |  12826  |  |  |  12827  | 1.96k  |         break;  |  12828  | 11.1k  |       }  |  12829  | 1.58k  |       case ada::state::FILE_HOST: { |  12830  | 1.58k  |         std::string_view view = helpers::substring(url_data, input_position);  |  12831  | 1.58k  |         ada_log("FILE_HOST ", helpers::substring(url_data, input_position)); |  12832  |  |  |  12833  | 1.58k  |         size_t location = view.find_first_of("/\\?"); |  12834  | 1.58k  |         std::string_view file_host_buffer(  |  12835  | 1.58k  |             view.data(),  |  12836  | 1.58k  |             (location != std::string_view::npos) ? location : view.size());  |  12837  |  |  |  12838  | 1.58k  |         if (checkers::is_windows_drive_letter(file_host_buffer)) { |  12839  | 22  |           state = ada::state::PATH;  |  12840  | 1.56k  |         } else if (file_host_buffer.empty()) { |  12841  |  |           // Set url’s host to the empty string.  |  12842  | 43  |           if constexpr (result_type_is_ada_url) { |  12843  | 43  |             url.host = "";  |  12844  | 43  |           } else { |  12845  | 43  |             url.update_base_hostname(""); |  12846  | 43  |           }  |  12847  |  |           // Set state to path start state.  |  12848  | 43  |           state = ada::state::PATH_START;  |  12849  | 1.52k  |         } else { |  12850  | 1.52k  |           size_t consumed_bytes = file_host_buffer.size();  |  12851  | 1.52k  |           input_position += consumed_bytes;  |  12852  |  |           // Let host be the result of host parsing buffer with url is not  |  12853  |  |           // special.  |  12854  | 1.52k  |           if (!url.parse_host(file_host_buffer)) { |  12855  | 259  |             return url;  |  12856  | 259  |           }  |  12857  |  |  |  12858  | 1.26k  |           if constexpr (result_type_is_ada_url) { |  12859  |  |             // If host is "localhost", then set host to the empty string.  |  12860  | 1.26k  |             if (url.host.has_value() && url.host.value() == "localhost") { |  12861  | 1.26k  |               url.host = "";  |  12862  | 1.26k  |             }  |  12863  | 1.26k  |           } else { |  12864  | 1.26k  |             if (url.get_hostname() == "localhost") { |  12865  | 10  |               url.update_base_hostname(""); |  12866  | 10  |             }  |  12867  | 1.26k  |           }  |  12868  |  |  |  12869  |  |           // Set buffer to the empty string and state to path start state.  |  12870  | 1.26k  |           state = ada::state::PATH_START;  |  12871  | 1.26k  |         }  |  12872  |  |  |  12873  | 1.33k  |         break;  |  12874  | 1.58k  |       }  |  12875  | 4.69k  |       case ada::state::FILE: { |  12876  | 4.69k  |         ada_log("FILE ", helpers::substring(url_data, input_position)); |  12877  | 4.69k  |         std::string_view file_view =  |  12878  | 4.69k  |             helpers::substring(url_data, input_position);  |  12879  |  |  |  12880  | 4.69k  |         url.set_protocol_as_file();  |  12881  | 4.69k  |         if constexpr (result_type_is_ada_url) { |  12882  |  |           // Set url’s host to the empty string.  |  12883  | 4.69k  |           url.host = "";  |  12884  | 4.69k  |         } else { |  12885  | 4.69k  |           url.update_base_hostname(""); |  12886  | 4.69k  |         }  |  12887  |  |         // If c is U+002F (/) or U+005C (\), then:  |  12888  | 4.69k  |         if (input_position != input_size &&  |  12889  | 4.69k  |             (url_data[input_position] == '/' ||  |  12890  | 2.92k  |              url_data[input_position] == '\\')) { |  12891  | 1.96k  |           ada_log("FILE c is U+002F or U+005C"); |  12892  |  |           // Set state to file slash state.  |  12893  | 1.96k  |           state = ada::state::FILE_SLASH;  |  12894  | 1.96k  |         }  |  12895  |  |         // Otherwise, if base is non-null and base’s scheme is "file":  |  12896  | 2.72k  |         else if (base_url != nullptr &&  |  12897  | 2.72k  |                  base_url->type == ada::scheme::type::FILE) { |  12898  |  |           // Set url’s host to base’s host, url’s path to a clone of base’s  |  12899  |  |           // path, and url’s query to base’s query.  |  12900  | 380  |           ada_log("FILE base non-null"); |  12901  | 380  |           if constexpr (result_type_is_ada_url) { |  12902  | 380  |             url.host = base_url->host;  |  12903  | 380  |             url.path = base_url->path;  |  12904  | 380  |             url.query = base_url->query;  |  12905  | 380  |           } else { |  12906  |  |             // TODO: Get rid of set_hostname and replace it with  |  12907  |  |             // update_base_hostname  |  12908  | 380  |             url.set_hostname(base_url->get_hostname());  |  12909  | 380  |             url.update_base_pathname(base_url->get_pathname());  |  12910  | 380  |             url.update_base_search(base_url->get_search());  |  12911  | 380  |           }  |  12912  | 380  |           url.has_opaque_path = base_url->has_opaque_path;  |  12913  |  |  |  12914  |  |           // If c is U+003F (?), then set url’s query to the empty string and  |  12915  |  |           // state to query state.  |  12916  | 380  |           if (input_position != input_size && url_data[input_position] == '?') { |  12917  | 2  |             state = ada::state::QUERY;  |  12918  | 2  |           }  |  12919  |  |           // Otherwise, if c is not the EOF code point:  |  12920  | 378  |           else if (input_position != input_size) { |  12921  |  |             // Set url’s query to null.  |  12922  | 105  |             url.clear_search();  |  12923  |  |             // If the code point substring from pointer to the end of input does  |  12924  |  |             // not start with a Windows drive letter, then shorten url’s path.  |  12925  | 105  |             if (!checkers::is_windows_drive_letter(file_view)) { |  12926  | 93  |               if constexpr (result_type_is_ada_url) { |  12927  | 93  |                 helpers::shorten_path(url.path, url.type);  |  12928  | 93  |               } else { |  12929  | 93  |                 std::string_view path = url.get_pathname();  |  12930  | 93  |                 if (helpers::shorten_path(path, url.type)) { |  12931  | 85  |                   url.update_base_pathname(std::string(path));  |  12932  | 85  |                 }  |  12933  | 93  |               }  |  12934  | 93  |             }  |  12935  |  |             // Otherwise:  |  12936  | 12  |             else { |  12937  |  |               // Set url’s path to an empty list.  |  12938  | 12  |               url.clear_pathname();  |  12939  | 12  |               url.has_opaque_path = true;  |  12940  | 12  |             }  |  12941  |  |  |  12942  |  |             // Set state to path state and decrease pointer by 1.  |  12943  | 105  |             state = ada::state::PATH;  |  12944  | 105  |             break;  |  12945  | 105  |           }  |  12946  | 380  |         }  |  12947  |  |         // Otherwise, set state to path state, and decrease pointer by 1.  |  12948  | 2.34k  |         else { |  12949  | 2.34k  |           ada_log("FILE go to path"); |  12950  | 2.34k  |           state = ada::state::PATH;  |  12951  | 2.34k  |           break;  |  12952  | 2.34k  |         }  |  12953  |  |  |  12954  | 2.24k  |         input_position++;  |  12955  | 2.24k  |         break;  |  12956  | 4.69k  |       }  |  12957  | 0  |       default:  |  12958  | 0  |         ada::unreachable();  |  12959  | 168k  |     }  |  12960  | 168k  |   }  |  12961  | 11.1k  |   if (fragment.has_value()) { |  12962  | 408  |     url.update_unencoded_base_hash(*fragment);  |  12963  | 408  |   }  |  12964  | 11.1k  |   return url;  |  12965  | 45.4k  | }  |  
  | 
12966  |  |  | 
12967  |  | template url parse_url<url>(std::string_view user_input,  | 
12968  |  |                             const url* base_url = nullptr);  | 
12969  |  | template url_aggregator parse_url<url_aggregator>(  | 
12970  |  |     std::string_view user_input, const url_aggregator* base_url = nullptr);  | 
12971  |  |  | 
12972  |  | }  // namespace ada::parser  | 
12973  |  | /* end file src/parser.cpp */  | 
12974  |  | /* begin file src/url_components.cpp */  | 
12975  |  |  | 
12976  |  | #include <numeric>  | 
12977  |  | #include <string>  | 
12978  |  |  | 
12979  |  | namespace ada { | 
12980  |  |  | 
12981  | 0  | bool url_components::check_offset_consistency() const noexcept { | 
12982  |  |   /**  | 
12983  |  |    * https://user:pass@example.com:1234/foo/bar?baz#quux  | 
12984  |  |    *       |     |    |          | ^^^^|       |   |  | 
12985  |  |    *       |     |    |          | |   |       |   `----- hash_start  | 
12986  |  |    *       |     |    |          | |   |       `--------- search_start  | 
12987  |  |    *       |     |    |          | |   `----------------- pathname_start  | 
12988  |  |    *       |     |    |          | `--------------------- port  | 
12989  |  |    *       |     |    |          `----------------------- host_end  | 
12990  |  |    *       |     |    `---------------------------------- host_start  | 
12991  |  |    *       |     `--------------------------------------- username_end  | 
12992  |  |    *       `--------------------------------------------- protocol_end  | 
12993  |  |    */  | 
12994  |  |   // These conditions can be made more strict.  | 
12995  | 0  |   uint32_t index = 0;  | 
12996  |  | 
  | 
12997  | 0  |   if (protocol_end == url_components::omitted) { | 
12998  | 0  |     return false;  | 
12999  | 0  |   }  | 
13000  | 0  |   if (protocol_end < index) { | 
13001  | 0  |     return false;  | 
13002  | 0  |   }  | 
13003  | 0  |   index = protocol_end;  | 
13004  |  | 
  | 
13005  | 0  |   if (username_end == url_components::omitted) { | 
13006  | 0  |     return false;  | 
13007  | 0  |   }  | 
13008  | 0  |   if (username_end < index) { | 
13009  | 0  |     return false;  | 
13010  | 0  |   }  | 
13011  | 0  |   index = username_end;  | 
13012  |  | 
  | 
13013  | 0  |   if (host_start == url_components::omitted) { | 
13014  | 0  |     return false;  | 
13015  | 0  |   }  | 
13016  | 0  |   if (host_start < index) { | 
13017  | 0  |     return false;  | 
13018  | 0  |   }  | 
13019  | 0  |   index = host_start;  | 
13020  |  | 
  | 
13021  | 0  |   if (port != url_components::omitted) { | 
13022  | 0  |     if (port > 0xffff) { | 
13023  | 0  |       return false;  | 
13024  | 0  |     }  | 
13025  | 0  |     uint32_t port_length = helpers::fast_digit_count(port) + 1;  | 
13026  | 0  |     if (index + port_length < index) { | 
13027  | 0  |       return false;  | 
13028  | 0  |     }  | 
13029  | 0  |     index += port_length;  | 
13030  | 0  |   }  | 
13031  |  |  | 
13032  | 0  |   if (pathname_start == url_components::omitted) { | 
13033  | 0  |     return false;  | 
13034  | 0  |   }  | 
13035  | 0  |   if (pathname_start < index) { | 
13036  | 0  |     return false;  | 
13037  | 0  |   }  | 
13038  | 0  |   index = pathname_start;  | 
13039  |  | 
  | 
13040  | 0  |   if (search_start != url_components::omitted) { | 
13041  | 0  |     if (search_start < index) { | 
13042  | 0  |       return false;  | 
13043  | 0  |     }  | 
13044  | 0  |     index = search_start;  | 
13045  | 0  |   }  | 
13046  |  |  | 
13047  | 0  |   if (hash_start != url_components::omitted) { | 
13048  | 0  |     if (hash_start < index) { | 
13049  | 0  |       return false;  | 
13050  | 0  |     }  | 
13051  | 0  |     index = hash_start;  | 
13052  | 0  |   }  | 
13053  |  |  | 
13054  | 0  |   return true;  | 
13055  | 0  | }  | 
13056  |  |  | 
13057  | 0  | std::string url_components::to_string() const { | 
13058  | 0  |   std::string answer;  | 
13059  | 0  |   auto back = std::back_insert_iterator(answer);  | 
13060  | 0  |   answer.append("{\n"); | 
13061  |  | 
  | 
13062  | 0  |   answer.append("\t\"protocol_end\":\""); | 
13063  | 0  |   helpers::encode_json(std::to_string(protocol_end), back);  | 
13064  | 0  |   answer.append("\",\n"); | 
13065  |  | 
  | 
13066  | 0  |   answer.append("\t\"username_end\":\""); | 
13067  | 0  |   helpers::encode_json(std::to_string(username_end), back);  | 
13068  | 0  |   answer.append("\",\n"); | 
13069  |  | 
  | 
13070  | 0  |   answer.append("\t\"host_start\":\""); | 
13071  | 0  |   helpers::encode_json(std::to_string(host_start), back);  | 
13072  | 0  |   answer.append("\",\n"); | 
13073  |  | 
  | 
13074  | 0  |   answer.append("\t\"host_end\":\""); | 
13075  | 0  |   helpers::encode_json(std::to_string(host_end), back);  | 
13076  | 0  |   answer.append("\",\n"); | 
13077  |  | 
  | 
13078  | 0  |   answer.append("\t\"port\":\""); | 
13079  | 0  |   helpers::encode_json(std::to_string(port), back);  | 
13080  | 0  |   answer.append("\",\n"); | 
13081  |  | 
  | 
13082  | 0  |   answer.append("\t\"pathname_start\":\""); | 
13083  | 0  |   helpers::encode_json(std::to_string(pathname_start), back);  | 
13084  | 0  |   answer.append("\",\n"); | 
13085  |  | 
  | 
13086  | 0  |   answer.append("\t\"search_start\":\""); | 
13087  | 0  |   helpers::encode_json(std::to_string(search_start), back);  | 
13088  | 0  |   answer.append("\",\n"); | 
13089  |  | 
  | 
13090  | 0  |   answer.append("\t\"hash_start\":\""); | 
13091  | 0  |   helpers::encode_json(std::to_string(hash_start), back);  | 
13092  | 0  |   answer.append("\",\n"); | 
13093  |  | 
  | 
13094  | 0  |   answer.append("\n}"); | 
13095  | 0  |   return answer;  | 
13096  | 0  | }  | 
13097  |  |  | 
13098  |  | }  // namespace ada  | 
13099  |  | /* end file src/url_components.cpp */  | 
13100  |  | /* begin file src/url_aggregator.cpp */  | 
13101  |  |  | 
13102  |  | #include <string>  | 
13103  |  | #include <string_view>  | 
13104  |  |  | 
13105  |  | namespace ada { | 
13106  |  | template <bool has_state_override>  | 
13107  |  | [[nodiscard]] ada_really_inline bool url_aggregator::parse_scheme_with_colon(  | 
13108  | 24.6k  |     const std::string_view input_with_colon) { | 
13109  | 24.6k  |   ada_log("url_aggregator::parse_scheme_with_colon ", input_with_colon); | 
13110  | 24.6k  |   ADA_ASSERT_TRUE(validate());  | 
13111  | 24.6k  |   ADA_ASSERT_TRUE(!helpers::overlaps(input_with_colon, buffer));  | 
13112  | 24.6k  |   std::string_view input{input_with_colon}; | 
13113  | 24.6k  |   input.remove_suffix(1);  | 
13114  | 24.6k  |   auto parsed_type = ada::scheme::get_scheme_type(input);  | 
13115  | 24.6k  |   bool is_input_special = (parsed_type != ada::scheme::NOT_SPECIAL);  | 
13116  |  |   /**  | 
13117  |  |    * In the common case, we will immediately recognize a special scheme (e.g.,  | 
13118  |  |    *http, https), in which case, we can go really fast.  | 
13119  |  |    **/  | 
13120  | 24.6k  |   if (is_input_special) {  // fast path!!! | 
13121  | 10.6k  |     if (has_state_override) { | 
13122  |  |       // If url’s scheme is not a special scheme and buffer is a special scheme,  | 
13123  |  |       // then return.  | 
13124  | 71  |       if (is_special() != is_input_special) { | 
13125  | 2  |         return true;  | 
13126  | 2  |       }  | 
13127  |  |  | 
13128  |  |       // If url includes credentials or has a non-null port, and buffer is  | 
13129  |  |       // "file", then return.  | 
13130  | 69  |       if ((has_credentials() || components.port != url_components::omitted) &&  | 
13131  | 69  |           parsed_type == ada::scheme::type::FILE) { | 
13132  | 1  |         return true;  | 
13133  | 1  |       }  | 
13134  |  |  | 
13135  |  |       // If url’s scheme is "file" and its host is an empty host, then return.  | 
13136  |  |       // An empty host is the empty string.  | 
13137  | 68  |       if (type == ada::scheme::type::FILE &&  | 
13138  | 68  |           components.host_start == components.host_end) { | 
13139  | 2  |         return true;  | 
13140  | 2  |       }  | 
13141  | 68  |     }  | 
13142  |  |  | 
13143  | 10.6k  |     type = parsed_type;  | 
13144  | 10.6k  |     set_scheme_from_view_with_colon(input_with_colon);  | 
13145  |  |  | 
13146  | 10.6k  |     if (has_state_override) { | 
13147  |  |       // This is uncommon.  | 
13148  | 66  |       uint16_t urls_scheme_port = get_special_port();  | 
13149  |  |  | 
13150  |  |       // If url’s port is url’s scheme’s default port, then set url’s port to  | 
13151  |  |       // null.  | 
13152  | 66  |       if (components.port == urls_scheme_port) { | 
13153  | 13  |         clear_port();  | 
13154  | 13  |       }  | 
13155  | 66  |     }  | 
13156  | 13.9k  |   } else {  // slow path | 
13157  | 13.9k  |     std::string _buffer = std::string(input);  | 
13158  |  |     // Next function is only valid if the input is ASCII and returns false  | 
13159  |  |     // otherwise, but it seems that we always have ascii content so we do not  | 
13160  |  |     // need to check the return value.  | 
13161  | 13.9k  |     unicode::to_lower_ascii(_buffer.data(), _buffer.size());  | 
13162  |  |  | 
13163  | 13.9k  |     if (has_state_override) { | 
13164  |  |       // If url’s scheme is a special scheme and buffer is not a special scheme,  | 
13165  |  |       // then return. If url’s scheme is not a special scheme and buffer is a  | 
13166  |  |       // special scheme, then return.  | 
13167  | 282  |       if (is_special() != ada::scheme::is_special(_buffer)) { | 
13168  | 117  |         return true;  | 
13169  | 117  |       }  | 
13170  |  |  | 
13171  |  |       // If url includes credentials or has a non-null port, and buffer is  | 
13172  |  |       // "file", then return.  | 
13173  | 165  |       if ((has_credentials() || components.port != url_components::omitted) &&  | 
13174  | 165  |           _buffer == "file") { | 
13175  | 1  |         return true;  | 
13176  | 1  |       }  | 
13177  |  |  | 
13178  |  |       // If url’s scheme is "file" and its host is an empty host, then return.  | 
13179  |  |       // An empty host is the empty string.  | 
13180  | 164  |       if (type == ada::scheme::type::FILE &&  | 
13181  | 164  |           components.host_start == components.host_end) { | 
13182  | 3  |         return true;  | 
13183  | 3  |       }  | 
13184  | 164  |     }  | 
13185  |  |  | 
13186  | 13.8k  |     set_scheme(_buffer);  | 
13187  |  |  | 
13188  | 13.8k  |     if (has_state_override) { | 
13189  |  |       // This is uncommon.  | 
13190  | 161  |       uint16_t urls_scheme_port = get_special_port();  | 
13191  |  |  | 
13192  |  |       // If url’s port is url’s scheme’s default port, then set url’s port to  | 
13193  |  |       // null.  | 
13194  | 161  |       if (components.port == urls_scheme_port) { | 
13195  | 14  |         clear_port();  | 
13196  | 14  |       }  | 
13197  | 161  |     }  | 
13198  | 13.8k  |   }  | 
13199  | 24.4k  |   ADA_ASSERT_TRUE(validate());  | 
13200  | 24.4k  |   return true;  | 
13201  | 24.6k  | } bool ada::url_aggregator::parse_scheme_with_colon<false>(std::__1::basic_string_view<char, std::__1::char_traits<char> >) Line  | Count  | Source  |  13108  | 24.2k  |     const std::string_view input_with_colon) { |  13109  | 24.2k  |   ada_log("url_aggregator::parse_scheme_with_colon ", input_with_colon); |  13110  | 24.2k  |   ADA_ASSERT_TRUE(validate());  |  13111  | 24.2k  |   ADA_ASSERT_TRUE(!helpers::overlaps(input_with_colon, buffer));  |  13112  | 24.2k  |   std::string_view input{input_with_colon}; |  13113  | 24.2k  |   input.remove_suffix(1);  |  13114  | 24.2k  |   auto parsed_type = ada::scheme::get_scheme_type(input);  |  13115  | 24.2k  |   bool is_input_special = (parsed_type != ada::scheme::NOT_SPECIAL);  |  13116  |  |   /**  |  13117  |  |    * In the common case, we will immediately recognize a special scheme (e.g.,  |  13118  |  |    *http, https), in which case, we can go really fast.  |  13119  |  |    **/  |  13120  | 24.2k  |   if (is_input_special) {  // fast path!!! |  13121  | 10.5k  |     if (has_state_override) { |  13122  |  |       // If url’s scheme is not a special scheme and buffer is a special scheme,  |  13123  |  |       // then return.  |  13124  | 0  |       if (is_special() != is_input_special) { |  13125  | 0  |         return true;  |  13126  | 0  |       }  |  13127  |  |  |  13128  |  |       // If url includes credentials or has a non-null port, and buffer is  |  13129  |  |       // "file", then return.  |  13130  | 0  |       if ((has_credentials() || components.port != url_components::omitted) &&  |  13131  | 0  |           parsed_type == ada::scheme::type::FILE) { |  13132  | 0  |         return true;  |  13133  | 0  |       }  |  13134  |  |  |  13135  |  |       // If url’s scheme is "file" and its host is an empty host, then return.  |  13136  |  |       // An empty host is the empty string.  |  13137  | 0  |       if (type == ada::scheme::type::FILE &&  |  13138  | 0  |           components.host_start == components.host_end) { |  13139  | 0  |         return true;  |  13140  | 0  |       }  |  13141  | 0  |     }  |  13142  |  |  |  13143  | 10.5k  |     type = parsed_type;  |  13144  | 10.5k  |     set_scheme_from_view_with_colon(input_with_colon);  |  13145  |  |  |  13146  | 10.5k  |     if (has_state_override) { |  13147  |  |       // This is uncommon.  |  13148  | 0  |       uint16_t urls_scheme_port = get_special_port();  |  13149  |  |  |  13150  |  |       // If url’s port is url’s scheme’s default port, then set url’s port to  |  13151  |  |       // null.  |  13152  | 0  |       if (components.port == urls_scheme_port) { |  13153  | 0  |         clear_port();  |  13154  | 0  |       }  |  13155  | 0  |     }  |  13156  | 13.6k  |   } else {  // slow path |  13157  | 13.6k  |     std::string _buffer = std::string(input);  |  13158  |  |     // Next function is only valid if the input is ASCII and returns false  |  13159  |  |     // otherwise, but it seems that we always have ascii content so we do not  |  13160  |  |     // need to check the return value.  |  13161  | 13.6k  |     unicode::to_lower_ascii(_buffer.data(), _buffer.size());  |  13162  |  |  |  13163  | 13.6k  |     if (has_state_override) { |  13164  |  |       // If url’s scheme is a special scheme and buffer is not a special scheme,  |  13165  |  |       // then return. If url’s scheme is not a special scheme and buffer is a  |  13166  |  |       // special scheme, then return.  |  13167  | 0  |       if (is_special() != ada::scheme::is_special(_buffer)) { |  13168  | 0  |         return true;  |  13169  | 0  |       }  |  13170  |  |  |  13171  |  |       // If url includes credentials or has a non-null port, and buffer is  |  13172  |  |       // "file", then return.  |  13173  | 0  |       if ((has_credentials() || components.port != url_components::omitted) &&  |  13174  | 0  |           _buffer == "file") { |  13175  | 0  |         return true;  |  13176  | 0  |       }  |  13177  |  |  |  13178  |  |       // If url’s scheme is "file" and its host is an empty host, then return.  |  13179  |  |       // An empty host is the empty string.  |  13180  | 0  |       if (type == ada::scheme::type::FILE &&  |  13181  | 0  |           components.host_start == components.host_end) { |  13182  | 0  |         return true;  |  13183  | 0  |       }  |  13184  | 0  |     }  |  13185  |  |  |  13186  | 13.6k  |     set_scheme(_buffer);  |  13187  |  |  |  13188  | 13.6k  |     if (has_state_override) { |  13189  |  |       // This is uncommon.  |  13190  | 0  |       uint16_t urls_scheme_port = get_special_port();  |  13191  |  |  |  13192  |  |       // If url’s port is url’s scheme’s default port, then set url’s port to  |  13193  |  |       // null.  |  13194  | 0  |       if (components.port == urls_scheme_port) { |  13195  | 0  |         clear_port();  |  13196  | 0  |       }  |  13197  | 0  |     }  |  13198  | 13.6k  |   }  |  13199  | 24.2k  |   ADA_ASSERT_TRUE(validate());  |  13200  | 24.2k  |   return true;  |  13201  | 24.2k  | }  |  
 bool ada::url_aggregator::parse_scheme_with_colon<true>(std::__1::basic_string_view<char, std::__1::char_traits<char> >) Line  | Count  | Source  |  13108  | 353  |     const std::string_view input_with_colon) { |  13109  | 353  |   ada_log("url_aggregator::parse_scheme_with_colon ", input_with_colon); |  13110  | 353  |   ADA_ASSERT_TRUE(validate());  |  13111  | 353  |   ADA_ASSERT_TRUE(!helpers::overlaps(input_with_colon, buffer));  |  13112  | 353  |   std::string_view input{input_with_colon}; |  13113  | 353  |   input.remove_suffix(1);  |  13114  | 353  |   auto parsed_type = ada::scheme::get_scheme_type(input);  |  13115  | 353  |   bool is_input_special = (parsed_type != ada::scheme::NOT_SPECIAL);  |  13116  |  |   /**  |  13117  |  |    * In the common case, we will immediately recognize a special scheme (e.g.,  |  13118  |  |    *http, https), in which case, we can go really fast.  |  13119  |  |    **/  |  13120  | 353  |   if (is_input_special) {  // fast path!!! |  13121  | 71  |     if (has_state_override) { |  13122  |  |       // If url’s scheme is not a special scheme and buffer is a special scheme,  |  13123  |  |       // then return.  |  13124  | 71  |       if (is_special() != is_input_special) { |  13125  | 2  |         return true;  |  13126  | 2  |       }  |  13127  |  |  |  13128  |  |       // If url includes credentials or has a non-null port, and buffer is  |  13129  |  |       // "file", then return.  |  13130  | 69  |       if ((has_credentials() || components.port != url_components::omitted) &&  |  13131  | 69  |           parsed_type == ada::scheme::type::FILE) { |  13132  | 1  |         return true;  |  13133  | 1  |       }  |  13134  |  |  |  13135  |  |       // If url’s scheme is "file" and its host is an empty host, then return.  |  13136  |  |       // An empty host is the empty string.  |  13137  | 68  |       if (type == ada::scheme::type::FILE &&  |  13138  | 68  |           components.host_start == components.host_end) { |  13139  | 2  |         return true;  |  13140  | 2  |       }  |  13141  | 68  |     }  |  13142  |  |  |  13143  | 66  |     type = parsed_type;  |  13144  | 66  |     set_scheme_from_view_with_colon(input_with_colon);  |  13145  |  |  |  13146  | 66  |     if (has_state_override) { |  13147  |  |       // This is uncommon.  |  13148  | 66  |       uint16_t urls_scheme_port = get_special_port();  |  13149  |  |  |  13150  |  |       // If url’s port is url’s scheme’s default port, then set url’s port to  |  13151  |  |       // null.  |  13152  | 66  |       if (components.port == urls_scheme_port) { |  13153  | 13  |         clear_port();  |  13154  | 13  |       }  |  13155  | 66  |     }  |  13156  | 282  |   } else {  // slow path |  13157  | 282  |     std::string _buffer = std::string(input);  |  13158  |  |     // Next function is only valid if the input is ASCII and returns false  |  13159  |  |     // otherwise, but it seems that we always have ascii content so we do not  |  13160  |  |     // need to check the return value.  |  13161  | 282  |     unicode::to_lower_ascii(_buffer.data(), _buffer.size());  |  13162  |  |  |  13163  | 282  |     if (has_state_override) { |  13164  |  |       // If url’s scheme is a special scheme and buffer is not a special scheme,  |  13165  |  |       // then return. If url’s scheme is not a special scheme and buffer is a  |  13166  |  |       // special scheme, then return.  |  13167  | 282  |       if (is_special() != ada::scheme::is_special(_buffer)) { |  13168  | 117  |         return true;  |  13169  | 117  |       }  |  13170  |  |  |  13171  |  |       // If url includes credentials or has a non-null port, and buffer is  |  13172  |  |       // "file", then return.  |  13173  | 165  |       if ((has_credentials() || components.port != url_components::omitted) &&  |  13174  | 165  |           _buffer == "file") { |  13175  | 1  |         return true;  |  13176  | 1  |       }  |  13177  |  |  |  13178  |  |       // If url’s scheme is "file" and its host is an empty host, then return.  |  13179  |  |       // An empty host is the empty string.  |  13180  | 164  |       if (type == ada::scheme::type::FILE &&  |  13181  | 164  |           components.host_start == components.host_end) { |  13182  | 3  |         return true;  |  13183  | 3  |       }  |  13184  | 164  |     }  |  13185  |  |  |  13186  | 161  |     set_scheme(_buffer);  |  13187  |  |  |  13188  | 161  |     if (has_state_override) { |  13189  |  |       // This is uncommon.  |  13190  | 161  |       uint16_t urls_scheme_port = get_special_port();  |  13191  |  |  |  13192  |  |       // If url’s port is url’s scheme’s default port, then set url’s port to  |  13193  |  |       // null.  |  13194  | 161  |       if (components.port == urls_scheme_port) { |  13195  | 14  |         clear_port();  |  13196  | 14  |       }  |  13197  | 161  |     }  |  13198  | 161  |   }  |  13199  | 227  |   ADA_ASSERT_TRUE(validate());  |  13200  | 227  |   return true;  |  13201  | 353  | }  |  
  | 
13202  |  |  | 
13203  | 803  | inline void url_aggregator::copy_scheme(const url_aggregator& u) noexcept { | 
13204  | 803  |   ada_log("url_aggregator::copy_scheme ", u.buffer); | 
13205  | 803  |   ADA_ASSERT_TRUE(validate());  | 
13206  |  |   // next line could overflow but unsigned arithmetic has well-defined  | 
13207  |  |   // overflows.  | 
13208  | 803  |   uint32_t new_difference = u.components.protocol_end - components.protocol_end;  | 
13209  | 803  |   type = u.type;  | 
13210  | 803  |   buffer.erase(0, components.protocol_end);  | 
13211  | 803  |   buffer.insert(0, u.get_protocol());  | 
13212  | 803  |   components.protocol_end = u.components.protocol_end;  | 
13213  |  |  | 
13214  |  |   // No need to update the components  | 
13215  | 803  |   if (new_difference == 0) { | 
13216  | 118  |     return;  | 
13217  | 118  |   }  | 
13218  |  |  | 
13219  |  |   // Update the rest of the components.  | 
13220  | 685  |   components.username_end += new_difference;  | 
13221  | 685  |   components.host_start += new_difference;  | 
13222  | 685  |   components.host_end += new_difference;  | 
13223  | 685  |   components.pathname_start += new_difference;  | 
13224  | 685  |   if (components.search_start != url_components::omitted) { | 
13225  | 0  |     components.search_start += new_difference;  | 
13226  | 0  |   }  | 
13227  | 685  |   if (components.hash_start != url_components::omitted) { | 
13228  | 0  |     components.hash_start += new_difference;  | 
13229  | 0  |   }  | 
13230  | 685  |   ADA_ASSERT_TRUE(validate());  | 
13231  | 685  | }  | 
13232  |  |  | 
13233  |  | inline void url_aggregator::set_scheme_from_view_with_colon(  | 
13234  | 10.6k  |     std::string_view new_scheme_with_colon) noexcept { | 
13235  | 10.6k  |   ada_log("url_aggregator::set_scheme_from_view_with_colon ", | 
13236  | 10.6k  |           new_scheme_with_colon);  | 
13237  | 10.6k  |   ADA_ASSERT_TRUE(validate());  | 
13238  | 10.6k  |   ADA_ASSERT_TRUE(!new_scheme_with_colon.empty() &&  | 
13239  | 10.6k  |                   new_scheme_with_colon.back() == ':');  | 
13240  |  |   // next line could overflow but unsigned arithmetic has well-defined  | 
13241  |  |   // overflows.  | 
13242  | 10.6k  |   uint32_t new_difference =  | 
13243  | 10.6k  |       uint32_t(new_scheme_with_colon.size()) - components.protocol_end;  | 
13244  |  |  | 
13245  | 10.6k  |   if (buffer.empty()) { | 
13246  | 10.5k  |     buffer.append(new_scheme_with_colon);  | 
13247  | 10.5k  |   } else { | 
13248  | 66  |     buffer.erase(0, components.protocol_end);  | 
13249  | 66  |     buffer.insert(0, new_scheme_with_colon);  | 
13250  | 66  |   }  | 
13251  | 10.6k  |   components.protocol_end += new_difference;  | 
13252  |  |  | 
13253  |  |   // Update the rest of the components.  | 
13254  | 10.6k  |   components.username_end += new_difference;  | 
13255  | 10.6k  |   components.host_start += new_difference;  | 
13256  | 10.6k  |   components.host_end += new_difference;  | 
13257  | 10.6k  |   components.pathname_start += new_difference;  | 
13258  | 10.6k  |   if (components.search_start != url_components::omitted) { | 
13259  | 18  |     components.search_start += new_difference;  | 
13260  | 18  |   }  | 
13261  | 10.6k  |   if (components.hash_start != url_components::omitted) { | 
13262  | 10  |     components.hash_start += new_difference;  | 
13263  | 10  |   }  | 
13264  | 10.6k  |   ADA_ASSERT_TRUE(validate());  | 
13265  | 10.6k  | }  | 
13266  |  |  | 
13267  | 13.8k  | inline void url_aggregator::set_scheme(std::string_view new_scheme) noexcept { | 
13268  | 13.8k  |   ada_log("url_aggregator::set_scheme ", new_scheme); | 
13269  | 13.8k  |   ADA_ASSERT_TRUE(validate());  | 
13270  | 13.8k  |   ADA_ASSERT_TRUE(new_scheme.empty() || new_scheme.back() != ':');  | 
13271  |  |   // next line could overflow but unsigned arithmetic has well-defined  | 
13272  |  |   // overflows.  | 
13273  | 13.8k  |   uint32_t new_difference =  | 
13274  | 13.8k  |       uint32_t(new_scheme.size()) - components.protocol_end + 1;  | 
13275  |  |  | 
13276  | 13.8k  |   type = ada::scheme::get_scheme_type(new_scheme);  | 
13277  | 13.8k  |   if (buffer.empty()) { | 
13278  | 13.6k  |     buffer.append(helpers::concat(new_scheme, ":"));  | 
13279  | 13.6k  |   } else { | 
13280  | 161  |     buffer.erase(0, components.protocol_end);  | 
13281  | 161  |     buffer.insert(0, helpers::concat(new_scheme, ":"));  | 
13282  | 161  |   }  | 
13283  | 13.8k  |   components.protocol_end = uint32_t(new_scheme.size() + 1);  | 
13284  |  |  | 
13285  |  |   // Update the rest of the components.  | 
13286  | 13.8k  |   components.username_end += new_difference;  | 
13287  | 13.8k  |   components.host_start += new_difference;  | 
13288  | 13.8k  |   components.host_end += new_difference;  | 
13289  | 13.8k  |   components.pathname_start += new_difference;  | 
13290  | 13.8k  |   if (components.search_start != url_components::omitted) { | 
13291  | 16  |     components.search_start += new_difference;  | 
13292  | 16  |   }  | 
13293  | 13.8k  |   if (components.hash_start != url_components::omitted) { | 
13294  | 18  |     components.hash_start += new_difference;  | 
13295  | 18  |   }  | 
13296  | 13.8k  |   ADA_ASSERT_TRUE(validate());  | 
13297  | 13.8k  | }  | 
13298  |  |  | 
13299  | 8.27k  | bool url_aggregator::set_protocol(const std::string_view input) { | 
13300  | 8.27k  |   ada_log("url_aggregator::set_protocol ", input); | 
13301  | 8.27k  |   ADA_ASSERT_TRUE(validate());  | 
13302  | 8.27k  |   ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));  | 
13303  | 8.27k  |   std::string view(input);  | 
13304  | 8.27k  |   helpers::remove_ascii_tab_or_newline(view);  | 
13305  | 8.27k  |   if (view.empty()) { | 
13306  | 6.74k  |     return true;  | 
13307  | 6.74k  |   }  | 
13308  |  |  | 
13309  |  |   // Schemes should start with alpha values.  | 
13310  | 1.52k  |   if (!checkers::is_alpha(view[0])) { | 
13311  | 1.08k  |     return false;  | 
13312  | 1.08k  |   }  | 
13313  |  |  | 
13314  | 437  |   view.append(":"); | 
13315  |  |  | 
13316  | 437  |   std::string::iterator pointer =  | 
13317  | 437  |       std::find_if_not(view.begin(), view.end(), unicode::is_alnum_plus);  | 
13318  |  |  | 
13319  | 437  |   if (pointer != view.end() && *pointer == ':') { | 
13320  | 353  |     return parse_scheme_with_colon<true>(  | 
13321  | 353  |         std::string_view(view.data(), pointer - view.begin() + 1));  | 
13322  | 353  |   }  | 
13323  | 84  |   return false;  | 
13324  | 437  | }  | 
13325  |  |  | 
13326  | 8.27k  | bool url_aggregator::set_username(const std::string_view input) { | 
13327  | 8.27k  |   ada_log("url_aggregator::set_username '", input, "' "); | 
13328  | 8.27k  |   ADA_ASSERT_TRUE(validate());  | 
13329  | 8.27k  |   ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));  | 
13330  | 8.27k  |   if (cannot_have_credentials_or_port()) { | 
13331  | 4.04k  |     return false;  | 
13332  | 4.04k  |   }  | 
13333  | 4.22k  |   size_t idx = ada::unicode::percent_encode_index(  | 
13334  | 4.22k  |       input, character_sets::USERINFO_PERCENT_ENCODE);  | 
13335  | 4.22k  |   if (idx == input.size()) { | 
13336  | 3.66k  |     update_base_username(input);  | 
13337  | 3.66k  |   } else { | 
13338  |  |     // We only create a temporary string if we have to!  | 
13339  | 558  |     update_base_username(ada::unicode::percent_encode(  | 
13340  | 558  |         input, character_sets::USERINFO_PERCENT_ENCODE, idx));  | 
13341  | 558  |   }  | 
13342  | 4.22k  |   ADA_ASSERT_TRUE(validate());  | 
13343  | 4.22k  |   return true;  | 
13344  | 8.27k  | }  | 
13345  |  |  | 
13346  | 8.27k  | bool url_aggregator::set_password(const std::string_view input) { | 
13347  | 8.27k  |   ada_log("url_aggregator::set_password '", input, "'"); | 
13348  | 8.27k  |   ADA_ASSERT_TRUE(validate());  | 
13349  | 8.27k  |   ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));  | 
13350  | 8.27k  |   if (cannot_have_credentials_or_port()) { | 
13351  | 4.04k  |     return false;  | 
13352  | 4.04k  |   }  | 
13353  | 4.22k  |   size_t idx = ada::unicode::percent_encode_index(  | 
13354  | 4.22k  |       input, character_sets::USERINFO_PERCENT_ENCODE);  | 
13355  | 4.22k  |   if (idx == input.size()) { | 
13356  | 3.66k  |     update_base_password(input);  | 
13357  | 3.66k  |   } else { | 
13358  |  |     // We only create a temporary string if we have to!  | 
13359  | 558  |     update_base_password(ada::unicode::percent_encode(  | 
13360  | 558  |         input, character_sets::USERINFO_PERCENT_ENCODE, idx));  | 
13361  | 558  |   }  | 
13362  | 4.22k  |   ADA_ASSERT_TRUE(validate());  | 
13363  | 4.22k  |   return true;  | 
13364  | 8.27k  | }  | 
13365  |  |  | 
13366  | 8.44k  | bool url_aggregator::set_port(const std::string_view input) { | 
13367  | 8.44k  |   ada_log("url_aggregator::set_port ", input); | 
13368  | 8.44k  |   ADA_ASSERT_TRUE(validate());  | 
13369  | 8.44k  |   ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));  | 
13370  | 8.44k  |   if (cannot_have_credentials_or_port()) { | 
13371  | 4.00k  |     return false;  | 
13372  | 4.00k  |   }  | 
13373  | 4.44k  |   std::string trimmed(input);  | 
13374  | 4.44k  |   helpers::remove_ascii_tab_or_newline(trimmed);  | 
13375  | 4.44k  |   if (trimmed.empty()) { | 
13376  | 3.28k  |     clear_port();  | 
13377  | 3.28k  |     return true;  | 
13378  | 3.28k  |   }  | 
13379  |  |   // Input should not start with control characters.  | 
13380  | 1.16k  |   if (ada::unicode::is_c0_control_or_space(trimmed.front())) { | 
13381  | 63  |     return false;  | 
13382  | 63  |   }  | 
13383  |  |   // Input should contain at least one ascii digit.  | 
13384  | 1.09k  |   if (input.find_first_of("0123456789") == std::string_view::npos) { | 
13385  | 523  |     return false;  | 
13386  | 523  |   }  | 
13387  |  |  | 
13388  |  |   // Revert changes if parse_port fails.  | 
13389  | 575  |   uint32_t previous_port = components.port;  | 
13390  | 575  |   parse_port(trimmed);  | 
13391  | 575  |   if (is_valid) { | 
13392  | 425  |     return true;  | 
13393  | 425  |   }  | 
13394  | 150  |   update_base_port(previous_port);  | 
13395  | 150  |   is_valid = true;  | 
13396  | 150  |   ADA_ASSERT_TRUE(validate());  | 
13397  | 150  |   return false;  | 
13398  | 575  | }  | 
13399  |  |  | 
13400  | 8.27k  | bool url_aggregator::set_pathname(const std::string_view input) { | 
13401  | 8.27k  |   ada_log("url_aggregator::set_pathname ", input); | 
13402  | 8.27k  |   ADA_ASSERT_TRUE(validate());  | 
13403  | 8.27k  |   ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));  | 
13404  | 8.27k  |   if (has_opaque_path) { | 
13405  | 1.06k  |     return false;  | 
13406  | 1.06k  |   }  | 
13407  | 7.20k  |   clear_pathname();  | 
13408  | 7.20k  |   parse_path(input);  | 
13409  | 7.20k  |   if (checkers::begins_with(input, "//") && !has_authority() &&  | 
13410  | 7.20k  |       !has_dash_dot()) { | 
13411  | 3  |     buffer.insert(components.pathname_start, "/.");  | 
13412  | 3  |     components.pathname_start += 2;  | 
13413  | 3  |   }  | 
13414  | 7.20k  |   ADA_ASSERT_TRUE(validate());  | 
13415  | 7.20k  |   return true;  | 
13416  | 8.27k  | }  | 
13417  |  |  | 
13418  | 7.20k  | ada_really_inline void url_aggregator::parse_path(std::string_view input) { | 
13419  | 7.20k  |   ada_log("url_aggregator::parse_path ", input); | 
13420  | 7.20k  |   ADA_ASSERT_TRUE(validate());  | 
13421  | 7.20k  |   ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));  | 
13422  | 7.20k  |   std::string tmp_buffer;  | 
13423  | 7.20k  |   std::string_view internal_input;  | 
13424  | 7.20k  |   if (unicode::has_tabs_or_newline(input)) { | 
13425  | 140  |     tmp_buffer = input;  | 
13426  |  |     // Optimization opportunity: Instead of copying and then pruning, we could  | 
13427  |  |     // just directly build the string from user_input.  | 
13428  | 140  |     helpers::remove_ascii_tab_or_newline(tmp_buffer);  | 
13429  | 140  |     internal_input = tmp_buffer;  | 
13430  | 7.06k  |   } else { | 
13431  | 7.06k  |     internal_input = input;  | 
13432  | 7.06k  |   }  | 
13433  |  |  | 
13434  |  |   // If url is special, then:  | 
13435  | 7.20k  |   if (is_special()) { | 
13436  | 5.52k  |     if (internal_input.empty()) { | 
13437  | 4.49k  |       update_base_pathname("/"); | 
13438  | 4.49k  |     } else if ((internal_input[0] == '/') || (internal_input[0] == '\\')) { | 
13439  | 24  |       consume_prepared_path(internal_input.substr(1));  | 
13440  | 1.00k  |     } else { | 
13441  | 1.00k  |       consume_prepared_path(internal_input);  | 
13442  | 1.00k  |     }  | 
13443  | 5.52k  |   } else if (!internal_input.empty()) { | 
13444  | 345  |     if (internal_input[0] == '/') { | 
13445  | 32  |       consume_prepared_path(internal_input.substr(1));  | 
13446  | 313  |     } else { | 
13447  | 313  |       consume_prepared_path(internal_input);  | 
13448  | 313  |     }  | 
13449  | 1.33k  |   } else { | 
13450  |  |     // Non-special URLs with an empty host can have their paths erased  | 
13451  |  |     // Path-only URLs cannot have their paths erased  | 
13452  | 1.33k  |     if (components.host_start == components.host_end && !has_authority()) { | 
13453  | 1.17k  |       update_base_pathname("/"); | 
13454  | 1.17k  |     }  | 
13455  | 1.33k  |   }  | 
13456  | 7.20k  |   ADA_ASSERT_TRUE(validate());  | 
13457  | 7.20k  | }  | 
13458  |  |  | 
13459  | 8.27k  | void url_aggregator::set_search(const std::string_view input) { | 
13460  | 8.27k  |   ada_log("url_aggregator::set_search ", input); | 
13461  | 8.27k  |   ADA_ASSERT_TRUE(validate());  | 
13462  | 8.27k  |   ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));  | 
13463  | 8.27k  |   if (input.empty()) { | 
13464  | 6.67k  |     clear_search();  | 
13465  | 6.67k  |     helpers::strip_trailing_spaces_from_opaque_path(*this);  | 
13466  | 6.67k  |     return;  | 
13467  | 6.67k  |   }  | 
13468  |  |  | 
13469  | 1.60k  |   std::string new_value;  | 
13470  | 1.60k  |   new_value = input[0] == '?' ? input.substr(1) : input;  | 
13471  | 1.60k  |   helpers::remove_ascii_tab_or_newline(new_value);  | 
13472  |  |  | 
13473  | 1.60k  |   auto query_percent_encode_set =  | 
13474  | 1.60k  |       is_special() ? ada::character_sets::SPECIAL_QUERY_PERCENT_ENCODE  | 
13475  | 1.60k  |                    : ada::character_sets::QUERY_PERCENT_ENCODE;  | 
13476  |  |  | 
13477  | 1.60k  |   update_base_search(new_value, query_percent_encode_set);  | 
13478  | 1.60k  |   ADA_ASSERT_TRUE(validate());  | 
13479  | 1.60k  | }  | 
13480  |  |  | 
13481  | 8.27k  | void url_aggregator::set_hash(const std::string_view input) { | 
13482  | 8.27k  |   ada_log("url_aggregator::set_hash ", input); | 
13483  | 8.27k  |   ADA_ASSERT_TRUE(validate());  | 
13484  | 8.27k  |   ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));  | 
13485  | 8.27k  |   if (input.empty()) { | 
13486  | 6.67k  |     if (components.hash_start != url_components::omitted) { | 
13487  | 126  |       buffer.resize(components.hash_start);  | 
13488  | 126  |       components.hash_start = url_components::omitted;  | 
13489  | 126  |     }  | 
13490  | 6.67k  |     helpers::strip_trailing_spaces_from_opaque_path(*this);  | 
13491  | 6.67k  |     return;  | 
13492  | 6.67k  |   }  | 
13493  |  |  | 
13494  | 1.60k  |   std::string new_value;  | 
13495  | 1.60k  |   new_value = input[0] == '#' ? input.substr(1) : input;  | 
13496  | 1.60k  |   helpers::remove_ascii_tab_or_newline(new_value);  | 
13497  | 1.60k  |   update_unencoded_base_hash(new_value);  | 
13498  | 1.60k  |   ADA_ASSERT_TRUE(validate());  | 
13499  | 1.60k  | }  | 
13500  |  |  | 
13501  | 0  | bool url_aggregator::set_href(const std::string_view input) { | 
13502  | 0  |   ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));  | 
13503  | 0  |   ada_log("url_aggregator::set_href ", input, "[", input.size(), " bytes]"); | 
13504  | 0  |   ada::result<url_aggregator> out = ada::parse<url_aggregator>(input);  | 
13505  | 0  |   ada_log("url_aggregator::set_href, success :", out.has_value()); | 
13506  |  | 
  | 
13507  | 0  |   if (out) { | 
13508  | 0  |     ada_log("url_aggregator::set_href, parsed ", out->to_string()); | 
13509  |  |     // TODO: Figure out why the following line puts test to never finish.  | 
13510  | 0  |     *this = *out;  | 
13511  | 0  |   }  | 
13512  |  | 
  | 
13513  | 0  |   return out.has_value();  | 
13514  | 0  | }  | 
13515  |  |  | 
13516  | 17.8k  | ada_really_inline bool url_aggregator::parse_host(std::string_view input) { | 
13517  | 17.8k  |   ada_log("url_aggregator:parse_host ", input, "[", input.size(), " bytes]"); | 
13518  | 17.8k  |   ADA_ASSERT_TRUE(validate());  | 
13519  | 17.8k  |   ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));  | 
13520  | 17.8k  |   if (input.empty()) { | 
13521  | 31  |     return is_valid = false;  | 
13522  | 31  |   }  // technically unnecessary.  | 
13523  |  |   // If input starts with U+005B ([), then:  | 
13524  | 17.7k  |   if (input[0] == '[') { | 
13525  |  |     // If input does not end with U+005D (]), validation error, return failure.  | 
13526  | 1.30k  |     if (input.back() != ']') { | 
13527  | 385  |       return is_valid = false;  | 
13528  | 385  |     }  | 
13529  | 922  |     ada_log("parse_host ipv6"); | 
13530  |  |  | 
13531  |  |     // Return the result of IPv6 parsing input with its leading U+005B ([) and  | 
13532  |  |     // trailing U+005D (]) removed.  | 
13533  | 922  |     input.remove_prefix(1);  | 
13534  | 922  |     input.remove_suffix(1);  | 
13535  | 922  |     return parse_ipv6(input);  | 
13536  | 1.30k  |   }  | 
13537  |  |  | 
13538  |  |   // If isNotSpecial is true, then return the result of opaque-host parsing  | 
13539  |  |   // input.  | 
13540  | 16.4k  |   if (!is_special()) { | 
13541  | 1.00k  |     return parse_opaque_host(input);  | 
13542  | 1.00k  |   }  | 
13543  |  |   // Let domain be the result of running UTF-8 decode without BOM on the  | 
13544  |  |   // percent-decoding of input. Let asciiDomain be the result of running domain  | 
13545  |  |   // to ASCII with domain and false. The most common case is an ASCII input, in  | 
13546  |  |   // which case we do not need to call the expensive 'to_ascii' if a few  | 
13547  |  |   // conditions are met: no '%' and no 'xn-' subsequence.  | 
13548  |  |  | 
13549  |  |   // Often, the input does not contain any forbidden code points, and no upper  | 
13550  |  |   // case ASCII letter, then we can just copy it to the buffer. We want to  | 
13551  |  |   // optimize for such a common case.  | 
13552  | 15.4k  |   uint8_t is_forbidden_or_upper =  | 
13553  | 15.4k  |       unicode::contains_forbidden_domain_code_point_or_upper(input.data(),  | 
13554  | 15.4k  |                                                              input.size());  | 
13555  |  |   // Minor optimization opportunity:  | 
13556  |  |   // contains_forbidden_domain_code_point_or_upper could be extend to check for  | 
13557  |  |   // the presence of characters that cannot appear in the ipv4 address and we  | 
13558  |  |   // could also check whether x and n and - are present, and so we could skip  | 
13559  |  |   // some of the checks below. However, the gains are likely to be small, and  | 
13560  |  |   // the code would be more complex.  | 
13561  | 15.4k  |   if (is_forbidden_or_upper == 0 &&  | 
13562  | 15.4k  |       input.find("xn-") == std::string_view::npos) { | 
13563  |  |     // fast path  | 
13564  | 7.91k  |     update_base_hostname(input);  | 
13565  | 7.91k  |     if (checkers::is_ipv4(get_hostname())) { | 
13566  | 3.21k  |       ada_log("parse_host fast path ipv4"); | 
13567  | 3.21k  |       return parse_ipv4(get_hostname());  | 
13568  | 3.21k  |     }  | 
13569  | 4.69k  |     ada_log("parse_host fast path ", get_hostname()); | 
13570  | 4.69k  |     return true;  | 
13571  | 7.91k  |   }  | 
13572  |  |   // We have encountered at least one forbidden code point or the input contains  | 
13573  |  |   // 'xn-' (case insensitive), so we need to call 'to_ascii' to perform the full  | 
13574  |  |   // conversion.  | 
13575  |  |  | 
13576  | 7.54k  |   ada_log("parse_host calling to_ascii"); | 
13577  | 7.54k  |   std::optional<std::string> host = std::string(get_hostname());  | 
13578  | 7.54k  |   is_valid = ada::unicode::to_ascii(host, input, input.find('%')); | 
13579  | 7.54k  |   if (!is_valid) { | 
13580  | 1.99k  |     ada_log("parse_host to_ascii returns false"); | 
13581  | 1.99k  |     return is_valid = false;  | 
13582  | 1.99k  |   }  | 
13583  |  |  | 
13584  | 5.55k  |   if (std::any_of(host.value().begin(), host.value().end(),  | 
13585  | 5.55k  |                   ada::unicode::is_forbidden_domain_code_point)) { | 
13586  | 0  |     return is_valid = false;  | 
13587  | 0  |   }  | 
13588  |  |  | 
13589  |  |   // If asciiDomain ends in a number, then return the result of IPv4 parsing  | 
13590  |  |   // asciiDomain.  | 
13591  | 5.55k  |   if (checkers::is_ipv4(host.value())) { | 
13592  | 808  |     ada_log("parse_host got ipv4", *host); | 
13593  | 808  |     return parse_ipv4(host.value());  | 
13594  | 808  |   }  | 
13595  |  |  | 
13596  | 4.74k  |   update_base_hostname(host.value());  | 
13597  | 4.74k  |   ADA_ASSERT_TRUE(validate());  | 
13598  | 4.74k  |   return true;  | 
13599  | 5.55k  | }  | 
13600  |  |  | 
13601  |  | template <bool override_hostname>  | 
13602  | 17.9k  | bool url_aggregator::set_host_or_hostname(const std::string_view input) { | 
13603  | 17.9k  |   ada_log("url_aggregator::set_host_or_hostname ", input); | 
13604  | 17.9k  |   ADA_ASSERT_TRUE(validate());  | 
13605  | 17.9k  |   ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));  | 
13606  | 17.9k  |   if (has_opaque_path) { | 
13607  | 2.13k  |     return false;  | 
13608  | 2.13k  |   }  | 
13609  |  |  | 
13610  | 15.8k  |   std::string previous_host = std::string(get_hostname());  | 
13611  | 15.8k  |   uint32_t previous_port = components.port;  | 
13612  |  |  | 
13613  | 15.8k  |   size_t host_end_pos = input.find('#'); | 
13614  | 15.8k  |   std::string _host(input.data(), host_end_pos != std::string_view::npos  | 
13615  | 15.8k  |                                       ? host_end_pos  | 
13616  | 15.8k  |                                       : input.size());  | 
13617  | 15.8k  |   helpers::remove_ascii_tab_or_newline(_host);  | 
13618  | 15.8k  |   std::string_view new_host(_host);  | 
13619  |  |  | 
13620  |  |   // If url's scheme is "file", then set state to file host state, instead of  | 
13621  |  |   // host state.  | 
13622  | 15.8k  |   if (type != ada::scheme::type::FILE) { | 
13623  | 12.2k  |     std::string_view host_view(_host.data(), _host.length());  | 
13624  | 12.2k  |     auto [location, found_colon] =  | 
13625  | 12.2k  |         helpers::get_host_delimiter_location(is_special(), host_view);  | 
13626  |  |  | 
13627  |  |     // Otherwise, if c is U+003A (:) and insideBrackets is false, then:  | 
13628  |  |     // Note: the 'found_colon' value is true if and only if a colon was  | 
13629  |  |     // encountered while not inside brackets.  | 
13630  | 12.2k  |     if (found_colon) { | 
13631  | 400  |       if (override_hostname) { | 
13632  | 200  |         return false;  | 
13633  | 200  |       }  | 
13634  | 200  |       std::string_view sub_buffer = new_host.substr(location + 1);  | 
13635  | 200  |       if (!sub_buffer.empty()) { | 
13636  | 177  |         set_port(sub_buffer);  | 
13637  | 177  |       }  | 
13638  | 200  |     }  | 
13639  |  |     // If url is special and host_view is the empty string, validation error,  | 
13640  |  |     // return failure. Otherwise, if state override is given, host_view is the  | 
13641  |  |     // empty string, and either url includes credentials or url’s port is  | 
13642  |  |     // non-null, return.  | 
13643  | 11.8k  |     else if (host_view.empty() &&  | 
13644  | 11.8k  |              (is_special() || has_credentials() ||  | 
13645  | 9.43k  |               components.port != url_components::omitted)) { | 
13646  | 6.64k  |       return false;  | 
13647  | 6.64k  |     }  | 
13648  |  |  | 
13649  |  |     // Let host be the result of host parsing host_view with url is not special.  | 
13650  | 5.36k  |     if (host_view.empty()) { | 
13651  | 2.86k  |       if (has_hostname()) { | 
13652  | 307  |         clear_hostname();  // easy!  | 
13653  | 2.56k  |       } else if (has_dash_dot()) { | 
13654  | 34  |         add_authority_slashes_if_needed();  | 
13655  | 34  |         delete_dash_dot();  | 
13656  | 34  |       }  | 
13657  | 2.86k  |       return true;  | 
13658  | 2.86k  |     }  | 
13659  |  |  | 
13660  | 2.49k  |     bool succeeded = parse_host(host_view);  | 
13661  | 2.49k  |     if (!succeeded) { | 
13662  | 669  |       update_base_hostname(previous_host);  | 
13663  | 669  |       update_base_port(previous_port);  | 
13664  | 1.82k  |     } else if (has_dash_dot()) { | 
13665  |  |       // Should remove dash_dot from pathname  | 
13666  | 9  |       delete_dash_dot();  | 
13667  | 9  |     }  | 
13668  | 2.49k  |     return succeeded;  | 
13669  | 5.36k  |   }  | 
13670  |  |  | 
13671  | 3.60k  |   size_t location = new_host.find_first_of("/\\?"); | 
13672  | 3.60k  |   if (location != std::string_view::npos) { | 
13673  | 44  |     new_host.remove_suffix(new_host.length() - location);  | 
13674  | 44  |   }  | 
13675  |  |  | 
13676  | 3.60k  |   if (new_host.empty()) { | 
13677  |  |     // Set url’s host to the empty string.  | 
13678  | 2.69k  |     clear_hostname();  | 
13679  | 2.69k  |   } else { | 
13680  |  |     // Let host be the result of host parsing buffer with url is not special.  | 
13681  | 906  |     if (!parse_host(new_host)) { | 
13682  | 138  |       update_base_hostname(previous_host);  | 
13683  | 138  |       update_base_port(previous_port);  | 
13684  | 138  |       return false;  | 
13685  | 138  |     }  | 
13686  |  |  | 
13687  |  |     // If host is "localhost", then set host to the empty string.  | 
13688  | 768  |     if (helpers::substring(buffer, components.host_start,  | 
13689  | 768  |                            components.host_end) == "localhost") { | 
13690  | 40  |       clear_hostname();  | 
13691  | 40  |     }  | 
13692  | 768  |   }  | 
13693  | 3.46k  |   ADA_ASSERT_TRUE(validate());  | 
13694  | 3.46k  |   return true;  | 
13695  | 3.60k  | } bool ada::url_aggregator::set_host_or_hostname<false>(std::__1::basic_string_view<char, std::__1::char_traits<char> >) Line  | Count  | Source  |  13602  | 8.53k  | bool url_aggregator::set_host_or_hostname(const std::string_view input) { |  13603  | 8.53k  |   ada_log("url_aggregator::set_host_or_hostname ", input); |  13604  | 8.53k  |   ADA_ASSERT_TRUE(validate());  |  13605  | 8.53k  |   ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));  |  13606  | 8.53k  |   if (has_opaque_path) { |  13607  | 1.06k  |     return false;  |  13608  | 1.06k  |   }  |  13609  |  |  |  13610  | 7.46k  |   std::string previous_host = std::string(get_hostname());  |  13611  | 7.46k  |   uint32_t previous_port = components.port;  |  13612  |  |  |  13613  | 7.46k  |   size_t host_end_pos = input.find('#'); |  13614  | 7.46k  |   std::string _host(input.data(), host_end_pos != std::string_view::npos  |  13615  | 7.46k  |                                       ? host_end_pos  |  13616  | 7.46k  |                                       : input.size());  |  13617  | 7.46k  |   helpers::remove_ascii_tab_or_newline(_host);  |  13618  | 7.46k  |   std::string_view new_host(_host);  |  13619  |  |  |  13620  |  |   // If url's scheme is "file", then set state to file host state, instead of  |  13621  |  |   // host state.  |  13622  | 7.46k  |   if (type != ada::scheme::type::FILE) { |  13623  | 5.72k  |     std::string_view host_view(_host.data(), _host.length());  |  13624  | 5.72k  |     auto [location, found_colon] =  |  13625  | 5.72k  |         helpers::get_host_delimiter_location(is_special(), host_view);  |  13626  |  |  |  13627  |  |     // Otherwise, if c is U+003A (:) and insideBrackets is false, then:  |  13628  |  |     // Note: the 'found_colon' value is true if and only if a colon was  |  13629  |  |     // encountered while not inside brackets.  |  13630  | 5.72k  |     if (found_colon) { |  13631  | 200  |       if (override_hostname) { |  13632  | 0  |         return false;  |  13633  | 0  |       }  |  13634  | 200  |       std::string_view sub_buffer = new_host.substr(location + 1);  |  13635  | 200  |       if (!sub_buffer.empty()) { |  13636  | 177  |         set_port(sub_buffer);  |  13637  | 177  |       }  |  13638  | 200  |     }  |  13639  |  |     // If url is special and host_view is the empty string, validation error,  |  13640  |  |     // return failure. Otherwise, if state override is given, host_view is the  |  13641  |  |     // empty string, and either url includes credentials or url’s port is  |  13642  |  |     // non-null, return.  |  13643  | 5.52k  |     else if (host_view.empty() &&  |  13644  | 5.52k  |              (is_special() || has_credentials() ||  |  13645  | 4.65k  |               components.port != url_components::omitted)) { |  13646  | 3.32k  |       return false;  |  13647  | 3.32k  |     }  |  13648  |  |  |  13649  |  |     // Let host be the result of host parsing host_view with url is not special.  |  13650  | 2.40k  |     if (host_view.empty()) { |  13651  | 1.41k  |       if (has_hostname()) { |  13652  | 204  |         clear_hostname();  // easy!  |  13653  | 1.20k  |       } else if (has_dash_dot()) { |  13654  | 2  |         add_authority_slashes_if_needed();  |  13655  | 2  |         delete_dash_dot();  |  13656  | 2  |       }  |  13657  | 1.41k  |       return true;  |  13658  | 1.41k  |     }  |  13659  |  |  |  13660  | 990  |     bool succeeded = parse_host(host_view);  |  13661  | 990  |     if (!succeeded) { |  13662  | 363  |       update_base_hostname(previous_host);  |  13663  | 363  |       update_base_port(previous_port);  |  13664  | 627  |     } else if (has_dash_dot()) { |  13665  |  |       // Should remove dash_dot from pathname  |  13666  | 7  |       delete_dash_dot();  |  13667  | 7  |     }  |  13668  | 990  |     return succeeded;  |  13669  | 2.40k  |   }  |  13670  |  |  |  13671  | 1.74k  |   size_t location = new_host.find_first_of("/\\?"); |  13672  | 1.74k  |   if (location != std::string_view::npos) { |  13673  | 22  |     new_host.remove_suffix(new_host.length() - location);  |  13674  | 22  |   }  |  13675  |  |  |  13676  | 1.74k  |   if (new_host.empty()) { |  13677  |  |     // Set url’s host to the empty string.  |  13678  | 1.31k  |     clear_hostname();  |  13679  | 1.31k  |   } else { |  13680  |  |     // Let host be the result of host parsing buffer with url is not special.  |  13681  | 429  |     if (!parse_host(new_host)) { |  13682  | 69  |       update_base_hostname(previous_host);  |  13683  | 69  |       update_base_port(previous_port);  |  13684  | 69  |       return false;  |  13685  | 69  |     }  |  13686  |  |  |  13687  |  |     // If host is "localhost", then set host to the empty string.  |  13688  | 360  |     if (helpers::substring(buffer, components.host_start,  |  13689  | 360  |                            components.host_end) == "localhost") { |  13690  | 20  |       clear_hostname();  |  13691  | 20  |     }  |  13692  | 360  |   }  |  13693  | 1.67k  |   ADA_ASSERT_TRUE(validate());  |  13694  | 1.67k  |   return true;  |  13695  | 1.74k  | }  |  
 bool ada::url_aggregator::set_host_or_hostname<true>(std::__1::basic_string_view<char, std::__1::char_traits<char> >) Line  | Count  | Source  |  13602  | 9.41k  | bool url_aggregator::set_host_or_hostname(const std::string_view input) { |  13603  | 9.41k  |   ada_log("url_aggregator::set_host_or_hostname ", input); |  13604  | 9.41k  |   ADA_ASSERT_TRUE(validate());  |  13605  | 9.41k  |   ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));  |  13606  | 9.41k  |   if (has_opaque_path) { |  13607  | 1.06k  |     return false;  |  13608  | 1.06k  |   }  |  13609  |  |  |  13610  | 8.35k  |   std::string previous_host = std::string(get_hostname());  |  13611  | 8.35k  |   uint32_t previous_port = components.port;  |  13612  |  |  |  13613  | 8.35k  |   size_t host_end_pos = input.find('#'); |  13614  | 8.35k  |   std::string _host(input.data(), host_end_pos != std::string_view::npos  |  13615  | 8.35k  |                                       ? host_end_pos  |  13616  | 8.35k  |                                       : input.size());  |  13617  | 8.35k  |   helpers::remove_ascii_tab_or_newline(_host);  |  13618  | 8.35k  |   std::string_view new_host(_host);  |  13619  |  |  |  13620  |  |   // If url's scheme is "file", then set state to file host state, instead of  |  13621  |  |   // host state.  |  13622  | 8.35k  |   if (type != ada::scheme::type::FILE) { |  13623  | 6.48k  |     std::string_view host_view(_host.data(), _host.length());  |  13624  | 6.48k  |     auto [location, found_colon] =  |  13625  | 6.48k  |         helpers::get_host_delimiter_location(is_special(), host_view);  |  13626  |  |  |  13627  |  |     // Otherwise, if c is U+003A (:) and insideBrackets is false, then:  |  13628  |  |     // Note: the 'found_colon' value is true if and only if a colon was  |  13629  |  |     // encountered while not inside brackets.  |  13630  | 6.48k  |     if (found_colon) { |  13631  | 200  |       if (override_hostname) { |  13632  | 200  |         return false;  |  13633  | 200  |       }  |  13634  | 0  |       std::string_view sub_buffer = new_host.substr(location + 1);  |  13635  | 0  |       if (!sub_buffer.empty()) { |  13636  | 0  |         set_port(sub_buffer);  |  13637  | 0  |       }  |  13638  | 0  |     }  |  13639  |  |     // If url is special and host_view is the empty string, validation error,  |  13640  |  |     // return failure. Otherwise, if state override is given, host_view is the  |  13641  |  |     // empty string, and either url includes credentials or url’s port is  |  13642  |  |     // non-null, return.  |  13643  | 6.28k  |     else if (host_view.empty() &&  |  13644  | 6.28k  |              (is_special() || has_credentials() ||  |  13645  | 4.78k  |               components.port != url_components::omitted)) { |  13646  | 3.32k  |       return false;  |  13647  | 3.32k  |     }  |  13648  |  |  |  13649  |  |     // Let host be the result of host parsing host_view with url is not special.  |  13650  | 2.96k  |     if (host_view.empty()) { |  13651  | 1.45k  |       if (has_hostname()) { |  13652  | 103  |         clear_hostname();  // easy!  |  13653  | 1.35k  |       } else if (has_dash_dot()) { |  13654  | 32  |         add_authority_slashes_if_needed();  |  13655  | 32  |         delete_dash_dot();  |  13656  | 32  |       }  |  13657  | 1.45k  |       return true;  |  13658  | 1.45k  |     }  |  13659  |  |  |  13660  | 1.50k  |     bool succeeded = parse_host(host_view);  |  13661  | 1.50k  |     if (!succeeded) { |  13662  | 306  |       update_base_hostname(previous_host);  |  13663  | 306  |       update_base_port(previous_port);  |  13664  | 1.19k  |     } else if (has_dash_dot()) { |  13665  |  |       // Should remove dash_dot from pathname  |  13666  | 2  |       delete_dash_dot();  |  13667  | 2  |     }  |  13668  | 1.50k  |     return succeeded;  |  13669  | 2.96k  |   }  |  13670  |  |  |  13671  | 1.86k  |   size_t location = new_host.find_first_of("/\\?"); |  13672  | 1.86k  |   if (location != std::string_view::npos) { |  13673  | 22  |     new_host.remove_suffix(new_host.length() - location);  |  13674  | 22  |   }  |  13675  |  |  |  13676  | 1.86k  |   if (new_host.empty()) { |  13677  |  |     // Set url’s host to the empty string.  |  13678  | 1.38k  |     clear_hostname();  |  13679  | 1.38k  |   } else { |  13680  |  |     // Let host be the result of host parsing buffer with url is not special.  |  13681  | 477  |     if (!parse_host(new_host)) { |  13682  | 69  |       update_base_hostname(previous_host);  |  13683  | 69  |       update_base_port(previous_port);  |  13684  | 69  |       return false;  |  13685  | 69  |     }  |  13686  |  |  |  13687  |  |     // If host is "localhost", then set host to the empty string.  |  13688  | 408  |     if (helpers::substring(buffer, components.host_start,  |  13689  | 408  |                            components.host_end) == "localhost") { |  13690  | 20  |       clear_hostname();  |  13691  | 20  |     }  |  13692  | 408  |   }  |  13693  | 1.79k  |   ADA_ASSERT_TRUE(validate());  |  13694  | 1.79k  |   return true;  |  13695  | 1.86k  | }  |  
  | 
13696  |  |  | 
13697  | 8.53k  | bool url_aggregator::set_host(const std::string_view input) { | 
13698  | 8.53k  |   ada_log("url_aggregator::set_host '", input, "'"); | 
13699  | 8.53k  |   ADA_ASSERT_TRUE(validate());  | 
13700  | 8.53k  |   ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));  | 
13701  | 8.53k  |   return set_host_or_hostname<false>(input);  | 
13702  | 8.53k  | }  | 
13703  |  |  | 
13704  | 9.41k  | bool url_aggregator::set_hostname(const std::string_view input) { | 
13705  | 9.41k  |   ada_log("url_aggregator::set_hostname '", input, "'"); | 
13706  | 9.41k  |   ADA_ASSERT_TRUE(validate());  | 
13707  | 9.41k  |   ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));  | 
13708  | 9.41k  |   return set_host_or_hostname<true>(input);  | 
13709  | 9.41k  | }  | 
13710  |  |  | 
13711  | 8.27k  | [[nodiscard]] std::string url_aggregator::get_origin() const noexcept { | 
13712  | 8.27k  |   ada_log("url_aggregator::get_origin"); | 
13713  | 8.27k  |   if (is_special()) { | 
13714  |  |     // Return a new opaque origin.  | 
13715  | 5.52k  |     if (type == scheme::FILE) { | 
13716  | 1.48k  |       return "null";  | 
13717  | 1.48k  |     }  | 
13718  |  |  | 
13719  | 4.04k  |     return helpers::concat(get_protocol(), "//", get_host());  | 
13720  | 5.52k  |   }  | 
13721  |  |  | 
13722  | 2.74k  |   if (get_protocol() == "blob:") { | 
13723  | 395  |     std::string_view path = get_pathname();  | 
13724  | 395  |     if (!path.empty()) { | 
13725  | 393  |       auto out = ada::parse<ada::url_aggregator>(path);  | 
13726  | 393  |       if (out && (out->type == scheme::HTTP || out->type == scheme::HTTPS)) { | 
13727  |  |         // If pathURL’s scheme is not "http" and not "https", then return a  | 
13728  |  |         // new opaque origin.  | 
13729  | 10  |         return helpers::concat(out->get_protocol(), "//", out->get_host());  | 
13730  | 10  |       }  | 
13731  | 393  |     }  | 
13732  | 395  |   }  | 
13733  |  |  | 
13734  |  |   // Return a new opaque origin.  | 
13735  | 2.73k  |   return "null";  | 
13736  | 2.74k  | }  | 
13737  |  |  | 
13738  | 8.27k  | [[nodiscard]] std::string_view url_aggregator::get_username() const noexcept { | 
13739  | 8.27k  |   ada_log("url_aggregator::get_username"); | 
13740  | 8.27k  |   if (has_non_empty_username()) { | 
13741  | 902  |     return helpers::substring(buffer, components.protocol_end + 2,  | 
13742  | 902  |                               components.username_end);  | 
13743  | 902  |   }  | 
13744  | 7.37k  |   return "";  | 
13745  | 8.27k  | }  | 
13746  |  |  | 
13747  | 8.27k  | [[nodiscard]] std::string_view url_aggregator::get_password() const noexcept { | 
13748  | 8.27k  |   ada_log("url_aggregator::get_password"); | 
13749  | 8.27k  |   if (has_non_empty_password()) { | 
13750  | 902  |     return helpers::substring(buffer, components.username_end + 1,  | 
13751  | 902  |                               components.host_start);  | 
13752  | 902  |   }  | 
13753  | 7.37k  |   return "";  | 
13754  | 8.27k  | }  | 
13755  |  |  | 
13756  | 8.27k  | [[nodiscard]] std::string_view url_aggregator::get_port() const noexcept { | 
13757  | 8.27k  |   ada_log("url_aggregator::get_port"); | 
13758  | 8.27k  |   if (components.port == url_components::omitted) { | 
13759  | 8.03k  |     return "";  | 
13760  | 8.03k  |   }  | 
13761  | 241  |   return helpers::substring(buffer, components.host_end + 1,  | 
13762  | 241  |                             components.pathname_start);  | 
13763  | 8.27k  | }  | 
13764  |  |  | 
13765  | 8.27k  | [[nodiscard]] std::string_view url_aggregator::get_hash() const noexcept { | 
13766  | 8.27k  |   ada_log("url_aggregator::get_hash"); | 
13767  |  |   // If this’s URL’s fragment is either null or the empty string, then return  | 
13768  |  |   // the empty string. Return U+0023 (#), followed by this’s URL’s fragment.  | 
13769  | 8.27k  |   if (components.hash_start == url_components::omitted) { | 
13770  | 6.67k  |     return "";  | 
13771  | 6.67k  |   }  | 
13772  | 1.60k  |   if (buffer.size() - components.hash_start <= 1) { | 
13773  | 78  |     return "";  | 
13774  | 78  |   }  | 
13775  | 1.52k  |   return helpers::substring(buffer, components.hash_start);  | 
13776  | 1.60k  | }  | 
13777  |  |  | 
13778  | 12.5k  | [[nodiscard]] std::string_view url_aggregator::get_host() const noexcept { | 
13779  | 12.5k  |   ada_log("url_aggregator::get_host"); | 
13780  |  |   // Technically, we should check if there is a hostname, but  | 
13781  |  |   // the code below works even if there isn't.  | 
13782  |  |   // if(!has_hostname()) { return ""; } | 
13783  | 12.5k  |   size_t start = components.host_start;  | 
13784  | 12.5k  |   if (components.host_end > components.host_start &&  | 
13785  | 12.5k  |       buffer[components.host_start] == '@') { | 
13786  | 1.70k  |     start++;  | 
13787  | 1.70k  |   }  | 
13788  |  |   // if we have an empty host, then the space between components.host_end and  | 
13789  |  |   // components.pathname_start may be occupied by /.  | 
13790  | 12.5k  |   if (start == components.host_end) { | 
13791  | 4.04k  |     return std::string_view();  | 
13792  | 4.04k  |   }  | 
13793  | 8.53k  |   return helpers::substring(buffer, start, components.pathname_start);  | 
13794  | 12.5k  | }  | 
13795  |  |  | 
13796  | 45.1k  | [[nodiscard]] std::string_view url_aggregator::get_hostname() const noexcept { | 
13797  | 45.1k  |   ada_log("url_aggregator::get_hostname"); | 
13798  |  |   // Technically, we should check if there is a hostname, but  | 
13799  |  |   // the code below works even if there isn't.  | 
13800  |  |   // if(!has_hostname()) { return ""; } | 
13801  | 45.1k  |   size_t start = components.host_start;  | 
13802  |  |   // So host_start is not where the host begins.  | 
13803  | 45.1k  |   if (components.host_end > components.host_start &&  | 
13804  | 45.1k  |       buffer[components.host_start] == '@') { | 
13805  | 4.54k  |     start++;  | 
13806  | 4.54k  |   }  | 
13807  | 45.1k  |   return helpers::substring(buffer, start, components.host_end);  | 
13808  | 45.1k  | }  | 
13809  |  |  | 
13810  | 15.8k  | [[nodiscard]] std::string_view url_aggregator::get_pathname() const noexcept { | 
13811  | 15.8k  |   ada_log("url_aggregator::get_pathname pathname_start = ", | 
13812  | 15.8k  |           components.pathname_start, " buffer.size() = ", buffer.size(),  | 
13813  | 15.8k  |           " components.search_start = ", components.search_start,  | 
13814  | 15.8k  |           " components.hash_start = ", components.hash_start);  | 
13815  | 15.8k  |   uint32_t ending_index = uint32_t(buffer.size());  | 
13816  | 15.8k  |   if (components.search_start != url_components::omitted) { | 
13817  | 1.80k  |     ending_index = components.search_start;  | 
13818  | 14.0k  |   } else if (components.hash_start != url_components::omitted) { | 
13819  | 152  |     ending_index = components.hash_start;  | 
13820  | 152  |   }  | 
13821  | 15.8k  |   return helpers::substring(buffer, components.pathname_start, ending_index);  | 
13822  | 15.8k  | }  | 
13823  |  |  | 
13824  | 9.41k  | [[nodiscard]] std::string_view url_aggregator::get_search() const noexcept { | 
13825  | 9.41k  |   ada_log("url_aggregator::get_search"); | 
13826  |  |   // If this’s URL’s query is either null or the empty string, then return the  | 
13827  |  |   // empty string. Return U+003F (?), followed by this’s URL’s query.  | 
13828  | 9.41k  |   if (components.search_start == url_components::omitted) { | 
13829  | 7.73k  |     return "";  | 
13830  | 7.73k  |   }  | 
13831  | 1.67k  |   uint32_t ending_index = uint32_t(buffer.size());  | 
13832  | 1.67k  |   if (components.hash_start != url_components::omitted) { | 
13833  | 1.62k  |     ending_index = components.hash_start;  | 
13834  | 1.62k  |   }  | 
13835  | 1.67k  |   if (ending_index - components.search_start <= 1) { | 
13836  | 111  |     return "";  | 
13837  | 111  |   }  | 
13838  | 1.56k  |   return helpers::substring(buffer, components.search_start, ending_index);  | 
13839  | 1.67k  | }  | 
13840  |  |  | 
13841  | 15.8k  | [[nodiscard]] std::string_view url_aggregator::get_protocol() const noexcept { | 
13842  | 15.8k  |   ada_log("url_aggregator::get_protocol"); | 
13843  | 15.8k  |   return helpers::substring(buffer, 0, components.protocol_end);  | 
13844  | 15.8k  | }  | 
13845  |  |  | 
13846  | 0  | std::string ada::url_aggregator::to_string() const { | 
13847  | 0  |   ada_log("url_aggregator::to_string buffer:", buffer, "[", buffer.size(), | 
13848  | 0  |           " bytes]");  | 
13849  | 0  |   if (!is_valid) { | 
13850  | 0  |     return "null";  | 
13851  | 0  |   }  | 
13852  |  |  | 
13853  | 0  |   std::string answer;  | 
13854  | 0  |   auto back = std::back_insert_iterator(answer);  | 
13855  | 0  |   answer.append("{\n"); | 
13856  |  | 
  | 
13857  | 0  |   answer.append("\t\"buffer\":\""); | 
13858  | 0  |   helpers::encode_json(buffer, back);  | 
13859  | 0  |   answer.append("\",\n"); | 
13860  |  | 
  | 
13861  | 0  |   answer.append("\t\"protocol\":\""); | 
13862  | 0  |   helpers::encode_json(get_protocol(), back);  | 
13863  | 0  |   answer.append("\",\n"); | 
13864  |  | 
  | 
13865  | 0  |   if (has_credentials()) { | 
13866  | 0  |     answer.append("\t\"username\":\""); | 
13867  | 0  |     helpers::encode_json(get_username(), back);  | 
13868  | 0  |     answer.append("\",\n"); | 
13869  | 0  |     answer.append("\t\"password\":\""); | 
13870  | 0  |     helpers::encode_json(get_password(), back);  | 
13871  | 0  |     answer.append("\",\n"); | 
13872  | 0  |   }  | 
13873  |  | 
  | 
13874  | 0  |   answer.append("\t\"host\":\""); | 
13875  | 0  |   helpers::encode_json(get_host(), back);  | 
13876  | 0  |   answer.append("\",\n"); | 
13877  |  | 
  | 
13878  | 0  |   answer.append("\t\"path\":\""); | 
13879  | 0  |   helpers::encode_json(get_pathname(), back);  | 
13880  | 0  |   answer.append("\",\n"); | 
13881  | 0  |   answer.append("\t\"opaque path\":"); | 
13882  | 0  |   answer.append((has_opaque_path ? "true" : "false"));  | 
13883  | 0  |   answer.append(",\n"); | 
13884  |  | 
  | 
13885  | 0  |   if (components.search_start != url_components::omitted) { | 
13886  | 0  |     answer.append("\t\"query\":\""); | 
13887  | 0  |     helpers::encode_json(get_search(), back);  | 
13888  | 0  |     answer.append("\",\n"); | 
13889  | 0  |   }  | 
13890  | 0  |   if (components.hash_start != url_components::omitted) { | 
13891  | 0  |     answer.append("\t\"fragment\":\""); | 
13892  | 0  |     helpers::encode_json(get_hash(), back);  | 
13893  | 0  |     answer.append("\",\n"); | 
13894  | 0  |   }  | 
13895  |  | 
  | 
13896  | 0  |   auto convert_offset_to_string = [](uint32_t offset) -> std::string { | 
13897  | 0  |     if (offset == url_components::omitted) { | 
13898  | 0  |       return "null";  | 
13899  | 0  |     } else { | 
13900  | 0  |       return std::to_string(offset);  | 
13901  | 0  |     }  | 
13902  | 0  |   };  | 
13903  |  | 
  | 
13904  | 0  |   answer.append("\t\"protocol_end\":"); | 
13905  | 0  |   answer.append(convert_offset_to_string(components.protocol_end));  | 
13906  | 0  |   answer.append(",\n"); | 
13907  |  | 
  | 
13908  | 0  |   answer.append("\t\"username_end\":"); | 
13909  | 0  |   answer.append(convert_offset_to_string(components.username_end));  | 
13910  | 0  |   answer.append(",\n"); | 
13911  |  | 
  | 
13912  | 0  |   answer.append("\t\"host_start\":"); | 
13913  | 0  |   answer.append(convert_offset_to_string(components.host_start));  | 
13914  | 0  |   answer.append(",\n"); | 
13915  |  | 
  | 
13916  | 0  |   answer.append("\t\"host_end\":"); | 
13917  | 0  |   answer.append(convert_offset_to_string(components.host_end));  | 
13918  | 0  |   answer.append(",\n"); | 
13919  |  | 
  | 
13920  | 0  |   answer.append("\t\"port\":"); | 
13921  | 0  |   answer.append(convert_offset_to_string(components.port));  | 
13922  | 0  |   answer.append(",\n"); | 
13923  |  | 
  | 
13924  | 0  |   answer.append("\t\"pathname_start\":"); | 
13925  | 0  |   answer.append(convert_offset_to_string(components.pathname_start));  | 
13926  | 0  |   answer.append(",\n"); | 
13927  |  | 
  | 
13928  | 0  |   answer.append("\t\"search_start\":"); | 
13929  | 0  |   answer.append(convert_offset_to_string(components.search_start));  | 
13930  | 0  |   answer.append(",\n"); | 
13931  |  | 
  | 
13932  | 0  |   answer.append("\t\"hash_start\":"); | 
13933  | 0  |   answer.append(convert_offset_to_string(components.hash_start));  | 
13934  | 0  |   answer.append("\n}"); | 
13935  |  | 
  | 
13936  | 0  |   return answer;  | 
13937  | 0  | }  | 
13938  |  |  | 
13939  | 0  | [[nodiscard]] bool url_aggregator::has_valid_domain() const noexcept { | 
13940  | 0  |   if (components.host_start == components.host_end) { | 
13941  | 0  |     return false;  | 
13942  | 0  |   }  | 
13943  | 0  |   return checkers::verify_dns_length(get_hostname());  | 
13944  | 0  | }  | 
13945  |  |  | 
13946  | 4.02k  | bool url_aggregator::parse_ipv4(std::string_view input) { | 
13947  | 4.02k  |   ada_log("parse_ipv4 ", input, "[", input.size(), | 
13948  | 4.02k  |           " bytes], overlaps with buffer: ",  | 
13949  | 4.02k  |           helpers::overlaps(input, buffer) ? "yes" : "no");  | 
13950  | 4.02k  |   ADA_ASSERT_TRUE(validate());  | 
13951  | 4.02k  |   const bool trailing_dot = (input.back() == '.');  | 
13952  | 4.02k  |   if (trailing_dot) { | 
13953  | 65  |     input.remove_suffix(1);  | 
13954  | 65  |   }  | 
13955  | 4.02k  |   size_t digit_count{0}; | 
13956  | 4.02k  |   int pure_decimal_count = 0;  // entries that are decimal  | 
13957  | 4.02k  |   uint64_t ipv4{0}; | 
13958  |  |   // we could unroll for better performance?  | 
13959  | 5.29k  |   for (; (digit_count < 4) && !(input.empty()); digit_count++) { | 
13960  | 5.26k  |     uint32_t  | 
13961  | 5.26k  |         segment_result{};  // If any number exceeds 32 bits, we have an error. | 
13962  | 5.26k  |     bool is_hex = checkers::has_hex_prefix(input);  | 
13963  | 5.26k  |     if (is_hex && ((input.length() == 2) ||  | 
13964  | 1.20k  |                    ((input.length() > 2) && (input[2] == '.')))) { | 
13965  |  |       // special case  | 
13966  | 124  |       segment_result = 0;  | 
13967  | 124  |       input.remove_prefix(2);  | 
13968  | 5.13k  |     } else { | 
13969  | 5.13k  |       std::from_chars_result r;  | 
13970  | 5.13k  |       if (is_hex) { | 
13971  | 1.07k  |         r = std::from_chars(input.data() + 2, input.data() + input.size(),  | 
13972  | 1.07k  |                             segment_result, 16);  | 
13973  | 4.05k  |       } else if ((input.length() >= 2) && input[0] == '0' &&  | 
13974  | 4.05k  |                  checkers::is_digit(input[1])) { | 
13975  | 504  |         r = std::from_chars(input.data() + 1, input.data() + input.size(),  | 
13976  | 504  |                             segment_result, 8);  | 
13977  | 3.55k  |       } else { | 
13978  | 3.55k  |         pure_decimal_count++;  | 
13979  | 3.55k  |         r = std::from_chars(input.data(), input.data() + input.size(),  | 
13980  | 3.55k  |                             segment_result, 10);  | 
13981  | 3.55k  |       }  | 
13982  | 5.13k  |       if (r.ec != std::errc()) { | 
13983  | 677  |         return is_valid = false;  | 
13984  | 677  |       }  | 
13985  | 4.45k  |       input.remove_prefix(r.ptr - input.data());  | 
13986  | 4.45k  |     }  | 
13987  | 4.58k  |     if (input.empty()) { | 
13988  |  |       // We have the last value.  | 
13989  |  |       // At this stage, ipv4 contains digit_count*8 bits.  | 
13990  |  |       // So we have 32-digit_count*8 bits left.  | 
13991  | 3.10k  |       if (segment_result > (uint64_t(1) << (32 - digit_count * 8))) { | 
13992  | 18  |         return is_valid = false;  | 
13993  | 18  |       }  | 
13994  | 3.08k  |       ipv4 <<= (32 - digit_count * 8);  | 
13995  | 3.08k  |       ipv4 |= segment_result;  | 
13996  | 3.08k  |       goto final;  | 
13997  | 3.10k  |     } else { | 
13998  |  |       // There is more, so that the value must no be larger than 255  | 
13999  |  |       // and we must have a '.'.  | 
14000  | 1.48k  |       if ((segment_result > 255) || (input[0] != '.')) { | 
14001  | 216  |         return is_valid = false;  | 
14002  | 216  |       }  | 
14003  | 1.26k  |       ipv4 <<= 8;  | 
14004  | 1.26k  |       ipv4 |= segment_result;  | 
14005  | 1.26k  |       input.remove_prefix(1);  // remove '.'  | 
14006  | 1.26k  |     }  | 
14007  | 4.58k  |   }  | 
14008  | 32  |   if ((digit_count != 4) || (!input.empty())) { | 
14009  | 32  |     return is_valid = false;  | 
14010  | 32  |   }  | 
14011  | 3.08k  | final:  | 
14012  | 3.08k  |   ada_log("url_aggregator::parse_ipv4 completed ", get_href(), | 
14013  | 3.08k  |           " host: ", get_host());  | 
14014  |  |  | 
14015  |  |   // We could also check r.ptr to see where the parsing ended.  | 
14016  | 3.08k  |   if (pure_decimal_count == 4 && !trailing_dot) { | 
14017  |  |     // The original input was already all decimal and we validated it. So we  | 
14018  |  |     // don't need to do anything.  | 
14019  | 2.85k  |   } else { | 
14020  |  |     // Optimization opportunity: Get rid of unnecessary string return in ipv4  | 
14021  |  |     // serializer.  | 
14022  |  |     // TODO: This is likely a bug because it goes back update_base_hostname, not  | 
14023  |  |     // what we want to do.  | 
14024  | 2.85k  |     update_base_hostname(  | 
14025  | 2.85k  |         ada::serializers::ipv4(ipv4));  // We have to reserialize the address.  | 
14026  | 2.85k  |   }  | 
14027  | 3.08k  |   ADA_ASSERT_TRUE(validate());  | 
14028  | 3.08k  |   return true;  | 
14029  | 32  | }  | 
14030  |  |  | 
14031  | 922  | bool url_aggregator::parse_ipv6(std::string_view input) { | 
14032  |  |   // TODO: Find a way to merge parse_ipv6 with url.cpp implementation.  | 
14033  | 922  |   ada_log("parse_ipv6 ", input, "[", input.size(), " bytes]"); | 
14034  | 922  |   ADA_ASSERT_TRUE(validate());  | 
14035  | 922  |   ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));  | 
14036  | 922  |   if (input.empty()) { | 
14037  | 61  |     return is_valid = false;  | 
14038  | 61  |   }  | 
14039  |  |   // Let address be a new IPv6 address whose IPv6 pieces are all 0.  | 
14040  | 861  |   std::array<uint16_t, 8> address{}; | 
14041  |  |  | 
14042  |  |   // Let pieceIndex be 0.  | 
14043  | 861  |   int piece_index = 0;  | 
14044  |  |  | 
14045  |  |   // Let compress be null.  | 
14046  | 861  |   std::optional<int> compress{}; | 
14047  |  |  | 
14048  |  |   // Let pointer be a pointer for input.  | 
14049  | 861  |   std::string_view::iterator pointer = input.begin();  | 
14050  |  |  | 
14051  |  |   // If c is U+003A (:), then:  | 
14052  | 861  |   if (input[0] == ':') { | 
14053  |  |     // If remaining does not start with U+003A (:), validation error, return  | 
14054  |  |     // failure.  | 
14055  | 241  |     if (input.size() == 1 || input[1] != ':') { | 
14056  | 16  |       ada_log("parse_ipv6 starts with : but the rest does not start with :"); | 
14057  | 16  |       return is_valid = false;  | 
14058  | 16  |     }  | 
14059  |  |  | 
14060  |  |     // Increase pointer by 2.  | 
14061  | 225  |     pointer += 2;  | 
14062  |  |  | 
14063  |  |     // Increase pieceIndex by 1 and then set compress to pieceIndex.  | 
14064  | 225  |     compress = ++piece_index;  | 
14065  | 225  |   }  | 
14066  |  |  | 
14067  |  |   // While c is not the EOF code point:  | 
14068  | 2.53k  |   while (pointer != input.end()) { | 
14069  |  |     // If pieceIndex is 8, validation error, return failure.  | 
14070  | 2.06k  |     if (piece_index == 8) { | 
14071  | 10  |       ada_log("parse_ipv6 piece_index == 8"); | 
14072  | 10  |       return is_valid = false;  | 
14073  | 10  |     }  | 
14074  |  |  | 
14075  |  |     // If c is U+003A (:), then:  | 
14076  | 2.05k  |     if (*pointer == ':') { | 
14077  |  |       // If compress is non-null, validation error, return failure.  | 
14078  | 167  |       if (compress.has_value()) { | 
14079  | 7  |         ada_log("parse_ipv6 compress is non-null"); | 
14080  | 7  |         return is_valid = false;  | 
14081  | 7  |       }  | 
14082  |  |  | 
14083  |  |       // Increase pointer and pieceIndex by 1, set compress to pieceIndex, and  | 
14084  |  |       // then continue.  | 
14085  | 160  |       pointer++;  | 
14086  | 160  |       compress = ++piece_index;  | 
14087  | 160  |       continue;  | 
14088  | 167  |     }  | 
14089  |  |  | 
14090  |  |     // Let value and length be 0.  | 
14091  | 1.88k  |     uint16_t value = 0, length = 0;  | 
14092  |  |  | 
14093  |  |     // While length is less than 4 and c is an ASCII hex digit,  | 
14094  |  |     // set value to value × 0x10 + c interpreted as hexadecimal number, and  | 
14095  |  |     // increase pointer and length by 1.  | 
14096  | 5.00k  |     while (length < 4 && pointer != input.end() &&  | 
14097  | 5.00k  |            unicode::is_ascii_hex_digit(*pointer)) { | 
14098  |  |       // https://stackoverflow.com/questions/39060852/why-does-the-addition-of-two-shorts-return-an-int  | 
14099  | 3.12k  |       value = uint16_t(value * 0x10 + unicode::convert_hex_to_binary(*pointer));  | 
14100  | 3.12k  |       pointer++;  | 
14101  | 3.12k  |       length++;  | 
14102  | 3.12k  |     }  | 
14103  |  |  | 
14104  |  |     // If c is U+002E (.), then:  | 
14105  | 1.88k  |     if (pointer != input.end() && *pointer == '.') { | 
14106  |  |       // If length is 0, validation error, return failure.  | 
14107  | 184  |       if (length == 0) { | 
14108  | 6  |         ada_log("parse_ipv6 length is 0"); | 
14109  | 6  |         return is_valid = false;  | 
14110  | 6  |       }  | 
14111  |  |  | 
14112  |  |       // Decrease pointer by length.  | 
14113  | 178  |       pointer -= length;  | 
14114  |  |  | 
14115  |  |       // If pieceIndex is greater than 6, validation error, return failure.  | 
14116  | 178  |       if (piece_index > 6) { | 
14117  | 6  |         ada_log("parse_ipv6 piece_index > 6"); | 
14118  | 6  |         return is_valid = false;  | 
14119  | 6  |       }  | 
14120  |  |  | 
14121  |  |       // Let numbersSeen be 0.  | 
14122  | 172  |       int numbers_seen = 0;  | 
14123  |  |  | 
14124  |  |       // While c is not the EOF code point:  | 
14125  | 525  |       while (pointer != input.end()) { | 
14126  |  |         // Let ipv4Piece be null.  | 
14127  | 463  |         std::optional<uint16_t> ipv4_piece{}; | 
14128  |  |  | 
14129  |  |         // If numbersSeen is greater than 0, then:  | 
14130  | 463  |         if (numbers_seen > 0) { | 
14131  |  |           // If c is a U+002E (.) and numbersSeen is less than 4, then increase  | 
14132  |  |           // pointer by 1.  | 
14133  | 291  |           if (*pointer == '.' && numbers_seen < 4) { | 
14134  | 255  |             pointer++;  | 
14135  | 255  |           } else { | 
14136  |  |             // Otherwise, validation error, return failure.  | 
14137  | 36  |             ada_log("parse_ipv6 Otherwise, validation error, return failure"); | 
14138  | 36  |             return is_valid = false;  | 
14139  | 36  |           }  | 
14140  | 291  |         }  | 
14141  |  |  | 
14142  |  |         // If c is not an ASCII digit, validation error, return failure.  | 
14143  | 427  |         if (pointer == input.end() || !checkers::is_digit(*pointer)) { | 
14144  | 47  |           ada_log(  | 
14145  | 47  |               "parse_ipv6 If c is not an ASCII digit, validation error, return "  | 
14146  | 47  |               "failure");  | 
14147  | 47  |           return is_valid = false;  | 
14148  | 47  |         }  | 
14149  |  |  | 
14150  |  |         // While c is an ASCII digit:  | 
14151  | 884  |         while (pointer != input.end() && checkers::is_digit(*pointer)) { | 
14152  |  |           // Let number be c interpreted as decimal number.  | 
14153  | 531  |           int number = *pointer - '0';  | 
14154  |  |  | 
14155  |  |           // If ipv4Piece is null, then set ipv4Piece to number.  | 
14156  | 531  |           if (!ipv4_piece.has_value()) { | 
14157  | 380  |             ipv4_piece = number;  | 
14158  | 380  |           }  | 
14159  |  |           // Otherwise, if ipv4Piece is 0, validation error, return failure.  | 
14160  | 151  |           else if (ipv4_piece == 0) { | 
14161  | 6  |             ada_log("parse_ipv6 if ipv4Piece is 0, validation error"); | 
14162  | 6  |             return is_valid = false;  | 
14163  | 6  |           }  | 
14164  |  |           // Otherwise, set ipv4Piece to ipv4Piece × 10 + number.  | 
14165  | 145  |           else { | 
14166  | 145  |             ipv4_piece = *ipv4_piece * 10 + number;  | 
14167  | 145  |           }  | 
14168  |  |  | 
14169  |  |           // If ipv4Piece is greater than 255, validation error, return failure.  | 
14170  | 525  |           if (ipv4_piece > 255) { | 
14171  | 21  |             ada_log("parse_ipv6 ipv4_piece > 255"); | 
14172  | 21  |             return is_valid = false;  | 
14173  | 21  |           }  | 
14174  |  |  | 
14175  |  |           // Increase pointer by 1.  | 
14176  | 504  |           pointer++;  | 
14177  | 504  |         }  | 
14178  |  |  | 
14179  |  |         // Set address[pieceIndex] to address[pieceIndex] × 0x100 + ipv4Piece.  | 
14180  |  |         // https://stackoverflow.com/questions/39060852/why-does-the-addition-of-two-shorts-return-an-int  | 
14181  | 353  |         address[piece_index] =  | 
14182  | 353  |             uint16_t(address[piece_index] * 0x100 + *ipv4_piece);  | 
14183  |  |  | 
14184  |  |         // Increase numbersSeen by 1.  | 
14185  | 353  |         numbers_seen++;  | 
14186  |  |  | 
14187  |  |         // If numbersSeen is 2 or 4, then increase pieceIndex by 1.  | 
14188  | 353  |         if (numbers_seen == 2 || numbers_seen == 4) { | 
14189  | 150  |           piece_index++;  | 
14190  | 150  |         }  | 
14191  | 353  |       }  | 
14192  |  |  | 
14193  |  |       // If numbersSeen is not 4, validation error, return failure.  | 
14194  | 62  |       if (numbers_seen != 4) { | 
14195  | 16  |         return is_valid = false;  | 
14196  | 16  |       }  | 
14197  |  |  | 
14198  |  |       // Break.  | 
14199  | 46  |       break;  | 
14200  | 62  |     }  | 
14201  |  |     // Otherwise, if c is U+003A (:):  | 
14202  | 1.70k  |     else if ((pointer != input.end()) && (*pointer == ':')) { | 
14203  |  |       // Increase pointer by 1.  | 
14204  | 1.20k  |       pointer++;  | 
14205  |  |  | 
14206  |  |       // If c is the EOF code point, validation error, return failure.  | 
14207  | 1.20k  |       if (pointer == input.end()) { | 
14208  | 6  |         ada_log(  | 
14209  | 6  |             "parse_ipv6 If c is the EOF code point, validation error, return "  | 
14210  | 6  |             "failure");  | 
14211  | 6  |         return is_valid = false;  | 
14212  | 6  |       }  | 
14213  | 1.20k  |     }  | 
14214  |  |     // Otherwise, if c is not the EOF code point, validation error, return  | 
14215  |  |     // failure.  | 
14216  | 501  |     else if (pointer != input.end()) { | 
14217  | 162  |       ada_log(  | 
14218  | 162  |           "parse_ipv6 Otherwise, if c is not the EOF code point, validation "  | 
14219  | 162  |           "error, return failure");  | 
14220  | 162  |       return is_valid = false;  | 
14221  | 162  |     }  | 
14222  |  |  | 
14223  |  |     // Set address[pieceIndex] to value.  | 
14224  | 1.53k  |     address[piece_index] = value;  | 
14225  |  |  | 
14226  |  |     // Increase pieceIndex by 1.  | 
14227  | 1.53k  |     piece_index++;  | 
14228  | 1.53k  |   }  | 
14229  |  |  | 
14230  |  |   // If compress is non-null, then:  | 
14231  | 522  |   if (compress.has_value()) { | 
14232  |  |     // Let swaps be pieceIndex − compress.  | 
14233  | 366  |     int swaps = piece_index - *compress;  | 
14234  |  |  | 
14235  |  |     // Set pieceIndex to 7.  | 
14236  | 366  |     piece_index = 7;  | 
14237  |  |  | 
14238  |  |     // While pieceIndex is not 0 and swaps is greater than 0,  | 
14239  |  |     // swap address[pieceIndex] with address[compress + swaps − 1], and then  | 
14240  |  |     // decrease both pieceIndex and swaps by 1.  | 
14241  | 921  |     while (piece_index != 0 && swaps > 0) { | 
14242  | 555  |       std::swap(address[piece_index], address[*compress + swaps - 1]);  | 
14243  | 555  |       piece_index--;  | 
14244  | 555  |       swaps--;  | 
14245  | 555  |     }  | 
14246  | 366  |   }  | 
14247  |  |   // Otherwise, if compress is null and pieceIndex is not 8, validation error,  | 
14248  |  |   // return failure.  | 
14249  | 156  |   else if (piece_index != 8) { | 
14250  | 110  |     ada_log(  | 
14251  | 110  |         "parse_ipv6 if compress is null and pieceIndex is not 8, validation "  | 
14252  | 110  |         "error, return failure");  | 
14253  | 110  |     return is_valid = false;  | 
14254  | 110  |   }  | 
14255  |  |   // TODO: Optimization opportunity: Get rid of unnecessary string creation.  | 
14256  |  |   // TODO: This is likely a bug because it goes back update_base_hostname, not  | 
14257  |  |   // what we want to do.  | 
14258  | 412  |   update_base_hostname(ada::serializers::ipv6(address));  | 
14259  | 412  |   ada_log("parse_ipv6 ", get_hostname()); | 
14260  | 412  |   ADA_ASSERT_TRUE(validate());  | 
14261  | 412  |   return true;  | 
14262  | 522  | }  | 
14263  |  |  | 
14264  | 1.00k  | bool url_aggregator::parse_opaque_host(std::string_view input) { | 
14265  | 1.00k  |   ada_log("parse_opaque_host ", input, "[", input.size(), " bytes]"); | 
14266  | 1.00k  |   ADA_ASSERT_TRUE(validate());  | 
14267  | 1.00k  |   ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));  | 
14268  | 1.00k  |   if (std::any_of(input.begin(), input.end(),  | 
14269  | 1.00k  |                   ada::unicode::is_forbidden_host_code_point)) { | 
14270  | 103  |     return is_valid = false;  | 
14271  | 103  |   }  | 
14272  |  |  | 
14273  |  |   // Return the result of running UTF-8 percent-encode on input using the C0  | 
14274  |  |   // control percent-encode set.  | 
14275  | 902  |   size_t idx = ada::unicode::percent_encode_index(  | 
14276  | 902  |       input, character_sets::C0_CONTROL_PERCENT_ENCODE);  | 
14277  | 902  |   if (idx == input.size()) { | 
14278  | 458  |     update_base_hostname(input);  | 
14279  | 458  |   } else { | 
14280  |  |     // We only create a temporary string if we need to.  | 
14281  | 444  |     update_base_hostname(ada::unicode::percent_encode(  | 
14282  | 444  |         input, character_sets::C0_CONTROL_PERCENT_ENCODE, idx));  | 
14283  | 444  |   }  | 
14284  | 902  |   ADA_ASSERT_TRUE(validate());  | 
14285  | 902  |   return true;  | 
14286  | 1.00k  | }  | 
14287  |  |  | 
14288  | 0  | std::string url_aggregator::to_diagram() const { | 
14289  | 0  |   if (!is_valid) { | 
14290  | 0  |     return "invalid";  | 
14291  | 0  |   }  | 
14292  | 0  |   std::string answer;  | 
14293  | 0  |   answer.append(buffer);  | 
14294  | 0  |   answer.append(" ["); | 
14295  | 0  |   answer.append(std::to_string(buffer.size()));  | 
14296  | 0  |   answer.append(" bytes]"); | 
14297  | 0  |   answer.append("\n"); | 
14298  |  |   // first line  | 
14299  | 0  |   std::string line1;  | 
14300  | 0  |   line1.resize(buffer.size(), ' ');  | 
14301  | 0  |   if (components.hash_start != url_components::omitted) { | 
14302  | 0  |     line1[components.hash_start] = '|';  | 
14303  | 0  |   }  | 
14304  | 0  |   if (components.search_start != url_components::omitted) { | 
14305  | 0  |     line1[components.search_start] = '|';  | 
14306  | 0  |   }  | 
14307  | 0  |   if (components.pathname_start != buffer.size()) { | 
14308  | 0  |     line1[components.pathname_start] = '|';  | 
14309  | 0  |   }  | 
14310  | 0  |   if (components.host_end != buffer.size()) { | 
14311  | 0  |     line1[components.host_end] = '|';  | 
14312  | 0  |   }  | 
14313  | 0  |   if (components.host_start != buffer.size()) { | 
14314  | 0  |     line1[components.host_start] = '|';  | 
14315  | 0  |   }  | 
14316  | 0  |   if (components.username_end != buffer.size()) { | 
14317  | 0  |     line1[components.username_end] = '|';  | 
14318  | 0  |   }  | 
14319  | 0  |   if (components.protocol_end != buffer.size()) { | 
14320  | 0  |     line1[components.protocol_end] = '|';  | 
14321  | 0  |   }  | 
14322  | 0  |   answer.append(line1);  | 
14323  | 0  |   answer.append("\n"); | 
14324  |  | 
  | 
14325  | 0  |   std::string line2 = line1;  | 
14326  | 0  |   if (components.hash_start != url_components::omitted) { | 
14327  | 0  |     line2[components.hash_start] = '`';  | 
14328  | 0  |     line1[components.hash_start] = ' ';  | 
14329  |  | 
  | 
14330  | 0  |     for (size_t i = components.hash_start + 1; i < line2.size(); i++) { | 
14331  | 0  |       line2[i] = '-';  | 
14332  | 0  |     }  | 
14333  | 0  |     line2.append(" hash_start"); | 
14334  | 0  |     answer.append(line2);  | 
14335  | 0  |     answer.append("\n"); | 
14336  | 0  |   }  | 
14337  |  | 
  | 
14338  | 0  |   std::string line3 = line1;  | 
14339  | 0  |   if (components.search_start != url_components::omitted) { | 
14340  | 0  |     line3[components.search_start] = '`';  | 
14341  | 0  |     line1[components.search_start] = ' ';  | 
14342  |  | 
  | 
14343  | 0  |     for (size_t i = components.search_start + 1; i < line3.size(); i++) { | 
14344  | 0  |       line3[i] = '-';  | 
14345  | 0  |     }  | 
14346  | 0  |     line3.append(" search_start "); | 
14347  | 0  |     line3.append(std::to_string(components.search_start));  | 
14348  | 0  |     answer.append(line3);  | 
14349  | 0  |     answer.append("\n"); | 
14350  | 0  |   }  | 
14351  |  | 
  | 
14352  | 0  |   std::string line4 = line1;  | 
14353  | 0  |   if (components.pathname_start != buffer.size()) { | 
14354  | 0  |     line4[components.pathname_start] = '`';  | 
14355  | 0  |     line1[components.pathname_start] = ' ';  | 
14356  | 0  |     for (size_t i = components.pathname_start + 1; i < line4.size(); i++) { | 
14357  | 0  |       line4[i] = '-';  | 
14358  | 0  |     }  | 
14359  | 0  |     line4.append(" pathname_start "); | 
14360  | 0  |     line4.append(std::to_string(components.pathname_start));  | 
14361  | 0  |     answer.append(line4);  | 
14362  | 0  |     answer.append("\n"); | 
14363  | 0  |   }  | 
14364  |  | 
  | 
14365  | 0  |   std::string line5 = line1;  | 
14366  | 0  |   if (components.host_end != buffer.size()) { | 
14367  | 0  |     line5[components.host_end] = '`';  | 
14368  | 0  |     line1[components.host_end] = ' ';  | 
14369  |  | 
  | 
14370  | 0  |     for (size_t i = components.host_end + 1; i < line5.size(); i++) { | 
14371  | 0  |       line5[i] = '-';  | 
14372  | 0  |     }  | 
14373  | 0  |     line5.append(" host_end "); | 
14374  | 0  |     line5.append(std::to_string(components.host_end));  | 
14375  | 0  |     answer.append(line5);  | 
14376  | 0  |     answer.append("\n"); | 
14377  | 0  |   }  | 
14378  |  | 
  | 
14379  | 0  |   std::string line6 = line1;  | 
14380  | 0  |   if (components.host_start != buffer.size()) { | 
14381  | 0  |     line6[components.host_start] = '`';  | 
14382  | 0  |     line1[components.host_start] = ' ';  | 
14383  |  | 
  | 
14384  | 0  |     for (size_t i = components.host_start + 1; i < line6.size(); i++) { | 
14385  | 0  |       line6[i] = '-';  | 
14386  | 0  |     }  | 
14387  | 0  |     line6.append(" host_start "); | 
14388  | 0  |     line6.append(std::to_string(components.host_start));  | 
14389  | 0  |     answer.append(line6);  | 
14390  | 0  |     answer.append("\n"); | 
14391  | 0  |   }  | 
14392  |  | 
  | 
14393  | 0  |   std::string line7 = line1;  | 
14394  | 0  |   if (components.username_end != buffer.size()) { | 
14395  | 0  |     line7[components.username_end] = '`';  | 
14396  | 0  |     line1[components.username_end] = ' ';  | 
14397  |  | 
  | 
14398  | 0  |     for (size_t i = components.username_end + 1; i < line7.size(); i++) { | 
14399  | 0  |       line7[i] = '-';  | 
14400  | 0  |     }  | 
14401  | 0  |     line7.append(" username_end "); | 
14402  | 0  |     line7.append(std::to_string(components.username_end));  | 
14403  | 0  |     answer.append(line7);  | 
14404  | 0  |     answer.append("\n"); | 
14405  | 0  |   }  | 
14406  |  | 
  | 
14407  | 0  |   std::string line8 = line1;  | 
14408  | 0  |   if (components.protocol_end != buffer.size()) { | 
14409  | 0  |     line8[components.protocol_end] = '`';  | 
14410  | 0  |     line1[components.protocol_end] = ' ';  | 
14411  |  | 
  | 
14412  | 0  |     for (size_t i = components.protocol_end + 1; i < line8.size(); i++) { | 
14413  | 0  |       line8[i] = '-';  | 
14414  | 0  |     }  | 
14415  | 0  |     line8.append(" protocol_end "); | 
14416  | 0  |     line8.append(std::to_string(components.protocol_end));  | 
14417  | 0  |     answer.append(line8);  | 
14418  | 0  |     answer.append("\n"); | 
14419  | 0  |   }  | 
14420  |  | 
  | 
14421  | 0  |   if (components.hash_start == url_components::omitted) { | 
14422  | 0  |     answer.append("note: hash omitted\n"); | 
14423  | 0  |   }  | 
14424  | 0  |   if (components.search_start == url_components::omitted) { | 
14425  | 0  |     answer.append("note: search omitted\n"); | 
14426  | 0  |   }  | 
14427  | 0  |   if (components.protocol_end > buffer.size()) { | 
14428  | 0  |     answer.append("warning: protocol_end overflows\n"); | 
14429  | 0  |   }  | 
14430  | 0  |   if (components.username_end > buffer.size()) { | 
14431  | 0  |     answer.append("warning: username_end overflows\n"); | 
14432  | 0  |   }  | 
14433  | 0  |   if (components.host_start > buffer.size()) { | 
14434  | 0  |     answer.append("warning: host_start overflows\n"); | 
14435  | 0  |   }  | 
14436  | 0  |   if (components.host_end > buffer.size()) { | 
14437  | 0  |     answer.append("warning: host_end overflows\n"); | 
14438  | 0  |   }  | 
14439  | 0  |   if (components.pathname_start > buffer.size()) { | 
14440  | 0  |     answer.append("warning: pathname_start overflows\n"); | 
14441  | 0  |   }  | 
14442  | 0  |   return answer;  | 
14443  | 0  | }  | 
14444  |  |  | 
14445  | 0  | bool url_aggregator::validate() const noexcept { | 
14446  | 0  |   if (!is_valid) { | 
14447  | 0  |     return true;  | 
14448  | 0  |   }  | 
14449  | 0  |   if (!components.check_offset_consistency()) { | 
14450  | 0  |     ada_log("url_aggregator::validate inconsistent components \n", | 
14451  | 0  |             to_diagram());  | 
14452  | 0  |     return false;  | 
14453  | 0  |   }  | 
14454  |  |   // We have a credible components struct, but let us investivate more  | 
14455  |  |   // carefully:  | 
14456  |  |   /**  | 
14457  |  |    * https://user:pass@example.com:1234/foo/bar?baz#quux  | 
14458  |  |    *       |     |    |          | ^^^^|       |   |  | 
14459  |  |    *       |     |    |          | |   |       |   `----- hash_start  | 
14460  |  |    *       |     |    |          | |   |       `--------- search_start  | 
14461  |  |    *       |     |    |          | |   `----------------- pathname_start  | 
14462  |  |    *       |     |    |          | `--------------------- port  | 
14463  |  |    *       |     |    |          `----------------------- host_end  | 
14464  |  |    *       |     |    `---------------------------------- host_start  | 
14465  |  |    *       |     `--------------------------------------- username_end  | 
14466  |  |    *       `--------------------------------------------- protocol_end  | 
14467  |  |    */  | 
14468  | 0  |   if (components.protocol_end == url_components::omitted) { | 
14469  | 0  |     ada_log("url_aggregator::validate omitted protocol_end \n", to_diagram()); | 
14470  | 0  |     return false;  | 
14471  | 0  |   }  | 
14472  | 0  |   if (components.username_end == url_components::omitted) { | 
14473  | 0  |     ada_log("url_aggregator::validate omitted username_end \n", to_diagram()); | 
14474  | 0  |     return false;  | 
14475  | 0  |   }  | 
14476  | 0  |   if (components.host_start == url_components::omitted) { | 
14477  | 0  |     ada_log("url_aggregator::validate omitted host_start \n", to_diagram()); | 
14478  | 0  |     return false;  | 
14479  | 0  |   }  | 
14480  | 0  |   if (components.host_end == url_components::omitted) { | 
14481  | 0  |     ada_log("url_aggregator::validate omitted host_end \n", to_diagram()); | 
14482  | 0  |     return false;  | 
14483  | 0  |   }  | 
14484  | 0  |   if (components.pathname_start == url_components::omitted) { | 
14485  | 0  |     ada_log("url_aggregator::validate omitted pathname_start \n", to_diagram()); | 
14486  | 0  |     return false;  | 
14487  | 0  |   }  | 
14488  |  |  | 
14489  | 0  |   if (components.protocol_end > buffer.size()) { | 
14490  | 0  |     ada_log("url_aggregator::validate protocol_end overflow \n", to_diagram()); | 
14491  | 0  |     return false;  | 
14492  | 0  |   }  | 
14493  | 0  |   if (components.username_end > buffer.size()) { | 
14494  | 0  |     ada_log("url_aggregator::validate username_end overflow \n", to_diagram()); | 
14495  | 0  |     return false;  | 
14496  | 0  |   }  | 
14497  | 0  |   if (components.host_start > buffer.size()) { | 
14498  | 0  |     ada_log("url_aggregator::validate host_start overflow \n", to_diagram()); | 
14499  | 0  |     return false;  | 
14500  | 0  |   }  | 
14501  | 0  |   if (components.host_end > buffer.size()) { | 
14502  | 0  |     ada_log("url_aggregator::validate host_end overflow \n", to_diagram()); | 
14503  | 0  |     return false;  | 
14504  | 0  |   }  | 
14505  | 0  |   if (components.pathname_start > buffer.size()) { | 
14506  | 0  |     ada_log("url_aggregator::validate pathname_start overflow \n", | 
14507  | 0  |             to_diagram());  | 
14508  | 0  |     return false;  | 
14509  | 0  |   }  | 
14510  |  |  | 
14511  | 0  |   if (components.protocol_end > 0) { | 
14512  | 0  |     if (buffer[components.protocol_end - 1] != ':') { | 
14513  | 0  |       ada_log(  | 
14514  | 0  |           "url_aggregator::validate missing : at the end of the protocol \n",  | 
14515  | 0  |           to_diagram());  | 
14516  | 0  |       return false;  | 
14517  | 0  |     }  | 
14518  | 0  |   }  | 
14519  |  |  | 
14520  | 0  |   if (components.username_end != buffer.size() &&  | 
14521  | 0  |       components.username_end > components.protocol_end + 2) { | 
14522  | 0  |     if (buffer[components.username_end] != ':' &&  | 
14523  | 0  |         buffer[components.username_end] != '@') { | 
14524  | 0  |       ada_log(  | 
14525  | 0  |           "url_aggregator::validate missing : or @ at the end of the username "  | 
14526  | 0  |           "\n",  | 
14527  | 0  |           to_diagram());  | 
14528  | 0  |       return false;  | 
14529  | 0  |     }  | 
14530  | 0  |   }  | 
14531  |  |  | 
14532  | 0  |   if (components.host_start != buffer.size()) { | 
14533  | 0  |     if (components.host_start > components.username_end) { | 
14534  | 0  |       if (buffer[components.host_start] != '@') { | 
14535  | 0  |         ada_log(  | 
14536  | 0  |             "url_aggregator::validate missing @ at the end of the password \n",  | 
14537  | 0  |             to_diagram());  | 
14538  | 0  |         return false;  | 
14539  | 0  |       }  | 
14540  | 0  |     } else if (components.host_start == components.username_end &&  | 
14541  | 0  |                components.host_end > components.host_start) { | 
14542  | 0  |       if (components.host_start == components.protocol_end + 2) { | 
14543  | 0  |         if (buffer[components.protocol_end] != '/' ||  | 
14544  | 0  |             buffer[components.protocol_end + 1] != '/') { | 
14545  | 0  |           ada_log(  | 
14546  | 0  |               "url_aggregator::validate missing // between protocol and host "  | 
14547  | 0  |               "\n",  | 
14548  | 0  |               to_diagram());  | 
14549  | 0  |           return false;  | 
14550  | 0  |         }  | 
14551  | 0  |       } else { | 
14552  | 0  |         if (components.host_start > components.protocol_end &&  | 
14553  | 0  |             buffer[components.host_start] != '@') { | 
14554  | 0  |           ada_log(  | 
14555  | 0  |               "url_aggregator::validate missing @ at the end of the username "  | 
14556  | 0  |               "\n",  | 
14557  | 0  |               to_diagram());  | 
14558  | 0  |           return false;  | 
14559  | 0  |         }  | 
14560  | 0  |       }  | 
14561  | 0  |     } else { | 
14562  | 0  |       if (components.host_end != components.host_start) { | 
14563  | 0  |         ada_log("url_aggregator::validate expected omitted host \n", | 
14564  | 0  |                 to_diagram());  | 
14565  | 0  |         return false;  | 
14566  | 0  |       }  | 
14567  | 0  |     }  | 
14568  | 0  |   }  | 
14569  | 0  |   if (components.host_end != buffer.size() &&  | 
14570  | 0  |       components.pathname_start > components.host_end) { | 
14571  | 0  |     if (components.pathname_start == components.host_end + 2 &&  | 
14572  | 0  |         buffer[components.host_end] == '/' &&  | 
14573  | 0  |         buffer[components.host_end + 1] == '.') { | 
14574  | 0  |       if (components.pathname_start + 1 >= buffer.size() ||  | 
14575  | 0  |           buffer[components.pathname_start] != '/' ||  | 
14576  | 0  |           buffer[components.pathname_start + 1] != '/') { | 
14577  | 0  |         ada_log(  | 
14578  | 0  |             "url_aggregator::validate expected the path to begin with // \n",  | 
14579  | 0  |             to_diagram());  | 
14580  | 0  |         return false;  | 
14581  | 0  |       }  | 
14582  | 0  |     } else if (buffer[components.host_end] != ':') { | 
14583  | 0  |       ada_log("url_aggregator::validate missing : at the port \n", | 
14584  | 0  |               to_diagram());  | 
14585  | 0  |       return false;  | 
14586  | 0  |     }  | 
14587  | 0  |   }  | 
14588  | 0  |   if (components.pathname_start != buffer.size() &&  | 
14589  | 0  |       components.pathname_start < components.search_start &&  | 
14590  | 0  |       components.pathname_start < components.hash_start && !has_opaque_path) { | 
14591  | 0  |     if (buffer[components.pathname_start] != '/') { | 
14592  | 0  |       ada_log("url_aggregator::validate missing / at the path \n", | 
14593  | 0  |               to_diagram());  | 
14594  | 0  |       return false;  | 
14595  | 0  |     }  | 
14596  | 0  |   }  | 
14597  | 0  |   if (components.search_start != url_components::omitted) { | 
14598  | 0  |     if (buffer[components.search_start] != '?') { | 
14599  | 0  |       ada_log("url_aggregator::validate missing ? at the search \n", | 
14600  | 0  |               to_diagram());  | 
14601  | 0  |       return false;  | 
14602  | 0  |     }  | 
14603  | 0  |   }  | 
14604  | 0  |   if (components.hash_start != url_components::omitted) { | 
14605  | 0  |     if (buffer[components.hash_start] != '#') { | 
14606  | 0  |       ada_log("url_aggregator::validate missing # at the hash \n", | 
14607  | 0  |               to_diagram());  | 
14608  | 0  |       return false;  | 
14609  | 0  |     }  | 
14610  | 0  |   }  | 
14611  |  |  | 
14612  | 0  |   return true;  | 
14613  | 0  | }  | 
14614  |  |  | 
14615  | 79  | void url_aggregator::delete_dash_dot() { | 
14616  | 79  |   ada_log("url_aggregator::delete_dash_dot"); | 
14617  | 79  |   ADA_ASSERT_TRUE(validate());  | 
14618  | 79  |   ADA_ASSERT_TRUE(has_dash_dot());  | 
14619  | 79  |   buffer.erase(components.host_end, 2);  | 
14620  | 79  |   components.pathname_start -= 2;  | 
14621  | 79  |   if (components.search_start != url_components::omitted) { | 
14622  | 30  |     components.search_start -= 2;  | 
14623  | 30  |   }  | 
14624  | 79  |   if (components.hash_start != url_components::omitted) { | 
14625  | 37  |     components.hash_start -= 2;  | 
14626  | 37  |   }  | 
14627  | 79  |   ADA_ASSERT_TRUE(validate());  | 
14628  | 79  |   ADA_ASSERT_TRUE(!has_dash_dot());  | 
14629  | 79  | }  | 
14630  |  |  | 
14631  | 8.63k  | inline void url_aggregator::consume_prepared_path(std::string_view input) { | 
14632  | 8.63k  |   ada_log("url_aggregator::consume_prepared_path ", input); | 
14633  |  |   /***  | 
14634  |  |    * This is largely duplicated code from helpers::parse_prepared_path, which is  | 
14635  |  |    * unfortunate. This particular function is nearly identical, except that it  | 
14636  |  |    * is a method on url_aggregator. The idea is that the trivial path (which is  | 
14637  |  |    * very common) merely appends to the buffer. This is the same trivial path as  | 
14638  |  |    * with helpers::parse_prepared_path, except that we have the additional check  | 
14639  |  |    * for is_at_path(). Otherwise, we grab a copy of the current path and we  | 
14640  |  |    * modify it, and then insert it back into the buffer.  | 
14641  |  |    */  | 
14642  | 8.63k  |   uint8_t accumulator = checkers::path_signature(input);  | 
14643  |  |   // Let us first detect a trivial case.  | 
14644  |  |   // If it is special, we check that we have no dot, no %,  no \ and no  | 
14645  |  |   // character needing percent encoding. Otherwise, we check that we have no %,  | 
14646  |  |   // no dot, and no character needing percent encoding.  | 
14647  | 8.63k  |   constexpr uint8_t need_encoding = 1;  | 
14648  | 8.63k  |   constexpr uint8_t backslash_char = 2;  | 
14649  | 8.63k  |   constexpr uint8_t dot_char = 4;  | 
14650  | 8.63k  |   constexpr uint8_t percent_char = 8;  | 
14651  | 8.63k  |   bool special = type != ada::scheme::NOT_SPECIAL;  | 
14652  | 8.63k  |   bool may_need_slow_file_handling = (type == ada::scheme::type::FILE &&  | 
14653  | 8.63k  |                                       checkers::is_windows_drive_letter(input));  | 
14654  | 8.63k  |   bool trivial_path =  | 
14655  | 8.63k  |       (special ? (accumulator == 0)  | 
14656  | 8.63k  |                : ((accumulator & (need_encoding | dot_char | percent_char)) ==  | 
14657  | 3.61k  |                   0)) &&  | 
14658  | 8.63k  |       (!may_need_slow_file_handling);  | 
14659  | 8.63k  |   if (accumulator == dot_char && !may_need_slow_file_handling) { | 
14660  |  |     // '4' means that we have at least one dot, but nothing that requires  | 
14661  |  |     // percent encoding or decoding. The only part that is not trivial is  | 
14662  |  |     // that we may have single dots and double dots path segments.  | 
14663  |  |     // If we have such segments, then we either have a path that begins  | 
14664  |  |     // with '.' (easy to check), or we have the sequence './'.  | 
14665  |  |     // Note: input cannot be empty, it must at least contain one character ('.') | 
14666  |  |     // Note: we know that '\' is not present.  | 
14667  | 1.08k  |     if (input[0] != '.') { | 
14668  | 563  |       size_t slashdot = input.find("/."); | 
14669  | 563  |       if (slashdot == std::string_view::npos) {  // common case | 
14670  | 150  |         trivial_path = true;  | 
14671  | 413  |       } else {  // uncommon | 
14672  |  |         // only three cases matter: /./, /.. or a final /  | 
14673  | 413  |         trivial_path =  | 
14674  | 413  |             !(slashdot + 2 == input.size() || input[slashdot + 2] == '.' ||  | 
14675  | 413  |               input[slashdot + 2] == '/');  | 
14676  | 413  |       }  | 
14677  | 563  |     }  | 
14678  | 1.08k  |   }  | 
14679  | 8.63k  |   if (trivial_path && is_at_path()) { | 
14680  | 5.12k  |     ada_log("parse_path trivial"); | 
14681  | 5.12k  |     buffer += '/';  | 
14682  | 5.12k  |     buffer += input;  | 
14683  | 5.12k  |     return;  | 
14684  | 5.12k  |   }  | 
14685  | 3.50k  |   std::string path = std::string(get_pathname());  | 
14686  |  |   // We are going to need to look a bit at the path, but let us see if we can  | 
14687  |  |   // ignore percent encoding *and* backslashes *and* percent characters.  | 
14688  |  |   // Except for the trivial case, this is likely to capture 99% of paths out  | 
14689  |  |   // there.  | 
14690  | 3.50k  |   bool fast_path =  | 
14691  | 3.50k  |       (special &&  | 
14692  | 3.50k  |        (accumulator & (need_encoding | backslash_char | percent_char)) == 0) &&  | 
14693  | 3.50k  |       (type != ada::scheme::type::FILE);  | 
14694  | 3.50k  |   if (fast_path) { | 
14695  | 550  |     ada_log("parse_prepared_path fast"); | 
14696  |  |     // Here we don't need to worry about \ or percent encoding.  | 
14697  |  |     // We also do not have a file protocol. We might have dots, however,  | 
14698  |  |     // but dots must as appear as '.', and they cannot be encoded because  | 
14699  |  |     // the symbol '%' is not present.  | 
14700  | 550  |     size_t previous_location = 0;  // We start at 0.  | 
14701  | 4.39k  |     do { | 
14702  | 4.39k  |       size_t new_location = input.find('/', previous_location); | 
14703  |  |       // std::string_view path_view = input;  | 
14704  |  |       //  We process the last segment separately:  | 
14705  | 4.39k  |       if (new_location == std::string_view::npos) { | 
14706  | 550  |         std::string_view path_view = input.substr(previous_location);  | 
14707  | 550  |         if (path_view == "..") {  // The path ends with .. | 
14708  |  |           // e.g., if you receive ".." with an empty path, you go to "/".  | 
14709  | 73  |           if (path.empty()) { | 
14710  | 27  |             path = '/';  | 
14711  | 27  |             update_base_pathname(path);  | 
14712  | 27  |             return;  | 
14713  | 27  |           }  | 
14714  |  |           // Fast case where we have nothing to do:  | 
14715  | 46  |           if (path.back() == '/') { | 
14716  | 21  |             update_base_pathname(path);  | 
14717  | 21  |             return;  | 
14718  | 21  |           }  | 
14719  |  |           // If you have the path "/joe/myfriend",  | 
14720  |  |           // then you delete 'myfriend'.  | 
14721  | 25  |           path.resize(path.rfind('/') + 1); | 
14722  | 25  |           update_base_pathname(path);  | 
14723  | 25  |           return;  | 
14724  | 46  |         }  | 
14725  | 477  |         path += '/';  | 
14726  | 477  |         if (path_view != ".") { | 
14727  | 334  |           path.append(path_view);  | 
14728  | 334  |         }  | 
14729  | 477  |         update_base_pathname(path);  | 
14730  | 477  |         return;  | 
14731  | 3.84k  |       } else { | 
14732  |  |         // This is a non-final segment.  | 
14733  | 3.84k  |         std::string_view path_view =  | 
14734  | 3.84k  |             input.substr(previous_location, new_location - previous_location);  | 
14735  | 3.84k  |         previous_location = new_location + 1;  | 
14736  | 3.84k  |         if (path_view == "..") { | 
14737  | 672  |           size_t last_delimiter = path.rfind('/'); | 
14738  | 672  |           if (last_delimiter != std::string::npos) { | 
14739  | 353  |             path.erase(last_delimiter);  | 
14740  | 353  |           }  | 
14741  | 3.17k  |         } else if (path_view != ".") { | 
14742  | 2.76k  |           path += '/';  | 
14743  | 2.76k  |           path.append(path_view);  | 
14744  | 2.76k  |         }  | 
14745  | 3.84k  |       }  | 
14746  | 4.39k  |     } while (true);  | 
14747  | 2.95k  |   } else { | 
14748  | 2.95k  |     ada_log("parse_path slow"); | 
14749  |  |     // we have reached the general case  | 
14750  | 2.95k  |     bool needs_percent_encoding = (accumulator & 1);  | 
14751  | 2.95k  |     std::string path_buffer_tmp;  | 
14752  | 20.4k  |     do { | 
14753  | 20.4k  |       size_t location = (special && (accumulator & 2))  | 
14754  | 20.4k  |                             ? input.find_first_of("/\\") | 
14755  | 20.4k  |                             : input.find('/'); | 
14756  | 20.4k  |       std::string_view path_view = input;  | 
14757  | 20.4k  |       if (location != std::string_view::npos) { | 
14758  | 17.4k  |         path_view.remove_suffix(path_view.size() - location);  | 
14759  | 17.4k  |         input.remove_prefix(location + 1);  | 
14760  | 17.4k  |       }  | 
14761  |  |       // path_buffer is either path_view or it might point at a percent encoded  | 
14762  |  |       // temporary string.  | 
14763  | 20.4k  |       std::string_view path_buffer =  | 
14764  | 20.4k  |           (needs_percent_encoding &&  | 
14765  | 20.4k  |            ada::unicode::percent_encode<false>(  | 
14766  | 11.8k  |                path_view, character_sets::PATH_PERCENT_ENCODE, path_buffer_tmp))  | 
14767  | 20.4k  |               ? path_buffer_tmp  | 
14768  | 20.4k  |               : path_view;  | 
14769  | 20.4k  |       if (unicode::is_double_dot_path_segment(path_buffer)) { | 
14770  | 4.53k  |         if ((helpers::shorten_path(path, type) || special) &&  | 
14771  | 4.53k  |             location == std::string_view::npos) { | 
14772  | 277  |           path += '/';  | 
14773  | 277  |         }  | 
14774  | 15.8k  |       } else if (unicode::is_single_dot_path_segment(path_buffer) &&  | 
14775  | 15.8k  |                  (location == std::string_view::npos)) { | 
14776  | 124  |         path += '/';  | 
14777  | 124  |       }  | 
14778  |  |       // Otherwise, if path_buffer is not a single-dot path segment, then:  | 
14779  | 15.7k  |       else if (!unicode::is_single_dot_path_segment(path_buffer)) { | 
14780  |  |         // If url’s scheme is "file", url’s path is empty, and path_buffer is a  | 
14781  |  |         // Windows drive letter, then replace the second code point in  | 
14782  |  |         // path_buffer with U+003A (:).  | 
14783  | 14.3k  |         if (type == ada::scheme::type::FILE && path.empty() &&  | 
14784  | 14.3k  |             checkers::is_windows_drive_letter(path_buffer)) { | 
14785  | 138  |           path += '/';  | 
14786  | 138  |           path += path_buffer[0];  | 
14787  | 138  |           path += ':';  | 
14788  | 138  |           path_buffer.remove_prefix(2);  | 
14789  | 138  |           path.append(path_buffer);  | 
14790  | 14.2k  |         } else { | 
14791  |  |           // Append path_buffer to url’s path.  | 
14792  | 14.2k  |           path += '/';  | 
14793  | 14.2k  |           path.append(path_buffer);  | 
14794  | 14.2k  |         }  | 
14795  | 14.3k  |       }  | 
14796  | 20.4k  |       if (location == std::string_view::npos) { | 
14797  | 2.95k  |         update_base_pathname(path);  | 
14798  | 2.95k  |         return;  | 
14799  | 2.95k  |       }  | 
14800  | 20.4k  |     } while (true);  | 
14801  | 2.95k  |   }  | 
14802  | 3.50k  | }  | 
14803  |  | }  // namespace ada  | 
14804  |  | /* end file src/url_aggregator.cpp */  | 
14805  |  | /* begin file src/ada_c.cpp */  | 
14806  |  |  | 
14807  | 0  | ada::result<ada::url_aggregator>& get_instance(void* result) noexcept { | 
14808  | 0  |   return *(ada::result<ada::url_aggregator>*)result;  | 
14809  | 0  | }  | 
14810  |  |  | 
14811  |  | extern "C" { | 
14812  |  | typedef void* ada_url;  | 
14813  |  |  | 
14814  |  | struct ada_string { | 
14815  |  |   const char* data;  | 
14816  |  |   size_t length;  | 
14817  |  | };  | 
14818  |  |  | 
14819  |  | struct ada_owned_string { | 
14820  |  |   const char* data;  | 
14821  |  |   size_t length;  | 
14822  |  | };  | 
14823  |  |  | 
14824  | 0  | ada_string ada_string_create(const char* data, size_t length) { | 
14825  | 0  |   ada_string out{}; | 
14826  | 0  |   out.data = data;  | 
14827  | 0  |   out.length = length;  | 
14828  | 0  |   return out;  | 
14829  | 0  | }  | 
14830  |  |  | 
14831  |  | struct ada_url_components { | 
14832  |  |   /*  | 
14833  |  |    * By using 32-bit integers, we implicitly assume that the URL string  | 
14834  |  |    * cannot exceed 4 GB.  | 
14835  |  |    *  | 
14836  |  |    * https://user:pass@example.com:1234/foo/bar?baz#quux  | 
14837  |  |    *       |     |    |          | ^^^^|       |   |  | 
14838  |  |    *       |     |    |          | |   |       |   `----- hash_start  | 
14839  |  |    *       |     |    |          | |   |       `--------- search_start  | 
14840  |  |    *       |     |    |          | |   `----------------- pathname_start  | 
14841  |  |    *       |     |    |          | `--------------------- port  | 
14842  |  |    *       |     |    |          `----------------------- host_end  | 
14843  |  |    *       |     |    `---------------------------------- host_start  | 
14844  |  |    *       |     `--------------------------------------- username_end  | 
14845  |  |    *       `--------------------------------------------- protocol_end  | 
14846  |  |    */  | 
14847  |  |   uint32_t protocol_end;  | 
14848  |  |   /**  | 
14849  |  |    * Username end is not `omitted` by default (-1) to make username and password  | 
14850  |  |    * getters less costly to implement.  | 
14851  |  |    */  | 
14852  |  |   uint32_t username_end;  | 
14853  |  |   uint32_t host_start;  | 
14854  |  |   uint32_t host_end;  | 
14855  |  |   uint32_t port;  | 
14856  |  |   uint32_t pathname_start;  | 
14857  |  |   uint32_t search_start;  | 
14858  |  |   uint32_t hash_start;  | 
14859  |  | };  | 
14860  |  |  | 
14861  | 0  | ada_url ada_parse(const char* input, size_t length) noexcept { | 
14862  | 0  |   return new ada::result<ada::url_aggregator>(  | 
14863  | 0  |       ada::parse<ada::url_aggregator>(std::string_view(input, length)));  | 
14864  | 0  | }  | 
14865  |  |  | 
14866  |  | ada_url ada_parse_with_base(const char* input, size_t input_length,  | 
14867  | 0  |                             const char* base, size_t base_length) noexcept { | 
14868  | 0  |   auto base_out =  | 
14869  | 0  |       ada::parse<ada::url_aggregator>(std::string_view(base, base_length));  | 
14870  |  | 
  | 
14871  | 0  |   if (!base_out) { | 
14872  | 0  |     return new ada::result<ada::url_aggregator>(base_out);  | 
14873  | 0  |   }  | 
14874  |  |  | 
14875  | 0  |   return new ada::result<ada::url_aggregator>(ada::parse<ada::url_aggregator>(  | 
14876  | 0  |       std::string_view(input, input_length), &base_out.value()));  | 
14877  | 0  | }  | 
14878  |  |  | 
14879  | 0  | bool ada_can_parse(const char* input, size_t length) noexcept { | 
14880  | 0  |   return ada::can_parse(std::string_view(input, length));  | 
14881  | 0  | }  | 
14882  |  |  | 
14883  |  | bool ada_can_parse_with_base(const char* input, size_t input_length,  | 
14884  | 0  |                              const char* base, size_t base_length) noexcept { | 
14885  | 0  |   auto base_view = std::string_view(base, base_length);  | 
14886  | 0  |   return ada::can_parse(std::string_view(input, input_length), &base_view);  | 
14887  | 0  | }  | 
14888  |  |  | 
14889  | 0  | void ada_free(ada_url result) noexcept { | 
14890  | 0  |   ada::result<ada::url_aggregator>* r =  | 
14891  | 0  |       (ada::result<ada::url_aggregator>*)result;  | 
14892  | 0  |   delete r;  | 
14893  | 0  | }  | 
14894  |  |  | 
14895  | 0  | bool ada_is_valid(ada_url result) noexcept { | 
14896  | 0  |   ada::result<ada::url_aggregator>& r = get_instance(result);  | 
14897  | 0  |   return r.has_value();  | 
14898  | 0  | }  | 
14899  |  |  | 
14900  |  | // caller must free the result with ada_free_owned_string  | 
14901  | 0  | ada_owned_string ada_get_origin(ada_url result) noexcept { | 
14902  | 0  |   ada::result<ada::url_aggregator>& r = get_instance(result);  | 
14903  | 0  |   ada_owned_string owned;  | 
14904  | 0  |   if (!r) { | 
14905  | 0  |     owned.data = nullptr;  | 
14906  | 0  |     owned.length = 0;  | 
14907  | 0  |     return owned;  | 
14908  | 0  |   }  | 
14909  | 0  |   std::string out = r->get_origin();  | 
14910  | 0  |   owned.length = out.size();  | 
14911  | 0  |   owned.data = new char[owned.length];  | 
14912  | 0  |   memcpy((void*)owned.data, out.data(), owned.length);  | 
14913  | 0  |   return owned;  | 
14914  | 0  | }  | 
14915  |  |  | 
14916  | 0  | void ada_free_owned_string(ada_owned_string owned) noexcept { | 
14917  | 0  |   delete[] owned.data;  | 
14918  | 0  |   owned.data = nullptr;  | 
14919  | 0  |   owned.length = 0;  | 
14920  | 0  | }  | 
14921  |  |  | 
14922  | 0  | ada_string ada_get_href(ada_url result) noexcept { | 
14923  | 0  |   ada::result<ada::url_aggregator>& r = get_instance(result);  | 
14924  | 0  |   if (!r) { | 
14925  | 0  |     return ada_string_create(NULL, 0);  | 
14926  | 0  |   }  | 
14927  | 0  |   std::string_view out = r->get_href();  | 
14928  | 0  |   return ada_string_create(out.data(), out.length());  | 
14929  | 0  | }  | 
14930  |  |  | 
14931  | 0  | ada_string ada_get_username(ada_url result) noexcept { | 
14932  | 0  |   ada::result<ada::url_aggregator>& r = get_instance(result);  | 
14933  | 0  |   if (!r) { | 
14934  | 0  |     return ada_string_create(NULL, 0);  | 
14935  | 0  |   }  | 
14936  | 0  |   std::string_view out = r->get_username();  | 
14937  | 0  |   return ada_string_create(out.data(), out.length());  | 
14938  | 0  | }  | 
14939  |  |  | 
14940  | 0  | ada_string ada_get_password(ada_url result) noexcept { | 
14941  | 0  |   ada::result<ada::url_aggregator>& r = get_instance(result);  | 
14942  | 0  |   if (!r) { | 
14943  | 0  |     return ada_string_create(NULL, 0);  | 
14944  | 0  |   }  | 
14945  | 0  |   std::string_view out = r->get_password();  | 
14946  | 0  |   return ada_string_create(out.data(), out.length());  | 
14947  | 0  | }  | 
14948  |  |  | 
14949  | 0  | ada_string ada_get_port(ada_url result) noexcept { | 
14950  | 0  |   ada::result<ada::url_aggregator>& r = get_instance(result);  | 
14951  | 0  |   if (!r) { | 
14952  | 0  |     return ada_string_create(NULL, 0);  | 
14953  | 0  |   }  | 
14954  | 0  |   std::string_view out = r->get_port();  | 
14955  | 0  |   return ada_string_create(out.data(), out.length());  | 
14956  | 0  | }  | 
14957  |  |  | 
14958  | 0  | ada_string ada_get_hash(ada_url result) noexcept { | 
14959  | 0  |   ada::result<ada::url_aggregator>& r = get_instance(result);  | 
14960  | 0  |   if (!r) { | 
14961  | 0  |     return ada_string_create(NULL, 0);  | 
14962  | 0  |   }  | 
14963  | 0  |   std::string_view out = r->get_hash();  | 
14964  | 0  |   return ada_string_create(out.data(), out.length());  | 
14965  | 0  | }  | 
14966  |  |  | 
14967  | 0  | ada_string ada_get_host(ada_url result) noexcept { | 
14968  | 0  |   ada::result<ada::url_aggregator>& r = get_instance(result);  | 
14969  | 0  |   if (!r) { | 
14970  | 0  |     return ada_string_create(NULL, 0);  | 
14971  | 0  |   }  | 
14972  | 0  |   std::string_view out = r->get_host();  | 
14973  | 0  |   return ada_string_create(out.data(), out.length());  | 
14974  | 0  | }  | 
14975  |  |  | 
14976  | 0  | ada_string ada_get_hostname(ada_url result) noexcept { | 
14977  | 0  |   ada::result<ada::url_aggregator>& r = get_instance(result);  | 
14978  | 0  |   if (!r) { | 
14979  | 0  |     return ada_string_create(NULL, 0);  | 
14980  | 0  |   }  | 
14981  | 0  |   std::string_view out = r->get_hostname();  | 
14982  | 0  |   return ada_string_create(out.data(), out.length());  | 
14983  | 0  | }  | 
14984  |  |  | 
14985  | 0  | ada_string ada_get_pathname(ada_url result) noexcept { | 
14986  | 0  |   ada::result<ada::url_aggregator>& r = get_instance(result);  | 
14987  | 0  |   if (!r) { | 
14988  | 0  |     return ada_string_create(NULL, 0);  | 
14989  | 0  |   }  | 
14990  | 0  |   std::string_view out = r->get_pathname();  | 
14991  | 0  |   return ada_string_create(out.data(), out.length());  | 
14992  | 0  | }  | 
14993  |  |  | 
14994  | 0  | ada_string ada_get_search(ada_url result) noexcept { | 
14995  | 0  |   ada::result<ada::url_aggregator>& r = get_instance(result);  | 
14996  | 0  |   if (!r) { | 
14997  | 0  |     return ada_string_create(NULL, 0);  | 
14998  | 0  |   }  | 
14999  | 0  |   std::string_view out = r->get_search();  | 
15000  | 0  |   return ada_string_create(out.data(), out.length());  | 
15001  | 0  | }  | 
15002  |  |  | 
15003  | 0  | ada_string ada_get_protocol(ada_url result) noexcept { | 
15004  | 0  |   ada::result<ada::url_aggregator>& r = get_instance(result);  | 
15005  | 0  |   if (!r) { | 
15006  | 0  |     return ada_string_create(NULL, 0);  | 
15007  | 0  |   }  | 
15008  | 0  |   std::string_view out = r->get_protocol();  | 
15009  | 0  |   return ada_string_create(out.data(), out.length());  | 
15010  | 0  | }  | 
15011  |  |  | 
15012  | 0  | bool ada_set_href(ada_url result, const char* input, size_t length) noexcept { | 
15013  | 0  |   ada::result<ada::url_aggregator>& r = get_instance(result);  | 
15014  | 0  |   if (!r) { | 
15015  | 0  |     return false;  | 
15016  | 0  |   }  | 
15017  | 0  |   return r->set_href(std::string_view(input, length));  | 
15018  | 0  | }  | 
15019  |  |  | 
15020  | 0  | bool ada_set_host(ada_url result, const char* input, size_t length) noexcept { | 
15021  | 0  |   ada::result<ada::url_aggregator>& r = get_instance(result);  | 
15022  | 0  |   if (!r) { | 
15023  | 0  |     return false;  | 
15024  | 0  |   }  | 
15025  | 0  |   return r->set_host(std::string_view(input, length));  | 
15026  | 0  | }  | 
15027  |  |  | 
15028  |  | bool ada_set_hostname(ada_url result, const char* input,  | 
15029  | 0  |                       size_t length) noexcept { | 
15030  | 0  |   ada::result<ada::url_aggregator>& r = get_instance(result);  | 
15031  | 0  |   if (!r) { | 
15032  | 0  |     return false;  | 
15033  | 0  |   }  | 
15034  | 0  |   return r->set_hostname(std::string_view(input, length));  | 
15035  | 0  | }  | 
15036  |  |  | 
15037  |  | bool ada_set_protocol(ada_url result, const char* input,  | 
15038  | 0  |                       size_t length) noexcept { | 
15039  | 0  |   ada::result<ada::url_aggregator>& r = get_instance(result);  | 
15040  | 0  |   if (!r) { | 
15041  | 0  |     return false;  | 
15042  | 0  |   }  | 
15043  | 0  |   return r->set_protocol(std::string_view(input, length));  | 
15044  | 0  | }  | 
15045  |  |  | 
15046  |  | bool ada_set_username(ada_url result, const char* input,  | 
15047  | 0  |                       size_t length) noexcept { | 
15048  | 0  |   ada::result<ada::url_aggregator>& r = get_instance(result);  | 
15049  | 0  |   if (!r) { | 
15050  | 0  |     return false;  | 
15051  | 0  |   }  | 
15052  | 0  |   return r->set_username(std::string_view(input, length));  | 
15053  | 0  | }  | 
15054  |  |  | 
15055  |  | bool ada_set_password(ada_url result, const char* input,  | 
15056  | 0  |                       size_t length) noexcept { | 
15057  | 0  |   ada::result<ada::url_aggregator>& r = get_instance(result);  | 
15058  | 0  |   if (!r) { | 
15059  | 0  |     return false;  | 
15060  | 0  |   }  | 
15061  | 0  |   return r->set_password(std::string_view(input, length));  | 
15062  | 0  | }  | 
15063  |  |  | 
15064  | 0  | bool ada_set_port(ada_url result, const char* input, size_t length) noexcept { | 
15065  | 0  |   ada::result<ada::url_aggregator>& r = get_instance(result);  | 
15066  | 0  |   if (!r) { | 
15067  | 0  |     return false;  | 
15068  | 0  |   }  | 
15069  | 0  |   return r->set_port(std::string_view(input, length));  | 
15070  | 0  | }  | 
15071  |  |  | 
15072  |  | bool ada_set_pathname(ada_url result, const char* input,  | 
15073  | 0  |                       size_t length) noexcept { | 
15074  | 0  |   ada::result<ada::url_aggregator>& r = get_instance(result);  | 
15075  | 0  |   if (!r) { | 
15076  | 0  |     return false;  | 
15077  | 0  |   }  | 
15078  | 0  |   return r->set_pathname(std::string_view(input, length));  | 
15079  | 0  | }  | 
15080  |  |  | 
15081  | 0  | void ada_set_search(ada_url result, const char* input, size_t length) noexcept { | 
15082  | 0  |   ada::result<ada::url_aggregator>& r = get_instance(result);  | 
15083  | 0  |   if (r) { | 
15084  | 0  |     r->set_search(std::string_view(input, length));  | 
15085  | 0  |   }  | 
15086  | 0  | }  | 
15087  |  |  | 
15088  | 0  | void ada_set_hash(ada_url result, const char* input, size_t length) noexcept { | 
15089  | 0  |   ada::result<ada::url_aggregator>& r = get_instance(result);  | 
15090  | 0  |   if (r) { | 
15091  | 0  |     r->set_hash(std::string_view(input, length));  | 
15092  | 0  |   }  | 
15093  | 0  | }  | 
15094  |  |  | 
15095  | 0  | bool ada_has_credentials(ada_url result) noexcept { | 
15096  | 0  |   ada::result<ada::url_aggregator>& r = get_instance(result);  | 
15097  | 0  |   if (!r) { | 
15098  | 0  |     return false;  | 
15099  | 0  |   }  | 
15100  | 0  |   return r->has_credentials();  | 
15101  | 0  | }  | 
15102  |  |  | 
15103  | 0  | bool ada_has_empty_hostname(ada_url result) noexcept { | 
15104  | 0  |   ada::result<ada::url_aggregator>& r = get_instance(result);  | 
15105  | 0  |   if (!r) { | 
15106  | 0  |     return false;  | 
15107  | 0  |   }  | 
15108  | 0  |   return r->has_empty_hostname();  | 
15109  | 0  | }  | 
15110  |  |  | 
15111  | 0  | bool ada_has_hostname(ada_url result) noexcept { | 
15112  | 0  |   ada::result<ada::url_aggregator>& r = get_instance(result);  | 
15113  | 0  |   if (!r) { | 
15114  | 0  |     return false;  | 
15115  | 0  |   }  | 
15116  | 0  |   return r->has_hostname();  | 
15117  | 0  | }  | 
15118  |  |  | 
15119  | 0  | bool ada_has_non_empty_username(ada_url result) noexcept { | 
15120  | 0  |   ada::result<ada::url_aggregator>& r = get_instance(result);  | 
15121  | 0  |   if (!r) { | 
15122  | 0  |     return false;  | 
15123  | 0  |   }  | 
15124  | 0  |   return r->has_non_empty_username();  | 
15125  | 0  | }  | 
15126  |  |  | 
15127  | 0  | bool ada_has_non_empty_password(ada_url result) noexcept { | 
15128  | 0  |   ada::result<ada::url_aggregator>& r = get_instance(result);  | 
15129  | 0  |   if (!r) { | 
15130  | 0  |     return false;  | 
15131  | 0  |   }  | 
15132  | 0  |   return r->has_non_empty_password();  | 
15133  | 0  | }  | 
15134  |  |  | 
15135  | 0  | bool ada_has_port(ada_url result) noexcept { | 
15136  | 0  |   ada::result<ada::url_aggregator>& r = get_instance(result);  | 
15137  | 0  |   if (!r) { | 
15138  | 0  |     return false;  | 
15139  | 0  |   }  | 
15140  | 0  |   return r->has_port();  | 
15141  | 0  | }  | 
15142  |  |  | 
15143  | 0  | bool ada_has_password(ada_url result) noexcept { | 
15144  | 0  |   ada::result<ada::url_aggregator>& r = get_instance(result);  | 
15145  | 0  |   if (!r) { | 
15146  | 0  |     return false;  | 
15147  | 0  |   }  | 
15148  | 0  |   return r->has_password();  | 
15149  | 0  | }  | 
15150  |  |  | 
15151  | 0  | bool ada_has_hash(ada_url result) noexcept { | 
15152  | 0  |   ada::result<ada::url_aggregator>& r = get_instance(result);  | 
15153  | 0  |   if (!r) { | 
15154  | 0  |     return false;  | 
15155  | 0  |   }  | 
15156  | 0  |   return r->has_hash();  | 
15157  | 0  | }  | 
15158  |  |  | 
15159  | 0  | bool ada_has_search(ada_url result) noexcept { | 
15160  | 0  |   ada::result<ada::url_aggregator>& r = get_instance(result);  | 
15161  | 0  |   if (!r) { | 
15162  | 0  |     return false;  | 
15163  | 0  |   }  | 
15164  | 0  |   return r->has_search();  | 
15165  | 0  | }  | 
15166  |  |  | 
15167  |  | // returns a pointer to the internal url_aggregator::url_components  | 
15168  | 0  | const ada_url_components* ada_get_components(ada_url result) noexcept { | 
15169  | 0  |   static_assert(sizeof(ada_url_components) == sizeof(ada::url_components));  | 
15170  | 0  |   ada::result<ada::url_aggregator>& r = get_instance(result);  | 
15171  | 0  |   if (!r) { | 
15172  | 0  |     return nullptr;  | 
15173  | 0  |   }  | 
15174  | 0  |   return reinterpret_cast<const ada_url_components*>(&r->get_components());  | 
15175  | 0  | }  | 
15176  |  | }  // extern "C"  | 
15177  |  | /* end file src/ada_c.cpp */  | 
15178  |  | /* end file src/ada.cpp */  |