blob: a23a6a46cf0fb0cfe608db4b17febf63ea9aec45 [file] [log] [blame]
Adam Lesinski59e04c62016-02-04 15:59:23 -08001/*
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
Ryan Mitchell833a1a62018-07-10 13:51:36 -070017#include "Dump.h"
18
Adam Lesinski93190b72017-11-03 15:20:17 -070019#include <cinttypes>
Adam Lesinskice5e56e2016-10-21 17:56:45 -070020#include <vector>
21
Adam Lesinski93190b72017-11-03 15:20:17 -070022#include "android-base/stringprintf.h"
MÃ¥rten Kongstad24c9aa62018-06-20 08:46:41 +020023#include "androidfw/ConfigDescription.h"
Adam Lesinskid5083f62017-01-16 15:07:21 -080024#include "androidfw/StringPiece.h"
25
Adam Lesinski59e04c62016-02-04 15:59:23 -080026#include "Debug.h"
27#include "Diagnostics.h"
Ryan Mitchell5d275512018-07-19 14:29:00 -070028#include "LoadedApk.h"
29#include "Util.h"
Adam Lesinski00451162017-10-03 07:44:08 -070030#include "format/Container.h"
Adam Lesinski46708052017-09-29 14:49:15 -070031#include "format/binary/BinaryResourceParser.h"
Ryan Mitchell5d275512018-07-19 14:29:00 -070032#include "format/binary/XmlFlattener.h"
Adam Lesinski46708052017-09-29 14:49:15 -070033#include "format/proto/ProtoDeserialize.h"
Adam Lesinski00451162017-10-03 07:44:08 -070034#include "io/FileStream.h"
Adam Lesinski64587af2016-02-18 18:33:06 -080035#include "io/ZipArchive.h"
Adam Lesinski59e04c62016-02-04 15:59:23 -080036#include "process/IResourceTableConsumer.h"
Adam Lesinski93190b72017-11-03 15:20:17 -070037#include "text/Printer.h"
Adam Lesinski59e04c62016-02-04 15:59:23 -080038#include "util/Files.h"
Adam Lesinskid5083f62017-01-16 15:07:21 -080039
Adam Lesinski93190b72017-11-03 15:20:17 -070040using ::aapt::text::Printer;
Adam Lesinski4ffea042017-08-10 15:37:28 -070041using ::android::StringPiece;
Adam Lesinski93190b72017-11-03 15:20:17 -070042using ::android::base::StringPrintf;
Adam Lesinski59e04c62016-02-04 15:59:23 -080043
Adam Lesinski59e04c62016-02-04 15:59:23 -080044namespace aapt {
45
Adam Lesinski00451162017-10-03 07:44:08 -070046static 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;
Adam Lesinskicacb28f2016-10-19 12:18:14 -070056 }
Adam Lesinski00451162017-10-03 07:44:08 -070057 return "UNKNOWN";
Adam Lesinski59e04c62016-02-04 15:59:23 -080058}
59
Adam Lesinski00451162017-10-03 07:44:08 -070060static void DumpCompiledFile(const ResourceFile& file, const Source& source, off64_t offset,
Adam Lesinski93190b72017-11-03 15:20:17 -070061 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));
Adam Lesinski00451162017-10-03 07:44:08 -070075}
76
Adam Lesinski00451162017-10-03 07:44:08 -070077namespace {
78
Adam Lesinski59e04c62016-02-04 15:59:23 -080079class DumpContext : public IAaptContext {
Adam Lesinskicacb28f2016-10-19 12:18:14 -070080 public:
Adam Lesinskib522f042017-04-21 16:57:59 -070081 PackageType GetPackageType() override {
82 // Doesn't matter.
83 return PackageType::kApp;
84 }
85
Adam Lesinskid0f492d2017-04-03 18:12:45 -070086 IDiagnostics* GetDiagnostics() override {
87 return &diagnostics_;
88 }
Adam Lesinski59e04c62016-02-04 15:59:23 -080089
Adam Lesinskice5e56e2016-10-21 17:56:45 -070090 NameMangler* GetNameMangler() override {
Adam Lesinski00451162017-10-03 07:44:08 -070091 UNIMPLEMENTED(FATAL);
Adam Lesinskicacb28f2016-10-19 12:18:14 -070092 return nullptr;
93 }
Adam Lesinski59e04c62016-02-04 15:59:23 -080094
Adam Lesinskice5e56e2016-10-21 17:56:45 -070095 const std::string& GetCompilationPackage() override {
Adam Lesinskicacb28f2016-10-19 12:18:14 -070096 static std::string empty;
97 return empty;
98 }
Adam Lesinski59e04c62016-02-04 15:59:23 -080099
Adam Lesinskid0f492d2017-04-03 18:12:45 -0700100 uint8_t GetPackageId() override {
101 return 0;
102 }
Adam Lesinski59e04c62016-02-04 15:59:23 -0800103
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700104 SymbolTable* GetExternalSymbols() override {
Adam Lesinski00451162017-10-03 07:44:08 -0700105 UNIMPLEMENTED(FATAL);
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700106 return nullptr;
107 }
Adam Lesinski59e04c62016-02-04 15:59:23 -0800108
Adam Lesinskid0f492d2017-04-03 18:12:45 -0700109 bool IsVerbose() override {
110 return verbose_;
111 }
Adam Lesinski355f2852016-02-13 20:26:45 -0800112
Adam Lesinskid0f492d2017-04-03 18:12:45 -0700113 void SetVerbose(bool val) {
114 verbose_ = val;
115 }
Adam Lesinski355f2852016-02-13 20:26:45 -0800116
Adam Lesinskid0f492d2017-04-03 18:12:45 -0700117 int GetMinSdkVersion() override {
118 return 0;
119 }
Adam Lesinskifb6312f2016-06-28 14:40:32 -0700120
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700121 private:
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700122 StdErrDiagnostics diagnostics_;
123 bool verbose_ = false;
Adam Lesinski59e04c62016-02-04 15:59:23 -0800124};
125
Adam Lesinski00451162017-10-03 07:44:08 -0700126} // namespace
127
Ryan Mitchell5d275512018-07-19 14:29:00 -0700128int DumpAPCCommand::Action(const std::vector<std::string>& args) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700129 DumpContext context;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700130 DebugPrintTableOptions print_options;
131 print_options.show_sources = true;
132 print_options.show_values = !no_values_;
133
134 if (args.size() < 1) {
Ryan Mitchell214846d2018-09-19 16:57:01 -0700135 diag_->Error(DiagMessage() << "No dump container specified");
Ryan Mitchell5d275512018-07-19 14:29:00 -0700136 return 1;
137 }
138
Ryan Mitchell214846d2018-09-19 16:57:01 -0700139 bool error = false;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700140 for (auto container : args) {
141 io::FileInputStream input(container);
142 if (input.HadError()) {
143 context.GetDiagnostics()->Error(DiagMessage(container)
Ryan Mitchell214846d2018-09-19 16:57:01 -0700144 << "failed to open file: " << input.GetError());
145 error = true;
146 continue;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700147 }
148
149 // Try as a compiled file.
150 ContainerReader reader(&input);
151 if (reader.HadError()) {
152 context.GetDiagnostics()->Error(DiagMessage(container)
Ryan Mitchell214846d2018-09-19 16:57:01 -0700153 << "failed to read container: " << reader.GetError());
154 error = true;
155 continue;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700156 }
157
Ryan Mitchell214846d2018-09-19 16:57:01 -0700158 printer_->Println("AAPT2 Container (APC)");
Ryan Mitchell5d275512018-07-19 14:29:00 -0700159 ContainerReaderEntry* entry;
160 std::string error;
161 while ((entry = reader.Next()) != nullptr) {
162 if (entry->Type() == ContainerEntryType::kResTable) {
Ryan Mitchell214846d2018-09-19 16:57:01 -0700163 printer_->Println("kResTable");
Ryan Mitchell5d275512018-07-19 14:29:00 -0700164
165 pb::ResourceTable pb_table;
166 if (!entry->GetResTable(&pb_table)) {
167 context.GetDiagnostics()->Error(DiagMessage(container)
Ryan Mitchell214846d2018-09-19 16:57:01 -0700168 << "failed to parse proto table: " << entry->GetError());
169 error = true;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700170 continue;
171 }
172
173 ResourceTable table;
174 error.clear();
175 if (!DeserializeTableFromPb(pb_table, nullptr /*files*/, &table, &error)) {
176 context.GetDiagnostics()->Error(DiagMessage(container)
Ryan Mitchell214846d2018-09-19 16:57:01 -0700177 << "failed to parse table: " << error);
178 error = true;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700179 continue;
180 }
181
Ryan Mitchell214846d2018-09-19 16:57:01 -0700182 printer_->Indent();
183 Debug::PrintTable(table, print_options, printer_);
184 printer_->Undent();
Ryan Mitchell5d275512018-07-19 14:29:00 -0700185 } else if (entry->Type() == ContainerEntryType::kResFile) {
Ryan Mitchell214846d2018-09-19 16:57:01 -0700186 printer_->Println("kResFile");
Ryan Mitchell5d275512018-07-19 14:29:00 -0700187 pb::internal::CompiledFile pb_compiled_file;
188 off64_t offset;
189 size_t length;
190 if (!entry->GetResFileOffsets(&pb_compiled_file, &offset, &length)) {
Ryan Mitchell214846d2018-09-19 16:57:01 -0700191 context.GetDiagnostics()->Error(DiagMessage(container)
192 << "failed to parse compiled proto file: "
193 << entry->GetError());
194 error = true;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700195 continue;
196 }
197
198 ResourceFile file;
199 if (!DeserializeCompiledFileFromPb(pb_compiled_file, &file, &error)) {
200 context.GetDiagnostics()->Warn(DiagMessage(container)
Ryan Mitchell214846d2018-09-19 16:57:01 -0700201 << "failed to parse compiled file: " << error);
202 error = true;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700203 continue;
204 }
205
Ryan Mitchell214846d2018-09-19 16:57:01 -0700206 printer_->Indent();
207 DumpCompiledFile(file, Source(container), offset, length, printer_);
208 printer_->Undent();
Ryan Mitchell5d275512018-07-19 14:29:00 -0700209 }
Pierre Lecesneaadf27e2017-05-05 14:58:21 +0100210 }
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700211 }
Ryan Mitchell5d275512018-07-19 14:29:00 -0700212
Ryan Mitchell214846d2018-09-19 16:57:01 -0700213 return (error) ? 1 : 0;
Adam Lesinski59e04c62016-02-04 15:59:23 -0800214}
215
Ryan Mitchell214846d2018-09-19 16:57:01 -0700216int 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}
Ryan Mitchell5d275512018-07-19 14:29:00 -0700221
Ryan Mitchell214846d2018-09-19 16:57:01 -0700222int DumpConfigsCommand::Dump(LoadedApk* apk) {
223 ResourceTable* table = apk->GetResourceTable();
Ryan Mitchellfc225b22018-08-21 14:52:51 -0700224 if (!table) {
Ryan Mitchell214846d2018-09-19 16:57:01 -0700225 GetDiagnostics()->Error(DiagMessage() << "Failed to retrieve resource table");
Ryan Mitchellfc225b22018-08-21 14:52:51 -0700226 return 1;
227 }
228
Ryan Mitchell5d275512018-07-19 14:29:00 -0700229 // Comparison function used to order configurations
MÃ¥rten Kongstad24c9aa62018-06-20 08:46:41 +0200230 auto compare = [](android::ConfigDescription c1, android::ConfigDescription c2) -> bool {
Ryan Mitchell214846d2018-09-19 16:57:01 -0700231 return c1.compare(c2) < 0;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700232 };
233
234 // Insert the configurations into a set in order to keep every configuarion seen
MÃ¥rten Kongstad24c9aa62018-06-20 08:46:41 +0200235 std::set<android::ConfigDescription, decltype(compare)> configs(compare);
Ryan Mitchellfc225b22018-08-21 14:52:51 -0700236 for (auto& package : table->packages) {
Ryan Mitchell5d275512018-07-19 14:29:00 -0700237 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) {
Ryan Mitchell214846d2018-09-19 16:57:01 -0700248 GetPrinter()->Print(StringPrintf("%s\n", config.to_string().data()));
Ryan Mitchell5d275512018-07-19 14:29:00 -0700249 }
Ryan Mitchell5d275512018-07-19 14:29:00 -0700250 return 0;
251}
252
Ryan Mitchell214846d2018-09-19 16:57:01 -0700253int DumpPackageNameCommand::Dump(LoadedApk* apk) {
Aurimas Liutikas13e6a1d2018-09-25 16:11:40 -0700254 Maybe<std::string> package_name = GetPackageName(apk);
255 if (!package_name) {
Ryan Mitchell5d275512018-07-19 14:29:00 -0700256 return 1;
257 }
258
Aurimas Liutikas13e6a1d2018-09-25 16:11:40 -0700259 GetPrinter()->Println(package_name.value());
Ryan Mitchell5d275512018-07-19 14:29:00 -0700260 return 0;
261}
262
Ryan Mitchell214846d2018-09-19 16:57:01 -0700263int DumpStringsCommand::Dump(LoadedApk* apk) {
264 ResourceTable* table = apk->GetResourceTable();
265 if (!table) {
266 GetDiagnostics()->Error(DiagMessage() << "Failed to retrieve resource table");
Ryan Mitchell5d275512018-07-19 14:29:00 -0700267 return 1;
268 }
269
Ryan Mitchell214846d2018-09-19 16:57:01 -0700270 // 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
Aurimas Liutikas13e6a1d2018-09-25 16:11:40 -0700279int 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
Ryan Mitchell214846d2018-09-19 16:57:01 -0700304int 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 }
Ryan Mitchell5d275512018-07-19 14:29:00 -0700316
317 DebugPrintTableOptions print_options;
318 print_options.show_sources = true;
319 print_options.show_values = !no_values_;
Ryan Mitchell214846d2018-09-19 16:57:01 -0700320 Debug::PrintTable(*table, print_options, GetPrinter());
Ryan Mitchell5d275512018-07-19 14:29:00 -0700321 return 0;
322}
323
Ryan Mitchell214846d2018-09-19 16:57:01 -0700324int DumpXmlStringsCommand::Dump(LoadedApk* apk) {
Ryan Mitchell5d275512018-07-19 14:29:00 -0700325 DumpContext context;
Ryan Mitchell214846d2018-09-19 16:57:01 -0700326 bool error = false;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700327 for (auto xml_file : files_) {
328 android::ResXMLTree tree;
329
Ryan Mitchell214846d2018-09-19 16:57:01 -0700330 if (apk->GetApkFormat() == ApkFormat::kProto) {
331 auto xml = apk->LoadXml(xml_file, GetDiagnostics());
Ryan Mitchell5d275512018-07-19 14:29:00 -0700332 if (!xml) {
Ryan Mitchell214846d2018-09-19 16:57:01 -0700333 error = true;
334 continue;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700335 }
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())) {
Ryan Mitchell214846d2018-09-19 16:57:01 -0700343 error = true;
344 continue;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700345 }
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
Ryan Mitchell214846d2018-09-19 16:57:01 -0700351 } else if (apk->GetApkFormat() == ApkFormat::kBinary) {
352 io::IFile* file = apk->GetFileCollection()->FindFile(xml_file);
Ryan Mitchell5d275512018-07-19 14:29:00 -0700353 if (!file) {
Ryan Mitchell214846d2018-09-19 16:57:01 -0700354 GetDiagnostics()->Error(DiagMessage(xml_file)
355 << "File '" << xml_file << "' not found in APK");
356 error = true;
357 continue;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700358 }
359
360 std::unique_ptr<io::IData> data = file->OpenAsData();
361 if (!data) {
Ryan Mitchell214846d2018-09-19 16:57:01 -0700362 GetDiagnostics()->Error(DiagMessage() << "Failed to open " << xml_file);
363 error = true;
364 continue;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700365 }
366
367 // Load the run-time xml tree from the file data
368 tree.setTo(data->data(), data->size(), /** copyData */ true);
Ryan Mitchell214846d2018-09-19 16:57:01 -0700369 } else {
370 GetDiagnostics()->Error(DiagMessage(apk->GetSource()) << "Unknown APK format");
371 error = true;
372 continue;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700373 }
374
Ryan Mitchell214846d2018-09-19 16:57:01 -0700375 Debug::DumpResStringPool(&tree.getStrings(), GetPrinter());
Ryan Mitchell5d275512018-07-19 14:29:00 -0700376 }
Ryan Mitchell214846d2018-09-19 16:57:01 -0700377 return (error) ? 1 : 0;
378}
Ryan Mitchell5d275512018-07-19 14:29:00 -0700379
Ryan Mitchell214846d2018-09-19 16:57:01 -0700380int 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 }
Ryan Mitchell5d275512018-07-19 14:29:00 -0700388 return 0;
389}
390
Ryan Mitchell214846d2018-09-19 16:57:01 -0700391const 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};
Ryan Mitchell5d275512018-07-19 14:29:00 -0700546
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700547} // namespace aapt