1d3b64855b
Add a command to print a resource table's <overlayable> resources. Given the following input <overlayable name="TestResources"> <policy type="system"> <item type="string" name="a" /> </policy> <policy type="sytem|vendor"> <item type="string" name="b" /> <item type="string" name="c" /> </policy> </overlayable> aapt2 dump overlayable will produce name="TestResources" actor="" policies="system" string/a policies="system|vendor" string/b string/c Bug: 120609160 Test: manual (aapt2 dump overlayable $(gettop)/frameworks/base/cmds/idmap2/tests/data/target/target.apk) Change-Id: I21041e6169c62d01f1a469624911ce7cad3e18a8
565 lines
26 KiB
C++
565 lines
26 KiB
C++
/*
|
|
* Copyright (C) 2016 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "Dump.h"
|
|
|
|
#include <cinttypes>
|
|
#include <vector>
|
|
|
|
#include "android-base/stringprintf.h"
|
|
#include "androidfw/ConfigDescription.h"
|
|
#include "androidfw/StringPiece.h"
|
|
|
|
#include "Debug.h"
|
|
#include "Diagnostics.h"
|
|
#include "LoadedApk.h"
|
|
#include "Util.h"
|
|
#include "format/Container.h"
|
|
#include "format/binary/BinaryResourceParser.h"
|
|
#include "format/binary/XmlFlattener.h"
|
|
#include "format/proto/ProtoDeserialize.h"
|
|
#include "io/FileStream.h"
|
|
#include "io/ZipArchive.h"
|
|
#include "process/IResourceTableConsumer.h"
|
|
#include "text/Printer.h"
|
|
#include "util/Files.h"
|
|
|
|
using ::aapt::text::Printer;
|
|
using ::android::StringPiece;
|
|
using ::android::base::StringPrintf;
|
|
|
|
namespace aapt {
|
|
|
|
static const char* ResourceFileTypeToString(const ResourceFile::Type& type) {
|
|
switch (type) {
|
|
case ResourceFile::Type::kPng:
|
|
return "PNG";
|
|
case ResourceFile::Type::kBinaryXml:
|
|
return "BINARY_XML";
|
|
case ResourceFile::Type::kProtoXml:
|
|
return "PROTO_XML";
|
|
default:
|
|
break;
|
|
}
|
|
return "UNKNOWN";
|
|
}
|
|
|
|
static void DumpCompiledFile(const ResourceFile& file, const Source& source, off64_t offset,
|
|
size_t len, Printer* printer) {
|
|
printer->Print("Resource: ");
|
|
printer->Println(file.name.to_string());
|
|
|
|
printer->Print("Config: ");
|
|
printer->Println(file.config.to_string());
|
|
|
|
printer->Print("Source: ");
|
|
printer->Println(file.source.to_string());
|
|
|
|
printer->Print("Type: ");
|
|
printer->Println(ResourceFileTypeToString(file.type));
|
|
|
|
printer->Println(StringPrintf("Data: offset=%" PRIi64 " length=%zd", offset, len));
|
|
}
|
|
|
|
namespace {
|
|
|
|
class DumpContext : public IAaptContext {
|
|
public:
|
|
PackageType GetPackageType() override {
|
|
// Doesn't matter.
|
|
return PackageType::kApp;
|
|
}
|
|
|
|
IDiagnostics* GetDiagnostics() override {
|
|
return &diagnostics_;
|
|
}
|
|
|
|
NameMangler* GetNameMangler() override {
|
|
UNIMPLEMENTED(FATAL);
|
|
return nullptr;
|
|
}
|
|
|
|
const std::string& GetCompilationPackage() override {
|
|
static std::string empty;
|
|
return empty;
|
|
}
|
|
|
|
uint8_t GetPackageId() override {
|
|
return 0;
|
|
}
|
|
|
|
SymbolTable* GetExternalSymbols() override {
|
|
UNIMPLEMENTED(FATAL);
|
|
return nullptr;
|
|
}
|
|
|
|
bool IsVerbose() override {
|
|
return verbose_;
|
|
}
|
|
|
|
void SetVerbose(bool val) {
|
|
verbose_ = val;
|
|
}
|
|
|
|
int GetMinSdkVersion() override {
|
|
return 0;
|
|
}
|
|
|
|
const std::set<std::string>& GetSplitNameDependencies() override {
|
|
UNIMPLEMENTED(FATAL) << "Split Name Dependencies should not be necessary";
|
|
static std::set<std::string> empty;
|
|
return empty;
|
|
}
|
|
|
|
private:
|
|
StdErrDiagnostics diagnostics_;
|
|
bool verbose_ = false;
|
|
};
|
|
|
|
} // namespace
|
|
|
|
int DumpAPCCommand::Action(const std::vector<std::string>& args) {
|
|
DumpContext context;
|
|
DebugPrintTableOptions print_options;
|
|
print_options.show_sources = true;
|
|
print_options.show_values = !no_values_;
|
|
|
|
if (args.size() < 1) {
|
|
diag_->Error(DiagMessage() << "No dump container specified");
|
|
return 1;
|
|
}
|
|
|
|
bool error = false;
|
|
for (auto container : args) {
|
|
io::FileInputStream input(container);
|
|
if (input.HadError()) {
|
|
context.GetDiagnostics()->Error(DiagMessage(container)
|
|
<< "failed to open file: " << input.GetError());
|
|
error = true;
|
|
continue;
|
|
}
|
|
|
|
// Try as a compiled file.
|
|
ContainerReader reader(&input);
|
|
if (reader.HadError()) {
|
|
context.GetDiagnostics()->Error(DiagMessage(container)
|
|
<< "failed to read container: " << reader.GetError());
|
|
error = true;
|
|
continue;
|
|
}
|
|
|
|
printer_->Println("AAPT2 Container (APC)");
|
|
ContainerReaderEntry* entry;
|
|
std::string error;
|
|
while ((entry = reader.Next()) != nullptr) {
|
|
if (entry->Type() == ContainerEntryType::kResTable) {
|
|
printer_->Println("kResTable");
|
|
|
|
pb::ResourceTable pb_table;
|
|
if (!entry->GetResTable(&pb_table)) {
|
|
context.GetDiagnostics()->Error(DiagMessage(container)
|
|
<< "failed to parse proto table: " << entry->GetError());
|
|
error = true;
|
|
continue;
|
|
}
|
|
|
|
ResourceTable table;
|
|
error.clear();
|
|
if (!DeserializeTableFromPb(pb_table, nullptr /*files*/, &table, &error)) {
|
|
context.GetDiagnostics()->Error(DiagMessage(container)
|
|
<< "failed to parse table: " << error);
|
|
error = true;
|
|
continue;
|
|
}
|
|
|
|
printer_->Indent();
|
|
Debug::PrintTable(table, print_options, printer_);
|
|
printer_->Undent();
|
|
} else if (entry->Type() == ContainerEntryType::kResFile) {
|
|
printer_->Println("kResFile");
|
|
pb::internal::CompiledFile pb_compiled_file;
|
|
off64_t offset;
|
|
size_t length;
|
|
if (!entry->GetResFileOffsets(&pb_compiled_file, &offset, &length)) {
|
|
context.GetDiagnostics()->Error(DiagMessage(container)
|
|
<< "failed to parse compiled proto file: "
|
|
<< entry->GetError());
|
|
error = true;
|
|
continue;
|
|
}
|
|
|
|
ResourceFile file;
|
|
if (!DeserializeCompiledFileFromPb(pb_compiled_file, &file, &error)) {
|
|
context.GetDiagnostics()->Warn(DiagMessage(container)
|
|
<< "failed to parse compiled file: " << error);
|
|
error = true;
|
|
continue;
|
|
}
|
|
|
|
printer_->Indent();
|
|
DumpCompiledFile(file, Source(container), offset, length, printer_);
|
|
printer_->Undent();
|
|
}
|
|
}
|
|
}
|
|
|
|
return (error) ? 1 : 0;
|
|
}
|
|
|
|
int DumpBadgerCommand::Action(const std::vector<std::string>& args) {
|
|
printer_->Print(StringPrintf("%s", kBadgerData));
|
|
printer_->Print("Did you mean \"aapt2 dump badging\"?\n");
|
|
return 1;
|
|
}
|
|
|
|
int DumpConfigsCommand::Dump(LoadedApk* apk) {
|
|
ResourceTable* table = apk->GetResourceTable();
|
|
if (!table) {
|
|
GetDiagnostics()->Error(DiagMessage() << "Failed to retrieve resource table");
|
|
return 1;
|
|
}
|
|
|
|
// Comparison function used to order configurations
|
|
auto compare = [](android::ConfigDescription c1, android::ConfigDescription c2) -> bool {
|
|
return c1.compare(c2) < 0;
|
|
};
|
|
|
|
// Insert the configurations into a set in order to keep every configuarion seen
|
|
std::set<android::ConfigDescription, decltype(compare)> configs(compare);
|
|
for (auto& package : table->packages) {
|
|
for (auto& type : package->types) {
|
|
for (auto& entry : type->entries) {
|
|
for (auto& value : entry->values) {
|
|
configs.insert(value->config);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Print the configurations in order
|
|
for (auto& config : configs) {
|
|
GetPrinter()->Print(StringPrintf("%s\n", config.to_string().data()));
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int DumpPackageNameCommand::Dump(LoadedApk* apk) {
|
|
Maybe<std::string> package_name = GetPackageName(apk);
|
|
if (!package_name) {
|
|
return 1;
|
|
}
|
|
|
|
GetPrinter()->Println(package_name.value());
|
|
return 0;
|
|
}
|
|
|
|
int DumpStringsCommand::Dump(LoadedApk* apk) {
|
|
ResourceTable* table = apk->GetResourceTable();
|
|
if (!table) {
|
|
GetDiagnostics()->Error(DiagMessage() << "Failed to retrieve resource table");
|
|
return 1;
|
|
}
|
|
|
|
// Load the run-time xml string pool using the flattened data
|
|
BigBuffer buffer(4096);
|
|
StringPool::FlattenUtf8(&buffer, table->string_pool, GetDiagnostics());
|
|
auto data = buffer.to_string();
|
|
android::ResStringPool pool(data.data(), data.size(), false);
|
|
Debug::DumpResStringPool(&pool, GetPrinter());
|
|
return 0;
|
|
}
|
|
|
|
int DumpStyleParentCommand::Dump(LoadedApk* apk) {
|
|
Maybe<std::string> package_name = GetPackageName(apk);
|
|
if (!package_name) {
|
|
return 1;
|
|
}
|
|
|
|
const auto target_style = ResourceName(package_name.value(), ResourceType::kStyle, style_);
|
|
const auto table = apk->GetResourceTable();
|
|
|
|
if (!table) {
|
|
GetDiagnostics()->Error(DiagMessage() << "Failed to retrieve resource table");
|
|
return 1;
|
|
}
|
|
|
|
Maybe<ResourceTable::SearchResult> target = table->FindResource(target_style);
|
|
if (!target) {
|
|
GetDiagnostics()->Error(
|
|
DiagMessage() << "Target style \"" << target_style.entry << "\" does not exist");
|
|
return 1;
|
|
}
|
|
|
|
Debug::PrintStyleGraph(table, target_style);
|
|
return 0;
|
|
}
|
|
|
|
int DumpTableCommand::Dump(LoadedApk* apk) {
|
|
if (apk->GetApkFormat() == ApkFormat::kProto) {
|
|
GetPrinter()->Println("Proto APK");
|
|
} else {
|
|
GetPrinter()->Println("Binary APK");
|
|
}
|
|
|
|
ResourceTable* table = apk->GetResourceTable();
|
|
if (!table) {
|
|
GetDiagnostics()->Error(DiagMessage() << "Failed to retrieve resource table");
|
|
return 1;
|
|
}
|
|
|
|
DebugPrintTableOptions print_options;
|
|
print_options.show_sources = true;
|
|
print_options.show_values = !no_values_;
|
|
Debug::PrintTable(*table, print_options, GetPrinter());
|
|
return 0;
|
|
}
|
|
|
|
int DumpXmlStringsCommand::Dump(LoadedApk* apk) {
|
|
DumpContext context;
|
|
bool error = false;
|
|
for (auto xml_file : files_) {
|
|
android::ResXMLTree tree;
|
|
|
|
if (apk->GetApkFormat() == ApkFormat::kProto) {
|
|
auto xml = apk->LoadXml(xml_file, GetDiagnostics());
|
|
if (!xml) {
|
|
error = true;
|
|
continue;
|
|
}
|
|
|
|
// Flatten the xml document to get a binary representation of the proto xml file
|
|
BigBuffer buffer(4096);
|
|
XmlFlattenerOptions options = {};
|
|
options.keep_raw_values = true;
|
|
XmlFlattener flattener(&buffer, options);
|
|
if (!flattener.Consume(&context, xml.get())) {
|
|
error = true;
|
|
continue;
|
|
}
|
|
|
|
// Load the run-time xml tree using the flattened data
|
|
std::string data = buffer.to_string();
|
|
tree.setTo(data.data(), data.size(), /** copyData */ true);
|
|
|
|
} else if (apk->GetApkFormat() == ApkFormat::kBinary) {
|
|
io::IFile* file = apk->GetFileCollection()->FindFile(xml_file);
|
|
if (!file) {
|
|
GetDiagnostics()->Error(DiagMessage(xml_file)
|
|
<< "File '" << xml_file << "' not found in APK");
|
|
error = true;
|
|
continue;
|
|
}
|
|
|
|
std::unique_ptr<io::IData> data = file->OpenAsData();
|
|
if (!data) {
|
|
GetDiagnostics()->Error(DiagMessage() << "Failed to open " << xml_file);
|
|
error = true;
|
|
continue;
|
|
}
|
|
|
|
// Load the run-time xml tree from the file data
|
|
tree.setTo(data->data(), data->size(), /** copyData */ true);
|
|
} else {
|
|
GetDiagnostics()->Error(DiagMessage(apk->GetSource()) << "Unknown APK format");
|
|
error = true;
|
|
continue;
|
|
}
|
|
|
|
Debug::DumpResStringPool(&tree.getStrings(), GetPrinter());
|
|
}
|
|
return (error) ? 1 : 0;
|
|
}
|
|
|
|
int DumpXmlTreeCommand::Dump(LoadedApk* apk) {
|
|
for (auto file : files_) {
|
|
auto xml = apk->LoadXml(file, GetDiagnostics());
|
|
if (!xml) {
|
|
return 1;
|
|
}
|
|
Debug::DumpXml(*xml, GetPrinter());
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int DumpOverlayableCommand::Dump(LoadedApk* apk) {
|
|
ResourceTable* table = apk->GetResourceTable();
|
|
if (!table) {
|
|
GetDiagnostics()->Error(DiagMessage() << "Failed to retrieve resource table");
|
|
return 1;
|
|
}
|
|
|
|
Debug::DumpOverlayable(*table, GetPrinter());
|
|
return 0;
|
|
}
|
|
|
|
const char DumpBadgerCommand::kBadgerData[2925] = {
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 95, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 63, 86, 35, 40, 46, 46,
|
|
95, 95, 95, 95, 97, 97, 44, 32, 46, 124, 42, 33, 83, 62, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 58, 46, 58, 59, 61, 59, 61, 81, 81, 81, 81, 66, 96, 61, 61, 58, 46,
|
|
46, 46, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 58, 106, 81, 81,
|
|
81, 81, 102, 59, 61, 59, 59, 61, 61, 61, 58, 46, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
61, 59, 59, 59, 58, 109, 81, 81, 81, 81, 61, 59, 59, 59, 59, 59, 58, 59, 59,
|
|
46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 60, 81, 81, 81, 81, 87, 58,
|
|
59, 59, 59, 59, 59, 59, 61, 119, 44, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 47, 61, 59, 59,
|
|
58, 100, 81, 81, 81, 81, 35, 58, 59, 59, 59, 59, 59, 58, 121, 81, 91, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 46, 109, 58, 59, 59, 61, 81, 81, 81, 81, 81, 109, 58, 59, 59, 59,
|
|
59, 61, 109, 81, 81, 76, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 87, 59, 61, 59, 41, 81, 81,
|
|
81, 81, 81, 81, 59, 61, 59, 59, 58, 109, 81, 81, 87, 39, 46, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
60, 81, 91, 59, 59, 61, 81, 81, 81, 81, 81, 87, 43, 59, 58, 59, 60, 81, 81,
|
|
81, 76, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 52, 91, 58, 45, 59, 87, 81, 81, 81, 81,
|
|
70, 58, 58, 58, 59, 106, 81, 81, 81, 91, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 93, 40,
|
|
32, 46, 59, 100, 81, 81, 81, 81, 40, 58, 46, 46, 58, 100, 81, 81, 68, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 46, 46, 32, 46,
|
|
46, 46, 32, 46, 32, 46, 45, 91, 59, 61, 58, 109, 81, 81, 81, 87, 46, 58, 61,
|
|
59, 60, 81, 81, 80, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 46, 46,
|
|
61, 59, 61, 61, 61, 59, 61, 61, 59, 59, 59, 58, 58, 46, 46, 41, 58, 59, 58,
|
|
81, 81, 81, 81, 69, 58, 59, 59, 60, 81, 81, 68, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32,
|
|
32, 32, 32, 32, 58, 59, 61, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
|
|
59, 59, 61, 61, 46, 61, 59, 93, 81, 81, 81, 81, 107, 58, 59, 58, 109, 87, 68,
|
|
96, 32, 32, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 10, 32, 32, 32, 46, 60, 61, 61, 59, 59, 59, 59, 59, 59,
|
|
59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 58, 58, 58, 115, 109, 68, 41, 36,
|
|
81, 109, 46, 61, 61, 81, 69, 96, 46, 58, 58, 46, 58, 46, 46, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 46, 32, 95, 81, 67,
|
|
61, 61, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
|
|
59, 59, 58, 68, 39, 61, 105, 61, 63, 81, 119, 58, 106, 80, 32, 58, 61, 59, 59,
|
|
61, 59, 61, 59, 61, 46, 95, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 10, 32, 32, 36, 81, 109, 105, 59, 61, 59, 59, 59, 59, 59, 59, 59, 59,
|
|
59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 46, 58, 37, 73, 108, 108, 62, 52, 81,
|
|
109, 34, 32, 61, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 59, 61, 61, 46, 46,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 46, 45, 57, 101, 43, 43, 61,
|
|
61, 59, 59, 59, 59, 59, 59, 61, 59, 59, 59, 59, 59, 59, 59, 59, 59, 58, 97,
|
|
46, 61, 108, 62, 126, 58, 106, 80, 96, 46, 61, 61, 59, 59, 59, 59, 59, 59, 59,
|
|
59, 59, 59, 59, 59, 59, 61, 61, 97, 103, 97, 32, 32, 32, 32, 32, 32, 32, 10,
|
|
32, 32, 32, 32, 45, 46, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 45,
|
|
58, 59, 59, 59, 59, 61, 119, 81, 97, 124, 105, 124, 124, 39, 126, 95, 119, 58, 61,
|
|
58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 119, 81, 81,
|
|
99, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 59, 59, 58, 106, 81, 81, 81, 109, 119,
|
|
119, 119, 109, 109, 81, 81, 122, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
|
|
59, 59, 59, 58, 115, 81, 87, 81, 102, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 58,
|
|
59, 61, 81, 81, 81, 81, 81, 81, 87, 87, 81, 81, 81, 81, 81, 58, 59, 59, 59,
|
|
59, 59, 59, 59, 59, 58, 45, 45, 45, 59, 59, 59, 41, 87, 66, 33, 32, 32, 32,
|
|
32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 58, 59, 59, 93, 81, 81, 81, 81, 81, 81, 81, 81, 81,
|
|
81, 81, 81, 81, 40, 58, 59, 59, 59, 58, 45, 32, 46, 32, 32, 32, 32, 32, 46,
|
|
32, 126, 96, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 59, 58, 81,
|
|
81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 40, 58, 59, 59, 59, 58, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 58, 59, 59, 58, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
|
|
81, 40, 58, 59, 59, 59, 46, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 59, 60, 81, 81, 81, 81,
|
|
81, 81, 81, 81, 81, 81, 81, 81, 81, 59, 61, 59, 59, 61, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
58, 59, 59, 93, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 40, 59,
|
|
59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 58, 106, 81, 81, 81, 81, 81, 81, 81,
|
|
81, 81, 81, 81, 81, 81, 76, 58, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 58, 58,
|
|
81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 87, 58, 59, 59, 59, 59,
|
|
32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 58, 59, 61, 41, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
|
|
81, 81, 87, 59, 61, 58, 59, 59, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 58, 61, 81, 81,
|
|
81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 107, 58, 59, 59, 59, 59, 58, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 58, 59, 59, 58, 51, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 102, 94,
|
|
59, 59, 59, 59, 59, 61, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 59, 59, 59, 43, 63, 36, 81,
|
|
81, 81, 87, 64, 86, 102, 58, 59, 59, 59, 59, 59, 59, 59, 46, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 61,
|
|
59, 59, 59, 59, 59, 59, 59, 43, 33, 58, 126, 126, 58, 59, 59, 59, 59, 59, 59,
|
|
59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 58, 45, 58, 61, 59, 58, 58, 58, 61,
|
|
59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 58, 32, 46, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 59, 59,
|
|
58, 95, 32, 45, 61, 59, 61, 59, 59, 59, 59, 59, 59, 59, 45, 58, 59, 59, 59,
|
|
59, 61, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 58, 61, 59, 59, 59, 59, 59, 61, 59, 61, 46, 46, 32, 45, 45, 45, 59, 58,
|
|
45, 45, 46, 58, 59, 59, 59, 59, 59, 59, 61, 46, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 46, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59,
|
|
61, 59, 46, 32, 32, 46, 32, 46, 32, 58, 61, 59, 59, 59, 59, 59, 59, 59, 59,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45,
|
|
59, 59, 59, 59, 59, 59, 59, 59, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61,
|
|
59, 59, 59, 59, 59, 59, 59, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 59, 59, 59, 59, 32, 46, 32,
|
|
32, 32, 32, 32, 32, 61, 46, 61, 59, 59, 59, 59, 59, 59, 58, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 59, 59, 59,
|
|
59, 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 32, 46, 61, 58, 59, 59,
|
|
59, 59, 59, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 58, 59, 59, 59, 59, 59, 59, 59, 59, 46, 46, 32, 32, 32, 32,
|
|
32, 32, 32, 61, 59, 59, 59, 59, 59, 59, 59, 45, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 32, 45, 61, 59, 59, 59, 59,
|
|
59, 58, 32, 46, 32, 32, 32, 32, 32, 32, 32, 58, 59, 59, 59, 59, 59, 58, 45,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 45, 45, 45, 45, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 45, 61, 59, 58, 45, 45, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 32, 32, 46, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10};
|
|
|
|
} // namespace aapt
|