1 /*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "Dump.h"
18
19 #include <cinttypes>
20 #include <vector>
21
22 #include "android-base/stringprintf.h"
23 #include "androidfw/ConfigDescription.h"
24 #include "androidfw/StringPiece.h"
25
26 #include "Debug.h"
27 #include "Diagnostics.h"
28 #include "LoadedApk.h"
29 #include "Util.h"
30 #include "format/Container.h"
31 #include "format/binary/BinaryResourceParser.h"
32 #include "format/binary/XmlFlattener.h"
33 #include "format/proto/ProtoDeserialize.h"
34 #include "io/FileStream.h"
35 #include "io/ZipArchive.h"
36 #include "process/IResourceTableConsumer.h"
37 #include "text/Printer.h"
38 #include "util/Files.h"
39
40 using ::aapt::text::Printer;
41 using ::android::StringPiece;
42 using ::android::base::StringPrintf;
43
44 namespace aapt {
45
ResourceFileTypeToString(const ResourceFile::Type & type)46 static const char* ResourceFileTypeToString(const ResourceFile::Type& type) {
47 switch (type) {
48 case ResourceFile::Type::kPng:
49 return "PNG";
50 case ResourceFile::Type::kBinaryXml:
51 return "BINARY_XML";
52 case ResourceFile::Type::kProtoXml:
53 return "PROTO_XML";
54 default:
55 break;
56 }
57 return "UNKNOWN";
58 }
59
DumpCompiledFile(const ResourceFile & file,const Source & source,off64_t offset,size_t len,Printer * printer)60 static void DumpCompiledFile(const ResourceFile& file, const Source& source, off64_t offset,
61 size_t len, Printer* printer) {
62 printer->Print("Resource: ");
63 printer->Println(file.name.to_string());
64
65 printer->Print("Config: ");
66 printer->Println(file.config.to_string());
67
68 printer->Print("Source: ");
69 printer->Println(file.source.to_string());
70
71 printer->Print("Type: ");
72 printer->Println(ResourceFileTypeToString(file.type));
73
74 printer->Println(StringPrintf("Data: offset=%" PRIi64 " length=%zd", offset, len));
75 }
76
77 namespace {
78
79 class DumpContext : public IAaptContext {
80 public:
GetPackageType()81 PackageType GetPackageType() override {
82 // Doesn't matter.
83 return PackageType::kApp;
84 }
85
GetDiagnostics()86 IDiagnostics* GetDiagnostics() override {
87 return &diagnostics_;
88 }
89
GetNameMangler()90 NameMangler* GetNameMangler() override {
91 UNIMPLEMENTED(FATAL);
92 return nullptr;
93 }
94
GetCompilationPackage()95 const std::string& GetCompilationPackage() override {
96 static std::string empty;
97 return empty;
98 }
99
GetPackageId()100 uint8_t GetPackageId() override {
101 return 0;
102 }
103
GetExternalSymbols()104 SymbolTable* GetExternalSymbols() override {
105 UNIMPLEMENTED(FATAL);
106 return nullptr;
107 }
108
IsVerbose()109 bool IsVerbose() override {
110 return verbose_;
111 }
112
SetVerbose(bool val)113 void SetVerbose(bool val) {
114 verbose_ = val;
115 }
116
GetMinSdkVersion()117 int GetMinSdkVersion() override {
118 return 0;
119 }
120
121 private:
122 StdErrDiagnostics diagnostics_;
123 bool verbose_ = false;
124 };
125
126 } // namespace
127
Action(const std::vector<std::string> & args)128 int DumpAPCCommand::Action(const std::vector<std::string>& args) {
129 DumpContext context;
130 DebugPrintTableOptions print_options;
131 print_options.show_sources = true;
132 print_options.show_values = !no_values_;
133
134 if (args.size() < 1) {
135 diag_->Error(DiagMessage() << "No dump container specified");
136 return 1;
137 }
138
139 bool error = false;
140 for (auto container : args) {
141 io::FileInputStream input(container);
142 if (input.HadError()) {
143 context.GetDiagnostics()->Error(DiagMessage(container)
144 << "failed to open file: " << input.GetError());
145 error = true;
146 continue;
147 }
148
149 // Try as a compiled file.
150 ContainerReader reader(&input);
151 if (reader.HadError()) {
152 context.GetDiagnostics()->Error(DiagMessage(container)
153 << "failed to read container: " << reader.GetError());
154 error = true;
155 continue;
156 }
157
158 printer_->Println("AAPT2 Container (APC)");
159 ContainerReaderEntry* entry;
160 std::string error;
161 while ((entry = reader.Next()) != nullptr) {
162 if (entry->Type() == ContainerEntryType::kResTable) {
163 printer_->Println("kResTable");
164
165 pb::ResourceTable pb_table;
166 if (!entry->GetResTable(&pb_table)) {
167 context.GetDiagnostics()->Error(DiagMessage(container)
168 << "failed to parse proto table: " << entry->GetError());
169 error = true;
170 continue;
171 }
172
173 ResourceTable table;
174 error.clear();
175 if (!DeserializeTableFromPb(pb_table, nullptr /*files*/, &table, &error)) {
176 context.GetDiagnostics()->Error(DiagMessage(container)
177 << "failed to parse table: " << error);
178 error = true;
179 continue;
180 }
181
182 printer_->Indent();
183 Debug::PrintTable(table, print_options, printer_);
184 printer_->Undent();
185 } else if (entry->Type() == ContainerEntryType::kResFile) {
186 printer_->Println("kResFile");
187 pb::internal::CompiledFile pb_compiled_file;
188 off64_t offset;
189 size_t length;
190 if (!entry->GetResFileOffsets(&pb_compiled_file, &offset, &length)) {
191 context.GetDiagnostics()->Error(DiagMessage(container)
192 << "failed to parse compiled proto file: "
193 << entry->GetError());
194 error = true;
195 continue;
196 }
197
198 ResourceFile file;
199 if (!DeserializeCompiledFileFromPb(pb_compiled_file, &file, &error)) {
200 context.GetDiagnostics()->Warn(DiagMessage(container)
201 << "failed to parse compiled file: " << error);
202 error = true;
203 continue;
204 }
205
206 printer_->Indent();
207 DumpCompiledFile(file, Source(container), offset, length, printer_);
208 printer_->Undent();
209 }
210 }
211 }
212
213 return (error) ? 1 : 0;
214 }
215
Action(const std::vector<std::string> & args)216 int DumpBadgerCommand::Action(const std::vector<std::string>& args) {
217 printer_->Print(StringPrintf("%s", kBadgerData));
218 printer_->Print("Did you mean \"aapt2 dump badging\"?\n");
219 return 1;
220 }
221
Dump(LoadedApk * apk)222 int DumpConfigsCommand::Dump(LoadedApk* apk) {
223 ResourceTable* table = apk->GetResourceTable();
224 if (!table) {
225 GetDiagnostics()->Error(DiagMessage() << "Failed to retrieve resource table");
226 return 1;
227 }
228
229 // Comparison function used to order configurations
230 auto compare = [](android::ConfigDescription c1, android::ConfigDescription c2) -> bool {
231 return c1.compare(c2) < 0;
232 };
233
234 // Insert the configurations into a set in order to keep every configuarion seen
235 std::set<android::ConfigDescription, decltype(compare)> configs(compare);
236 for (auto& package : table->packages) {
237 for (auto& type : package->types) {
238 for (auto& entry : type->entries) {
239 for (auto& value : entry->values) {
240 configs.insert(value->config);
241 }
242 }
243 }
244 }
245
246 // Print the configurations in order
247 for (auto& config : configs) {
248 GetPrinter()->Print(StringPrintf("%s\n", config.to_string().data()));
249 }
250 return 0;
251 }
252
Dump(LoadedApk * apk)253 int DumpPackageNameCommand::Dump(LoadedApk* apk) {
254 Maybe<std::string> package_name = GetPackageName(apk);
255 if (!package_name) {
256 return 1;
257 }
258
259 GetPrinter()->Println(package_name.value());
260 return 0;
261 }
262
Dump(LoadedApk * apk)263 int DumpStringsCommand::Dump(LoadedApk* apk) {
264 ResourceTable* table = apk->GetResourceTable();
265 if (!table) {
266 GetDiagnostics()->Error(DiagMessage() << "Failed to retrieve resource table");
267 return 1;
268 }
269
270 // Load the run-time xml string pool using the flattened data
271 BigBuffer buffer(4096);
272 StringPool::FlattenUtf8(&buffer, table->string_pool, GetDiagnostics());
273 auto data = buffer.to_string();
274 android::ResStringPool pool(data.data(), data.size(), false);
275 Debug::DumpResStringPool(&pool, GetPrinter());
276 return 0;
277 }
278
Dump(LoadedApk * apk)279 int DumpStyleParentCommand::Dump(LoadedApk* apk) {
280 Maybe<std::string> package_name = GetPackageName(apk);
281 if (!package_name) {
282 return 1;
283 }
284
285 const auto target_style = ResourceName(package_name.value(), ResourceType::kStyle, style_);
286 const auto table = apk->GetResourceTable();
287
288 if (!table) {
289 GetDiagnostics()->Error(DiagMessage() << "Failed to retrieve resource table");
290 return 1;
291 }
292
293 Maybe<ResourceTable::SearchResult> target = table->FindResource(target_style);
294 if (!target) {
295 GetDiagnostics()->Error(
296 DiagMessage() << "Target style \"" << target_style.entry << "\" does not exist");
297 return 1;
298 }
299
300 Debug::PrintStyleGraph(table, target_style);
301 return 0;
302 }
303
Dump(LoadedApk * apk)304 int DumpTableCommand::Dump(LoadedApk* apk) {
305 if (apk->GetApkFormat() == ApkFormat::kProto) {
306 GetPrinter()->Println("Proto APK");
307 } else {
308 GetPrinter()->Println("Binary APK");
309 }
310
311 ResourceTable* table = apk->GetResourceTable();
312 if (!table) {
313 GetDiagnostics()->Error(DiagMessage() << "Failed to retrieve resource table");
314 return 1;
315 }
316
317 DebugPrintTableOptions print_options;
318 print_options.show_sources = true;
319 print_options.show_values = !no_values_;
320 Debug::PrintTable(*table, print_options, GetPrinter());
321 return 0;
322 }
323
Dump(LoadedApk * apk)324 int DumpXmlStringsCommand::Dump(LoadedApk* apk) {
325 DumpContext context;
326 bool error = false;
327 for (auto xml_file : files_) {
328 android::ResXMLTree tree;
329
330 if (apk->GetApkFormat() == ApkFormat::kProto) {
331 auto xml = apk->LoadXml(xml_file, GetDiagnostics());
332 if (!xml) {
333 error = true;
334 continue;
335 }
336
337 // Flatten the xml document to get a binary representation of the proto xml file
338 BigBuffer buffer(4096);
339 XmlFlattenerOptions options = {};
340 options.keep_raw_values = true;
341 XmlFlattener flattener(&buffer, options);
342 if (!flattener.Consume(&context, xml.get())) {
343 error = true;
344 continue;
345 }
346
347 // Load the run-time xml tree using the flattened data
348 std::string data = buffer.to_string();
349 tree.setTo(data.data(), data.size(), /** copyData */ true);
350
351 } else if (apk->GetApkFormat() == ApkFormat::kBinary) {
352 io::IFile* file = apk->GetFileCollection()->FindFile(xml_file);
353 if (!file) {
354 GetDiagnostics()->Error(DiagMessage(xml_file)
355 << "File '" << xml_file << "' not found in APK");
356 error = true;
357 continue;
358 }
359
360 std::unique_ptr<io::IData> data = file->OpenAsData();
361 if (!data) {
362 GetDiagnostics()->Error(DiagMessage() << "Failed to open " << xml_file);
363 error = true;
364 continue;
365 }
366
367 // Load the run-time xml tree from the file data
368 tree.setTo(data->data(), data->size(), /** copyData */ true);
369 } else {
370 GetDiagnostics()->Error(DiagMessage(apk->GetSource()) << "Unknown APK format");
371 error = true;
372 continue;
373 }
374
375 Debug::DumpResStringPool(&tree.getStrings(), GetPrinter());
376 }
377 return (error) ? 1 : 0;
378 }
379
Dump(LoadedApk * apk)380 int DumpXmlTreeCommand::Dump(LoadedApk* apk) {
381 for (auto file : files_) {
382 auto xml = apk->LoadXml(file, GetDiagnostics());
383 if (!xml) {
384 return 1;
385 }
386 Debug::DumpXml(*xml, GetPrinter());
387 }
388 return 0;
389 }
390
391 const char DumpBadgerCommand::kBadgerData[2925] = {
392 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
393 32, 32, 32, 32, 32, 32, 95, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
394 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
395 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
396 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 63, 86, 35, 40, 46, 46,
397 95, 95, 95, 95, 97, 97, 44, 32, 46, 124, 42, 33, 83, 62, 32, 32, 32, 32, 32,
398 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32,
399 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
400 32, 32, 58, 46, 58, 59, 61, 59, 61, 81, 81, 81, 81, 66, 96, 61, 61, 58, 46,
401 46, 46, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
402 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
403 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 58, 106, 81, 81,
404 81, 81, 102, 59, 61, 59, 59, 61, 61, 61, 58, 46, 32, 32, 32, 32, 32, 32, 32,
405 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32,
406 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
407 61, 59, 59, 59, 58, 109, 81, 81, 81, 81, 61, 59, 59, 59, 59, 59, 58, 59, 59,
408 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
409 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
410 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 60, 81, 81, 81, 81, 87, 58,
411 59, 59, 59, 59, 59, 59, 61, 119, 44, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
412 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
413 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 47, 61, 59, 59,
414 58, 100, 81, 81, 81, 81, 35, 58, 59, 59, 59, 59, 59, 58, 121, 81, 91, 32, 32,
415 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32,
416 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
417 32, 32, 32, 46, 109, 58, 59, 59, 61, 81, 81, 81, 81, 81, 109, 58, 59, 59, 59,
418 59, 61, 109, 81, 81, 76, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
419 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
420 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 87, 59, 61, 59, 41, 81, 81,
421 81, 81, 81, 81, 59, 61, 59, 59, 58, 109, 81, 81, 87, 39, 46, 32, 32, 32, 32,
422 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32,
423 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
424 60, 81, 91, 59, 59, 61, 81, 81, 81, 81, 81, 87, 43, 59, 58, 59, 60, 81, 81,
425 81, 76, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
426 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
427 32, 32, 32, 32, 32, 32, 32, 32, 32, 52, 91, 58, 45, 59, 87, 81, 81, 81, 81,
428 70, 58, 58, 58, 59, 106, 81, 81, 81, 91, 32, 32, 32, 32, 32, 32, 32, 32, 32,
429 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32,
430 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 93, 40,
431 32, 46, 59, 100, 81, 81, 81, 81, 40, 58, 46, 46, 58, 100, 81, 81, 68, 32, 32,
432 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
433 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 46, 46, 32, 46,
434 46, 46, 32, 46, 32, 46, 45, 91, 59, 61, 58, 109, 81, 81, 81, 87, 46, 58, 61,
435 59, 60, 81, 81, 80, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
436 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 46, 46,
437 61, 59, 61, 61, 61, 59, 61, 61, 59, 59, 59, 58, 58, 46, 46, 41, 58, 59, 58,
438 81, 81, 81, 81, 69, 58, 59, 59, 60, 81, 81, 68, 32, 32, 32, 32, 32, 32, 32,
439 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32,
440 32, 32, 32, 32, 58, 59, 61, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
441 59, 59, 61, 61, 46, 61, 59, 93, 81, 81, 81, 81, 107, 58, 59, 58, 109, 87, 68,
442 96, 32, 32, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
443 32, 32, 32, 32, 32, 10, 32, 32, 32, 46, 60, 61, 61, 59, 59, 59, 59, 59, 59,
444 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 58, 58, 58, 115, 109, 68, 41, 36,
445 81, 109, 46, 61, 61, 81, 69, 96, 46, 58, 58, 46, 58, 46, 46, 32, 32, 32, 32,
446 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 46, 32, 95, 81, 67,
447 61, 61, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
448 59, 59, 58, 68, 39, 61, 105, 61, 63, 81, 119, 58, 106, 80, 32, 58, 61, 59, 59,
449 61, 59, 61, 59, 61, 46, 95, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
450 32, 32, 10, 32, 32, 36, 81, 109, 105, 59, 61, 59, 59, 59, 59, 59, 59, 59, 59,
451 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 46, 58, 37, 73, 108, 108, 62, 52, 81,
452 109, 34, 32, 61, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 59, 61, 61, 46, 46,
453 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 46, 45, 57, 101, 43, 43, 61,
454 61, 59, 59, 59, 59, 59, 59, 61, 59, 59, 59, 59, 59, 59, 59, 59, 59, 58, 97,
455 46, 61, 108, 62, 126, 58, 106, 80, 96, 46, 61, 61, 59, 59, 59, 59, 59, 59, 59,
456 59, 59, 59, 59, 59, 59, 61, 61, 97, 103, 97, 32, 32, 32, 32, 32, 32, 32, 10,
457 32, 32, 32, 32, 45, 46, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 45,
458 58, 59, 59, 59, 59, 61, 119, 81, 97, 124, 105, 124, 124, 39, 126, 95, 119, 58, 61,
459 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 119, 81, 81,
460 99, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
461 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 59, 59, 58, 106, 81, 81, 81, 109, 119,
462 119, 119, 109, 109, 81, 81, 122, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
463 59, 59, 59, 58, 115, 81, 87, 81, 102, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32,
464 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 58,
465 59, 61, 81, 81, 81, 81, 81, 81, 87, 87, 81, 81, 81, 81, 81, 58, 59, 59, 59,
466 59, 59, 59, 59, 59, 58, 45, 45, 45, 59, 59, 59, 41, 87, 66, 33, 32, 32, 32,
467 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
468 32, 32, 32, 32, 32, 32, 58, 59, 59, 93, 81, 81, 81, 81, 81, 81, 81, 81, 81,
469 81, 81, 81, 81, 40, 58, 59, 59, 59, 58, 45, 32, 46, 32, 32, 32, 32, 32, 46,
470 32, 126, 96, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32,
471 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 59, 58, 81,
472 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 40, 58, 59, 59, 59, 58, 32,
473 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
474 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
475 32, 32, 32, 58, 59, 59, 58, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
476 81, 40, 58, 59, 59, 59, 46, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
477 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
478 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 59, 60, 81, 81, 81, 81,
479 81, 81, 81, 81, 81, 81, 81, 81, 81, 59, 61, 59, 59, 61, 32, 32, 32, 32, 32,
480 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32,
481 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
482 58, 59, 59, 93, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 40, 59,
483 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
484 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
485 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 58, 106, 81, 81, 81, 81, 81, 81, 81,
486 81, 81, 81, 81, 81, 81, 76, 58, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32,
487 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32,
488 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 58, 58,
489 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 87, 58, 59, 59, 59, 59,
490 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
491 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
492 32, 32, 32, 32, 32, 58, 59, 61, 41, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
493 81, 81, 87, 59, 61, 58, 59, 59, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
494 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32,
495 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 58, 61, 81, 81,
496 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 107, 58, 59, 59, 59, 59, 58, 32, 32,
497 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
498 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
499 32, 32, 58, 59, 59, 58, 51, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 102, 94,
500 59, 59, 59, 59, 59, 61, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
501 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
502 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 59, 59, 59, 43, 63, 36, 81,
503 81, 81, 87, 64, 86, 102, 58, 59, 59, 59, 59, 59, 59, 59, 46, 32, 32, 32, 32,
504 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32,
505 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 61,
506 59, 59, 59, 59, 59, 59, 59, 43, 33, 58, 126, 126, 58, 59, 59, 59, 59, 59, 59,
507 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
508 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
509 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 58, 45, 58, 61, 59, 58, 58, 58, 61,
510 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 58, 32, 46, 32, 32, 32, 32,
511 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32,
512 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 59, 59,
513 58, 95, 32, 45, 61, 59, 61, 59, 59, 59, 59, 59, 59, 59, 45, 58, 59, 59, 59,
514 59, 61, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
515 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
516 32, 58, 61, 59, 59, 59, 59, 59, 61, 59, 61, 46, 46, 32, 45, 45, 45, 59, 58,
517 45, 45, 46, 58, 59, 59, 59, 59, 59, 59, 61, 46, 32, 32, 32, 32, 32, 32, 32,
518 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32,
519 32, 32, 32, 32, 32, 32, 32, 32, 46, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59,
520 61, 59, 46, 32, 32, 46, 32, 46, 32, 58, 61, 59, 59, 59, 59, 59, 59, 59, 59,
521 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10,
522 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45,
523 59, 59, 59, 59, 59, 59, 59, 59, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61,
524 59, 59, 59, 59, 59, 59, 59, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
525 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
526 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 59, 59, 59, 59, 32, 46, 32,
527 32, 32, 32, 32, 32, 61, 46, 61, 59, 59, 59, 59, 59, 59, 58, 32, 32, 32, 32,
528 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32,
529 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 59, 59, 59,
530 59, 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 32, 46, 61, 58, 59, 59,
531 59, 59, 59, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
532 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
533 32, 32, 32, 32, 58, 59, 59, 59, 59, 59, 59, 59, 59, 46, 46, 32, 32, 32, 32,
534 32, 32, 32, 61, 59, 59, 59, 59, 59, 59, 59, 45, 32, 32, 32, 32, 32, 32, 32,
535 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32,
536 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 32, 45, 61, 59, 59, 59, 59,
537 59, 58, 32, 46, 32, 32, 32, 32, 32, 32, 32, 58, 59, 59, 59, 59, 59, 58, 45,
538 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
539 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
540 32, 32, 32, 32, 45, 45, 45, 45, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32,
541 32, 45, 61, 59, 58, 45, 45, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
542 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
543 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
544 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 32, 32, 46, 32, 32, 32, 32, 32, 32,
545 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10};
546
547 } // namespace aapt
548