Compare commits

...

42 Commits

Author SHA1 Message Date
Morph 5d29d2111c system_archive: Update Nintendo Extended OSS font
Co-authored-by: Its-Rei <kupfel@gmail.com>
2020-12-17 08:58:13 -05:00
bunnei ac3b4f918f Merge pull request #5196 from lat9nq/fix-conan-boost-2
cmake/conan: Conditionally add target Boost::context
2020-12-15 21:15:05 -08:00
lat9nq 9b023a56a3 cmake/conan: Conditionally add target Boost::context
Addresses an issue with the two competing versions of Conan's Boost
package that are currently floating around.

Adds the Boost::context target only if it's recognized by CMake as a
target.
2020-12-15 23:47:29 -05:00
bunnei f3db273753 Merge pull request #5190 from Morph1984/validate_device_handle
controllers/npad: Validate device handles before use
2020-12-15 16:40:11 -08:00
bunnei 2e1b998d5e Merge pull request #5119 from Morph1984/fs-opendatastoragewithprogramindex
fsp_srv: Implement OpenDataStorageWithProgramIndex
2020-12-15 11:07:03 -08:00
bunnei 37bec068c2 Merge pull request #5157 from lioncash/array-dirty
maxwell_3d: Remove unused dirty_pointer array
2020-12-15 00:35:47 -08:00
bunnei df6427d30b Merge pull request #5168 from Morph1984/aoc-PurchaseEventManager
aoc_u: Stub IPurchaseEventManager and its service commands
2020-12-14 16:08:38 -08:00
bunnei c96930fd9d Merge pull request #5193 from lat9nq/fix-conan-boost
cmake: Fix generating CMake configs and linking with Boost
2020-12-12 23:42:14 -08:00
lat9nq 292dd642ce cmake: Fix generating CMake configs and linking with Boost
Fixes regression by 761206cf81, causing
yuzu to not build on Linux with any version of Boost except a cached
1.73 Conan version from before about a day ago.

Moves the Boost requirement out of the `REQUIRED_LIBS` psuedo-2D-array
for Conan to instead be manually configured, using Conan as a fallback
solution if the system does not meet our requirements.

Requires any update from the linux-fresh container in order to build.

**DO NOT MERGE** until someone with the MSVC toolchain can verify this
works there, too.
2020-12-13 01:28:51 -05:00
bunnei 761206cf81 common: Update CMakeList to fix build issue with Boost. 2020-12-12 11:50:07 -08:00
Morph 1c773c0869 controllers/npad: Validate device handles before use
Some games such as NEKOPARA Vol. 3 send invalid device handles when calling InitializeVibrationDevice. Introduce a check to validate the device handle before use.
2020-12-12 07:05:38 -05:00
bunnei 69b46dd607 Merge pull request #5183 from lioncash/alias2
vfs: Use existing type aliases consistently
2020-12-12 01:54:28 -08:00
bunnei c918c6480f Merge pull request #5187 from Morph1984/revert-stdfs
fs: Revert all std::filesystem changes
2020-12-11 20:07:37 -08:00
bunnei 37194dd4e9 Merge pull request #5172 from lioncash/svc-wide
svc: Remove unnecessary casts
2020-12-11 17:39:30 -08:00
Morph 4de079b256 Revert "Merge pull request #5173 from lioncash/common-fs"
This reverts commit ce5fcb6bb2, reversing
changes made to 6f41763061.
2020-12-11 20:24:22 -05:00
Morph 8941cdb7d2 Revert "Merge pull request #5174 from ReinUsesLisp/fs-fix"
This reverts commit 5fe55b16a1, reversing
changes made to e94dd7e2c4.
2020-12-11 20:24:22 -05:00
Morph dfee6321cd Revert "Merge pull request #5176 from Morph1984/fix-createfile"
This reverts commit 6d6115475b, reversing
changes made to 5fe55b16a1.
2020-12-11 20:24:22 -05:00
Morph 0195038c07 Revert "Merge pull request #5179 from ReinUsesLisp/fs-path"
This reverts commit 4e94d0d53a, reversing
changes made to 6d6115475b.
2020-12-11 20:21:46 -05:00
Morph ac3ec5ed13 Revert "Merge pull request #5181 from Morph1984/5174-review"
This reverts commit cdb36aef9e, reversing
changes made to 5e9b77129f.
2020-12-11 20:21:21 -05:00
bunnei cdb36aef9e Merge pull request #5181 from Morph1984/5174-review
common/file_util: Address review comments of #5174
2020-12-10 15:52:11 -08:00
LC 5e9b77129f Merge pull request #5184 from lat9nq/travis-linux-ccache-fix
travis/linux: Use correct ccache directory
2020-12-10 15:01:47 -05:00
bunnei 2d47a5fd41 Merge pull request #5123 from Morph1984/nim-IsLargeResourceAvailable
nim: Stub IsLargeResourceAvailable
2020-12-10 11:34:18 -08:00
lat9nq 3802474483 travis/linux: Use correct ccache directory
Changes the bound ccache directory to `/home/yuzu/.ccache` instead of
`/root/.ccache`, since the `/root` directory is not accessible by the
`yuzu` user in the guest container.
2020-12-10 03:34:16 -05:00
bunnei d1a2b3fb18 Merge pull request #5162 from lioncash/copy-shader
gl_shader_decompiler: Elide unnecessary copies within DeclareConstantBuffers()
2020-12-10 00:11:11 -08:00
Lioncash b1657b8c6b vfs: Use existing type aliases consistently
Makes use of the VirtualDir and VirtualFile aliases across the board
instead of having a few isolated places that don't use it.
2020-12-10 01:44:43 -05:00
Morph ec8548b414 common/file_util: Simplify the behavior of CreateFullPath 2020-12-09 19:28:11 -05:00
LC 4e94d0d53a Merge pull request #5179 from ReinUsesLisp/fs-path
common/file_util: Let std::filesystem cast from UTF16 to std::string
2020-12-09 17:25:09 -05:00
ReinUsesLisp bab9cae71f common/file_util: Let std::filesystem cast from UTF16 to std::string
Fix invalid encoding paths when iterating over a directory on Windows.
2020-12-09 18:52:36 -03:00
Chloe 6d6115475b Merge pull request #5176 from Morph1984/fix-createfile
vfs_real: Fix CreateFile for files without a file extension
2020-12-09 22:47:03 +11:00
Morph b06d6e3646 vfs_real: Fix CreateFile for files without a file extension 2020-12-09 06:34:49 -05:00
Morph 5fe55b16a1 Merge pull request #5174 from ReinUsesLisp/fs-fix
common/file_util: Fix and deprecate CreateFullPath, add CreateDirs
2020-12-09 18:07:44 +08:00
Lioncash 2de124e223 svc: Remove unnecessary casts
Simplifies and removes some casts. In all cases, these were generally
widening from a 32-bit unsigned type to a 64-bit unsigned type, so no
information would be lost from the conversion.
2020-12-08 15:42:10 -05:00
Morph deff708cbe IPurchaseEventManager: Implement GetPurchasedEventReadableHandle
- Used by Pokémon Café Mix
- Used by DOOM: Eternal
2020-12-08 13:39:19 -05:00
Morph a9cfe06aaf IPurchaseEventManager: Stub Set(Default)DeliveryTarget
- Used by Pokémon Café Mix
- Used by DOOM: Eternal
2020-12-08 13:39:13 -05:00
Morph 009bdb3558 aoc_u: Stub Create(Permanent)EcPurchasedEventManager
- Used by Pokémon Café Mix
- Used by DOOM: Eternal
2020-12-08 13:39:07 -05:00
Morph e15039372e fsp_srv: Implement OpenDataStorageWithProgramIndex
- Used by RollerCoaster Tycoon 3: Complete Edition
2020-12-08 08:19:05 -05:00
Morph 0eb6c6cd83 file_sys: Consolidate common Title ID operations 2020-12-08 08:19:05 -05:00
Lioncash edcbd47800 gl_shader_decompiler: Elide unnecessary copies within DeclareConstantBuffers()
Resolves a -Wrange-loop-analysis warning.
2020-12-07 14:01:52 -05:00
Lioncash 9e7a1f1351 maxwell_3d: Move member variables to end of class
Follows our established coding style.
2020-12-06 20:56:00 -05:00
Lioncash ce0712bf95 maxwell_3d: Resolve -Wdocumentation warning
Removes a documentation comment for a non-existent member.
2020-12-06 20:48:12 -05:00
Lioncash bcc5c4403a maxwell_3d: Remove unused dirty_pointer array
This is unused and removing it shrinks the structure by 3584 bytes.
2020-12-06 20:46:57 -05:00
Morph c2f83c04cb nim: Stub IsLargeResourceAvailable
- Used by Immortals Fenyx Rising
2020-12-04 09:53:21 -05:00
53 changed files with 1253 additions and 549 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
#!/bin/bash -ex
mkdir -p "$HOME/.ccache"
docker run -e ENABLE_COMPATIBILITY_REPORTING --env-file .travis/common/travis-ci.env -v $(pwd):/yuzu -v "$HOME/.ccache":/root/.ccache yuzuemu/build-environments:linux-fresh /bin/bash /yuzu/.travis/linux/docker.sh
docker run -e ENABLE_COMPATIBILITY_REPORTING --env-file .travis/common/travis-ci.env -v $(pwd):/yuzu -v "$HOME/.ccache":/home/yuzu/.ccache yuzuemu/build-environments:linux-fresh /bin/bash /yuzu/.travis/linux/docker.sh
+27 -1
View File
@@ -160,7 +160,6 @@ macro(yuzu_find_packages)
# Capitalization matters here. We need the naming to match the generated paths from Conan
set(REQUIRED_LIBS
# Cmake Pkg Prefix Version Conan Pkg
"Boost 1.73 boost/1.73.0"
"Catch2 2.13 catch2/2.13.0"
"fmt 7.1 fmt/7.1.2"
# can't use until https://github.com/bincrafters/community/issues/1173
@@ -195,6 +194,22 @@ macro(yuzu_find_packages)
unset(FN_FORCE_REQUIRED)
endmacro()
find_package(Boost 1.73.0 COMPONENTS context headers QUIET)
if (Boost_FOUND)
set(Boost_LIBRARIES Boost::boost)
# Conditionally add Boost::context only if the active version of the Conan or system Boost package provides it
# The old version is missing Boost::context, so we want to avoid adding in that case
# The new version requires adding Boost::context to prevent linking issues
#
# This one is used by Conan on subsequent CMake configures, not the first configure.
if (TARGET Boost::context)
list(APPEND Boost_LIBRARIES Boost::context)
endif()
else()
message(STATUS "Boost 1.73.0 or newer not found, falling back to Conan")
list(APPEND CONAN_REQUIRED_LIBS "boost/1.73.0")
endif()
# Attempt to locate any packages that are required and report the missing ones in CONAN_REQUIRED_LIBS
yuzu_find_packages()
@@ -299,6 +314,17 @@ if (CONAN_REQUIRED_LIBS)
# this time with required, so we bail if its not found.
yuzu_find_packages(FORCE_REQUIRED)
if (NOT Boost_FOUND)
find_package(Boost 1.73.0 REQUIRED COMPONENTS context headers)
set(Boost_LIBRARIES Boost::boost)
# Conditionally add Boost::context only if the active version of the Conan Boost package provides it
# The old version is missing Boost::context, so we want to avoid adding in that case
# The new version requires adding Boost::context to prevent linking issues
if (TARGET Boost::context)
list(APPEND Boost_LIBRARIES Boost::context)
endif()
endif()
# Due to issues with variable scopes in functions, we need to also find_package(qt5) outside of the function
if(ENABLE_QT)
list(APPEND CMAKE_MODULE_PATH "${CONAN_QT_ROOT_RELEASE}")
-1
View File
@@ -209,7 +209,6 @@ else()
endif()
create_target_directory_groups(common)
find_package(Boost 1.71 COMPONENTS context headers REQUIRED)
target_link_libraries(common PUBLIC ${Boost_LIBRARIES} fmt::fmt microprofile)
target_link_libraries(common PRIVATE lz4::lz4 xbyak)
+348 -113
View File
@@ -3,7 +3,6 @@
// Refer to the license.txt file included.
#include <array>
#include <filesystem>
#include <limits>
#include <memory>
#include <sstream>
@@ -68,128 +67,290 @@
#include <algorithm>
#include <sys/stat.h>
#ifndef S_ISDIR
#define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR)
#endif
// This namespace has various generic functions related to files and paths.
// The code still needs a ton of cleanup.
// REMEMBER: strdup considered harmful!
namespace Common::FS {
namespace fs = std::filesystem;
bool Exists(const fs::path& path) {
std::error_code ec;
return fs::exists(path, ec);
// Remove any ending forward slashes from directory paths
// Modifies argument.
static void StripTailDirSlashes(std::string& fname) {
if (fname.length() <= 1) {
return;
}
std::size_t i = fname.length();
while (i > 0 && fname[i - 1] == DIR_SEP_CHR) {
--i;
}
fname.resize(i);
}
bool IsDirectory(const fs::path& path) {
std::error_code ec;
return fs::is_directory(path, ec);
bool Exists(const std::string& filename) {
struct stat file_info;
std::string copy(filename);
StripTailDirSlashes(copy);
#ifdef _WIN32
// Windows needs a slash to identify a driver root
if (copy.size() != 0 && copy.back() == ':')
copy += DIR_SEP_CHR;
int result = _wstat64(Common::UTF8ToUTF16W(copy).c_str(), &file_info);
#else
int result = stat(copy.c_str(), &file_info);
#endif
return (result == 0);
}
bool Delete(const fs::path& path) {
LOG_TRACE(Common_Filesystem, "file {}", path.string());
bool IsDirectory(const std::string& filename) {
struct stat file_info;
std::string copy(filename);
StripTailDirSlashes(copy);
#ifdef _WIN32
// Windows needs a slash to identify a driver root
if (copy.size() != 0 && copy.back() == ':')
copy += DIR_SEP_CHR;
int result = _wstat64(Common::UTF8ToUTF16W(copy).c_str(), &file_info);
#else
int result = stat(copy.c_str(), &file_info);
#endif
if (result < 0) {
LOG_DEBUG(Common_Filesystem, "stat failed on {}: {}", filename, GetLastErrorMsg());
return false;
}
return S_ISDIR(file_info.st_mode);
}
bool Delete(const std::string& filename) {
LOG_TRACE(Common_Filesystem, "file {}", filename);
// Return true because we care about the file no
// being there, not the actual delete.
if (!Exists(path)) {
LOG_DEBUG(Common_Filesystem, "{} does not exist", path.string());
if (!Exists(filename)) {
LOG_DEBUG(Common_Filesystem, "{} does not exist", filename);
return true;
}
std::error_code ec;
return fs::remove(path, ec);
// We can't delete a directory
if (IsDirectory(filename)) {
LOG_ERROR(Common_Filesystem, "Failed: {} is a directory", filename);
return false;
}
#ifdef _WIN32
if (!DeleteFileW(Common::UTF8ToUTF16W(filename).c_str())) {
LOG_ERROR(Common_Filesystem, "DeleteFile failed on {}: {}", filename, GetLastErrorMsg());
return false;
}
#else
if (unlink(filename.c_str()) == -1) {
LOG_ERROR(Common_Filesystem, "unlink failed on {}: {}", filename, GetLastErrorMsg());
return false;
}
#endif
return true;
}
bool CreateDir(const fs::path& path) {
LOG_TRACE(Common_Filesystem, "directory {}", path.string());
bool CreateDir(const std::string& path) {
LOG_TRACE(Common_Filesystem, "directory {}", path);
#ifdef _WIN32
if (::CreateDirectoryW(Common::UTF8ToUTF16W(path).c_str(), nullptr))
return true;
DWORD error = GetLastError();
if (error == ERROR_ALREADY_EXISTS) {
LOG_DEBUG(Common_Filesystem, "CreateDirectory failed on {}: already exists", path);
return true;
}
LOG_ERROR(Common_Filesystem, "CreateDirectory failed on {}: {}", path, error);
return false;
#else
if (mkdir(path.c_str(), 0755) == 0)
return true;
if (Exists(path)) {
LOG_DEBUG(Common_Filesystem, "path exists {}", path.string());
int err = errno;
if (err == EEXIST) {
LOG_DEBUG(Common_Filesystem, "mkdir failed on {}: already exists", path);
return true;
}
std::error_code ec;
const bool success = fs::create_directory(path, ec);
if (!success) {
LOG_ERROR(Common_Filesystem, "Unable to create directory: {}", ec.message());
return false;
}
return true;
LOG_ERROR(Common_Filesystem, "mkdir failed on {}: {}", path, strerror(err));
return false;
#endif
}
bool CreateDirs(const fs::path& path) {
LOG_TRACE(Common_Filesystem, "path {}", path.string());
bool CreateFullPath(const std::string& fullPath) {
int panicCounter = 100;
LOG_TRACE(Common_Filesystem, "path {}", fullPath);
if (Exists(path)) {
LOG_DEBUG(Common_Filesystem, "path exists {}", path.string());
if (Exists(fullPath)) {
LOG_DEBUG(Common_Filesystem, "path exists {}", fullPath);
return true;
}
std::error_code ec;
const bool success = fs::create_directories(path, ec);
std::size_t position = 0;
while (true) {
// Find next sub path
position = fullPath.find(DIR_SEP_CHR, position);
if (!success) {
LOG_ERROR(Common_Filesystem, "Unable to create directories: {}", ec.message());
// we're done, yay!
if (position == fullPath.npos)
return true;
// Include the '/' so the first call is CreateDir("/") rather than CreateDir("")
std::string const subPath(fullPath.substr(0, position + 1));
if (!IsDirectory(subPath) && !CreateDir(subPath)) {
LOG_ERROR(Common, "CreateFullPath: directory creation failed");
return false;
}
// A safety check
panicCounter--;
if (panicCounter <= 0) {
LOG_ERROR(Common, "CreateFullPath: directory structure is too deep");
return false;
}
position++;
}
}
bool DeleteDir(const std::string& filename) {
LOG_TRACE(Common_Filesystem, "directory {}", filename);
// check if a directory
if (!IsDirectory(filename)) {
LOG_ERROR(Common_Filesystem, "Not a directory {}", filename);
return false;
}
return true;
#ifdef _WIN32
if (::RemoveDirectoryW(Common::UTF8ToUTF16W(filename).c_str()))
return true;
#else
if (rmdir(filename.c_str()) == 0)
return true;
#endif
LOG_ERROR(Common_Filesystem, "failed {}: {}", filename, GetLastErrorMsg());
return false;
}
bool CreateFullPath(const fs::path& path) {
LOG_TRACE(Common_Filesystem, "path {}", path);
// Removes trailing slashes and turns any '\' into '/'
const auto new_path = SanitizePath(path.string(), DirectorySeparator::ForwardSlash);
if (new_path.rfind('.') == std::string::npos) {
// The path is a directory
return CreateDirs(new_path);
} else {
// The path is a file
// Creates directory preceding the last '/'
return CreateDirs(new_path.substr(0, new_path.rfind('/')));
}
bool Rename(const std::string& srcFilename, const std::string& destFilename) {
LOG_TRACE(Common_Filesystem, "{} --> {}", srcFilename, destFilename);
#ifdef _WIN32
if (_wrename(Common::UTF8ToUTF16W(srcFilename).c_str(),
Common::UTF8ToUTF16W(destFilename).c_str()) == 0)
return true;
#else
if (rename(srcFilename.c_str(), destFilename.c_str()) == 0)
return true;
#endif
LOG_ERROR(Common_Filesystem, "failed {} --> {}: {}", srcFilename, destFilename,
GetLastErrorMsg());
return false;
}
bool Rename(const fs::path& src, const fs::path& dst) {
LOG_TRACE(Common_Filesystem, "{} --> {}", src.string(), dst.string());
bool Copy(const std::string& srcFilename, const std::string& destFilename) {
LOG_TRACE(Common_Filesystem, "{} --> {}", srcFilename, destFilename);
#ifdef _WIN32
if (CopyFileW(Common::UTF8ToUTF16W(srcFilename).c_str(),
Common::UTF8ToUTF16W(destFilename).c_str(), FALSE))
return true;
std::error_code ec;
fs::rename(src, dst, ec);
LOG_ERROR(Common_Filesystem, "failed {} --> {}: {}", srcFilename, destFilename,
GetLastErrorMsg());
return false;
#else
using CFilePointer = std::unique_ptr<FILE, decltype(&std::fclose)>;
if (ec) {
LOG_ERROR(Common_Filesystem, "Unable to rename file from {} to {}: {}", src.string(),
dst.string(), ec.message());
// Open input file
CFilePointer input{fopen(srcFilename.c_str(), "rb"), std::fclose};
if (!input) {
LOG_ERROR(Common_Filesystem, "opening input failed {} --> {}: {}", srcFilename,
destFilename, GetLastErrorMsg());
return false;
}
return true;
}
bool Copy(const fs::path& src, const fs::path& dst) {
LOG_TRACE(Common_Filesystem, "{} --> {}", src.string(), dst.string());
std::error_code ec;
const bool success = fs::copy_file(src, dst, fs::copy_options::overwrite_existing, ec);
if (!success) {
LOG_ERROR(Common_Filesystem, "Unable to copy file {} to {}: {}", src.string(), dst.string(),
ec.message());
// open output file
CFilePointer output{fopen(destFilename.c_str(), "wb"), std::fclose};
if (!output) {
LOG_ERROR(Common_Filesystem, "opening output failed {} --> {}: {}", srcFilename,
destFilename, GetLastErrorMsg());
return false;
}
// copy loop
std::array<char, 1024> buffer;
while (!feof(input.get())) {
// read input
std::size_t rnum = fread(buffer.data(), sizeof(char), buffer.size(), input.get());
if (rnum != buffer.size()) {
if (ferror(input.get()) != 0) {
LOG_ERROR(Common_Filesystem, "failed reading from source, {} --> {}: {}",
srcFilename, destFilename, GetLastErrorMsg());
return false;
}
}
// write output
std::size_t wnum = fwrite(buffer.data(), sizeof(char), rnum, output.get());
if (wnum != rnum) {
LOG_ERROR(Common_Filesystem, "failed writing to output, {} --> {}: {}", srcFilename,
destFilename, GetLastErrorMsg());
return false;
}
}
return true;
#endif
}
u64 GetSize(const fs::path& path) {
std::error_code ec;
const auto size = fs::file_size(path, ec);
if (ec) {
LOG_ERROR(Common_Filesystem, "Unable to retrieve file size ({}): {}", path.string(),
ec.message());
u64 GetSize(const std::string& filename) {
if (!Exists(filename)) {
LOG_ERROR(Common_Filesystem, "failed {}: No such file", filename);
return 0;
}
return size;
if (IsDirectory(filename)) {
LOG_ERROR(Common_Filesystem, "failed {}: is a directory", filename);
return 0;
}
struct stat buf;
#ifdef _WIN32
if (_wstat64(Common::UTF8ToUTF16W(filename).c_str(), &buf) == 0)
#else
if (stat(filename.c_str(), &buf) == 0)
#endif
{
LOG_TRACE(Common_Filesystem, "{}: {}", filename, buf.st_size);
return buf.st_size;
}
LOG_ERROR(Common_Filesystem, "Stat failed {}: {}", filename, GetLastErrorMsg());
return 0;
}
u64 GetSize(const int fd) {
struct stat buf;
if (fstat(fd, &buf) != 0) {
LOG_ERROR(Common_Filesystem, "GetSize: stat failed {}: {}", fd, GetLastErrorMsg());
return 0;
}
return buf.st_size;
}
u64 GetSize(FILE* f) {
@@ -277,58 +438,132 @@ bool ForeachDirectoryEntry(u64* num_entries_out, const std::string& directory,
return true;
}
bool DeleteDirRecursively(const fs::path& path) {
std::error_code ec;
fs::remove_all(path, ec);
u64 ScanDirectoryTree(const std::string& directory, FSTEntry& parent_entry,
unsigned int recursion) {
const auto callback = [recursion, &parent_entry](u64* num_entries_out,
const std::string& directory,
const std::string& virtual_name) -> bool {
FSTEntry entry;
entry.virtualName = virtual_name;
entry.physicalName = directory + DIR_SEP + virtual_name;
if (ec) {
LOG_ERROR(Common_Filesystem, "Unable to completely delete directory {}: {}", path.string(),
ec.message());
if (IsDirectory(entry.physicalName)) {
entry.isDirectory = true;
// is a directory, lets go inside if we didn't recurse to often
if (recursion > 0) {
entry.size = ScanDirectoryTree(entry.physicalName, entry, recursion - 1);
*num_entries_out += entry.size;
} else {
entry.size = 0;
}
} else { // is a file
entry.isDirectory = false;
entry.size = GetSize(entry.physicalName);
}
(*num_entries_out)++;
// Push into the tree
parent_entry.children.push_back(std::move(entry));
return true;
};
u64 num_entries;
return ForeachDirectoryEntry(&num_entries, directory, callback) ? num_entries : 0;
}
bool DeleteDirRecursively(const std::string& directory, unsigned int recursion) {
const auto callback = [recursion](u64*, const std::string& directory,
const std::string& virtual_name) {
const std::string new_path = directory + DIR_SEP_CHR + virtual_name;
if (IsDirectory(new_path)) {
if (recursion == 0) {
return false;
}
return DeleteDirRecursively(new_path, recursion - 1);
}
return Delete(new_path);
};
if (!ForeachDirectoryEntry(nullptr, directory, callback))
return false;
}
// Delete the outermost directory
DeleteDir(directory);
return true;
}
void CopyDir(const fs::path& src, const fs::path& dst) {
constexpr auto copy_flags = fs::copy_options::skip_existing | fs::copy_options::recursive;
void CopyDir([[maybe_unused]] const std::string& source_path,
[[maybe_unused]] const std::string& dest_path) {
#ifndef _WIN32
if (source_path == dest_path) {
return;
}
if (!Exists(source_path)) {
return;
}
if (!Exists(dest_path)) {
CreateFullPath(dest_path);
}
std::error_code ec;
fs::copy(src, dst, copy_flags, ec);
if (ec) {
LOG_ERROR(Common_Filesystem, "Error copying directory {} to {}: {}", src.string(),
dst.string(), ec.message());
DIR* dirp = opendir(source_path.c_str());
if (!dirp) {
return;
}
LOG_TRACE(Common_Filesystem, "Successfully copied directory.");
while (struct dirent* result = readdir(dirp)) {
const std::string virtualName(result->d_name);
// check for "." and ".."
if (((virtualName[0] == '.') && (virtualName[1] == '\0')) ||
((virtualName[0] == '.') && (virtualName[1] == '.') && (virtualName[2] == '\0'))) {
continue;
}
std::string source, dest;
source = source_path + virtualName;
dest = dest_path + virtualName;
if (IsDirectory(source)) {
source += '/';
dest += '/';
if (!Exists(dest)) {
CreateFullPath(dest);
}
CopyDir(source, dest);
} else if (!Exists(dest)) {
Copy(source, dest);
}
}
closedir(dirp);
#endif
}
std::optional<fs::path> GetCurrentDir() {
std::error_code ec;
auto path = fs::current_path(ec);
if (ec) {
LOG_ERROR(Common_Filesystem, "Unable to retrieve current working directory: {}",
ec.message());
std::optional<std::string> GetCurrentDir() {
// Get the current working directory (getcwd uses malloc)
#ifdef _WIN32
wchar_t* dir = _wgetcwd(nullptr, 0);
if (!dir) {
#else
char* dir = getcwd(nullptr, 0);
if (!dir) {
#endif
LOG_ERROR(Common_Filesystem, "GetCurrentDirectory failed: {}", GetLastErrorMsg());
return std::nullopt;
}
return {std::move(path)};
#ifdef _WIN32
std::string strDir = Common::UTF16ToUTF8(dir);
#else
std::string strDir = dir;
#endif
free(dir);
return strDir;
}
bool SetCurrentDir(const fs::path& path) {
std::error_code ec;
fs::current_path(path, ec);
if (ec) {
LOG_ERROR(Common_Filesystem, "Unable to set {} as working directory: {}", path.string(),
ec.message());
return false;
}
return true;
bool SetCurrentDir(const std::string& directory) {
#ifdef _WIN32
return _wchdir(Common::UTF8ToUTF16W(directory).c_str()) == 0;
#else
return chdir(directory.c_str()) == 0;
#endif
}
#if defined(__APPLE__)
+45 -28
View File
@@ -6,7 +6,6 @@
#include <array>
#include <cstdio>
#include <filesystem>
#include <fstream>
#include <functional>
#include <limits>
@@ -39,40 +38,48 @@ enum class UserPath {
UserDir,
};
// Returns true if the path exists
[[nodiscard]] bool Exists(const std::filesystem::path& path);
// FileSystem tree node/
struct FSTEntry {
bool isDirectory;
u64 size; // file length or number of entries from children
std::string physicalName; // name on disk
std::string virtualName; // name in FST names table
std::vector<FSTEntry> children;
};
// Returns true if path is a directory
[[nodiscard]] bool IsDirectory(const std::filesystem::path& path);
// Returns true if file filename exists
[[nodiscard]] bool Exists(const std::string& filename);
// Returns true if filename is a directory
[[nodiscard]] bool IsDirectory(const std::string& filename);
// Returns the size of filename (64bit)
[[nodiscard]] u64 GetSize(const std::filesystem::path& path);
[[nodiscard]] u64 GetSize(const std::string& filename);
// Overloaded GetSize, accepts file descriptor
[[nodiscard]] u64 GetSize(int fd);
// Overloaded GetSize, accepts FILE*
[[nodiscard]] u64 GetSize(FILE* f);
// Returns true if successful, or path already exists.
bool CreateDir(const std::filesystem::path& path);
bool CreateDir(const std::string& filename);
// Create all directories in path
// Returns true if successful, or path already exists.
[[nodiscard("Directory creation can fail and must be tested")]] bool CreateDirs(
const std::filesystem::path& path);
// Creates the full path of fullPath returns true on success
bool CreateFullPath(const std::string& fullPath);
// Creates directories in path. Returns true on success.
[[deprecated("This function is deprecated, use CreateDirs")]] bool CreateFullPath(
const std::filesystem::path& path);
// Deletes a given filename, return true on success
// Doesn't supports deleting a directory
bool Delete(const std::string& filename);
// Deletes a given file at the path.
// This will also delete empty directories.
// Return true on success
bool Delete(const std::filesystem::path& path);
// Deletes a directory filename, returns true on success
bool DeleteDir(const std::string& filename);
// Renames file src to dst, returns true on success
bool Rename(const std::filesystem::path& src, const std::filesystem::path& dst);
// renames file srcFilename to destFilename, returns true on success
bool Rename(const std::string& srcFilename, const std::string& destFilename);
// copies file src to dst, returns true on success
bool Copy(const std::filesystem::path& src, const std::filesystem::path& dst);
// copies file srcFilename to destFilename, returns true on success
bool Copy(const std::string& srcFilename, const std::string& destFilename);
// creates an empty file filename, returns true on success
bool CreateEmptyFile(const std::string& filename);
@@ -99,17 +106,27 @@ using DirectoryEntryCallable = std::function<bool(
bool ForeachDirectoryEntry(u64* num_entries_out, const std::string& directory,
DirectoryEntryCallable callback);
// Deletes the given path and anything under it. Returns true on success.
bool DeleteDirRecursively(const std::filesystem::path& path);
/**
* Scans the directory tree, storing the results.
* @param directory the parent directory to start scanning from
* @param parent_entry FSTEntry where the filesystem tree results will be stored.
* @param recursion Number of children directories to read before giving up.
* @return the total number of files/directories found
*/
u64 ScanDirectoryTree(const std::string& directory, FSTEntry& parent_entry,
unsigned int recursion = 0);
// deletes the given directory and anything under it. Returns true on success.
bool DeleteDirRecursively(const std::string& directory, unsigned int recursion = 256);
// Returns the current directory
[[nodiscard]] std::optional<std::filesystem::path> GetCurrentDir();
[[nodiscard]] std::optional<std::string> GetCurrentDir();
// Create directory and copy contents (does not overwrite existing files)
void CopyDir(const std::filesystem::path& src, const std::filesystem::path& dst);
void CopyDir(const std::string& source_path, const std::string& dest_path);
// Set the current directory to given path
bool SetCurrentDir(const std::filesystem::path& path);
// Set the current directory to given directory
bool SetCurrentDir(const std::string& directory);
// Returns a pointer to a string with a yuzu data dir in the user's home
// directory. To be used in "multi-user" mode (that is, installed).
+1
View File
@@ -41,6 +41,7 @@ add_library(core STATIC
file_sys/bis_factory.h
file_sys/card_image.cpp
file_sys/card_image.h
file_sys/common_funcs.h
file_sys/content_archive.cpp
file_sys/content_archive.h
file_sys/control_metadata.cpp
+56
View File
@@ -0,0 +1,56 @@
// Copyright 2020 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include "common/common_types.h"
namespace FileSys {
constexpr u64 AOC_TITLE_ID_MASK = 0x7FF;
constexpr u64 AOC_TITLE_ID_OFFSET = 0x1000;
constexpr u64 BASE_TITLE_ID_MASK = 0xFFFFFFFFFFFFE000;
/**
* Gets the base title ID from a given title ID.
*
* @param title_id The title ID.
* @returns The base title ID.
*/
[[nodiscard]] constexpr u64 GetBaseTitleID(u64 title_id) {
return title_id & BASE_TITLE_ID_MASK;
}
/**
* Gets the base title ID with a program index offset from a given title ID.
*
* @param title_id The title ID.
* @param program_index The program index.
* @returns The base title ID with a program index offset.
*/
[[nodiscard]] constexpr u64 GetBaseTitleIDWithProgramIndex(u64 title_id, u64 program_index) {
return GetBaseTitleID(title_id) + program_index;
}
/**
* Gets the AOC (Add-On Content) base title ID from a given title ID.
*
* @param title_id The title ID.
* @returns The AOC base title ID.
*/
[[nodiscard]] constexpr u64 GetAOCBaseTitleID(u64 title_id) {
return GetBaseTitleID(title_id) + AOC_TITLE_ID_OFFSET;
}
/**
* Gets the AOC (Add-On Content) ID from a given AOC title ID.
*
* @param aoc_title_id The AOC title ID.
* @returns The AOC ID.
*/
[[nodiscard]] constexpr u64 GetAOCID(u64 aoc_title_id) {
return aoc_title_id & AOC_TITLE_ID_MASK;
}
} // namespace FileSys
+7 -5
View File
@@ -519,15 +519,17 @@ Loader::ResultStatus NCA::GetStatus() const {
return status;
}
std::vector<std::shared_ptr<VfsFile>> NCA::GetFiles() const {
if (status != Loader::ResultStatus::Success)
std::vector<VirtualFile> NCA::GetFiles() const {
if (status != Loader::ResultStatus::Success) {
return {};
}
return files;
}
std::vector<std::shared_ptr<VfsDirectory>> NCA::GetSubdirectories() const {
if (status != Loader::ResultStatus::Success)
std::vector<VirtualDir> NCA::GetSubdirectories() const {
if (status != Loader::ResultStatus::Success) {
return {};
}
return dirs;
}
@@ -535,7 +537,7 @@ std::string NCA::GetName() const {
return file->GetName();
}
std::shared_ptr<VfsDirectory> NCA::GetParentDirectory() const {
VirtualDir NCA::GetParentDirectory() const {
return file->GetContainingDirectory();
}
+4 -4
View File
@@ -82,7 +82,7 @@ struct NCAHeader {
};
static_assert(sizeof(NCAHeader) == 0x400, "NCAHeader has incorrect size.");
inline bool IsDirectoryExeFS(const std::shared_ptr<VfsDirectory>& pfs) {
inline bool IsDirectoryExeFS(const VirtualDir& pfs) {
// According to switchbrew, an exefs must only contain these two files:
return pfs->GetFile("main") != nullptr && pfs->GetFile("main.npdm") != nullptr;
}
@@ -104,10 +104,10 @@ public:
Loader::ResultStatus GetStatus() const;
std::vector<std::shared_ptr<VfsFile>> GetFiles() const override;
std::vector<std::shared_ptr<VfsDirectory>> GetSubdirectories() const override;
std::vector<VirtualFile> GetFiles() const override;
std::vector<VirtualDir> GetSubdirectories() const override;
std::string GetName() const override;
std::shared_ptr<VfsDirectory> GetParentDirectory() const override;
VirtualDir GetParentDirectory() const override;
NCAContentType GetType() const;
u64 GetTitleId() const;
+1 -1
View File
@@ -191,7 +191,7 @@ bool BKTR::Resize(std::size_t new_size) {
return false;
}
std::shared_ptr<VfsDirectory> BKTR::GetContainingDirectory() const {
VirtualDir BKTR::GetContainingDirectory() const {
return base_romfs->GetContainingDirectory();
}
+1 -1
View File
@@ -106,7 +106,7 @@ public:
bool Resize(std::size_t new_size) override;
std::shared_ptr<VfsDirectory> GetContainingDirectory() const override;
VirtualDir GetContainingDirectory() const override;
bool IsWritable() const override;
+2 -2
View File
@@ -12,6 +12,7 @@
#include "common/logging/log.h"
#include "common/string_util.h"
#include "core/core.h"
#include "core/file_sys/common_funcs.h"
#include "core/file_sys/content_archive.h"
#include "core/file_sys/control_metadata.h"
#include "core/file_sys/ips_layer.h"
@@ -30,7 +31,6 @@ namespace FileSys {
namespace {
constexpr u32 SINGLE_BYTE_MODULUS = 0x100;
constexpr u64 DLC_BASE_TITLE_ID_MASK = 0xFFFFFFFFFFFFE000;
constexpr std::array<const char*, 14> EXEFS_FILE_NAMES{
"main", "main.npdm", "rtld", "sdk", "subsdk0", "subsdk1", "subsdk2",
@@ -532,7 +532,7 @@ PatchManager::PatchVersionNames PatchManager::GetPatchVersionNames(VirtualFile u
dlc_match.reserve(dlc_entries.size());
std::copy_if(dlc_entries.begin(), dlc_entries.end(), std::back_inserter(dlc_match),
[this](const ContentProviderEntry& entry) {
return (entry.title_id & DLC_BASE_TITLE_ID_MASK) == title_id &&
return GetBaseTitleID(entry.title_id) == title_id &&
content_provider.GetEntry(entry)->GetStatus() ==
Loader::ResultStatus::Success;
});
+22
View File
@@ -7,6 +7,7 @@
#include "common/common_types.h"
#include "common/logging/log.h"
#include "core/file_sys/card_image.h"
#include "core/file_sys/common_funcs.h"
#include "core/file_sys/content_archive.h"
#include "core/file_sys/nca_metadata.h"
#include "core/file_sys/patch_manager.h"
@@ -47,6 +48,27 @@ ResultVal<VirtualFile> RomFSFactory::OpenCurrentProcess(u64 current_process_titl
patch_manager.PatchRomFS(file, ivfc_offset, ContentRecordType::Program, update_raw));
}
ResultVal<VirtualFile> RomFSFactory::OpenPatchedRomFS(u64 title_id, ContentRecordType type) const {
auto nca = content_provider.GetEntry(title_id, type);
if (nca == nullptr) {
// TODO: Find the right error code to use here
return RESULT_UNKNOWN;
}
const PatchManager patch_manager{title_id, filesystem_controller, content_provider};
return MakeResult<VirtualFile>(
patch_manager.PatchRomFS(nca->GetRomFS(), nca->GetBaseIVFCOffset(), type));
}
ResultVal<VirtualFile> RomFSFactory::OpenPatchedRomFSWithProgramIndex(
u64 title_id, u8 program_index, ContentRecordType type) const {
const auto res_title_id = GetBaseTitleIDWithProgramIndex(title_id, program_index);
return OpenPatchedRomFS(res_title_id, type);
}
ResultVal<VirtualFile> RomFSFactory::Open(u64 title_id, StorageId storage,
ContentRecordType type) const {
const std::shared_ptr<NCA> res = GetEntry(title_id, storage, type);
+4
View File
@@ -42,6 +42,10 @@ public:
void SetPackedUpdate(VirtualFile update_raw);
[[nodiscard]] ResultVal<VirtualFile> OpenCurrentProcess(u64 current_process_title_id) const;
[[nodiscard]] ResultVal<VirtualFile> OpenPatchedRomFS(u64 title_id,
ContentRecordType type) const;
[[nodiscard]] ResultVal<VirtualFile> OpenPatchedRomFSWithProgramIndex(
u64 title_id, u8 program_index, ContentRecordType type) const;
[[nodiscard]] ResultVal<VirtualFile> Open(u64 title_id, StorageId storage,
ContentRecordType type) const;
@@ -6,191 +6,356 @@
namespace FileSys::SystemArchive::SharedFontData {
const std::array<unsigned char, 2932> FONT_NINTENDO_EXTENDED{{
0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x80, 0x00, 0x03, 0x00, 0x70, 0x44, 0x53, 0x49, 0x47,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0b, 0x6c, 0x00, 0x00, 0x00, 0x08, 0x4f, 0x53, 0x2f, 0x32,
0x33, 0x86, 0x1d, 0x9b, 0x00, 0x00, 0x01, 0x78, 0x00, 0x00, 0x00, 0x60, 0x63, 0x6d, 0x61, 0x70,
0xc2, 0x06, 0x20, 0xde, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x63, 0x76, 0x74, 0x20,
0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x04, 0x2c, 0x00, 0x00, 0x00, 0x06, 0x66, 0x70, 0x67, 0x6d,
0x06, 0x59, 0x9c, 0x37, 0x00, 0x00, 0x02, 0xa0, 0x00, 0x00, 0x01, 0x73, 0x67, 0x61, 0x73, 0x70,
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x0b, 0x64, 0x00, 0x00, 0x00, 0x08, 0x67, 0x6c, 0x79, 0x66,
0x10, 0x31, 0x88, 0x00, 0x00, 0x00, 0x04, 0x34, 0x00, 0x00, 0x04, 0x64, 0x68, 0x65, 0x61, 0x64,
0x15, 0x9d, 0xef, 0x91, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x36, 0x68, 0x68, 0x65, 0x61,
0x09, 0x60, 0x03, 0x71, 0x00, 0x00, 0x01, 0x34, 0x00, 0x00, 0x00, 0x24, 0x68, 0x6d, 0x74, 0x78,
0x0d, 0x2e, 0x03, 0xa7, 0x00, 0x00, 0x01, 0xd8, 0x00, 0x00, 0x00, 0x26, 0x6c, 0x6f, 0x63, 0x61,
0x05, 0xc0, 0x04, 0x6c, 0x00, 0x00, 0x08, 0x98, 0x00, 0x00, 0x00, 0x1e, 0x6d, 0x61, 0x78, 0x70,
0x02, 0x1c, 0x00, 0x5f, 0x00, 0x00, 0x01, 0x58, 0x00, 0x00, 0x00, 0x20, 0x6e, 0x61, 0x6d, 0x65,
0x7c, 0xe0, 0x84, 0x5c, 0x00, 0x00, 0x08, 0xb8, 0x00, 0x00, 0x02, 0x09, 0x70, 0x6f, 0x73, 0x74,
0x47, 0x4e, 0x74, 0x19, 0x00, 0x00, 0x0a, 0xc4, 0x00, 0x00, 0x00, 0x9e, 0x70, 0x72, 0x65, 0x70,
0x1c, 0xfc, 0x7d, 0x9c, 0x00, 0x00, 0x04, 0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x01, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00, 0x7c, 0xc7, 0xb1, 0x63, 0x5f, 0x0f, 0x3c, 0xf5, 0x00, 0x1b, 0x03, 0xe8,
0x00, 0x00, 0x00, 0x00, 0xd9, 0x44, 0x2f, 0x5d, 0x00, 0x00, 0x00, 0x00, 0xd9, 0x45, 0x7b, 0x69,
0x00, 0x00, 0x00, 0x00, 0x03, 0xe6, 0x03, 0xe8, 0x00, 0x00, 0x00, 0x06, 0x00, 0x02, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0x84, 0xff, 0x83, 0x01, 0xf4, 0x03, 0xe8,
0x00, 0x00, 0x00, 0x00, 0x03, 0xe6, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x5e,
0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x03, 0x74, 0x01, 0x90, 0x00, 0x05,
0x00, 0x04, 0x00, 0xcd, 0x00, 0xcd, 0x00, 0x00, 0x01, 0x1f, 0x00, 0xcd, 0x00, 0xcd, 0x00, 0x00,
0x03, 0xc3, 0x00, 0x66, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
const std::array<unsigned char, 5584> FONT_NINTENDO_EXTENDED{{
0x00, 0x01, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x80, 0x00, 0x03, 0x00, 0x70, 0x46, 0x46, 0x54, 0x4D,
0x91, 0x11, 0xFE, 0x98, 0x00, 0x00, 0x15, 0xB4, 0x00, 0x00, 0x00, 0x1C, 0x4F, 0x53, 0x2F, 0x32,
0x34, 0x00, 0x1E, 0x15, 0x00, 0x00, 0x01, 0x78, 0x00, 0x00, 0x00, 0x60, 0x63, 0x6D, 0x61, 0x70,
0xE0, 0xDE, 0xE8, 0x03, 0x00, 0x00, 0x02, 0x14, 0x00, 0x00, 0x01, 0x62, 0x63, 0x76, 0x74, 0x20,
0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x05, 0x04, 0x00, 0x00, 0x00, 0x06, 0x66, 0x70, 0x67, 0x6D,
0x06, 0x59, 0x9C, 0x37, 0x00, 0x00, 0x03, 0x78, 0x00, 0x00, 0x01, 0x73, 0x67, 0x61, 0x73, 0x70,
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x15, 0xAC, 0x00, 0x00, 0x00, 0x08, 0x67, 0x6C, 0x79, 0x66,
0x03, 0x3B, 0xBA, 0xCD, 0x00, 0x00, 0x05, 0x40, 0x00, 0x00, 0x0D, 0x68, 0x68, 0x65, 0x61, 0x64,
0x18, 0x64, 0x83, 0x1F, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x36, 0x68, 0x68, 0x65, 0x61,
0x09, 0x9C, 0x03, 0x86, 0x00, 0x00, 0x01, 0x34, 0x00, 0x00, 0x00, 0x24, 0x68, 0x6D, 0x74, 0x78,
0x0A, 0x01, 0x00, 0xA4, 0x00, 0x00, 0x01, 0xD8, 0x00, 0x00, 0x00, 0x3A, 0x6C, 0x6F, 0x63, 0x61,
0x25, 0xD6, 0x22, 0x28, 0x00, 0x00, 0x05, 0x0C, 0x00, 0x00, 0x00, 0x32, 0x6D, 0x61, 0x78, 0x70,
0x02, 0x28, 0x00, 0x72, 0x00, 0x00, 0x01, 0x58, 0x00, 0x00, 0x00, 0x20, 0x6E, 0x61, 0x6D, 0x65,
0xDB, 0xC5, 0x42, 0x4D, 0x00, 0x00, 0x12, 0xA8, 0x00, 0x00, 0x01, 0xFE, 0x70, 0x6F, 0x73, 0x74,
0x29, 0x22, 0x77, 0xE5, 0x00, 0x00, 0x14, 0xA8, 0x00, 0x00, 0x01, 0x02, 0x70, 0x72, 0x65, 0x70,
0x1C, 0xFC, 0x7D, 0x9C, 0x00, 0x00, 0x04, 0xEC, 0x00, 0x00, 0x00, 0x16, 0x00, 0x01, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00, 0x72, 0x95, 0xA1, 0x24, 0x5F, 0x0F, 0x3C, 0xF5, 0x00, 0x0B, 0x04, 0x00,
0x00, 0x00, 0x00, 0x00, 0xD9, 0x44, 0x2F, 0x5D, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x01, 0x0F, 0xBD,
0x00, 0x00, 0xFF, 0x84, 0x04, 0x00, 0x03, 0x84, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0x9A, 0xFF, 0x80, 0x02, 0x00, 0x04, 0x00,
0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x71,
0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x03, 0xBA, 0x01, 0x90, 0x00, 0x05,
0x00, 0x04, 0x00, 0xD2, 0x00, 0xD2, 0x00, 0x00, 0x01, 0x26, 0x00, 0xD2, 0x00, 0xD2, 0x00, 0x00,
0x03, 0xDA, 0x00, 0x68, 0x02, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x00, 0xc0, 0x00, 0x00, 0xe0, 0xe9, 0x03, 0x84, 0xff, 0x83,
0x01, 0xf4, 0x02, 0xee, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe8,
0x02, 0xbc, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xfa, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x03, 0xe8, 0x00, 0xeb, 0x01, 0x21, 0x00, 0xff,
0x00, 0xff, 0x01, 0x3d, 0x01, 0x17, 0x00, 0x42, 0x00, 0x1c, 0x00, 0x3e, 0x00, 0x17, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x68, 0x00, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x1c, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x68, 0x00, 0x06, 0x00, 0x4c,
0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x00, 0xC0, 0x00, 0x0D, 0xE0, 0xE9, 0x03, 0x9A, 0xFF, 0x80,
0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
0x02, 0xCD, 0x00, 0x00, 0x00, 0x20, 0x00, 0x01, 0x04, 0x00, 0x00, 0xA4, 0x00, 0x00, 0x00, 0x00,
0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x04, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0a,
0x00, 0x08, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x20, 0xe0, 0xe9, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x20, 0xe0, 0xe0, 0xff, 0xff, 0x00, 0x01, 0xff, 0xf5,
0xff, 0xe3, 0x1f, 0x24, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xb8, 0x00, 0x00, 0x2c, 0x4b, 0xb8, 0x00, 0x09, 0x50, 0x58, 0xb1, 0x01, 0x01, 0x8e, 0x59, 0xb8,
0x01, 0xff, 0x85, 0xb8, 0x00, 0x44, 0x1d, 0xb9, 0x00, 0x09, 0x00, 0x03, 0x5f, 0x5e, 0x2d, 0xb8,
0x00, 0x01, 0x2c, 0x20, 0x20, 0x45, 0x69, 0x44, 0xb0, 0x01, 0x60, 0x2d, 0xb8, 0x00, 0x02, 0x2c,
0xb8, 0x00, 0x01, 0x2a, 0x21, 0x2d, 0xb8, 0x00, 0x03, 0x2c, 0x20, 0x46, 0xb0, 0x03, 0x25, 0x46,
0x52, 0x58, 0x23, 0x59, 0x20, 0x8a, 0x20, 0x8a, 0x49, 0x64, 0x8a, 0x20, 0x46, 0x20, 0x68, 0x61,
0x64, 0xb0, 0x04, 0x25, 0x46, 0x20, 0x68, 0x61, 0x64, 0x52, 0x58, 0x23, 0x65, 0x8a, 0x59, 0x2f,
0x20, 0xb0, 0x00, 0x53, 0x58, 0x69, 0x20, 0xb0, 0x00, 0x54, 0x58, 0x21, 0xb0, 0x40, 0x59, 0x1b,
0x69, 0x20, 0xb0, 0x00, 0x54, 0x58, 0x21, 0xb0, 0x40, 0x65, 0x59, 0x59, 0x3a, 0x2d, 0xb8, 0x00,
0x04, 0x2c, 0x20, 0x46, 0xb0, 0x04, 0x25, 0x46, 0x52, 0x58, 0x23, 0x8a, 0x59, 0x20, 0x46, 0x20,
0x6a, 0x61, 0x64, 0xb0, 0x04, 0x25, 0x46, 0x20, 0x6a, 0x61, 0x64, 0x52, 0x58, 0x23, 0x8a, 0x59,
0x2f, 0xfd, 0x2d, 0xb8, 0x00, 0x05, 0x2c, 0x4b, 0x20, 0xb0, 0x03, 0x26, 0x50, 0x58, 0x51, 0x58,
0xb0, 0x80, 0x44, 0x1b, 0xb0, 0x40, 0x44, 0x59, 0x1b, 0x21, 0x21, 0x20, 0x45, 0xb0, 0xc0, 0x50,
0x58, 0xb0, 0xc0, 0x44, 0x1b, 0x21, 0x59, 0x59, 0x2d, 0xb8, 0x00, 0x06, 0x2c, 0x20, 0x20, 0x45,
0x69, 0x44, 0xb0, 0x01, 0x60, 0x20, 0x20, 0x45, 0x7d, 0x69, 0x18, 0x44, 0xb0, 0x01, 0x60, 0x2d,
0xb8, 0x00, 0x07, 0x2c, 0xb8, 0x00, 0x06, 0x2a, 0x2d, 0xb8, 0x00, 0x08, 0x2c, 0x4b, 0x20, 0xb0,
0x03, 0x26, 0x53, 0x58, 0xb0, 0x40, 0x1b, 0xb0, 0x00, 0x59, 0x8a, 0x8a, 0x20, 0xb0, 0x03, 0x26,
0x53, 0x58, 0x23, 0x21, 0xb0, 0x80, 0x8a, 0x8a, 0x1b, 0x8a, 0x23, 0x59, 0x20, 0xb0, 0x03, 0x26,
0x53, 0x58, 0x23, 0x21, 0xb8, 0x00, 0xc0, 0x8a, 0x8a, 0x1b, 0x8a, 0x23, 0x59, 0x20, 0xb0, 0x03,
0x26, 0x53, 0x58, 0x23, 0x21, 0xb8, 0x01, 0x00, 0x8a, 0x8a, 0x1b, 0x8a, 0x23, 0x59, 0x20, 0xb0,
0x03, 0x26, 0x53, 0x58, 0x23, 0x21, 0xb8, 0x01, 0x40, 0x8a, 0x8a, 0x1b, 0x8a, 0x23, 0x59, 0x20,
0xb8, 0x00, 0x03, 0x26, 0x53, 0x58, 0xb0, 0x03, 0x25, 0x45, 0xb8, 0x01, 0x80, 0x50, 0x58, 0x23,
0x21, 0xb8, 0x01, 0x80, 0x23, 0x21, 0x1b, 0xb0, 0x03, 0x25, 0x45, 0x23, 0x21, 0x23, 0x21, 0x59,
0x1b, 0x21, 0x59, 0x44, 0x2d, 0xb8, 0x00, 0x09, 0x2c, 0x4b, 0x53, 0x58, 0x45, 0x44, 0x1b, 0x21,
0x21, 0x59, 0x2d, 0x00, 0xb8, 0x00, 0x00, 0x2b, 0x00, 0xba, 0x00, 0x01, 0x00, 0x01, 0x00, 0x07,
0x2b, 0xb8, 0x00, 0x00, 0x20, 0x45, 0x7d, 0x69, 0x18, 0x44, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x03, 0xe6, 0x03, 0xe8, 0x00, 0x06,
0x00, 0x00, 0x35, 0x01, 0x33, 0x15, 0x01, 0x23, 0x35, 0x03, 0x52, 0x94, 0xfc, 0xa6, 0x8c, 0x90,
0x03, 0x58, 0x86, 0xfc, 0xa0, 0x8e, 0x00, 0x00, 0x00, 0x02, 0x00, 0xeb, 0x00, 0xcc, 0x02, 0xfb,
0x03, 0x1e, 0x00, 0x08, 0x00, 0x0f, 0x00, 0x00, 0x01, 0x33, 0x13, 0x23, 0x27, 0x23, 0x07, 0x23,
0x13, 0x17, 0x07, 0x06, 0x15, 0x33, 0x27, 0x07, 0x01, 0xbc, 0x6d, 0xd2, 0x7c, 0x26, 0xcc, 0x26,
0x7c, 0xd1, 0x35, 0x40, 0x02, 0x89, 0x45, 0x02, 0x03, 0x1e, 0xfd, 0xae, 0x77, 0x77, 0x02, 0x52,
0x9b, 0xcc, 0x08, 0x04, 0xda, 0x02, 0x00, 0x00, 0x00, 0x03, 0x01, 0x21, 0x00, 0xcc, 0x02, 0xc5,
0x03, 0x1e, 0x00, 0x15, 0x00, 0x1f, 0x00, 0x2b, 0x00, 0x00, 0x25, 0x11, 0x33, 0x32, 0x1e, 0x02,
0x15, 0x14, 0x0e, 0x02, 0x07, 0x1e, 0x01, 0x15, 0x14, 0x0e, 0x02, 0x2b, 0x01, 0x13, 0x33, 0x32,
0x36, 0x35, 0x34, 0x26, 0x2b, 0x01, 0x1d, 0x01, 0x33, 0x32, 0x3e, 0x02, 0x35, 0x34, 0x26, 0x2b,
0x01, 0x15, 0x01, 0x21, 0xea, 0x25, 0x3f, 0x2e, 0x1a, 0x0e, 0x15, 0x1b, 0x0e, 0x2d, 0x2d, 0x1a,
0x2e, 0x3f, 0x25, 0xf8, 0x76, 0x62, 0x20, 0x2a, 0x28, 0x22, 0x62, 0x76, 0x10, 0x18, 0x11, 0x09,
0x22, 0x22, 0x74, 0xcc, 0x02, 0x52, 0x18, 0x2b, 0x3c, 0x24, 0x1d, 0x1f, 0x17, 0x17, 0x14, 0x0f,
0x48, 0x2f, 0x24, 0x3f, 0x2e, 0x1a, 0x01, 0x5b, 0x29, 0x20, 0x20, 0x2b, 0x94, 0xf8, 0x0e, 0x16,
0x1c, 0x0e, 0x1f, 0x31, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0x00, 0xcc, 0x02, 0xe7,
0x03, 0x1e, 0x00, 0x0c, 0x00, 0x00, 0x01, 0x33, 0x17, 0x37, 0x33, 0x03, 0x13, 0x23, 0x27, 0x07,
0x23, 0x13, 0x03, 0x01, 0x04, 0x86, 0x69, 0x69, 0x86, 0xa3, 0xa8, 0x88, 0x6c, 0x6c, 0x88, 0xa8,
0xa3, 0x03, 0x1e, 0xcb, 0xcb, 0xfe, 0xda, 0xfe, 0xd4, 0xcf, 0xcf, 0x01, 0x2c, 0x01, 0x26, 0x00,
0x00, 0x01, 0x00, 0xff, 0x00, 0xcc, 0x02, 0xe7, 0x03, 0x1e, 0x00, 0x0f, 0x00, 0x00, 0x01, 0x03,
0x33, 0x17, 0x32, 0x15, 0x1e, 0x01, 0x15, 0x1b, 0x01, 0x33, 0x03, 0x15, 0x23, 0x35, 0x01, 0xb8,
0xb9, 0x7e, 0x01, 0x01, 0x01, 0x03, 0x70, 0x75, 0x7f, 0xb9, 0x76, 0x01, 0xa3, 0x01, 0x7b, 0x01,
0x01, 0x01, 0x05, 0x02, 0xff, 0x00, 0x01, 0x0a, 0xfe, 0x85, 0xd7, 0xd7, 0x00, 0x01, 0x01, 0x3d,
0x00, 0xcc, 0x02, 0xa9, 0x03, 0x1e, 0x00, 0x06, 0x00, 0x00, 0x25, 0x11, 0x33, 0x11, 0x33, 0x15,
0x21, 0x01, 0x3d, 0x75, 0xf7, 0xfe, 0x94, 0xcc, 0x02, 0x52, 0xfe, 0x10, 0x62, 0x00, 0x00, 0x00,
0x00, 0x02, 0x01, 0x17, 0x00, 0xbc, 0x02, 0xcf, 0x03, 0x0e, 0x00, 0x15, 0x00, 0x21, 0x00, 0x00,
0x25, 0x11, 0x33, 0x32, 0x1e, 0x02, 0x1d, 0x01, 0x0e, 0x03, 0x1d, 0x01, 0x17, 0x15, 0x23, 0x27,
0x23, 0x15, 0x23, 0x13, 0x33, 0x32, 0x3e, 0x02, 0x35, 0x34, 0x26, 0x2b, 0x01, 0x15, 0x01, 0x17,
0xf4, 0x27, 0x40, 0x2e, 0x19, 0x01, 0x1f, 0x24, 0x1e, 0x78, 0x7d, 0x6a, 0x5c, 0x75, 0x76, 0x72,
0x12, 0x19, 0x11, 0x08, 0x26, 0x26, 0x6a, 0xbc, 0x02, 0x52, 0x1d, 0x31, 0x42, 0x25, 0x16, 0x18,
0x32, 0x2a, 0x1b, 0x02, 0x01, 0xef, 0x06, 0xd7, 0xd7, 0x01, 0x3f, 0x10, 0x1a, 0x1e, 0x0f, 0x23,
0x36, 0xb0, 0x00, 0x00, 0x00, 0x02, 0x00, 0x42, 0x00, 0xbc, 0x03, 0xa4, 0x03, 0x0e, 0x00, 0x0a,
0x00, 0x11, 0x00, 0x00, 0x13, 0x35, 0x21, 0x15, 0x01, 0x21, 0x15, 0x21, 0x35, 0x01, 0x21, 0x01,
0x11, 0x33, 0x11, 0x33, 0x15, 0x21, 0x42, 0x01, 0xa7, 0xfe, 0xeb, 0x01, 0x1b, 0xfe, 0x53, 0x01,
0x15, 0xfe, 0xeb, 0x01, 0xf7, 0x75, 0xf6, 0xfe, 0x95, 0x02, 0xac, 0x62, 0x45, 0xfe, 0x55, 0x62,
0x47, 0x01, 0xa9, 0xfe, 0x10, 0x02, 0x52, 0xfe, 0x10, 0x62, 0x00, 0x00, 0x00, 0x03, 0x00, 0x1c,
0x00, 0xbc, 0x03, 0xca, 0x03, 0x0e, 0x00, 0x0a, 0x00, 0x21, 0x00, 0x2f, 0x00, 0x00, 0x13, 0x35,
0x21, 0x15, 0x01, 0x21, 0x15, 0x21, 0x35, 0x01, 0x21, 0x01, 0x11, 0x33, 0x32, 0x1e, 0x02, 0x15,
0x14, 0x06, 0x07, 0x0e, 0x03, 0x15, 0x17, 0x15, 0x23, 0x27, 0x23, 0x15, 0x23, 0x13, 0x33, 0x32,
0x3e, 0x02, 0x35, 0x34, 0x2e, 0x02, 0x2b, 0x01, 0x15, 0x1c, 0x01, 0xa7, 0xfe, 0xeb, 0x01, 0x1b,
0xfe, 0x53, 0x01, 0x15, 0xfe, 0xeb, 0x01, 0xf7, 0xf3, 0x27, 0x41, 0x2d, 0x19, 0x1c, 0x20, 0x01,
0x0d, 0x0e, 0x0a, 0x78, 0x7d, 0x69, 0x5c, 0x75, 0x76, 0x71, 0x11, 0x1a, 0x12, 0x09, 0x0a, 0x14,
0x1d, 0x13, 0x69, 0x02, 0xac, 0x62, 0x45, 0xfe, 0x55, 0x62, 0x47, 0x01, 0xa9, 0xfe, 0x10, 0x02,
0x52, 0x1d, 0x31, 0x42, 0x25, 0x2b, 0x44, 0x1d, 0x01, 0x08, 0x09, 0x07, 0x01, 0xf1, 0x06, 0xd7,
0xd7, 0x01, 0x3f, 0x11, 0x19, 0x1f, 0x0e, 0x11, 0x20, 0x19, 0x0f, 0xb0, 0x00, 0x02, 0x00, 0x3e,
0x00, 0xb3, 0x03, 0xa8, 0x03, 0x17, 0x00, 0x3a, 0x00, 0x41, 0x00, 0x00, 0x13, 0x34, 0x3e, 0x02,
0x33, 0x32, 0x1e, 0x02, 0x15, 0x23, 0x27, 0x34, 0x27, 0x2e, 0x01, 0x23, 0x22, 0x0e, 0x02, 0x15,
0x14, 0x16, 0x15, 0x1e, 0x05, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x2e, 0x02, 0x35, 0x33, 0x1e,
0x01, 0x33, 0x32, 0x3e, 0x02, 0x35, 0x34, 0x2e, 0x04, 0x35, 0x01, 0x11, 0x33, 0x11, 0x33, 0x15,
0x21, 0x50, 0x24, 0x3b, 0x4a, 0x27, 0x28, 0x4b, 0x39, 0x22, 0x73, 0x01, 0x01, 0x08, 0x2b, 0x29,
0x10, 0x20, 0x19, 0x0f, 0x01, 0x0b, 0x35, 0x41, 0x46, 0x3b, 0x25, 0x23, 0x3a, 0x4b, 0x27, 0x2b,
0x50, 0x3f, 0x26, 0x74, 0x05, 0x34, 0x33, 0x10, 0x20, 0x1a, 0x11, 0x2c, 0x42, 0x4d, 0x42, 0x2c,
0x01, 0xef, 0x73, 0xf6, 0xfe, 0x97, 0x02, 0x70, 0x2a, 0x3f, 0x2a, 0x14, 0x18, 0x2e, 0x44, 0x2c,
0x02, 0x03, 0x01, 0x27, 0x27, 0x07, 0x10, 0x1a, 0x12, 0x02, 0x0b, 0x02, 0x1f, 0x22, 0x19, 0x17,
0x27, 0x3f, 0x34, 0x2c, 0x3e, 0x28, 0x13, 0x1a, 0x32, 0x48, 0x2e, 0x30, 0x30, 0x06, 0x0f, 0x1a,
0x13, 0x21, 0x27, 0x1e, 0x1b, 0x29, 0x3e, 0x31, 0xfe, 0x4c, 0x02, 0x53, 0xfe, 0x10, 0x63, 0x00,
0x00, 0x03, 0x00, 0x17, 0x00, 0xb3, 0x03, 0xce, 0x03, 0x17, 0x00, 0x38, 0x00, 0x4f, 0x00, 0x5d,
0x00, 0x00, 0x13, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x23, 0x27, 0x34, 0x23, 0x2e,
0x01, 0x23, 0x22, 0x0e, 0x02, 0x15, 0x14, 0x1e, 0x04, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x2e,
0x02, 0x35, 0x33, 0x1e, 0x01, 0x33, 0x32, 0x3e, 0x02, 0x35, 0x34, 0x26, 0x27, 0x2e, 0x03, 0x35,
0x01, 0x11, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x14, 0x06, 0x07, 0x30, 0x0e, 0x02, 0x31, 0x17, 0x15,
0x23, 0x27, 0x23, 0x15, 0x23, 0x13, 0x33, 0x32, 0x3e, 0x02, 0x35, 0x34, 0x2e, 0x02, 0x2b, 0x01,
0x15, 0x2a, 0x24, 0x3a, 0x4a, 0x26, 0x29, 0x4b, 0x39, 0x23, 0x73, 0x01, 0x01, 0x08, 0x2a, 0x2a,
0x10, 0x1f, 0x1a, 0x10, 0x2c, 0x42, 0x4d, 0x42, 0x2c, 0x23, 0x39, 0x4b, 0x27, 0x2b, 0x51, 0x3f,
0x27, 0x75, 0x05, 0x34, 0x33, 0x10, 0x20, 0x1a, 0x10, 0x1f, 0x1c, 0x25, 0x53, 0x47, 0x2e, 0x01,
0xed, 0xf3, 0x27, 0x41, 0x2d, 0x19, 0x1c, 0x20, 0x0c, 0x0e, 0x0c, 0x78, 0x7d, 0x68, 0x5d, 0x75,
0x76, 0x71, 0x11, 0x1a, 0x12, 0x09, 0x0a, 0x14, 0x1d, 0x13, 0x69, 0x02, 0x71, 0x2a, 0x3e, 0x2a,
0x14, 0x18, 0x2e, 0x44, 0x2c, 0x02, 0x02, 0x27, 0x29, 0x07, 0x11, 0x1a, 0x12, 0x1d, 0x24, 0x1c,
0x1d, 0x2b, 0x40, 0x32, 0x2c, 0x3f, 0x29, 0x13, 0x1a, 0x31, 0x49, 0x2e, 0x30, 0x30, 0x06, 0x0f,
0x19, 0x13, 0x1e, 0x22, 0x0b, 0x0e, 0x20, 0x2f, 0x43, 0x30, 0xfe, 0x4b, 0x02, 0x52, 0x1d, 0x32,
0x42, 0x25, 0x2c, 0x42, 0x1d, 0x08, 0x0a, 0x08, 0xf1, 0x06, 0xd7, 0xd7, 0x01, 0x3f, 0x11, 0x19,
0x1f, 0x0e, 0x11, 0x20, 0x19, 0x0f, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x12, 0x00, 0x12,
0x00, 0x12, 0x00, 0x32, 0x00, 0x72, 0x00, 0x8e, 0x00, 0xac, 0x00, 0xbe, 0x00, 0xf0, 0x01, 0x14,
0x01, 0x5c, 0x01, 0xb6, 0x02, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0xa2, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x02, 0x00, 0x07, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x2f,
0x00, 0x17, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x12, 0x00, 0x46, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x0d, 0x00, 0x58, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x06, 0x00, 0x12, 0x00, 0x65, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x01, 0x00, 0x20,
0x00, 0x77, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x97, 0x00, 0x03,
0x00, 0x01, 0x04, 0x09, 0x00, 0x03, 0x00, 0x5e, 0x00, 0xa5, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09,
0x00, 0x04, 0x00, 0x24, 0x01, 0x03, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x05, 0x00, 0x1a,
0x01, 0x27, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x06, 0x00, 0x24, 0x01, 0x41, 0x00, 0x03,
0x00, 0x01, 0x04, 0x09, 0x00, 0x11, 0x00, 0x02, 0x01, 0x65, 0x59, 0x75, 0x7a, 0x75, 0x4f, 0x53,
0x53, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x67, 0x75, 0x6c, 0x61,
0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x31, 0x2e, 0x30, 0x30, 0x30, 0x3b, 0x3b,
0x59, 0x75, 0x7a, 0x75, 0x4f, 0x53, 0x53, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e,
0x2d, 0x52, 0x3b, 0x32, 0x30, 0x31, 0x39, 0x3b, 0x46, 0x4c, 0x56, 0x49, 0x2d, 0x36, 0x31, 0x34,
0x59, 0x75, 0x7a, 0x75, 0x4f, 0x53, 0x53, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e,
0x20, 0x52, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x31, 0x2e, 0x30, 0x30, 0x30, 0x59,
0x75, 0x7a, 0x75, 0x4f, 0x53, 0x53, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x2d,
0x52, 0x00, 0x59, 0x00, 0x75, 0x00, 0x7a, 0x00, 0x75, 0x00, 0x4f, 0x00, 0x53, 0x00, 0x53, 0x00,
0x45, 0x00, 0x78, 0x00, 0x74, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00,
0x6e, 0x00, 0x52, 0x00, 0x65, 0x00, 0x67, 0x00, 0x75, 0x00, 0x6c, 0x00, 0x61, 0x00, 0x72, 0x00,
0x56, 0x00, 0x65, 0x00, 0x72, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00,
0x31, 0x00, 0x2e, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x3b, 0x00, 0x3b, 0x00, 0x59, 0x00,
0x75, 0x00, 0x7a, 0x00, 0x75, 0x00, 0x4f, 0x00, 0x53, 0x00, 0x53, 0x00, 0x45, 0x00, 0x78, 0x00,
0x74, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x2d, 0x00,
0x52, 0x00, 0x3b, 0x00, 0x32, 0x00, 0x30, 0x00, 0x31, 0x00, 0x39, 0x00, 0x3b, 0x00, 0x46, 0x00,
0x4c, 0x00, 0x56, 0x00, 0x49, 0x00, 0x2d, 0x00, 0x36, 0x00, 0x31, 0x00, 0x34, 0x00, 0x59, 0x00,
0x75, 0x00, 0x7a, 0x00, 0x75, 0x00, 0x4f, 0x00, 0x53, 0x00, 0x53, 0x00, 0x45, 0x00, 0x78, 0x00,
0x74, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00,
0x52, 0x00, 0x56, 0x00, 0x65, 0x00, 0x72, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00,
0x20, 0x00, 0x31, 0x00, 0x2e, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x59, 0x00, 0x75, 0x00,
0x7a, 0x00, 0x75, 0x00, 0x4f, 0x00, 0x53, 0x00, 0x53, 0x00, 0x45, 0x00, 0x78, 0x00, 0x74, 0x00,
0x65, 0x00, 0x6e, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x2d, 0x00, 0x52, 0x00,
0x52, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x9c, 0x00, 0x32,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1C,
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5C, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1C,
0x00, 0x04, 0x00, 0x40, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x08, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00,
0x00, 0x0D, 0x00, 0x20, 0xE0, 0xA9, 0xE0, 0xE9, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D,
0x00, 0x20, 0xE0, 0xA0, 0xE0, 0xE0, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xF5, 0xFF, 0xE3, 0x1F, 0x64,
0x1F, 0x2E, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02,
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x01, 0x02, 0x01, 0x03, 0x00, 0x03, 0x01, 0x04,
0x01, 0x05, 0x01, 0x06, 0x01, 0x07, 0x01, 0x08, 0x01, 0x09, 0x01, 0x0a, 0x01, 0x0b, 0x01, 0x0c,
0x01, 0x0d, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x30, 0x30, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x30,
0x30, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x45, 0x30, 0x45, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x45, 0x30,
0x45, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x45, 0x30, 0x45, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x45, 0x30,
0x45, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x45, 0x30, 0x45, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x45, 0x30,
0x45, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x45, 0x30, 0x45, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x45, 0x30,
0x45, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x45, 0x30, 0x45, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x45, 0x30,
0x45, 0x39, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0xff, 0xff, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB8, 0x00, 0x00, 0x2C, 0x4B, 0xB8, 0x00, 0x09,
0x50, 0x58, 0xB1, 0x01, 0x01, 0x8E, 0x59, 0xB8, 0x01, 0xFF, 0x85, 0xB8, 0x00, 0x44, 0x1D, 0xB9,
0x00, 0x09, 0x00, 0x03, 0x5F, 0x5E, 0x2D, 0xB8, 0x00, 0x01, 0x2C, 0x20, 0x20, 0x45, 0x69, 0x44,
0xB0, 0x01, 0x60, 0x2D, 0xB8, 0x00, 0x02, 0x2C, 0xB8, 0x00, 0x01, 0x2A, 0x21, 0x2D, 0xB8, 0x00,
0x03, 0x2C, 0x20, 0x46, 0xB0, 0x03, 0x25, 0x46, 0x52, 0x58, 0x23, 0x59, 0x20, 0x8A, 0x20, 0x8A,
0x49, 0x64, 0x8A, 0x20, 0x46, 0x20, 0x68, 0x61, 0x64, 0xB0, 0x04, 0x25, 0x46, 0x20, 0x68, 0x61,
0x64, 0x52, 0x58, 0x23, 0x65, 0x8A, 0x59, 0x2F, 0x20, 0xB0, 0x00, 0x53, 0x58, 0x69, 0x20, 0xB0,
0x00, 0x54, 0x58, 0x21, 0xB0, 0x40, 0x59, 0x1B, 0x69, 0x20, 0xB0, 0x00, 0x54, 0x58, 0x21, 0xB0,
0x40, 0x65, 0x59, 0x59, 0x3A, 0x2D, 0xB8, 0x00, 0x04, 0x2C, 0x20, 0x46, 0xB0, 0x04, 0x25, 0x46,
0x52, 0x58, 0x23, 0x8A, 0x59, 0x20, 0x46, 0x20, 0x6A, 0x61, 0x64, 0xB0, 0x04, 0x25, 0x46, 0x20,
0x6A, 0x61, 0x64, 0x52, 0x58, 0x23, 0x8A, 0x59, 0x2F, 0xFD, 0x2D, 0xB8, 0x00, 0x05, 0x2C, 0x4B,
0x20, 0xB0, 0x03, 0x26, 0x50, 0x58, 0x51, 0x58, 0xB0, 0x80, 0x44, 0x1B, 0xB0, 0x40, 0x44, 0x59,
0x1B, 0x21, 0x21, 0x20, 0x45, 0xB0, 0xC0, 0x50, 0x58, 0xB0, 0xC0, 0x44, 0x1B, 0x21, 0x59, 0x59,
0x2D, 0xB8, 0x00, 0x06, 0x2C, 0x20, 0x20, 0x45, 0x69, 0x44, 0xB0, 0x01, 0x60, 0x20, 0x20, 0x45,
0x7D, 0x69, 0x18, 0x44, 0xB0, 0x01, 0x60, 0x2D, 0xB8, 0x00, 0x07, 0x2C, 0xB8, 0x00, 0x06, 0x2A,
0x2D, 0xB8, 0x00, 0x08, 0x2C, 0x4B, 0x20, 0xB0, 0x03, 0x26, 0x53, 0x58, 0xB0, 0x40, 0x1B, 0xB0,
0x00, 0x59, 0x8A, 0x8A, 0x20, 0xB0, 0x03, 0x26, 0x53, 0x58, 0x23, 0x21, 0xB0, 0x80, 0x8A, 0x8A,
0x1B, 0x8A, 0x23, 0x59, 0x20, 0xB0, 0x03, 0x26, 0x53, 0x58, 0x23, 0x21, 0xB8, 0x00, 0xC0, 0x8A,
0x8A, 0x1B, 0x8A, 0x23, 0x59, 0x20, 0xB0, 0x03, 0x26, 0x53, 0x58, 0x23, 0x21, 0xB8, 0x01, 0x00,
0x8A, 0x8A, 0x1B, 0x8A, 0x23, 0x59, 0x20, 0xB0, 0x03, 0x26, 0x53, 0x58, 0x23, 0x21, 0xB8, 0x01,
0x40, 0x8A, 0x8A, 0x1B, 0x8A, 0x23, 0x59, 0x20, 0xB8, 0x00, 0x03, 0x26, 0x53, 0x58, 0xB0, 0x03,
0x25, 0x45, 0xB8, 0x01, 0x80, 0x50, 0x58, 0x23, 0x21, 0xB8, 0x01, 0x80, 0x23, 0x21, 0x1B, 0xB0,
0x03, 0x25, 0x45, 0x23, 0x21, 0x23, 0x21, 0x59, 0x1B, 0x21, 0x59, 0x44, 0x2D, 0xB8, 0x00, 0x09,
0x2C, 0x4B, 0x53, 0x58, 0x45, 0x44, 0x1B, 0x21, 0x21, 0x59, 0x2D, 0x00, 0xB8, 0x00, 0x00, 0x2B,
0x00, 0xBA, 0x00, 0x01, 0x00, 0x01, 0x00, 0x07, 0x2B, 0xB8, 0x00, 0x00, 0x20, 0x45, 0x7D, 0x69,
0x18, 0x44, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16,
0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x72, 0x00, 0xD4, 0x01, 0x28, 0x01, 0x6C, 0x01, 0x92,
0x01, 0xE4, 0x02, 0x2C, 0x02, 0x98, 0x03, 0x3C, 0x03, 0xD4, 0x04, 0x16, 0x04, 0x6E, 0x04, 0xB0,
0x04, 0xE2, 0x04, 0xFE, 0x05, 0x44, 0x05, 0x74, 0x05, 0xD2, 0x06, 0x30, 0x06, 0xB4, 0x00, 0x00,
0x00, 0x02, 0x00, 0xA4, 0xFF, 0xFF, 0x03, 0x5C, 0x03, 0x09, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00,
0x13, 0x11, 0x21, 0x11, 0x25, 0x21, 0x11, 0x21, 0xCD, 0x02, 0x66, 0xFD, 0x71, 0x02, 0xB8, 0xFD,
0x48, 0x02, 0xE0, 0xFD, 0x48, 0x02, 0xB8, 0x29, 0xFC, 0xF6, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
0xFF, 0x84, 0x04, 0x00, 0x03, 0x84, 0x00, 0x0F, 0x00, 0x1F, 0x00, 0x2E, 0x00, 0x39, 0x00, 0x00,
0x00, 0x22, 0x0E, 0x02, 0x14, 0x1E, 0x02, 0x32, 0x3E, 0x02, 0x34, 0x2E, 0x01, 0x24, 0x32, 0x1E,
0x02, 0x14, 0x0E, 0x02, 0x22, 0x2E, 0x02, 0x34, 0x3E, 0x01, 0x13, 0x12, 0x37, 0x33, 0x13, 0x12,
0x16, 0x07, 0x2F, 0x01, 0x0F, 0x01, 0x23, 0x22, 0x26, 0x25, 0x27, 0x26, 0x2F, 0x01, 0x16, 0x07,
0x06, 0x16, 0x37, 0x32, 0x02, 0x5E, 0xBC, 0xAA, 0x7C, 0x49, 0x49, 0x7C, 0xAA, 0xBC, 0xAA, 0x7C,
0x49, 0x49, 0x7C, 0xFE, 0x90, 0xD0, 0xBE, 0x89, 0x51, 0x51, 0x89, 0xBE, 0xD0, 0xBE, 0x89, 0x51,
0x51, 0x89, 0x24, 0x6F, 0x63, 0x72, 0x6C, 0x6B, 0x02, 0x3B, 0x3B, 0x2F, 0xDA, 0x2D, 0x39, 0x34,
0x05, 0x01, 0x55, 0x17, 0x07, 0x28, 0x05, 0x4C, 0x95, 0x01, 0x62, 0x0E, 0x20, 0x03, 0x51, 0x49,
0x7B, 0xAB, 0xBC, 0xAA, 0x7C, 0x49, 0x49, 0x7C, 0xAA, 0xBC, 0xAB, 0x7B, 0x7C, 0x51, 0x89, 0xBE,
0xD0, 0xBE, 0x89, 0x51, 0x51, 0x89, 0xBE, 0xD0, 0xBE, 0x89, 0xFD, 0x49, 0x01, 0x22, 0xF8, 0xFE,
0xF3, 0xFE, 0xF2, 0x02, 0x01, 0x01, 0x7C, 0x01, 0x7C, 0x02, 0xD6, 0x40, 0x13, 0x68, 0x0D, 0x33,
0x95, 0x01, 0x01, 0x01, 0x00, 0x05, 0x00, 0x00, 0xFF, 0x84, 0x04, 0x00, 0x03, 0x84, 0x00, 0x07,
0x00, 0x13, 0x00, 0x25, 0x00, 0x30, 0x00, 0x3A, 0x00, 0x00, 0x12, 0x10, 0x00, 0x20, 0x00, 0x10,
0x00, 0x20, 0x00, 0x10, 0x3E, 0x01, 0x20, 0x1E, 0x01, 0x10, 0x0E, 0x01, 0x20, 0x26, 0x01, 0x16,
0x17, 0x14, 0x0E, 0x01, 0x2B, 0x01, 0x11, 0x33, 0x16, 0x17, 0x16, 0x17, 0x16, 0x07, 0x06, 0x0F,
0x01, 0x36, 0x35, 0x34, 0x2E, 0x01, 0x27, 0x23, 0x15, 0x33, 0x32, 0x27, 0x32, 0x37, 0x36, 0x34,
0x27, 0x26, 0x27, 0x23, 0x15, 0x33, 0x01, 0x0F, 0x01, 0x7C, 0x01, 0x0F, 0xFE, 0xF1, 0xFE, 0x84,
0xFE, 0xBE, 0x89, 0xEC, 0x01, 0x16, 0xEC, 0x89, 0x89, 0xEC, 0xFE, 0xEA, 0xEC, 0x02, 0x0C, 0x64,
0x02, 0x51, 0x6C, 0xB6, 0x51, 0x86, 0x91, 0x1E, 0x3E, 0x21, 0x19, 0x03, 0x06, 0x3C, 0x5A, 0x47,
0x1C, 0x2E, 0x55, 0x49, 0x49, 0x4A, 0x6A, 0x75, 0x16, 0x20, 0x2E, 0x08, 0x4F, 0x4F, 0x02, 0x43,
0xFE, 0x83, 0xFE, 0xF1, 0x01, 0x0F, 0x01, 0x7D, 0x01, 0x0E, 0xFD, 0xA8, 0x01, 0x16, 0xEC, 0x89,
0x89, 0xEC, 0xFE, 0xEA, 0xEC, 0x89, 0x89, 0x01, 0x7C, 0x21, 0x60, 0x43, 0x52, 0x09, 0x02, 0x1D,
0x01, 0x04, 0x09, 0x33, 0x25, 0x2D, 0x44, 0x21, 0xC9, 0x06, 0x40, 0x1A, 0x24, 0x0B, 0x01, 0x91,
0xEA, 0x0A, 0x0F, 0x58, 0x0A, 0x02, 0x01, 0x7E, 0x00, 0x03, 0x00, 0x00, 0xFF, 0x84, 0x04, 0x00,
0x03, 0x84, 0x00, 0x07, 0x00, 0x13, 0x00, 0x30, 0x00, 0x00, 0x12, 0x10, 0x00, 0x20, 0x00, 0x10,
0x00, 0x20, 0x00, 0x10, 0x3E, 0x01, 0x20, 0x1E, 0x01, 0x10, 0x0E, 0x01, 0x20, 0x26, 0x36, 0x34,
0x3F, 0x01, 0x27, 0x26, 0x27, 0x33, 0x17, 0x16, 0x33, 0x36, 0x3F, 0x01, 0x33, 0x36, 0x14, 0x02,
0x16, 0x12, 0x14, 0x2B, 0x01, 0x27, 0x26, 0x06, 0x0F, 0x01, 0x23, 0x33, 0x01, 0x0F, 0x01, 0x7C,
0x01, 0x0F, 0xFE, 0xF1, 0xFE, 0x84, 0xFE, 0xBE, 0x89, 0xEC, 0x01, 0x16, 0xEC, 0x89, 0x89, 0xEC,
0xFE, 0xEA, 0xEC, 0x80, 0x5C, 0x5C, 0x51, 0x52, 0x05, 0x7F, 0x36, 0x36, 0x02, 0x01, 0x35, 0x34,
0x3F, 0x3E, 0xA7, 0x01, 0xB7, 0x41, 0x41, 0x3C, 0x3C, 0x03, 0x3C, 0x3B, 0x41, 0x02, 0x43, 0xFE,
0x83, 0xFE, 0xF1, 0x01, 0x0F, 0x01, 0x7D, 0x01, 0x0E, 0xFD, 0xA8, 0x01, 0x16, 0xEC, 0x89, 0x89,
0xEC, 0xFE, 0xEA, 0xEC, 0x89, 0x89, 0x65, 0x01, 0x8D, 0x8D, 0x7E, 0x7F, 0x06, 0x57, 0x57, 0x01,
0x56, 0x57, 0x01, 0x02, 0xFE, 0xFB, 0x04, 0xFE, 0xED, 0x01, 0x5E, 0x5E, 0x03, 0x5D, 0x5C, 0x00,
0x00, 0x03, 0x00, 0x00, 0xFF, 0x84, 0x04, 0x00, 0x03, 0x84, 0x00, 0x07, 0x00, 0x13, 0x00, 0x23,
0x00, 0x00, 0x00, 0x20, 0x00, 0x10, 0x00, 0x20, 0x00, 0x10, 0x00, 0x20, 0x1E, 0x01, 0x10, 0x0E,
0x01, 0x20, 0x2E, 0x01, 0x10, 0x36, 0x01, 0x35, 0x27, 0x2E, 0x01, 0x3B, 0x01, 0x17, 0x16, 0x36,
0x3F, 0x01, 0x33, 0x03, 0x15, 0x23, 0x02, 0xBE, 0xFE, 0x84, 0xFE, 0xF1, 0x01, 0x0F, 0x01, 0x7C,
0x01, 0x0F, 0xFD, 0xA8, 0x01, 0x16, 0xEC, 0x89, 0x89, 0xEC, 0xFE, 0xEA, 0xEC, 0x89, 0x89, 0x01,
0x43, 0x62, 0x62, 0x01, 0x3F, 0x3F, 0x40, 0x40, 0x02, 0x3E, 0x3D, 0x7C, 0xC6, 0x6C, 0x03, 0x51,
0xFE, 0xF2, 0xFE, 0x83, 0xFE, 0xF1, 0x01, 0x0F, 0x01, 0x7D, 0x01, 0x41, 0x89, 0xEC, 0xFE, 0xEA,
0xEC, 0x89, 0x89, 0xEC, 0x01, 0x16, 0xEC, 0xFD, 0xE4, 0x72, 0x9C, 0x9C, 0x01, 0x6C, 0x6B, 0x03,
0x6A, 0x6A, 0xFE, 0xC6, 0xE2, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0xFF, 0xAB, 0x04, 0x00,
0x03, 0x5D, 0x00, 0x06, 0x00, 0x0C, 0x00, 0x12, 0x00, 0x00, 0x01, 0x21, 0x22, 0x15, 0x30, 0x11,
0x21, 0x17, 0x21, 0x11, 0x10, 0x29, 0x01, 0x01, 0x11, 0x33, 0x11, 0x21, 0x15, 0x03, 0xCD, 0xFD,
0x5D, 0xF7, 0x03, 0x9A, 0x33, 0xFC, 0x00, 0x01, 0x2A, 0x02, 0xD6, 0xFD, 0x40, 0x6D, 0x01, 0x13,
0x03, 0x2A, 0xF7, 0xFD, 0xAB, 0x33, 0x02, 0x88, 0x01, 0x2A, 0xFD, 0x19, 0x02, 0x1D, 0xFE, 0x3E,
0x5B, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0xFF, 0xAB, 0x04, 0x00, 0x03, 0x5D, 0x00, 0x06,
0x00, 0x0C, 0x00, 0x27, 0x00, 0x32, 0x00, 0x00, 0x05, 0x11, 0x34, 0x23, 0x30, 0x21, 0x11, 0x07,
0x11, 0x21, 0x20, 0x19, 0x01, 0x25, 0x11, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x07,
0x06, 0x07, 0x06, 0x07, 0x1E, 0x02, 0x15, 0x07, 0x23, 0x27, 0x2E, 0x01, 0x2F, 0x01, 0x15, 0x13,
0x36, 0x35, 0x34, 0x27, 0x26, 0x27, 0x23, 0x15, 0x33, 0x36, 0x03, 0xCD, 0xF7, 0xFD, 0x5D, 0x33,
0x02, 0xD6, 0x01, 0x2A, 0xFD, 0x0D, 0x7B, 0x7B, 0x16, 0x4C, 0x21, 0x37, 0x09, 0x04, 0x06, 0x14,
0x6A, 0x0D, 0x01, 0x20, 0x30, 0x69, 0x3F, 0x40, 0x2B, 0x5A, 0x29, 0x30, 0x1A, 0x9F, 0x3E, 0x21,
0x11, 0x59, 0x52, 0x49, 0x49, 0x22, 0x02, 0x55, 0xF7, 0xFC, 0xB4, 0x33, 0x03, 0xB2, 0xFE, 0xD6,
0xFD, 0x78, 0xCB, 0x02, 0x1D, 0x01, 0x04, 0x14, 0x22, 0x47, 0x1E, 0x1B, 0x5C, 0x15, 0x02, 0x01,
0x14, 0x2F, 0xA8, 0x01, 0x02, 0x40, 0x86, 0x1B, 0x01, 0x01, 0xE3, 0x01, 0x3A, 0x08, 0x3C, 0x2B,
0x10, 0x08, 0x01, 0x8A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0xFF, 0xE5, 0x04, 0x00,
0x03, 0x23, 0x00, 0x09, 0x00, 0x11, 0x00, 0x26, 0x00, 0x32, 0x00, 0x00, 0x37, 0x21, 0x34, 0x10,
0x35, 0x34, 0x27, 0x21, 0x04, 0x11, 0x23, 0x10, 0x25, 0x21, 0x16, 0x15, 0x11, 0x21, 0x37, 0x35,
0x37, 0x36, 0x22, 0x2B, 0x01, 0x3D, 0x01, 0x3B, 0x01, 0x1D, 0x01, 0x0F, 0x01, 0x3B, 0x01, 0x1D,
0x01, 0x2B, 0x01, 0x25, 0x35, 0x3B, 0x01, 0x1D, 0x01, 0x3B, 0x01, 0x1D, 0x01, 0x2B, 0x01, 0x33,
0x03, 0x9A, 0x48, 0xFE, 0x1A, 0xFE, 0x94, 0x33, 0x01, 0x9F, 0x01, 0xE6, 0x7B, 0xFC, 0x00, 0xAE,
0x6C, 0x6C, 0x01, 0x5F, 0x60, 0x96, 0x96, 0x70, 0x71, 0x75, 0x75, 0xA7, 0xA6, 0x01, 0x84, 0x29,
0x29, 0x67, 0x67, 0x90, 0x90, 0x19, 0x6D, 0x01, 0xB5, 0x6D, 0x47, 0x01, 0x02, 0xFE, 0x96, 0x01,
0x9C, 0x03, 0x01, 0x7A, 0xFD, 0x3D, 0xC2, 0x26, 0x85, 0x85, 0x23, 0x22, 0x20, 0x20, 0x8A, 0x8B,
0x22, 0x23, 0xCB, 0xCB, 0xA8, 0xA9, 0x22, 0x23, 0x00, 0x05, 0x00, 0x00, 0xFF, 0xE5, 0x04, 0x00,
0x03, 0x23, 0x00, 0x08, 0x00, 0x10, 0x00, 0x2B, 0x00, 0x37, 0x00, 0x44, 0x00, 0x00, 0x37, 0x21,
0x11, 0x10, 0x25, 0x30, 0x21, 0x06, 0x15, 0x03, 0x11, 0x34, 0x37, 0x21, 0x04, 0x19, 0x01, 0x01,
0x35, 0x17, 0x32, 0x17, 0x16, 0x17, 0x16, 0x07, 0x06, 0x07, 0x06, 0x17, 0x16, 0x17, 0x16, 0x17,
0x16, 0x23, 0x2F, 0x01, 0x2E, 0x01, 0x2F, 0x01, 0x15, 0x23, 0x37, 0x32, 0x36, 0x37, 0x36, 0x35,
0x26, 0x27, 0x26, 0x2B, 0x01, 0x15, 0x05, 0x35, 0x37, 0x36, 0x34, 0x2B, 0x01, 0x35, 0x21, 0x15,
0x03, 0x17, 0x15, 0x33, 0x03, 0x9A, 0xFE, 0x94, 0xFE, 0x1A, 0x48, 0x33, 0x7B, 0x01, 0xE6, 0x01,
0x9F, 0xFE, 0x0A, 0x6A, 0x73, 0x16, 0x49, 0x10, 0x05, 0x04, 0x0E, 0x51, 0x09, 0x09, 0x20, 0x1E,
0x3C, 0x07, 0x01, 0x32, 0x31, 0x24, 0x39, 0x1F, 0x2B, 0x14, 0x52, 0x88, 0x36, 0x1A, 0x0E, 0x14,
0x0A, 0x24, 0x07, 0x3A, 0x39, 0xFE, 0x2B, 0x6C, 0x6C, 0x60, 0x60, 0x01, 0x2C, 0xE1, 0xEA, 0x19,
0x01, 0x6B, 0x01, 0x69, 0x03, 0x01, 0x47, 0xFD, 0x3D, 0x02, 0xC3, 0x7A, 0x01, 0x03, 0xFE, 0x64,
0xFE, 0x61, 0x01, 0x6A, 0xCD, 0x01, 0x04, 0x0D, 0x45, 0x16, 0x1F, 0x47, 0x10, 0x04, 0x06, 0x15,
0x2D, 0x5A, 0x10, 0x01, 0x01, 0x36, 0x55, 0x1E, 0x01, 0x01, 0xAC, 0xEC, 0x04, 0x07, 0x0A, 0x21,
0x2E, 0x04, 0x01, 0x69, 0xEC, 0x4A, 0x85, 0x85, 0x01, 0x45, 0x40, 0xFE, 0xEB, 0x01, 0x44, 0x00,
0x00, 0x04, 0x00, 0x00, 0x00, 0x46, 0x04, 0x00, 0x02, 0xC2, 0x00, 0x08, 0x00, 0x16, 0x00, 0x64,
0x00, 0x70, 0x00, 0x00, 0x25, 0x11, 0x21, 0x22, 0x07, 0x30, 0x15, 0x14, 0x33, 0x11, 0x21, 0x32,
0x15, 0x11, 0x14, 0x27, 0x21, 0x22, 0x26, 0x3D, 0x01, 0x34, 0x36, 0x13, 0x26, 0x27, 0x26, 0x27,
0x26, 0x35, 0x33, 0x36, 0x37, 0x36, 0x33, 0x16, 0x17, 0x16, 0x17, 0x16, 0x37, 0x36, 0x37, 0x36,
0x35, 0x34, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x34, 0x37, 0x36, 0x37,
0x36, 0x37, 0x36, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, 0x07, 0x22, 0x06, 0x23,
0x27, 0x26, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x07, 0x06, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16,
0x17, 0x16, 0x17, 0x16, 0x07, 0x06, 0x07, 0x06, 0x27, 0x37, 0x35, 0x3B, 0x01, 0x1D, 0x01, 0x3B,
0x01, 0x1D, 0x01, 0x2B, 0x01, 0x03, 0xCD, 0xFD, 0x0D, 0xA6, 0x01, 0xA7, 0x03, 0x0C, 0x1A, 0x1A,
0xFC, 0xF4, 0x5B, 0x7F, 0x7F, 0xD2, 0x3A, 0x1E, 0x17, 0x08, 0x03, 0x02, 0x10, 0x0D, 0x1F, 0x01,
0x02, 0x04, 0x0D, 0x2C, 0x10, 0x0F, 0x19, 0x0C, 0x09, 0x04, 0x16, 0x34, 0x24, 0x13, 0x1D, 0x0F,
0x09, 0x03, 0x01, 0x01, 0x09, 0x23, 0x10, 0x14, 0x30, 0x2C, 0x14, 0x0F, 0x0D, 0x08, 0x0B, 0x05,
0x02, 0x03, 0x03, 0x38, 0x03, 0x02, 0x03, 0x09, 0x0E, 0x23, 0x17, 0x0F, 0x11, 0x01, 0x01, 0x08,
0x0B, 0x34, 0x27, 0x13, 0x28, 0x10, 0x09, 0x01, 0x01, 0x10, 0x12, 0x25, 0x22, 0x2C, 0xEC, 0x22,
0x21, 0x55, 0x54, 0x76, 0x76, 0x7A, 0x02, 0x14, 0xB6, 0xA8, 0xB6, 0x02, 0x48, 0x1A, 0xFD, 0xB8,
0x1A, 0x01, 0x89, 0x60, 0xA8, 0x60, 0x8A, 0xFE, 0x16, 0x04, 0x20, 0x19, 0x27, 0x10, 0x01, 0x02,
0x01, 0x03, 0x05, 0x0C, 0x2B, 0x05, 0x02, 0x03, 0x04, 0x11, 0x0B, 0x0E, 0x0A, 0x07, 0x13, 0x0D,
0x0A, 0x08, 0x0D, 0x18, 0x0E, 0x11, 0x06, 0x19, 0x05, 0x29, 0x14, 0x09, 0x04, 0x0A, 0x0D, 0x06,
0x0A, 0x09, 0x0E, 0x10, 0x14, 0x0C, 0x07, 0x03, 0x02, 0x04, 0x11, 0x0A, 0x12, 0x08, 0x09, 0x0F,
0x0C, 0x08, 0x0C, 0x0D, 0x0A, 0x08, 0x10, 0x21, 0x12, 0x18, 0x1F, 0x1C, 0x1F, 0x0C, 0x0B, 0x02,
0xB1, 0xAC, 0x8F, 0x8F, 0x1D, 0x1D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x47, 0x04, 0x00,
0x02, 0xC2, 0x00, 0x08, 0x00, 0x16, 0x00, 0x2E, 0x00, 0x38, 0x00, 0x65, 0x00, 0x00, 0x01, 0x30,
0x21, 0x11, 0x21, 0x32, 0x37, 0x35, 0x26, 0x27, 0x32, 0x16, 0x1D, 0x01, 0x14, 0x06, 0x23, 0x21,
0x22, 0x35, 0x11, 0x34, 0x33, 0x01, 0x11, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x07, 0x06, 0x07,
0x17, 0x1E, 0x01, 0x1F, 0x01, 0x23, 0x22, 0x2E, 0x02, 0x23, 0x27, 0x15, 0x37, 0x32, 0x37, 0x36,
0x27, 0x2E, 0x01, 0x2B, 0x01, 0x15, 0x05, 0x26, 0x27, 0x37, 0x32, 0x3F, 0x01, 0x16, 0x17, 0x1E,
0x01, 0x37, 0x36, 0x27, 0x2E, 0x04, 0x37, 0x3E, 0x01, 0x33, 0x32, 0x17, 0x16, 0x17, 0x14, 0x06,
0x27, 0x26, 0x27, 0x26, 0x0E, 0x01, 0x1E, 0x02, 0x17, 0x16, 0x06, 0x07, 0x06, 0x07, 0x06, 0x03,
0x26, 0xFD, 0x0D, 0x02, 0xF3, 0xA6, 0x01, 0x01, 0xA6, 0x5B, 0x7F, 0x7F, 0x5B, 0xFC, 0xF4, 0x1A,
0x1A, 0x01, 0xE6, 0x4A, 0x47, 0x11, 0x41, 0x19, 0x22, 0x0B, 0x0C, 0x46, 0x04, 0x18, 0x1D, 0x1F,
0x17, 0x28, 0x28, 0x02, 0x50, 0x19, 0x20, 0x11, 0x26, 0x3C, 0x0D, 0x23, 0x08, 0x03, 0x1C, 0x41,
0x2A, 0xFE, 0x9E, 0x0E, 0x04, 0x02, 0x02, 0x1F, 0x1F, 0x03, 0x02, 0x0D, 0x4E, 0x14, 0x21, 0x07,
0x04, 0x1C, 0x5A, 0x2E, 0x1D, 0x01, 0x02, 0x46, 0x38, 0x4C, 0x20, 0x11, 0x03, 0x44, 0x01, 0x06,
0x0B, 0x17, 0x3E, 0x19, 0x0C, 0x17, 0x61, 0x16, 0x35, 0x03, 0x2D, 0x1F, 0x36, 0x5D, 0x02, 0x8E,
0xFD, 0xEC, 0xB6, 0xA8, 0xB6, 0x34, 0x8A, 0x60, 0xA8, 0x60, 0x89, 0x19, 0x02, 0x48, 0x1A, 0xFE,
0x1C, 0x01, 0x53, 0x01, 0x02, 0x1A, 0x23, 0x35, 0x3B, 0x0C, 0x08, 0x10, 0x28, 0x31, 0x26, 0x01,
0x79, 0x13, 0x01, 0x8E, 0xC3, 0x04, 0x09, 0x2C, 0x10, 0x0E, 0x57, 0x8F, 0x18, 0x1F, 0x04, 0x03,
0x03, 0x0D, 0x04, 0x28, 0x0E, 0x0D, 0x15, 0x1B, 0x0F, 0x0E, 0x17, 0x17, 0x2D, 0x1B, 0x2F, 0x2F,
0x2C, 0x17, 0x1E, 0x06, 0x04, 0x01, 0x1B, 0x09, 0x12, 0x09, 0x18, 0x19, 0x0E, 0x18, 0x0C, 0x1C,
0x76, 0x1C, 0x13, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0xFF, 0x84, 0x04, 0x00,
0x03, 0x84, 0x00, 0x0B, 0x00, 0x1B, 0x00, 0x25, 0x00, 0x00, 0x00, 0x20, 0x1E, 0x01, 0x10, 0x0E,
0x01, 0x20, 0x2E, 0x01, 0x10, 0x36, 0x13, 0x06, 0x16, 0x3B, 0x01, 0x3F, 0x01, 0x1F, 0x01, 0x32,
0x35, 0x26, 0x0B, 0x01, 0x23, 0x06, 0x17, 0x06, 0x07, 0x22, 0x37, 0x36, 0x37, 0x17, 0x16, 0x17,
0x01, 0x75, 0x01, 0x16, 0xEC, 0x89, 0x89, 0xEC, 0xFE, 0xEA, 0xEC, 0x89, 0x89, 0x75, 0x01, 0x04,
0x35, 0x39, 0x2D, 0xDA, 0x2F, 0x3B, 0x3A, 0x01, 0x6B, 0x6C, 0x72, 0x63, 0xE5, 0x06, 0x5E, 0x31,
0x01, 0x48, 0x01, 0x05, 0x0B, 0x0F, 0x03, 0x84, 0x89, 0xEC, 0xFE, 0xEA, 0xEC, 0x89, 0x89, 0xEC,
0x01, 0x16, 0xEC, 0xFD, 0x81, 0x02, 0x02, 0x7C, 0x01, 0x7C, 0x01, 0x02, 0x02, 0x01, 0x0D, 0x01,
0x0D, 0xF8, 0x4E, 0x01, 0x01, 0x02, 0xC7, 0x01, 0x0D, 0x1C, 0x28, 0x00, 0x00, 0x04, 0x00, 0x00,
0xFF, 0x84, 0x04, 0x00, 0x03, 0x84, 0x00, 0x0B, 0x00, 0x22, 0x00, 0x2D, 0x00, 0x38, 0x00, 0x00,
0x34, 0x10, 0x3E, 0x01, 0x20, 0x1E, 0x01, 0x10, 0x0E, 0x01, 0x20, 0x26, 0x13, 0x11, 0x33, 0x32,
0x37, 0x3E, 0x01, 0x35, 0x34, 0x27, 0x26, 0x27, 0x30, 0x37, 0x36, 0x37, 0x36, 0x27, 0x26, 0x27,
0x26, 0x27, 0x23, 0x01, 0x06, 0x2B, 0x01, 0x35, 0x33, 0x1E, 0x02, 0x15, 0x14, 0x27, 0x23, 0x35,
0x33, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x89, 0xEC, 0x01, 0x16, 0xEC, 0x89, 0x89, 0xEC,
0xFE, 0xEA, 0xEC, 0xAE, 0x51, 0xB7, 0x2A, 0x41, 0x51, 0x26, 0x19, 0x27, 0x0A, 0x3D, 0x05, 0x04,
0x1A, 0x22, 0x3D, 0x1D, 0x92, 0x86, 0x01, 0x0E, 0x0E, 0x4A, 0x49, 0x49, 0x54, 0x2F, 0x1C, 0xBF,
0x29, 0x4F, 0x4F, 0x08, 0x2E, 0x20, 0x16, 0xF9, 0x01, 0x16, 0xEC, 0x89, 0x89, 0xEC, 0xFE, 0xEA,
0xEC, 0x89, 0x89, 0x01, 0x6C, 0xFE, 0xF1, 0x03, 0x05, 0x53, 0x43, 0x3B, 0x23, 0x16, 0x0D, 0x06,
0x22, 0x43, 0x2C, 0x26, 0x32, 0x0A, 0x04, 0x01, 0xFE, 0x3F, 0x01, 0x91, 0x01, 0x0B, 0x23, 0x1B,
0x40, 0xE3, 0x7E, 0x01, 0x02, 0x0B, 0x2F, 0x27, 0x10, 0x0A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
0xFF, 0x84, 0x04, 0x00, 0x03, 0x84, 0x00, 0x0B, 0x00, 0x28, 0x00, 0x00, 0x34, 0x10, 0x3E, 0x01,
0x20, 0x1E, 0x01, 0x10, 0x0E, 0x01, 0x20, 0x26, 0x36, 0x14, 0x3B, 0x01, 0x37, 0x3E, 0x01, 0x1F,
0x01, 0x33, 0x32, 0x34, 0x02, 0x26, 0x12, 0x34, 0x07, 0x23, 0x07, 0x06, 0x07, 0x22, 0x2F, 0x01,
0x23, 0x16, 0x1F, 0x01, 0x07, 0x89, 0xEC, 0x01, 0x16, 0xEC, 0x89, 0x89, 0xEC, 0xFE, 0xEA, 0xEC,
0x80, 0x40, 0x41, 0x3B, 0x3C, 0x02, 0x3D, 0x3C, 0x41, 0x41, 0xB7, 0x01, 0xA7, 0x3E, 0x3F, 0x34,
0x35, 0x01, 0x01, 0x37, 0x36, 0x7F, 0x04, 0x53, 0x51, 0x5C, 0xF9, 0x01, 0x16, 0xEC, 0x89, 0x89,
0xEC, 0xFE, 0xEA, 0xEC, 0x89, 0x89, 0x66, 0x01, 0x5C, 0x5D, 0x03, 0x5E, 0x5E, 0x01, 0x01, 0x13,
0x04, 0x01, 0x05, 0x02, 0x01, 0x57, 0x56, 0x01, 0x57, 0x57, 0x06, 0x7F, 0x7E, 0x8D, 0x00, 0x00,
0x00, 0x02, 0x00, 0x00, 0xFF, 0x84, 0x04, 0x00, 0x03, 0x84, 0x00, 0x0B, 0x00, 0x1B, 0x00, 0x00,
0x00, 0x20, 0x1E, 0x01, 0x10, 0x0E, 0x01, 0x20, 0x2E, 0x01, 0x10, 0x36, 0x01, 0x15, 0x33, 0x35,
0x13, 0x23, 0x07, 0x0E, 0x01, 0x2F, 0x01, 0x23, 0x22, 0x14, 0x1F, 0x01, 0x01, 0x75, 0x01, 0x16,
0xEC, 0x89, 0x89, 0xEC, 0xFE, 0xEA, 0xEC, 0x89, 0x89, 0x01, 0x43, 0x6C, 0xC6, 0x7C, 0x3D, 0x3E,
0x03, 0x3F, 0x40, 0x3F, 0x3F, 0x63, 0x62, 0x03, 0x84, 0x89, 0xEC, 0xFE, 0xEA, 0xEC, 0x89, 0x89,
0xEC, 0x01, 0x16, 0xEC, 0xFD, 0xE4, 0x71, 0xE2, 0x01, 0x3A, 0x6A, 0x6A, 0x03, 0x6B, 0x6C, 0x01,
0x9C, 0x9C, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0xFF, 0xAD, 0x04, 0x00, 0x03, 0x5C, 0x00, 0x05,
0x00, 0x0B, 0x00, 0x00, 0x05, 0x21, 0x11, 0x10, 0x05, 0x21, 0x01, 0x21, 0x35, 0x21, 0x11, 0x23,
0x04, 0x00, 0xFC, 0x00, 0x01, 0x1F, 0x02, 0xE1, 0xFD, 0x40, 0x01, 0x80, 0xFE, 0xED, 0x6D, 0x53,
0x02, 0x90, 0x01, 0x1F, 0x01, 0xFD, 0x1B, 0x5B, 0x01, 0xC2, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
0xFF, 0xAD, 0x04, 0x00, 0x03, 0x5B, 0x00, 0x05, 0x00, 0x20, 0x00, 0x2B, 0x00, 0x00, 0x15, 0x11,
0x21, 0x20, 0x19, 0x01, 0x25, 0x33, 0x35, 0x17, 0x1E, 0x01, 0x1F, 0x01, 0x33, 0x37, 0x2E, 0x02,
0x27, 0x34, 0x37, 0x36, 0x37, 0x36, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x2B, 0x01, 0x05, 0x06,
0x2B, 0x01, 0x35, 0x33, 0x16, 0x17, 0x16, 0x15, 0x14, 0x02, 0xE1, 0x01, 0x1F, 0xFD, 0x0D, 0x6D,
0x1A, 0x30, 0x29, 0x5A, 0x2B, 0x40, 0x3F, 0x01, 0x69, 0x2E, 0x21, 0x0E, 0x6A, 0x14, 0x06, 0x04,
0x09, 0x37, 0x21, 0x4C, 0x16, 0x7B, 0x7B, 0x01, 0x0C, 0x0D, 0x49, 0x49, 0x52, 0x59, 0x11, 0x21,
0x53, 0x03, 0xAE, 0xFE, 0xE2, 0xFD, 0x70, 0xC9, 0xE3, 0x01, 0x01, 0x1B, 0x86, 0x40, 0x02, 0x01,
0xA9, 0x2E, 0x14, 0x01, 0x02, 0x14, 0x5D, 0x1B, 0x1E, 0x47, 0x22, 0x14, 0x04, 0x01, 0xE3, 0x02,
0x8A, 0x01, 0x08, 0x10, 0x2B, 0x3C, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0xFF, 0xEB, 0x04, 0x00,
0x03, 0x1E, 0x00, 0x08, 0x00, 0x15, 0x00, 0x1B, 0x00, 0x00, 0x05, 0x21, 0x11, 0x10, 0x21, 0x30,
0x21, 0x32, 0x15, 0x01, 0x21, 0x35, 0x23, 0x13, 0x35, 0x21, 0x15, 0x33, 0x32, 0x22, 0x0F, 0x01,
0x05, 0x21, 0x35, 0x23, 0x11, 0x23, 0x04, 0x00, 0xFC, 0x00, 0x01, 0x9A, 0x02, 0x00, 0x66, 0xFC,
0xAE, 0x01, 0x4D, 0xEA, 0xE1, 0xFE, 0xD4, 0x60, 0x60, 0x01, 0x6B, 0x6C, 0x01, 0x84, 0x01, 0x20,
0xCE, 0x52, 0x15, 0x01, 0x99, 0x01, 0x9A, 0x67, 0xFD, 0xCB, 0x45, 0x01, 0x15, 0x40, 0x45, 0x85,
0x85, 0x4B, 0x45, 0x01, 0x51, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0xFF, 0xEB, 0x04, 0x00,
0x03, 0x1E, 0x00, 0x07, 0x00, 0x22, 0x00, 0x2F, 0x00, 0x3C, 0x00, 0x00, 0x15, 0x11, 0x34, 0x37,
0x21, 0x20, 0x19, 0x01, 0x01, 0x15, 0x33, 0x35, 0x17, 0x1E, 0x01, 0x1F, 0x02, 0x32, 0x35, 0x26,
0x27, 0x26, 0x27, 0x26, 0x37, 0x36, 0x37, 0x36, 0x27, 0x26, 0x27, 0x26, 0x23, 0x27, 0x17, 0x30,
0x23, 0x35, 0x33, 0x32, 0x17, 0x16, 0x17, 0x14, 0x07, 0x0E, 0x01, 0x05, 0x21, 0x35, 0x27, 0x13,
0x35, 0x21, 0x15, 0x33, 0x32, 0x14, 0x0F, 0x01, 0x66, 0x02, 0x00, 0x01, 0x9A, 0xFE, 0x0A, 0x52,
0x14, 0x2B, 0x1F, 0x39, 0x24, 0x31, 0x31, 0x06, 0x3D, 0x1E, 0x20, 0x09, 0x09, 0x51, 0x0E, 0x04,
0x05, 0x10, 0x49, 0x16, 0x73, 0x6A, 0x88, 0x36, 0x39, 0x3A, 0x07, 0x24, 0x0A, 0x14, 0x0E, 0x1A,
0xFD, 0xBF, 0x01, 0x4D, 0xEA, 0xE1, 0xFE, 0xD4, 0x60, 0x60, 0x6C, 0x6C, 0x15, 0x02, 0xCC, 0x66,
0x01, 0xFE, 0x66, 0xFE, 0x67, 0x01, 0x64, 0xCD, 0xAC, 0x01, 0x01, 0x1E, 0x55, 0x36, 0x01, 0x01,
0x0F, 0x5B, 0x2E, 0x14, 0x06, 0x04, 0x10, 0x47, 0x1F, 0x16, 0x45, 0x0D, 0x04, 0x01, 0xAE, 0x69,
0x01, 0x04, 0x2E, 0x22, 0x09, 0x07, 0x04, 0xEC, 0x44, 0x01, 0x01, 0x15, 0x40, 0x45, 0x01, 0x85,
0x85, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x51, 0x04, 0x00, 0x02, 0xB7, 0x00, 0x08,
0x00, 0x37, 0x00, 0x3D, 0x00, 0x00, 0x13, 0x30, 0x21, 0x11, 0x21, 0x22, 0x3D, 0x01, 0x34, 0x05,
0x37, 0x34, 0x27, 0x26, 0x27, 0x26, 0x07, 0x06, 0x07, 0x0E, 0x01, 0x17, 0x1E, 0x01, 0x17, 0x16,
0x14, 0x07, 0x06, 0x26, 0x27, 0x26, 0x27, 0x22, 0x06, 0x07, 0x22, 0x17, 0x1E, 0x01, 0x17, 0x16,
0x37, 0x36, 0x27, 0x26, 0x27, 0x2E, 0x02, 0x37, 0x36, 0x33, 0x32, 0x1F, 0x02, 0x33, 0x35, 0x23,
0x11, 0x23, 0xCA, 0x03, 0x36, 0xFC, 0xCA, 0xCA, 0x01, 0xD8, 0x03, 0x02, 0x0C, 0x3C, 0x2D, 0x2F,
0x14, 0x10, 0x2D, 0x01, 0x35, 0x18, 0x58, 0x16, 0x04, 0x09, 0x15, 0x5B, 0x0D, 0x04, 0x02, 0x02,
0x28, 0x15, 0x01, 0x04, 0x08, 0x35, 0x3A, 0x63, 0x21, 0x11, 0x01, 0x03, 0x3F, 0x13, 0x5C, 0x12,
0x01, 0x02, 0x3C, 0x2E, 0x09, 0x02, 0xA3, 0xEC, 0xA9, 0x43, 0x02, 0xB7, 0xFD, 0x9A, 0xDB, 0xB0,
0xDB, 0xE5, 0x03, 0x07, 0x0C, 0x3A, 0x11, 0x0D, 0x0A, 0x04, 0x09, 0x1A, 0x70, 0x18, 0x0B, 0x18,
0x12, 0x07, 0x18, 0x0B, 0x1B, 0x0B, 0x2A, 0x0C, 0x05, 0x04, 0x02, 0x11, 0x27, 0x39, 0x04, 0x06,
0x39, 0x1E, 0x1E, 0x42, 0x19, 0x08, 0x17, 0x14, 0x0C, 0x20, 0x2D, 0x04, 0xF3, 0x3A, 0x01, 0x1E,
0x00, 0x04, 0x00, 0x00, 0x00, 0x51, 0x04, 0x00, 0x02, 0xB7, 0x00, 0x07, 0x00, 0x1F, 0x00, 0x2A,
0x00, 0x58, 0x00, 0x00, 0x01, 0x32, 0x1D, 0x01, 0x14, 0x23, 0x21, 0x11, 0x01, 0x33, 0x35, 0x17,
0x1E, 0x03, 0x3B, 0x01, 0x27, 0x2E, 0x01, 0x2F, 0x01, 0x36, 0x37, 0x36, 0x27, 0x26, 0x27, 0x26,
0x2B, 0x01, 0x17, 0x30, 0x23, 0x35, 0x33, 0x32, 0x16, 0x17, 0x16, 0x07, 0x06, 0x05, 0x16, 0x37,
0x36, 0x37, 0x3E, 0x01, 0x27, 0x2E, 0x03, 0x3E, 0x01, 0x17, 0x16, 0x17, 0x30, 0x37, 0x36, 0x35,
0x26, 0x27, 0x26, 0x27, 0x22, 0x06, 0x07, 0x06, 0x1E, 0x03, 0x17, 0x16, 0x07, 0x06, 0x26, 0x27,
0x26, 0x27, 0x07, 0x06, 0x23, 0x07, 0x16, 0x03, 0x36, 0xCA, 0xCA, 0xFC, 0xCA, 0x02, 0x00, 0x44,
0x11, 0x20, 0x19, 0x50, 0x02, 0x28, 0x28, 0x17, 0x1F, 0x1D, 0x18, 0x04, 0x46, 0x0C, 0x0B, 0x22,
0x19, 0x41, 0x10, 0x48, 0x4A, 0x6A, 0x26, 0x2A, 0x41, 0x1C, 0x03, 0x08, 0x23, 0x0D, 0xFE, 0x3C,
0x23, 0x5D, 0x36, 0x1F, 0x2D, 0x03, 0x35, 0x17, 0x60, 0x17, 0x0C, 0x19, 0x3E, 0x17, 0x0B, 0x06,
0x23, 0x22, 0x03, 0x11, 0x20, 0x4C, 0x38, 0x46, 0x02, 0x01, 0x1D, 0x2E, 0x5A, 0x1C, 0x04, 0x07,
0x21, 0x14, 0x4E, 0x0D, 0x01, 0x04, 0x1F, 0x1F, 0x02, 0x02, 0x04, 0x02, 0xB7, 0xDB, 0xB0, 0xDB,
0x02, 0x66, 0xFE, 0x27, 0x8E, 0x01, 0x01, 0x12, 0x79, 0x01, 0x26, 0x31, 0x28, 0x10, 0x08, 0x0C,
0x3B, 0x35, 0x23, 0x1A, 0x02, 0x01, 0x90, 0x57, 0x0E, 0x10, 0x2C, 0x09, 0x04, 0x8F, 0x3C, 0x02,
0x01, 0x13, 0x1C, 0x76, 0x1C, 0x0C, 0x18, 0x0E, 0x19, 0x18, 0x09, 0x12, 0x09, 0x1B, 0x01, 0x01,
0x07, 0x1F, 0x16, 0x2B, 0x01, 0x2F, 0x2F, 0x1B, 0x2D, 0x17, 0x17, 0x0E, 0x0F, 0x1B, 0x15, 0x0D,
0x0E, 0x28, 0x04, 0x0D, 0x03, 0x03, 0x04, 0x1F, 0x00, 0x00, 0x00, 0x0E, 0x00, 0xAE, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x2C, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x00, 0x10, 0x00, 0x64, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x07,
0x00, 0x85, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x10, 0x00, 0xAF, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x10, 0x00, 0xE2, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x05, 0x00, 0x0D, 0x01, 0x0F, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x10,
0x01, 0x3F, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x03,
0x00, 0x01, 0x04, 0x09, 0x00, 0x01, 0x00, 0x20, 0x00, 0x42, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09,
0x00, 0x02, 0x00, 0x0E, 0x00, 0x75, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x03, 0x00, 0x20,
0x00, 0x8D, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x04, 0x00, 0x20, 0x00, 0xC0, 0x00, 0x03,
0x00, 0x01, 0x04, 0x09, 0x00, 0x05, 0x00, 0x1A, 0x00, 0xF3, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09,
0x00, 0x06, 0x00, 0x20, 0x01, 0x1D, 0x00, 0x59, 0x00, 0x75, 0x00, 0x7A, 0x00, 0x75, 0x00, 0x20,
0x00, 0x45, 0x00, 0x6D, 0x00, 0x75, 0x00, 0x6C, 0x00, 0x61, 0x00, 0x74, 0x00, 0x6F, 0x00, 0x72,
0x00, 0x20, 0x00, 0x50, 0x00, 0x72, 0x00, 0x6F, 0x00, 0x6A, 0x00, 0x65, 0x00, 0x63, 0x00, 0x74,
0x00, 0x00, 0x59, 0x75, 0x7A, 0x75, 0x20, 0x45, 0x6D, 0x75, 0x6C, 0x61, 0x74, 0x6F, 0x72, 0x20,
0x50, 0x72, 0x6F, 0x6A, 0x65, 0x63, 0x74, 0x00, 0x00, 0x59, 0x00, 0x75, 0x00, 0x7A, 0x00, 0x75,
0x00, 0x4F, 0x00, 0x53, 0x00, 0x53, 0x00, 0x45, 0x00, 0x78, 0x00, 0x74, 0x00, 0x65, 0x00, 0x6E,
0x00, 0x73, 0x00, 0x69, 0x00, 0x6F, 0x00, 0x6E, 0x00, 0x00, 0x59, 0x75, 0x7A, 0x75, 0x4F, 0x53,
0x53, 0x45, 0x78, 0x74, 0x65, 0x6E, 0x73, 0x69, 0x6F, 0x6E, 0x00, 0x00, 0x52, 0x00, 0x65, 0x00,
0x67, 0x00, 0x75, 0x00, 0x6C, 0x00, 0x61, 0x00, 0x72, 0x00, 0x00, 0x52, 0x65, 0x67, 0x75, 0x6C,
0x61, 0x72, 0x00, 0x00, 0x59, 0x00, 0x75, 0x00, 0x7A, 0x00, 0x75, 0x00, 0x4F, 0x00, 0x53, 0x00,
0x53, 0x00, 0x45, 0x00, 0x78, 0x00, 0x74, 0x00, 0x65, 0x00, 0x6E, 0x00, 0x73, 0x00, 0x69, 0x00,
0x6F, 0x00, 0x6E, 0x00, 0x00, 0x59, 0x75, 0x7A, 0x75, 0x4F, 0x53, 0x53, 0x45, 0x78, 0x74, 0x65,
0x6E, 0x73, 0x69, 0x6F, 0x6E, 0x00, 0x00, 0x59, 0x00, 0x75, 0x00, 0x7A, 0x00, 0x75, 0x00, 0x4F,
0x00, 0x53, 0x00, 0x53, 0x00, 0x45, 0x00, 0x78, 0x00, 0x74, 0x00, 0x65, 0x00, 0x6E, 0x00, 0x73,
0x00, 0x69, 0x00, 0x6F, 0x00, 0x6E, 0x00, 0x00, 0x59, 0x75, 0x7A, 0x75, 0x4F, 0x53, 0x53, 0x45,
0x78, 0x74, 0x65, 0x6E, 0x73, 0x69, 0x6F, 0x6E, 0x00, 0x00, 0x56, 0x00, 0x65, 0x00, 0x72, 0x00,
0x73, 0x00, 0x69, 0x00, 0x6F, 0x00, 0x6E, 0x00, 0x20, 0x00, 0x31, 0x00, 0x2E, 0x00, 0x30, 0x00,
0x30, 0x00, 0x30, 0x00, 0x00, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x20, 0x31, 0x2E, 0x30,
0x30, 0x30, 0x00, 0x00, 0x59, 0x00, 0x75, 0x00, 0x7A, 0x00, 0x75, 0x00, 0x4F, 0x00, 0x53, 0x00,
0x53, 0x00, 0x45, 0x00, 0x78, 0x00, 0x74, 0x00, 0x65, 0x00, 0x6E, 0x00, 0x73, 0x00, 0x69, 0x00,
0x6F, 0x00, 0x6E, 0x00, 0x00, 0x59, 0x75, 0x7A, 0x75, 0x4F, 0x53, 0x53, 0x45, 0x78, 0x74, 0x65,
0x6E, 0x73, 0x69, 0x6F, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xDD, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x01, 0x02, 0x01, 0x03,
0x00, 0x03, 0x01, 0x04, 0x01, 0x05, 0x01, 0x06, 0x01, 0x07, 0x01, 0x08, 0x01, 0x09, 0x01, 0x0A,
0x01, 0x0B, 0x01, 0x0C, 0x01, 0x0D, 0x01, 0x0E, 0x01, 0x0F, 0x01, 0x10, 0x01, 0x11, 0x01, 0x12,
0x01, 0x13, 0x01, 0x14, 0x01, 0x15, 0x01, 0x16, 0x01, 0x17, 0x07, 0x75, 0x6E, 0x69, 0x30, 0x30,
0x30, 0x30, 0x07, 0x75, 0x6E, 0x69, 0x30, 0x30, 0x30, 0x44, 0x07, 0x75, 0x6E, 0x69, 0x45, 0x30,
0x41, 0x30, 0x07, 0x75, 0x6E, 0x69, 0x45, 0x30, 0x41, 0x31, 0x07, 0x75, 0x6E, 0x69, 0x45, 0x30,
0x41, 0x32, 0x07, 0x75, 0x6E, 0x69, 0x45, 0x30, 0x41, 0x33, 0x07, 0x75, 0x6E, 0x69, 0x45, 0x30,
0x41, 0x34, 0x07, 0x75, 0x6E, 0x69, 0x45, 0x30, 0x41, 0x35, 0x07, 0x75, 0x6E, 0x69, 0x45, 0x30,
0x41, 0x36, 0x07, 0x75, 0x6E, 0x69, 0x45, 0x30, 0x41, 0x37, 0x07, 0x75, 0x6E, 0x69, 0x45, 0x30,
0x41, 0x38, 0x07, 0x75, 0x6E, 0x69, 0x45, 0x30, 0x41, 0x39, 0x07, 0x75, 0x6E, 0x69, 0x45, 0x30,
0x45, 0x30, 0x07, 0x75, 0x6E, 0x69, 0x45, 0x30, 0x45, 0x31, 0x07, 0x75, 0x6E, 0x69, 0x45, 0x30,
0x45, 0x32, 0x07, 0x75, 0x6E, 0x69, 0x45, 0x30, 0x45, 0x33, 0x07, 0x75, 0x6E, 0x69, 0x45, 0x30,
0x45, 0x34, 0x07, 0x75, 0x6E, 0x69, 0x45, 0x30, 0x45, 0x35, 0x07, 0x75, 0x6E, 0x69, 0x45, 0x30,
0x45, 0x36, 0x07, 0x75, 0x6E, 0x69, 0x45, 0x30, 0x45, 0x37, 0x07, 0x75, 0x6E, 0x69, 0x45, 0x30,
0x45, 0x38, 0x07, 0x75, 0x6E, 0x69, 0x45, 0x30, 0x45, 0x39, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01,
0xFF, 0xFF, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xDB, 0xCC, 0xBF, 0x7D,
0x00, 0x00, 0x00, 0x00, 0xD9, 0x44, 0x2F, 0x5D, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x01, 0x0F, 0xBD,
}};
} // namespace FileSys::SystemArchive::SharedFontData
@@ -8,6 +8,6 @@
namespace FileSys::SystemArchive::SharedFontData {
extern const std::array<unsigned char, 2932> FONT_NINTENDO_EXTENDED;
extern const std::array<unsigned char, 5584> FONT_NINTENDO_EXTENDED;
} // namespace FileSys::SystemArchive::SharedFontData
+16 -16
View File
@@ -203,7 +203,7 @@ std::string VfsFile::GetFullPath() const {
return GetContainingDirectory()->GetFullPath() + "/" + GetName();
}
std::shared_ptr<VfsFile> VfsDirectory::GetFileRelative(std::string_view path) const {
VirtualFile VfsDirectory::GetFileRelative(std::string_view path) const {
auto vec = Common::FS::SplitPathComponents(path);
vec.erase(std::remove_if(vec.begin(), vec.end(), [](const auto& str) { return str.empty(); }),
vec.end());
@@ -231,7 +231,7 @@ std::shared_ptr<VfsFile> VfsDirectory::GetFileRelative(std::string_view path) co
return dir->GetFile(vec.back());
}
std::shared_ptr<VfsFile> VfsDirectory::GetFileAbsolute(std::string_view path) const {
VirtualFile VfsDirectory::GetFileAbsolute(std::string_view path) const {
if (IsRoot()) {
return GetFileRelative(path);
}
@@ -239,7 +239,7 @@ std::shared_ptr<VfsFile> VfsDirectory::GetFileAbsolute(std::string_view path) co
return GetParentDirectory()->GetFileAbsolute(path);
}
std::shared_ptr<VfsDirectory> VfsDirectory::GetDirectoryRelative(std::string_view path) const {
VirtualDir VfsDirectory::GetDirectoryRelative(std::string_view path) const {
auto vec = Common::FS::SplitPathComponents(path);
vec.erase(std::remove_if(vec.begin(), vec.end(), [](const auto& str) { return str.empty(); }),
vec.end());
@@ -261,7 +261,7 @@ std::shared_ptr<VfsDirectory> VfsDirectory::GetDirectoryRelative(std::string_vie
return dir;
}
std::shared_ptr<VfsDirectory> VfsDirectory::GetDirectoryAbsolute(std::string_view path) const {
VirtualDir VfsDirectory::GetDirectoryAbsolute(std::string_view path) const {
if (IsRoot()) {
return GetDirectoryRelative(path);
}
@@ -269,14 +269,14 @@ std::shared_ptr<VfsDirectory> VfsDirectory::GetDirectoryAbsolute(std::string_vie
return GetParentDirectory()->GetDirectoryAbsolute(path);
}
std::shared_ptr<VfsFile> VfsDirectory::GetFile(std::string_view name) const {
VirtualFile VfsDirectory::GetFile(std::string_view name) const {
const auto& files = GetFiles();
const auto iter = std::find_if(files.begin(), files.end(),
[&name](const auto& file1) { return name == file1->GetName(); });
return iter == files.end() ? nullptr : *iter;
}
std::shared_ptr<VfsDirectory> VfsDirectory::GetSubdirectory(std::string_view name) const {
VirtualDir VfsDirectory::GetSubdirectory(std::string_view name) const {
const auto& subs = GetSubdirectories();
const auto iter = std::find_if(subs.begin(), subs.end(),
[&name](const auto& file1) { return name == file1->GetName(); });
@@ -301,7 +301,7 @@ std::size_t VfsDirectory::GetSize() const {
return file_total + subdir_total;
}
std::shared_ptr<VfsFile> VfsDirectory::CreateFileRelative(std::string_view path) {
VirtualFile VfsDirectory::CreateFileRelative(std::string_view path) {
auto vec = Common::FS::SplitPathComponents(path);
vec.erase(std::remove_if(vec.begin(), vec.end(), [](const auto& str) { return str.empty(); }),
vec.end());
@@ -324,7 +324,7 @@ std::shared_ptr<VfsFile> VfsDirectory::CreateFileRelative(std::string_view path)
return dir->CreateFileRelative(Common::FS::GetPathWithoutTop(path));
}
std::shared_ptr<VfsFile> VfsDirectory::CreateFileAbsolute(std::string_view path) {
VirtualFile VfsDirectory::CreateFileAbsolute(std::string_view path) {
if (IsRoot()) {
return CreateFileRelative(path);
}
@@ -332,7 +332,7 @@ std::shared_ptr<VfsFile> VfsDirectory::CreateFileAbsolute(std::string_view path)
return GetParentDirectory()->CreateFileAbsolute(path);
}
std::shared_ptr<VfsDirectory> VfsDirectory::CreateDirectoryRelative(std::string_view path) {
VirtualDir VfsDirectory::CreateDirectoryRelative(std::string_view path) {
auto vec = Common::FS::SplitPathComponents(path);
vec.erase(std::remove_if(vec.begin(), vec.end(), [](const auto& str) { return str.empty(); }),
vec.end());
@@ -355,7 +355,7 @@ std::shared_ptr<VfsDirectory> VfsDirectory::CreateDirectoryRelative(std::string_
return dir->CreateDirectoryRelative(Common::FS::GetPathWithoutTop(path));
}
std::shared_ptr<VfsDirectory> VfsDirectory::CreateDirectoryAbsolute(std::string_view path) {
VirtualDir VfsDirectory::CreateDirectoryAbsolute(std::string_view path) {
if (IsRoot()) {
return CreateDirectoryRelative(path);
}
@@ -446,27 +446,27 @@ bool ReadOnlyVfsDirectory::IsReadable() const {
return true;
}
std::shared_ptr<VfsDirectory> ReadOnlyVfsDirectory::CreateSubdirectory(std::string_view name) {
VirtualDir ReadOnlyVfsDirectory::CreateSubdirectory(std::string_view name) {
return nullptr;
}
std::shared_ptr<VfsFile> ReadOnlyVfsDirectory::CreateFile(std::string_view name) {
VirtualFile ReadOnlyVfsDirectory::CreateFile(std::string_view name) {
return nullptr;
}
std::shared_ptr<VfsFile> ReadOnlyVfsDirectory::CreateFileAbsolute(std::string_view path) {
VirtualFile ReadOnlyVfsDirectory::CreateFileAbsolute(std::string_view path) {
return nullptr;
}
std::shared_ptr<VfsFile> ReadOnlyVfsDirectory::CreateFileRelative(std::string_view path) {
VirtualFile ReadOnlyVfsDirectory::CreateFileRelative(std::string_view path) {
return nullptr;
}
std::shared_ptr<VfsDirectory> ReadOnlyVfsDirectory::CreateDirectoryAbsolute(std::string_view path) {
VirtualDir ReadOnlyVfsDirectory::CreateDirectoryAbsolute(std::string_view path) {
return nullptr;
}
std::shared_ptr<VfsDirectory> ReadOnlyVfsDirectory::CreateDirectoryRelative(std::string_view path) {
VirtualDir ReadOnlyVfsDirectory::CreateDirectoryRelative(std::string_view path) {
return nullptr;
}
+22 -22
View File
@@ -91,7 +91,7 @@ public:
// Resizes the file to new_size. Returns whether or not the operation was successful.
virtual bool Resize(std::size_t new_size) = 0;
// Gets a pointer to the directory containing this file, returning nullptr if there is none.
virtual std::shared_ptr<VfsDirectory> GetContainingDirectory() const = 0;
virtual VirtualDir GetContainingDirectory() const = 0;
// Returns whether or not the file can be written to.
virtual bool IsWritable() const = 0;
@@ -183,27 +183,27 @@ public:
// Retrives the file located at path as if the current directory was root. Returns nullptr if
// not found.
virtual std::shared_ptr<VfsFile> GetFileRelative(std::string_view path) const;
virtual VirtualFile GetFileRelative(std::string_view path) const;
// Calls GetFileRelative(path) on the root of the current directory.
virtual std::shared_ptr<VfsFile> GetFileAbsolute(std::string_view path) const;
virtual VirtualFile GetFileAbsolute(std::string_view path) const;
// Retrives the directory located at path as if the current directory was root. Returns nullptr
// if not found.
virtual std::shared_ptr<VfsDirectory> GetDirectoryRelative(std::string_view path) const;
virtual VirtualDir GetDirectoryRelative(std::string_view path) const;
// Calls GetDirectoryRelative(path) on the root of the current directory.
virtual std::shared_ptr<VfsDirectory> GetDirectoryAbsolute(std::string_view path) const;
virtual VirtualDir GetDirectoryAbsolute(std::string_view path) const;
// Returns a vector containing all of the files in this directory.
virtual std::vector<std::shared_ptr<VfsFile>> GetFiles() const = 0;
virtual std::vector<VirtualFile> GetFiles() const = 0;
// Returns the file with filename matching name. Returns nullptr if directory dosen't have a
// file with name.
virtual std::shared_ptr<VfsFile> GetFile(std::string_view name) const;
virtual VirtualFile GetFile(std::string_view name) const;
// Returns a vector containing all of the subdirectories in this directory.
virtual std::vector<std::shared_ptr<VfsDirectory>> GetSubdirectories() const = 0;
virtual std::vector<VirtualDir> GetSubdirectories() const = 0;
// Returns the directory with name matching name. Returns nullptr if directory dosen't have a
// directory with name.
virtual std::shared_ptr<VfsDirectory> GetSubdirectory(std::string_view name) const;
virtual VirtualDir GetSubdirectory(std::string_view name) const;
// Returns whether or not the directory can be written to.
virtual bool IsWritable() const = 0;
@@ -219,31 +219,31 @@ public:
virtual std::size_t GetSize() const;
// Returns the parent directory of this directory. Returns nullptr if this directory is root or
// has no parent.
virtual std::shared_ptr<VfsDirectory> GetParentDirectory() const = 0;
virtual VirtualDir GetParentDirectory() const = 0;
// Creates a new subdirectory with name name. Returns a pointer to the new directory or nullptr
// if the operation failed.
virtual std::shared_ptr<VfsDirectory> CreateSubdirectory(std::string_view name) = 0;
virtual VirtualDir CreateSubdirectory(std::string_view name) = 0;
// Creates a new file with name name. Returns a pointer to the new file or nullptr if the
// operation failed.
virtual std::shared_ptr<VfsFile> CreateFile(std::string_view name) = 0;
virtual VirtualFile CreateFile(std::string_view name) = 0;
// Creates a new file at the path relative to this directory. Also creates directories if
// they do not exist and is supported by this implementation. Returns nullptr on any failure.
virtual std::shared_ptr<VfsFile> CreateFileRelative(std::string_view path);
virtual VirtualFile CreateFileRelative(std::string_view path);
// Creates a new file at the path relative to root of this directory. Also creates directories
// if they do not exist and is supported by this implementation. Returns nullptr on any failure.
virtual std::shared_ptr<VfsFile> CreateFileAbsolute(std::string_view path);
virtual VirtualFile CreateFileAbsolute(std::string_view path);
// Creates a new directory at the path relative to this directory. Also creates directories if
// they do not exist and is supported by this implementation. Returns nullptr on any failure.
virtual std::shared_ptr<VfsDirectory> CreateDirectoryRelative(std::string_view path);
virtual VirtualDir CreateDirectoryRelative(std::string_view path);
// Creates a new directory at the path relative to root of this directory. Also creates
// directories if they do not exist and is supported by this implementation. Returns nullptr on
// any failure.
virtual std::shared_ptr<VfsDirectory> CreateDirectoryAbsolute(std::string_view path);
virtual VirtualDir CreateDirectoryAbsolute(std::string_view path);
// Deletes the subdirectory with the given name and returns true on success.
virtual bool DeleteSubdirectory(std::string_view name) = 0;
@@ -280,12 +280,12 @@ class ReadOnlyVfsDirectory : public VfsDirectory {
public:
bool IsWritable() const override;
bool IsReadable() const override;
std::shared_ptr<VfsDirectory> CreateSubdirectory(std::string_view name) override;
std::shared_ptr<VfsFile> CreateFile(std::string_view name) override;
std::shared_ptr<VfsFile> CreateFileAbsolute(std::string_view path) override;
std::shared_ptr<VfsFile> CreateFileRelative(std::string_view path) override;
std::shared_ptr<VfsDirectory> CreateDirectoryAbsolute(std::string_view path) override;
std::shared_ptr<VfsDirectory> CreateDirectoryRelative(std::string_view path) override;
VirtualDir CreateSubdirectory(std::string_view name) override;
VirtualFile CreateFile(std::string_view name) override;
VirtualFile CreateFileAbsolute(std::string_view path) override;
VirtualFile CreateFileRelative(std::string_view path) override;
VirtualDir CreateDirectoryAbsolute(std::string_view path) override;
VirtualDir CreateDirectoryRelative(std::string_view path) override;
bool DeleteSubdirectory(std::string_view name) override;
bool DeleteSubdirectoryRecursive(std::string_view name) override;
bool CleanSubdirectoryRecursive(std::string_view name) override;
+11 -7
View File
@@ -46,7 +46,7 @@ VirtualFile ConcatenatedVfsFile::MakeConcatenatedFile(std::vector<VirtualFile> f
if (files.size() == 1)
return files[0];
return std::shared_ptr<VfsFile>(new ConcatenatedVfsFile(std::move(files), std::move(name)));
return VirtualFile(new ConcatenatedVfsFile(std::move(files), std::move(name)));
}
VirtualFile ConcatenatedVfsFile::MakeConcatenatedFile(u8 filler_byte,
@@ -71,20 +71,23 @@ VirtualFile ConcatenatedVfsFile::MakeConcatenatedFile(u8 filler_byte,
if (files.begin()->first != 0)
files.emplace(0, std::make_shared<StaticVfsFile>(filler_byte, files.begin()->first));
return std::shared_ptr<VfsFile>(new ConcatenatedVfsFile(std::move(files), std::move(name)));
return VirtualFile(new ConcatenatedVfsFile(std::move(files), std::move(name)));
}
std::string ConcatenatedVfsFile::GetName() const {
if (files.empty())
if (files.empty()) {
return "";
if (!name.empty())
}
if (!name.empty()) {
return name;
}
return files.begin()->second->GetName();
}
std::size_t ConcatenatedVfsFile::GetSize() const {
if (files.empty())
if (files.empty()) {
return 0;
}
return files.rbegin()->first + files.rbegin()->second->GetSize();
}
@@ -92,9 +95,10 @@ bool ConcatenatedVfsFile::Resize(std::size_t new_size) {
return false;
}
std::shared_ptr<VfsDirectory> ConcatenatedVfsFile::GetContainingDirectory() const {
if (files.empty())
VirtualDir ConcatenatedVfsFile::GetContainingDirectory() const {
if (files.empty()) {
return nullptr;
}
return files.begin()->second->GetContainingDirectory();
}
+1 -1
View File
@@ -31,7 +31,7 @@ public:
std::string GetName() const override;
std::size_t GetSize() const override;
bool Resize(std::size_t new_size) override;
std::shared_ptr<VfsDirectory> GetContainingDirectory() const override;
VirtualDir GetContainingDirectory() const override;
bool IsWritable() const override;
bool IsReadable() const override;
std::size_t Read(u8* data, std::size_t length, std::size_t offset) const override;
+12 -12
View File
@@ -20,10 +20,10 @@ VirtualDir LayeredVfsDirectory::MakeLayeredDirectory(std::vector<VirtualDir> dir
if (dirs.size() == 1)
return dirs[0];
return std::shared_ptr<VfsDirectory>(new LayeredVfsDirectory(std::move(dirs), std::move(name)));
return VirtualDir(new LayeredVfsDirectory(std::move(dirs), std::move(name)));
}
std::shared_ptr<VfsFile> LayeredVfsDirectory::GetFileRelative(std::string_view path) const {
VirtualFile LayeredVfsDirectory::GetFileRelative(std::string_view path) const {
for (const auto& layer : dirs) {
const auto file = layer->GetFileRelative(path);
if (file != nullptr)
@@ -33,23 +33,23 @@ std::shared_ptr<VfsFile> LayeredVfsDirectory::GetFileRelative(std::string_view p
return nullptr;
}
std::shared_ptr<VfsDirectory> LayeredVfsDirectory::GetDirectoryRelative(
std::string_view path) const {
VirtualDir LayeredVfsDirectory::GetDirectoryRelative(std::string_view path) const {
std::vector<VirtualDir> out;
for (const auto& layer : dirs) {
auto dir = layer->GetDirectoryRelative(path);
if (dir != nullptr)
if (dir != nullptr) {
out.push_back(std::move(dir));
}
}
return MakeLayeredDirectory(std::move(out));
}
std::shared_ptr<VfsFile> LayeredVfsDirectory::GetFile(std::string_view name) const {
VirtualFile LayeredVfsDirectory::GetFile(std::string_view name) const {
return GetFileRelative(name);
}
std::shared_ptr<VfsDirectory> LayeredVfsDirectory::GetSubdirectory(std::string_view name) const {
VirtualDir LayeredVfsDirectory::GetSubdirectory(std::string_view name) const {
return GetDirectoryRelative(name);
}
@@ -57,7 +57,7 @@ std::string LayeredVfsDirectory::GetFullPath() const {
return dirs[0]->GetFullPath();
}
std::vector<std::shared_ptr<VfsFile>> LayeredVfsDirectory::GetFiles() const {
std::vector<VirtualFile> LayeredVfsDirectory::GetFiles() const {
std::vector<VirtualFile> out;
for (const auto& layer : dirs) {
for (const auto& file : layer->GetFiles()) {
@@ -72,7 +72,7 @@ std::vector<std::shared_ptr<VfsFile>> LayeredVfsDirectory::GetFiles() const {
return out;
}
std::vector<std::shared_ptr<VfsDirectory>> LayeredVfsDirectory::GetSubdirectories() const {
std::vector<VirtualDir> LayeredVfsDirectory::GetSubdirectories() const {
std::vector<std::string> names;
for (const auto& layer : dirs) {
for (const auto& sd : layer->GetSubdirectories()) {
@@ -101,15 +101,15 @@ std::string LayeredVfsDirectory::GetName() const {
return name.empty() ? dirs[0]->GetName() : name;
}
std::shared_ptr<VfsDirectory> LayeredVfsDirectory::GetParentDirectory() const {
VirtualDir LayeredVfsDirectory::GetParentDirectory() const {
return dirs[0]->GetParentDirectory();
}
std::shared_ptr<VfsDirectory> LayeredVfsDirectory::CreateSubdirectory(std::string_view name) {
VirtualDir LayeredVfsDirectory::CreateSubdirectory(std::string_view name) {
return nullptr;
}
std::shared_ptr<VfsFile> LayeredVfsDirectory::CreateFile(std::string_view name) {
VirtualFile LayeredVfsDirectory::CreateFile(std::string_view name) {
return nullptr;
}
+9 -9
View File
@@ -21,20 +21,20 @@ public:
/// Wrapper function to allow for more efficient handling of dirs.size() == 0, 1 cases.
static VirtualDir MakeLayeredDirectory(std::vector<VirtualDir> dirs, std::string name = "");
std::shared_ptr<VfsFile> GetFileRelative(std::string_view path) const override;
std::shared_ptr<VfsDirectory> GetDirectoryRelative(std::string_view path) const override;
std::shared_ptr<VfsFile> GetFile(std::string_view name) const override;
std::shared_ptr<VfsDirectory> GetSubdirectory(std::string_view name) const override;
VirtualFile GetFileRelative(std::string_view path) const override;
VirtualDir GetDirectoryRelative(std::string_view path) const override;
VirtualFile GetFile(std::string_view name) const override;
VirtualDir GetSubdirectory(std::string_view name) const override;
std::string GetFullPath() const override;
std::vector<std::shared_ptr<VfsFile>> GetFiles() const override;
std::vector<std::shared_ptr<VfsDirectory>> GetSubdirectories() const override;
std::vector<VirtualFile> GetFiles() const override;
std::vector<VirtualDir> GetSubdirectories() const override;
bool IsWritable() const override;
bool IsReadable() const override;
std::string GetName() const override;
std::shared_ptr<VfsDirectory> GetParentDirectory() const override;
std::shared_ptr<VfsDirectory> CreateSubdirectory(std::string_view name) override;
std::shared_ptr<VfsFile> CreateFile(std::string_view name) override;
VirtualDir GetParentDirectory() const override;
VirtualDir CreateSubdirectory(std::string_view name) override;
VirtualFile CreateFile(std::string_view name) override;
bool DeleteSubdirectory(std::string_view name) override;
bool DeleteFile(std::string_view name) override;
bool Rename(std::string_view name) override;
+2 -2
View File
@@ -9,7 +9,7 @@
namespace FileSys {
OffsetVfsFile::OffsetVfsFile(std::shared_ptr<VfsFile> file_, std::size_t size_, std::size_t offset_,
OffsetVfsFile::OffsetVfsFile(VirtualFile file_, std::size_t size_, std::size_t offset_,
std::string name_, VirtualDir parent_)
: file(file_), offset(offset_), size(size_), name(std::move(name_)),
parent(parent_ == nullptr ? file->GetContainingDirectory() : std::move(parent_)) {}
@@ -37,7 +37,7 @@ bool OffsetVfsFile::Resize(std::size_t new_size) {
return true;
}
std::shared_ptr<VfsDirectory> OffsetVfsFile::GetContainingDirectory() const {
VirtualDir OffsetVfsFile::GetContainingDirectory() const {
return parent;
}
+3 -3
View File
@@ -17,14 +17,14 @@ namespace FileSys {
// the size of this wrapper.
class OffsetVfsFile : public VfsFile {
public:
OffsetVfsFile(std::shared_ptr<VfsFile> file, std::size_t size, std::size_t offset = 0,
OffsetVfsFile(VirtualFile file, std::size_t size, std::size_t offset = 0,
std::string new_name = "", VirtualDir new_parent = nullptr);
~OffsetVfsFile() override;
std::string GetName() const override;
std::size_t GetSize() const override;
bool Resize(std::size_t new_size) override;
std::shared_ptr<VfsDirectory> GetContainingDirectory() const override;
VirtualDir GetContainingDirectory() const override;
bool IsWritable() const override;
bool IsReadable() const override;
std::size_t Read(u8* data, std::size_t length, std::size_t offset) const override;
@@ -42,7 +42,7 @@ public:
private:
std::size_t TrimToFit(std::size_t r_size, std::size_t r_offset) const;
std::shared_ptr<VfsFile> file;
VirtualFile file;
std::size_t offset;
std::size_t size;
std::string name;
+12 -12
View File
@@ -263,7 +263,7 @@ bool RealVfsFile::Resize(std::size_t new_size) {
return backing->Resize(new_size);
}
std::shared_ptr<VfsDirectory> RealVfsFile::GetContainingDirectory() const {
VirtualDir RealVfsFile::GetContainingDirectory() const {
return base.OpenDirectory(parent_path, perms);
}
@@ -352,7 +352,7 @@ RealVfsDirectory::RealVfsDirectory(RealVfsFilesystem& base_, const std::string&
RealVfsDirectory::~RealVfsDirectory() = default;
std::shared_ptr<VfsFile> RealVfsDirectory::GetFileRelative(std::string_view path) const {
VirtualFile RealVfsDirectory::GetFileRelative(std::string_view path) const {
const auto full_path = FS::SanitizePath(this->path + DIR_SEP + std::string(path));
if (!FS::Exists(full_path) || FS::IsDirectory(full_path)) {
return nullptr;
@@ -360,7 +360,7 @@ std::shared_ptr<VfsFile> RealVfsDirectory::GetFileRelative(std::string_view path
return base.OpenFile(full_path, perms);
}
std::shared_ptr<VfsDirectory> RealVfsDirectory::GetDirectoryRelative(std::string_view path) const {
VirtualDir RealVfsDirectory::GetDirectoryRelative(std::string_view path) const {
const auto full_path = FS::SanitizePath(this->path + DIR_SEP + std::string(path));
if (!FS::Exists(full_path) || !FS::IsDirectory(full_path)) {
return nullptr;
@@ -368,20 +368,20 @@ std::shared_ptr<VfsDirectory> RealVfsDirectory::GetDirectoryRelative(std::string
return base.OpenDirectory(full_path, perms);
}
std::shared_ptr<VfsFile> RealVfsDirectory::GetFile(std::string_view name) const {
VirtualFile RealVfsDirectory::GetFile(std::string_view name) const {
return GetFileRelative(name);
}
std::shared_ptr<VfsDirectory> RealVfsDirectory::GetSubdirectory(std::string_view name) const {
VirtualDir RealVfsDirectory::GetSubdirectory(std::string_view name) const {
return GetDirectoryRelative(name);
}
std::shared_ptr<VfsFile> RealVfsDirectory::CreateFileRelative(std::string_view path) {
VirtualFile RealVfsDirectory::CreateFileRelative(std::string_view path) {
const auto full_path = FS::SanitizePath(this->path + DIR_SEP + std::string(path));
return base.CreateFile(full_path, perms);
}
std::shared_ptr<VfsDirectory> RealVfsDirectory::CreateDirectoryRelative(std::string_view path) {
VirtualDir RealVfsDirectory::CreateDirectoryRelative(std::string_view path) {
const auto full_path = FS::SanitizePath(this->path + DIR_SEP + std::string(path));
return base.CreateDirectory(full_path, perms);
}
@@ -391,11 +391,11 @@ bool RealVfsDirectory::DeleteSubdirectoryRecursive(std::string_view name) {
return base.DeleteDirectory(full_path);
}
std::vector<std::shared_ptr<VfsFile>> RealVfsDirectory::GetFiles() const {
std::vector<VirtualFile> RealVfsDirectory::GetFiles() const {
return IterateEntries<RealVfsFile, VfsFile>();
}
std::vector<std::shared_ptr<VfsDirectory>> RealVfsDirectory::GetSubdirectories() const {
std::vector<VirtualDir> RealVfsDirectory::GetSubdirectories() const {
return IterateEntries<RealVfsDirectory, VfsDirectory>();
}
@@ -411,7 +411,7 @@ std::string RealVfsDirectory::GetName() const {
return path_components.back();
}
std::shared_ptr<VfsDirectory> RealVfsDirectory::GetParentDirectory() const {
VirtualDir RealVfsDirectory::GetParentDirectory() const {
if (path_components.size() <= 1) {
return nullptr;
}
@@ -419,12 +419,12 @@ std::shared_ptr<VfsDirectory> RealVfsDirectory::GetParentDirectory() const {
return base.OpenDirectory(parent_path, perms);
}
std::shared_ptr<VfsDirectory> RealVfsDirectory::CreateSubdirectory(std::string_view name) {
VirtualDir RealVfsDirectory::CreateSubdirectory(std::string_view name) {
const std::string subdir_path = (path + DIR_SEP).append(name);
return base.CreateDirectory(subdir_path, perms);
}
std::shared_ptr<VfsFile> RealVfsDirectory::CreateFile(std::string_view name) {
VirtualFile RealVfsDirectory::CreateFile(std::string_view name) {
const std::string file_path = (path + DIR_SEP).append(name);
return base.CreateFile(file_path, perms);
}
+12 -12
View File
@@ -50,7 +50,7 @@ public:
std::string GetName() const override;
std::size_t GetSize() const override;
bool Resize(std::size_t new_size) override;
std::shared_ptr<VfsDirectory> GetContainingDirectory() const override;
VirtualDir GetContainingDirectory() const override;
bool IsWritable() const override;
bool IsReadable() const override;
std::size_t Read(u8* data, std::size_t length, std::size_t offset) const override;
@@ -79,21 +79,21 @@ class RealVfsDirectory : public VfsDirectory {
public:
~RealVfsDirectory() override;
std::shared_ptr<VfsFile> GetFileRelative(std::string_view path) const override;
std::shared_ptr<VfsDirectory> GetDirectoryRelative(std::string_view path) const override;
std::shared_ptr<VfsFile> GetFile(std::string_view name) const override;
std::shared_ptr<VfsDirectory> GetSubdirectory(std::string_view name) const override;
std::shared_ptr<VfsFile> CreateFileRelative(std::string_view path) override;
std::shared_ptr<VfsDirectory> CreateDirectoryRelative(std::string_view path) override;
VirtualFile GetFileRelative(std::string_view path) const override;
VirtualDir GetDirectoryRelative(std::string_view path) const override;
VirtualFile GetFile(std::string_view name) const override;
VirtualDir GetSubdirectory(std::string_view name) const override;
VirtualFile CreateFileRelative(std::string_view path) override;
VirtualDir CreateDirectoryRelative(std::string_view path) override;
bool DeleteSubdirectoryRecursive(std::string_view name) override;
std::vector<std::shared_ptr<VfsFile>> GetFiles() const override;
std::vector<std::shared_ptr<VfsDirectory>> GetSubdirectories() const override;
std::vector<VirtualFile> GetFiles() const override;
std::vector<VirtualDir> GetSubdirectories() const override;
bool IsWritable() const override;
bool IsReadable() const override;
std::string GetName() const override;
std::shared_ptr<VfsDirectory> GetParentDirectory() const override;
std::shared_ptr<VfsDirectory> CreateSubdirectory(std::string_view name) override;
std::shared_ptr<VfsFile> CreateFile(std::string_view name) override;
VirtualDir GetParentDirectory() const override;
VirtualDir CreateSubdirectory(std::string_view name) override;
VirtualFile CreateFile(std::string_view name) override;
bool DeleteSubdirectory(std::string_view name) override;
bool DeleteFile(std::string_view name) override;
bool Rename(std::string_view name) override;
+1 -1
View File
@@ -31,7 +31,7 @@ public:
return true;
}
std::shared_ptr<VfsDirectory> GetContainingDirectory() const override {
VirtualDir GetContainingDirectory() const override {
return parent;
}
+6 -6
View File
@@ -25,7 +25,7 @@ bool VectorVfsFile::Resize(size_t new_size) {
return true;
}
std::shared_ptr<VfsDirectory> VectorVfsFile::GetContainingDirectory() const {
VirtualDir VectorVfsFile::GetContainingDirectory() const {
return parent;
}
@@ -68,11 +68,11 @@ VectorVfsDirectory::VectorVfsDirectory(std::vector<VirtualFile> files_,
VectorVfsDirectory::~VectorVfsDirectory() = default;
std::vector<std::shared_ptr<VfsFile>> VectorVfsDirectory::GetFiles() const {
std::vector<VirtualFile> VectorVfsDirectory::GetFiles() const {
return files;
}
std::vector<std::shared_ptr<VfsDirectory>> VectorVfsDirectory::GetSubdirectories() const {
std::vector<VirtualDir> VectorVfsDirectory::GetSubdirectories() const {
return dirs;
}
@@ -88,7 +88,7 @@ std::string VectorVfsDirectory::GetName() const {
return name;
}
std::shared_ptr<VfsDirectory> VectorVfsDirectory::GetParentDirectory() const {
VirtualDir VectorVfsDirectory::GetParentDirectory() const {
return parent;
}
@@ -116,11 +116,11 @@ bool VectorVfsDirectory::Rename(std::string_view name_) {
return true;
}
std::shared_ptr<VfsDirectory> VectorVfsDirectory::CreateSubdirectory(std::string_view name) {
VirtualDir VectorVfsDirectory::CreateSubdirectory(std::string_view name) {
return nullptr;
}
std::shared_ptr<VfsFile> VectorVfsDirectory::CreateFile(std::string_view name) {
VirtualFile VectorVfsDirectory::CreateFile(std::string_view name) {
return nullptr;
}
+7 -7
View File
@@ -33,7 +33,7 @@ public:
return false;
}
std::shared_ptr<VfsDirectory> GetContainingDirectory() const override {
VirtualDir GetContainingDirectory() const override {
return parent;
}
@@ -82,7 +82,7 @@ public:
std::string GetName() const override;
std::size_t GetSize() const override;
bool Resize(std::size_t new_size) override;
std::shared_ptr<VfsDirectory> GetContainingDirectory() const override;
VirtualDir GetContainingDirectory() const override;
bool IsWritable() const override;
bool IsReadable() const override;
std::size_t Read(u8* data, std::size_t length, std::size_t offset) const override;
@@ -106,17 +106,17 @@ public:
VirtualDir parent = nullptr);
~VectorVfsDirectory() override;
std::vector<std::shared_ptr<VfsFile>> GetFiles() const override;
std::vector<std::shared_ptr<VfsDirectory>> GetSubdirectories() const override;
std::vector<VirtualFile> GetFiles() const override;
std::vector<VirtualDir> GetSubdirectories() const override;
bool IsWritable() const override;
bool IsReadable() const override;
std::string GetName() const override;
std::shared_ptr<VfsDirectory> GetParentDirectory() const override;
VirtualDir GetParentDirectory() const override;
bool DeleteSubdirectory(std::string_view name) override;
bool DeleteFile(std::string_view name) override;
bool Rename(std::string_view name) override;
std::shared_ptr<VfsDirectory> CreateSubdirectory(std::string_view name) override;
std::shared_ptr<VfsFile> CreateFile(std::string_view name) override;
VirtualDir CreateSubdirectory(std::string_view name) override;
VirtualFile CreateFile(std::string_view name) override;
virtual void AddFile(VirtualFile file);
virtual void AddDirectory(VirtualDir dir);
+3 -3
View File
@@ -152,11 +152,11 @@ NAXContentType NAX::GetContentType() const {
return type;
}
std::vector<std::shared_ptr<VfsFile>> NAX::GetFiles() const {
std::vector<VirtualFile> NAX::GetFiles() const {
return {dec_file};
}
std::vector<std::shared_ptr<VfsDirectory>> NAX::GetSubdirectories() const {
std::vector<VirtualDir> NAX::GetSubdirectories() const {
return {};
}
@@ -164,7 +164,7 @@ std::string NAX::GetName() const {
return file->GetName();
}
std::shared_ptr<VfsDirectory> NAX::GetParentDirectory() const {
VirtualDir NAX::GetParentDirectory() const {
return file->GetContainingDirectory();
}
+3 -3
View File
@@ -47,13 +47,13 @@ public:
NAXContentType GetContentType() const;
std::vector<std::shared_ptr<VfsFile>> GetFiles() const override;
std::vector<VirtualFile> GetFiles() const override;
std::vector<std::shared_ptr<VfsDirectory>> GetSubdirectories() const override;
std::vector<VirtualDir> GetSubdirectories() const override;
std::string GetName() const override;
std::shared_ptr<VfsDirectory> GetParentDirectory() const override;
VirtualDir GetParentDirectory() const override;
private:
Loader::ResultStatus Parse(std::string_view path);
+25 -35
View File
@@ -234,8 +234,7 @@ static ResultCode SetMemoryAttribute(Core::System& system, VAddr address, u64 si
static ResultCode SetMemoryAttribute32(Core::System& system, u32 address, u32 size, u32 mask,
u32 attribute) {
return SetMemoryAttribute(system, static_cast<VAddr>(address), static_cast<std::size_t>(size),
mask, attribute);
return SetMemoryAttribute(system, address, size, mask, attribute);
}
/// Maps a memory range into a different range.
@@ -255,8 +254,7 @@ static ResultCode MapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr
}
static ResultCode MapMemory32(Core::System& system, u32 dst_addr, u32 src_addr, u32 size) {
return MapMemory(system, static_cast<VAddr>(dst_addr), static_cast<VAddr>(src_addr),
static_cast<std::size_t>(size));
return MapMemory(system, dst_addr, src_addr, size);
}
/// Unmaps a region that was previously mapped with svcMapMemory
@@ -276,8 +274,7 @@ static ResultCode UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_ad
}
static ResultCode UnmapMemory32(Core::System& system, u32 dst_addr, u32 src_addr, u32 size) {
return UnmapMemory(system, static_cast<VAddr>(dst_addr), static_cast<VAddr>(src_addr),
static_cast<std::size_t>(size));
return UnmapMemory(system, dst_addr, src_addr, size);
}
/// Connect to an OS service given the port name, returns the handle to the port to out
@@ -531,8 +528,7 @@ static ResultCode ArbitrateLock(Core::System& system, Handle holding_thread_hand
static ResultCode ArbitrateLock32(Core::System& system, Handle holding_thread_handle,
u32 mutex_addr, Handle requesting_thread_handle) {
return ArbitrateLock(system, holding_thread_handle, static_cast<VAddr>(mutex_addr),
requesting_thread_handle);
return ArbitrateLock(system, holding_thread_handle, mutex_addr, requesting_thread_handle);
}
/// Unlock a mutex
@@ -555,7 +551,7 @@ static ResultCode ArbitrateUnlock(Core::System& system, VAddr mutex_addr) {
}
static ResultCode ArbitrateUnlock32(Core::System& system, u32 mutex_addr) {
return ArbitrateUnlock(system, static_cast<VAddr>(mutex_addr));
return ArbitrateUnlock(system, mutex_addr);
}
enum class BreakType : u32 {
@@ -677,7 +673,7 @@ static void Break(Core::System& system, u32 reason, u64 info1, u64 info2) {
}
static void Break32(Core::System& system, u32 reason, u32 info1, u32 info2) {
Break(system, reason, static_cast<u64>(info1), static_cast<u64>(info2));
Break(system, reason, info1, info2);
}
/// Used to output a message on a debug hardware unit - does nothing on a retail unit
@@ -948,7 +944,7 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, u64 ha
static ResultCode GetInfo32(Core::System& system, u32* result_low, u32* result_high, u32 sub_id_low,
u32 info_id, u32 handle, u32 sub_id_high) {
const u64 sub_id{static_cast<u64>(sub_id_low | (static_cast<u64>(sub_id_high) << 32))};
const u64 sub_id{u64{sub_id_low} | (u64{sub_id_high} << 32)};
u64 res_value{};
const ResultCode result{GetInfo(system, &res_value, info_id, handle, sub_id)};
@@ -1009,7 +1005,7 @@ static ResultCode MapPhysicalMemory(Core::System& system, VAddr addr, u64 size)
}
static ResultCode MapPhysicalMemory32(Core::System& system, u32 addr, u32 size) {
return MapPhysicalMemory(system, static_cast<VAddr>(addr), static_cast<std::size_t>(size));
return MapPhysicalMemory(system, addr, size);
}
/// Unmaps memory previously mapped via MapPhysicalMemory
@@ -1063,7 +1059,7 @@ static ResultCode UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size
}
static ResultCode UnmapPhysicalMemory32(Core::System& system, u32 addr, u32 size) {
return UnmapPhysicalMemory(system, static_cast<VAddr>(addr), static_cast<std::size_t>(size));
return UnmapPhysicalMemory(system, addr, size);
}
/// Sets the thread activity
@@ -1144,7 +1140,7 @@ static ResultCode GetThreadContext(Core::System& system, VAddr thread_context, H
}
static ResultCode GetThreadContext32(Core::System& system, u32 thread_context, Handle handle) {
return GetThreadContext(system, static_cast<VAddr>(thread_context), handle);
return GetThreadContext(system, thread_context, handle);
}
/// Gets the priority for the specified thread
@@ -1281,8 +1277,7 @@ static ResultCode MapSharedMemory(Core::System& system, Handle shared_memory_han
static ResultCode MapSharedMemory32(Core::System& system, Handle shared_memory_handle, u32 addr,
u32 size, u32 permissions) {
return MapSharedMemory(system, shared_memory_handle, static_cast<VAddr>(addr),
static_cast<std::size_t>(size), permissions);
return MapSharedMemory(system, shared_memory_handle, addr, size, permissions);
}
static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_address,
@@ -1552,8 +1547,7 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e
static ResultCode CreateThread32(Core::System& system, Handle* out_handle, u32 priority,
u32 entry_point, u32 arg, u32 stack_top, s32 processor_id) {
return CreateThread(system, out_handle, static_cast<VAddr>(entry_point), static_cast<u64>(arg),
static_cast<VAddr>(stack_top), priority, processor_id);
return CreateThread(system, out_handle, entry_point, arg, stack_top, priority, processor_id);
}
/// Starts the thread for the provided handle
@@ -1637,8 +1631,7 @@ static void SleepThread(Core::System& system, s64 nanoseconds) {
}
static void SleepThread32(Core::System& system, u32 nanoseconds_low, u32 nanoseconds_high) {
const s64 nanoseconds = static_cast<s64>(static_cast<u64>(nanoseconds_low) |
(static_cast<u64>(nanoseconds_high) << 32));
const auto nanoseconds = static_cast<s64>(u64{nanoseconds_low} | (u64{nanoseconds_high} << 32));
SleepThread(system, nanoseconds);
}
@@ -1724,10 +1717,8 @@ static ResultCode WaitProcessWideKeyAtomic(Core::System& system, VAddr mutex_add
static ResultCode WaitProcessWideKeyAtomic32(Core::System& system, u32 mutex_addr,
u32 condition_variable_addr, Handle thread_handle,
u32 nanoseconds_low, u32 nanoseconds_high) {
const s64 nanoseconds =
static_cast<s64>(nanoseconds_low | (static_cast<u64>(nanoseconds_high) << 32));
return WaitProcessWideKeyAtomic(system, static_cast<VAddr>(mutex_addr),
static_cast<VAddr>(condition_variable_addr), thread_handle,
const auto nanoseconds = static_cast<s64>(nanoseconds_low | (u64{nanoseconds_high} << 32));
return WaitProcessWideKeyAtomic(system, mutex_addr, condition_variable_addr, thread_handle,
nanoseconds);
}
@@ -1833,8 +1824,8 @@ static ResultCode WaitForAddress(Core::System& system, VAddr address, u32 type,
static ResultCode WaitForAddress32(Core::System& system, u32 address, u32 type, s32 value,
u32 timeout_low, u32 timeout_high) {
s64 timeout = static_cast<s64>(timeout_low | (static_cast<u64>(timeout_high) << 32));
return WaitForAddress(system, static_cast<VAddr>(address), type, value, timeout);
const auto timeout = static_cast<s64>(timeout_low | (u64{timeout_high} << 32));
return WaitForAddress(system, address, type, value, timeout);
}
// Signals to an address (via Address Arbiter)
@@ -1862,7 +1853,7 @@ static ResultCode SignalToAddress(Core::System& system, VAddr address, u32 type,
static ResultCode SignalToAddress32(Core::System& system, u32 address, u32 type, s32 value,
s32 num_to_wake) {
return SignalToAddress(system, static_cast<VAddr>(address), type, value, num_to_wake);
return SignalToAddress(system, address, type, value, num_to_wake);
}
static void KernelDebug([[maybe_unused]] Core::System& system,
@@ -1893,7 +1884,7 @@ static u64 GetSystemTick(Core::System& system) {
}
static void GetSystemTick32(Core::System& system, u32* time_low, u32* time_high) {
u64 time = GetSystemTick(system);
const auto time = GetSystemTick(system);
*time_low = static_cast<u32>(time);
*time_high = static_cast<u32>(time >> 32);
}
@@ -1984,8 +1975,7 @@ static ResultCode CreateTransferMemory(Core::System& system, Handle* handle, VAd
static ResultCode CreateTransferMemory32(Core::System& system, Handle* handle, u32 addr, u32 size,
u32 permissions) {
return CreateTransferMemory(system, handle, static_cast<VAddr>(addr),
static_cast<std::size_t>(size), permissions);
return CreateTransferMemory(system, handle, addr, size, permissions);
}
static ResultCode GetThreadCoreMask(Core::System& system, Handle thread_handle, u32* core,
@@ -2075,8 +2065,7 @@ static ResultCode SetThreadCoreMask(Core::System& system, Handle thread_handle,
static ResultCode SetThreadCoreMask32(Core::System& system, Handle thread_handle, u32 core,
u32 affinity_mask_low, u32 affinity_mask_high) {
const u64 affinity_mask =
static_cast<u64>(affinity_mask_low) | (static_cast<u64>(affinity_mask_high) << 32);
const auto affinity_mask = u64{affinity_mask_low} | (u64{affinity_mask_high} << 32);
return SetThreadCoreMask(system, thread_handle, core, affinity_mask);
}
@@ -2341,9 +2330,10 @@ static ResultCode GetThreadList(Core::System& system, u32* out_num_threads, VAdd
return RESULT_SUCCESS;
}
static ResultCode FlushProcessDataCache32(Core::System& system, Handle handle, u32 address,
u32 size) {
// Note(Blinkhawk): For emulation purposes of the data cache this is mostly a nope
static ResultCode FlushProcessDataCache32([[maybe_unused]] Core::System& system,
[[maybe_unused]] Handle handle,
[[maybe_unused]] u32 address, [[maybe_unused]] u32 size) {
// Note(Blinkhawk): For emulation purposes of the data cache this is mostly a no-op,
// as all emulation is done in the same cache level in host architecture, thus data cache
// does not need flushing.
LOG_DEBUG(Kernel_SVC, "called");
+79 -9
View File
@@ -7,6 +7,7 @@
#include <vector>
#include "common/logging/log.h"
#include "core/core.h"
#include "core/file_sys/common_funcs.h"
#include "core/file_sys/content_archive.h"
#include "core/file_sys/control_metadata.h"
#include "core/file_sys/nca_metadata.h"
@@ -23,11 +24,8 @@
namespace Service::AOC {
constexpr u64 DLC_BASE_TITLE_ID_MASK = 0xFFFFFFFFFFFFE000;
constexpr u64 DLC_BASE_TO_AOC_ID = 0x1000;
static bool CheckAOCTitleIDMatchesBase(u64 title_id, u64 base) {
return (title_id & DLC_BASE_TITLE_ID_MASK) == base;
return FileSys::GetBaseTitleID(title_id) == base;
}
static std::vector<u64> AccumulateAOCTitleIDs(Core::System& system) {
@@ -48,6 +46,62 @@ static std::vector<u64> AccumulateAOCTitleIDs(Core::System& system) {
return add_on_content;
}
class IPurchaseEventManager final : public ServiceFramework<IPurchaseEventManager> {
public:
explicit IPurchaseEventManager(Core::System& system_)
: ServiceFramework{system_, "IPurchaseEventManager"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &IPurchaseEventManager::SetDefaultDeliveryTarget, "SetDefaultDeliveryTarget"},
{1, &IPurchaseEventManager::SetDeliveryTarget, "SetDeliveryTarget"},
{2, &IPurchaseEventManager::GetPurchasedEventReadableHandle, "GetPurchasedEventReadableHandle"},
{3, nullptr, "PopPurchasedProductInfo"},
{4, nullptr, "PopPurchasedProductInfoWithUid"},
};
// clang-format on
RegisterHandlers(functions);
purchased_event = Kernel::WritableEvent::CreateEventPair(
system.Kernel(), "IPurchaseEventManager:PurchasedEvent");
}
private:
void SetDefaultDeliveryTarget(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto unknown_1 = rp.Pop<u64>();
[[maybe_unused]] const auto unknown_2 = ctx.ReadBuffer();
LOG_WARNING(Service_AOC, "(STUBBED) called, unknown_1={}", unknown_1);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void SetDeliveryTarget(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto unknown_1 = rp.Pop<u64>();
[[maybe_unused]] const auto unknown_2 = ctx.ReadBuffer();
LOG_WARNING(Service_AOC, "(STUBBED) called, unknown_1={}", unknown_1);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void GetPurchasedEventReadableHandle(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_AOC, "called");
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(purchased_event.readable);
}
Kernel::EventPair purchased_event;
};
AOC_U::AOC_U(Core::System& system_)
: ServiceFramework{system_, "aoc:u"}, add_on_content{AccumulateAOCTitleIDs(system)} {
// clang-format off
@@ -62,8 +116,8 @@ AOC_U::AOC_U(Core::System& system_)
{7, &AOC_U::PrepareAddOnContent, "PrepareAddOnContent"},
{8, &AOC_U::GetAddOnContentListChangedEvent, "GetAddOnContentListChangedEvent"},
{9, nullptr, "GetAddOnContentLostErrorCode"},
{100, nullptr, "CreateEcPurchasedEventManager"},
{101, nullptr, "CreatePermanentEcPurchasedEventManager"},
{100, &AOC_U::CreateEcPurchasedEventManager, "CreateEcPurchasedEventManager"},
{101, &AOC_U::CreatePermanentEcPurchasedEventManager, "CreatePermanentEcPurchasedEventManager"},
};
// clang-format on
@@ -123,11 +177,11 @@ void AOC_U::ListAddOnContent(Kernel::HLERequestContext& ctx) {
const auto& disabled = Settings::values.disabled_addons[current];
if (std::find(disabled.begin(), disabled.end(), "DLC") == disabled.end()) {
for (u64 content_id : add_on_content) {
if ((content_id & DLC_BASE_TITLE_ID_MASK) != current) {
if (FileSys::GetBaseTitleID(content_id) != current) {
continue;
}
out.push_back(static_cast<u32>(content_id & 0x7FF));
out.push_back(static_cast<u32>(FileSys::GetAOCID(content_id)));
}
}
@@ -169,7 +223,7 @@ void AOC_U::GetAddOnContentBaseId(Kernel::HLERequestContext& ctx) {
const auto res = pm.GetControlMetadata();
if (res.first == nullptr) {
rb.Push(title_id + DLC_BASE_TO_AOC_ID);
rb.Push(FileSys::GetAOCBaseTitleID(title_id));
return;
}
@@ -201,6 +255,22 @@ void AOC_U::GetAddOnContentListChangedEvent(Kernel::HLERequestContext& ctx) {
rb.PushCopyObjects(aoc_change_event.readable);
}
void AOC_U::CreateEcPurchasedEventManager(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_AOC, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IPurchaseEventManager>(system);
}
void AOC_U::CreatePermanentEcPurchasedEventManager(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_AOC, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IPurchaseEventManager>(system);
}
void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) {
std::make_shared<AOC_U>(system)->InstallAsService(service_manager);
}
+2
View File
@@ -27,6 +27,8 @@ private:
void GetAddOnContentBaseId(Kernel::HLERequestContext& ctx);
void PrepareAddOnContent(Kernel::HLERequestContext& ctx);
void GetAddOnContentListChangedEvent(Kernel::HLERequestContext& ctx);
void CreateEcPurchasedEventManager(Kernel::HLERequestContext& ctx);
void CreatePermanentEcPurchasedEventManager(Kernel::HLERequestContext& ctx);
std::vector<u64> add_on_content;
Kernel::EventPair aoc_change_event;
@@ -298,6 +298,31 @@ ResultVal<FileSys::VirtualFile> FileSystemController::OpenRomFSCurrentProcess()
return romfs_factory->OpenCurrentProcess(system.CurrentProcess()->GetTitleID());
}
ResultVal<FileSys::VirtualFile> FileSystemController::OpenPatchedRomFS(
u64 title_id, FileSys::ContentRecordType type) const {
LOG_TRACE(Service_FS, "Opening patched RomFS for title_id={:016X}", title_id);
if (romfs_factory == nullptr) {
// TODO: Find a better error code for this
return RESULT_UNKNOWN;
}
return romfs_factory->OpenPatchedRomFS(title_id, type);
}
ResultVal<FileSys::VirtualFile> FileSystemController::OpenPatchedRomFSWithProgramIndex(
u64 title_id, u8 program_index, FileSys::ContentRecordType type) const {
LOG_TRACE(Service_FS, "Opening patched RomFS for title_id={:016X}, program_index={}", title_id,
program_index);
if (romfs_factory == nullptr) {
// TODO: Find a better error code for this
return RESULT_UNKNOWN;
}
return romfs_factory->OpenPatchedRomFSWithProgramIndex(title_id, program_index, type);
}
ResultVal<FileSys::VirtualFile> FileSystemController::OpenRomFS(
u64 title_id, FileSys::StorageId storage_id, FileSys::ContentRecordType type) const {
LOG_TRACE(Service_FS, "Opening RomFS for title_id={:016X}, storage_id={:02X}, type={:02X}",
@@ -66,6 +66,10 @@ public:
void SetPackedUpdate(FileSys::VirtualFile update_raw);
ResultVal<FileSys::VirtualFile> OpenRomFSCurrentProcess() const;
ResultVal<FileSys::VirtualFile> OpenPatchedRomFS(u64 title_id,
FileSys::ContentRecordType type) const;
ResultVal<FileSys::VirtualFile> OpenPatchedRomFSWithProgramIndex(
u64 title_id, u8 program_index, FileSys::ContentRecordType type) const;
ResultVal<FileSys::VirtualFile> OpenRomFS(u64 title_id, FileSys::StorageId storage_id,
FileSys::ContentRecordType type) const;
ResultVal<FileSys::VirtualDir> CreateSaveData(
+27 -1
View File
@@ -717,7 +717,7 @@ FSP_SRV::FSP_SRV(Core::System& system_)
{202, &FSP_SRV::OpenDataStorageByDataId, "OpenDataStorageByDataId"},
{203, &FSP_SRV::OpenPatchDataStorageByCurrentProcess, "OpenPatchDataStorageByCurrentProcess"},
{204, nullptr, "OpenDataFileSystemByProgramIndex"},
{205, nullptr, "OpenDataStorageByProgramIndex"},
{205, &FSP_SRV::OpenDataStorageWithProgramIndex, "OpenDataStorageWithProgramIndex"},
{400, nullptr, "OpenDeviceOperator"},
{500, nullptr, "OpenSdCardDetectionEventNotifier"},
{501, nullptr, "OpenGameCardDetectionEventNotifier"},
@@ -994,6 +994,32 @@ void FSP_SRV::OpenPatchDataStorageByCurrentProcess(Kernel::HLERequestContext& ct
rb.Push(FileSys::ERROR_ENTITY_NOT_FOUND);
}
void FSP_SRV::OpenDataStorageWithProgramIndex(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto program_index = rp.PopRaw<u8>();
LOG_DEBUG(Service_FS, "called, program_index={}", program_index);
auto romfs = fsc.OpenPatchedRomFSWithProgramIndex(
system.CurrentProcess()->GetTitleID(), program_index, FileSys::ContentRecordType::Program);
if (romfs.Failed()) {
// TODO: Find the right error code to use here
LOG_ERROR(Service_FS, "could not open storage with program_index={}", program_index);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_UNKNOWN);
return;
}
auto storage = std::make_shared<IStorage>(system, std::move(romfs.Unwrap()));
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IStorage>(std::move(storage));
}
void FSP_SRV::SetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
log_mode = rp.PopEnum<LogMode>();
@@ -49,6 +49,7 @@ private:
void OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx);
void OpenDataStorageByDataId(Kernel::HLERequestContext& ctx);
void OpenPatchDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx);
void OpenDataStorageWithProgramIndex(Kernel::HLERequestContext& ctx);
void SetGlobalAccessLogMode(Kernel::HLERequestContext& ctx);
void GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx);
void OutputAccessLogToSdCard(Kernel::HLERequestContext& ctx);
@@ -116,6 +116,31 @@ u32 Controller_NPad::IndexToNPad(std::size_t index) {
}
}
bool Controller_NPad::IsNpadIdValid(u32 npad_id) {
switch (npad_id) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case NPAD_UNKNOWN:
case NPAD_HANDHELD:
return true;
default:
LOG_ERROR(Service_HID, "Invalid npad id {}", npad_id);
return false;
}
}
bool Controller_NPad::IsDeviceHandleValid(const DeviceHandle& device_handle) {
return IsNpadIdValid(device_handle.npad_id) &&
device_handle.npad_type < NpadType::MaxNpadType &&
device_handle.device_index < DeviceIndex::MaxDeviceIndex;
}
Controller_NPad::Controller_NPad(Core::System& system) : ControllerBase(system), system(system) {}
Controller_NPad::~Controller_NPad() {
@@ -742,6 +767,10 @@ bool Controller_NPad::VibrateControllerAtIndex(std::size_t npad_index, std::size
void Controller_NPad::VibrateController(const DeviceHandle& vibration_device_handle,
const VibrationValue& vibration_value) {
if (!IsDeviceHandleValid(vibration_device_handle)) {
return;
}
if (!Settings::values.vibration_enabled.GetValue() && !permit_vibration_session_enabled) {
return;
}
@@ -798,12 +827,20 @@ void Controller_NPad::VibrateControllers(const std::vector<DeviceHandle>& vibrat
Controller_NPad::VibrationValue Controller_NPad::GetLastVibration(
const DeviceHandle& vibration_device_handle) const {
if (!IsDeviceHandleValid(vibration_device_handle)) {
return {};
}
const auto npad_index = NPadIdToIndex(vibration_device_handle.npad_id);
const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index);
return latest_vibration_values[npad_index][device_index];
}
void Controller_NPad::InitializeVibrationDevice(const DeviceHandle& vibration_device_handle) {
if (!IsDeviceHandleValid(vibration_device_handle)) {
return;
}
const auto npad_index = NPadIdToIndex(vibration_device_handle.npad_id);
const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index);
InitializeVibrationDeviceAtIndex(npad_index, device_index);
@@ -824,6 +861,10 @@ void Controller_NPad::SetPermitVibrationSession(bool permit_vibration_session) {
}
bool Controller_NPad::IsVibrationDeviceMounted(const DeviceHandle& vibration_device_handle) const {
if (!IsDeviceHandleValid(vibration_device_handle)) {
return false;
}
const auto npad_index = NPadIdToIndex(vibration_device_handle.npad_id);
const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index);
return vibration_devices_mounted[npad_index][device_index];
@@ -56,12 +56,14 @@ public:
JoyconLeft = 6,
JoyconRight = 7,
Pokeball = 9,
MaxNpadType = 10,
};
enum class DeviceIndex : u8 {
Left = 0,
Right = 1,
None = 2,
MaxDeviceIndex = 3,
};
enum class GyroscopeZeroDriftMode : u32 {
@@ -213,6 +215,8 @@ public:
static Settings::ControllerType MapNPadToSettingsType(Controller_NPad::NPadControllerType type);
static std::size_t NPadIdToIndex(u32 npad_id);
static u32 IndexToNPad(std::size_t index);
static bool IsNpadIdValid(u32 npad_id);
static bool IsDeviceHandleValid(const DeviceHandle& device_handle);
private:
struct CommonHeader {
+13 -1
View File
@@ -217,7 +217,7 @@ public:
{1, nullptr, "RefreshDebugAvailability"},
{2, nullptr, "ClearDebugResponse"},
{3, nullptr, "RegisterDebugResponse"},
{4, nullptr, "IsLargeResourceAvailable"},
{4, &NIM_ECA::IsLargeResourceAvailable, "IsLargeResourceAvailable"},
};
// clang-format on
@@ -231,6 +231,18 @@ private:
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IShopServiceAccessServer>(system);
}
void IsLargeResourceAvailable(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto unknown{rp.Pop<u64>()};
LOG_INFO(Service_NIM, "(STUBBED) called, unknown={}", unknown);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push(false);
}
};
class NIM_SHP final : public ServiceFramework<NIM_SHP> {
@@ -32,7 +32,7 @@ public:
/**
* Returns the type of the file
* @param file std::shared_ptr<VfsFile> open file
* @param file open file
* @return FileType found, or FileType::Error if this loader doesn't know it
*/
static FileType IdentifyType(const FileSys::VirtualFile& file);
+1 -1
View File
@@ -21,7 +21,7 @@ public:
/**
* Returns the type of the file
* @param file std::shared_ptr<VfsFile> open file
* @param file open file
* @return FileType found, or FileType::Error if this loader doesn't know it
*/
static FileType IdentifyType(const FileSys::VirtualFile& file);
+1 -1
View File
@@ -23,7 +23,7 @@ public:
/**
* Returns the type of the file
* @param file std::shared_ptr<VfsFile> open file
* @param file open file
* @return FileType found, or FileType::Error if this loader doesn't know it
*/
static FileType IdentifyType(const FileSys::VirtualFile& file);
+1 -1
View File
@@ -28,7 +28,7 @@ public:
/**
* Returns the type of the file
* @param file std::shared_ptr<VfsFile> open file
* @param file open file
* @return FileType found, or FileType::Error if this loader doesn't know it
*/
static FileType IdentifyType(const FileSys::VirtualFile& file);
+1 -1
View File
@@ -28,7 +28,7 @@ public:
/**
* Returns the type of the file
* @param file std::shared_ptr<VfsFile> open file
* @param file open file
* @return FileType found, or FileType::Error if this loader doesn't know it
*/
static FileType IdentifyType(const FileSys::VirtualFile& file);
+1 -1
View File
@@ -32,7 +32,7 @@ public:
/**
* Returns the type of the file
* @param file std::shared_ptr<VfsFile> open file
* @param file open file
* @return FileType found, or FileType::Error if this loader doesn't know it
*/
static FileType IdentifyType(const FileSys::VirtualFile& file);
+1 -1
View File
@@ -75,7 +75,7 @@ public:
/**
* Returns the type of the file
* @param file std::shared_ptr<VfsFile> open file
* @param file open file
* @return FileType found, or FileType::Error if this loader doesn't know it
*/
static FileType IdentifyType(const FileSys::VirtualFile& file);
+1 -1
View File
@@ -34,7 +34,7 @@ public:
/**
* Returns the type of the file
* @param file std::shared_ptr<VfsFile> open file
* @param file open file
* @return FileType found, or FileType::Error if this loader doesn't know it
*/
static FileType IdentifyType(const FileSys::VirtualFile& file);
+1 -1
View File
@@ -34,7 +34,7 @@ public:
/**
* Returns the type of the file
* @param file std::shared_ptr<VfsFile> open file
* @param file open file
* @return FileType found, or FileType::Error if this loader doesn't know it
*/
static FileType IdentifyType(const FileSys::VirtualFile& file);
+33 -34
View File
@@ -1473,39 +1473,6 @@ private:
void ProcessMethodCall(u32 method, u32 argument, u32 nonshadow_argument, bool is_last_call);
Core::System& system;
MemoryManager& memory_manager;
VideoCore::RasterizerInterface* rasterizer = nullptr;
/// Start offsets of each macro in macro_memory
std::array<u32, 0x80> macro_positions = {};
std::array<bool, Regs::NUM_REGS> mme_inline{};
/// Macro method that is currently being executed / being fed parameters.
u32 executing_macro = 0;
/// Parameters that have been submitted to the macro call so far.
std::vector<u32> macro_params;
/// Interpreter for the macro codes uploaded to the GPU.
std::unique_ptr<MacroEngine> macro_engine;
static constexpr u32 null_cb_data = 0xFFFFFFFF;
struct {
std::array<std::array<u32, 0x4000>, 16> buffer;
u32 current{null_cb_data};
u32 id{null_cb_data};
u32 start_pos{};
u32 counter{};
} cb_data_state;
Upload::State upload_state;
bool execute_on{true};
std::array<u8, Regs::NUM_REGS> dirty_pointers{};
/// Retrieves information about a specific TIC entry from the TIC buffer.
Texture::TICEntry GetTICEntry(u32 tic_index) const;
@@ -1514,8 +1481,8 @@ private:
/**
* Call a macro on this engine.
*
* @param method Method to call
* @param num_parameters Number of arguments
* @param parameters Arguments to the method call
*/
void CallMacroMethod(u32 method, const std::vector<u32>& parameters);
@@ -1564,6 +1531,38 @@ private:
/// Returns a query's value or an empty object if the value will be deferred through a cache.
std::optional<u64> GetQueryResult();
Core::System& system;
MemoryManager& memory_manager;
VideoCore::RasterizerInterface* rasterizer = nullptr;
/// Start offsets of each macro in macro_memory
std::array<u32, 0x80> macro_positions{};
std::array<bool, Regs::NUM_REGS> mme_inline{};
/// Macro method that is currently being executed / being fed parameters.
u32 executing_macro = 0;
/// Parameters that have been submitted to the macro call so far.
std::vector<u32> macro_params;
/// Interpreter for the macro codes uploaded to the GPU.
std::unique_ptr<MacroEngine> macro_engine;
static constexpr u32 null_cb_data = 0xFFFFFFFF;
struct CBDataState {
std::array<std::array<u32, 0x4000>, 16> buffer;
u32 current{null_cb_data};
u32 id{null_cb_data};
u32 start_pos{};
u32 counter{};
};
CBDataState cb_data_state;
Upload::State upload_state;
bool execute_on{true};
};
#define ASSERT_REG_POSITION(field_name, position) \
@@ -878,7 +878,7 @@ private:
}
u32 binding = device.GetBaseBindings(stage).uniform_buffer;
for (const auto [index, info] : ir.GetConstantBuffers()) {
for (const auto& [index, info] : ir.GetConstantBuffers()) {
const u32 num_elements = Common::AlignUp(info.GetSize(), 4) / 4;
const u32 size = info.IsIndirect() ? MAX_CONSTBUFFER_ELEMENTS : num_elements;
code.AddLine("layout (std140, binding = {}) uniform {} {{", binding++,
+3 -4
View File
@@ -83,6 +83,7 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual
#include "core/core.h"
#include "core/crypto/key_manager.h"
#include "core/file_sys/card_image.h"
#include "core/file_sys/common_funcs.h"
#include "core/file_sys/content_archive.h"
#include "core/file_sys/control_metadata.h"
#include "core/file_sys/patch_manager.h"
@@ -148,8 +149,6 @@ __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
constexpr int default_mouse_timeout = 2500;
constexpr u64 DLC_BASE_TITLE_ID_MASK = 0xFFFFFFFFFFFFE000;
/**
* "Callouts" are one-time instructional messages shown to the user. In the config settings, there
* is a bitfield "callout_flags" options, used to track if a message has already been shown to the
@@ -1529,7 +1528,7 @@ void GMainWindow::RemoveAddOnContent(u64 program_id, const QString& entry_type)
FileSys::TitleType::AOC, FileSys::ContentRecordType::Data);
for (const auto& entry : dlc_entries) {
if ((entry.title_id & DLC_BASE_TITLE_ID_MASK) == program_id) {
if (FileSys::GetBaseTitleID(entry.title_id) == program_id) {
const auto res =
fs_controller.GetUserNANDContents()->RemoveExistingEntry(entry.title_id) ||
fs_controller.GetSDMCContents()->RemoveExistingEntry(entry.title_id);
@@ -2709,7 +2708,7 @@ std::optional<u64> GMainWindow::SelectRomFSDumpTarget(const FileSys::ContentProv
dlc_match.reserve(dlc_entries.size());
std::copy_if(dlc_entries.begin(), dlc_entries.end(), std::back_inserter(dlc_match),
[&program_id, &installed](const FileSys::ContentProviderEntry& entry) {
return (entry.title_id & DLC_BASE_TITLE_ID_MASK) == program_id &&
return FileSys::GetBaseTitleID(entry.title_id) == program_id &&
installed.GetEntry(entry)->GetStatus() == Loader::ResultStatus::Success;
});