diff --git a/README.md b/README.md index 3ce52ea..9bff686 100644 --- a/README.md +++ b/README.md @@ -36,18 +36,11 @@ Load **bear.bsz** into [bella_gui](https://bellarender.com/builds) for rendering - [TODO] convert chunk camera for anim - - - # Build -Download SDK for your OS and move **bella_scene_sdk** into your **workdir**. On Windows rename unzipped folder by removing version ie bella_engine_sdk-24.6.0 -> bella_scene_sdk -https://bellarender.com/builds/ - - ``` workdir/ -├── bella_scene_sdk/ +├── bella_engine_sdk/ ├── libplist/ ├── lzfse/ ├── opengametools/ @@ -55,9 +48,16 @@ workdir/ ``` # MacOS +Install Cmake to /Applications +``` +curl -LO https://github.com/Kitware/CMake/releases/download/v3.31.6/cmake-3.31.6-macos-universal.dmg +open cmake-3.31.6-macos-universal.dmg +``` ``` mkdir workdir +curl -LO https://downloads.bellarender.com/bella_scene_sdk-25.3.0-macos.zip +unzip bella_scene_sdk-25.3.0-macos.zip git clone https://github.com/lzfse/lzfse mkdir -p lzfse/build cd lzfse/build @@ -85,13 +85,17 @@ cd vmax2bella make all -j4 install_name_tool -change ../lzfse/build/liblzfse.dylib @rpath/liblzfse.dylib bin/Darwin/release/vmax2bella install_name_tool -change /usr/local/lib/libplist-2.0.4.dylib @rpath/libplist-2.0.4.dylib bin/Darwin/release/vmax2bella - +git clone https://github.com/oomer/vmax2bella.git +cd vmax2bella +make all -j4 ``` -# Linux [NOT READY] +## Linux ``` mkdir workdir +curl -LO https://downloads.bellarender.com/bella_engine_sdk-25.3.0-linux.tar.gz +tar -xvf bella_engine_sdk-25.3.0-linux.tar.gz git clone https://github.com/lzfse/lzfse mkdir lzfse/build cd lzfse/build @@ -107,15 +111,22 @@ git clone https://github.com/jpaver/opengametools.git git clone https://github.com/oomer/oom.git git clone https://github.com/oomer/vmax2bella.git cd vmax2bella -make +make all -j4 ``` -# Windows -- Install Visual Studio Community 2022 -- Add Desktop development with C++ workload -- Launch x64 Native tools Command Prompt for VS2022 +## Windows (win10) +- [optioanl] Install https://git-scm.com + +- Download Visual Studio Community Edition 2022 +- Run VisualStudioSetup.exe +- Workload = [x] Desktop development with C++ +- Individual components = [x] Git For Windows + +#### x64 Developer console ``` mkdir workdir +curl -LO https://downloads.bellarender.com/bella_engine_sdk-25.3.0-win32.zip +tar -xf bella_engine_sdk-25.3.0-win32.zip git clone https://github.com/lzfse/lzfse mkdir -p lzfse/build cd lzfse/build diff --git a/debug.cpp b/debug.cpp deleted file mode 100644 index 674c899..0000000 --- a/debug.cpp +++ /dev/null @@ -1,586 +0,0 @@ -#include "debug.h" - - -/** - * Decodes a voxel's layercolor and color from the ds data stream - * - * @param dsData The raw ds data stream containing layer-color pairs - * @return A vector of Voxel structures with explicit coordinates and colors - */ -std::vector decodeVoxels2(const std::vector& dsData, int mortonOffset) { - std::vector voxels; - for (int i = 0; i < dsData.size() - 1; i += 2) { - dsVoxel _vxVoxel; // VoxelMax data - _vxVoxel.layer = static_cast(dsData[i]); - _vxVoxel.color = static_cast(dsData[i + 1]); - uint32_t dx, dy, dz; - decodeMorton3DOptimized(i/2 + mortonOffset, dx, dy, dz); // index IS the morton code - if (_vxVoxel.color != 0) { - newVoxel voxel = {dx, dy, dz, _vxVoxel.color}; - voxels.push_back(voxel); - } - - } - return voxels; -} - - -/** - * Print a plist node's contents recursively. - * This function takes a plist node and prints its contents in a human-readable format. - * It handles all types of plist nodes (dictionaries, arrays, strings, etc.) by using - * recursion to traverse the entire plist structure. - * - * @param node The plist node to print (plist_t is a pointer to the internal plist structure) - * @param indent The current indentation level (defaults to 0 for the root node) - */ -void printPlistNode(const plist_t& node, int indent ) { - // Early return if node is null (safety check) - if (!node) return; - - // Create a string with 'indent * 2' spaces for proper indentation - // This helps visualize the hierarchy of nested structures - std::string indentStr(indent * 2, ' '); - - // Get the type of the current node (dictionary, array, string, etc.) - plist_type nodeType = plist_get_node_type(node); - - // Handle each type of node differently - switch (nodeType) { - case PLIST_DICT: { - std::cout << indentStr << "Dictionary:" << std::endl; - - // Create an iterator for the dictionary - // nullptr is passed as initial value; the iterator will be allocated by plist_dict_new_iter - plist_dict_iter it = nullptr; - plist_dict_new_iter(node, &it); - - // Variables to store the current key-value pair - char* key = nullptr; // Will hold the dictionary key (needs to be freed) - plist_t value = nullptr; // Will hold the value node - - // Iterate through all items in the dictionary - while (true) { - // Get the next key-value pair - plist_dict_next_item(node, it, &key, &value); - - // Break if we've reached the end of the dictionary - if (!key || !value) break; - - // Print the key and recursively print its value - std::cout << indentStr << " " << key << ":" << std::endl; - printPlistNode(value, indent + 2); // Increase indent for nested values - - // Free the key string (allocated by plist_dict_next_item) - free(key); - key = nullptr; // Set to nullptr to avoid double-free - } - - // Free the iterator when done - free(it); - break; - } - case PLIST_ARRAY: { - std::cout << indentStr << "Array:" << std::endl; - uint32_t size = plist_array_get_size(node); - for (uint32_t i = 0; i < size; i++) { - plist_t item = plist_array_get_item(node, i); - std::cout << indentStr << " [" << i << "]:" << std::endl; - printPlistNode(item, indent + 2); - } - break; - } - case PLIST_STRING: { - char* str = nullptr; - plist_get_string_val(node, &str); - std::cout << indentStr << "String: " << (str ? str : "(null)") << std::endl; - free(str); - break; - } - case PLIST_BOOLEAN: { - uint8_t bval; - plist_get_bool_val(node, &bval); - std::cout << indentStr << "Boolean: " << (bval ? "true" : "false") << std::endl; - break; - } - case PLIST_UINT: { - uint64_t val; - plist_get_uint_val(node, &val); - std::cout << indentStr << "Integer: " << val << std::endl; - break; - } - case PLIST_REAL: { - double val; - plist_get_real_val(node, &val); - std::cout << indentStr << "Real: " << val << std::endl; - break; - } - case PLIST_DATE: { - int32_t sec = 0; - int32_t usec = 0; - plist_get_date_val(node, &sec, &usec); - std::cout << indentStr << "Date: " << sec << "." << usec << std::endl; - break; - } - case PLIST_DATA: { - char* data = nullptr; - uint64_t length = 0; - plist_get_data_val(node, &data, &length); - std::cout << indentStr << "Data: <" << length << " bytes>" << std::endl; - free(data); - break; - } - default: - std::cout << indentStr << "Unknown type" << std::endl; - } -} - - -/** - * New visualization function that definitely uses the correct z-plane - * - * @param voxels The vector of decoded voxels - * @param zPlane The z-coordinate of the plane to visualize - * @param size The size of the grid (default: 32x32) - */ -void visualizeZPlaneFixed(const std::vector& voxels, int zPlane, int size ) { - // Bounds checking - const int MIN_Z = 0; - const int MAX_Z = 31; - if (zPlane < MIN_Z || zPlane > MAX_Z) { - std::cout << "WARNING: z-plane value " << zPlane << " is out of bounds. Valid range is " << MIN_Z << "-" << MAX_Z << ". Using z=0 instead." << std::endl; - zPlane = 0; - } - - std::cout << "Visualizing z-plane: " << zPlane << std::endl; - - // Create a 2D grid for visualization - std::vector> grid(size, std::vector(size, ' ')); - - // Count voxels for statistics - int totalVoxels = voxels.size(); - int voxelsAtRequestedZ = 0; - int coloredVoxels = 0; - int clearVoxels = 0; - - // Loop 1: Debug output for the first few matching voxels - int debugCount = 0; - for (const auto& voxel : voxels) { - if (voxel.z == zPlane) { - voxelsAtRequestedZ++; - - // Update the grid and count color types - if (voxel.x >= 0 && voxel.x < size && voxel.y >= 0 && voxel.y < size) { - if (voxel.color == 0x00) { - grid[voxel.y][voxel.x] = '.'; // Clear voxel (0x00) - clearVoxels++; - } else if (voxel.color == 0x25) { - grid[voxel.y][voxel.x] = '#'; // Colored voxel (0x25) - coloredVoxels++; - } else { - grid[voxel.y][voxel.x] = 'X'; // Other color - coloredVoxels++; - } - } - } - } - - // Print statistics - std::cout << "\nVisualization Statistics:" << std::endl; - std::cout << "- Total voxels in data: " << totalVoxels << std::endl; - std::cout << "- Voxels at z=" << zPlane << ": " << voxelsAtRequestedZ << std::endl; - std::cout << "- Colored voxels: " << coloredVoxels << " (shown as '#' or 'X')" << std::endl; - std::cout << "- Clear voxels: " << clearVoxels << " (shown as '.')" << std::endl; - - // If no matching voxels were found, print a message and return - if (voxelsAtRequestedZ == 0) { - std::cout << "\n*** NO VOXELS FOUND AT Z=" << zPlane << " ***\n" << std::endl; - return; - } - - // Print legend - std::cout << "\nLegend:" << std::endl; - std::cout << "- '#': Color 0x25" << std::endl; - std::cout << "- '.': Clear (0x00)" << std::endl; - std::cout << "- 'X': Other colors" << std::endl; - std::cout << "- ' ': No voxel present" << std::endl; - std::cout << "- Each 8x4 section represents one subchunk" << std::endl; - - // Print x-axis header - std::cout << "\n "; - for (int x = 0; x < size; x++) { - if (x % 8 == 0) { - std::cout << "|"; // Mark subchunk boundaries - } else { - std::cout << x % 10; // Print digit for readability - } - } - std::cout << std::endl; - - // Print divider line - std::cout << " "; - for (int x = 0; x < size; x++) { - if (x % 8 == 0) { - std::cout << "+"; // Mark subchunk corners - } else { - std::cout << "-"; - } - } - std::cout << std::endl; - - // Print grid with y-axis labels and subchunk markers - for (int y = 0; y < size; y++) { - std::cout << std::setw(2) << y << " "; - - // Mark subchunk boundaries on y-axis - if (y % 4 == 0) { - std::cout << "+"; - } else { - std::cout << "|"; - } - - // Print the actual voxel data for this row - for (int x = 0; x < size; x++) { - std::cout << grid[y][x]; - } - std::cout << std::endl; - } - - std::cout << "\n===============================================\n"; -} - -/** - * Examines a specific array element at the given index from a plist file. - * This function allows inspection of individual chunks/snapshots in the data. - * - * @param plistFilePath Path to the plist file - * @param index The index of the array element to examine - * @param arrayPath The path to the array in the plist structure - * @return true if successful, false if any errors occurred - */ -bool examinePlistNode(const plist_t& root_node, int snapshotIndex, int zIndex, const std::string& arrayPath) { - std::cout << "Examining Plist array at snapshot " << snapshotIndex << " zIndex " << zIndex << std::endl; - - if (!root_node) { - std::cerr << "Failed to process Plist data" << std::endl; - return false; - } - plist_t current_node = root_node; - // if the array path contains slashes, we need to navigate through the structure - std::string path = arrayPath; - size_t pos = 0; - std::string token; - while ((pos = path.find('/')) != std::string::npos) { - token = path.substr(0, pos); - path.erase(0, pos + 1); - - // current node must be a dictionary - if (plist_get_node_type(current_node) != PLIST_DICT) { - std::cerr << "error: expected dictionary at path component '" << token << "'" << std::endl; - //plist_free(root_node); - return false; - } - - // get the next node in the path - current_node = plist_dict_get_item(current_node, token.c_str()); - if (!current_node) { - std::cerr << "error: could not find key '" << token << "' in dictionary" << std::endl; - //plist_free(root_node); - return false; - } - } - - // Now path contains the final key name - if (!path.empty() && plist_get_node_type(current_node) == PLIST_DICT) { - current_node = plist_dict_get_item(current_node, path.c_str()); - if (!current_node) { - std::cerr << "Error: Could not find key '" << path << "' in dictionary" << std::endl; - return false; - } - } - - // Check if we found an array - if (plist_get_node_type(current_node) != PLIST_ARRAY) { - std::cerr << "Error: '" << "arrayPath" << "' is not an array" << std::endl; - return false; - } - - // Get Plist node array size - uint32_t arraySize = plist_array_get_size(current_node); - if (snapshotIndex < 0 || snapshotIndex >= static_cast(arraySize)) { - std::cerr << "Error: Index " << snapshotIndex << " is out of range (array size: " << arraySize << ")" << std::endl; - return false; - } - - // Get the Plist node at the specified index - plist_t element = plist_array_get_item(current_node, snapshotIndex); - if (!element) { - std::cerr << "Error: Could not get Plist node at snapshot " << snapshotIndex << std::endl; - return false; - } - - std::cout << "Array size: " << arraySize << std::endl; - std::cout << "Plist node details at snapshot " << snapshotIndex << " zIndex " << zIndex << ":" << std::endl; - printPlistNode(element); - debugSnapshots(element, snapshotIndex, zIndex); - return true; -} -/** - * Handles 's' dictionary in a Plist node holding 32x32x32 chunks of voxel data. - * - * @param element The Plist node to examine - * @return true if successful, false if any errors occurred - */ -bool debugSnapshots(plist_t element, int snapshotIndex, int zIndex) { - std::cout << "Debugging snapshots" << std::endl; - // Special handling for 's' dictionaries - if (plist_get_node_type(element) == PLIST_DICT) { - plist_t sNode = plist_dict_get_item(element, "s"); - if (sNode) { - // Look for specific keys of interest in the 's' dictionary - if (plist_get_node_type(sNode) == PLIST_DICT) { - // Check for 'ds' (data stream) in the 's' dictionary - plist_t dsNode = plist_dict_get_item(sNode, "ds"); - if (dsNode && plist_get_node_type(dsNode) == PLIST_DATA) { - char* data = nullptr; - uint64_t length = 0; - plist_get_data_val(dsNode, &data, &length); - - std::cout << "\nDetailed analysis of 'ds' data stream (size: " << length << " bytes):" << std::endl; - - // Detailed analysis of the data stream - if (length > 0 && data) { - // Display as hex bytes - increased to 384 bytes - std::cout << "First 384 bytes (hex):" << std::endl; - size_t bytesToShow = std::min(static_cast(384), static_cast(length)); - for (size_t i = 0; i < bytesToShow; i++) { - std::cout << std::hex << std::setw(2) << std::setfill('0') - << static_cast(static_cast(data[i])) << " "; - if ((i + 1) % 16 == 0) std::cout << std::endl; - } - std::cout << std::dec << std::endl; - - // If data appears to be position-color pairs (as in voxel data) - if (length % 2 == 0) { - size_t numPairs = length / 2; - std::cout << "Data appears to contain " << numPairs << " position-color pairs" << std::endl; - - // Check if all positions are 0 (common for optimized voxel data) - bool allPositionsZero = true; - for (size_t i = 0; i < std::min(numPairs, static_cast(100)); i++) { - if (static_cast(data[i * 2]) != 0) { - allPositionsZero = false; - break; - } - } - - if (allPositionsZero) { - // Show only color values for more compact analysis - std::cout << "\nAll position values are 0. Showing only color values:" << std::endl; - std::cout << "First 384 color values (hex):" << std::endl; - size_t colorsToShow = std::min(static_cast(384), numPairs); - for (size_t i = 0; i < colorsToShow; i++) { - std::cout << std::hex << std::setw(2) << std::setfill('0') - << static_cast(static_cast(data[i * 2 + 1])) << " "; - if ((i + 1) % 16 == 0) std::cout << std::endl; - } - std::cout << std::dec << std::endl; - } else { - // Show position-color pairs if positions vary - std::cout << "\nFirst 10 position-color pairs:" << std::endl; - std::cout << "Index | Position | Color" << std::endl; - std::cout << "------|----------|------" << std::endl; - - size_t pairsToShow = std::min(static_cast(10), numPairs); - for (size_t i = 0; i < pairsToShow; i++) { - uint8_t position = static_cast(data[i * 2]); - uint8_t color = static_cast(data[i * 2 + 1]); - - std::cout << std::setw(5) << i << " | " - << std::setw(8) << std::hex << std::setfill('0') - << static_cast(position) << std::dec << std::setfill(' ') << " | " - << std::setw(5) << std::hex << std::setfill('0') - << static_cast(color) << std::dec << std::setfill(' ') << std::endl; - } - } - - // Analyze and print color runs - std::cout << "\nAnalyzing color runs:" << std::endl; - - if (numPairs > 0) { - uint8_t currentColor = static_cast(data[1]); // First color - size_t runStart = 0; - size_t runLength = 1; - - // Find all runs - std::vector> colorRuns; - - for (size_t i = 1; i < numPairs; i++) { - uint8_t color = static_cast(data[i * 2 + 1]); - - if (color == currentColor) { - // Continue the current run - runLength++; - } else { - // End the current run and start a new one - colorRuns.emplace_back(runStart, runStart + runLength - 1, currentColor); - currentColor = color; - runStart = i; - runLength = 1; - } - } - - // Add the last run - colorRuns.emplace_back(runStart, runStart + runLength - 1, currentColor); - - // Print the runs in a condensed format - std::cout << "Found " << colorRuns.size() << " color runs:" << std::endl; - std::cout << "Color | Voxel Count | Range" << std::endl; - std::cout << "------|-------------|------" << std::endl; - - for (const auto& run : colorRuns) { - size_t start = std::get<0>(run); - size_t end = std::get<1>(run); - uint8_t color = std::get<2>(run); - size_t length = end - start + 1; - - std::cout << " 0x" << std::hex << std::setw(2) << std::setfill('0') - << static_cast(color) << " | " - << std::dec << std::setfill(' ') << std::setw(11) << length << " | " - << std::setw(5) << start << "-" << std::setw(5) << end - << std::endl; - } - - // Add special notice for full-voxel-space runs - if (colorRuns.size() == 1) { - const auto& singleRun = colorRuns[0]; - size_t start = std::get<0>(singleRun); - size_t end = std::get<1>(singleRun); - size_t length = end - start + 1; - uint8_t color = std::get<2>(singleRun); - - if (start == 0 && length == 32768) { - std::cout << "\nNOTICE: This chunk contains a single color (0x" - << std::hex << static_cast(color) << std::dec - << ") for all 32,768 voxels, which would fill a complete 32x32x32 voxel space." << std::endl; - std::cout << "This could indicate:"; - std::cout << "\n - A solid block of one color"; - std::cout << "\n - A special encoding for empty/default chunks"; - std::cout << "\n - A placeholder or initialization state" << std::endl; - } - } - } - } - - // Decode voxels for visualization - // @param TODO: get morton offset from the 'lt' dictionary - std::vector voxels = decodeVoxels2(std::vector(data, data + length), 0); - - printVoxelTable(voxels, 100); - - // Explicitly decode the voxels for visualization - char* data = nullptr; - uint64_t length = 0; - plist_get_data_val(dsNode, &data, &length); - - if (length > 0 && data) { - std::vector voxels = decodeVoxels2(std::vector(data, data + length), 0); - visualizeZPlaneFixed(voxels, zIndex); - free(data); - } - } - - free(data); - } - - // Check for 'id' dictionary to get chunk information - plist_t idNode = plist_dict_get_item(sNode, "id"); - if (idNode && plist_get_node_type(idNode) == PLIST_DICT) { - plist_t chunkIdNode = plist_dict_get_item(idNode, "c"); - if (chunkIdNode && plist_get_node_type(chunkIdNode) == PLIST_UINT) { - uint64_t chunkId; - plist_get_uint_val(chunkIdNode, &chunkId); - std::cout << "\nChunk ID: " << chunkId << std::endl; - } - } - - // Check for 'lt' (location table) - plist_t ltNode = plist_dict_get_item(sNode, "lt"); - if (ltNode && plist_get_node_type(ltNode) == PLIST_DATA) { - char* data = nullptr; - uint64_t length = 0; - plist_get_data_val(ltNode, &data, &length); - - std::cout << "\nLocation table size: " << length << " bytes" << std::endl; - if (length > 0 && data) { - std::cout << "First 16 bytes of location table:" << std::endl; - size_t bytesToShow = std::min(static_cast(16), static_cast(length)); - for (size_t i = 0; i < bytesToShow; i++) { - std::cout << std::hex << std::setw(2) << std::setfill('0') - << static_cast(static_cast(data[i])) << " "; - } - std::cout << std::dec << std::endl; - } - - free(data); - } - } - } - } -} - -/** - * Prints a table of voxel positions and colors - * - * @param voxels The vector of decoded voxels - * @param limit Maximum number of voxels to display (0 for all) - * @param filterZ Optional z-value to filter by - */ -void printVoxelTable(const std::vector& voxels, size_t limit , int filterZ ) { - int emptyVoxels = 32768 - voxels.size(); - std::cout << "Voxels: " << voxels.size() << " Empty: " << emptyVoxels << std::endl; - - // Count voxels at the filtered z-level if filtering is active - int filteredCount = 0; - if (filterZ >= 0) { - for (const auto& voxel : voxels) { - if (voxel.z == filterZ) filteredCount++; - } - std::cout << "Voxels at z=" << filterZ << ": " << filteredCount << std::endl; - } - - std::cout << "Index | X | Y | Z | Color" << std::endl; - std::cout << "------|----|----|----|---------" << std::endl; - - int count = 0; - int shownCount = 0; - for (size_t i = 0; i < voxels.size(); i++) { - const auto& voxel = voxels[i]; - - // Skip if we're filtering by z and this doesn't match - if (filterZ >= 0 && voxel.z != filterZ) continue; - - std::cout << std::setw(6) << i << " | "; - std::cout << std::setw(2) << voxel.x << " | "; - std::cout << std::setw(2) << voxel.y << " | "; - std::cout << std::setw(2) << voxel.z << " | "; - std::cout << "0x" << std::hex << std::setw(2) << std::setfill('0') - << static_cast(voxel.color) << std::dec << std::setfill(' ') << std::endl; - - // Count shown voxels - shownCount++; - - // Check if we've reached the limit - if (limit > 0 && shownCount >= limit) { - if (filterZ >= 0) { - int remaining = filteredCount - shownCount; - if (remaining > 0) { - std::cout << "... (output truncated, " << remaining << " more voxels at z=" << filterZ << ")" << std::endl; - } - } else { - std::cout << "... (output truncated, " << (voxels.size() - shownCount) << " more voxels)" << std::endl; - } - break; - } - } -} diff --git a/debug.h b/debug.h deleted file mode 100644 index 4644bb4..0000000 --- a/debug.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include "../libplist/include/plist/plist.h" // Library for handling Apple property list files -#include "common.h" // Debugging functions -// Include any necessary structures - -// Optimized function to compact bits (From VoxelMax) -uint32_t compactBits(uint32_t n); -// Optimized function to decode Morton code using parallel bit manipulation -void decodeMorton3DOptimized(uint32_t morton, uint32_t& x, uint32_t& y, uint32_t& z); - - - -// Function declarations -std::vector decodeVoxels(const std::vector& dsData, int mortonOffset); -void printPlistNode(const plist_t& node, int indent = 0); -bool examinePlistNode(const plist_t& root_node, int snapshotIndex, int zIndex, const std::string& arrayPath); -bool debugSnapshots(plist_t element, int snapshotIndex, int zIndex); -void printVoxelTable(const std::vector& voxels, size_t limit = 100, int filterZ = -1); -void visualizeZPlaneFixed(const std::vector& voxels, int zPlane, int size = 32); \ No newline at end of file diff --git a/extra.cpp b/extra.cpp deleted file mode 100644 index 184839e..0000000 --- a/extra.cpp +++ /dev/null @@ -1,70 +0,0 @@ -#include "extra.h" -// Function that returns the license text for this program -std::string initializeGlobalLicense() -{ - // R"(...)" is a C++ raw string literal - allows multi-line strings with preserved formatting - return R"( -vmax2bella - -Copyright (c) 2025 Harvey Fong - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE.)"; -} - -// Function that returns third-party license text -std::string initializeGlobalThirdPartyLicences() -{ - return R"( -Bella SDK (Software Development Kit) - -Copyright Diffuse Logic SCP, all rights reserved. - -Permission is hereby granted to any person obtaining a copy of this software -(the "Software"), to use, copy, publish, distribute, sublicense, and/or sell -copies of the Software. - -THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. ALL -IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF MERCHANTABILITY -ARE HEREBY DISCLAIMED.) - -=== - -lzfse - -Copyright (c) 2015-2016, Apple Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer - in the documentation and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder(s) nor the names of any contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -)"; -} - diff --git a/makefile b/makefile index 8b31100..b4a6df8 100644 --- a/makefile +++ b/makefile @@ -1,11 +1,11 @@ # Project configuration -BELLA_SDK_NAME = bella_scene_sdk +BELLA_SDK_NAME = bella_engine_sdk EXECUTABLE_NAME = vmax2bella PLATFORM = $(shell uname) BUILD_TYPE ?= release# Default to release build if not specified # Common paths -BELLA_SDK_PATH = ../bella_scene_sdk +BELLA_SDK_PATH = ../bella_engine_sdk LZFSE_PATH = ../lzfse LIBPLIST_PATH = ../libplist OBJ_DIR = obj/$(PLATFORM)/$(BUILD_TYPE) @@ -18,6 +18,7 @@ ifeq ($(PLATFORM), Darwin) SDK_LIB_EXT = dylib LZFSE_LIB_NAME = liblzfse.$(SDK_LIB_EXT) PLIST_LIB_NAME = libplist-2.0.4.$(SDK_LIB_EXT) + USD_LIB_NAME = libdl_usd_ms.$(SDK_LIB_EXT) MACOS_SDK_PATH = /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk # Compiler settings @@ -43,6 +44,7 @@ else SDK_LIB_EXT = so LZFSE_LIB_NAME = liblzfse.$(SDK_LIB_EXT) PLIST_LIB_NAME = libplist.$(SDK_LIB_EXT) + USD_LIB_NAME = libdl_usd_ms.$(SDK_LIB_EXT) # Compiler settings CC = gcc @@ -96,6 +98,7 @@ $(OUTPUT_FILE): $(OBJECT_FILES) $(CXX) -o $@ $(OBJECT_FILES) $(LINKER_FLAGS) $(LIB_PATHS) $(LIBRARIES) @echo "Copying libraries to $(BIN_DIR)..." @cp $(SDK_LIB_PATH)/$(SDK_LIB_FILE) $(BIN_DIR)/$(SDK_LIB_FILE) + @cp $(SDK_LIB_PATH)/$(USD_LIB_NAME) $(BIN_DIR)/$(USD_LIB_NAME) @cp $(LZFSE_BUILD_DIR)/$(LZFSE_LIB_NAME) $(BIN_DIR)/$(LZFSE_LIB_NAME) @cp $(PLIST_LIB_DIR)/$(PLIST_LIB_NAME) $(BIN_DIR)/ @echo "Build complete: $(OUTPUT_FILE)" @@ -108,7 +111,7 @@ clean: rm -f $(OBJ_DIR)/vmax2bella.o rm -f $(OUTPUT_FILE) rm -f $(BIN_DIR)/$(SDK_LIB_FILE) - rm -f $(BIN_DIR)/*.dylib + rm -f $(BIN_DIR)/*.$(SDK_LIB_EXT) rmdir $(OBJ_DIR) 2>/dev/null || true rmdir $(BIN_DIR) 2>/dev/null || true @@ -119,8 +122,8 @@ cleanall: rm -f bin/*/debug/$(EXECUTABLE_NAME) rm -f bin/*/release/$(SDK_LIB_FILE) rm -f bin/*/debug/$(SDK_LIB_FILE) - rm -f bin/*/release/*.dylib - rm -f bin/*/debug/*.dylib + rm -f bin/*/release/*.$(SDK_LIB_EXT) + rm -f bin/*/debug/*.$(SDK_LIB_EXT) rmdir obj/*/release 2>/dev/null || true rmdir obj/*/debug 2>/dev/null || true rmdir bin/*/release 2>/dev/null || true diff --git a/oomer_misc.h b/oomer_misc.h deleted file mode 100644 index 264e62d..0000000 --- a/oomer_misc.h +++ /dev/null @@ -1,1595 +0,0 @@ -#pragma once -#include // For std::string -#include -#include // For std::ofstream -#include // For std::filesystem -//#include "DayEnvironmentHDRI019_1K-TONEMAPPED.h" // embedded image dome light -#include // For std::pow - -//Forward declarations -extern const unsigned int DayEnvironmentHDRI019_1K_TONEMAPPED_jpg_len; -extern const unsigned char DayEnvironmentHDRI019_1K_TONEMAPPED_jpg[]; - -// Convert sRGB color value to linear color space -inline float srgbToLinear(float value) { - return (value <= 0.04045f) ? - (value * (1.0f/12.92f)) : - std::pow((value + 0.055f) * (1.0f/1.055f), 2.4f); -} - - -// read binary compressed LZFSE file into an array -inline std::vector LZFSEToArray(const std::string& lzfseFullName) { - std::ifstream lzfseFile(lzfseFullName, std::ios::binary); - if (!lzfseFile.is_open()) { - std::cerr << "Error: Could not open LZFSE file: " << lzfseFullName << std::endl; - throw std::runtime_error("Error message"); - } - // Get file size using std::filesystem - size_t lzfseFileSize = std::filesystem::file_size(lzfseFullName); - - // store the lzfse file in a memory buffer - std::vector lzfseArray(lzfseFileSize); - lzfseFile.read(reinterpret_cast(lzfseArray.data()), lzfseFileSize); - lzfseFile.close(); - return lzfseArray; -} - - - -// read binary compressed LZFSE file -// Why not use liblzfse directly? -// @param dirName: the name of the directory containing the LZFSE file -// @param compressedName: the name of the LZFSE file to decompress -inline std::vector decompressLZFSE(const std::string& dirName, const std::string& compressedName) { - std::string lzfseFullName = dirName + "/"+compressedName; - - std::cout << "Decompressing LZFSE file: " << lzfseFullName << std::endl; - std::ifstream lzfseFile(lzfseFullName, std::ios::binary); - if (!lzfseFile.is_open()) { - std::cerr << "Error: Could not open input file: " << lzfseFullName << std::endl; - throw std::runtime_error("Error message"); - } - - // Get lzfse file size and read content - lzfseFile.seekg(0, std::ios::end); - size_t lzfseFileSize = lzfseFile.tellg(); - lzfseFile.seekg(0, std::ios::beg); - // store the lzfse file in a memory buffer - std::vector lzfseBuffer(lzfseFileSize); - lzfseFile.read(reinterpret_cast(lzfseBuffer.data()), lzfseFileSize); - lzfseFile.close(); - return lzfseBuffer; -} - -// Function that saves the embedded HDRI file to the res directory -// Allows executable to be moved around without the HDRI file -inline void saveHDRI() { - // Create hdri file if it doesn't exist - std::string hdriName = "DayEnvironmentHDRI019_1K-TONEMAPPED.jpg"; - std::string resDir= "./res"; - std::filesystem::path hdriFile = std::filesystem::path(resDir) / hdriName; - if (!std::filesystem::exists(hdriFile)) { - std::cout << "HDRI file not found, creating it" << std::endl; - std::filesystem::create_directories(resDir); - std::ofstream outFile(hdriFile, std::ios::binary); - if (!outFile) { - std::cerr << "HDRI failed to write" << hdriFile << std::endl; - } - - // Write the data to the file using the exact length - outFile.write(reinterpret_cast(DayEnvironmentHDRI019_1K_TONEMAPPED_jpg), - DayEnvironmentHDRI019_1K_TONEMAPPED_jpg_len); - // Check if write was successful - if (!outFile) { - std::cerr << "HDRI failed to write" << hdriFile << std::endl; - } - } -} - - - -// Function that returns the license text for this program -inline std::string initializeGlobalLicense() { - // R"(...)" is a C++ raw string literal - allows multi-line strings with preserved formatting - return R"( -vmax2bella - -Copyright (c) 2025 Harvey Fong - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE.)"; -} - -// Function that returns third-party license text -inline std::string initializeGlobalThirdPartyLicences() { - return R"( -Bella SDK (Software Development Kit) - -Copyright Diffuse Logic SCP, all rights reserved. - -Permission is hereby granted to any person obtaining a copy of this software -(the "Software"), to use, copy, publish, distribute, sublicense, and/or sell -copies of the Software. - -THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. ALL -IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF MERCHANTABILITY -ARE HEREBY DISCLAIMED.) - -=== - -lzfse - -Copyright (c) 2015-2016, Apple Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer - in the documentation and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder(s) nor the names of any contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=== - -DayEnvironmentHDRI019_1K-TONEMAPPED.jpg from ambientCG.com, -licensed under the Creative Commons CC0 1.0 Universal License. - -=== -https://github.com/libimobiledevice/libplist - -This software uses libraries from the libplist project under the LGPL version 2.1. - -)"; -} - -const unsigned char DayEnvironmentHDRI019_1K_TONEMAPPED_jpg[] = { - 0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01, - 0x01, 0x00, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, 0xff, 0xe1, 0x00, 0x4c, - 0x45, 0x78, 0x69, 0x66, 0x00, 0x00, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, - 0x00, 0x08, 0x00, 0x01, 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xa0, 0x01, - 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa0, 0x02, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0xa0, 0x03, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, - 0x00, 0x00, 0xff, 0xed, 0x00, 0x38, 0x50, 0x68, 0x6f, 0x74, 0x6f, 0x73, - 0x68, 0x6f, 0x70, 0x20, 0x33, 0x2e, 0x30, 0x00, 0x38, 0x42, 0x49, 0x4d, - 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x42, 0x49, 0x4d, - 0x04, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xd4, 0x1d, 0x8c, 0xd9, - 0x8f, 0x00, 0xb2, 0x04, 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e, - 0xff, 0xc0, 0x00, 0x11, 0x08, 0x00, 0x80, 0x01, 0x00, 0x03, 0x01, 0x22, - 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xc4, 0x00, 0x1f, 0x00, - 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0xff, 0xc4, 0x00, 0xb5, 0x10, 0x00, 0x02, 0x01, - 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, - 0x7d, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, - 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, - 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, - 0x72, 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, - 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, - 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, - 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, - 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, - 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, - 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, - 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, - 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, - 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, - 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xc4, 0x00, 0x1f, 0x01, - 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0xff, 0xc4, 0x00, 0xb5, 0x11, 0x00, 0x02, 0x01, - 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, - 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, - 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, - 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, - 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, - 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, - 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, - 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, - 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, - 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, - 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, - 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, - 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, - 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xdb, 0x00, 0x43, 0x00, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x03, 0x02, 0x02, 0x02, 0x02, 0x03, 0x04, 0x03, 0x03, - 0x03, 0x03, 0x03, 0x04, 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, - 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x08, 0xff, 0xdb, 0x00, 0x43, 0x01, 0x01, 0x01, 0x01, - 0x02, 0x02, 0x02, 0x03, 0x02, 0x02, 0x03, 0x08, 0x05, 0x05, 0x05, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x08, 0xff, 0xdd, 0x00, 0x04, 0x00, 0x10, 0xff, 0xda, 0x00, 0x0c, 0x03, - 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0xfa, 0xdf, 0x42, - 0xf8, 0xbd, 0xf0, 0x27, 0xc4, 0xba, 0xde, 0x9b, 0xa5, 0xf8, 0x66, 0xcf, - 0x52, 0xd3, 0x5a, 0xee, 0xe0, 0x45, 0x73, 0x71, 0xe2, 0x49, 0x9e, 0x44, - 0x47, 0x2d, 0x80, 0x90, 0x3c, 0x77, 0xf0, 0xc3, 0x33, 0x1c, 0x81, 0xe5, - 0xab, 0x79, 0x81, 0x8e, 0x0a, 0x82, 0x40, 0xa8, 0xfe, 0x24, 0x7c, 0x46, - 0xf0, 0xad, 0x8e, 0x93, 0x3d, 0xcf, 0x85, 0x2c, 0xb4, 0x6d, 0x58, 0xd9, - 0x4a, 0x12, 0xe7, 0xed, 0x45, 0x92, 0xe0, 0xb0, 0x38, 0x65, 0x5b, 0x51, - 0x3c, 0x93, 0x7c, 0xa3, 0xae, 0xe6, 0xc9, 0xe9, 0xd6, 0xbe, 0x29, 0xf8, - 0x2f, 0xf1, 0x8e, 0xf7, 0xc4, 0x16, 0x97, 0x9e, 0x1f, 0xd1, 0x27, 0xd3, - 0x24, 0xd5, 0x6f, 0x60, 0x86, 0xc9, 0xf4, 0xcb, 0xab, 0x8b, 0x58, 0x96, - 0x26, 0x54, 0x60, 0x8b, 0x0c, 0x33, 0xc9, 0x1a, 0x3e, 0xc2, 0x79, 0x68, - 0xc2, 0x30, 0x04, 0x90, 0xc1, 0x9b, 0x23, 0xdf, 0xbf, 0x67, 0xdf, 0xd9, - 0xcf, 0x58, 0xf8, 0xcf, 0x26, 0x94, 0x87, 0xfe, 0x15, 0xe4, 0x72, 0xa6, - 0xa9, 0x34, 0xf7, 0xe6, 0xf3, 0x53, 0x37, 0x71, 0xcf, 0x35, 0xaa, 0x10, - 0xb1, 0xbd, 0x94, 0x12, 0xde, 0x32, 0xc8, 0xec, 0x00, 0x25, 0x23, 0x52, - 0xa0, 0x38, 0x04, 0x73, 0xb7, 0xf8, 0xa6, 0x18, 0x4a, 0x78, 0xc7, 0x2a, - 0x36, 0xb3, 0xd3, 0x4d, 0x7f, 0xcd, 0x2f, 0x3e, 0xde, 0x76, 0xdb, 0x86, - 0x35, 0x64, 0xd2, 0xe5, 0x3c, 0x13, 0xe2, 0x17, 0xed, 0x91, 0xf0, 0xdf, - 0xc2, 0xda, 0xb6, 0x75, 0x5d, 0x3b, 0xc3, 0x46, 0x35, 0x83, 0x65, 0xcc, - 0x3a, 0x4c, 0x3a, 0x84, 0x12, 0xc2, 0x70, 0x4e, 0xe2, 0x24, 0x55, 0xfd, - 0xe0, 0xce, 0x08, 0x66, 0x2a, 0x4f, 0x7a, 0xf1, 0x19, 0xff, 0x00, 0x6d, - 0x4f, 0x00, 0x6a, 0x96, 0x8f, 0x36, 0x8b, 0xa7, 0x25, 0xcc, 0x0d, 0x9d, - 0xf2, 0x3d, 0xca, 0x45, 0x3c, 0x61, 0x9b, 0x68, 0xdb, 0xe6, 0x4c, 0x84, - 0x9f, 0x40, 0xbd, 0x0f, 0x04, 0xe6, 0xbe, 0xc8, 0xf8, 0xef, 0xff, 0x00, - 0x04, 0xfc, 0xbd, 0x16, 0xba, 0xcf, 0x8a, 0x74, 0xb3, 0xa4, 0x58, 0x43, - 0xa0, 0x5e, 0x3d, 0xbe, 0xb3, 0xa2, 0xe9, 0xd3, 0x4b, 0xf6, 0x98, 0xae, - 0x19, 0x41, 0x12, 0x5a, 0xd9, 0xdd, 0x4d, 0x24, 0xcd, 0x0b, 0x87, 0x43, - 0x1b, 0x3a, 0xc6, 0xaf, 0xc8, 0x54, 0x0c, 0x18, 0x57, 0xd1, 0xbf, 0x05, - 0xff, 0x00, 0x67, 0xbf, 0xd8, 0x7b, 0xe3, 0x0f, 0xc1, 0xb3, 0xa3, 0xe9, - 0xfe, 0x18, 0xf0, 0x34, 0x5a, 0xc8, 0x86, 0x1b, 0x5d, 0x46, 0xf7, 0xc5, - 0xb3, 0xdd, 0x5a, 0x6b, 0x92, 0x5e, 0x18, 0x42, 0x3a, 0x59, 0xdb, 0xc6, - 0x65, 0xb5, 0x95, 0x8c, 0xc4, 0x98, 0xda, 0x46, 0x51, 0xb5, 0x01, 0x96, - 0x0e, 0x41, 0x3e, 0xde, 0x17, 0x83, 0xf0, 0x55, 0x2d, 0x4e, 0xa2, 0x69, - 0xa5, 0x7d, 0x64, 0xd2, 0xb6, 0xbb, 0x2e, 0xb7, 0xf2, 0x6c, 0xc6, 0xf5, - 0x5c, 0xac, 0xda, 0x3f, 0x0e, 0xb5, 0xff, 0x00, 0xda, 0x0f, 0xed, 0x9a, - 0xbb, 0xda, 0xe8, 0x7a, 0x8e, 0xbb, 0xa7, 0x94, 0x21, 0xd8, 0xdd, 0xcf, - 0x95, 0xc1, 0x3c, 0x28, 0x55, 0x94, 0x6d, 0xe3, 0xfb, 0xcc, 0x7e, 0x95, - 0x9f, 0xab, 0xfc, 0x6a, 0xf1, 0x15, 0xc5, 0x93, 0xdc, 0xdb, 0x78, 0xae, - 0xea, 0x08, 0xbe, 0x48, 0x61, 0x8d, 0xd9, 0x24, 0x99, 0xe5, 0x23, 0x24, - 0x66, 0xdd, 0xb7, 0xf6, 0x3c, 0x14, 0x07, 0xa7, 0x24, 0xd7, 0xea, 0xcc, - 0x3f, 0xf0, 0x4f, 0x7f, 0x81, 0x9e, 0x07, 0xf1, 0xc3, 0x78, 0x7b, 0xc6, - 0x7a, 0x15, 0xb4, 0xba, 0x8e, 0xa9, 0xac, 0xdb, 0x6a, 0x1a, 0x5c, 0x9e, - 0x1c, 0xf1, 0x85, 0x95, 0x99, 0x02, 0x79, 0x04, 0x09, 0x6d, 0x04, 0x32, - 0xd9, 0x5d, 0xc5, 0x2d, 0xab, 0xcf, 0xb8, 0x00, 0x63, 0xf3, 0x97, 0x85, - 0xd8, 0x54, 0x12, 0xdf, 0x70, 0xfc, 0x5c, 0xff, 0x00, 0x82, 0x4a, 0xfe, - 0xc4, 0x96, 0x3f, 0x0c, 0xa3, 0xd7, 0x6e, 0xa3, 0xf1, 0x77, 0x87, 0x75, - 0xb3, 0x75, 0x25, 0xdc, 0x3a, 0x3b, 0xdf, 0xd9, 0xc9, 0x79, 0x1b, 0xe5, - 0x99, 0x61, 0x68, 0x63, 0xb3, 0xf3, 0x66, 0x54, 0x54, 0x60, 0x8f, 0xb8, - 0x06, 0x05, 0x4e, 0xd0, 0x32, 0xab, 0xee, 0xd3, 0xe1, 0xcc, 0x2d, 0x3a, - 0x52, 0x92, 0x76, 0xe4, 0x57, 0x77, 0x49, 0x3b, 0x79, 0x5d, 0x5a, 0xef, - 0xb5, 0xfe, 0xf3, 0x38, 0xe1, 0x6a, 0x4a, 0xfa, 0x9f, 0x80, 0xde, 0x0c, - 0x3a, 0xb6, 0xa5, 0xa5, 0x4f, 0xaa, 0x78, 0x93, 0xc6, 0xda, 0xcb, 0xcb, - 0x0a, 0x3c, 0x83, 0x4f, 0xb2, 0x32, 0x99, 0x51, 0x97, 0x8f, 0xde, 0xf0, - 0xec, 0x99, 0x6e, 0x00, 0x61, 0xed, 0xc1, 0xa9, 0xb4, 0x1b, 0xed, 0x37, - 0x53, 0xb1, 0x9b, 0x5b, 0xd5, 0xfe, 0x21, 0x5e, 0xe9, 0x91, 0xc5, 0xbd, - 0x61, 0x85, 0x1a, 0x2b, 0xd9, 0xdc, 0xae, 0x0e, 0x5a, 0x0b, 0xa9, 0xa2, - 0xca, 0xe0, 0xf5, 0x4c, 0x91, 0xd4, 0xa8, 0x1c, 0xd7, 0x73, 0xfb, 0x4f, - 0x69, 0xff, 0x00, 0xb2, 0xcf, 0xc2, 0x3d, 0x06, 0x1f, 0x0e, 0xf8, 0x0e, - 0xc2, 0xf6, 0x0b, 0xf8, 0xef, 0x21, 0xb9, 0xbf, 0x92, 0xe4, 0xdc, 0x4f, - 0xa8, 0x0f, 0x25, 0x36, 0xfc, 0xd1, 0xcc, 0xfe, 0x4b, 0x39, 0xdc, 0x0c, - 0xb1, 0x3a, 0xac, 0x71, 0x90, 0x81, 0x9f, 0x92, 0x95, 0xf1, 0x6e, 0x93, - 0xe0, 0x1d, 0x6f, 0xe2, 0x1c, 0x56, 0xf2, 0x68, 0xba, 0x0d, 0xf3, 0xb3, - 0x4b, 0x24, 0xb7, 0x17, 0xf7, 0x52, 0x88, 0xe2, 0x98, 0xba, 0x2c, 0x8b, - 0x1c, 0x51, 0xd9, 0x59, 0x92, 0x82, 0x25, 0x60, 0x15, 0x99, 0xb6, 0x93, - 0x9c, 0x95, 0x1c, 0x2f, 0x89, 0x86, 0xc2, 0x29, 0x27, 0x5a, 0x55, 0x5a, - 0x57, 0xed, 0x14, 0xad, 0xe5, 0x74, 0xbf, 0xaf, 0xc2, 0x5d, 0x2b, 0x3e, - 0x57, 0xfa, 0x9f, 0x49, 0x2f, 0x8c, 0xfe, 0x1d, 0xdc, 0x58, 0x48, 0x20, - 0xf1, 0x6f, 0x8a, 0x6f, 0x25, 0x8f, 0x20, 0xdd, 0xc6, 0x96, 0x71, 0xc4, - 0x1c, 0x63, 0xe5, 0x68, 0x4a, 0x92, 0xc4, 0x93, 0xd0, 0x48, 0xb8, 0xc8, - 0x19, 0x6e, 0x33, 0xcd, 0x78, 0x73, 0xc4, 0x5a, 0x7e, 0xa7, 0xaa, 0x32, - 0xea, 0x5e, 0x2e, 0xd5, 0xb4, 0x7b, 0x21, 0x38, 0x56, 0xbe, 0xbe, 0xb4, - 0x12, 0xc2, 0x01, 0x5d, 0xd8, 0x22, 0x34, 0x99, 0x81, 0xc1, 0xc8, 0xda, - 0xac, 0x00, 0xeb, 0xe9, 0x5f, 0x3d, 0x68, 0x96, 0x5e, 0x38, 0xf0, 0xf4, - 0xf2, 0x4d, 0x6d, 0xe1, 0x4d, 0x37, 0x54, 0x4b, 0x8b, 0xe5, 0x89, 0xed, - 0x2e, 0x7c, 0xc9, 0x9e, 0x56, 0x5d, 0xbb, 0x81, 0xb9, 0x8e, 0x6d, 0xd0, - 0x6f, 0x0d, 0xc3, 0x89, 0x53, 0x0c, 0x09, 0x52, 0x73, 0x5f, 0x5d, 0xfc, - 0x56, 0xfd, 0xb0, 0xfc, 0x65, 0xf1, 0x43, 0x46, 0xd1, 0xbe, 0x1a, 0x5d, - 0x78, 0x1b, 0xc1, 0xde, 0x06, 0xb2, 0xd1, 0x8c, 0x11, 0x35, 0xbe, 0x8f, - 0x02, 0xdf, 0x5f, 0x08, 0x18, 0x36, 0xd8, 0xe6, 0xb8, 0xbd, 0xb8, 0x96, - 0x6b, 0x86, 0xf9, 0x87, 0xca, 0xf3, 0x33, 0x73, 0x8f, 0x97, 0x21, 0x6b, - 0xd4, 0xfa, 0x85, 0x25, 0x09, 0x4e, 0x15, 0x5b, 0x6e, 0xda, 0x5e, 0x3b, - 0x75, 0x7b, 0x3f, 0xf8, 0x73, 0x29, 0x2e, 0xe7, 0xa7, 0x5b, 0xf8, 0x3f, - 0xe1, 0xee, 0xa3, 0xaf, 0x59, 0xe8, 0x7e, 0x1f, 0xf8, 0x81, 0xfd, 0xa4, - 0xd7, 0xc8, 0x25, 0xb7, 0xd4, 0x75, 0x48, 0x3f, 0xb2, 0xad, 0x58, 0x3e, - 0x55, 0x5f, 0x33, 0x5b, 0xf1, 0x19, 0x6c, 0xe1, 0xdb, 0x0a, 0x71, 0xce, - 0x06, 0x4d, 0x7a, 0xd6, 0x9d, 0xfb, 0x31, 0x78, 0x9e, 0x7d, 0x4e, 0x3b, - 0x0d, 0x2f, 0xc6, 0x7a, 0x1c, 0xf2, 0x99, 0x9a, 0x28, 0xe4, 0x86, 0xfb, - 0x47, 0x91, 0x1c, 0x82, 0xbf, 0x28, 0x2d, 0x23, 0x45, 0x26, 0x37, 0x0c, - 0x95, 0xce, 0x73, 0xc0, 0xaf, 0xcf, 0x27, 0xd7, 0xbc, 0x49, 0x7f, 0xa6, - 0xea, 0x9a, 0x0e, 0x9b, 0x1e, 0x87, 0x78, 0xa8, 0x96, 0x86, 0xd6, 0x34, - 0xd3, 0xed, 0x3c, 0xfb, 0x7b, 0x3b, 0xd2, 0x42, 0x22, 0xdc, 0xed, 0x12, - 0xc7, 0x21, 0x38, 0x59, 0x32, 0x8d, 0x22, 0x11, 0x86, 0x60, 0x46, 0x2b, - 0xd3, 0xfe, 0x1d, 0xfc, 0x30, 0xf8, 0xe1, 0xae, 0xf8, 0x23, 0x42, 0xf1, - 0x9f, 0xc3, 0xff, 0x00, 0x0b, 0xdd, 0xea, 0x03, 0x52, 0xd7, 0x0e, 0x8f, - 0x64, 0xb0, 0x16, 0x90, 0xde, 0x4b, 0x17, 0xcd, 0x29, 0x58, 0x51, 0x5b, - 0xf7, 0x11, 0xe7, 0x12, 0x5c, 0x4c, 0x52, 0x35, 0x3b, 0x07, 0x4c, 0xd7, - 0x5c, 0x78, 0x7d, 0x56, 0x8b, 0x71, 0x6e, 0x2f, 0xe4, 0xd5, 0xbe, 0x69, - 0x7f, 0x97, 0x4d, 0x74, 0x32, 0x75, 0xda, 0xd2, 0xd7, 0x3f, 0x62, 0x3e, - 0x14, 0x7f, 0xc1, 0x34, 0xfe, 0x32, 0xfc, 0x54, 0x5b, 0x8d, 0x3f, 0xc2, - 0x3e, 0x2a, 0xf0, 0xf4, 0x13, 0xdb, 0x81, 0x2c, 0x96, 0xd0, 0xdf, 0x5b, - 0xad, 0xe3, 0x37, 0x46, 0xc4, 0x96, 0x90, 0x10, 0x17, 0x27, 0xee, 0x17, - 0xe0, 0xe3, 0x8c, 0x74, 0xf7, 0xbb, 0x6f, 0xf8, 0x24, 0x5f, 0xc7, 0x5d, - 0x2a, 0xd7, 0xcd, 0xf1, 0x57, 0x8a, 0xa5, 0x8a, 0x22, 0xe7, 0x25, 0xb5, - 0x68, 0x8c, 0x45, 0x41, 0x3b, 0x49, 0x69, 0x1a, 0x1c, 0x67, 0x18, 0xeb, - 0x8c, 0x9e, 0xb5, 0xf1, 0x6e, 0x97, 0xf0, 0x33, 0xf6, 0xb8, 0xf8, 0x25, - 0xf0, 0xd6, 0xf3, 0xe2, 0xa7, 0xc6, 0xef, 0x01, 0xdc, 0xbd, 0xb4, 0x7a, - 0x9c, 0x36, 0xab, 0xf6, 0xeb, 0xe9, 0x22, 0x8e, 0xdd, 0x2e, 0x97, 0x08, - 0xcf, 0x67, 0x6d, 0x11, 0x2b, 0x19, 0x77, 0x53, 0x13, 0xc7, 0x34, 0x64, - 0x12, 0x01, 0x45, 0xc1, 0xaf, 0xdc, 0xdf, 0xd8, 0x9f, 0xe0, 0x57, 0xc3, - 0xcf, 0x8a, 0x9e, 0x00, 0xb3, 0xf8, 0xa3, 0xe2, 0x3d, 0x2b, 0x5e, 0xd2, - 0x6f, 0xe3, 0xcd, 0xb3, 0xd8, 0xc9, 0x77, 0x3f, 0x93, 0x30, 0x08, 0x81, - 0xd9, 0xe2, 0xbb, 0x8e, 0x49, 0x42, 0x86, 0x2c, 0x15, 0x44, 0xac, 0x07, - 0xcc, 0x72, 0x0b, 0x10, 0x3e, 0x9b, 0x2b, 0xe0, 0x8c, 0x3b, 0xaa, 0xb0, - 0xd5, 0x69, 0x4a, 0x53, 0x6a, 0xea, 0xf2, 0xb2, 0x6b, 0xbb, 0xf7, 0x34, - 0xfd, 0x76, 0x3a, 0x68, 0xe2, 0x9c, 0x9d, 0xad, 0x6f, 0xbc, 0xf9, 0x63, - 0xc1, 0x7f, 0xf0, 0x4c, 0x06, 0xd5, 0x66, 0x16, 0xcd, 0x33, 0x4e, 0x8a, - 0xc8, 0xaf, 0x72, 0xba, 0xad, 0x95, 0xd2, 0xc9, 0x93, 0x86, 0x3b, 0x52, - 0x77, 0x2b, 0x83, 0xd4, 0x02, 0xde, 0xd9, 0x3c, 0x57, 0xbb, 0xe8, 0xdf, - 0xf0, 0x49, 0x8f, 0x83, 0x37, 0x17, 0x5f, 0x60, 0xf1, 0x5b, 0xf8, 0xac, - 0x4e, 0xf3, 0x32, 0x6e, 0xd3, 0x66, 0xb2, 0x10, 0xed, 0x50, 0x09, 0x21, - 0xe4, 0x8c, 0x60, 0x1e, 0xdd, 0x4f, 0xb0, 0xe9, 0x5f, 0xad, 0xfe, 0x0b, - 0xf0, 0x6f, 0x82, 0xb4, 0x98, 0xb7, 0xe8, 0x16, 0xd1, 0x83, 0x0b, 0xec, - 0xde, 0xd1, 0xed, 0x64, 0x60, 0x07, 0x19, 0x2a, 0x0e, 0x40, 0xc5, 0x7a, - 0x7c, 0x56, 0xe3, 0x18, 0xe0, 0x0f, 0x6a, 0xfb, 0xdc, 0x3f, 0x86, 0x19, - 0x6d, 0x94, 0xaa, 0x41, 0x37, 0x7f, 0x2d, 0xbe, 0x49, 0x7e, 0xa7, 0x5c, - 0x25, 0xe4, 0x7e, 0x40, 0x6a, 0xdf, 0xf0, 0x49, 0x7f, 0x82, 0xf1, 0x79, - 0x50, 0xe8, 0x16, 0x3a, 0x84, 0x91, 0x2c, 0x80, 0xc9, 0x2d, 0xd6, 0xba, - 0x04, 0xcc, 0xbf, 0xee, 0x0d, 0x35, 0xa3, 0xe3, 0xeb, 0x9f, 0x7a, 0xe7, - 0x6f, 0xbf, 0xe0, 0x94, 0xf0, 0xd9, 0x78, 0x91, 0xe7, 0xf0, 0xd4, 0x7e, - 0x1f, 0x9b, 0x48, 0x0b, 0xb9, 0x2d, 0x75, 0x7b, 0xab, 0xb3, 0x3e, 0xe2, - 0x39, 0x50, 0xd6, 0xb1, 0x44, 0xa0, 0x67, 0xa1, 0xce, 0x7d, 0xab, 0xf6, - 0xb0, 0x40, 0xa0, 0x0c, 0x11, 0xf8, 0xd3, 0xfc, 0xa1, 0xea, 0x2b, 0xba, - 0xaf, 0x87, 0x19, 0x4c, 0x9b, 0x7e, 0xca, 0xde, 0x96, 0x56, 0xfb, 0x96, - 0xbf, 0x3b, 0x97, 0xce, 0xed, 0x63, 0xf9, 0xf4, 0xb8, 0xff, 0x00, 0x82, - 0x5b, 0x7c, 0x48, 0xb8, 0xf1, 0x28, 0x82, 0x7d, 0x0f, 0xc3, 0x89, 0xa7, - 0xb6, 0xef, 0x32, 0x7b, 0x1d, 0x62, 0xf1, 0x07, 0x24, 0x81, 0x8f, 0x3f, - 0xcd, 0x7c, 0x81, 0x82, 0x47, 0x97, 0x83, 0xd3, 0x23, 0xad, 0x7b, 0xce, - 0x97, 0xff, 0x00, 0x04, 0x6d, 0xf8, 0x0b, 0x77, 0x6f, 0x24, 0x9e, 0x22, - 0xbb, 0xd5, 0xa0, 0xb8, 0x64, 0xc4, 0x5f, 0x60, 0xbb, 0x49, 0x91, 0x5c, - 0x8f, 0xbc, 0x44, 0xb6, 0xa8, 0xdc, 0x1e, 0xdb, 0xce, 0x7d, 0x6b, 0xf6, - 0x44, 0xa2, 0x8f, 0x4a, 0x4c, 0x28, 0xe9, 0x4b, 0x0d, 0xe1, 0xce, 0x55, - 0x4e, 0x72, 0x9f, 0xb3, 0x6e, 0xfd, 0xde, 0xde, 0x96, 0xb1, 0x3c, 0xc7, - 0xe4, 0x1e, 0x81, 0xff, 0x00, 0x04, 0x71, 0xf8, 0x0b, 0x61, 0x7d, 0xe7, - 0x6b, 0xda, 0xce, 0xb7, 0x7f, 0x6e, 0xa0, 0xf9, 0x70, 0x44, 0xb1, 0xdb, - 0x3e, 0x4f, 0x4d, 0xf2, 0x2e, 0xfd, 0xc0, 0x0e, 0xa3, 0x68, 0xcf, 0x5c, - 0x8a, 0xee, 0x2d, 0xff, 0x00, 0xe0, 0x96, 0xff, 0x00, 0x04, 0x34, 0xc9, - 0xcc, 0x16, 0x56, 0xf3, 0xc9, 0x6a, 0x33, 0x82, 0x6e, 0xee, 0x62, 0x9c, - 0x13, 0xfc, 0x41, 0xc4, 0xcc, 0xa4, 0x8e, 0xa3, 0x28, 0x07, 0xb6, 0x38, - 0xaf, 0xd4, 0x6d, 0xcb, 0xd6, 0x8c, 0xad, 0x6c, 0xfc, 0x3d, 0xca, 0x79, - 0x79, 0x7d, 0x87, 0x5b, 0xeb, 0x29, 0x3f, 0xcd, 0xbb, 0xaf, 0x27, 0xa1, - 0x4a, 0x76, 0xe8, 0x7e, 0x36, 0xf8, 0x97, 0xfe, 0x09, 0xaf, 0xe2, 0x6d, - 0x03, 0x5a, 0x92, 0xd7, 0xe1, 0x75, 0xf4, 0x57, 0x7a, 0x7c, 0x8a, 0x5d, - 0x27, 0xf1, 0x1c, 0xe2, 0x59, 0x21, 0x38, 0x3f, 0x22, 0x84, 0x8f, 0x71, - 0x1d, 0x00, 0x39, 0xe4, 0xf5, 0x03, 0xad, 0x79, 0xae, 0xb1, 0xfb, 0x06, - 0x7c, 0x77, 0xd3, 0xec, 0x24, 0xd4, 0x6f, 0x1e, 0xda, 0x2e, 0x19, 0x5a, - 0xdb, 0x45, 0xb7, 0x82, 0x79, 0x24, 0xc0, 0xe1, 0x86, 0x59, 0x4a, 0x9e, - 0xdc, 0x06, 0x3f, 0x9d, 0x7e, 0xee, 0x6e, 0x1d, 0x29, 0xc3, 0x19, 0xaf, - 0x17, 0x15, 0xe1, 0x2e, 0x55, 0x52, 0x4e, 0x50, 0xe6, 0x85, 0xee, 0xec, - 0x9e, 0x9f, 0x73, 0xe9, 0xf3, 0x29, 0x55, 0x67, 0xf3, 0x8f, 0x61, 0xfb, - 0x14, 0x7e, 0xd3, 0x48, 0xf1, 0xbc, 0xda, 0x5d, 0x8c, 0xf6, 0x73, 0xc4, - 0xb3, 0xc7, 0x2e, 0xa4, 0xf7, 0xc6, 0x61, 0xbd, 0xb1, 0xb1, 0xa3, 0x8a, - 0x09, 0x4a, 0xc8, 0x01, 0xe8, 0x7e, 0x51, 0xea, 0x79, 0xaf, 0xa1, 0x74, - 0xbf, 0xd8, 0x7b, 0xf6, 0x82, 0xb3, 0xd3, 0x9a, 0x7b, 0x5d, 0x2b, 0xc0, - 0x8b, 0x28, 0xdb, 0x12, 0xc7, 0xfe, 0x96, 0x25, 0x3b, 0x17, 0x87, 0x7d, - 0xde, 0x5a, 0x10, 0xd9, 0xe7, 0x6b, 0x72, 0x7a, 0x8f, 0x4f, 0xdb, 0x70, - 0xc3, 0x1c, 0x60, 0x1a, 0x42, 0xcd, 0xed, 0x59, 0xe0, 0x7c, 0x24, 0xcb, - 0x28, 0xdf, 0x76, 0xfb, 0xde, 0xcc, 0x97, 0x51, 0xbe, 0xa7, 0xf3, 0xdb, - 0xf1, 0x1f, 0xc1, 0x9f, 0xb6, 0x17, 0xc2, 0x1b, 0xc4, 0xbc, 0x7d, 0x3f, - 0xc2, 0xf6, 0xf6, 0xcd, 0x22, 0xda, 0x47, 0x6d, 0xa7, 0x03, 0x14, 0x32, - 0xb1, 0x56, 0x65, 0x76, 0xf3, 0xa1, 0x69, 0x00, 0x38, 0x20, 0x9f, 0x34, - 0x0e, 0x00, 0xe7, 0x35, 0xf3, 0x16, 0xab, 0xfb, 0x46, 0xfc, 0x5e, 0x32, - 0x24, 0x3a, 0x81, 0x96, 0xde, 0xe3, 0x24, 0x98, 0x6d, 0x17, 0x30, 0xb2, - 0x8c, 0x91, 0x86, 0xb6, 0xdb, 0x26, 0xd1, 0xdd, 0x88, 0x3c, 0x77, 0xaf, - 0xe9, 0xeb, 0x55, 0xf0, 0x27, 0x86, 0x75, 0x9d, 0x60, 0x6b, 0xba, 0x9c, - 0x53, 0x49, 0x70, 0x0a, 0x95, 0x22, 0x79, 0x55, 0x46, 0xc1, 0x80, 0x02, - 0x2b, 0x01, 0x8f, 0x5e, 0x39, 0x35, 0xf0, 0xff, 0x00, 0xc7, 0x4f, 0x1c, - 0xfe, 0xc1, 0xfe, 0x1d, 0xb4, 0xbd, 0xf0, 0x9f, 0x8e, 0xf5, 0x3f, 0x0c, - 0x69, 0xba, 0x8c, 0x56, 0xb7, 0x12, 0xc5, 0xa4, 0xea, 0x1a, 0x95, 0xde, - 0x8f, 0x6d, 0x24, 0xf6, 0xe8, 0xca, 0x44, 0xde, 0x41, 0x45, 0x0e, 0x77, - 0x60, 0xb1, 0x56, 0x91, 0x87, 0x40, 0xd8, 0xaf, 0x9f, 0xcd, 0x7c, 0x38, - 0x74, 0x54, 0xb9, 0x31, 0x56, 0x4e, 0xf6, 0x53, 0x9b, 0xfc, 0x34, 0x7f, - 0x86, 0xbd, 0x35, 0x07, 0x37, 0xba, 0x91, 0xf8, 0x29, 0x7f, 0xfb, 0x71, - 0x7c, 0x5c, 0xd1, 0x2e, 0xc5, 0x8d, 0xb6, 0x8b, 0x60, 0xd0, 0x39, 0xd9, - 0x23, 0x6a, 0x03, 0x54, 0xb8, 0xbb, 0x45, 0xe0, 0x19, 0x23, 0x55, 0x68, - 0xd0, 0x83, 0x9c, 0xae, 0xe6, 0x52, 0x7d, 0x00, 0xad, 0x49, 0x7f, 0x6e, - 0x8f, 0x19, 0xc9, 0xe1, 0x51, 0x75, 0x1e, 0x9c, 0x6e, 0x24, 0xb6, 0x99, - 0xd7, 0xed, 0x30, 0xcb, 0x2d, 0xb1, 0x91, 0x88, 0x25, 0x41, 0x86, 0x69, - 0xa2, 0x5c, 0x0c, 0x72, 0x00, 0x27, 0x3d, 0x33, 0xc8, 0x3f, 0x3f, 0x7e, - 0xd1, 0xbf, 0x16, 0xfc, 0x3d, 0xab, 0xdc, 0xbf, 0x83, 0xf4, 0xdd, 0x03, - 0xc3, 0x96, 0x56, 0xbf, 0xe9, 0x53, 0xbd, 0xd5, 0xa6, 0xb7, 0x3d, 0xd1, - 0x48, 0xe3, 0xdc, 0x20, 0xf2, 0x65, 0xf3, 0x5d, 0x54, 0x4c, 0x85, 0x64, - 0x53, 0x2c, 0x09, 0x21, 0x1d, 0x02, 0x8a, 0xf8, 0x47, 0x47, 0x9e, 0xdb, - 0xe2, 0x57, 0x8b, 0x2d, 0xf4, 0x2b, 0x46, 0xd6, 0x75, 0x6d, 0x5a, 0xe2, - 0xf8, 0xd9, 0x47, 0xa7, 0x69, 0xf7, 0xb0, 0x1b, 0x34, 0x62, 0x9f, 0xbb, - 0x76, 0xbb, 0xb8, 0x69, 0x6d, 0x41, 0x92, 0x5f, 0x90, 0x87, 0x55, 0x3d, - 0x43, 0x1c, 0x9c, 0x9f, 0xca, 0xaa, 0x51, 0xc5, 0x42, 0x4a, 0x14, 0xea, - 0x35, 0x6e, 0xcd, 0xf9, 0xef, 0x7b, 0x6f, 0xfa, 0x1c, 0xf2, 0xac, 0xef, - 0x6b, 0xdc, 0xfb, 0x23, 0x53, 0xff, 0x00, 0x82, 0x91, 0xf8, 0xe4, 0xf9, - 0xf6, 0x1a, 0xfe, 0x81, 0x6b, 0x34, 0x20, 0x96, 0x8a, 0x5b, 0xcb, 0xb9, - 0xed, 0xee, 0x62, 0x0b, 0x9d, 0xc4, 0xab, 0xba, 0x21, 0x1c, 0xf1, 0xb4, - 0xb0, 0xe8, 0x01, 0x26, 0xae, 0xf8, 0x7b, 0xf6, 0xbb, 0xf0, 0x27, 0x88, - 0x4a, 0xea, 0x7e, 0x25, 0xb2, 0xd7, 0xee, 0xad, 0x61, 0x90, 0x4b, 0x7f, - 0x0e, 0x8e, 0xb6, 0xf6, 0x88, 0x88, 0x46, 0x0a, 0x7d, 0xaa, 0x6b, 0xa9, - 0x32, 0xc0, 0x91, 0x8c, 0xae, 0x4e, 0x71, 0xc6, 0x2b, 0xc5, 0x3e, 0x24, - 0xfc, 0x0b, 0xd2, 0x7e, 0x19, 0xdf, 0xa6, 0x87, 0xa8, 0x4d, 0x02, 0xdf, - 0x40, 0x62, 0x8b, 0x55, 0xf0, 0xe5, 0xdc, 0x30, 0x5c, 0x5c, 0xc3, 0x34, - 0x8a, 0x15, 0x76, 0x48, 0x87, 0xc8, 0x99, 0x49, 0xe4, 0xb4, 0x6d, 0xb9, - 0x0f, 0x45, 0xc6, 0x4d, 0x79, 0x95, 0xd7, 0xc7, 0xfb, 0xdf, 0x08, 0xe9, - 0x83, 0xc1, 0x3e, 0x16, 0xbf, 0x8a, 0x2b, 0x78, 0x27, 0x96, 0x51, 0x6a, - 0xe1, 0x67, 0xb4, 0x67, 0x42, 0x02, 0xc6, 0x62, 0x02, 0x4d, 0x8b, 0xc0, - 0xc1, 0x55, 0x11, 0x8f, 0x94, 0x83, 0x9a, 0xf2, 0x71, 0xf8, 0xd8, 0xce, - 0xa2, 0x4a, 0x12, 0x94, 0x96, 0x8f, 0x57, 0xa7, 0xad, 0xfa, 0xf9, 0x7d, - 0xe4, 0xa9, 0x4e, 0x37, 0xe6, 0x67, 0xff, 0xd0, 0xfc, 0x0c, 0xd6, 0x24, - 0xd4, 0xb4, 0x5b, 0x84, 0xba, 0x67, 0x90, 0x4e, 0xaa, 0x51, 0x58, 0x48, - 0xca, 0xc3, 0x1c, 0xe1, 0xb6, 0xba, 0x8e, 0x18, 0x67, 0x04, 0x63, 0xd8, - 0xf5, 0xae, 0x93, 0xc1, 0x9f, 0xb4, 0x07, 0xc4, 0xaf, 0x87, 0xb2, 0x48, - 0xfe, 0x1c, 0xd5, 0x2e, 0x6c, 0x1d, 0xc0, 0x53, 0x71, 0x61, 0x3b, 0x5a, - 0xce, 0x08, 0xe4, 0x17, 0x74, 0x70, 0x79, 0x03, 0x38, 0xcf, 0x3f, 0x95, - 0x7e, 0x88, 0x6a, 0xdf, 0xb1, 0x4f, 0xc7, 0x3f, 0x11, 0x5b, 0x49, 0xac, - 0x78, 0x3f, 0xc0, 0x1e, 0x2f, 0xbf, 0xd2, 0x6c, 0xa5, 0xb8, 0x82, 0xe6, - 0x7b, 0x1b, 0x71, 0xa8, 0x2c, 0xc2, 0x29, 0x17, 0x7b, 0xb5, 0xd5, 0xad, - 0x9a, 0x22, 0x86, 0xdd, 0x84, 0x29, 0x6e, 0x77, 0x8d, 0xa5, 0x01, 0x51, - 0x9a, 0xf8, 0xbb, 0xe3, 0x77, 0x84, 0xac, 0xda, 0xd2, 0xc3, 0xc2, 0x5e, - 0x05, 0xbd, 0xfb, 0x64, 0xd6, 0xde, 0x6c, 0xfa, 0xbe, 0x98, 0xb6, 0x9f, - 0x62, 0x97, 0x4e, 0x9a, 0xd8, 0x3f, 0x99, 0x14, 0xa8, 0x23, 0x8c, 0x12, - 0x8a, 0xad, 0xe6, 0xbe, 0xd0, 0xc5, 0x87, 0xdd, 0x23, 0x00, 0x7f, 0x3b, - 0xc6, 0x54, 0xeb, 0x25, 0x29, 0xc1, 0x38, 0xf7, 0xfc, 0xba, 0x68, 0x7c, - 0xfa, 0xa2, 0xd0, 0xe9, 0xff, 0x00, 0x69, 0xcf, 0x8a, 0x3e, 0x24, 0xd4, - 0x93, 0x5f, 0xbe, 0xf1, 0x26, 0xa5, 0x71, 0x38, 0x54, 0x92, 0x39, 0xef, - 0x6f, 0xa6, 0x69, 0x16, 0x40, 0x32, 0x85, 0x18, 0xbb, 0x64, 0x00, 0x30, - 0xad, 0x93, 0xb3, 0x91, 0xc0, 0xc5, 0x7d, 0xd7, 0xe0, 0xaf, 0xdb, 0x57, - 0x4d, 0xbe, 0xf8, 0x57, 0x3f, 0x84, 0x35, 0xfd, 0x25, 0x9f, 0x52, 0xbf, - 0x48, 0x66, 0x59, 0x74, 0xc8, 0x60, 0x8a, 0xce, 0x59, 0x6c, 0x3c, 0xb4, - 0x78, 0xcb, 0x48, 0x24, 0x8c, 0x6f, 0x88, 0x02, 0xe5, 0x62, 0x93, 0x05, - 0x73, 0xb2, 0x3d, 0xee, 0xc7, 0xf1, 0x37, 0x41, 0xf0, 0xe5, 0xfe, 0xac, - 0x6e, 0x75, 0x7b, 0xc7, 0x92, 0xda, 0xc2, 0x26, 0x10, 0xab, 0x92, 0xf8, - 0x33, 0x0c, 0x16, 0x8f, 0x05, 0x15, 0xce, 0xd1, 0x91, 0x8c, 0x01, 0xbb, - 0x00, 0x13, 0xc9, 0xab, 0x3a, 0xf7, 0xc4, 0x6b, 0x7f, 0x09, 0x4b, 0x06, - 0x9f, 0xe0, 0xd9, 0x27, 0x8e, 0xee, 0x37, 0xf3, 0x4d, 0xdc, 0x8f, 0xf2, - 0x20, 0x44, 0xd8, 0xcd, 0x1a, 0x93, 0x8c, 0xb2, 0x02, 0xa5, 0x73, 0x86, - 0x52, 0x54, 0xe4, 0x64, 0x0e, 0xa9, 0x65, 0x70, 0x9c, 0x9a, 0xa5, 0x6b, - 0xf5, 0xf2, 0xf5, 0x7e, 0x46, 0x94, 0xa2, 0xd3, 0x76, 0x3f, 0x41, 0x3c, - 0x79, 0xfb, 0x47, 0x78, 0xdf, 0xc3, 0x7e, 0x33, 0xbc, 0xd5, 0x7c, 0x29, - 0x2d, 0xed, 0xb3, 0xa4, 0xe8, 0x66, 0x8e, 0xe1, 0xa3, 0xb9, 0x96, 0x07, - 0x0e, 0xd2, 0x94, 0x1b, 0xa1, 0x55, 0x54, 0x57, 0x73, 0xc2, 0xae, 0x30, - 0x48, 0x38, 0x52, 0x6a, 0xdf, 0x8a, 0x7f, 0x6f, 0xdf, 0xda, 0xc3, 0xe3, - 0x34, 0xd6, 0x3e, 0x1d, 0xd7, 0xfc, 0x59, 0xab, 0x7f, 0xa0, 0x6f, 0x96, - 0x39, 0x04, 0xad, 0xe7, 0x6e, 0x50, 0x63, 0x65, 0x63, 0x95, 0x2d, 0xf2, - 0x12, 0xa1, 0x33, 0x8c, 0x64, 0x10, 0x73, 0x8a, 0xf3, 0xaf, 0x81, 0x5f, - 0x09, 0xef, 0x3e, 0x26, 0x78, 0xfe, 0x4f, 0x84, 0x3e, 0x10, 0xb6, 0xd4, - 0x7c, 0x55, 0xe2, 0xed, 0x7f, 0x4e, 0xb7, 0xba, 0xb2, 0xd4, 0xec, 0x6e, - 0x2e, 0x26, 0x5d, 0x32, 0x0c, 0x94, 0xbc, 0xb9, 0x68, 0xde, 0x01, 0xe6, - 0x61, 0x15, 0xcf, 0x96, 0x84, 0x82, 0x1a, 0x33, 0x90, 0x37, 0x57, 0xaa, - 0xf8, 0xf3, 0x4a, 0xd0, 0x3e, 0x0d, 0x29, 0xf8, 0x59, 0x73, 0xa4, 0xac, - 0xba, 0xc0, 0xb4, 0x87, 0x59, 0xb5, 0x4b, 0xbd, 0x3e, 0x5b, 0x7d, 0x72, - 0xca, 0xee, 0x47, 0x21, 0xe6, 0x96, 0x5d, 0x83, 0x7d, 0xbe, 0xdd, 0xbb, - 0xe3, 0xb9, 0x12, 0x44, 0xcb, 0x22, 0xaa, 0x46, 0x24, 0x05, 0x85, 0x54, - 0xc2, 0x53, 0xc3, 0xd0, 0x56, 0xd5, 0xb5, 0xf2, 0xdb, 0x77, 0xbd, 0xfe, - 0x7b, 0x75, 0x34, 0x54, 0xe5, 0xb2, 0x66, 0x72, 0x7e, 0xcb, 0xbe, 0x34, - 0xf1, 0x71, 0xba, 0xf1, 0x2e, 0xa5, 0xa8, 0x5d, 0xea, 0x10, 0x46, 0x11, - 0xae, 0x6e, 0x2f, 0x96, 0x54, 0x90, 0xc4, 0xe8, 0x24, 0x46, 0x91, 0xa4, - 0x79, 0xc2, 0xfe, 0xef, 0x24, 0xb0, 0x05, 0x55, 0x81, 0x50, 0x18, 0x2e, - 0x4d, 0xaf, 0x03, 0xfe, 0xcf, 0xf0, 0xde, 0x5d, 0xc7, 0x77, 0xa6, 0xeb, - 0xb1, 0xdc, 0x69, 0x56, 0xec, 0x27, 0xd4, 0x34, 0x9b, 0xab, 0x98, 0x56, - 0xe1, 0x54, 0xb6, 0xd9, 0xd6, 0x3b, 0x65, 0x7f, 0xde, 0xba, 0xaa, 0xe4, - 0xec, 0x51, 0x21, 0x50, 0x1b, 0xe5, 0x5c, 0x11, 0xe2, 0xd6, 0x7e, 0x3b, - 0xbf, 0xf1, 0xd5, 0xa4, 0xda, 0xb7, 0x8a, 0xfc, 0x47, 0x74, 0xe6, 0xea, - 0x0f, 0xb4, 0x26, 0x93, 0x63, 0x9d, 0x3e, 0xc5, 0x2e, 0xc1, 0x2e, 0x5f, - 0xc8, 0x8a, 0x07, 0x45, 0xde, 0xa5, 0x95, 0x11, 0x36, 0x37, 0x98, 0xb9, - 0xf9, 0x50, 0x80, 0x79, 0x2d, 0x7b, 0xe2, 0x5f, 0x8f, 0x3c, 0x55, 0x6b, - 0x05, 0xd4, 0x37, 0x9a, 0xb5, 0xad, 0x85, 0x85, 0xb7, 0xf6, 0x6d, 0x81, - 0xb8, 0x99, 0xa0, 0x82, 0x55, 0xb4, 0x42, 0xe2, 0x3c, 0x1f, 0x95, 0x9c, - 0x92, 0x19, 0x51, 0x57, 0x83, 0xd7, 0xb9, 0xaf, 0x3a, 0x9e, 0x17, 0x11, - 0x56, 0x32, 0x8c, 0xaa, 0x5f, 0x4b, 0x69, 0xa2, 0x5e, 0x7b, 0x7d, 0xcb, - 0xf2, 0x1f, 0x22, 0x4f, 0x63, 0xe9, 0x88, 0x8e, 0xa3, 0xe0, 0x1d, 0x4a, - 0x6b, 0x8f, 0x0f, 0xc0, 0xff, 0x00, 0x66, 0x22, 0x69, 0xac, 0xe7, 0xbd, - 0x84, 0xc7, 0x71, 0xe4, 0xa3, 0xe5, 0x8a, 0xbc, 0x89, 0xe6, 0x6d, 0x46, - 0xf9, 0x02, 0xf9, 0xaf, 0xdb, 0x3d, 0x98, 0x50, 0xd7, 0xf5, 0xbf, 0x14, - 0x78, 0xbc, 0x59, 0x78, 0xd7, 0x51, 0x4b, 0x69, 0xca, 0x9f, 0x2a, 0x6b, - 0x7b, 0x5d, 0xb1, 0x5c, 0x15, 0x00, 0x85, 0x91, 0x53, 0xe4, 0xf3, 0x46, - 0x08, 0x22, 0x46, 0xf4, 0xc0, 0xc8, 0x53, 0x5f, 0x0d, 0x3f, 0xc5, 0x2f, - 0x1e, 0xc8, 0x12, 0x79, 0xb5, 0x29, 0x21, 0x8e, 0x29, 0xfe, 0x54, 0x67, - 0xc4, 0x8f, 0xd7, 0x86, 0xc9, 0xc1, 0xe0, 0x1e, 0x54, 0x60, 0x7a, 0x9c, - 0x8a, 0xee, 0x61, 0xf8, 0xa5, 0xe2, 0x7b, 0x99, 0xed, 0x53, 0x50, 0x9e, - 0x18, 0x56, 0x08, 0xd5, 0x2d, 0xa2, 0xb1, 0x09, 0x0b, 0xe5, 0xc0, 0xdc, - 0x84, 0xa7, 0xcc, 0xfb, 0xf1, 0x9e, 0x72, 0x14, 0x9c, 0xa8, 0x5c, 0x91, - 0x59, 0x50, 0xe1, 0x89, 0x27, 0xcf, 0x2f, 0x79, 0xbd, 0x9f, 0x51, 0x4e, - 0x37, 0x3e, 0xc6, 0xf0, 0xdf, 0x8d, 0xbc, 0x3d, 0x61, 0xa9, 0xf9, 0xdf, - 0x11, 0xfc, 0x3f, 0x73, 0x0c, 0x93, 0xac, 0xab, 0x0d, 0xf6, 0x9e, 0x22, - 0xbe, 0x46, 0xde, 0xd9, 0x56, 0x92, 0x27, 0x72, 0x06, 0xd1, 0x85, 0xc8, - 0x70, 0xd9, 0xc9, 0x07, 0x02, 0xbf, 0x61, 0x7f, 0x64, 0xdf, 0xda, 0x37, - 0xe0, 0x8f, 0xc3, 0x9d, 0x52, 0xd9, 0xbc, 0x5f, 0xe1, 0x75, 0xd5, 0xde, - 0x0f, 0x2a, 0x7b, 0x4b, 0xdf, 0x0c, 0x5d, 0x43, 0x67, 0x7d, 0xe4, 0xef, - 0x62, 0xb3, 0xc9, 0x04, 0xc6, 0x31, 0x24, 0x9b, 0xb2, 0x36, 0x34, 0x8e, - 0x06, 0x3e, 0x5c, 0x16, 0x2c, 0xdf, 0x84, 0xde, 0x08, 0xbf, 0xb9, 0x9e, - 0x47, 0xbf, 0x9d, 0x25, 0x0b, 0x2e, 0xfb, 0x49, 0x65, 0x8e, 0x64, 0x88, - 0x74, 0x2e, 0xc0, 0x92, 0x64, 0x56, 0x52, 0xb9, 0x39, 0x03, 0x2c, 0x73, - 0xc7, 0x51, 0x5e, 0xad, 0xa1, 0xf8, 0x32, 0xd8, 0x49, 0x24, 0xf6, 0xfa, - 0xf5, 0xfc, 0x13, 0xc0, 0x9f, 0xe8, 0x73, 0x3a, 0xa4, 0xcd, 0x0c, 0x4b, - 0x20, 0xdc, 0x52, 0x21, 0xb6, 0x42, 0x9c, 0xb7, 0x39, 0x55, 0xc6, 0x32, - 0x38, 0xc1, 0x98, 0x61, 0x5e, 0x12, 0xb2, 0x97, 0x32, 0x5e, 0x4d, 0x5f, - 0xf3, 0xbf, 0xf5, 0xb5, 0x8c, 0x35, 0x47, 0xf6, 0xbf, 0xf0, 0xeb, 0xfe, - 0x0a, 0x69, 0xf0, 0x22, 0xdb, 0xc4, 0x17, 0x1e, 0x1a, 0xd4, 0x75, 0x2d, - 0x67, 0x5b, 0x47, 0x48, 0xd2, 0x08, 0xb5, 0x31, 0xa6, 0x58, 0x3c, 0x13, - 0x03, 0xb4, 0xa7, 0x9c, 0xf2, 0x40, 0x8e, 0x72, 0x76, 0xb9, 0x24, 0x85, - 0x65, 0xe1, 0xd9, 0x4e, 0xea, 0xfb, 0x0f, 0x41, 0xfd, 0xa2, 0xfe, 0x03, - 0xfc, 0x3d, 0xf8, 0x7b, 0x75, 0xe3, 0xaf, 0x16, 0xde, 0xe8, 0x7e, 0x1d, - 0x12, 0x4e, 0xb3, 0xcb, 0xa1, 0xd8, 0x6a, 0x36, 0xf7, 0xd7, 0x50, 0x87, - 0x55, 0xc3, 0x4b, 0x0c, 0x2c, 0x02, 0xcd, 0xb4, 0x65, 0xe3, 0x8c, 0x36, - 0xc0, 0xb8, 0x24, 0x9c, 0x81, 0xfc, 0x31, 0x78, 0x1f, 0xc4, 0x3a, 0x87, - 0x84, 0x74, 0x4b, 0xad, 0x2f, 0x57, 0xd4, 0x12, 0xe6, 0xe6, 0x68, 0xe5, - 0x66, 0x8e, 0x40, 0xd2, 0x39, 0xd8, 0xe4, 0x99, 0x12, 0xdd, 0x5b, 0x69, - 0x91, 0xb8, 0x20, 0xe4, 0x67, 0xd3, 0x8c, 0x1e, 0x8b, 0x59, 0xf1, 0xc4, - 0xda, 0xc5, 0x98, 0x96, 0x53, 0xaf, 0xbd, 0xb4, 0x50, 0x89, 0x27, 0x79, - 0xd2, 0x51, 0x1c, 0xb1, 0x47, 0x21, 0xc4, 0x6e, 0xad, 0xf2, 0xa9, 0x77, - 0x2a, 0x06, 0x42, 0xfa, 0x60, 0x9c, 0x67, 0xea, 0x70, 0x3c, 0x7f, 0x8f, - 0x55, 0x65, 0x19, 0xfb, 0xcb, 0xa6, 0x9a, 0x2f, 0x3e, 0xef, 0xef, 0xef, - 0x74, 0x6f, 0x4e, 0xaf, 0xbb, 0xaa, 0x3f, 0xb6, 0x8f, 0x0d, 0x7e, 0xdf, - 0x3f, 0xb3, 0x9f, 0x8b, 0xf4, 0x1f, 0xf8, 0x48, 0xbc, 0x31, 0x7b, 0x73, - 0x34, 0x1f, 0x6c, 0xfb, 0x20, 0x33, 0xc6, 0xb0, 0xe4, 0x03, 0x83, 0x20, - 0x25, 0xcf, 0xcb, 0xfc, 0x43, 0xb9, 0x1c, 0x8a, 0xfa, 0x83, 0xc0, 0x3f, - 0x14, 0xfe, 0x1d, 0xfc, 0x4a, 0xb5, 0x7b, 0xaf, 0x04, 0xea, 0x96, 0x97, - 0xe2, 0x20, 0xa6, 0x54, 0x86, 0x54, 0x69, 0x13, 0x70, 0xc8, 0xdc, 0xaa, - 0x49, 0x1c, 0xe4, 0x72, 0x39, 0x20, 0xe3, 0x38, 0xcd, 0x7f, 0x0a, 0x1a, - 0x7f, 0xed, 0x07, 0xe2, 0x0d, 0x6b, 0x45, 0xb6, 0xb3, 0xf0, 0xf4, 0xcb, - 0x6c, 0xb1, 0xc0, 0x6e, 0x2e, 0x7c, 0xa7, 0x68, 0x56, 0x45, 0x32, 0xf9, - 0x41, 0x9a, 0x15, 0x79, 0x04, 0x65, 0x30, 0x98, 0x68, 0xc2, 0x0d, 0xad, - 0x8e, 0xb9, 0xcf, 0xec, 0xff, 0x00, 0xfc, 0x12, 0xfb, 0xe2, 0xdf, 0x87, - 0xb5, 0xbf, 0x8a, 0x36, 0x10, 0x6b, 0x9a, 0xa5, 0xf8, 0xf1, 0x0e, 0xa9, - 0x0f, 0xd8, 0xed, 0xac, 0x51, 0x54, 0xc4, 0x2d, 0xa1, 0xdc, 0xf2, 0x79, - 0xc1, 0xc3, 0x9d, 0xa0, 0xaa, 0x04, 0x75, 0x90, 0x1f, 0x9b, 0xa1, 0xce, - 0x6b, 0xd9, 0xc8, 0x38, 0xd7, 0x32, 0xab, 0x8e, 0x8d, 0x1c, 0x53, 0x83, - 0x84, 0x9d, 0x95, 0x93, 0x4d, 0x7c, 0xf5, 0x57, 0xbf, 0xf9, 0x16, 0xf1, - 0x0a, 0xea, 0x36, 0x3f, 0xa4, 0xd7, 0x95, 0x05, 0x55, 0x79, 0xd0, 0xf4, - 0xc9, 0xaa, 0xb8, 0x77, 0xe7, 0x93, 0x51, 0x34, 0x64, 0x73, 0xd2, 0xbf, - 0x66, 0x51, 0x45, 0xb6, 0xfa, 0x22, 0x47, 0x94, 0x91, 0xd7, 0x15, 0x09, - 0xb9, 0x0b, 0xc1, 0x35, 0xe4, 0xfe, 0x3e, 0xf8, 0xe1, 0xf0, 0x9f, 0xe1, - 0x85, 0xf5, 0xbe, 0x97, 0xe3, 0xbd, 0x77, 0x4f, 0xd3, 0xae, 0x2e, 0x83, - 0x34, 0x51, 0x5c, 0x4c, 0xaa, 0x76, 0xa2, 0xb3, 0xb1, 0x39, 0x3c, 0x00, - 0x14, 0xf5, 0xaf, 0x16, 0xb9, 0xfd, 0xb3, 0xbe, 0x00, 0xdd, 0x69, 0x6d, - 0xaa, 0x68, 0xfa, 0x94, 0xd7, 0xc4, 0x16, 0x11, 0x47, 0x6f, 0x17, 0x32, - 0x85, 0x19, 0xdc, 0x85, 0x88, 0x52, 0xa4, 0xf0, 0x0e, 0x73, 0x9e, 0xdd, - 0x33, 0xe6, 0x63, 0x73, 0xfc, 0x06, 0x1a, 0xeb, 0x13, 0x88, 0x8c, 0x3d, - 0x5a, 0x23, 0x99, 0xbd, 0x11, 0xf6, 0x08, 0xba, 0xe0, 0xe3, 0x14, 0xd8, - 0xaf, 0xe2, 0x7e, 0x51, 0x95, 0x86, 0x7a, 0xa9, 0x04, 0x71, 0xef, 0xed, - 0x5f, 0x9a, 0xff, 0x00, 0x14, 0xbf, 0x6a, 0xdd, 0x1b, 0x4b, 0x87, 0x5b, - 0x59, 0x2f, 0xa6, 0x87, 0x4e, 0xb5, 0xd2, 0x13, 0x53, 0x86, 0x6b, 0x59, - 0xa3, 0x33, 0x83, 0x73, 0x11, 0x68, 0x93, 0x64, 0x44, 0xb1, 0x50, 0x40, - 0x2c, 0x58, 0xa9, 0x8f, 0x3f, 0x33, 0x67, 0x02, 0xbe, 0x4e, 0xf0, 0xd7, - 0xfc, 0x14, 0x83, 0xc0, 0xd2, 0x78, 0x4e, 0xdb, 0x4d, 0xf0, 0xfd, 0xf2, - 0xd9, 0x6a, 0xd0, 0xa2, 0x3a, 0xc5, 0x68, 0xf1, 0xc8, 0x97, 0xb2, 0x87, - 0x91, 0xa4, 0x81, 0x63, 0x91, 0x8a, 0xa1, 0x72, 0x77, 0x2b, 0x60, 0xe4, - 0x02, 0x73, 0xd0, 0x57, 0xcd, 0x62, 0xfc, 0x44, 0xcb, 0x68, 0xd5, 0x74, - 0xe5, 0x2d, 0x12, 0x7f, 0x3b, 0x74, 0x5f, 0xa5, 0xda, 0xbd, 0xbb, 0x96, - 0xaf, 0x63, 0xf7, 0x76, 0xe3, 0x57, 0xb1, 0xb1, 0x81, 0xae, 0x6f, 0x24, - 0x48, 0xd1, 0x17, 0x73, 0xbc, 0x8c, 0x14, 0x28, 0xe9, 0x93, 0xe8, 0x2b, - 0x4a, 0x39, 0xc4, 0xb1, 0xac, 0xcb, 0x8d, 0x8e, 0x37, 0x2b, 0xe7, 0xe5, - 0x23, 0x19, 0xc8, 0x3d, 0x3a, 0x57, 0xe2, 0x06, 0xa5, 0xfb, 0x77, 0x78, - 0x67, 0xc5, 0xf6, 0xce, 0xba, 0xbd, 0xdf, 0xf6, 0x4d, 0xed, 0x8e, 0x99, - 0x35, 0xcd, 0xed, 0xed, 0xc0, 0x92, 0xce, 0xd9, 0x2d, 0xf6, 0x00, 0x01, - 0xc8, 0x7d, 0xe1, 0xd9, 0xd4, 0xe5, 0xd3, 0x67, 0xdd, 0x23, 0x39, 0xaf, - 0x8f, 0x7e, 0x20, 0xff, 0x00, 0xc1, 0x5a, 0xfc, 0x51, 0xa2, 0xf8, 0x3e, - 0x4f, 0x00, 0x41, 0x0d, 0xbd, 0xe6, 0x9d, 0xa9, 0x42, 0xd6, 0x96, 0x5a, - 0x95, 0xfc, 0x52, 0xc9, 0x3c, 0x0d, 0x32, 0x06, 0x55, 0x12, 0x07, 0x54, - 0x67, 0x45, 0x65, 0x74, 0x65, 0xdc, 0x39, 0x04, 0x8c, 0x10, 0x07, 0x9b, - 0x5f, 0xc4, 0xec, 0x04, 0x6c, 0xe3, 0x19, 0x34, 0xd6, 0x9a, 0x3f, 0xc7, - 0xb7, 0x6e, 0xa0, 0xa4, 0x96, 0xec, 0xfe, 0x9e, 0x2d, 0x75, 0x8d, 0x27, - 0x50, 0x85, 0x27, 0xd3, 0xee, 0x61, 0x99, 0x58, 0x95, 0x1e, 0x5b, 0xa9, - 0xcb, 0x01, 0x92, 0xbd, 0x73, 0xb8, 0x67, 0x91, 0xd4, 0x77, 0xab, 0x73, - 0xc7, 0x24, 0xf6, 0xef, 0x0c, 0x32, 0x34, 0x2e, 0xe8, 0x42, 0x4a, 0xaa, - 0x09, 0x42, 0x46, 0x03, 0x00, 0xc0, 0x83, 0x8e, 0xbc, 0x8c, 0x57, 0xe0, - 0x7f, 0xec, 0x31, 0xf1, 0x43, 0xe2, 0xbf, 0xc4, 0x4d, 0x61, 0x4d, 0xd7, - 0x88, 0x6c, 0x8d, 0xae, 0x93, 0x6c, 0x75, 0x1b, 0x7d, 0x3e, 0x79, 0x26, - 0x68, 0xda, 0x72, 0xc0, 0x36, 0xff, 0x00, 0x20, 0x2c, 0x72, 0x3e, 0xcf, - 0x2d, 0x5a, 0x35, 0x91, 0xb6, 0x02, 0xa5, 0x8e, 0xe0, 0x54, 0x7e, 0xe3, - 0x69, 0x3e, 0x2a, 0xb2, 0xbd, 0xd2, 0x52, 0xee, 0x6b, 0xdb, 0x57, 0x30, - 0x84, 0x82, 0xf2, 0x60, 0xe1, 0x11, 0x2e, 0x14, 0x28, 0x75, 0x70, 0x48, - 0xd8, 0xdb, 0x8f, 0xdd, 0x6c, 0x11, 0x90, 0x31, 0x5f, 0x51, 0xc3, 0xd9, - 0xda, 0xcc, 0x30, 0xea, 0xba, 0x8f, 0x2d, 0xfc, 0xc6, 0xa4, 0x7c, 0xdd, - 0xab, 0x5a, 0x7c, 0x7a, 0xf0, 0x8f, 0xc5, 0xd9, 0xf5, 0xad, 0x5b, 0x59, - 0xd3, 0xe7, 0xf0, 0xb4, 0xe8, 0xcf, 0x63, 0x14, 0x50, 0x47, 0x1d, 0xdb, - 0x34, 0x0a, 0x64, 0x68, 0xaf, 0xa7, 0x36, 0x8c, 0xb1, 0xdb, 0x95, 0xdf, - 0xb4, 0xa3, 0x02, 0xa5, 0x41, 0x67, 0xf9, 0x8d, 0x7e, 0x7f, 0x7c, 0x76, - 0xfd, 0x94, 0x2c, 0xbe, 0x34, 0xf8, 0xa3, 0x58, 0x1a, 0x55, 0xf7, 0x83, - 0xbc, 0x37, 0xa7, 0xc3, 0x73, 0x3e, 0xad, 0x61, 0xaa, 0xcd, 0x37, 0xdb, - 0x75, 0x08, 0x66, 0x37, 0x0e, 0x62, 0x81, 0x91, 0x04, 0xb6, 0xd6, 0xf0, - 0xbd, 0xc3, 0xef, 0x59, 0x98, 0xbb, 0x80, 0x36, 0x22, 0x46, 0x2b, 0xf4, - 0x2f, 0xf6, 0x8c, 0xf1, 0x8f, 0xc3, 0xa6, 0xf8, 0x63, 0xff, 0x00, 0x09, - 0xac, 0x9e, 0x1f, 0xb5, 0xf1, 0xf4, 0xd6, 0xe9, 0x25, 0xce, 0x91, 0xa7, - 0xe9, 0xee, 0x97, 0x4d, 0x2f, 0xca, 0xd1, 0xbb, 0xa1, 0x8d, 0xff, 0x00, - 0xd5, 0x28, 0x62, 0x24, 0x20, 0x90, 0x01, 0xe8, 0x5b, 0x68, 0x3f, 0x96, - 0x5a, 0x5f, 0xc6, 0x9d, 0x4f, 0xc3, 0xbf, 0x11, 0xaf, 0xbc, 0x13, 0xaf, - 0x5f, 0x68, 0xb3, 0x6a, 0x5a, 0x8d, 0x85, 0xc4, 0xde, 0x20, 0xd0, 0xf5, - 0x9d, 0x1e, 0xcb, 0x50, 0xd3, 0xb4, 0x7b, 0x8b, 0x70, 0x4f, 0xf6, 0x78, - 0x9e, 0x0b, 0x98, 0xcc, 0xb0, 0x46, 0xb2, 0xff, 0x00, 0xab, 0x94, 0x2c, - 0x9b, 0xf0, 0x32, 0x5c, 0xe1, 0x3c, 0x5c, 0xf3, 0x2f, 0xc3, 0xca, 0x2a, - 0x9e, 0x21, 0xf3, 0x45, 0xbd, 0x2e, 0xef, 0xbf, 0x9f, 0xae, 0xd6, 0x7d, - 0x2f, 0xd0, 0x89, 0xd6, 0xb3, 0x51, 0x48, 0xfc, 0xaf, 0xf1, 0x6f, 0x85, - 0x3e, 0x26, 0xf8, 0x29, 0xf5, 0x9d, 0x7f, 0xe2, 0x67, 0x87, 0x3e, 0x1f, - 0xea, 0x97, 0x32, 0xdf, 0xa6, 0x87, 0x13, 0x78, 0x9a, 0x2d, 0x2b, 0x45, - 0x7b, 0x34, 0x8e, 0xd4, 0x94, 0xbc, 0xbf, 0x97, 0x4d, 0x36, 0xf3, 0xbb, - 0xa2, 0x97, 0x92, 0xda, 0x68, 0xcc, 0xc6, 0x79, 0x1e, 0x36, 0x85, 0x9c, - 0x11, 0xe6, 0x7c, 0x05, 0x75, 0xa0, 0xfc, 0x5d, 0xf8, 0x69, 0x6b, 0x69, - 0xae, 0x7c, 0x32, 0x9e, 0xd7, 0x40, 0x81, 0xae, 0xaf, 0x3f, 0xe2, 0xa6, - 0xf0, 0xe4, 0xef, 0x1c, 0xf7, 0x70, 0x87, 0x2e, 0xf1, 0xc5, 0x75, 0x14, - 0xbb, 0x9d, 0xb6, 0xb6, 0x7e, 0x72, 0x65, 0x88, 0x10, 0x0a, 0xed, 0xf9, - 0x0f, 0xed, 0x1f, 0x8f, 0xbc, 0x7b, 0xa1, 0x6a, 0x77, 0xba, 0xac, 0xb0, - 0xe9, 0x7e, 0x0c, 0xf0, 0xa6, 0xb7, 0xab, 0x44, 0xda, 0x87, 0x88, 0x75, - 0x23, 0xa9, 0x89, 0x34, 0x8b, 0xcb, 0x1b, 0x9b, 0x7f, 0x2a, 0x44, 0xb6, - 0x80, 0xfd, 0xa5, 0xa5, 0x8d, 0xd4, 0x79, 0x2d, 0x6d, 0xe5, 0x4b, 0x99, - 0x5b, 0x18, 0x0c, 0x85, 0x47, 0xe6, 0xd7, 0x88, 0x3f, 0x67, 0x8d, 0x5f, - 0xc0, 0x3f, 0x0d, 0xee, 0xbc, 0x51, 0xa9, 0xc5, 0x16, 0x91, 0xa6, 0xea, - 0xfa, 0x95, 0xd5, 0xe6, 0x9d, 0xfd, 0xa3, 0x31, 0x17, 0xfe, 0x62, 0x4a, - 0x13, 0x69, 0x49, 0x08, 0x9e, 0x39, 0x11, 0x5f, 0x6b, 0x27, 0x93, 0x81, - 0xf2, 0xf3, 0xb5, 0x95, 0x8f, 0xe6, 0x3c, 0x51, 0x96, 0x62, 0x29, 0x47, - 0xeb, 0x18, 0x77, 0xa4, 0x77, 0x7a, 0x7e, 0x37, 0xf7, 0xbb, 0x6f, 0xa1, - 0xc5, 0x09, 0x27, 0x2b, 0x1f, 0x97, 0xff, 0x00, 0x19, 0x3c, 0x53, 0xe3, - 0xcf, 0x89, 0x7a, 0xf4, 0xba, 0x9f, 0x8b, 0x75, 0xbb, 0xeb, 0xad, 0x52, - 0xd6, 0xd2, 0x3b, 0x18, 0x2e, 0xf5, 0x2f, 0x32, 0x59, 0x25, 0xb5, 0x45, - 0x2c, 0x8c, 0x92, 0x0c, 0x86, 0x4c, 0xb1, 0x1b, 0x9d, 0x83, 0x73, 0x91, - 0xd0, 0xe3, 0xe6, 0x5b, 0xe8, 0x75, 0xbd, 0x3e, 0x76, 0x9e, 0xee, 0x63, - 0xe7, 0x48, 0x10, 0xab, 0xa3, 0x2b, 0x11, 0x11, 0x24, 0x61, 0xe4, 0x19, - 0x75, 0x72, 0xc0, 0x1c, 0x30, 0x07, 0xbe, 0xec, 0xd7, 0xd7, 0xde, 0x35, - 0xf8, 0x77, 0xe2, 0x5d, 0x52, 0x57, 0xd3, 0xac, 0xe2, 0xd5, 0x2e, 0xa1, - 0x59, 0x61, 0x37, 0x1a, 0x76, 0x9f, 0x66, 0xd3, 0xde, 0x4a, 0x65, 0x0d, - 0x23, 0x49, 0x6b, 0x0a, 0x88, 0xde, 0x41, 0x1a, 0x00, 0xcd, 0x99, 0x0a, - 0x81, 0x92, 0x70, 0x3a, 0x47, 0xa0, 0x7c, 0x0b, 0xf8, 0x8f, 0xe2, 0x2b, - 0x03, 0xe2, 0x7b, 0x4b, 0x1b, 0xbf, 0xec, 0xa8, 0xae, 0xd6, 0xc3, 0x57, - 0xbf, 0xb9, 0x8e, 0xdd, 0x05, 0x94, 0x90, 0x3a, 0x2c, 0x2d, 0x79, 0x04, - 0x4a, 0xee, 0x8a, 0xea, 0xcb, 0x87, 0x90, 0x48, 0x1f, 0x04, 0xff, 0x00, - 0x06, 0x6b, 0xc3, 0xc2, 0xe3, 0x6d, 0x4f, 0xda, 0xb5, 0x74, 0xf7, 0xdf, - 0x6d, 0x3a, 0xb5, 0x7f, 0xe9, 0x5b, 0x7d, 0x07, 0x4e, 0xfb, 0x1f, 0xff, - 0xd1, 0xf2, 0x1d, 0x3b, 0xf6, 0xc1, 0xfd, 0xa0, 0x7c, 0x67, 0x79, 0xa5, - 0xf8, 0x59, 0x1b, 0x54, 0xd2, 0xf4, 0x37, 0x92, 0x09, 0x96, 0x3f, 0x0c, - 0xc1, 0x71, 0xa4, 0x35, 0xe8, 0xc8, 0xda, 0x96, 0xf7, 0x16, 0xb2, 0x47, - 0x70, 0xa1, 0xd1, 0xbf, 0xd6, 0x33, 0x95, 0x64, 0x1c, 0x44, 0xa4, 0x0c, - 0x71, 0x7a, 0xbf, 0xc4, 0x5f, 0x81, 0x3e, 0x21, 0xbd, 0xd5, 0xfe, 0x25, - 0x78, 0xe6, 0xe6, 0x1b, 0x3d, 0x6e, 0x4b, 0xc9, 0x8e, 0x87, 0x77, 0xe2, - 0x2b, 0x18, 0xb5, 0x79, 0x52, 0x65, 0x89, 0xbc, 0xd8, 0xaf, 0x5b, 0x51, - 0x37, 0x17, 0x32, 0xa3, 0x04, 0x81, 0x22, 0x73, 0x24, 0xc0, 0x21, 0x24, - 0x85, 0x2c, 0x58, 0x7e, 0x8a, 0x7e, 0xd8, 0x5f, 0xb3, 0x97, 0xc3, 0x8f, - 0xd9, 0x27, 0xc3, 0x5a, 0xbf, 0x89, 0x3c, 0x71, 0xa9, 0xea, 0x7a, 0x8f, - 0x88, 0xe6, 0xbd, 0x87, 0x48, 0xf0, 0x3e, 0x8d, 0xa6, 0xeb, 0x46, 0x3b, - 0x3b, 0x68, 0xfe, 0xf4, 0x91, 0xde, 0x5b, 0x40, 0x04, 0xea, 0xf6, 0xa9, - 0xb5, 0x4b, 0xcc, 0x1d, 0x4b, 0x7d, 0xe4, 0x6d, 0xc0, 0x0f, 0xe7, 0x07, - 0xe3, 0xff, 0x00, 0xc6, 0xef, 0x89, 0x5f, 0x12, 0x75, 0x9b, 0x8d, 0x0b, - 0xc4, 0xfa, 0xc5, 0xe5, 0xec, 0x50, 0x5c, 0x7e, 0xf6, 0x2d, 0x46, 0x76, - 0x99, 0xa1, 0x98, 0x29, 0x89, 0x84, 0x5b, 0x89, 0x2d, 0x90, 0x36, 0xf2, - 0x03, 0x1e, 0xa4, 0x13, 0x9c, 0xff, 0x00, 0x3c, 0xcb, 0x26, 0xc4, 0x61, - 0xe6, 0xa9, 0xce, 0x76, 0x7d, 0x52, 0x7a, 0x2e, 0xcf, 0xfc, 0x5a, 0xf9, - 0x1e, 0x34, 0x6b, 0xf4, 0x67, 0x85, 0xf8, 0xff, 0x00, 0xc7, 0x10, 0x5c, - 0xde, 0xdf, 0xea, 0xd7, 0xd7, 0x36, 0xda, 0x8d, 0xe5, 0xfb, 0xbd, 0xe4, - 0x4d, 0x6c, 0x8d, 0xf6, 0x75, 0x9e, 0x49, 0x4f, 0x98, 0x36, 0x48, 0x7f, - 0x76, 0x00, 0xc9, 0x45, 0x25, 0x89, 0xf9, 0x72, 0x15, 0x46, 0xda, 0xf9, - 0x9f, 0xc4, 0xe7, 0x53, 0xbf, 0xd4, 0xa4, 0xb7, 0xd5, 0xad, 0x9e, 0xde, - 0xf0, 0x49, 0x2c, 0x32, 0xdb, 0xc8, 0xac, 0x93, 0x2b, 0x8c, 0xee, 0x46, - 0x89, 0xb0, 0xc9, 0xcf, 0x63, 0x93, 0xea, 0x4f, 0x04, 0xfb, 0x2e, 0xa4, - 0x2e, 0xad, 0x5e, 0xea, 0xc0, 0x34, 0x46, 0xe7, 0x6b, 0xdd, 0x46, 0xb2, - 0x28, 0x75, 0x95, 0x8b, 0x63, 0x0b, 0xb8, 0x10, 0xdd, 0xf0, 0x32, 0x72, - 0x32, 0x4d, 0x78, 0x16, 0xa5, 0x79, 0x12, 0x6a, 0xb2, 0xdd, 0x97, 0x90, - 0x1f, 0xb3, 0x15, 0x77, 0x2e, 0x5a, 0x43, 0x20, 0xc8, 0xce, 0xec, 0xe7, - 0x07, 0x23, 0x39, 0xec, 0x6b, 0xeb, 0x72, 0xea, 0x09, 0x41, 0xa4, 0xb5, - 0xfc, 0xff, 0x00, 0x23, 0x6a, 0x4e, 0xe8, 0xfa, 0x2b, 0xc3, 0x3f, 0x12, - 0x7c, 0x61, 0xf0, 0xe2, 0xf7, 0xc3, 0x3f, 0x13, 0xbc, 0x11, 0x05, 0xe4, - 0x5a, 0x85, 0x96, 0x74, 0xc7, 0xd5, 0x94, 0x4a, 0xaa, 0x9f, 0x6a, 0x50, - 0xcb, 0x01, 0x9a, 0x36, 0x01, 0x24, 0x65, 0x46, 0xe0, 0x30, 0x26, 0x32, - 0xf9, 0x04, 0x16, 0x15, 0xdf, 0x5f, 0xfc, 0x53, 0xb8, 0xf0, 0x36, 0xa3, - 0x20, 0xf0, 0x24, 0x07, 0x52, 0xba, 0xbd, 0xb3, 0x16, 0x9a, 0xd4, 0x9a, - 0xba, 0x4b, 0xe4, 0xc5, 0x75, 0x37, 0x37, 0x30, 0x85, 0x8a, 0xe0, 0x07, - 0x5d, 0xdf, 0x2b, 0x06, 0x0a, 0x71, 0x94, 0x38, 0x1b, 0xc1, 0xf3, 0x0d, - 0x7a, 0xfb, 0xc3, 0x77, 0x1e, 0x03, 0xf0, 0xee, 0x8f, 0xa4, 0xea, 0x56, - 0xbf, 0x6b, 0x29, 0x26, 0xa1, 0x7e, 0xb1, 0xc7, 0x2c, 0x1f, 0x65, 0x96, - 0x00, 0xe1, 0x61, 0x9d, 0x8a, 0xed, 0x9a, 0x49, 0x3e, 0x42, 0x8e, 0x87, - 0x11, 0xa9, 0xda, 0x7b, 0x9a, 0xfb, 0x83, 0xf6, 0x6b, 0xf0, 0x6f, 0x88, - 0x7e, 0x21, 0xfc, 0x3d, 0x83, 0xe1, 0x77, 0xc1, 0x9f, 0x02, 0xb5, 0xf7, - 0x88, 0xa7, 0xd4, 0x2e, 0x1b, 0x58, 0xf1, 0x43, 0x42, 0x6e, 0xa5, 0x92, - 0xc1, 0xa2, 0x48, 0x0c, 0x56, 0x2f, 0xb1, 0x3c, 0x90, 0x80, 0xc8, 0xf3, - 0x65, 0x97, 0x74, 0x6f, 0xc9, 0x8c, 0xa9, 0x66, 0xee, 0x8e, 0x40, 0xa7, - 0x18, 0xb4, 0xaf, 0x6f, 0xf3, 0xd2, 0xff, 0x00, 0x7e, 0x86, 0x55, 0x2b, - 0x28, 0xb3, 0xe4, 0x2b, 0x7f, 0x88, 0x16, 0xfe, 0x2d, 0x58, 0xef, 0xfc, - 0x55, 0x15, 0xf3, 0xcb, 0x69, 0x6d, 0x0d, 0x85, 0xb5, 0xc4, 0x13, 0xac, - 0x41, 0x21, 0x51, 0xb4, 0xc3, 0x15, 0xba, 0x95, 0x8c, 0xa6, 0xd6, 0x60, - 0xa1, 0x11, 0x46, 0x09, 0xdd, 0xbb, 0x9c, 0x6f, 0x7c, 0x59, 0xf1, 0xef, - 0x87, 0xf5, 0x4f, 0x0d, 0x5a, 0xcb, 0xe1, 0x9b, 0x2d, 0x62, 0xc2, 0x7b, - 0x56, 0x31, 0xdf, 0xa6, 0xa3, 0xe4, 0x41, 0x0a, 0x79, 0x88, 0x78, 0xb6, - 0x58, 0xf7, 0x48, 0xcc, 0x76, 0xff, 0x00, 0xac, 0x90, 0xfc, 0xc3, 0x0b, - 0x81, 0xb7, 0x2f, 0xf6, 0xcf, 0xc5, 0x9f, 0xd9, 0x0f, 0xc3, 0xdf, 0x06, - 0xed, 0x64, 0x4b, 0xa8, 0xf5, 0x9b, 0x5d, 0x72, 0xfe, 0xe7, 0x4f, 0x5d, - 0x2f, 0x43, 0xb9, 0x8d, 0x4d, 0xf5, 0x80, 0xb9, 0x24, 0xc3, 0xf6, 0xa1, - 0x06, 0x02, 0x4b, 0x30, 0x42, 0xc9, 0x1a, 0xae, 0xe1, 0xca, 0xef, 0x76, - 0x42, 0xb5, 0xf0, 0xff, 0x00, 0x8e, 0x7c, 0x39, 0x77, 0xac, 0x69, 0xba, - 0x8e, 0x83, 0xe6, 0x4d, 0xa9, 0xdc, 0xdc, 0x62, 0x4d, 0x3d, 0xe4, 0xb4, - 0x6f, 0xb7, 0x35, 0xc4, 0x2e, 0x1e, 0x37, 0x56, 0x93, 0x64, 0xe9, 0x1b, - 0xc0, 0x4e, 0x78, 0x70, 0xe7, 0xb7, 0x71, 0xce, 0xf2, 0xe9, 0x53, 0xa8, - 0x95, 0x45, 0x6f, 0xcb, 0xe5, 0xea, 0x61, 0x1c, 0x4a, 0x94, 0x8f, 0x0e, - 0x9f, 0x50, 0xd2, 0x6f, 0x35, 0x54, 0xb5, 0xb1, 0x96, 0xe1, 0xed, 0x7c, - 0xdd, 0xa8, 0xf8, 0xf2, 0x24, 0xc4, 0x85, 0x37, 0x17, 0xcb, 0xc8, 0xaa, - 0x32, 0x76, 0x86, 0xdd, 0xdc, 0x16, 0xce, 0x38, 0x92, 0x2b, 0xbb, 0xfd, - 0x2b, 0xc5, 0x1f, 0xf0, 0x8f, 0xdb, 0x97, 0xdf, 0x04, 0xb2, 0x05, 0x65, - 0x9b, 0x20, 0xc9, 0x1b, 0x1c, 0x9f, 0x35, 0x48, 0xde, 0xa4, 0x00, 0x37, - 0x2f, 0x27, 0xaa, 0xf5, 0x02, 0xba, 0x8b, 0x0f, 0x03, 0xe9, 0xb6, 0xfe, - 0x24, 0xd3, 0x66, 0xd3, 0xc4, 0x76, 0xa8, 0xba, 0x70, 0xba, 0x9d, 0xaf, - 0x1f, 0xe4, 0x33, 0x42, 0x5c, 0x11, 0x94, 0x0b, 0x80, 0xe0, 0x20, 0xc3, - 0x90, 0xc4, 0xf2, 0x71, 0xb8, 0x0a, 0xd2, 0xf0, 0x4e, 0x91, 0xe3, 0x36, - 0xf1, 0xce, 0xa7, 0xe3, 0xdd, 0x0b, 0x4e, 0x8e, 0x54, 0xd0, 0x83, 0xea, - 0x77, 0x61, 0x63, 0x69, 0xe0, 0xb7, 0x59, 0x27, 0x58, 0x83, 0x34, 0x6d, - 0x27, 0x28, 0x92, 0x30, 0x50, 0x1c, 0x95, 0x24, 0x00, 0xf9, 0x04, 0xe7, - 0xdb, 0x8d, 0x04, 0xae, 0xd6, 0xc9, 0x7f, 0x5f, 0x71, 0xd5, 0xed, 0x23, - 0xb9, 0xed, 0xfa, 0x0f, 0xc5, 0x49, 0xf5, 0xbb, 0x58, 0x6c, 0x6f, 0x63, - 0x46, 0x95, 0xfe, 0x69, 0xa4, 0x41, 0x3b, 0xcb, 0x08, 0x25, 0x41, 0x74, - 0x56, 0x32, 0x2a, 0xec, 0x39, 0x01, 0x97, 0x69, 0x1b, 0x8f, 0x71, 0x96, - 0xf4, 0x56, 0xf1, 0x7f, 0x85, 0xbc, 0x27, 0x72, 0xf7, 0x36, 0xfa, 0xba, - 0x5c, 0x45, 0x2d, 0x99, 0x69, 0x20, 0x82, 0x4f, 0xdf, 0x0b, 0x80, 0xbc, - 0xa1, 0x73, 0x21, 0x1b, 0x33, 0x86, 0x2d, 0x9d, 0xe7, 0x90, 0x30, 0x05, - 0x7c, 0x89, 0xe1, 0xcb, 0x2b, 0x9d, 0x63, 0xc5, 0xd7, 0x12, 0xcf, 0x35, - 0xae, 0x9a, 0xcb, 0x25, 0xd3, 0xc7, 0x01, 0x42, 0xb0, 0xab, 0x96, 0xda, - 0x61, 0xb7, 0x89, 0xd9, 0xf2, 0x08, 0x77, 0x0a, 0x0e, 0xe2, 0x0e, 0x39, - 0xcf, 0x23, 0xbe, 0xb6, 0xb9, 0xb6, 0xf8, 0x57, 0xe3, 0xbd, 0x33, 0x5b, - 0xf0, 0xfc, 0xf6, 0x3a, 0x9c, 0xb0, 0x5a, 0xc1, 0xa9, 0xc8, 0xf0, 0x44, - 0xb2, 0xc5, 0x0d, 0xc3, 0xe5, 0xbc, 0x96, 0x59, 0xd3, 0x6c, 0xad, 0x17, - 0x01, 0xf7, 0x26, 0xd2, 0xe0, 0xa8, 0xdc, 0x06, 0xe6, 0xf0, 0xeb, 0x65, - 0x34, 0xe4, 0xd4, 0xb6, 0xf4, 0x32, 0x9c, 0x93, 0xd8, 0xfa, 0x7b, 0xc0, - 0xda, 0xef, 0xc4, 0x2d, 0x72, 0x39, 0x7c, 0x47, 0xa7, 0xc4, 0xfb, 0x44, - 0x4d, 0x2d, 0xbc, 0x32, 0xb2, 0x19, 0x2e, 0x25, 0x42, 0xb9, 0x58, 0x23, - 0x6d, 0xf2, 0xbc, 0xdb, 0x5b, 0x12, 0x6d, 0x1d, 0x08, 0xc9, 0xe4, 0x57, - 0xba, 0xe9, 0x5f, 0x16, 0x6f, 0xfc, 0x2d, 0x75, 0x0b, 0x36, 0xb7, 0x04, - 0x76, 0xf7, 0x76, 0x91, 0xb5, 0xe6, 0x9d, 0x6d, 0x6d, 0x0b, 0x18, 0x7c, - 0xf2, 0x41, 0xf3, 0xa3, 0x91, 0xc0, 0x57, 0x3b, 0x4f, 0x98, 0xac, 0xa3, - 0x67, 0x1c, 0xe0, 0x8c, 0xf8, 0x2c, 0x1e, 0x3c, 0xd2, 0x7c, 0x57, 0xa6, - 0xc9, 0x7a, 0xe9, 0x34, 0x5a, 0xb3, 0x83, 0x2e, 0x9d, 0xa8, 0xbc, 0xc9, - 0x0d, 0xa3, 0x5e, 0x33, 0x00, 0xf2, 0xcf, 0x12, 0x44, 0x1d, 0x4e, 0xc6, - 0xf2, 0xf6, 0x46, 0x4a, 0x65, 0x83, 0x9e, 0x71, 0x9f, 0x18, 0xf1, 0x24, - 0x5a, 0x37, 0x8a, 0x35, 0x14, 0xd5, 0xec, 0xee, 0x64, 0x82, 0xfe, 0xeb, - 0x55, 0x30, 0xde, 0xda, 0xc3, 0x1a, 0x49, 0x1c, 0x50, 0x95, 0xc3, 0xcc, - 0x6e, 0x73, 0xf3, 0x33, 0xee, 0x39, 0xf9, 0x14, 0x00, 0x37, 0x64, 0xe7, - 0x03, 0x87, 0x13, 0x93, 0xe1, 0xea, 0xa6, 0xe5, 0xa3, 0x31, 0xb3, 0xe8, - 0x7e, 0xb1, 0x78, 0x23, 0xc5, 0x1e, 0x0c, 0xf1, 0x2d, 0xb4, 0x56, 0x5e, - 0x1e, 0xbf, 0xb2, 0x99, 0x66, 0x8d, 0x12, 0xe2, 0x78, 0x2d, 0x52, 0xd4, - 0x4b, 0x22, 0xee, 0x06, 0x26, 0x02, 0x46, 0x5e, 0x37, 0x2b, 0xab, 0x85, - 0x25, 0x5f, 0xd4, 0x61, 0x8f, 0xea, 0x87, 0xec, 0x6d, 0xaf, 0xdf, 0xfc, - 0x3a, 0xf8, 0xd3, 0xe1, 0xad, 0x5f, 0xc2, 0x3f, 0xda, 0xfa, 0xdf, 0xf6, - 0x56, 0x04, 0xf6, 0x50, 0xe9, 0x7e, 0x64, 0xf7, 0x20, 0x33, 0x35, 0xc5, - 0xb5, 0xa2, 0x36, 0xe5, 0x39, 0x65, 0x3b, 0x19, 0x5a, 0x32, 0x4e, 0xd6, - 0x1d, 0x48, 0xaf, 0xe7, 0x33, 0xc3, 0x5e, 0x0f, 0x6f, 0x0c, 0xeb, 0xd1, - 0xf8, 0xef, 0xc1, 0xb6, 0x72, 0x1b, 0x7b, 0x49, 0x9e, 0x6b, 0x67, 0xb5, - 0x94, 0xcb, 0x22, 0xc6, 0x08, 0x50, 0xd2, 0x21, 0x18, 0x93, 0x60, 0x26, - 0x47, 0x2c, 0x01, 0xc0, 0x66, 0xda, 0x14, 0x01, 0x5f, 0xbc, 0xff, 0x00, - 0xb2, 0x6f, 0xc4, 0xbf, 0x82, 0x7e, 0x0a, 0xf0, 0xde, 0x99, 0xe3, 0xad, - 0x62, 0xf3, 0x5c, 0xbb, 0xd4, 0x6c, 0x0c, 0x76, 0x92, 0xf8, 0x77, 0x53, - 0xbb, 0xbe, 0x86, 0x3b, 0x9b, 0x88, 0x16, 0x39, 0x5a, 0x4b, 0x29, 0xec, - 0x60, 0x11, 0xc3, 0x20, 0x72, 0x16, 0x23, 0x3c, 0xae, 0x00, 0x20, 0xba, - 0xa7, 0xcb, 0x9f, 0x3b, 0x01, 0x93, 0x38, 0xe2, 0x23, 0x3f, 0x6f, 0xcb, - 0x15, 0xae, 0xba, 0x3d, 0x1d, 0xf4, 0xd5, 0xef, 0xd9, 0xd9, 0xdc, 0xcb, - 0xda, 0xeb, 0x67, 0xd0, 0xfe, 0xbd, 0x7e, 0x18, 0xfc, 0x59, 0x5f, 0x1c, - 0x78, 0x5b, 0x4f, 0xd5, 0x7c, 0x59, 0xa7, 0xcb, 0xe1, 0x8d, 0x53, 0x50, - 0x86, 0x4b, 0xa4, 0xd0, 0xf5, 0x72, 0xb6, 0xf7, 0x4b, 0x12, 0xb6, 0x01, - 0x11, 0xbb, 0x07, 0x6d, 0xa0, 0xa8, 0x73, 0xb4, 0x0d, 0xdd, 0x3e, 0x5c, - 0x13, 0xf2, 0x47, 0xed, 0xb1, 0xfb, 0x6b, 0xe9, 0xff, 0x00, 0xb2, 0xe5, - 0xc6, 0x8f, 0xa3, 0x4b, 0x1d, 0xb4, 0xff, 0x00, 0xf0, 0x91, 0x5b, 0x5c, - 0xc3, 0x15, 0xe4, 0x37, 0x0a, 0xd3, 0x69, 0xf7, 0x20, 0x06, 0xb7, 0x96, - 0x68, 0x70, 0xdf, 0xe8, 0xf2, 0x28, 0x71, 0xbf, 0xbb, 0x0c, 0x0e, 0x86, - 0xbf, 0x0d, 0x7f, 0x6a, 0x3f, 0xda, 0x7b, 0x53, 0xf1, 0x4f, 0xc3, 0x4b, - 0xc7, 0xd0, 0xae, 0xef, 0xac, 0xbf, 0xb2, 0xbc, 0xef, 0xec, 0x2b, 0x9b, - 0x6b, 0xd9, 0x2e, 0xef, 0xed, 0x11, 0x2e, 0x8c, 0xeb, 0xf6, 0xa7, 0x9a, - 0x56, 0x92, 0x59, 0x90, 0x14, 0x89, 0xcb, 0x37, 0xfa, 0xb5, 0x1c, 0x96, - 0xc9, 0xaf, 0xcc, 0xed, 0x4b, 0xf6, 0x9d, 0xd4, 0xee, 0x34, 0xbb, 0x1f, - 0x8a, 0x3f, 0x1b, 0xae, 0x6f, 0x6e, 0x6e, 0x61, 0xb3, 0xfb, 0x13, 0xde, - 0x4b, 0x70, 0xc8, 0x26, 0xdc, 0x02, 0x46, 0xe0, 0xb9, 0x69, 0x19, 0x44, - 0x00, 0x65, 0x1f, 0xca, 0x0b, 0xcf, 0x04, 0xe0, 0xd7, 0xd5, 0xe7, 0xbc, - 0x77, 0x51, 0x50, 0x9d, 0x1c, 0x12, 0xe6, 0x93, 0x49, 0x29, 0x27, 0xae, - 0xab, 0xb5, 0xb7, 0xfc, 0xb7, 0xb2, 0x3a, 0x3e, 0xb3, 0x76, 0xa2, 0x7d, - 0x9b, 0xe2, 0x8d, 0x52, 0x6f, 0xda, 0x17, 0xc4, 0x17, 0xbe, 0x39, 0xb0, - 0xf1, 0x3e, 0xa3, 0x73, 0x74, 0xda, 0x83, 0x6a, 0x17, 0x92, 0xdc, 0xc9, - 0x18, 0x45, 0x8d, 0xe7, 0x69, 0x4d, 0xa4, 0x53, 0x26, 0xed, 0xb0, 0x06, - 0x24, 0xa9, 0x18, 0xc0, 0x1d, 0x0e, 0x45, 0x78, 0x56, 0xb3, 0xf1, 0xd7, - 0x52, 0xf8, 0x5f, 0x76, 0xfa, 0x7d, 0xf4, 0xf7, 0xa9, 0xa6, 0xda, 0xa0, - 0x9e, 0x14, 0xfb, 0x47, 0x9d, 0x77, 0x79, 0x21, 0x2d, 0xbd, 0x1f, 0x80, - 0xbc, 0x11, 0xc3, 0x60, 0xe4, 0x11, 0xca, 0x90, 0x48, 0xf0, 0x6b, 0x6f, - 0x8c, 0x1a, 0x4e, 0x87, 0xa3, 0x3f, 0x89, 0x34, 0x5b, 0xb7, 0x8a, 0x2b, - 0xa7, 0x37, 0x33, 0xc7, 0x6f, 0x37, 0x97, 0xb6, 0x29, 0x57, 0x69, 0xf2, - 0xf6, 0xb1, 0x2a, 0xbb, 0x18, 0x3f, 0xcd, 0xf3, 0x73, 0xc0, 0x03, 0x04, - 0x7c, 0xe1, 0xfb, 0x40, 0x7c, 0x4e, 0xd0, 0x26, 0xf0, 0xe8, 0x16, 0xfa, - 0xb4, 0xd7, 0x92, 0x37, 0xef, 0xe7, 0x9c, 0xce, 0x43, 0xc7, 0x1c, 0x8a, - 0x07, 0x94, 0x9b, 0x24, 0x00, 0x29, 0x18, 0x57, 0x38, 0xce, 0x08, 0xc8, - 0x23, 0xa7, 0xe0, 0xd1, 0xc0, 0xe2, 0x71, 0xb5, 0x9c, 0x2b, 0xbe, 0x64, - 0xde, 0xfb, 0xbf, 0xbd, 0x7f, 0x5a, 0xf7, 0xd4, 0xdb, 0x9a, 0x2a, 0xdc, - 0xba, 0x33, 0xd3, 0xfc, 0x75, 0xfb, 0x79, 0x68, 0xfa, 0xd1, 0xbc, 0xd2, - 0xb4, 0x87, 0xd5, 0x2d, 0xee, 0xe5, 0x50, 0xf7, 0x16, 0x7f, 0xbd, 0x0b, - 0x32, 0x4b, 0x8c, 0x89, 0x06, 0xf6, 0x03, 0x19, 0xf9, 0xf0, 0xac, 0x73, - 0x93, 0xce, 0xd0, 0x2b, 0xe4, 0x0f, 0x0d, 0x7e, 0xd4, 0x17, 0x9a, 0x07, - 0x8d, 0xe3, 0xb7, 0xb5, 0xb2, 0x4d, 0x02, 0xe1, 0x2f, 0x3c, 0xc8, 0xa5, - 0xf2, 0x16, 0xe2, 0xe4, 0x2b, 0x11, 0x90, 0x5e, 0x76, 0x40, 0xbb, 0x9b, - 0x6b, 0x72, 0x47, 0x04, 0x60, 0xed, 0xe2, 0xbe, 0x27, 0xf1, 0x87, 0x8b, - 0x56, 0xeb, 0x5e, 0xb9, 0xd3, 0x74, 0x19, 0xa1, 0xb5, 0x12, 0x49, 0xf2, - 0x30, 0x91, 0xc2, 0x65, 0x06, 0x14, 0x92, 0x77, 0x31, 0x04, 0x12, 0x47, - 0xd3, 0xa7, 0x27, 0x35, 0x6c, 0xad, 0x7e, 0xdf, 0x30, 0xd6, 0x3c, 0x50, - 0xf3, 0x8b, 0x79, 0x16, 0x4b, 0x88, 0x2e, 0x6d, 0xe4, 0x0c, 0xeb, 0x2a, - 0xe1, 0x46, 0x51, 0xcb, 0x00, 0x09, 0x20, 0x00, 0x40, 0x1b, 0x78, 0x07, - 0x18, 0xaf, 0xbd, 0xcb, 0xf8, 0x57, 0x0d, 0x41, 0x49, 0xa4, 0xf6, 0xea, - 0xdd, 0xef, 0xe5, 0xfd, 0x32, 0x64, 0xa4, 0xde, 0xa7, 0xee, 0xae, 0x8d, - 0xfb, 0x56, 0x1f, 0x11, 0x78, 0xe2, 0xca, 0x3b, 0xad, 0x6f, 0x54, 0xb6, - 0x55, 0xf2, 0x5f, 0x50, 0xd5, 0xa3, 0x53, 0x23, 0x5b, 0x5b, 0x38, 0x48, - 0xe7, 0x79, 0x22, 0x88, 0x86, 0x96, 0x1d, 0xfb, 0x8a, 0xc4, 0xe7, 0x6a, - 0x80, 0x15, 0x48, 0x6c, 0x9a, 0xc6, 0xf8, 0xc3, 0xf1, 0x67, 0xc0, 0xfe, - 0x2f, 0x7d, 0x37, 0x4f, 0x9a, 0xfa, 0xce, 0x5b, 0x1d, 0x1a, 0x25, 0xb0, - 0xb4, 0x1a, 0x5e, 0xeb, 0x54, 0x90, 0x5a, 0x33, 0x94, 0x99, 0xe0, 0x00, - 0x28, 0x92, 0x61, 0xb4, 0xc9, 0xb4, 0x97, 0x60, 0x76, 0xe7, 0x03, 0x35, - 0xf8, 0xd5, 0xa2, 0x78, 0xd3, 0x58, 0xd2, 0x96, 0x28, 0xad, 0x6e, 0x36, - 0x9b, 0xc2, 0xb1, 0xb2, 0xce, 0x44, 0x1e, 0x58, 0x90, 0x7c, 0xa1, 0xe4, - 0x04, 0x06, 0x0c, 0xaa, 0x77, 0x7c, 0xa0, 0x7c, 0xa3, 0x8e, 0x95, 0xf4, - 0xe7, 0xc0, 0xdb, 0x4f, 0x0e, 0x7c, 0x45, 0x87, 0x54, 0xb3, 0xd7, 0x64, - 0x8a, 0xce, 0x48, 0x20, 0x9a, 0xdc, 0xdd, 0xea, 0x31, 0xca, 0xad, 0x1d, - 0xc0, 0x06, 0x28, 0xad, 0xc2, 0x96, 0x76, 0x32, 0x6e, 0x2a, 0xc1, 0xc6, - 0xd4, 0x04, 0x10, 0x54, 0x92, 0x2b, 0xcf, 0xc4, 0xe5, 0x3e, 0xcd, 0x73, - 0xb9, 0xf2, 0xc7, 0xab, 0xff, 0x00, 0x81, 0xfd, 0x3e, 0xdd, 0x89, 0xe4, - 0x67, 0xec, 0x5f, 0xc2, 0x2f, 0xf8, 0x28, 0x00, 0xf8, 0x5b, 0x69, 0x37, - 0x80, 0x7c, 0x12, 0x6d, 0x74, 0xf4, 0x96, 0xe1, 0x26, 0x7b, 0xc6, 0x55, - 0x69, 0xa2, 0x5c, 0xf2, 0xb6, 0xf2, 0x46, 0x54, 0x21, 0x7c, 0xb1, 0xdd, - 0xb7, 0x78, 0x18, 0x42, 0xc7, 0x35, 0xea, 0x7e, 0x23, 0xfd, 0xa9, 0xfe, - 0x30, 0xda, 0xdc, 0xdf, 0xf8, 0x8f, 0x4f, 0xf1, 0x75, 0xe5, 0xdb, 0x6b, - 0xf0, 0x99, 0xbc, 0x45, 0x66, 0x2f, 0x1a, 0x33, 0x72, 0x62, 0x54, 0x68, - 0xe5, 0x6d, 0x8c, 0x32, 0xa0, 0x2a, 0x8d, 0xa8, 0x43, 0xee, 0x52, 0x55, - 0x81, 0x2d, 0x5f, 0x81, 0xff, 0x00, 0x10, 0x7e, 0x1e, 0xf8, 0xcf, 0xe0, - 0x7b, 0x36, 0xa7, 0xa6, 0xa5, 0xed, 0xf5, 0x92, 0x42, 0xb1, 0x5d, 0x5f, - 0xc6, 0x64, 0x56, 0x85, 0x83, 0x04, 0x0d, 0x95, 0x2c, 0x0c, 0x6d, 0x9c, - 0x8e, 0x71, 0x82, 0x47, 0x5a, 0xe4, 0x34, 0x7f, 0x8b, 0x9a, 0x8d, 0x84, - 0xd1, 0x26, 0xa6, 0x97, 0x88, 0x66, 0x52, 0xb6, 0x9b, 0xc3, 0x42, 0x8e, - 0xe9, 0xd5, 0xc3, 0x93, 0x86, 0x65, 0xc8, 0x07, 0x8e, 0x3b, 0xf6, 0xae, - 0x3a, 0x38, 0x5c, 0x54, 0x9c, 0x65, 0x85, 0xc4, 0xb7, 0x05, 0x7d, 0x9b, - 0xb5, 0xfa, 0xe9, 0x75, 0x67, 0xbf, 0xc9, 0x8e, 0x53, 0x76, 0x3f, 0x72, - 0x1f, 0xf6, 0xc8, 0xf8, 0x89, 0x67, 0x70, 0xbe, 0x06, 0xf0, 0x36, 0xad, - 0x3d, 0x8d, 0xc5, 0xd5, 0xbf, 0xf6, 0x4c, 0x52, 0x48, 0x76, 0x39, 0x5b, - 0x80, 0xc0, 0xc0, 0x5a, 0x63, 0x29, 0x8a, 0x36, 0x66, 0x2a, 0xc2, 0x27, - 0x53, 0x28, 0x20, 0x1e, 0x82, 0xbb, 0x0f, 0x82, 0x1f, 0x16, 0x7c, 0x1f, - 0xe3, 0xad, 0x2f, 0x58, 0x1f, 0x11, 0xae, 0x7f, 0xb6, 0x3c, 0x40, 0xd2, - 0x45, 0x69, 0xa4, 0x69, 0x70, 0x49, 0x79, 0x1d, 0xa5, 0xe6, 0x56, 0xde, - 0x02, 0xf3, 0xc4, 0xd2, 0xa1, 0x90, 0xe4, 0x39, 0x25, 0x1d, 0x59, 0x9a, - 0x21, 0xf2, 0xe3, 0x0c, 0xbf, 0x82, 0x1a, 0x47, 0xc5, 0xcf, 0x15, 0x78, - 0x8f, 0x5f, 0x93, 0x4c, 0xf0, 0xcd, 0xcb, 0x4f, 0x70, 0x1f, 0x6b, 0x49, - 0x72, 0xc8, 0x1e, 0x29, 0x94, 0x73, 0x92, 0x5b, 0x20, 0x83, 0x81, 0xd3, - 0x21, 0xb3, 0x8c, 0xf5, 0xaf, 0xe8, 0x27, 0xf6, 0x0b, 0xfd, 0x83, 0xfc, - 0x4e, 0xda, 0xd7, 0x86, 0x6e, 0xfc, 0x41, 0xe2, 0x5f, 0x0d, 0xe9, 0x3e, - 0x36, 0x96, 0xfa, 0xdf, 0xc4, 0x76, 0x5a, 0x6e, 0xa9, 0x75, 0xe4, 0xf9, - 0x96, 0xca, 0xd1, 0xbc, 0x2e, 0x8d, 0xf6, 0x79, 0x09, 0xdb, 0x0b, 0x8b, - 0x9d, 0x92, 0x15, 0xdd, 0x88, 0xc4, 0x61, 0x8b, 0x19, 0x57, 0xed, 0x72, - 0x7c, 0x36, 0x31, 0xb5, 0x4e, 0xb4, 0xae, 0xb4, 0x56, 0x6e, 0xfb, 0xed, - 0xbf, 0xe1, 0xf7, 0x9c, 0x2d, 0xbb, 0xec, 0x7e, 0xb9, 0x7c, 0x1e, 0xfd, - 0x9f, 0xff, 0x00, 0x65, 0x7f, 0x86, 0xde, 0x24, 0xd2, 0x3c, 0x6f, 0xfb, - 0x4d, 0xcd, 0xa6, 0x5b, 0x5d, 0x78, 0x8e, 0xc1, 0x0e, 0x99, 0xab, 0x34, - 0x4b, 0x77, 0xa1, 0xca, 0x6f, 0xad, 0x9a, 0x48, 0xa4, 0x8e, 0xfa, 0xe2, - 0xea, 0xe6, 0x06, 0x09, 0x0c, 0x86, 0x21, 0xf6, 0xab, 0x76, 0x53, 0xf2, - 0x48, 0x0e, 0xf6, 0x04, 0x7d, 0xb9, 0x65, 0xfb, 0x16, 0x7c, 0x3b, 0x79, - 0xa3, 0x99, 0x74, 0x3f, 0x09, 0x6a, 0x9a, 0x44, 0x3a, 0xa5, 0xac, 0xda, - 0x24, 0x90, 0xc7, 0x35, 0xac, 0x56, 0xba, 0x7c, 0xd3, 0x89, 0x6e, 0x25, - 0x8a, 0x28, 0x65, 0x74, 0x6b, 0xa3, 0x21, 0x25, 0x4e, 0x23, 0x86, 0x2e, - 0x4c, 0x48, 0x09, 0x20, 0xfc, 0xdd, 0xfb, 0x44, 0xfc, 0x65, 0xf8, 0x21, - 0xe1, 0xbd, 0x0a, 0x3f, 0x00, 0x69, 0x1e, 0x09, 0xd3, 0xaf, 0xa7, 0xb3, - 0x81, 0xb4, 0x7b, 0x96, 0x36, 0x4d, 0x6b, 0x6d, 0x6f, 0x77, 0x6d, 0xbb, - 0xce, 0x5b, 0x6b, 0x29, 0x59, 0x8c, 0x31, 0x3e, 0xf6, 0x7d, 0x8c, 0x15, - 0xd9, 0x64, 0x52, 0x72, 0xbf, 0x35, 0x7a, 0x67, 0xec, 0xe5, 0xfb, 0x59, - 0xf8, 0x32, 0xd7, 0x5e, 0x97, 0xc3, 0x13, 0x98, 0x62, 0x8e, 0x41, 0x25, - 0xdc, 0x49, 0x1c, 0xa1, 0x96, 0xc2, 0xd1, 0x44, 0xb3, 0x6c, 0x32, 0x10, - 0xa1, 0xce, 0xf3, 0xf3, 0x31, 0x27, 0x73, 0x12, 0xc4, 0x92, 0x4d, 0x7e, - 0x99, 0x82, 0xa9, 0x83, 0xa7, 0x27, 0x84, 0xa9, 0x6e, 0x57, 0xe5, 0xa5, - 0xdf, 0x47, 0x7d, 0x19, 0xd4, 0xf4, 0xd9, 0x1e, 0xdb, 0xfb, 0x53, 0xfe, - 0xcb, 0x9f, 0xb2, 0x8e, 0xae, 0xde, 0x19, 0xd7, 0x7c, 0x49, 0x6b, 0x6b, - 0xa1, 0x6a, 0xf6, 0x97, 0xad, 0xa4, 0xf8, 0x63, 0xfb, 0x17, 0x4f, 0xb4, - 0x37, 0x13, 0xcc, 0xd6, 0xec, 0xe9, 0x64, 0x8b, 0xe5, 0xab, 0x79, 0x40, - 0x44, 0xcf, 0x85, 0x91, 0x3e, 0x63, 0xcb, 0xe0, 0x85, 0xaf, 0xe7, 0x0f, - 0xc6, 0x5f, 0xb4, 0x37, 0xc2, 0xaf, 0x85, 0x5e, 0x17, 0xbd, 0xf8, 0x71, - 0xf0, 0xae, 0xd1, 0x2e, 0x74, 0xdd, 0x0b, 0x5a, 0xbe, 0x09, 0xa8, 0x6a, - 0x31, 0xc6, 0x9a, 0x7e, 0xa1, 0x75, 0x23, 0xb2, 0xcf, 0x6f, 0xa9, 0xc1, - 0x2b, 0x5c, 0x49, 0x34, 0x50, 0x44, 0x86, 0x18, 0xe3, 0x8c, 0x34, 0x6a, - 0xad, 0xb8, 0x0d, 0xee, 0x09, 0xfd, 0xb6, 0xfd, 0xb8, 0xe6, 0xf0, 0x0f, - 0xc6, 0xbb, 0xad, 0x20, 0xe8, 0xd2, 0xe9, 0x33, 0x6a, 0x3a, 0x6a, 0xdb, - 0x46, 0x2e, 0x75, 0x3b, 0xa8, 0x55, 0x21, 0x17, 0x8c, 0x5c, 0x88, 0xe3, - 0x2b, 0x2a, 0xf9, 0x8a, 0x8b, 0x99, 0x4b, 0x23, 0x2a, 0xa9, 0x1c, 0x1c, - 0xf3, 0xf2, 0x1f, 0xc4, 0x4f, 0xd8, 0xde, 0xcb, 0xe2, 0xa7, 0x8c, 0xb4, - 0x0f, 0x0a, 0xdd, 0x0f, 0x04, 0x78, 0xb2, 0xcc, 0xde, 0x41, 0x26, 0xbb, - 0xa8, 0xf8, 0x6a, 0xc5, 0x77, 0x43, 0x0a, 0x4e, 0xed, 0xb5, 0xd1, 0x64, - 0xc4, 0x02, 0x28, 0xd4, 0x15, 0x78, 0xd3, 0x05, 0xe5, 0x29, 0x8c, 0x63, - 0x3f, 0x1d, 0xc5, 0xb9, 0x74, 0xf1, 0x15, 0xa7, 0x47, 0x08, 0x94, 0x6d, - 0x65, 0x75, 0xd5, 0x3b, 0x2b, 0x7e, 0x1d, 0x17, 0x4f, 0x93, 0xe8, 0x73, - 0xfb, 0x49, 0x1f, 0xff, 0xd2, 0xe4, 0xff, 0x00, 0x6b, 0xaf, 0x89, 0xbe, - 0x00, 0xf8, 0xb3, 0xf1, 0x63, 0x5c, 0xf1, 0x04, 0x2d, 0x71, 0xa9, 0x6a, - 0x3f, 0x64, 0x8e, 0x48, 0xae, 0x7c, 0x42, 0x2d, 0x91, 0xae, 0x2e, 0xc3, - 0x30, 0x90, 0xd9, 0x08, 0x56, 0x18, 0xa4, 0x0e, 0xb9, 0x1b, 0xd5, 0x19, - 0x82, 0x20, 0x01, 0xb9, 0x3b, 0xff, 0x00, 0x02, 0x7e, 0x20, 0x4c, 0xf7, - 0x3e, 0x2b, 0xba, 0x87, 0x57, 0xd3, 0xae, 0xb4, 0xf9, 0x52, 0x79, 0x3c, - 0xc9, 0x8a, 0x2b, 0x1c, 0xee, 0x63, 0x82, 0x54, 0x92, 0xc0, 0x9c, 0xe0, - 0x85, 0xc6, 0x39, 0xe7, 0x9a, 0xfb, 0x4f, 0x58, 0xf1, 0x6f, 0xc5, 0x2f, - 0x15, 0xfc, 0x65, 0xd2, 0xa5, 0xd2, 0x6c, 0xae, 0x6f, 0x2c, 0x2d, 0x7c, - 0x3f, 0xe6, 0x5d, 0x08, 0x2e, 0x55, 0x7e, 0xce, 0xec, 0x76, 0x82, 0xc3, - 0x0c, 0xb2, 0x14, 0x6d, 0xa4, 0x6d, 0x0c, 0x77, 0x6d, 0x23, 0x07, 0x91, - 0xe1, 0x5f, 0x10, 0xd0, 0xcb, 0xab, 0xdf, 0x6a, 0xfa, 0x81, 0x2a, 0x63, - 0x7e, 0x21, 0x96, 0x45, 0x95, 0x88, 0x2b, 0xf7, 0x9b, 0x78, 0x40, 0x76, - 0x82, 0xd8, 0x04, 0x1c, 0x9e, 0xbc, 0x12, 0x2b, 0xf1, 0x29, 0x51, 0xf6, - 0x78, 0xa9, 0x37, 0x24, 0xef, 0xae, 0xfd, 0x5f, 0xf9, 0x9f, 0x2b, 0x4e, - 0xbd, 0xdd, 0xd9, 0xe0, 0xde, 0x21, 0xbb, 0xd3, 0xf5, 0x1b, 0x07, 0xbd, - 0xd4, 0x9a, 0x65, 0xb9, 0x65, 0x21, 0x8c, 0x65, 0x0b, 0x47, 0xe5, 0x2e, - 0xf5, 0x08, 0xc7, 0x27, 0x3c, 0x82, 0xd8, 0x18, 0xe4, 0xf4, 0x35, 0xf3, - 0xa7, 0x8a, 0xe6, 0xb7, 0x91, 0x63, 0xd4, 0x60, 0xc0, 0x9c, 0x81, 0x6e, - 0x41, 0x50, 0x9b, 0x97, 0x69, 0xc3, 0x95, 0xc6, 0x33, 0xb9, 0x79, 0xed, - 0xfc, 0xab, 0xd9, 0x7c, 0x77, 0xa9, 0xc1, 0xa7, 0x59, 0x79, 0x2a, 0xa1, - 0x1f, 0x6a, 0xab, 0x13, 0xb3, 0xf7, 0xa5, 0x41, 0x32, 0x00, 0x8a, 0x3a, - 0x65, 0x82, 0xee, 0x04, 0xe7, 0x9e, 0xd9, 0xcf, 0xcf, 0x3e, 0x27, 0xd4, - 0x2c, 0xaf, 0xac, 0xa3, 0xd4, 0xad, 0x14, 0xa2, 0xab, 0xaa, 0x79, 0x51, - 0xf3, 0xb7, 0x0c, 0x33, 0x19, 0xc0, 0x1d, 0x49, 0xe3, 0x9e, 0x87, 0xeb, - 0x5f, 0x4d, 0x96, 0x51, 0xd1, 0x3b, 0x1e, 0xce, 0x19, 0x5c, 0xa7, 0xe1, - 0x8b, 0xe8, 0x66, 0xd7, 0xae, 0xa4, 0x63, 0x70, 0x60, 0x41, 0x2c, 0x8c, - 0x91, 0x03, 0xb0, 0x0d, 0xb9, 0x70, 0x54, 0x8c, 0x94, 0x5c, 0x1e, 0x73, - 0xd1, 0x47, 0xbe, 0x3f, 0x72, 0x7f, 0x64, 0xcf, 0xf8, 0x29, 0xe4, 0xdf, - 0xb1, 0x7e, 0x91, 0x6d, 0xe1, 0x9f, 0x84, 0x1e, 0x1e, 0xf0, 0x54, 0xe0, - 0x2c, 0xb6, 0xf7, 0x57, 0x9e, 0x25, 0xb0, 0x8f, 0x52, 0x6b, 0xc8, 0xae, - 0x6d, 0xe2, 0x49, 0xa3, 0x9a, 0xe8, 0x6c, 0x63, 0x02, 0xcb, 0x1b, 0xcb, - 0x1c, 0x0a, 0x87, 0x97, 0xe7, 0x79, 0x45, 0xcf, 0xe0, 0x16, 0x9b, 0x7e, - 0xb1, 0x5f, 0xdd, 0x99, 0xc1, 0x8f, 0xcc, 0x12, 0x0b, 0x72, 0x49, 0xc9, - 0x1f, 0x31, 0x2d, 0xd7, 0x19, 0x39, 0xf4, 0xe3, 0xa5, 0x6e, 0xeb, 0x5e, - 0x22, 0xbb, 0xb4, 0x91, 0xec, 0xa6, 0xb7, 0xf3, 0x6d, 0xc2, 0xc4, 0x02, - 0x09, 0x36, 0x36, 0x4a, 0x67, 0x80, 0x70, 0x72, 0x71, 0x8c, 0xe7, 0x8e, - 0xb8, 0xed, 0x5e, 0xb4, 0xa1, 0x5a, 0xef, 0xd9, 0xc9, 0xa2, 0x31, 0x34, - 0x6f, 0x2b, 0xa3, 0xf5, 0x1f, 0xe3, 0xa7, 0xed, 0x79, 0xe3, 0xaf, 0x8c, - 0x9e, 0x23, 0xbf, 0xf1, 0xd5, 0xe9, 0xb7, 0xb0, 0x92, 0xf3, 0x57, 0x93, - 0x55, 0xd5, 0xac, 0x6c, 0x65, 0x79, 0x20, 0xba, 0xba, 0x32, 0xbb, 0x6f, - 0x0f, 0x21, 0xf3, 0x3e, 0xcc, 0x80, 0x81, 0x1c, 0x25, 0x98, 0x27, 0x5e, - 0xa4, 0xd7, 0x39, 0x3f, 0x8e, 0xac, 0xfc, 0x63, 0xe0, 0xb8, 0xee, 0xfc, - 0x4b, 0x2d, 0xb4, 0x9a, 0xad, 0xbd, 0x8c, 0xf6, 0xd1, 0x5c, 0xdc, 0xbc, - 0xaf, 0x74, 0xb0, 0x84, 0x41, 0x6c, 0xf1, 0x16, 0x65, 0x84, 0x88, 0xc8, - 0xd9, 0xe5, 0xe0, 0x6d, 0x8d, 0xc9, 0x5d, 0xc4, 0x2a, 0xc7, 0xf9, 0xa1, - 0x6b, 0xe3, 0x4f, 0x10, 0xf9, 0x10, 0x59, 0x69, 0xab, 0x38, 0xb6, 0x95, - 0xc2, 0xdc, 0xdb, 0x4b, 0x23, 0x1d, 0x80, 0x71, 0xf2, 0xbf, 0x42, 0xb8, - 0x63, 0xc1, 0xf4, 0xe4, 0x73, 0x5e, 0xfb, 0xe1, 0x8f, 0x14, 0x6a, 0x9a, - 0x0d, 0xdc, 0x77, 0x9e, 0x1d, 0x92, 0xed, 0x2f, 0x23, 0x40, 0xa1, 0xed, - 0xa5, 0x68, 0x56, 0x38, 0xd8, 0x61, 0x9f, 0x7a, 0x10, 0x70, 0xc1, 0x88, - 0xea, 0xa7, 0x03, 0x9e, 0x6b, 0xcf, 0xaf, 0x46, 0xb4, 0x1a, 0x95, 0x47, - 0xcc, 0x79, 0xd5, 0x68, 0xa8, 0xea, 0x8f, 0xae, 0x7e, 0x0b, 0xfc, 0x47, - 0xf8, 0x7b, 0xe0, 0x5d, 0x62, 0xde, 0x5f, 0x88, 0x5a, 0x43, 0xf8, 0x9b, - 0x44, 0xba, 0xf0, 0xa4, 0xba, 0x6c, 0xb6, 0x57, 0x72, 0x79, 0x32, 0xdb, - 0xbc, 0xb2, 0x2b, 0x19, 0xad, 0xa7, 0x50, 0xcb, 0x13, 0x2b, 0xc6, 0x70, - 0x19, 0x1d, 0x70, 0x4f, 0x07, 0x3c, 0x32, 0xef, 0xe3, 0x4d, 0x85, 0xe7, - 0x8a, 0x7c, 0x73, 0x7d, 0xe0, 0x55, 0xb7, 0xd0, 0xf4, 0x4d, 0x56, 0xc1, - 0xac, 0x13, 0x42, 0xb7, 0x6b, 0x88, 0xed, 0xa7, 0xb3, 0x37, 0x25, 0xe3, - 0x88, 0xed, 0x75, 0xf3, 0x8c, 0x6d, 0x89, 0x7f, 0x78, 0x59, 0x77, 0x8c, - 0xf9, 0x67, 0x68, 0x51, 0xf1, 0x3e, 0xa7, 0x73, 0x73, 0x69, 0xaa, 0xa1, - 0x92, 0x55, 0x4b, 0x7f, 0xf5, 0x50, 0xa4, 0x72, 0xa1, 0x55, 0x0e, 0xc1, - 0x80, 0xc1, 0x21, 0xb1, 0x92, 0xdc, 0x64, 0xfa, 0xe6, 0xb5, 0x23, 0xb9, - 0xbc, 0x75, 0x8a, 0x7b, 0x26, 0x65, 0x44, 0x97, 0x6c, 0xa8, 0x50, 0x6e, - 0x27, 0x1c, 0x8e, 0x7a, 0x0e, 0x57, 0xe6, 0xe0, 0x83, 0x4e, 0xa6, 0x3a, - 0xb7, 0x27, 0x2b, 0x6a, 0xcf, 0xcb, 0xf5, 0xfd, 0x08, 0x9f, 0x46, 0x99, - 0xa5, 0x61, 0xe2, 0x0d, 0x2b, 0x48, 0xf1, 0x62, 0xbe, 0xad, 0x6a, 0x97, - 0xd6, 0xf1, 0x34, 0xee, 0xf0, 0x3c, 0xbe, 0x4b, 0xc8, 0x65, 0xdc, 0xb1, - 0x48, 0x92, 0x36, 0xcc, 0x84, 0x90, 0x86, 0x65, 0x24, 0x6f, 0x50, 0x46, - 0x57, 0x21, 0xab, 0xdb, 0x34, 0x1f, 0x86, 0xfe, 0x3e, 0xd5, 0xb4, 0xdf, - 0x14, 0x6b, 0xda, 0x0d, 0xee, 0x9d, 0xa7, 0xd8, 0x5a, 0x88, 0x24, 0xbc, - 0xb0, 0x9f, 0x51, 0xb7, 0xb7, 0x9e, 0x45, 0x93, 0x98, 0xa2, 0x8a, 0x19, - 0x9c, 0x4d, 0x37, 0x96, 0x32, 0x0e, 0xc0, 0x76, 0xe3, 0x2d, 0xc1, 0x35, - 0xf3, 0x26, 0xab, 0x1e, 0xab, 0x69, 0xab, 0xc7, 0x7d, 0x04, 0xb1, 0xc8, - 0x81, 0x14, 0xf9, 0x62, 0x45, 0x24, 0xbb, 0x7c, 0xed, 0xb1, 0x95, 0x38, - 0x3d, 0x36, 0x90, 0xa0, 0x13, 0xeb, 0xc1, 0x3d, 0x7d, 0x8f, 0x8c, 0x6d, - 0xf4, 0xdb, 0xcf, 0xb1, 0x5c, 0x44, 0xe0, 0x30, 0x23, 0xc8, 0x0b, 0xf3, - 0xe5, 0x97, 0x9c, 0x70, 0x14, 0x92, 0x41, 0xe0, 0x1e, 0xbf, 0x4a, 0xc1, - 0x55, 0x95, 0xac, 0x95, 0xff, 0x00, 0xaf, 0xeb, 0xfa, 0xd9, 0xd4, 0xa9, - 0x65, 0x74, 0x7e, 0xda, 0xfe, 0xc2, 0xbf, 0x08, 0x3e, 0x18, 0x78, 0x9b, - 0xe1, 0xc7, 0x88, 0x75, 0x8f, 0x1a, 0xe8, 0xfa, 0x76, 0xb7, 0xe2, 0x27, - 0xb1, 0x1a, 0x3e, 0x8d, 0x6f, 0x77, 0x24, 0xbf, 0x65, 0xb0, 0x92, 0x53, - 0x18, 0x6d, 0x46, 0x48, 0xa2, 0x92, 0xde, 0xed, 0x1a, 0x28, 0xe7, 0x46, - 0xb7, 0x71, 0x95, 0x79, 0x46, 0xdd, 0xa7, 0x70, 0x2b, 0xf9, 0x87, 0xac, - 0x5d, 0x59, 0x78, 0x6b, 0xc7, 0xd7, 0xd2, 0x49, 0x3c, 0x01, 0x23, 0xd4, - 0xae, 0x56, 0x3f, 0x28, 0x09, 0x55, 0xa3, 0x01, 0xb6, 0x12, 0xae, 0x4a, - 0xed, 0xe4, 0x6d, 0x24, 0x9c, 0x76, 0xcf, 0x5a, 0xd8, 0xf8, 0x73, 0xf1, - 0x5f, 0xc4, 0xbe, 0x18, 0xbd, 0x33, 0x69, 0x89, 0x6f, 0x75, 0x0b, 0xdb, - 0x86, 0x96, 0xde, 0xfc, 0xbb, 0xa9, 0x12, 0x6d, 0xcb, 0x34, 0x6a, 0xde, - 0x59, 0xe0, 0x29, 0x1b, 0xbb, 0xe3, 0x8e, 0x05, 0x78, 0xe7, 0xc5, 0x0d, - 0x76, 0xef, 0xc6, 0x9e, 0x2c, 0xbd, 0xd5, 0xb5, 0x15, 0x78, 0x25, 0xb9, - 0xd4, 0xa7, 0x9c, 0xa2, 0xb3, 0x71, 0x19, 0x50, 0x10, 0x1e, 0x7e, 0xe9, - 0xc0, 0xc6, 0x79, 0x2b, 0xf5, 0xcd, 0x72, 0x54, 0xc4, 0x73, 0xda, 0x0e, - 0x36, 0xb7, 0x5d, 0x2d, 0xfe, 0x66, 0xb4, 0xa4, 0xa4, 0xb7, 0xb1, 0xfa, - 0x07, 0xf0, 0xfb, 0xf6, 0x83, 0xf1, 0x36, 0x9d, 0xa0, 0x4d, 0xe1, 0xbb, - 0x3b, 0xbb, 0x49, 0xad, 0xb5, 0x89, 0x41, 0xb8, 0x97, 0x55, 0xb0, 0x8a, - 0xfc, 0xab, 0x02, 0x26, 0x76, 0x4b, 0x89, 0x22, 0x92, 0x54, 0xfb, 0xad, - 0xb4, 0x06, 0x20, 0xab, 0x48, 0x30, 0x4b, 0x31, 0xaf, 0xd1, 0xaf, 0x87, - 0xff, 0x00, 0x11, 0x6c, 0xbc, 0x73, 0xe1, 0xed, 0x33, 0xc4, 0x01, 0xf4, - 0x0f, 0x0b, 0x5d, 0x69, 0xdf, 0x68, 0xb0, 0x8e, 0xd3, 0xc2, 0x56, 0x33, - 0xa2, 0x4e, 0xb3, 0x13, 0x2b, 0xcb, 0x72, 0x97, 0x32, 0xaa, 0xc4, 0x59, - 0x48, 0x42, 0x13, 0xf7, 0x44, 0x82, 0xdb, 0x32, 0x58, 0xb7, 0xf3, 0xcb, - 0xa7, 0x78, 0xc6, 0x1f, 0x0f, 0x03, 0x67, 0x6d, 0x14, 0x26, 0x11, 0x10, - 0x79, 0xe2, 0x77, 0x39, 0x21, 0x31, 0xbd, 0xa1, 0x18, 0x39, 0x65, 0x19, - 0xc1, 0xfc, 0x7b, 0x57, 0xd9, 0x9f, 0x02, 0xbe, 0x29, 0xf8, 0x82, 0xeb, - 0x40, 0xd5, 0xed, 0xb4, 0x9d, 0x50, 0x47, 0x6a, 0xb6, 0x92, 0x43, 0x75, - 0x1a, 0x4b, 0x04, 0xb7, 0x17, 0x31, 0xcc, 0xc8, 0xd0, 0x28, 0xde, 0xcf, - 0x30, 0x31, 0xed, 0x0d, 0x29, 0x25, 0xc2, 0xa8, 0x5c, 0x05, 0x3c, 0x57, - 0x3c, 0xdd, 0x57, 0x16, 0x9c, 0xbd, 0xdf, 0x3d, 0x7e, 0xee, 0xc6, 0x53, - 0x8b, 0xb5, 0xde, 0xa7, 0xd5, 0x7f, 0xb4, 0x87, 0xc5, 0x5d, 0x02, 0x61, - 0xa9, 0x69, 0x9a, 0x76, 0xa7, 0xa9, 0xcb, 0x7d, 0x75, 0x70, 0xb2, 0xfd, - 0x96, 0xc2, 0xf5, 0x21, 0x58, 0x90, 0x37, 0xce, 0xbe, 0x62, 0x8d, 0xcf, - 0xd4, 0x93, 0x8f, 0x61, 0xc8, 0x3b, 0x8f, 0xc1, 0x5e, 0x25, 0xf8, 0xc3, - 0xe1, 0xfd, 0x32, 0x58, 0xb4, 0x1f, 0x0e, 0x43, 0x79, 0x6c, 0x21, 0x8d, - 0x8d, 0xec, 0xd6, 0x52, 0x93, 0x3c, 0xd2, 0xc8, 0x03, 0x4b, 0x70, 0xd3, - 0x5c, 0x96, 0x6d, 0xc1, 0xc7, 0xc8, 0xea, 0xa9, 0x8f, 0x98, 0xaf, 0x27, - 0x9f, 0x2f, 0xf8, 0xd7, 0xad, 0xf8, 0x97, 0x46, 0xb9, 0xb6, 0x8e, 0xfe, - 0xc7, 0x6c, 0xb2, 0x46, 0xb7, 0xd6, 0xd7, 0x22, 0x52, 0xe0, 0x06, 0x3f, - 0x24, 0xaa, 0x14, 0x83, 0x92, 0x33, 0x9d, 0xd9, 0x03, 0x90, 0x72, 0x40, - 0xaf, 0x9c, 0xf5, 0x3d, 0x7b, 0xc6, 0x57, 0x3a, 0x9c, 0xf7, 0x3a, 0x55, - 0xdd, 0xcc, 0x2f, 0x3a, 0x18, 0xa7, 0x68, 0xc9, 0xcb, 0x29, 0x23, 0x70, - 0x04, 0x72, 0x7b, 0x63, 0x1d, 0x0f, 0x4a, 0x8c, 0xa3, 0x24, 0x84, 0x57, - 0x3f, 0x35, 0xec, 0x55, 0x28, 0x36, 0xae, 0x7d, 0x8f, 0xac, 0x7c, 0x5c, - 0xd5, 0x3c, 0x23, 0x60, 0xd7, 0xba, 0x9c, 0xfa, 0x5e, 0xb7, 0x6a, 0x20, - 0x8d, 0x6c, 0x66, 0xdc, 0x4e, 0x55, 0x94, 0x00, 0x0d, 0xbc, 0x81, 0x19, - 0xe4, 0x52, 0xdf, 0x3c, 0xbf, 0x38, 0x2c, 0x4e, 0x1c, 0x70, 0x07, 0xc8, - 0x9e, 0x37, 0xf8, 0xc1, 0xab, 0x78, 0x87, 0x50, 0x9e, 0x79, 0xb7, 0x85, - 0x95, 0xcb, 0xc7, 0x12, 0x3f, 0xca, 0xa4, 0x02, 0xab, 0xf2, 0xaf, 0x0a, - 0x71, 0xe9, 0x8f, 0xc4, 0x56, 0x36, 0xbd, 0xa3, 0x5c, 0xc6, 0xb1, 0x59, - 0x49, 0x70, 0x64, 0x31, 0xc8, 0xd2, 0xbf, 0xda, 0xb7, 0xb9, 0x4c, 0xa8, - 0xf9, 0x94, 0xa6, 0x54, 0xf2, 0x41, 0x38, 0x24, 0x11, 0xea, 0x05, 0x78, - 0xe5, 0xd2, 0xbc, 0x17, 0x4e, 0xd2, 0xb7, 0xc8, 0xbf, 0x20, 0xf2, 0xce, - 0x43, 0x0e, 0x49, 0x20, 0xe7, 0x9e, 0x3d, 0x3b, 0x57, 0xbf, 0x80, 0xcb, - 0x28, 0xc5, 0xb9, 0xa5, 0xab, 0x3b, 0xe9, 0x53, 0xb6, 0xe7, 0x41, 0x27, - 0x89, 0xf5, 0x3f, 0xed, 0x90, 0xb7, 0x1e, 0x70, 0x98, 0xca, 0x41, 0x53, - 0x80, 0xc8, 0xd9, 0xc7, 0x00, 0x72, 0x0a, 0xe3, 0xa1, 0x1c, 0x0c, 0x0e, - 0xd5, 0xf4, 0xc6, 0x81, 0xf1, 0x33, 0xc3, 0x97, 0x10, 0x3d, 0x8d, 0xfe, - 0x16, 0x4b, 0x9b, 0x01, 0x6d, 0x77, 0x04, 0x4a, 0x36, 0x6f, 0x8d, 0x86, - 0xd1, 0xb4, 0xb0, 0x21, 0xb8, 0xc9, 0x23, 0x92, 0xc0, 0x1e, 0x71, 0x8a, - 0xf8, 0xd2, 0x4d, 0x52, 0xd9, 0xa6, 0x71, 0x08, 0x2b, 0xb8, 0xe4, 0x01, - 0xcf, 0xca, 0x41, 0xc0, 0x5c, 0xe4, 0x9f, 0xc4, 0xe7, 0x8e, 0xf5, 0x5e, - 0x2b, 0xa6, 0xb5, 0x9a, 0x49, 0xd6, 0x43, 0xbd, 0x97, 0x70, 0x20, 0x91, - 0x83, 0xcf, 0x43, 0x9e, 0x41, 0x38, 0xce, 0x6b, 0xbf, 0x13, 0x95, 0xc2, - 0x76, 0xb2, 0xb5, 0x8d, 0xdc, 0x7b, 0x1f, 0x42, 0xea, 0x7f, 0x13, 0xee, - 0x75, 0xa5, 0x2e, 0x8c, 0xbf, 0xba, 0x48, 0xe1, 0x6d, 0xca, 0x01, 0x69, - 0x21, 0xe3, 0x70, 0x3c, 0x9c, 0x36, 0x72, 0x71, 0xd8, 0x57, 0xa9, 0x78, - 0x1f, 0xe2, 0x9e, 0xa5, 0xa6, 0xda, 0xc7, 0x67, 0xa4, 0x43, 0x24, 0x3b, - 0x64, 0x49, 0x9e, 0x60, 0x5c, 0xee, 0x62, 0x39, 0x67, 0x05, 0xb6, 0x90, - 0xd8, 0xeb, 0x80, 0x48, 0x03, 0x92, 0x41, 0xaf, 0x8f, 0xb4, 0xe9, 0x64, - 0x85, 0xe4, 0xd8, 0xbf, 0x23, 0x66, 0x64, 0x91, 0x8f, 0x19, 0x27, 0x3b, - 0x8e, 0x72, 0x08, 0x2b, 0x9e, 0x38, 0xe7, 0xf2, 0x3d, 0xbe, 0x97, 0xae, - 0xc9, 0x67, 0xa8, 0xaa, 0xc4, 0xc5, 0xa1, 0x29, 0xd4, 0x00, 0xc7, 0x95, - 0xf9, 0x87, 0x7e, 0x9f, 0x5f, 0xc2, 0xb8, 0xf1, 0x99, 0x35, 0x27, 0x17, - 0x05, 0x10, 0x70, 0x4e, 0x3b, 0x1f, 0xa1, 0xb3, 0x7e, 0xd1, 0xbe, 0x2d, - 0xb6, 0xf0, 0xba, 0xe8, 0x97, 0x92, 0xc9, 0xf6, 0x69, 0xe4, 0xcc, 0xa5, - 0x25, 0x3b, 0xdc, 0x81, 0xd1, 0x1b, 0x39, 0x04, 0xe4, 0x83, 0xec, 0x78, - 0xe0, 0x9c, 0xfc, 0xcf, 0x7d, 0xe2, 0x6f, 0x10, 0xf8, 0xd3, 0x58, 0xb6, - 0xd1, 0x8d, 0xfb, 0x38, 0x12, 0x79, 0x56, 0xf1, 0x5d, 0x5c, 0x14, 0x83, - 0x63, 0xb1, 0x20, 0x10, 0xe4, 0xa2, 0x2f, 0x2b, 0xba, 0x4e, 0x3e, 0x6f, - 0x9b, 0x20, 0x1d, 0xd5, 0xe3, 0x7a, 0xd7, 0x8a, 0x2e, 0x27, 0xb5, 0x36, - 0xf2, 0xf9, 0x8a, 0xdb, 0x4a, 0xc6, 0xb1, 0x6d, 0x65, 0x8f, 0x91, 0xfc, - 0x19, 0x23, 0xee, 0xe4, 0x1c, 0x10, 0x71, 0xd2, 0xae, 0xc7, 0x76, 0x74, - 0x8b, 0x28, 0x2f, 0xa1, 0x7b, 0x67, 0xba, 0x56, 0x25, 0x31, 0x97, 0x25, - 0x31, 0xd4, 0x03, 0xf2, 0x9c, 0x63, 0x90, 0x47, 0x3c, 0x67, 0xa8, 0x15, - 0xe6, 0xd1, 0xc8, 0xa9, 0x50, 0x4e, 0x74, 0xe2, 0x93, 0x7f, 0xd5, 0xff, - 0x00, 0xcc, 0xc6, 0x54, 0xdd, 0x8f, 0x7f, 0xf0, 0x85, 0xb4, 0x1e, 0x0a, - 0xbb, 0x92, 0xee, 0xfe, 0xe4, 0xc7, 0x7b, 0x79, 0x3c, 0x8c, 0x24, 0x49, - 0x7c, 0xb8, 0xe6, 0x50, 0x4b, 0x31, 0xdc, 0xa5, 0xd5, 0x90, 0xb0, 0x04, - 0x02, 0x76, 0x9f, 0xef, 0x73, 0x8a, 0xfe, 0x87, 0xbf, 0xe0, 0x9c, 0x1a, - 0xde, 0x91, 0xf1, 0xc3, 0xc6, 0x10, 0xe9, 0xda, 0xbc, 0x97, 0xe7, 0xc6, - 0x16, 0x29, 0x1d, 0x96, 0x9d, 0x35, 0x9c, 0xde, 0x5d, 0xfb, 0x5a, 0xc7, - 0x11, 0xb7, 0xd9, 0xa6, 0x8b, 0x47, 0xb3, 0xf3, 0x5a, 0x23, 0x2c, 0x4f, - 0x1c, 0x62, 0x51, 0xbb, 0x69, 0x24, 0x9c, 0x2a, 0xa7, 0xf2, 0xe1, 0xa1, - 0x78, 0x96, 0xf6, 0xff, 0x00, 0x54, 0xb7, 0xd2, 0xef, 0x27, 0x13, 0xc7, - 0x71, 0x74, 0x17, 0xcc, 0xb8, 0x52, 0x63, 0x8d, 0x9b, 0x38, 0x70, 0x01, - 0x24, 0x0e, 0x73, 0x9e, 0xfe, 0x87, 0xa5, 0x7e, 0xb1, 0xfe, 0xcb, 0x5f, - 0x12, 0xfc, 0x6b, 0xf0, 0x6f, 0xc6, 0x3a, 0x77, 0x89, 0xbc, 0x22, 0xd7, - 0x65, 0xb4, 0xd9, 0xcc, 0x96, 0xda, 0x8a, 0x83, 0xe7, 0x16, 0x2b, 0xb5, - 0xd1, 0x76, 0x6f, 0x2a, 0xc4, 0x1f, 0x97, 0xe6, 0xef, 0xce, 0x4e, 0x48, - 0xf9, 0xfe, 0x23, 0xc4, 0x4f, 0x0d, 0xc9, 0x52, 0x4e, 0xed, 0x34, 0xf4, - 0xed, 0xf3, 0xfc, 0xbf, 0x13, 0x8a, 0x74, 0xfd, 0xed, 0x4f, 0xea, 0x1b, - 0xf6, 0xd2, 0xf8, 0x49, 0xa7, 0x78, 0x03, 0x56, 0xd5, 0x75, 0xdd, 0x3e, - 0xea, 0x5b, 0x4b, 0x7d, 0x35, 0x20, 0x4b, 0x7d, 0x46, 0x50, 0x41, 0xbe, - 0xd6, 0xe4, 0xb7, 0xdd, 0x2c, 0x11, 0x02, 0xcf, 0x24, 0x71, 0xa9, 0xc1, - 0x1f, 0xbf, 0x94, 0x0d, 0xc5, 0x8c, 0x84, 0xe3, 0x77, 0xe7, 0x7f, 0xc2, - 0x7d, 0x7f, 0xc5, 0x3e, 0x11, 0xd2, 0x2f, 0xbc, 0x45, 0xe2, 0x73, 0x0a, - 0x5f, 0xfd, 0xac, 0x6d, 0x11, 0x5d, 0xa5, 0xd4, 0xb2, 0x46, 0xee, 0xcd, - 0x96, 0x48, 0xd8, 0xb2, 0xa6, 0x71, 0xb5, 0x8b, 0x8c, 0x90, 0x46, 0x39, - 0x38, 0xe2, 0x7c, 0x55, 0xfb, 0x67, 0x6b, 0xbf, 0x10, 0xf5, 0x0b, 0x2f, - 0x0f, 0xfc, 0x50, 0xbb, 0x7d, 0x56, 0xd0, 0x5e, 0xa3, 0xac, 0x36, 0xc8, - 0x63, 0x48, 0xac, 0x60, 0x88, 0x08, 0x91, 0xe2, 0x8d, 0x52, 0x1f, 0x32, - 0x30, 0xac, 0xa5, 0xcf, 0xdf, 0x07, 0x1c, 0x71, 0xb7, 0xe4, 0x6f, 0x1e, - 0xfc, 0x3b, 0xf8, 0xc7, 0xe1, 0xff, 0x00, 0x18, 0x2e, 0xb9, 0xf0, 0xd9, - 0x75, 0x0b, 0xcd, 0x1f, 0x5b, 0x7c, 0x43, 0x6d, 0x63, 0x1b, 0xce, 0x96, - 0xf9, 0x3c, 0xac, 0xcc, 0x81, 0x15, 0x43, 0x6d, 0x52, 0xae, 0xd9, 0x4d, - 0xc0, 0xe4, 0x8c, 0x64, 0xf3, 0xae, 0x25, 0xc2, 0x57, 0xa8, 0xa1, 0x46, - 0x2e, 0x09, 0xa6, 0xd5, 0xfa, 0xf5, 0xd3, 0xb7, 0xfc, 0x07, 0xab, 0x7a, - 0xb9, 0xa9, 0x51, 0xa7, 0x78, 0xa3, 0xf5, 0xeb, 0x49, 0xf8, 0xc7, 0xa1, - 0xf8, 0xaa, 0xfe, 0x1b, 0x6b, 0xcb, 0xc9, 0xe2, 0xf3, 0xca, 0x99, 0xae, - 0xe3, 0x7c, 0x48, 0x97, 0x4c, 0xbe, 0x58, 0x66, 0xe5, 0xbf, 0x8b, 0x04, - 0x0f, 0x97, 0x77, 0x18, 0x35, 0xd5, 0x7c, 0x25, 0xf1, 0xc7, 0xc5, 0x99, - 0x7c, 0x73, 0x75, 0x63, 0xa1, 0x97, 0x3f, 0x64, 0x89, 0xae, 0x75, 0x5b, - 0x8f, 0x32, 0xde, 0xda, 0x61, 0xe5, 0x65, 0xe3, 0x99, 0x63, 0x93, 0xf7, - 0x6d, 0x04, 0x85, 0x0e, 0x64, 0x73, 0xb4, 0xf9, 0x6c, 0xcd, 0x81, 0xc8, - 0xfc, 0x68, 0xf0, 0xfd, 0xaf, 0xc4, 0x5f, 0x0e, 0xbf, 0xfc, 0x24, 0xba, - 0xf4, 0x71, 0xc9, 0x63, 0x13, 0x46, 0xaf, 0x0c, 0x5b, 0xbc, 0xf8, 0x51, - 0x82, 0xf9, 0x8b, 0x24, 0x7c, 0x1d, 0xc1, 0xc1, 0x5d, 0x8b, 0xc7, 0x04, - 0x92, 0x14, 0x1a, 0xea, 0x3c, 0x79, 0xfb, 0x42, 0x37, 0x87, 0xbc, 0x43, - 0x67, 0xe2, 0x2b, 0x3b, 0xf6, 0xb2, 0x4b, 0xbd, 0x26, 0x58, 0x6e, 0x26, - 0x96, 0x62, 0x2d, 0x6e, 0x02, 0xab, 0x66, 0x29, 0x82, 0x9e, 0x92, 0x01, - 0x94, 0xc2, 0x96, 0x0c, 0xc3, 0xe4, 0xe3, 0x23, 0xd5, 0xca, 0xea, 0x46, - 0x75, 0x79, 0x7e, 0x24, 0xfb, 0x3b, 0x3b, 0xfa, 0xf4, 0xf3, 0x09, 0x62, - 0x2e, 0xed, 0xd4, 0xff, 0xd3, 0xf2, 0x0f, 0x1a, 0xfc, 0x1b, 0xf0, 0x9f, - 0x82, 0xad, 0x6e, 0x64, 0xf0, 0xa8, 0xf2, 0xa3, 0x1b, 0x0c, 0x76, 0x96, - 0xaa, 0x0c, 0x71, 0x2c, 0x20, 0x85, 0x11, 0xc4, 0xa0, 0x02, 0xd8, 0xe0, - 0x33, 0x64, 0xf6, 0xf6, 0x3f, 0x93, 0x3f, 0x16, 0x34, 0x19, 0x3c, 0x45, - 0x3d, 0xc4, 0x5a, 0x34, 0x6f, 0xa7, 0x11, 0x72, 0xea, 0xef, 0x2f, 0x92, - 0x93, 0xcd, 0xb5, 0x49, 0xc7, 0x90, 0xe3, 0x95, 0x3c, 0x0f, 0xbb, 0x9e, - 0x79, 0xce, 0x73, 0x5f, 0xa9, 0x1e, 0x32, 0xf1, 0xa7, 0x9b, 0x1c, 0x91, - 0x4a, 0x49, 0x59, 0x01, 0x46, 0xed, 0xc1, 0x04, 0x1c, 0x8c, 0xfb, 0xd7, - 0xc2, 0xdf, 0x10, 0xb4, 0x58, 0xe3, 0x95, 0xaf, 0x34, 0x5b, 0x74, 0x2d, - 0x1c, 0xbe, 0x72, 0xc5, 0x14, 0x51, 0x8f, 0x9d, 0x72, 0xe1, 0xd9, 0x82, - 0x93, 0xd7, 0xa9, 0x00, 0xb1, 0xcf, 0x00, 0xf2, 0x2b, 0xe2, 0xf8, 0x8b, - 0x86, 0xbd, 0x85, 0x67, 0x8a, 0xa5, 0xb3, 0xe9, 0xd9, 0xf9, 0x79, 0x7e, - 0x47, 0x8a, 0xb0, 0x4a, 0x4f, 0x9a, 0x9a, 0xd7, 0xb1, 0xf0, 0x17, 0x88, - 0xfc, 0x05, 0xa7, 0x68, 0xe2, 0x48, 0x35, 0x6b, 0xc7, 0x94, 0xc2, 0xcd, - 0x27, 0xd9, 0xd5, 0x87, 0xee, 0x4b, 0xf0, 0x57, 0x70, 0x0a, 0x07, 0x3d, - 0x00, 0x23, 0x8e, 0x9d, 0x06, 0x7e, 0x7b, 0xd6, 0xa0, 0x16, 0xf7, 0x37, - 0x16, 0xb0, 0x08, 0xbc, 0x98, 0x8a, 0xaa, 0x34, 0x6c, 0x4a, 0xbb, 0x13, - 0xbb, 0x76, 0x3a, 0xe4, 0x71, 0x9c, 0x9e, 0x7a, 0x57, 0xd4, 0x3e, 0x3f, - 0xf0, 0x0f, 0x8c, 0x3c, 0x4b, 0x39, 0x96, 0xea, 0xfa, 0xd9, 0x03, 0x49, - 0x23, 0xc1, 0x63, 0x6e, 0xaa, 0x03, 0x0d, 0xb8, 0x73, 0xf3, 0x92, 0xf2, - 0x3e, 0x08, 0xf9, 0x88, 0xe0, 0xe7, 0x85, 0x18, 0x07, 0x91, 0xd2, 0x3e, - 0x0b, 0xdf, 0x5a, 0x99, 0x6c, 0x64, 0x68, 0xa4, 0x79, 0xe3, 0x8f, 0x33, - 0xca, 0x59, 0x92, 0x21, 0x95, 0x00, 0x95, 0x8c, 0x92, 0xd8, 0xdc, 0x7b, - 0x70, 0x06, 0x47, 0x3c, 0xd7, 0x15, 0x2c, 0x4a, 0x8a, 0xf7, 0x99, 0xbe, - 0x1e, 0x8d, 0x4d, 0x5e, 0xe7, 0xcd, 0x3a, 0x8e, 0x92, 0xb0, 0x5c, 0x45, - 0x7d, 0x13, 0x0c, 0x41, 0x93, 0x12, 0x44, 0x01, 0x38, 0x3d, 0x4b, 0x9e, - 0xb9, 0x23, 0x9f, 0xff, 0x00, 0x58, 0xad, 0xa8, 0xf4, 0x09, 0xb5, 0xcb, - 0x96, 0xba, 0x6f, 0x92, 0x29, 0x02, 0xfd, 0xec, 0xe4, 0xf1, 0x8c, 0x60, - 0x9e, 0xd8, 0x24, 0x9e, 0xdf, 0x95, 0x7b, 0xf5, 0x8f, 0xc3, 0x2d, 0x52, - 0xee, 0xe6, 0x68, 0x6e, 0x7c, 0xa6, 0x26, 0x76, 0xb7, 0x9a, 0xe0, 0xb7, - 0x97, 0x0e, 0x20, 0x3b, 0x98, 0x04, 0x73, 0xbd, 0x8e, 0x3d, 0x38, 0x03, - 0x3c, 0x71, 0x5b, 0x36, 0x7e, 0x17, 0x8e, 0x29, 0xe0, 0xb2, 0x9e, 0x19, - 0x55, 0x65, 0x97, 0xf7, 0x51, 0x60, 0x85, 0xe1, 0xb3, 0xc9, 0x23, 0x81, - 0x81, 0xd0, 0x0e, 0xa3, 0x8e, 0x49, 0xad, 0x7f, 0xb4, 0x63, 0x14, 0xd2, - 0x77, 0x38, 0x2a, 0x56, 0xe8, 0x8f, 0x06, 0x8b, 0xc1, 0xb1, 0xdb, 0x49, - 0xb5, 0xb0, 0xc4, 0x0c, 0x81, 0xd3, 0x38, 0xeb, 0x80, 0x3e, 0xbc, 0x7f, - 0xfa, 0xab, 0x4e, 0xca, 0xd2, 0xe2, 0xce, 0x5f, 0x21, 0x61, 0x66, 0x54, - 0x89, 0xbc, 0xc2, 0x13, 0x24, 0x03, 0x91, 0x8e, 0x3a, 0x03, 0xdf, 0x23, - 0x19, 0xfc, 0xab, 0xd8, 0x2e, 0xb4, 0x68, 0xf4, 0xfd, 0x52, 0x3b, 0x3e, - 0x48, 0x79, 0x7c, 0xc0, 0x19, 0xbe, 0x50, 0xb9, 0x24, 0x29, 0x62, 0x14, - 0xf0, 0xbc, 0x0e, 0x87, 0xf3, 0xae, 0x17, 0x56, 0xbd, 0xd5, 0xec, 0x56, - 0x70, 0xac, 0x6e, 0xe5, 0x07, 0xfd, 0x54, 0x28, 0xf2, 0x28, 0xc8, 0x3c, - 0x92, 0x19, 0x70, 0x3a, 0x8f, 0x62, 0x47, 0x4c, 0xe6, 0xa1, 0xe2, 0x1c, - 0xd5, 0xbb, 0x9c, 0x9e, 0xd6, 0x4f, 0x43, 0x02, 0x5d, 0x2b, 0x4a, 0x96, - 0x5c, 0x6a, 0xa2, 0x43, 0x37, 0x94, 0xc0, 0x60, 0x8d, 0xb1, 0x83, 0xf3, - 0x7c, 0xd9, 0xc0, 0xc8, 0xcf, 0x60, 0x38, 0xef, 0x93, 0x57, 0xcc, 0x7e, - 0x25, 0xb8, 0x94, 0x69, 0x1e, 0x1e, 0x68, 0x92, 0x28, 0x60, 0x2f, 0xe6, - 0x65, 0xd9, 0x63, 0x52, 0x46, 0x59, 0xd8, 0x21, 0xe4, 0x91, 0x90, 0xb9, - 0xe7, 0xd7, 0xd6, 0x85, 0xde, 0x8b, 0x79, 0xad, 0xe9, 0x76, 0x8f, 0x71, - 0x2b, 0xd9, 0xbd, 0xc4, 0xcb, 0x14, 0x91, 0xd8, 0xc4, 0xde, 0x60, 0xf3, - 0x1b, 0x6a, 0x79, 0xa0, 0xb6, 0x01, 0x1b, 0x83, 0x10, 0x32, 0x46, 0x48, - 0xe8, 0x01, 0xae, 0xae, 0xc7, 0xc0, 0x1a, 0xa6, 0x9d, 0x12, 0xcb, 0x6b, - 0x34, 0x52, 0x79, 0x2c, 0x61, 0x92, 0x78, 0x51, 0xa6, 0x9d, 0x64, 0x87, - 0x1f, 0x39, 0x42, 0x40, 0xda, 0x70, 0x70, 0x36, 0x13, 0xcf, 0x71, 0xcd, - 0x73, 0xd7, 0x8d, 0x92, 0x77, 0xb8, 0x9d, 0xd5, 0x93, 0x67, 0x25, 0x7f, - 0xa8, 0xc1, 0xa3, 0x3d, 0xc6, 0x91, 0xac, 0xad, 0xa4, 0x8c, 0x56, 0x38, - 0xad, 0xae, 0x4b, 0xee, 0x09, 0xb7, 0x86, 0x0c, 0x04, 0x9b, 0xa3, 0x2c, - 0xd9, 0xe9, 0xf3, 0xe0, 0x82, 0x70, 0x39, 0xad, 0x8d, 0x1f, 0xfb, 0x1a, - 0xea, 0xd6, 0x2b, 0xcd, 0x31, 0x61, 0xb6, 0x64, 0x9f, 0x63, 0xc3, 0x29, - 0x48, 0x46, 0x57, 0x3b, 0xd4, 0x90, 0xb2, 0xbb, 0xee, 0x07, 0x83, 0x8e, - 0x9d, 0xb8, 0x02, 0xb4, 0x13, 0xc1, 0xf7, 0x9a, 0xc4, 0xf1, 0x47, 0x73, - 0xa6, 0x47, 0x72, 0x0c, 0x53, 0x4b, 0x14, 0x7a, 0x91, 0x82, 0xde, 0xe1, - 0xa3, 0x50, 0x73, 0xb1, 0x58, 0x33, 0x13, 0xd0, 0x0d, 0xcb, 0x9f, 0x42, - 0x0e, 0x6b, 0x67, 0x49, 0xd1, 0x7c, 0xef, 0x3e, 0xd9, 0xa0, 0x99, 0x2d, - 0x9c, 0x29, 0x16, 0x77, 0x16, 0xa1, 0xd0, 0x6e, 0xdb, 0x82, 0xdb, 0x1b, - 0xef, 0x12, 0xa4, 0xe3, 0x6a, 0xf3, 0xc8, 0x38, 0x04, 0x1c, 0x9a, 0x49, - 0x22, 0xdc, 0x74, 0xb9, 0x9f, 0x6e, 0x9a, 0xb4, 0x51, 0x9b, 0x88, 0x9a, - 0xd9, 0x65, 0x8f, 0x6e, 0xc8, 0x4b, 0xbe, 0x14, 0x64, 0x9c, 0x85, 0xf2, - 0xc6, 0xec, 0x21, 0x23, 0x19, 0xce, 0xee, 0x0e, 0x0e, 0x45, 0x61, 0xe9, - 0x3a, 0x4e, 0xb3, 0x78, 0x5c, 0xea, 0x49, 0x20, 0x99, 0xce, 0xe9, 0x0c, - 0xbb, 0x94, 0x29, 0x72, 0xb8, 0xce, 0x40, 0xee, 0xc3, 0x8c, 0xe4, 0x77, - 0x07, 0xbf, 0xbe, 0xf8, 0x5f, 0xe1, 0x66, 0xa7, 0xa9, 0xf3, 0x6d, 0x6f, - 0x1c, 0x43, 0xcc, 0x1b, 0xa7, 0x58, 0x8a, 0x97, 0xda, 0x4e, 0x77, 0xe4, - 0x01, 0xdb, 0x9c, 0x1c, 0x8c, 0x74, 0xec, 0x7e, 0x8e, 0xd0, 0xbe, 0x18, - 0xe8, 0x96, 0x09, 0x9d, 0x79, 0xd2, 0x47, 0x04, 0x33, 0x46, 0xec, 0x5d, - 0x63, 0x90, 0x2e, 0x0a, 0x8c, 0xe1, 0xb6, 0x9c, 0xf2, 0xa4, 0xe0, 0x0e, - 0xc0, 0x1a, 0xda, 0x86, 0x16, 0x73, 0xf8, 0x63, 0xa7, 0x73, 0xb3, 0x0d, - 0x97, 0xd5, 0xa9, 0xf0, 0xab, 0x1f, 0x33, 0xf8, 0x4b, 0xe1, 0x1d, 0xef, - 0x8a, 0x9c, 0x4e, 0x91, 0x5b, 0xdb, 0xa0, 0xfd, 0xe4, 0xb7, 0x72, 0x28, - 0x61, 0xe5, 0x95, 0xf9, 0xc0, 0xc2, 0xf7, 0x19, 0xe0, 0x30, 0xfa, 0x7a, - 0xfd, 0x71, 0xfb, 0x25, 0xe8, 0x7f, 0x0f, 0x3e, 0x16, 0x6a, 0x1a, 0xbd, - 0x87, 0x89, 0xfc, 0x2f, 0x2f, 0x88, 0xb4, 0x2b, 0x90, 0x9e, 0x4a, 0xce, - 0xcb, 0x13, 0x49, 0x2a, 0x79, 0x7b, 0x18, 0x36, 0x32, 0xa8, 0xa1, 0x08, - 0x21, 0x79, 0x6c, 0xf2, 0x48, 0xc8, 0x39, 0xdf, 0xd9, 0xf7, 0x9a, 0x8d, - 0xef, 0xf6, 0x76, 0x83, 0x17, 0x93, 0x63, 0xc4, 0x4e, 0x07, 0xca, 0xac, - 0x83, 0x19, 0x50, 0x07, 0x18, 0x24, 0x72, 0x3b, 0xd7, 0xbf, 0x78, 0x47, - 0x47, 0xba, 0xb7, 0x85, 0x60, 0x65, 0x55, 0x03, 0x00, 0x2e, 0x2b, 0xee, - 0x72, 0x6c, 0xb1, 0x42, 0x3c, 0xd2, 0xd7, 0xfa, 0xec, 0x7a, 0x15, 0x30, - 0x91, 0xa2, 0xb9, 0x6f, 0x77, 0xd4, 0xf0, 0xaf, 0xda, 0x57, 0x43, 0xd1, - 0x3e, 0x2a, 0x78, 0x9e, 0xe7, 0x50, 0xd2, 0x34, 0xd1, 0xe1, 0xdb, 0x0f, - 0xb1, 0x0b, 0x4b, 0x3b, 0x68, 0xc6, 0xf8, 0x2d, 0xe3, 0x43, 0xb8, 0xa9, - 0x0a, 0xab, 0x92, 0x5c, 0xb3, 0x64, 0x11, 0xd4, 0xf0, 0x73, 0x5f, 0x1e, - 0x6a, 0xdf, 0x08, 0xfc, 0x75, 0xe1, 0x9b, 0x86, 0xd4, 0x6c, 0xad, 0xcd, - 0xd5, 0x9e, 0xed, 0xc9, 0x79, 0xa7, 0x6d, 0x9c, 0x15, 0xf5, 0x28, 0x14, - 0x32, 0x9f, 0xe1, 0xc1, 0xed, 0xd6, 0xbf, 0x5f, 0x2e, 0xb4, 0x1b, 0x59, - 0x20, 0xff, 0x00, 0x49, 0x8e, 0x36, 0x53, 0xc3, 0x02, 0xb9, 0xfa, 0xd7, - 0x99, 0x6a, 0x9e, 0x0b, 0xb5, 0xd3, 0xa5, 0x6d, 0x43, 0xc3, 0xbf, 0xba, - 0x75, 0x53, 0xfe, 0x8f, 0x92, 0x22, 0x6e, 0x0f, 0x61, 0xd3, 0xaf, 0x51, - 0x9f, 0xa1, 0xac, 0xb1, 0xd9, 0x54, 0x3d, 0xe9, 0x45, 0x5a, 0xfd, 0xbb, - 0xfa, 0x1a, 0x53, 0xc3, 0xc2, 0x7a, 0x3d, 0x0f, 0xc6, 0x1b, 0xeb, 0xa6, - 0x9a, 0xe6, 0x6b, 0x29, 0xd4, 0x89, 0xae, 0x5d, 0xc4, 0x8c, 0x4e, 0xd6, - 0x8d, 0x14, 0x91, 0x86, 0xe3, 0x71, 0x2b, 0x8c, 0x16, 0x00, 0xe0, 0xe4, - 0x06, 0xc7, 0x15, 0xf3, 0xc6, 0xb9, 0x35, 0x8c, 0x37, 0x37, 0x16, 0x79, - 0x96, 0x19, 0x15, 0xb6, 0x18, 0x18, 0xfd, 0x0f, 0x27, 0xaa, 0x93, 0xd8, - 0x73, 0xe9, 0x5f, 0xaf, 0xbf, 0x15, 0x34, 0x8f, 0x08, 0xea, 0x2f, 0x22, - 0x78, 0xab, 0x47, 0xf2, 0x59, 0xed, 0xc2, 0x9b, 0xc5, 0x86, 0x3f, 0x3d, - 0x9d, 0x37, 0x31, 0x55, 0x93, 0x69, 0x47, 0x05, 0x86, 0xe0, 0x0e, 0x18, - 0x67, 0x27, 0x04, 0x1a, 0xf8, 0xef, 0xc6, 0x5f, 0xb3, 0xdd, 0x85, 0xcc, - 0x92, 0x4d, 0xe1, 0x7b, 0xfd, 0xc6, 0x44, 0x32, 0x3f, 0x9a, 0x42, 0x3b, - 0x21, 0x3c, 0x06, 0x60, 0x06, 0x49, 0x27, 0x9e, 0xa4, 0x67, 0x8c, 0x57, - 0x91, 0x43, 0x0f, 0x28, 0xb7, 0x73, 0x5a, 0xb4, 0x1c, 0x1d, 0xb7, 0xf4, - 0x3e, 0x2a, 0xb0, 0xd4, 0xad, 0x64, 0xbe, 0xb6, 0x26, 0x37, 0x91, 0xfc, - 0xc2, 0x24, 0x88, 0x44, 0x1f, 0xe4, 0xc6, 0x03, 0x01, 0xcf, 0xd0, 0xfd, - 0x72, 0x31, 0xd6, 0xb5, 0x24, 0x16, 0x6d, 0x71, 0x15, 0xd4, 0x1f, 0xea, - 0xf8, 0x0d, 0xb4, 0x29, 0xc9, 0x66, 0xe5, 0x7b, 0xf7, 0x18, 0xe3, 0x23, - 0x9a, 0xee, 0xb5, 0xff, 0x00, 0x85, 0x3e, 0x2a, 0xf0, 0xf2, 0x07, 0xfe, - 0xcf, 0xb8, 0x96, 0x4d, 0x9e, 0x4b, 0xc9, 0x19, 0x67, 0x0c, 0xa5, 0x89, - 0xdd, 0xc9, 0x5e, 0x7b, 0x92, 0x7d, 0x7a, 0x1c, 0x57, 0x0f, 0x07, 0x87, - 0xb5, 0x48, 0xa6, 0x68, 0x75, 0x1b, 0x39, 0x20, 0x64, 0x5d, 0xf1, 0x32, - 0x2e, 0xcc, 0x95, 0xe7, 0x18, 0xc1, 0xc9, 0xcf, 0x1c, 0x7f, 0x8d, 0x74, - 0x73, 0x2e, 0xe6, 0x0e, 0x5e, 0x56, 0x1d, 0x7d, 0x7a, 0xd0, 0x13, 0x15, - 0xa2, 0xb0, 0x06, 0x4f, 0xde, 0x09, 0x0f, 0x4e, 0x70, 0x38, 0x07, 0x18, - 0xc0, 0xee, 0x3b, 0xfb, 0xd4, 0x77, 0xfa, 0xc5, 0x9c, 0x60, 0x4e, 0x65, - 0x7c, 0x7c, 0xa8, 0x91, 0x82, 0xca, 0xa0, 0x05, 0x00, 0x9f, 0x9b, 0x27, - 0x38, 0x1e, 0xa4, 0x56, 0x6d, 0xc4, 0x17, 0xb7, 0xf7, 0x96, 0xf1, 0x3c, - 0x7e, 0x53, 0x4a, 0x86, 0x10, 0xf2, 0xa8, 0x0c, 0x0a, 0x64, 0xfc, 0xdc, - 0xe4, 0x0c, 0xf4, 0xef, 0xf5, 0xad, 0x23, 0xa1, 0xcb, 0x7b, 0x32, 0x3d, - 0xa4, 0x0f, 0xe5, 0x8f, 0x97, 0x6c, 0x03, 0xcc, 0x05, 0xcf, 0x38, 0x1c, - 0x6e, 0xf5, 0x1d, 0x3b, 0x13, 0xcf, 0x35, 0x1a, 0x2b, 0x5c, 0x9f, 0x6a, - 0x96, 0xe6, 0xbd, 0xa6, 0xbf, 0xa7, 0xa5, 0xc2, 0xc9, 0x76, 0x44, 0x8a, - 0x8a, 0x4c, 0x6a, 0x41, 0x07, 0x9f, 0xef, 0x05, 0x6e, 0x3e, 0xa0, 0xe7, - 0xb7, 0xbd, 0x6e, 0x4f, 0xa9, 0xd9, 0xcf, 0x0f, 0x51, 0x18, 0xc9, 0xf9, - 0x09, 0xe4, 0x03, 0xf3, 0x75, 0xec, 0x49, 0x03, 0x27, 0xd3, 0x8c, 0xfa, - 0x79, 0xdd, 0x8d, 0x8f, 0xcf, 0xf6, 0x84, 0x57, 0x50, 0x66, 0xf2, 0x55, - 0x98, 0xe5, 0x77, 0xe0, 0xed, 0x03, 0x04, 0x10, 0xcc, 0x01, 0xc0, 0x00, - 0xd6, 0x9d, 0x96, 0x93, 0xad, 0x2e, 0xa4, 0xd2, 0xc3, 0x69, 0x36, 0x4c, - 0x82, 0x39, 0x91, 0x9d, 0x4e, 0x32, 0x33, 0x85, 0x5e, 0x30, 0x57, 0xa8, - 0xef, 0xb7, 0x3e, 0xf5, 0x9c, 0xe1, 0xd7, 0x98, 0x4e, 0x6a, 0xfd, 0x8f, - 0x5a, 0xf0, 0xe6, 0xb1, 0x6d, 0x69, 0x72, 0x93, 0x5c, 0x22, 0xef, 0xc8, - 0x70, 0x24, 0x01, 0x80, 0x3c, 0x6d, 0xda, 0x7d, 0xbf, 0x9f, 0xd6, 0xbe, - 0xe2, 0xf8, 0x57, 0xe3, 0xad, 0x32, 0x3b, 0x28, 0x8c, 0x8b, 0x24, 0x32, - 0xc5, 0x3a, 0xc8, 0xb1, 0x33, 0xb6, 0x33, 0x91, 0xb9, 0x98, 0x82, 0x70, - 0xbc, 0x06, 0x2c, 0x3f, 0x0e, 0x79, 0xaf, 0x82, 0x2d, 0x3c, 0x0f, 0xe3, - 0x0b, 0xd9, 0x73, 0x6b, 0x6d, 0x73, 0xe4, 0x49, 0x1f, 0x9d, 0x0d, 0xd1, - 0x86, 0x53, 0x13, 0xb8, 0xcf, 0xee, 0xd6, 0x50, 0x98, 0xdf, 0x91, 0x80, - 0xa0, 0x1e, 0x7f, 0x0a, 0xe8, 0x74, 0xeb, 0x3f, 0x88, 0xba, 0x86, 0x97, - 0x1b, 0x69, 0x7a, 0x76, 0xa2, 0x2e, 0x16, 0x7f, 0x24, 0xce, 0xdb, 0xed, - 0x8c, 0x6a, 0x71, 0x90, 0xde, 0x62, 0x80, 0x72, 0x0f, 0x1e, 0x9f, 0x4e, - 0x2b, 0xe6, 0x33, 0x6c, 0x99, 0x62, 0x55, 0x9b, 0x30, 0x71, 0xe6, 0x7e, - 0xe9, 0xf7, 0xb2, 0xfc, 0x5b, 0xd6, 0x62, 0xf1, 0x1a, 0x6a, 0x67, 0x51, - 0x8a, 0x38, 0x22, 0xd4, 0x96, 0x27, 0xb6, 0x8a, 0x55, 0xc8, 0xb6, 0xdb, - 0x86, 0xda, 0xb2, 0x3a, 0x17, 0x0c, 0x31, 0x8f, 0xbc, 0x31, 0x92, 0x00, - 0xcd, 0x7e, 0xa6, 0x78, 0x7f, 0xe3, 0x65, 0xce, 0xab, 0x63, 0xa7, 0x5b, - 0x78, 0x46, 0x59, 0x6f, 0x4d, 0xc1, 0x5b, 0x79, 0x5a, 0xd9, 0x15, 0x59, - 0x23, 0x45, 0x6c, 0xef, 0xda, 0xc0, 0x05, 0x04, 0x0e, 0xa4, 0x0e, 0xc7, - 0x23, 0x15, 0xf8, 0xdd, 0xe0, 0x9f, 0x80, 0x7e, 0x35, 0xf1, 0x1b, 0x5b, - 0x6a, 0x1a, 0xad, 0xff, 0x00, 0x9a, 0xb0, 0xa8, 0x13, 0xda, 0x5b, 0xe9, - 0xe9, 0x72, 0xf2, 0x30, 0x65, 0x2c, 0x10, 0xac, 0x6a, 0xbf, 0x75, 0x80, - 0xce, 0xf3, 0x9e, 0x9c, 0x8c, 0xd7, 0xeb, 0xc7, 0xc0, 0x9f, 0x83, 0x53, - 0xf8, 0x53, 0x47, 0xfb, 0x27, 0x89, 0xe5, 0x5f, 0xb0, 0x96, 0x59, 0x62, - 0xb0, 0xb7, 0x50, 0x92, 0xb0, 0xe9, 0x8b, 0x86, 0x0a, 0x15, 0x41, 0x00, - 0x7c, 0x88, 0x38, 0xc9, 0x19, 0xef, 0x5f, 0x23, 0x5b, 0x82, 0xea, 0x62, - 0x2b, 0xd3, 0x78, 0x58, 0xdd, 0xa5, 0x67, 0xd1, 0x5b, 0xcd, 0xe9, 0xff, - 0x00, 0x04, 0xd1, 0xe5, 0xb2, 0x6b, 0x9a, 0x5a, 0x23, 0xe9, 0xfd, 0x3b, - 0xe0, 0xff, 0x00, 0x84, 0xfe, 0x31, 0x38, 0xbc, 0xf1, 0x04, 0x4f, 0x0f, - 0x97, 0xe5, 0xa9, 0x7b, 0x59, 0x1d, 0x21, 0xca, 0x15, 0x93, 0x6b, 0x61, - 0xb6, 0xb1, 0x2d, 0x86, 0x05, 0x70, 0x31, 0x81, 0xd2, 0xbd, 0x4e, 0x7f, - 0xd9, 0xef, 0xe0, 0x9d, 0x96, 0x8e, 0x9a, 0x24, 0x9a, 0x4e, 0x97, 0x3c, - 0x51, 0xc3, 0xe4, 0xa2, 0xdc, 0xdb, 0xa3, 0x90, 0xbd, 0x86, 0x71, 0xf9, - 0x73, 0x5c, 0x95, 0xbf, 0x8d, 0x61, 0xd3, 0x6c, 0xe3, 0xb0, 0xd3, 0x42, - 0xc5, 0x6f, 0x0a, 0x08, 0xa3, 0x8a, 0x3f, 0xba, 0x00, 0xfa, 0x1f, 0xcf, - 0xd6, 0xb9, 0xad, 0x4b, 0xe2, 0x0c, 0x92, 0x92, 0x4b, 0x3b, 0x63, 0x8e, - 0x4f, 0xff, 0x00, 0x5e, 0xbf, 0x64, 0xe1, 0x8e, 0x0f, 0x86, 0x06, 0x17, - 0xab, 0x2e, 0x79, 0xbf, 0xb9, 0x7a, 0x2f, 0xe9, 0x8d, 0x51, 0xa7, 0x0f, - 0x81, 0x7c, 0xcf, 0xff, 0xd4, 0xfc, 0xf5, 0xd6, 0xfc, 0x43, 0x2d, 0xc4, - 0x4d, 0xf3, 0x6e, 0xe4, 0xaf, 0x3c, 0xfa, 0xfb, 0xd7, 0x91, 0x6a, 0xb3, - 0x1b, 0xe2, 0x60, 0x7f, 0x98, 0x13, 0x8e, 0xbd, 0xbf, 0xc6, 0xbd, 0x0e, - 0x4d, 0x13, 0x52, 0x74, 0x92, 0x47, 0x7b, 0x40, 0x01, 0xe5, 0x5a, 0x43, - 0xb8, 0xf5, 0xce, 0x3e, 0x4e, 0x6b, 0x88, 0xd5, 0xf4, 0xbb, 0xa8, 0xd7, - 0x7c, 0x53, 0xc5, 0xd4, 0x6e, 0x50, 0x84, 0x1c, 0x13, 0xce, 0x18, 0xf1, - 0xfa, 0x7f, 0x4a, 0xec, 0xc4, 0x54, 0x8c, 0xa2, 0xe2, 0xf5, 0x39, 0x68, - 0xc1, 0xa6, 0xa4, 0x8f, 0x25, 0xbc, 0xd1, 0x20, 0xd3, 0xee, 0x64, 0xbd, - 0x8c, 0xdc, 0x65, 0x6d, 0xe5, 0xd8, 0xb0, 0x29, 0x33, 0x0d, 0xaa, 0xdd, - 0x24, 0x55, 0xe0, 0x73, 0x8c, 0x6e, 0x52, 0xc0, 0x90, 0x49, 0xcd, 0x60, - 0xfc, 0x3e, 0xd2, 0x87, 0x88, 0x7c, 0x52, 0x3c, 0x2f, 0x73, 0x2c, 0xf6, - 0x37, 0x12, 0x79, 0xfe, 0x6d, 0xd5, 0xce, 0x10, 0x44, 0xd1, 0x92, 0x71, - 0xe5, 0xae, 0x3e, 0x7e, 0x76, 0xae, 0xe2, 0x76, 0x90, 0x39, 0xcd, 0x7a, - 0xac, 0xd0, 0x49, 0x6e, 0x99, 0x79, 0x19, 0x58, 0x1c, 0x87, 0x42, 0x72, - 0x0f, 0x3c, 0xe7, 0x8d, 0xbd, 0x7f, 0xfa, 0xf5, 0xc5, 0xdf, 0x45, 0x02, - 0xce, 0x97, 0x56, 0xe8, 0xad, 0x34, 0x4c, 0x76, 0xcc, 0xa3, 0x6b, 0x0d, - 0xdd, 0x79, 0x5f, 0xf3, 0xf5, 0xed, 0xf1, 0x15, 0x38, 0x7f, 0xdf, 0xe6, - 0x7a, 0xa7, 0xd0, 0xee, 0xab, 0x4e, 0x95, 0x49, 0x49, 0xcb, 0x46, 0xcd, - 0x7d, 0x47, 0xe1, 0xe6, 0xaf, 0xa7, 0x6a, 0xa2, 0xf2, 0xc6, 0xe1, 0xae, - 0x60, 0x03, 0xca, 0x54, 0x9d, 0x17, 0x7b, 0x47, 0x92, 0x49, 0x46, 0x8c, - 0x2b, 0x2e, 0x49, 0xdd, 0xd7, 0x3c, 0x9c, 0xe4, 0xf4, 0xe1, 0x23, 0xf0, - 0x4e, 0xb1, 0x65, 0x3b, 0x6a, 0x5f, 0x66, 0x49, 0xdd, 0xc4, 0xa6, 0x55, - 0x72, 0xec, 0xaa, 0xee, 0xac, 0xa5, 0x81, 0x27, 0xb9, 0xc6, 0x39, 0x53, - 0x8c, 0x8c, 0x30, 0x27, 0x3d, 0xbb, 0x78, 0xfb, 0x59, 0xb4, 0x78, 0xe2, - 0x99, 0x1a, 0xe2, 0xdd, 0x54, 0x80, 0xb3, 0xa0, 0x0c, 0xc1, 0x80, 0xc8, - 0x05, 0x46, 0x38, 0xc1, 0xc7, 0xf1, 0x11, 0xcf, 0x1d, 0x06, 0x85, 0x8f, - 0xc4, 0x1f, 0x0f, 0x5f, 0x06, 0x92, 0x13, 0x3c, 0x4a, 0xcc, 0xce, 0x8b, - 0x90, 0xd1, 0x6f, 0x6e, 0xa0, 0xf0, 0xe3, 0xef, 0x77, 0x03, 0x38, 0xed, - 0x53, 0x53, 0x23, 0xa1, 0x2d, 0x52, 0xe5, 0xf4, 0xff, 0x00, 0x23, 0x92, - 0xa6, 0x5d, 0x09, 0x69, 0xcb, 0xf7, 0x1e, 0x19, 0x7b, 0x61, 0x3d, 0xcc, - 0x0b, 0x69, 0x71, 0xa7, 0xcd, 0x6e, 0x86, 0x5b, 0x78, 0xcd, 0xe1, 0x47, - 0x72, 0x15, 0x48, 0xdd, 0xbe, 0x40, 0x54, 0x31, 0x04, 0xe0, 0x60, 0xaa, - 0xe0, 0x75, 0xe4, 0x63, 0x99, 0x99, 0x2c, 0x2e, 0x6d, 0x4a, 0x4a, 0x65, - 0x0d, 0xb4, 0xa9, 0x29, 0x0c, 0x91, 0x89, 0x3e, 0x62, 0x85, 0x42, 0x01, - 0x95, 0x07, 0x9d, 0xd9, 0xc1, 0xc0, 0x07, 0xb9, 0xaf, 0xab, 0x91, 0xb4, - 0xcd, 0x52, 0x63, 0x3b, 0xc9, 0x6e, 0x4a, 0xc5, 0x2c, 0x8b, 0x10, 0x60, - 0xa3, 0x7e, 0x17, 0x6a, 0xed, 0xce, 0xef, 0xef, 0x0c, 0x90, 0x3a, 0xd6, - 0xb5, 0x9d, 0xb5, 0xaf, 0xd9, 0x53, 0x61, 0xb4, 0x2c, 0xec, 0x44, 0x83, - 0x80, 0x23, 0x1d, 0x41, 0xeb, 0x93, 0xc6, 0x3f, 0x3a, 0xc6, 0x39, 0x14, - 0x7f, 0x9d, 0x99, 0x4b, 0x28, 0x82, 0x7b, 0xff, 0x00, 0x5e, 0xa7, 0xc9, - 0xf6, 0x70, 0xc3, 0x2c, 0xfe, 0x45, 0xcc, 0x93, 0x8d, 0xee, 0xde, 0x4c, - 0x31, 0xc1, 0x1c, 0x64, 0x06, 0x47, 0x04, 0x65, 0x9f, 0x8c, 0x7d, 0xe2, - 0xdb, 0xba, 0xfc, 0xc3, 0x3c, 0x8a, 0xb3, 0xff, 0x00, 0x08, 0x84, 0x1a, - 0x9d, 0xf8, 0x96, 0xc6, 0x1d, 0x48, 0x4b, 0x2f, 0xef, 0x6d, 0xe6, 0x16, - 0xeb, 0xb4, 0x1d, 0xfb, 0x04, 0x72, 0x67, 0x66, 0xc5, 0xc1, 0x27, 0x93, - 0xf7, 0x78, 0xea, 0x54, 0x57, 0xd2, 0xf1, 0x49, 0xe1, 0x7d, 0x3e, 0x36, - 0x37, 0xb3, 0xdb, 0x2f, 0x96, 0xc4, 0x44, 0xa6, 0x36, 0x6c, 0x6d, 0x38, - 0xe7, 0xa0, 0x1c, 0x74, 0xc7, 0xd2, 0xb4, 0xe3, 0xf1, 0x27, 0x84, 0xde, - 0xe4, 0xcd, 0x6d, 0x22, 0x22, 0xc6, 0x59, 0x1a, 0x40, 0x8a, 0xa4, 0xa6, - 0xd1, 0x80, 0x77, 0x1e, 0x4e, 0xe2, 0x48, 0x1c, 0x0f, 0xd7, 0x35, 0xfd, - 0x81, 0x1b, 0xfc, 0x6c, 0xca, 0x39, 0x5c, 0x6e, 0xec, 0xcf, 0x27, 0xb0, - 0xf8, 0x7b, 0xe2, 0x49, 0xaf, 0x21, 0x9b, 0x50, 0x68, 0xad, 0xd6, 0x2c, - 0x79, 0x33, 0x6d, 0x0f, 0xb1, 0x98, 0x10, 0x43, 0x60, 0x00, 0x4b, 0x6e, - 0x27, 0x2d, 0xc7, 0xa1, 0xe1, 0x6b, 0xb2, 0xb1, 0xf0, 0x5f, 0x87, 0xb4, - 0x2d, 0xb3, 0x5f, 0x6f, 0xbb, 0x9f, 0xe6, 0x63, 0xb1, 0x40, 0xca, 0x96, - 0xe7, 0x19, 0xc2, 0x00, 0x0e, 0x07, 0x27, 0x8c, 0x0e, 0x6a, 0x29, 0xfe, - 0x22, 0x5b, 0xcf, 0xa7, 0x7f, 0x66, 0xdb, 0x87, 0x99, 0xa2, 0xb8, 0xf3, - 0x1a, 0x49, 0x48, 0x05, 0xa4, 0x5c, 0x05, 0x6f, 0x94, 0xed, 0xc7, 0xa0, - 0xfe, 0x7d, 0x2b, 0x13, 0x54, 0xd7, 0x3c, 0x49, 0xe2, 0xd9, 0x22, 0xb9, - 0x79, 0x16, 0x4f, 0x25, 0x76, 0xa3, 0x31, 0xdd, 0x86, 0x24, 0xb3, 0x85, - 0x50, 0x02, 0xa7, 0x61, 0xc0, 0x62, 0x7b, 0xfa, 0xd7, 0x65, 0x1c, 0xaa, - 0x94, 0x15, 0xe0, 0xb5, 0xf3, 0xd4, 0xf5, 0x28, 0x60, 0x29, 0x53, 0x9a, - 0xba, 0xbf, 0xf5, 0xa7, 0xe2, 0x75, 0xed, 0xe2, 0x18, 0x24, 0x78, 0xe0, - 0xb0, 0x80, 0xc6, 0xac, 0x4f, 0xee, 0x51, 0xb0, 0xc5, 0x08, 0x3b, 0x59, - 0xc9, 0x00, 0x8c, 0x75, 0xc2, 0x9c, 0x67, 0xb9, 0xe2, 0xb5, 0x60, 0xd2, - 0x2e, 0xb5, 0x89, 0x59, 0xa6, 0x04, 0x2b, 0x48, 0x5d, 0xa4, 0x93, 0x82, - 0x4b, 0x72, 0xca, 0x14, 0x1c, 0x01, 0x9f, 0xc7, 0xe8, 0x38, 0xac, 0xff, - 0x00, 0x0d, 0xe8, 0xd8, 0x6f, 0xb5, 0x5d, 0x84, 0xdd, 0xd4, 0x28, 0x18, - 0xc7, 0x7c, 0x12, 0x49, 0x24, 0x8f, 0x5e, 0x3e, 0x95, 0xe9, 0xd6, 0x08, - 0x87, 0x01, 0x41, 0x03, 0xeb, 0xce, 0x6b, 0xd4, 0xc3, 0x60, 0xde, 0xf2, - 0x67, 0x6e, 0x2b, 0x18, 0x9e, 0x90, 0x8a, 0x4b, 0xfa, 0xea, 0x49, 0xa6, - 0x68, 0xb1, 0x5a, 0x22, 0xc5, 0x0e, 0x06, 0xda, 0xf4, 0xad, 0x22, 0x76, - 0x84, 0x2a, 0x37, 0xcc, 0x07, 0x1e, 0xe2, 0xb9, 0xb8, 0x15, 0x54, 0x02, - 0x79, 0xfe, 0x75, 0xa7, 0x0b, 0x88, 0xf9, 0xf6, 0xc8, 0x15, 0xeb, 0x41, - 0xd9, 0x59, 0x1e, 0x3c, 0xb5, 0x77, 0x67, 0x77, 0x2d, 0xd2, 0x49, 0x6f, - 0xb7, 0xb8, 0xae, 0x0b, 0x56, 0x97, 0x69, 0x2c, 0xa4, 0x83, 0xcf, 0x35, - 0x64, 0xdf, 0x29, 0x53, 0xbc, 0x8c, 0x8e, 0x99, 0xf5, 0xe9, 0xf8, 0x56, - 0x3d, 0xf3, 0x79, 0x89, 0xf3, 0x77, 0x1c, 0x67, 0xf2, 0xc8, 0xfc, 0x8d, - 0x4f, 0x37, 0x71, 0xd8, 0xf3, 0x7f, 0x13, 0x47, 0x06, 0xa3, 0x68, 0xf6, - 0xb7, 0xa8, 0xb2, 0xa3, 0x8c, 0x32, 0xb2, 0x82, 0x1b, 0xea, 0x08, 0xc1, - 0xaf, 0x96, 0x3c, 0x47, 0xf0, 0xd9, 0x12, 0xe9, 0xae, 0x74, 0x3b, 0x99, - 0xa0, 0x24, 0xe7, 0x63, 0x13, 0x24, 0x7d, 0x7a, 0x0c, 0x9d, 0xc0, 0x7d, - 0x1b, 0x03, 0xb0, 0xaf, 0xae, 0x35, 0x0b, 0x60, 0xcb, 0x90, 0x41, 0xed, - 0xb6, 0xb8, 0x2d, 0x4b, 0x4a, 0x56, 0xc9, 0xc0, 0xcf, 0x3d, 0x2b, 0x9e, - 0xae, 0x1a, 0x2c, 0xda, 0x13, 0x3e, 0x42, 0xd4, 0x34, 0x9f, 0x1a, 0x69, - 0xb9, 0x01, 0x3c, 0xe8, 0xd7, 0xa2, 0xc7, 0xf3, 0x21, 0xe3, 0x18, 0x2a, - 0x71, 0xc7, 0x7e, 0x87, 0xfa, 0xd6, 0x2d, 0xe6, 0xa3, 0xa3, 0x79, 0x65, - 0xb5, 0xdd, 0x3e, 0x0d, 0xe0, 0x11, 0xb5, 0xe1, 0xda, 0xd9, 0xe3, 0xaf, - 0xdd, 0x18, 0xeb, 0x5f, 0x56, 0x5c, 0xe8, 0xce, 0xd9, 0xe8, 0x7d, 0x88, - 0xfe, 0x95, 0x8b, 0x36, 0x83, 0xbd, 0x4a, 0xb4, 0x2a, 0xc0, 0xfa, 0x01, - 0xd0, 0x7a, 0xf6, 0xae, 0x29, 0xe1, 0x1f, 0x73, 0x4b, 0xa3, 0xe5, 0xdb, - 0x38, 0x7e, 0x1d, 0xde, 0x62, 0xe0, 0xe9, 0xe1, 0xa3, 0x6d, 0xdb, 0xc2, - 0xb8, 0x40, 0xa7, 0x8e, 0x3e, 0xe3, 0x72, 0x39, 0xfc, 0xb1, 0x57, 0xed, - 0x3c, 0x39, 0xf0, 0xce, 0x69, 0x8d, 0xcc, 0x5a, 0x5d, 0xd6, 0x76, 0x6f, - 0xdd, 0x95, 0x24, 0x91, 0xd8, 0x1c, 0x03, 0xeb, 0xfe, 0x4d, 0x7b, 0xb4, - 0x9e, 0x17, 0xd2, 0x18, 0x9d, 0xd6, 0x30, 0xb1, 0x27, 0xf8, 0xa2, 0x42, - 0x7d, 0xc7, 0x23, 0x9f, 0xeb, 0x51, 0x8f, 0x05, 0xf8, 0x73, 0x70, 0x5f, - 0xec, 0xf8, 0x49, 0xcf, 0x43, 0x12, 0xfe, 0x9c, 0x0a, 0xe6, 0xa9, 0x81, - 0x93, 0xe8, 0x1c, 0x90, 0x7b, 0x9e, 0x57, 0xa6, 0xe9, 0x9f, 0x08, 0x62, - 0x85, 0x6e, 0x9b, 0x48, 0xf3, 0x16, 0x32, 0xca, 0x55, 0xcc, 0x4a, 0x78, - 0x04, 0xe4, 0x10, 0x8c, 0x7e, 0xf0, 0x1c, 0xfe, 0x23, 0x15, 0xd5, 0x78, - 0x6a, 0xef, 0xc1, 0xf3, 0x5e, 0x05, 0xd0, 0x7c, 0x33, 0x63, 0x3b, 0x12, - 0x0b, 0xac, 0xca, 0x67, 0x6c, 0x8e, 0x87, 0x8d, 0x87, 0x83, 0x8e, 0x06, - 0x4f, 0x53, 0x8a, 0xf4, 0xdd, 0x2f, 0xc2, 0x3a, 0x0d, 0x86, 0xd4, 0xb7, - 0xd3, 0x6d, 0xd7, 0x03, 0x0a, 0x7c, 0xb4, 0xe3, 0xa7, 0xb1, 0xf4, 0xaf, - 0x49, 0xd3, 0xed, 0xee, 0x17, 0x68, 0x2a, 0x8a, 0xbc, 0x74, 0x1c, 0x0e, - 0xc3, 0xdb, 0xf2, 0xac, 0x7f, 0xb3, 0x1b, 0xf2, 0x29, 0x46, 0x9a, 0xd6, - 0xc7, 0x1f, 0xa7, 0xe9, 0xbf, 0x12, 0xaf, 0xf4, 0x7b, 0xed, 0x2f, 0x40, - 0xd3, 0xac, 0x74, 0xd4, 0xbb, 0x86, 0x55, 0x48, 0xe6, 0x88, 0x47, 0x1b, - 0x3b, 0xfd, 0xd6, 0x64, 0x20, 0xb9, 0xc1, 0x19, 0xf9, 0x88, 0x00, 0xf3, - 0xcf, 0x7e, 0xe3, 0xc0, 0xdf, 0x09, 0x35, 0x61, 0x27, 0x93, 0xe2, 0x2b, - 0x78, 0xe6, 0xb8, 0x0b, 0x87, 0x96, 0xd9, 0x5a, 0x4c, 0x2f, 0xca, 0x49, - 0x52, 0x88, 0xb9, 0xc9, 0x56, 0x01, 0x41, 0x64, 0x03, 0xb6, 0x4f, 0x1d, - 0x7e, 0x94, 0xf2, 0xc5, 0xb6, 0x3b, 0x99, 0x18, 0xa2, 0x9f, 0x95, 0x41, - 0x20, 0x0e, 0x7a, 0x81, 0xd0, 0x57, 0xa4, 0xd8, 0x78, 0x96, 0x5d, 0x3e, - 0x31, 0x1c, 0x07, 0x80, 0x06, 0x72, 0x3b, 0x7a, 0x7b, 0xfb, 0x57, 0x47, - 0xf6, 0x34, 0x24, 0x92, 0x92, 0xd8, 0x4a, 0x70, 0x4e, 0xfc, 0xa7, 0x43, - 0xe1, 0x99, 0x74, 0x3d, 0x06, 0x33, 0x69, 0xa6, 0xc7, 0x15, 0xbe, 0x3f, - 0x76, 0xdb, 0x14, 0x07, 0x24, 0x1e, 0x43, 0x77, 0xe0, 0x71, 0x8a, 0xeb, - 0x64, 0xf1, 0x7f, 0x96, 0x9b, 0x15, 0xd7, 0x00, 0xf0, 0xa5, 0x8e, 0x4f, - 0x15, 0xc3, 0x4d, 0xe2, 0x4d, 0x2b, 0x55, 0x1b, 0x35, 0x68, 0x62, 0x91, - 0xc2, 0x05, 0xdc, 0xea, 0x32, 0xa0, 0x67, 0x18, 0x6c, 0x86, 0x1d, 0x7f, - 0x85, 0x85, 0x65, 0xde, 0x68, 0x3a, 0x45, 0xde, 0x1a, 0xc6, 0xe2, 0xe2, - 0x22, 0x48, 0x65, 0x57, 0x61, 0x2a, 0x9c, 0xfa, 0x67, 0x0d, 0xf4, 0xcb, - 0x1a, 0xf7, 0xf0, 0xd0, 0x8d, 0x38, 0xa4, 0x95, 0x8c, 0x2b, 0x49, 0xcd, - 0xdd, 0xbb, 0x9e, 0xad, 0xa4, 0xf8, 0x82, 0xd2, 0xee, 0xec, 0xa6, 0xb7, - 0x78, 0x6c, 0xa0, 0xf2, 0x8b, 0x89, 0x21, 0x8c, 0xc9, 0x97, 0x0d, 0x8d, - 0x84, 0x0c, 0xed, 0xe3, 0x07, 0x38, 0x20, 0xf4, 0xe3, 0x1c, 0xf2, 0x7a, - 0xc7, 0x8a, 0xd2, 0x2b, 0xd9, 0xad, 0x6c, 0x2e, 0x0d, 0xc5, 0xba, 0xfd, - 0xcb, 0x86, 0x8c, 0xc4, 0x5b, 0x8e, 0x72, 0xa4, 0xe7, 0x83, 0x9e, 0x70, - 0x01, 0xeb, 0xc5, 0x70, 0x12, 0xe9, 0x3a, 0xc4, 0x12, 0x7f, 0xa3, 0xcf, - 0x06, 0x02, 0x9e, 0x5f, 0x7c, 0x7c, 0xfa, 0x9c, 0x06, 0xeb, 0xec, 0xd5, - 0x9d, 0x35, 0x97, 0x88, 0x1f, 0x11, 0xb9, 0x87, 0x1b, 0x43, 0x63, 0xcc, - 0x20, 0x71, 0xf5, 0x5e, 0xa7, 0x3f, 0xe4, 0xd6, 0xca, 0xa4, 0xb9, 0xee, - 0x9e, 0x84, 0x49, 0x47, 0x96, 0xd6, 0xd4, 0xff, 0xd5, 0xfc, 0xde, 0x37, - 0x64, 0x38, 0x3f, 0x2e, 0x17, 0x1b, 0x90, 0x16, 0x19, 0x5c, 0xf2, 0x7a, - 0xf7, 0xac, 0x3b, 0xe3, 0xb9, 0x76, 0x64, 0x9f, 0x9b, 0x3d, 0x3b, 0xfe, - 0x54, 0x2d, 0xec, 0x4d, 0x19, 0x32, 0x32, 0x82, 0xa8, 0x47, 0x97, 0xd9, - 0x89, 0x20, 0x60, 0x60, 0x11, 0x91, 0xea, 0x70, 0x31, 0x9e, 0xfd, 0x72, - 0xae, 0x2e, 0xf7, 0x92, 0x5b, 0x6e, 0x70, 0x4a, 0xaa, 0xe4, 0x64, 0x7e, - 0x95, 0xd6, 0xac, 0x71, 0x5d, 0x98, 0x37, 0xd0, 0xdb, 0xb6, 0x4b, 0x02, - 0xc7, 0x04, 0x03, 0x8e, 0x95, 0x85, 0xe4, 0x2b, 0x12, 0xa0, 0x0c, 0x74, - 0xc5, 0x6f, 0x5d, 0x3b, 0x31, 0x3b, 0x32, 0x48, 0x19, 0x39, 0xf4, 0xef, - 0x91, 0xd7, 0xf5, 0xac, 0xd5, 0xda, 0x8b, 0xb9, 0xf8, 0x18, 0xcb, 0x75, - 0xe7, 0xdb, 0x35, 0x56, 0x56, 0xd0, 0xa5, 0x27, 0xd4, 0xcf, 0x6d, 0x3c, - 0xb3, 0xee, 0xec, 0x3b, 0x91, 0xfc, 0xab, 0x16, 0x7f, 0x09, 0xe9, 0x4e, - 0xb0, 0xc7, 0xe4, 0xa4, 0x6b, 0x0c, 0x86, 0x44, 0x58, 0xbe, 0x4c, 0x93, - 0x9c, 0x86, 0x03, 0xa8, 0x39, 0xcf, 0x5e, 0xb5, 0xda, 0x2e, 0xc2, 0xdb, - 0x94, 0x71, 0xfe, 0x73, 0xc5, 0x3f, 0x64, 0x00, 0x15, 0x39, 0xf9, 0xbb, - 0x1f, 0x5a, 0xc6, 0x74, 0x53, 0xd1, 0x9a, 0x42, 0xab, 0x4f, 0x43, 0x88, - 0x93, 0xc2, 0xd6, 0xa6, 0x32, 0xd6, 0xe6, 0x45, 0xde, 0x54, 0x67, 0xe5, - 0x3b, 0x7d, 0xd4, 0x1e, 0x71, 0xc7, 0x72, 0x40, 0xa8, 0x9f, 0xc3, 0xd7, - 0x0a, 0xc1, 0x61, 0xb8, 0x18, 0x53, 0x97, 0x18, 0xfb, 0xc4, 0xe0, 0x73, - 0xcf, 0x07, 0x03, 0xe9, 0x5d, 0xd7, 0xca, 0x46, 0x06, 0x33, 0x9e, 0x49, - 0xc7, 0x5a, 0x80, 0xc2, 0x00, 0xde, 0x70, 0x7d, 0x79, 0xeb, 0x5c, 0xef, - 0x0a, 0x8d, 0xd6, 0x21, 0xf5, 0x3c, 0xff, 0x00, 0x50, 0xf0, 0xba, 0xcb, - 0x07, 0x95, 0x2b, 0x02, 0xc7, 0x70, 0x1c, 0x93, 0xd7, 0xa6, 0x47, 0x43, - 0x4c, 0xb4, 0xf0, 0xed, 0xb4, 0x5f, 0xbb, 0x6c, 0xb7, 0xcb, 0x8d, 0xc4, - 0x00, 0xdc, 0x77, 0xca, 0x81, 0xc8, 0xae, 0xee, 0x68, 0x58, 0x2e, 0xe0, - 0x73, 0x8f, 0x40, 0x7f, 0xad, 0x20, 0xb2, 0x0c, 0x37, 0x0c, 0x8c, 0xf4, - 0x3c, 0x83, 0xf8, 0xf5, 0xfc, 0x6a, 0xbe, 0xab, 0x1e, 0xa2, 0xf6, 0xed, - 0x98, 0xba, 0x5e, 0x89, 0xa3, 0x69, 0xb1, 0x94, 0xb7, 0xb7, 0x88, 0x17, - 0x6d, 0xcc, 0x08, 0xea, 0x71, 0xd7, 0xbf, 0x4a, 0xe9, 0xad, 0x62, 0x83, - 0xfe, 0x59, 0xa0, 0x03, 0xdb, 0x81, 0x8f, 0xf3, 0xff, 0x00, 0xea, 0xaa, - 0x42, 0xd1, 0x51, 0x87, 0x72, 0x48, 0xca, 0x83, 0xf9, 0x91, 0xd7, 0x1f, - 0xe7, 0xeb, 0x57, 0xe1, 0x04, 0x48, 0x15, 0x0e, 0xec, 0x0c, 0x72, 0x00, - 0x3f, 0xfd, 0x7f, 0xd2, 0xb4, 0xf6, 0x29, 0x11, 0xed, 0x1b, 0x3a, 0x5b, - 0x36, 0x5d, 0xc3, 0xe5, 0x38, 0xc6, 0x46, 0x3b, 0x77, 0xae, 0xa2, 0xd2, - 0x44, 0x0a, 0x19, 0xb0, 0x0e, 0x33, 0xc7, 0x5f, 0x63, 0x5c, 0x3c, 0x37, - 0x18, 0xc0, 0xfb, 0xa4, 0x0c, 0xe3, 0x20, 0x67, 0x1f, 0x5f, 0xe8, 0x6a, - 0xec, 0x77, 0x8c, 0xa7, 0x78, 0x6c, 0x81, 0xc1, 0x04, 0xff, 0x00, 0xfa, - 0xb2, 0x68, 0xe5, 0x44, 0xdf, 0xb9, 0xe9, 0x30, 0xdd, 0x03, 0xc6, 0xe0, - 0x36, 0xe3, 0xfc, 0xf3, 0x52, 0x49, 0x78, 0x31, 0xc3, 0x77, 0xc0, 0x39, - 0xaf, 0x3d, 0x3a, 0xb9, 0x4f, 0xf5, 0x7c, 0x8e, 0x83, 0x9e, 0x4f, 0xe3, - 0x9a, 0xb6, 0xba, 0xb2, 0xb2, 0x00, 0xca, 0xa4, 0xf1, 0xcf, 0xcd, 0x9c, - 0x0e, 0xbe, 0xdc, 0xe6, 0x95, 0x84, 0x75, 0xdf, 0x6e, 0xc9, 0xf9, 0xfa, - 0x9f, 0x5f, 0x43, 0x51, 0xcb, 0x72, 0x79, 0x18, 0xe7, 0xbe, 0x0e, 0x71, - 0x5c, 0x8b, 0xea, 0xd1, 0x46, 0x9b, 0xdf, 0x00, 0x03, 0x82, 0xc7, 0x3d, - 0x01, 0xfc, 0x2a, 0x16, 0xd5, 0xff, 0x00, 0x79, 0x87, 0x60, 0x06, 0x70, - 0x39, 0x1c, 0x8e, 0xfd, 0xe8, 0x71, 0x11, 0xb5, 0x34, 0xc4, 0x82, 0xc3, - 0x1e, 0x9c, 0xf1, 0x9a, 0xc4, 0xb9, 0x40, 0xca, 0x46, 0x31, 0x8f, 0x5e, - 0x08, 0xa7, 0xff, 0x00, 0x69, 0xc6, 0xec, 0x70, 0x09, 0xce, 0x71, 0x81, - 0xc7, 0x7f, 0xa5, 0x52, 0x9a, 0xf1, 0x26, 0x5d, 0xdc, 0xe7, 0x39, 0xda, - 0x39, 0x20, 0x76, 0xfa, 0x55, 0x72, 0x85, 0xca, 0x2f, 0x0f, 0xcc, 0x48, - 0x1d, 0x4f, 0x39, 0x18, 0xe7, 0xdb, 0x15, 0x44, 0xc6, 0x26, 0x95, 0x62, - 0x89, 0x43, 0x33, 0x30, 0x50, 0x07, 0x52, 0x49, 0xc0, 0x1d, 0x6a, 0xfb, - 0x5c, 0xc6, 0xdf, 0xbc, 0x61, 0x81, 0x8c, 0x91, 0xfe, 0x35, 0x1c, 0x7b, - 0x19, 0x8c, 0x88, 0xa1, 0x41, 0x07, 0x1d, 0x87, 0xff, 0x00, 0x5a, 0x87, - 0x01, 0xa9, 0x99, 0x6d, 0xa7, 0xba, 0x4e, 0xf1, 0xca, 0x36, 0xb2, 0x31, - 0x04, 0x63, 0xa3, 0x8e, 0x31, 0xf8, 0x54, 0xd1, 0xd9, 0x87, 0x6d, 0xb8, - 0xe7, 0x38, 0x15, 0x71, 0xe4, 0x85, 0x13, 0xe4, 0x46, 0xe3, 0x8e, 0x3b, - 0x9f, 0x5c, 0x55, 0x94, 0x2f, 0x2b, 0x26, 0x5b, 0xa2, 0x60, 0x67, 0xb7, - 0x1c, 0x0a, 0x95, 0x4d, 0x14, 0xe6, 0x3e, 0xda, 0xd2, 0x2f, 0x30, 0x85, - 0x03, 0x76, 0xd5, 0xf4, 0xc8, 0xff, 0x00, 0x26, 0xb5, 0xa3, 0x89, 0x87, - 0x0c, 0xca, 0xa0, 0x1c, 0x7a, 0x03, 0x9f, 0xc3, 0xf2, 0xaa, 0x36, 0xca, - 0x50, 0x8e, 0x46, 0x3b, 0xf7, 0xeb, 0x5b, 0x30, 0xed, 0xea, 0xa3, 0x38, - 0xcf, 0x6c, 0x64, 0x51, 0xc8, 0x85, 0xce, 0xcb, 0x31, 0x2f, 0x97, 0x86, - 0x62, 0x73, 0x9e, 0xa7, 0xb7, 0xff, 0x00, 0xae, 0xb6, 0xa3, 0x6f, 0x3a, - 0x1c, 0x63, 0x20, 0x73, 0xc0, 0x00, 0xf3, 0xea, 0x7a, 0xff, 0x00, 0x4a, - 0xc8, 0x56, 0x59, 0x0e, 0x00, 0xdd, 0xe8, 0x7b, 0x8c, 0x7f, 0x3a, 0xd3, - 0x80, 0xc0, 0x17, 0x6e, 0xe3, 0x9c, 0xe7, 0x8e, 0x6b, 0x45, 0xe4, 0x26, - 0xcb, 0x30, 0xdb, 0x4a, 0xce, 0x15, 0x7a, 0x74, 0x18, 0xe9, 0xfd, 0x73, - 0x5d, 0x25, 0xaa, 0x1b, 0x75, 0x2b, 0x93, 0x9f, 0x5e, 0xd9, 0xff, 0x00, - 0x3d, 0x6b, 0x36, 0x0b, 0x95, 0xc6, 0xd2, 0x57, 0x23, 0xef, 0x33, 0x75, - 0xfc, 0x71, 0x56, 0x13, 0x50, 0x88, 0x82, 0xd9, 0x0c, 0x01, 0xc0, 0x61, - 0xd3, 0xea, 0x08, 0xeb, 0x4a, 0xfa, 0x92, 0xd1, 0xa8, 0x2e, 0x19, 0x13, - 0x6c, 0x6e, 0x01, 0xee, 0x4f, 0x1f, 0xef, 0x1c, 0xd6, 0x0d, 0xfc, 0xf2, - 0x3e, 0x5d, 0xb9, 0x1c, 0xf4, 0x24, 0xe7, 0x1f, 0x8e, 0x29, 0xd2, 0xea, - 0x1b, 0x23, 0x25, 0x4b, 0x29, 0x74, 0xda, 0x17, 0x90, 0x36, 0x9e, 0xbc, - 0x7b, 0xf7, 0xac, 0x29, 0xef, 0x54, 0x7d, 0xee, 0x4e, 0x3f, 0x5e, 0x6a, - 0xa3, 0xb8, 0xa4, 0xec, 0x7f, 0xff, 0xd6, 0xfc, 0xa4, 0x2e, 0x8a, 0xad, - 0x1c, 0x87, 0x18, 0x6f, 0x6c, 0x63, 0x8f, 0x7c, 0xf5, 0xcf, 0x7a, 0xa6, - 0xf2, 0x42, 0x48, 0x0c, 0x38, 0x03, 0x20, 0x9e, 0x45, 0x57, 0x7b, 0xa8, - 0x9b, 0xe6, 0x1c, 0xe3, 0xa7, 0x22, 0xa2, 0x33, 0x92, 0x73, 0x85, 0x38, - 0xfe, 0x12, 0xd9, 0xfe, 0x55, 0xd2, 0xee, 0x71, 0x7c, 0x88, 0xe4, 0xdc, - 0x09, 0x09, 0x92, 0x4f, 0x7e, 0x41, 0xfe, 0xb5, 0x51, 0xa1, 0x25, 0xc3, - 0xc8, 0xe1, 0x4e, 0x0e, 0x3b, 0x37, 0xbf, 0x5f, 0xa5, 0x4f, 0x73, 0x2c, - 0x93, 0xb6, 0xf2, 0x22, 0x8b, 0xda, 0x3c, 0x80, 0x7e, 0xb9, 0x27, 0xfc, - 0x2a, 0x8c, 0xa3, 0x2a, 0x23, 0x6e, 0x4f, 0x6c, 0x12, 0x47, 0xe8, 0x29, - 0x29, 0x30, 0xe5, 0x2d, 0xf9, 0x6c, 0x70, 0xb1, 0xb7, 0x52, 0x00, 0x24, - 0x1f, 0xfe, 0xb5, 0x43, 0x24, 0xce, 0xaf, 0x86, 0x00, 0xf3, 0xc8, 0xe7, - 0xaf, 0x4f, 0x4a, 0xa2, 0xf1, 0x4f, 0xbb, 0xe5, 0x1f, 0x36, 0x79, 0xcb, - 0x0c, 0x7e, 0x54, 0xd8, 0xd2, 0xff, 0x00, 0x24, 0x12, 0x9e, 0xf8, 0x1c, - 0x75, 0xeb, 0xc1, 0xcd, 0x37, 0x2d, 0x46, 0x93, 0x12, 0x5b, 0xd6, 0x8d, - 0xc2, 0xe3, 0x39, 0x3d, 0x80, 0x3c, 0xe2, 0xa2, 0x6d, 0x53, 0x68, 0x05, - 0x23, 0x38, 0xcf, 0x07, 0xa7, 0x4f, 0x4e, 0x6a, 0x59, 0x62, 0xbc, 0xce, - 0xcc, 0x82, 0x3d, 0x36, 0x93, 0xed, 0xdf, 0xdb, 0xda, 0xa9, 0x4d, 0x65, - 0x77, 0x23, 0xf0, 0x4a, 0xe3, 0x9e, 0x13, 0x1c, 0xfe, 0x15, 0x5c, 0xc8, - 0x5b, 0x12, 0x2e, 0xab, 0x38, 0x52, 0xeb, 0x19, 0x2a, 0x0f, 0xcd, 0x9e, - 0xc4, 0x8e, 0x33, 0xcf, 0xf4, 0xab, 0x56, 0x9a, 0xe9, 0x61, 0x89, 0x15, - 0x17, 0x9c, 0xe7, 0x24, 0x74, 0xed, 0xc9, 0xac, 0xcf, 0xec, 0xfb, 0xa8, - 0x1b, 0xcc, 0x59, 0x1f, 0xd0, 0x8c, 0x1e, 0x9f, 0x4e, 0x95, 0x58, 0xe9, - 0x45, 0x88, 0x42, 0xf2, 0x83, 0x8e, 0xb8, 0x07, 0xf3, 0x1f, 0x2f, 0xf9, - 0xed, 0x4b, 0x99, 0x02, 0x6f, 0x73, 0xaf, 0x8e, 0xfe, 0x09, 0xdb, 0x9d, - 0x9c, 0x76, 0x2c, 0x32, 0x7f, 0x2c, 0xf4, 0xad, 0x78, 0xae, 0x6d, 0xd1, - 0x32, 0x19, 0x54, 0x8c, 0x10, 0xcb, 0xc6, 0x3f, 0xcf, 0xe1, 0x5e, 0x6b, - 0xfd, 0x99, 0x76, 0x1b, 0x31, 0xcc, 0xdb, 0x54, 0xf0, 0x0a, 0x95, 0xfe, - 0x59, 0xa6, 0x9b, 0x7d, 0x4a, 0x3c, 0x2e, 0x64, 0x60, 0x7f, 0xba, 0x0a, - 0xf3, 0xfa, 0x71, 0x52, 0xd7, 0x62, 0x94, 0x9f, 0x63, 0xd0, 0x9e, 0x7b, - 0x55, 0x24, 0x79, 0xcb, 0x96, 0x6e, 0xc4, 0x11, 0x83, 0xeb, 0xc9, 0xfd, - 0x2a, 0xbb, 0xdd, 0xc7, 0xd1, 0x59, 0x48, 0x03, 0xf8, 0x3f, 0xc4, 0x73, - 0xfa, 0x57, 0x04, 0x96, 0xd7, 0xff, 0x00, 0x7a, 0x55, 0x63, 0x9c, 0x0e, - 0x0f, 0x23, 0xf3, 0xff, 0x00, 0x1a, 0x73, 0xdb, 0xea, 0x4d, 0x18, 0x08, - 0x87, 0xaf, 0x21, 0x8e, 0x31, 0xf9, 0x67, 0xfa, 0x50, 0xad, 0xd4, 0x77, - 0x67, 0x63, 0xf6, 0xa7, 0x70, 0x5f, 0xe6, 0xe3, 0xb8, 0x27, 0xf3, 0x20, - 0xd3, 0x16, 0xe2, 0x66, 0x7d, 0xee, 0x48, 0x5c, 0xed, 0x19, 0xc7, 0x05, - 0x4f, 0x39, 0xe0, 0x7a, 0x8a, 0xe3, 0x4c, 0x1a, 0x94, 0x07, 0xe4, 0x57, - 0x04, 0x73, 0x95, 0x38, 0x03, 0x3d, 0x71, 0xcd, 0x48, 0xcb, 0xaa, 0xdc, - 0x2e, 0xc9, 0x4c, 0x8c, 0x3d, 0x0e, 0x4f, 0xf2, 0x22, 0xaa, 0xca, 0xfb, - 0x87, 0x31, 0xd9, 0x8b, 0xc4, 0x49, 0x08, 0x03, 0xa9, 0xdf, 0xbb, 0x8e, - 0x4f, 0x70, 0x30, 0x3f, 0x4a, 0x79, 0xbe, 0xb4, 0xc0, 0xf3, 0xa4, 0x38, - 0x27, 0x3c, 0xf5, 0x1e, 0x9e, 0x9f, 0xca, 0xb9, 0x7b, 0x58, 0xef, 0x2d, - 0x86, 0xe5, 0x50, 0xb9, 0x3c, 0x8e, 0x4f, 0x51, 0xdf, 0xa8, 0xe6, 0xac, - 0xca, 0x93, 0xcf, 0x28, 0x79, 0x90, 0x02, 0xa3, 0x0a, 0x49, 0x1d, 0x3e, - 0x98, 0xc7, 0xeb, 0x4d, 0x45, 0x77, 0x13, 0x99, 0xae, 0xfa, 0x82, 0xaf, - 0x4c, 0xb0, 0xcf, 0x0c, 0xa7, 0x9f, 0xcb, 0x92, 0x45, 0x3b, 0xfb, 0x45, - 0xe4, 0x20, 0x42, 0x8d, 0x9c, 0x60, 0x91, 0xc1, 0xc7, 0xae, 0x47, 0x4f, - 0xcb, 0xf2, 0xaa, 0x11, 0xed, 0x87, 0xe7, 0x75, 0x52, 0x38, 0x1b, 0x41, - 0x51, 0xfc, 0x89, 0xfe, 0x55, 0x7c, 0x5e, 0xdb, 0x6d, 0x2a, 0x88, 0xe3, - 0x9e, 0xbb, 0x89, 0xfc, 0x38, 0xa6, 0xe2, 0x84, 0xa5, 0xd0, 0x9e, 0x1b, - 0xac, 0xb8, 0x69, 0x5b, 0x73, 0x1e, 0x70, 0xe3, 0x38, 0xfc, 0x7a, 0x7f, - 0x5a, 0xbf, 0xe7, 0x29, 0x00, 0x21, 0xc8, 0xcf, 0x71, 0x81, 0x9f, 0xce, - 0xb2, 0x9a, 0xe6, 0x07, 0x1c, 0xed, 0x23, 0x18, 0x39, 0xc9, 0x3f, 0xad, - 0x49, 0xf6, 0x9b, 0x48, 0xce, 0x4a, 0x12, 0x47, 0x18, 0x53, 0x8e, 0x3e, - 0xa5, 0x6a, 0x6c, 0x3b, 0xf6, 0x35, 0xde, 0xe1, 0x89, 0x0c, 0xdc, 0x11, - 0xc0, 0xc7, 0x4c, 0x0e, 0xd5, 0x6c, 0xbb, 0xc5, 0x3a, 0xcf, 0x1b, 0x61, - 0xd7, 0x0e, 0x42, 0x12, 0xbb, 0x48, 0xe4, 0x60, 0x80, 0x30, 0x47, 0x5e, - 0x0d, 0x66, 0xc7, 0x79, 0xa4, 0x9e, 0x62, 0x8a, 0xe1, 0x4f, 0x19, 0x72, - 0xea, 0x7f, 0x00, 0x31, 0xd3, 0xeb, 0x44, 0xb7, 0x96, 0x4b, 0xf3, 0x15, - 0x94, 0x13, 0xfd, 0xf3, 0xd4, 0x7b, 0x70, 0x28, 0x48, 0x1b, 0x67, 0x45, - 0xe7, 0x2a, 0x0f, 0x36, 0x43, 0xb9, 0xa5, 0xcb, 0x3b, 0x64, 0xe7, 0x71, - 0x27, 0x92, 0x4e, 0x49, 0xc9, 0xe4, 0x9e, 0xf5, 0x2a, 0x5c, 0xc6, 0x88, - 0x5a, 0x3e, 0xdd, 0x71, 0xc5, 0x73, 0x49, 0xa9, 0xda, 0x92, 0x15, 0xf3, - 0xb4, 0x73, 0x80, 0x7d, 0x7a, 0xf3, 0x8a, 0x90, 0xea, 0x10, 0x6e, 0x0e, - 0x08, 0x0a, 0x4e, 0x79, 0x27, 0x3f, 0x5e, 0xdf, 0xce, 0x93, 0x8d, 0x85, - 0xcd, 0xd8, 0xeb, 0x12, 0x7d, 0xc4, 0xf2, 0xc1, 0x8f, 0x43, 0xf7, 0xbf, - 0xfa, 0xdf, 0xae, 0x6b, 0x42, 0x2b, 0x8f, 0x24, 0x0f, 0x9d, 0x89, 0xec, - 0x41, 0x18, 0x23, 0xe9, 0xd3, 0xf4, 0xcd, 0x70, 0x71, 0xea, 0x68, 0xec, - 0x77, 0x04, 0x18, 0x1f, 0xc0, 0xd8, 0x3c, 0x7e, 0x38, 0xfd, 0x0d, 0x09, - 0xa9, 0xa9, 0x61, 0x24, 0x4a, 0x57, 0x9c, 0xe7, 0x69, 0x27, 0x3f, 0x5e, - 0xd4, 0xb9, 0x47, 0xcc, 0x77, 0xa7, 0x53, 0x9c, 0x11, 0x1a, 0x01, 0x95, - 0xe0, 0x30, 0x1c, 0x73, 0xeb, 0xcf, 0x38, 0xa9, 0x93, 0x50, 0x56, 0x01, - 0x66, 0x75, 0x2c, 0x30, 0x4e, 0x7f, 0xc3, 0x35, 0xc6, 0x8d, 0x58, 0x32, - 0x6d, 0xf3, 0x19, 0x79, 0xe8, 0xfc, 0xff, 0x00, 0x4c, 0xd5, 0x85, 0xb9, - 0xb5, 0x75, 0xde, 0xd7, 0x30, 0x80, 0xa7, 0x9c, 0xa1, 0xe7, 0xfa, 0x9a, - 0x5c, 0xa3, 0xe6, 0xb9, 0xd2, 0x3d, 0xde, 0xf6, 0x2c, 0x4f, 0x1e, 0xa7, - 0x07, 0x8a, 0xce, 0x92, 0x55, 0x70, 0x5a, 0x33, 0x8f, 0xbd, 0x90, 0xc3, - 0x9c, 0xfb, 0x73, 0x5c, 0xdc, 0xfa, 0xa4, 0x71, 0x7c, 0xb1, 0x11, 0x21, - 0x27, 0xef, 0x20, 0x65, 0x1f, 0x53, 0xbb, 0x03, 0xf5, 0xa8, 0x06, 0xa8, - 0xbc, 0x06, 0x27, 0x9c, 0xf7, 0xe0, 0x0f, 0xd6, 0x9a, 0x25, 0xdc, 0xff, - 0xd9 -}; -const unsigned int DayEnvironmentHDRI019_1K_TONEMAPPED_jpg_len = 17065; \ No newline at end of file diff --git a/oomer_voxel_ogt.h b/oomer_voxel_ogt.h deleted file mode 100644 index 4ce22ae..0000000 --- a/oomer_voxel_ogt.h +++ /dev/null @@ -1,236 +0,0 @@ -// oomer wrapper code for opengametools voxel conversion - -#pragma once - -#include "oomer_voxel_vmax.h" - -#include -#include -#include -#include -#include -#include - -#include "../opengametools/src/ogt_vox.h" - -// Only define implementation once to avoid redefinition errors -#ifndef OGT_VOXEL_MESHIFY_IMPLEMENTATION -#define OGT_VOXEL_MESHIFY_IMPLEMENTATION -#endif -#include "../opengametools/src/ogt_voxel_meshify.h" - -// Convert a VmaxModel to an ogt_vox_model -// Note: The returned ogt_vox_model must be freed using ogt_vox_free when no longer needed -/*ogt_vox_model* convert_vmax_to_ogt_vox(const VmaxModel& vmaxModel) { - // Use max dimensions from vmaxModel - // Add 1 to get the actual size (since coordinates are 0-based) - uint32_t size_x = vmaxModel.maxx+1; - uint32_t size_y = vmaxModel.maxy+1; - uint32_t size_z = vmaxModel.maxz+1; - - // Add some safety checks - if (size_x > 256 || size_y > 256 || size_z > 256) { - std::cout << "Warning: Model dimensions exceed 256 limit. Clamping to 256." << std::endl; - size_x = std::min(size_x, 256u); - size_y = std::min(size_y, 256u); - size_z = std::min(size_z, 256u); - } - if (size_x == 0 || size_y == 0 || size_z == 0) { - std::cout << "Error: Model has zero dimensions. Setting minimum size of 1x1x1." << std::endl; - size_x = std::max(size_x, 1u); - size_y = std::max(size_y, 1u); - size_z = std::max(size_z, 1u); - } - // Create the voxel data array (initialized to 0, which means empty in ogt_vox) - size_t voxel_count = size_x * size_y * size_z; - uint8_t* voxel_data = (uint8_t*)ogt_vox_malloc(voxel_count); - if (!voxel_data) { - std::cout << "Error: Failed to allocate memory for voxel data" << std::endl; - return nullptr; - } - memset(voxel_data, 0, voxel_count); // Initialize all to 0 (empty) - - // Fill the voxel data array with color indices - int voxel_count_populated = 0; - for (uint32_t x = 0; x < size_x; x++) { - for (uint32_t y = 0; y < size_y; y++) { - for (uint32_t z = 0; z < size_z; z++) { - // Calculate the index in the 1D array - size_t index = x + (y * size_x) + (z * size_x * size_y); - - if (index < voxel_count) { - try { - // Use the new hasVoxelsAt and getVoxelsAt methods instead of directly accessing voxelsSpatial - if (vmaxModel.hasVoxelsAt(x, y, z)) { - const std::vector& voxels = vmaxModel.getVoxelsAt(x, y, z); - if (!voxels.empty()) { - uint8_t palette_index = voxels[0].palette; - if (palette_index == 0) palette_index = 1; // If palette is 0, use 1 instead to make it visible - voxel_data[index] = palette_index; - voxel_count_populated++; - } - } - // If no voxels at this position, it remains 0 (empty) - } - catch (const std::exception& e) { - std::cout << "ERROR: Exception accessing voxels at [" << x << "][" << y << "][" << z - << "]: " << e.what() << std::endl; - ogt_vox_free(voxel_data); - return nullptr; - } - } - } - } - } - - // Create and initialize the ogt_vox_model - ogt_vox_model* model = (ogt_vox_model*)ogt_vox_malloc(sizeof(ogt_vox_model)); - if (!model) { - std::cout << "Error: Failed to allocate memory for ogt_vox_model" << std::endl; - ogt_vox_free(voxel_data); - return nullptr; - } - - model->size_x = size_x; - model->size_y = size_y; - model->size_z = size_z; - model->voxel_data = voxel_data; - - // Calculate a simple hash for the voxel data - uint32_t hash = 0; - for (size_t i = 0; i < voxel_count; i++) { - hash = hash * 65599 + voxel_data[i]; - } - model->voxel_hash = hash; - - return model; -} -*/ - - -// Convert a vector of VmaxVoxel to an ogt_vox_model -// Note: The returned ogt_vox_model must be freed using ogt_vox_free when no longer needed -ogt_vox_model* convert_voxelsoftype_to_ogt_vox(const std::vector& voxelsOfType) { - // Find the maximum dimensions from the voxels - uint32_t size_x = 0; - uint32_t size_y = 0; - uint32_t size_z = 0; - - // WARNING must add 1 to each dimension - // because voxel coordinates are 0-based - for (const auto& voxel : voxelsOfType) { - size_x = std::max(size_x, static_cast(voxel.x)+1); // this seems wasteful - size_y = std::max(size_y, static_cast(voxel.y)+1); - size_z = std::max(size_z, static_cast(voxel.z)+1); - } - - // Add some safety checks - // This is a dense voxel model, so we need to make sure it's not too large - // todo use a sparse storage like morton - if (size_x > 256 || size_y > 256 || size_z > 256) { - std::cout << "Warning: Model dimensions exceed 256 limit. Clamping to 256." << std::endl; - size_x = std::min(size_x, 256u); - size_y = std::min(size_y, 256u); - size_z = std::min(size_z, 256u); - } - if (size_x == 0 || size_y == 0 || size_z == 0) { - std::cout << "Error: Model has zero dimensions. Setting minimum size of 1x1x1." << std::endl; - size_x = std::max(size_x, 1u); - size_y = std::max(size_y, 1u); - size_z = std::max(size_z, 1u); - } - - // Create the voxel data array (initialized to 0, which means empty in ogt_vox) - size_t voxel_count = size_x * size_y * size_z; - uint8_t* voxel_data = (uint8_t*)ogt_vox_malloc(voxel_count); - if (!voxel_data) { - std::cout << "Error: Failed to allocate memory for voxel data" << std::endl; - return nullptr; - } - memset(voxel_data, 0, voxel_count); // Initialize all to 0 (empty) - - // Fill the voxel data array with color indices - int voxel_count_populated = 0; - - // Loop through the vector of voxels directly - for (const auto& voxel : voxelsOfType) { - // Get the coordinates and palette - uint32_t x = voxel.x; - uint32_t y = voxel.y; - uint32_t z = voxel.z; - - // Skip voxels outside our valid range - if (x >= size_x || y >= size_y || z >= size_z) - continue; - - // Calculate the index in the 1D array - size_t index = x + (y * size_x) + (z * size_x * size_y); - - if (index < voxel_count) { - uint8_t palette_index = 0; // hardcoded for now - if (palette_index == 0) palette_index = 1; // If palette is 0, use 1 instead to make it visible - voxel_data[index] = palette_index; - voxel_count_populated++; - } - } - - // Create the model - ogt_vox_model* model = (ogt_vox_model*)ogt_vox_malloc(sizeof(ogt_vox_model)); - if (!model) { - std::cout << "Error: Failed to allocate memory for model" << std::endl; - ogt_vox_free(voxel_data); - return nullptr; - } - - model->size_x = size_x; - model->size_y = size_y; - model->size_z = size_z; - model->voxel_data = voxel_data; - - // Calculate a simple hash for the voxel data - uint32_t hash = 0; - for (size_t i = 0; i < voxel_count; i++) { - hash = hash * 65599 + voxel_data[i]; - } - model->voxel_hash = hash; - - return model; -} - -// Free resources allocated for an ogt_vox_model created by convert_vmax_to_ogt_vox -void free_ogt_vox_model(ogt_vox_model* model) { - if (model) { - if (model->voxel_data) { - ogt_vox_free((void*)model->voxel_data); - } - ogt_vox_free(model); - } -} - -// Free resources allocated for an ogt_vox_scene created by create_ogt_vox_scene_from_vmax -/*void free_ogt_vox_scene(ogt_vox_scene* scene) { - if (scene) { - // Free each model - for (uint32_t i = 0; i < scene->num_models; i++) { - free_ogt_vox_model((ogt_vox_model*)scene->models[i]); - } - - // Free pointers - if (scene->models) ogt_vox_free((void*)scene->models); - if (scene->instances) ogt_vox_free((void*)scene->instances); - if (scene->layers) ogt_vox_free((void*)scene->layers); - - // Free the scene itself - ogt_vox_free(scene); - } -} -*/ - -// Custom allocator functions for ogt_voxel_meshify -static void* voxel_meshify_malloc(size_t size, void* user_data) { - return malloc(size); -} - -static void voxel_meshify_free(void* ptr, void* user_data) { - free(ptr); -} diff --git a/oomer_voxel_vmax.h b/oomer_voxel_vmax.h deleted file mode 100644 index 80f8d64..0000000 --- a/oomer_voxel_vmax.h +++ /dev/null @@ -1,967 +0,0 @@ -#pragma once - -// This is a set of common oomer utilities for Vmax models -// Will avoid using bella_sdk - - -// Standard C++ library includes - these provide essential functionality -#include // For key-value pair data structures (maps) -#include // For set data structure -#include // For dynamic arrays (vectors) -#include // For std::string -#include // For fixed-size integer types (uint8_t, uint32_t, etc.) -#include // For file operations (reading/writing files) -#include // For input/output operations (cout, cin, etc.) -#include // For file system operations (directory handling, path manipulation) - -#include "../lzfse/src/lzfse.h" -#include "../libplist/include/plist/plist.h" // Library for handling Apple property list files -#include "thirdparty/json.hpp" - -using json = nlohmann::json; - -// Define STB_IMAGE_IMPLEMENTATION before including to create the implementation -#define STB_IMAGE_IMPLEMENTATION -#include "thirdparty/stb_image.h" // STB Image library - - - - - -// Structure to represent a 4x4 matrix for 3D transformations -// The matrix is stored as a 2D array where m[i][j] represents row i, column j -struct VmaxMatrix4x4 { - double m[4][4]; - // Constructor: Creates an identity matrix (1's on diagonal, 0's elsewhere) - VmaxMatrix4x4() { - for(int i = 0; i < 4; i++) { - for(int j = 0; j < 4; j++) { - m[i][j] = (i == j) ? 1.0 : 0.0; // 1.0 on diagonal, 0.0 elsewhere - } - } - } - - // Matrix multiplication operator to combine transformations - // Returns: A new matrix that represents the combined transformation - VmaxMatrix4x4 operator*(const VmaxMatrix4x4& other) const { - VmaxMatrix4x4 result; - // Perform matrix multiplication - for(int i = 0; i < 4; i++) { - for(int j = 0; j < 4; j++) { - result.m[i][j] = 0.0; - for(int k = 0; k < 4; k++) { - result.m[i][j] += m[i][k] * other.m[k][j]; - } - } - } - - return result; - } - - // Helper function to create a translation matrix - static VmaxMatrix4x4 createTranslation(double x, double y, double z) { - VmaxMatrix4x4 result; - result.m[3][0] = x; // Translation in X (bottom row) - result.m[3][1] = y; // Translation in Y (bottom row) - result.m[3][2] = z; // Translation in Z (bottom row) - return result; - } - - // Helper function to create a scale matrix - static VmaxMatrix4x4 createScale(double x, double y, double z) { - VmaxMatrix4x4 result; - result.m[0][0] = x; // Scale in X - result.m[1][1] = y; // Scale in Y - result.m[2][2] = z; // Scale in Z - return result; - } -}; - -// Converts axis-angle rotation to a 4x4 rotation matrix -// Parameters: -// ax, ay, az: The axis vector to rotate around (doesn't need to be normalized) -// angle: The angle to rotate by (in radians) -// Returns: A 4x4 rotation matrix that can be used to transform vectors -VmaxMatrix4x4 axisAngleToMatrix4x4(double ax, double ay, double az, double angle) { - // Step 1: Normalize the axis vector to make it a unit vector - // This is required for the rotation formula to work correctly - double length = sqrt(ax*ax + ay*ay + az*az); - if (length != 0) { - ax /= length; - ay /= length; - az /= length; - } - - // Step 2: Calculate trigonometric values needed for the rotation - double s = sin(angle); // sine of angle - double c = cos(angle); // cosine of angle - double t = 1.0 - c; // 1 - cos(angle), used in formula - - // Step 3: Create rotation matrix using Rodrigues' rotation formula - // This formula converts an axis-angle rotation into a 3x3 matrix - // We'll embed it in the upper-left corner of our 4x4 matrix - VmaxMatrix4x4 result; - - // First row of rotation matrix (upper-left 3x3 portion) - result.m[0][0] = t*ax*ax + c; // First column - result.m[0][1] = t*ax*ay + s*az; // Second column (changed sign) - result.m[0][2] = t*ax*az - s*ay; // Third column (changed sign) - - // Second row of rotation matrix - result.m[1][0] = t*ax*ay - s*az; // First column (changed sign) - result.m[1][1] = t*ay*ay + c; // Second column - result.m[1][2] = t*ay*az + s*ax; // Third column (changed sign) - - // Third row of rotation matrix - result.m[2][0] = t*ax*az + s*ay; // First column (changed sign) - result.m[2][1] = t*ay*az - s*ax; // Second column (changed sign) - result.m[2][2] = t*az*az + c; // Third column - - // Fourth row and column remain unchanged (0,0,0,1) - // This is already set by the constructor - - return result; -} - -// Combine a rotation, translation, and scale into a single 4x4 matrix -// Parameters: -// rotx, roty, rotz: The axis vector to rotate around (doesn't need to be normalized) -// rota: The angle to rotate by (in radians) -// posx, posy, posz: The position to translate to -// scalex, scaley, scalez: The scale to apply to the object -// Returns: A 4x4 matrix that represents the combined transformation -VmaxMatrix4x4 combineVmaxTransforms(double rotx, double roty, double rotz, double rota, double posx, double posy, double posz, double scalex, double scaley, double scalez) { - VmaxMatrix4x4 rotMat4 = axisAngleToMatrix4x4(rotx, - roty, - rotz, - rota); - VmaxMatrix4x4 transMat4 = VmaxMatrix4x4(); - transMat4 = transMat4.createTranslation(posx, - posy, - posz); - VmaxMatrix4x4 scaleMat4 = VmaxMatrix4x4(); - scaleMat4 = scaleMat4.createScale(scalex, - scaley, - scalez); - VmaxMatrix4x4 resultMat4 = scaleMat4 * rotMat4 * transMat4; - return resultMat4; -} - - -struct VmaxRGBA { - uint8_t r, g, b, a; -}; - -// Read a 256x1 PNG file and return a vector of VmaxRGBA colors -std::vector read256x1PaletteFromPNG(const std::string& filename) { - int width, height, channels; - // Load the image with 4 desired channels (RGBA) - unsigned char* data = stbi_load(filename.c_str(), &width, &height, &channels, 4); - - if (!data) { - std::cerr << "Error loading PNG file: " << filename << std::endl; - return {}; - } - // Make sure the image is 256x1 as expected - if (width != 256 || height != 1) { - std::cerr << "Warning: Expected a 256x1 image, but got " << width << "x" << height << std::endl; - } - // Create our palette array - std::vector palette; - // Read each pixel (each pixel is 4 bytes - RGBA) - for (int i = 0; i < width; i++) { - VmaxRGBA color; - color.r = data[i * 4]; - color.g = data[i * 4 + 1]; - color.b = data[i * 4 + 2]; - color.a = data[i * 4 + 3]; - palette.push_back(color); - } - stbi_image_free(data); // Free the image data - return palette; -} - -// Standard useful voxel structure, maps easily to VoxelMax's voxel structure and probably MagicaVoxel's -// We are using this to unpack a chunked voxel into a simple giant voxel -// using a uint8_t saves memory over a uint32_t and both VM and MV models are 256x256x256 -// The world itself can be larger, see scene.json -// Helper struct because in VmaxModel we use array of arrays to store material and color -// Allowing us to group voxels by material and color -struct VmaxVoxel { - uint8_t x, y, z; - uint8_t material; // material value 0-7 - uint8_t palette; // Color palette mapping index 0-255, search palette1.png - uint16_t chunkID; // Chunk ID 0-511 8x8x8 is a morton code - uint16_t minMorton; // morton encoded offset from chunk origin 0-32767 32x32x32, decoded value is added to voxel x y z - // Constructor - VmaxVoxel( uint8_t _x, - uint8_t _y, - uint8_t _z, - uint8_t _material, - uint8_t _palette, - uint16_t _chunkID, - uint16_t _minMorton) - : x(_x), y(_y), z(_z), material(_material), palette(_palette), chunkID(_chunkID), minMorton(_minMorton) { - } -}; - -inline uint32_t compactBits(uint32_t n) { - // For a 32-bit integer in C++ - n &= 0x49249249; // Keep only every 3rd bit - n = (n ^ (n >> 2)) & 0xc30c30c3; // Merge groups - n = (n ^ (n >> 4)) & 0x0f00f00f; // Continue merging - n = (n ^ (n >> 8)) & 0x00ff00ff; // Merge larger groups - n = (n ^ (n >> 16)) & 0x0000ffff; // Final merge - return n; -} - -// Optimized function to decode Morton code using parallel bit manipulation -inline void decodeMorton3DOptimized(uint32_t morton, uint32_t& x, uint32_t& y, uint32_t& z) { - x = compactBits(morton); - y = compactBits(morton >> 1); - z = compactBits(morton >> 2); -} - -struct VmaxMaterial { - std::string materialName; - double transmission; - double roughness; - double metalness; - double emission; - bool enableShadows; - bool dielectric; // future use - bool volumetric; // future use -}; - -struct VmaxVoxelGrid { - // dimensions of the voxel grid - uint32_t size_x, size_y, size_z; - // voxel data - uint8_t* voxel_data; -}; - - -// Create a structure to represent a model with its voxels with helper functions -// since the xyz coords are at the voxel level, we need an accessor to walk it sequentially -// maybe I create a new structure called VmaxVoxelGrid -struct VmaxModel { - // Model identifier or name - std::string vmaxbFileName; // file name is used like a key - - // Voxels organized by material and color - // First dimension: material (0-7) - // Second dimension: color (1-255, index 0 unused since color 0 means no voxel) - std::vector voxels[8][256]; - - // EDUCATIONAL NOTES ON DUAL DATA STRUCTURES FOR VOXELS: - // ---------------------------------------------------- - // This class uses two different data structures to store the same voxel data, - // each optimized for different access patterns: - // - // 1. voxels[8][256] - Organizes voxels by material and color - // - Efficient for queries like "give me all voxels of material 2, color 37" - // - Poor for spatial queries like "what's at position (x,y,z)?" - // - // 2. voxelsSpatial - Organizes voxels by their spatial position - // - Efficient for spatial queries like "what's at position (x,y,z)?" - // - Uses a map for memory efficiency with sparse data - // - // Tradeoffs: - // - Memory: We use more memory by storing voxels twice - // - Performance: We get optimal performance for both types of queries - // - Complexity: We need to maintain both structures in sync - // - // For novice programmers: This is a common technique in game/graphics programming - // where performance is critical. We're trading some extra memory for faster access. - - // Using a map for sparse 3D data instead of a fixed-size 3D array - // Key format: (x << 16) | (y << 8) | z - // This approach is memory-efficient for sparse data (mostly empty space) - // A 3D array would need 256³ = 16.7 million elements even if most are empty! - - - // todo we need to do morton decoing using chunkid to get x,y,z - std::map> voxelsSpatial; - - // Each model has local 0-7 materials - std::array materials; - // Each model has local colors - std::array colors; - uint8_t maxx=0, maxy=0, maxz=0; - - // Constructor - VmaxModel(const std::string& modelName) : vmaxbFileName(modelName) { - } - - // Helper function to create a key for the voxelsSpatial map - static uint32_t makeVoxelKey(uint8_t x, uint8_t y, uint8_t z) { - return (static_cast(x) << 16) | (static_cast(y) << 8) | static_cast(z); - } - - // Add a voxel to this model - // EDUCATIONAL NOTE: - // Notice how we maintain BOTH data structures when adding a voxel. - // This is a key practice when using dual data structures - keep them in sync - // by updating both whenever data changes. - void addVoxel(int x, int y, int z, int material, int color, int chunk, int chunkMin) { - - //todo add chunk offset to x,y,z - //chunkMin is offset withing each chunk used earlier - uint32_t _tempx, _tempy, _tempz; - decodeMorton3DOptimized(chunk, _tempx, _tempy, _tempz); // index IS the morton code - int worldOffsetX = _tempx * 24; // get world loc within 256x256x256 grid - int worldOffsetY = _tempy * 24; // Don't know why we need to multiply by 24 - int worldOffsetZ = _tempz * 24; // use to be 32 - x += worldOffsetX; - y += worldOffsetY; - z += worldOffsetZ; - - - if (material >= 0 && material < 8 && color > 0 && color < 256) { - voxels[material][color].emplace_back(x, y, z, material, color, chunk, chunkMin); - - // Add to voxelsSpatial using the map approach - uint32_t key = makeVoxelKey(x, y, z); - //todo add chunk offset to x,y,z - voxelsSpatial[key].emplace_back(x, y, z, material, color, chunk, chunkMin); - - if (x > maxx) maxx = x; - if (y > maxy) maxy = y; - if (z > maxz) maxz = z; - } - } - - // Get voxels at a specific position - // EDUCATIONAL NOTE: - // This method demonstrates the power of our spatial index. - // Time complexity: O(log n) where n is the number of occupied positions. - // Without voxelsSpatial, we would need to scan through ALL voxels (potentially thousands) - // to find those at a specific position, which would be O(total_voxel_count). - const std::vector& getVoxelsAt(uint8_t x, uint8_t y, uint8_t z) const { - uint32_t key = makeVoxelKey(x, y, z); - auto it = voxelsSpatial.find(key); - if (it != voxelsSpatial.end()) { - return it->second; - } - static const std::vector empty; - return empty; - } - - // Check if there are voxels at a specific position - // Another spatial query that benefits from our map-based structure - bool hasVoxelsAt(uint8_t x, uint8_t y, uint8_t z) const { - uint32_t key = makeVoxelKey(x, y, z); - auto it = voxelsSpatial.find(key); - return (it != voxelsSpatial.end() && !it->second.empty()); - } - - // Add materials to this model - void addMaterials(const std::array newMaterials) { - materials = newMaterials; - } - - // Add colors to this model - void addColors(const std::array newColors) { - colors = newColors; - } - - // Get all voxels of a specific material and color - const std::vector& getVoxels(int material, int color) const { - if (material >= 0 && material < 8 && color > 0 && color < 256) { - return voxels[material][color]; - } - static std::vector empty; - return empty; - } - - // Get total voxel count for this model - size_t getTotalVoxelCount() const { - size_t count = 0; - for (int m = 0; m < 8; m++) { - for (int c = 1; c < 256; c++) { // Skip index 0 - count += voxels[m][c].size(); - } - } - return count; - } - - // Get a map of used materials and their associated colors - std::map> getUsedMaterialsAndColors() const { - std::map> result; - - // Iterate through fixed size arrays - we know it's 8 materials and 256 colors - for (int material = 0; material < 8; material++) { - for (int color = 1; color < 256; color++) { // Skip index 0 as it means no voxel - if (!voxels[material][color].empty()) { - result[material].insert(color); - } - } - } - - return result; - } -}; - -inline std::array getVmaxMaterials(plist_t pnodPalettePlist) { - // Directly access the materials array - std::array vmaxMaterials; - plist_t materialsNode = plist_dict_get_item(pnodPalettePlist, "materials"); - if (materialsNode && plist_get_node_type(materialsNode) == PLIST_ARRAY) { - uint32_t materialsCount = plist_array_get_size(materialsNode); - //std::cout << "Found materials array with " << materialsCount << " items" << std::endl; - - // Process each material - for (uint32_t i = 0; i < materialsCount; i++) { - plist_t materialNode = plist_array_get_item(materialsNode, i); - if (materialNode && plist_get_node_type(materialNode) == PLIST_DICT) { - plist_t nameNode = plist_dict_get_item(materialNode, "mi"); - std::string vmaxMaterialName; - double vmaxTransmission = 0.0; // Declare outside the if block - double vmaxEmission = 0.0; // Declare outside the if block - double vmaxRoughness = 0.0; // Declare outside the if block - double vmaxMetalness = 0.0; // Declare outside the if block - uint8_t vmaxEnableShadows = 1; - - if (nameNode) { - char* rawName = nullptr; - plist_get_string_val(nameNode, &rawName); - vmaxMaterialName = rawName ? rawName : "unnamed"; - free(rawName); - } - plist_t pnodTc = plist_dict_get_item(materialNode, "tc"); - if (pnodTc) { plist_get_real_val(pnodTc, &vmaxTransmission); } - plist_t pnodEmission = plist_dict_get_item(materialNode, "sic"); - if (pnodEmission) { plist_get_real_val(pnodEmission, &vmaxEmission); } - plist_t pnodRoughness = plist_dict_get_item(materialNode, "rc"); - if (pnodRoughness) { plist_get_real_val(pnodRoughness, &vmaxRoughness); } - plist_t pnodMetalness = plist_dict_get_item(materialNode, "mc"); - if (pnodMetalness) { plist_get_real_val(pnodMetalness, &vmaxMetalness); } - plist_t pnodEnableShadow = plist_dict_get_item(materialNode, "sh"); - if (pnodEnableShadow) { plist_get_bool_val(pnodEnableShadow, &vmaxEnableShadows); } - - vmaxMaterials[i] = { - vmaxMaterialName, - vmaxTransmission, - vmaxRoughness, - vmaxMetalness, - vmaxEmission, - static_cast(vmaxEnableShadows), - false, // dielectric - false, // volumetric - }; - } - } - } else { - std::cout << "No materials array found or invalid type" << std::endl; - } - #ifdef _DEBUG23 - for (const auto& material : vmaxMaterials) { - std::cout << "Material: " << material.materialName << std::endl; - std::cout << " Transmission: " << material.transmission << std::endl; - std::cout << " Emission: " << material.emission << std::endl; - std::cout << " Roughness: " << material.roughness << std::endl; - std::cout << " Metalness: " << material.metalness << std::endl; - std::cout << " Enable Shadows: " << material.enableShadows << std::endl; - std::cout << " Dielectric: " << material.dielectric << std::endl; - std::cout << " Volumetric: " << material.volumetric << std::endl; - } - #endif - return vmaxMaterials; -} - - -/** - * Decodes a voxel's material index and palette index from the ds data stream - * - * @param dsData The raw ds data stream containing material and palette index pairs - * @param mortonOffset offset to apply to the morton code - * @param chunkID chunk ID - * @return vector of VmaxVoxel structures containing the voxels local to a snapshot - */ -inline std::vector decodeVoxels(const std::vector& dsData, int mortonOffset, uint16_t chunkID) { - std::vector voxels; - uint8_t material; - uint8_t color; - for (int i = 0; i < dsData.size() - 1; i += 2) { - material = dsData[i]; // also known as a layer color - color = dsData[i + 1]; - uint32_t _tempx, _tempy, _tempz; - decodeMorton3DOptimized(i/2 + mortonOffset, - _tempx, - _tempy, - _tempz); // index IS the morton code - if (color != 0) { - VmaxVoxel voxel = { - static_cast(_tempx), - static_cast(_tempy), - static_cast(_tempz), - material, - color, - chunkID, // todo is wasteful to pass chunkID? - static_cast(mortonOffset) - }; - voxels.push_back(voxel); - } - } - return voxels; -} - -//libplist reads in 64 bits -struct VmaxChunkInfo { - int64_t id; // was uint but will use -1 to indicate bad chunk - uint64_t type; - uint64_t mortoncode; - uint32_t voxelOffsetX; - uint32_t voxelOffsetY; - uint32_t voxelOffsetZ; -}; - -// Helper function to get a nested dictionary item -// @param root: root dictionary -// @param path: path to the item -// @return: item -// Using a vector of strings for dynamic path length -plist_t getNestedPlistNode(plist_t plist_root, const std::vector& path) { - plist_t current = plist_root; - for (const auto& key : path) { - if (!current) return nullptr; - current = plist_dict_get_item(current, key.c_str()); - } - return current; -} - -// Need morton code in snapshot before we can decode voxels -// @param an individual chunk: plist_t of a snapshot dict->item->s -// @return Chunk level info needed to decode voxels -VmaxChunkInfo vmaxChunkInfo(const plist_t& plist_snapshot_dict_item) { - uint64_t id; - uint64_t type; - uint64_t mortoncode; - uint32_t voxelOffsetX, voxelOffsetY, voxelOffsetZ; - try { - plist_t plist_snapshot = getNestedPlistNode(plist_snapshot_dict_item, {"s"}); - - // vmax file format must guarantee the existence - // s.st.min - // s.id.t - // s.id.c - plist_t plist_min = getNestedPlistNode(plist_snapshot, {"st", "min"}); - plist_t plist_min_val = plist_array_get_item(plist_min, 3); - plist_get_uint_val(plist_min_val, &mortoncode); - - // convert to 32x32x32 chunk offset - decodeMorton3DOptimized(mortoncode, - voxelOffsetX, - voxelOffsetY, - voxelOffsetZ); - - plist_t plist_type = getNestedPlistNode(plist_snapshot, {"id","t"}); - plist_get_uint_val(plist_type, &type); - plist_t plist_chunk = getNestedPlistNode(plist_snapshot, {"id","c"}); - plist_get_uint_val(plist_chunk, &id); - - return VmaxChunkInfo{static_cast(id), - type, - mortoncode, - voxelOffsetX, - voxelOffsetY, - voxelOffsetZ}; - } catch (std::exception& e) { - std::cout << "Error: " << e.what() << std::endl; - // Just continue to next snapshot - // This bypass might mean we miss useful snapshots - } - return VmaxChunkInfo{-1, 0, 0, 0, 0, 0}; -} - - -// Right after we get VmaxChunkInfo, we can get the voxels because we need morton chunk offset -// @param pnodSnaphot: plist_t of a snapshot -// @return vector of VmaxVoxel -//std::vector getVmaxSnapshot(plist_t& pnod_each_snapshot) { -std::vector vmaxVoxelInfo(plist_t& plist_datastream, uint64_t chunkID, uint64_t minMorton) { - std::vector voxelsArray; - try { - - // Extract the binary data - char* data = nullptr; - uint64_t length = 0; - plist_get_data_val(plist_datastream, &data, &length); - auto foo = std::vector(data, data + length) ; - std::vector allModelVoxels = decodeVoxels(std::vector(data, data + length), minMorton, chunkID); - - //std::cout << "allModelVoxels: " << allModelVoxels.size() << std::endl; - - uint32_t model_8x8x8_x, model_8x8x8_y, model_8x8x8_z; - decodeMorton3DOptimized(chunkID, - model_8x8x8_x, - model_8x8x8_y, - model_8x8x8_z); // index IS the morton code - int model_256x256x256_x = model_8x8x8_x * 8; // convert to model space - int model_256x256x256_y = model_8x8x8_y * 8; - int model_256x256x256_z = model_8x8x8_z * 8; - - for (const VmaxVoxel& eachVmaxVoxel : allModelVoxels) { - auto [ chunk_32x32x32_x, - chunk_32x32x32_y, - chunk_32x32x32_z, - materialMap, - colorMap, - chunkID, - minMorton] = eachVmaxVoxel; - - int voxel_256x256x256_x = model_256x256x256_x + chunk_32x32x32_x; - int voxel_256x256x256_y = model_256x256x256_y + chunk_32x32x32_y; - int voxel_256x256x256_z = model_256x256x256_z + chunk_32x32x32_z; - - auto one_voxel = VmaxVoxel(voxel_256x256x256_x, - voxel_256x256x256_y, - voxel_256x256x256_z, - materialMap, - colorMap, - chunkID, - minMorton); - voxelsArray.push_back(one_voxel); - } - return voxelsArray; - } catch (std::exception& e) { - std::cout << "Error: " << e.what() << std::endl; - // Just continue to next snapshot - // This bypass might mean we miss useful snapshots - } - return voxelsArray; // empty return -} - -/** - * Read a binary plist file and return a plist node. - * if the file is lzfse compressed, decompress it and parse the decompressed data - * - * Memory Management: - * - Creates temporary buffers for decompression - * - Handles buffer resizing if needed - * - Returns a plist node that must be freed by the caller - * - * @param lzfseFullName Path to the LZFSE file - * @param plistName Name of the plist file to write (optional) - * @return plist_t A pointer to the root node of the parsed plist, or nullptr if failed - */ -// read binary lzfse compressed/uncompressed file -inline plist_t readPlist(const std::string& inStrPlist, std::string outStrPlist, bool decompress) { - // Get file size using std::filesystem - size_t rawFileSize = std::filesystem::file_size(inStrPlist); - std::vector rawBytes(rawFileSize); - std::vector outBuffer; - size_t decodedSize = 0; - if (decompress) { // files are either lzfse compressed or uncompressed - std::ifstream rawBytesFile(inStrPlist, std::ios::binary); - if (!rawBytesFile.is_open()) { - std::cerr << "Error: Could not open plist file: " << inStrPlist << std::endl; - throw std::runtime_error("Error message"); // [learned] no need to return nullptr - } - - rawBytesFile.read(reinterpret_cast(rawBytes.data()), rawFileSize); - rawBytesFile.close(); - // Start with output buffer 4x input size (compression ratio is usually < 4) - size_t outAllocatedSize = rawFileSize * 8; - // vector automatically manages memory allocation/deallocation - //std::vector outBuffer(outAllocatedSize); - outBuffer.resize(outAllocatedSize); // Resize preserves existing content - - // LZFSE needs a scratch buffer for its internal operations - // Get the required size and allocate it - size_t scratchSize = lzfse_decode_scratch_size(); - std::vector scratch(scratchSize); - - // Decompress the data, growing the output buffer if needed - //size_t decodedSize = 0; - while (true) { - // Try to decompress with current buffer size - decodedSize = lzfse_decode_buffer( - outBuffer.data(), // Where to store decompressed data - outAllocatedSize, // Size of output buffer - rawBytes.data(), // Source of compressed data - rawBytes.size(), // Size of compressed data - scratch.data()); // Scratch space for LZFSE - - // Check if we need a larger buffer: - // - decodedSize == 0 indicates failure - // - decodedSize == outAllocatedSize might mean buffer was too small - if (decodedSize == 0 || decodedSize == outAllocatedSize) { - outAllocatedSize *= 2; // Double the buffer size - outBuffer.resize(outAllocatedSize); // Resize preserves existing content - continue; // Try again with larger buffer - } - break; // Successfully decompressed - } - - // Check if decompression failed - if (decodedSize == 0) { - std::cerr << "Failed to decompress data" << std::endl; - return nullptr; - } - - // If requested, write the decompressed data to a file - if (!outStrPlist.empty()) { - std::ofstream outFile(outStrPlist, std::ios::binary); - if (outFile) { - outFile.write(reinterpret_cast(outBuffer.data()), decodedSize); - std::cout << "Wrote decompressed plist to: " << outStrPlist << std::endl; - } else { - std::cerr << "Failed to write plist to file: " << outStrPlist << std::endl; - } - } - } else { - outBuffer.resize(rawFileSize); - // if the file is not compressed, just read the raw bytes - std::ifstream rawBytesFile(inStrPlist, std::ios::binary); - if (!rawBytesFile.is_open()) { - std::cerr << "Error: Could not open plist file: " << inStrPlist << std::endl; - throw std::runtime_error("Error message"); // [learned] no need to return nullptr - } - rawBytesFile.read(reinterpret_cast(outBuffer.data()), rawFileSize); - rawBytesFile.close(); - decodedSize = rawFileSize; // decodedSize is the same as rawFileSize when data is not compressed - - - } // outBuffer now contains the raw bytes of the plist file - - // Parse the decompressed data as a plist - plist_t root_node = nullptr; - plist_format_t format; // Will store the format of the plist (binary, xml, etc.) - - // Convert the raw decompressed data into a plist structure - plist_err_t err = plist_from_memory( - reinterpret_cast(outBuffer.data()), // Cast uint8_t* to char* - static_cast(decodedSize), // Cast size_t to uint32_t - &root_node, // Where to store the parsed plist - &format); // Where to store the format - - // Check if parsing succeeded - if (err != PLIST_ERR_SUCCESS) { - std::cerr << "Failed to parse plist data" << std::endl; - return nullptr; - } - - return root_node; // Caller is responsible for calling plist_free() -} - -// Overload for when you only want to specify inStrPlist and decompress -inline plist_t readPlist(const std::string& inStrPlist, bool decompress) { - return readPlist(inStrPlist, "", decompress); -} - -// Structure to hold object/model information from VoxelMax's scene.json -struct JsonModelInfo { - std::string id; - std::string parentId; - std::string name; - std::string dataFile; // The .vmaxb file - std::string paletteFile; // The palette PNG - std::string historyFile; // The history file, not sure what this is - - // Transform information - std::vector position; // t_p - std::vector rotation; // t_r - std::vector scale; // t_s - - // Extent information - std::vector extentCenter; // e_c - std::vector extentMin; // e_mi - std::vector extentMax; // e_ma -}; - -// Structure to hold group information from VoxelMax's scene.json -struct JsonGroupInfo { - std::string id; - std::string name; - std::vector position; - std::vector rotation; - std::vector scale; - std::vector extentCenter; - std::vector extentMin; - std::vector extentMax; - bool selected = false; - std::string parentId; -}; - -// Class to parse VoxelMax's scene.json -class JsonVmaxSceneParser { -private: - std::map models; // a vmax model can also be called a content - std::map groups; - -public: - bool parseScene(const std::string& jsonFilePath) { - try { - // Read the JSON file - std::ifstream file(jsonFilePath); - if (!file.is_open()) { - std::cerr << "Failed to open file: " << jsonFilePath << std::endl; - return false; - } - - // Parse the JSON - json sceneData; - file >> sceneData; - file.close(); - - // Parse groups - if (sceneData.contains("groups") && sceneData["groups"].is_array()) { - for (const auto& group : sceneData["groups"]) { - JsonGroupInfo groupInfo; - - // Extract group information - if (group.contains("id")) groupInfo.id = group["id"]; - if (group.contains("name")) groupInfo.name = group["name"]; - - // Extract transform data - if (group.contains("t_p") && group["t_p"].is_array()) - groupInfo.position = group["t_p"].get>(); - - if (group.contains("t_r") && group["t_r"].is_array()) - groupInfo.rotation = group["t_r"].get>(); - - if (group.contains("t_s") && group["t_s"].is_array()) - groupInfo.scale = group["t_s"].get>(); - - // Extract extent data - if (group.contains("e_c") && group["e_c"].is_array()) - groupInfo.extentCenter = group["e_c"].get>(); - - if (group.contains("e_mi") && group["e_mi"].is_array()) - groupInfo.extentMin = group["e_mi"].get>(); - - if (group.contains("e_ma") && group["e_ma"].is_array()) - groupInfo.extentMax = group["e_ma"].get>(); - - // Check if selected - if (group.contains("s")) groupInfo.selected = group["s"].get(); - - if (group.contains("pid")) groupInfo.parentId = group["pid"]; - // Store the group - groups[groupInfo.id] = groupInfo; - } - } - - // Parse objects (models) , objects are instances of models - // Maybe rename this objects, will leave for now - if (sceneData.contains("objects") && sceneData["objects"].is_array()) { - for (const auto& obj : sceneData["objects"]) { - JsonModelInfo modelInfo; - - // Extract model information - if (obj.contains("id")) modelInfo.id = obj["id"]; - if (obj.contains("pid")) modelInfo.parentId = obj["pid"]; - if (obj.contains("n")) modelInfo.name = obj["n"]; - - // Extract file paths - if (obj.contains("data")) modelInfo.dataFile = obj["data"];// This is the canonical model - if (obj.contains("pal")) modelInfo.paletteFile = obj["pal"]; - if (obj.contains("hist")) modelInfo.historyFile = obj["hist"]; - - // Extract transform data - if (obj.contains("t_p") && obj["t_p"].is_array()) - modelInfo.position = obj["t_p"].get>(); - - if (obj.contains("t_r") && obj["t_r"].is_array()) - modelInfo.rotation = obj["t_r"].get>(); - - if (obj.contains("t_s") && obj["t_s"].is_array()) - modelInfo.scale = obj["t_s"].get>(); - - // Extract extent data - if (obj.contains("e_c") && obj["e_c"].is_array()) - modelInfo.extentCenter = obj["e_c"].get>(); - - if (obj.contains("e_mi") && obj["e_mi"].is_array()) - modelInfo.extentMin = obj["e_mi"].get>(); - - if (obj.contains("e_ma") && obj["e_ma"].is_array()) - modelInfo.extentMax = obj["e_ma"].get>(); - - // Store the model - models[modelInfo.id] = modelInfo; - } - } - - return true; - - } catch (const std::exception& e) { - std::cerr << "Error parsing JSON: " << e.what() << std::endl; - return false; - } - } - - // Get the parsed models - const std::map& getModels() const { - return models; - } - - // Get the parsed groups - const std::map& getGroups() const { - return groups; - } - - /* Groups models by their data file names ie contentsN.vmaxb - * Since we can instance models, we can grab the first one when translating it to Bella - * @return Map where: - * - Key: contentN.vmaxb (string) - * - Value: vector of models using that data file - * Example: - * Input models: {"id1": model1, "id2": model2} where both use "data.file" - * Output: {"data.file": [model1, model2]} - */ - std::map> getModelContentVMaxbMap() const { - std::map> fileMap; - - for (const auto& [id, model] : models) { - fileMap[model.dataFile].push_back(model); - } - - return fileMap; - } - - // Print summary of parsed data - void printSummary() const { - std::cout << "=========== Scene Summary ===========" << std::endl; - std::cout << "Groups: " << groups.size() << std::endl; - std::cout << "Models: " << models.size() << std::endl; - - // Print unique model files - std::map modelFiles; - for (const auto& [id, model] : models) { - modelFiles[model.dataFile]++; - } - - std::cout << "\nModel Files:" << std::endl; - for (const auto& [file, count] : modelFiles) { - std::cout << " " << file << " (used " << count << " times)" << std::endl; - } - - std::cout << "\nGroups:" << std::endl; - for (const auto& [id, group] : groups) { - std::cout << " " << group.name << " (ID: " << id << ")" << std::endl; - if (!group.position.empty()) { - std::cout << " Position: [" - << group.position[0] << ", " - << group.position[1] << ", " - << group.position[2] << "]" << std::endl; - } - } - - std::cout << "\nModels:" << std::endl; - for (const auto& [id, model] : models) { - std::cout << " " << model.name << " (ID: " << id << ")" << std::endl; - std::cout << " Data: " << model.dataFile << std::endl; - std::cout << " Palette: " << model.paletteFile << std::endl; - std::cout << " Parent: " << model.parentId << std::endl; - - if (!model.position.empty()) { - std::cout << " Position: [" - << model.position[0] << ", " - << model.position[1] << ", " - << model.position[2] << "]" << std::endl; - } - } - } -}; diff --git a/patch_libplist/cnary.c b/patch_libplist/cnary.c deleted file mode 100644 index 82c20bd..0000000 --- a/patch_libplist/cnary.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * cnary.c - * - * Created on: Mar 9, 2011 - * Author: posixninja - * - * Copyright (c) 2011 Joshua Hill. All Rights Reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#include "node.h" - -int main(int argc, char* argv[]) { - puts("Creating root node"); - node_t root = node_create(NULL, NULL); - - puts("Creating child 1 node"); - node_t one = node_create(root, NULL); - puts("Creating child 2 node"); - node_t two = node_create(root, NULL); - - puts("Creating child 3 node"); - node_t three = node_create(one, NULL); - - puts("Debugging root node"); - node_debug(root); - - puts("Destroying root node"); - node_destroy(root); - return 0; -} - diff --git a/patch_libplist/config.h b/patch_libplist/config.h deleted file mode 100644 index a616b03..0000000 --- a/patch_libplist/config.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef CONFIG_H -#define CONFIG_H - -#define PACKAGE_VERSION "2.4.0" -#define PACKAGE "libplist" -#define PACKAGE_BUGREPORT "https://github.com/libimobiledevice/libplist/issues" -#define PACKAGE_NAME "libplist" -#define PACKAGE_STRING "libplist 2.4.0" -#define PACKAGE_TARNAME "libplist" -#define PACKAGE_URL "https://libimobiledevice.org" - -#endif /* CONFIG_H */ - diff --git a/patch_libplist/libplist.vcxproj b/patch_libplist/libplist.vcxproj deleted file mode 100644 index 7a39570..0000000 --- a/patch_libplist/libplist.vcxproj +++ /dev/null @@ -1,119 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - - 16.0 - {A34F0D57-E086-45B3-9A7D-8A04CAD3AFEF} - Win32Proj - libplist - 10.0 - - - - - - DynamicLibrary - true - v143 - Unicode - - - DynamicLibrary - false - v143 - true - Unicode - - - DynamicLibrary - true - v143 - Unicode - - - DynamicLibrary - false - v143 - true - Unicode - - - - - - $(SolutionDir)bin\$(Platform)\$(Configuration)\ - $(SolutionDir)obj\$(Platform)\$(Configuration)\$(ProjectName)\ - - - - - WIN32;_WINDOWS;_USRDLL;LIBPLIST_EXPORTS;_CRT_SECURE_NO_WARNINGS;HAVE_CONFIG_H;%(PreprocessorDefinitions) - $(ProjectDir)include;$(ProjectDir)src;$(ProjectDir)libcnary\include;$(ProjectDir);%(AdditionalIncludeDirectories) - Level3 - true - true - 4244;4267;4146 - - - Windows - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/patch_libplist/plist.c b/patch_libplist/plist.c deleted file mode 100644 index 03b1cae..0000000 --- a/patch_libplist/plist.c +++ /dev/null @@ -1,1969 +0,0 @@ -/* - * plist.c - * Builds plist XML structures - * - * Copyright (c) 2009-2023 Nikias Bassen, All Rights Reserved. - * Copyright (c) 2010-2015 Martin Szulecki, All Rights Reserved. - * Copyright (c) 2008 Zach C., All Rights Reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#define _GNU_SOURCE 1 -#include -#include "plist.h" -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef WIN32 -#include -#endif - -#include -#include -#include -#include - -#ifdef _MSC_VER -typedef SSIZE_T ssize_t; -#endif - -#ifdef DEBUG -static int plist_debug = 0; -#define PLIST_ERR(...) if (plist_debug > 0) { fprintf(stderr, "libplist ERROR: " __VA_ARGS__); } -#else -#define PLIST_ERR(...) -#endif - -#ifndef bswap16 -#define bswap16(x) ((((x) & 0xFF00) >> 8) | (((x) & 0x00FF) << 8)) -#endif - -#ifndef bswap32 -#define bswap32(x) ((((x) & 0xFF000000) >> 24) \ - | (((x) & 0x00FF0000) >> 8) \ - | (((x) & 0x0000FF00) << 8) \ - | (((x) & 0x000000FF) << 24)) -#endif - -#ifndef bswap64 -#define bswap64(x) ((((x) & 0xFF00000000000000ull) >> 56) \ - | (((x) & 0x00FF000000000000ull) >> 40) \ - | (((x) & 0x0000FF0000000000ull) >> 24) \ - | (((x) & 0x000000FF00000000ull) >> 8) \ - | (((x) & 0x00000000FF000000ull) << 8) \ - | (((x) & 0x0000000000FF0000ull) << 24) \ - | (((x) & 0x000000000000FF00ull) << 40) \ - | (((x) & 0x00000000000000FFull) << 56)) -#endif - -#ifndef le16toh -#ifdef __BIG_ENDIAN__ -#define le16toh(x) bswap16(x) -#else -#define le16toh(x) (x) -#endif -#endif - -#ifndef le32toh -#ifdef __BIG_ENDIAN__ -#define le32toh(x) bswap32(x) -#else -#define le32toh(x) (x) -#endif -#endif - -#ifndef le64toh -#ifdef __BIG_ENDIAN__ -#define le64toh(x) bswap64(x) -#else -#define le64toh(x) (x) -#endif -#endif - -// Reference: https://stackoverflow.com/a/2390626/1806760 -// Initializer/finalizer sample for MSVC and GCC/Clang. -// 2010-2016 Joe Lowe. Released into the public domain. - -#ifdef __cplusplus - #define INITIALIZER(f) \ - static void f(void); \ - struct f##_t_ { f##_t_(void) { f(); } }; static f##_t_ f##_; \ - static void f(void) -#elif defined(_MSC_VER) - #pragma section(".CRT$XCU",read) - #define INITIALIZER2_(f,p) \ - static void f(void); \ - __declspec(allocate(".CRT$XCU")) void (*f##_)(void) = f; \ - __pragma(comment(linker,"/include:" p #f "_")) \ - static void f(void) - #ifdef _WIN64 - #define INITIALIZER(f) INITIALIZER2_(f,"") - #else - #define INITIALIZER(f) INITIALIZER2_(f,"_") - #endif -#else - #define INITIALIZER(f) \ - static void f(void) __attribute__((__constructor__)); \ - static void f(void) -#endif - -extern void plist_xml_init(void); -extern void plist_xml_deinit(void); -extern void plist_bin_init(void); -extern void plist_bin_deinit(void); -extern void plist_json_init(void); -extern void plist_json_deinit(void); -extern void plist_ostep_init(void); -extern void plist_ostep_deinit(void); - -static void internal_plist_deinit(void) -{ - plist_bin_deinit(); - plist_xml_deinit(); - plist_json_deinit(); - plist_ostep_deinit(); -} - -INITIALIZER(internal_plist_init) -{ - plist_bin_init(); - plist_xml_init(); - plist_json_init(); - plist_ostep_init(); - atexit(internal_plist_deinit); -} - -#ifndef HAVE_MEMMEM -// see https://sourceware.org/legacy-ml/libc-alpha/2007-12/msg00000.html - -#ifndef _LIBC -# define __builtin_expect(expr, val) (expr) -#endif - -#undef memmem - -/* Return the first occurrence of NEEDLE in HAYSTACK. */ -void* memmem(const void* haystack, size_t haystack_len, const void* needle, size_t needle_len) -{ - /* not really Rabin-Karp, just using additive hashing */ - char* haystack_ = (char*)haystack; - char* needle_ = (char*)needle; - int hash = 0; /* this is the static hash value of the needle */ - int hay_hash = 0; /* rolling hash over the haystack */ - char* last; - size_t i; - - if (haystack_len < needle_len) - return NULL; - - if (!needle_len) - return haystack_; - - /* initialize hashes */ - for (i = needle_len; i; --i) { - hash += *needle_++; - hay_hash += *haystack_++; - } - - /* iterate over the haystack */ - haystack_ = (char*)haystack; - needle_ = (char*)needle; - last = haystack_+(haystack_len - needle_len + 1); - for (; haystack_ < last; ++haystack_) { - if (__builtin_expect(hash == hay_hash, 0) - && *haystack_ == *needle_ /* prevent calling memcmp, was a optimization from existing glibc */ - && !memcmp (haystack_, needle_, needle_len)) { - return haystack_; - } - /* roll the hash */ - hay_hash -= *haystack_; - hay_hash += *(haystack_+needle_len); - } - return NULL; -} -#endif - -int plist_is_binary(const char *plist_data, uint32_t length) -{ - if (length < 8) { - return 0; - } - - return (memcmp(plist_data, "bplist00", 8) == 0); -} - -#define SKIP_WS(blob, pos, len) \ - while (pos < len && ((blob[pos] == ' ') || (blob[pos] == '\t') || (blob[pos] == '\r') || (blob[pos] == '\n'))) pos++; -#define FIND_NEXT(blob, pos, len, chr) \ - while (pos < len && (blob[pos] != chr)) pos++; - -plist_err_t plist_from_memory(const char *plist_data, uint32_t length, plist_t *plist, plist_format_t *format) -{ - plist_err_t res = PLIST_ERR_UNKNOWN; - if (!plist) { - return PLIST_ERR_INVALID_ARG; - } - *plist = NULL; - if (!plist_data || length == 0) { - return PLIST_ERR_INVALID_ARG; - } - plist_format_t fmt = PLIST_FORMAT_NONE; - if (format) *format = PLIST_FORMAT_NONE; - if (plist_is_binary(plist_data, length)) { - res = plist_from_bin(plist_data, length, plist); - fmt = PLIST_FORMAT_BINARY; - } else { - uint32_t pos = 0; - int is_json = 0; - int is_xml = 0; - /* skip whitespace */ - SKIP_WS(plist_data, pos, length); - if (pos >= length) { - return PLIST_ERR_PARSE; - } - if (plist_data[pos] == '<' && (length-pos > 3) && !isxdigit(plist_data[pos+1]) && !isxdigit(plist_data[pos+2]) && !isxdigit(plist_data[pos+3])) { - is_xml = 1; - } else if (plist_data[pos] == '[') { - /* only valid for json */ - is_json = 1; - } else if (plist_data[pos] == '(') { - /* only valid for openstep */ - } else if (plist_data[pos] == '{') { - /* this could be json or openstep */ - pos++; - SKIP_WS(plist_data, pos, length); - if (pos >= length) { - return PLIST_ERR_PARSE; - } - if (plist_data[pos] == '"') { - /* still could be both */ - pos++; - while (pos < length) { - FIND_NEXT(plist_data, pos, length, '"'); - if (plist_data[pos-1] != '\\') { - break; - } - pos++; - } - if (pos >= length) { - return PLIST_ERR_PARSE; - } - if (plist_data[pos] == '"') { - pos++; - SKIP_WS(plist_data, pos, length); - if (pos >= length) { - return PLIST_ERR_PARSE; - } - if (plist_data[pos] == ':') { - /* this is definitely json */ - is_json = 1; - } - } - } - } - if (is_xml) { - res = plist_from_xml(plist_data, length, plist); - fmt = PLIST_FORMAT_XML; - } else if (is_json) { - res = plist_from_json(plist_data, length, plist); - fmt = PLIST_FORMAT_JSON; - } else { - res = plist_from_openstep(plist_data, length, plist); - fmt = PLIST_FORMAT_OSTEP; - } - } - if (format && res == PLIST_ERR_SUCCESS) { - *format = fmt; - } - return res; -} - -plist_err_t plist_read_from_file(const char *filename, plist_t *plist, plist_format_t *format) -{ - if (!filename || !plist) { - return PLIST_ERR_INVALID_ARG; - } - FILE *f = fopen(filename, "rb"); - if (!f) { - return PLIST_ERR_IO; - } - struct stat fst; - fstat(fileno(f), &fst); - if ((uint64_t)fst.st_size > UINT32_MAX) { - return PLIST_ERR_NO_MEM; - } - uint32_t total = (uint32_t)fst.st_size; - if (total == 0) { - return PLIST_ERR_PARSE; - } - char *buf = (char*)malloc(total); - if (!buf) { - fclose(f); - return PLIST_ERR_NO_MEM; - } - uint32_t done = 0; - while (done < total) { - ssize_t r = fread(buf + done, 1, total - done, f); - if (r <= 0) { - break; - } - done += r; - } - fclose(f); - if (done < total) { - free(buf); - return PLIST_ERR_IO; - } - plist_err_t res = plist_from_memory(buf, total, plist, format); - free(buf); - return res; -} - -plist_t plist_new_node(plist_data_t data) -{ - return (plist_t) node_create(NULL, data); -} - -plist_data_t plist_get_data(plist_t node) -{ - if (!node) - return NULL; - return (plist_data_t)((node_t)node)->data; -} - -plist_data_t plist_new_plist_data(void) -{ - plist_data_t data = (plist_data_t) calloc(sizeof(struct plist_data_s), 1); - return data; -} - -static unsigned int dict_key_hash(const void *data) -{ - plist_data_t keydata = (plist_data_t)data; - unsigned int hash = 5381; - size_t i; - char *str = keydata->strval; - for (i = 0; i < keydata->length; str++, i++) { - hash = ((hash << 5) + hash) + *str; - } - return hash; -} - -static int dict_key_compare(const void* a, const void* b) -{ - plist_data_t data_a = (plist_data_t)a; - plist_data_t data_b = (plist_data_t)b; - if (data_a->strval == NULL || data_b->strval == NULL) { - return FALSE; - } - if (data_a->length != data_b->length) { - return FALSE; - } - return (strcmp(data_a->strval, data_b->strval) == 0) ? TRUE : FALSE; -} - -void plist_free_data(plist_data_t data) -{ - if (data) - { - switch (data->type) - { - case PLIST_KEY: - case PLIST_STRING: - free(data->strval); - break; - case PLIST_DATA: - free(data->buff); - break; - case PLIST_ARRAY: - ptr_array_free((ptrarray_t*)data->hashtable); - break; - case PLIST_DICT: - hash_table_destroy((hashtable_t*)data->hashtable); - break; - default: - break; - } - free(data); - } -} - -static int plist_free_node(node_t node) -{ - plist_data_t data = NULL; - int node_index = node_detach(node->parent, node); - data = plist_get_data(node); - plist_free_data(data); - node->data = NULL; - - node_t ch; - for (ch = node_first_child(node); ch; ) { - node_t next = node_next_sibling(ch); - plist_free_node(ch); - ch = next; - } - - node_destroy(node); - - return node_index; -} - -plist_t plist_new_dict(void) -{ - plist_data_t data = plist_new_plist_data(); - data->type = PLIST_DICT; - return plist_new_node(data); -} - -plist_t plist_new_array(void) -{ - plist_data_t data = plist_new_plist_data(); - data->type = PLIST_ARRAY; - return plist_new_node(data); -} - -//These nodes should not be handled by users -static plist_t plist_new_key(const char *val) -{ - plist_data_t data = plist_new_plist_data(); - data->type = PLIST_KEY; - data->strval = strdup(val); - data->length = strlen(val); - return plist_new_node(data); -} - -plist_t plist_new_string(const char *val) -{ - plist_data_t data = plist_new_plist_data(); - data->type = PLIST_STRING; - data->strval = strdup(val); - data->length = strlen(val); - return plist_new_node(data); -} - -plist_t plist_new_bool(uint8_t val) -{ - plist_data_t data = plist_new_plist_data(); - data->type = PLIST_BOOLEAN; - data->boolval = val; - data->length = sizeof(uint8_t); - return plist_new_node(data); -} - -plist_t plist_new_uint(uint64_t val) -{ - plist_data_t data = plist_new_plist_data(); - data->type = PLIST_INT; - data->intval = val; - data->length = (val > INT_MAX) ? sizeof(uint64_t)*2 : sizeof(uint64_t); - return plist_new_node(data); -} - -plist_t plist_new_int(int64_t val) -{ - plist_data_t data = plist_new_plist_data(); - data->type = PLIST_INT; - data->intval = val; - data->length = sizeof(uint64_t); - return plist_new_node(data); -} - -plist_t plist_new_uid(uint64_t val) -{ - plist_data_t data = plist_new_plist_data(); - data->type = PLIST_UID; - data->intval = val; - data->length = sizeof(uint64_t); - return plist_new_node(data); -} - -plist_t plist_new_real(double val) -{ - plist_data_t data = plist_new_plist_data(); - data->type = PLIST_REAL; - data->realval = val; - data->length = sizeof(double); - return plist_new_node(data); -} - -plist_t plist_new_data(const char *val, uint64_t length) -{ - plist_data_t data = plist_new_plist_data(); - data->type = PLIST_DATA; - data->buff = (uint8_t *) malloc(length); - memcpy(data->buff, val, length); - data->length = length; - return plist_new_node(data); -} - -plist_t plist_new_date(int32_t sec, int32_t usec) -{ - plist_data_t data = plist_new_plist_data(); - data->type = PLIST_DATE; - data->realval = (double)sec + (double)usec / 1000000; - data->length = sizeof(double); - return plist_new_node(data); -} - -plist_t plist_new_null(void) -{ - plist_data_t data = plist_new_plist_data(); - data->type = PLIST_NULL; - data->intval = 0; - data->length = 0; - return plist_new_node(data); -} - -void plist_free(plist_t plist) -{ - if (plist) - { - plist_free_node((node_t)plist); - } -} - -void plist_mem_free(void* ptr) -{ - if (ptr) - { - free(ptr); - } -} - -static plist_t plist_copy_node(node_t node) -{ - plist_type node_type = PLIST_NONE; - plist_t newnode = NULL; - plist_data_t data = plist_get_data(node); - plist_data_t newdata = plist_new_plist_data(); - - assert(data); // plist should always have data - assert(newdata); - - memcpy(newdata, data, sizeof(struct plist_data_s)); - - node_type = plist_get_node_type(node); - switch (node_type) { - case PLIST_DATA: - newdata->buff = (uint8_t *) malloc(data->length); - memcpy(newdata->buff, data->buff, data->length); - break; - case PLIST_KEY: - case PLIST_STRING: - newdata->strval = strdup(data->strval); - break; - case PLIST_ARRAY: - if (data->hashtable) { - ptrarray_t* pa = ptr_array_new(((ptrarray_t*)data->hashtable)->capacity); - assert(pa); - newdata->hashtable = pa; - } - break; - case PLIST_DICT: - if (data->hashtable) { - hashtable_t* ht = hash_table_new(dict_key_hash, dict_key_compare, NULL); - assert(ht); - newdata->hashtable = ht; - } - break; - default: - break; - } - newnode = plist_new_node(newdata); - - node_t ch; - unsigned int node_index = 0; - for (ch = node_first_child(node); ch; ch = node_next_sibling(ch)) { - /* copy child node */ - plist_t newch = plist_copy_node(ch); - /* attach to new parent node */ - node_attach((node_t)newnode, (node_t)newch); - /* if needed, add child node to lookup table of parent node */ - switch (node_type) { - case PLIST_ARRAY: - if (newdata->hashtable) { - ptr_array_add((ptrarray_t*)newdata->hashtable, newch); - } - break; - case PLIST_DICT: - if (newdata->hashtable && (node_index % 2 != 0)) { - hash_table_insert((hashtable_t*)newdata->hashtable, (node_prev_sibling((node_t)newch))->data, newch); - } - break; - default: - break; - } - node_index++; - } - return newnode; -} - -plist_t plist_copy(plist_t node) -{ - return node ? plist_copy_node((node_t)node) : NULL; -} - -uint32_t plist_array_get_size(plist_t node) -{ - uint32_t ret = 0; - if (node && PLIST_ARRAY == plist_get_node_type(node)) - { - ret = node_n_children((node_t)node); - } - return ret; -} - -plist_t plist_array_get_item(plist_t node, uint32_t n) -{ - plist_t ret = NULL; - if (node && PLIST_ARRAY == plist_get_node_type(node) && n < INT_MAX) - { - ptrarray_t *pa = (ptrarray_t*)((plist_data_t)((node_t)node)->data)->hashtable; - if (pa) { - ret = (plist_t)ptr_array_index(pa, n); - } else { - ret = (plist_t)node_nth_child((node_t)node, n); - } - } - return ret; -} - -uint32_t plist_array_get_item_index(plist_t node) -{ - plist_t father = plist_get_parent(node); - if (PLIST_ARRAY == plist_get_node_type(father)) - { - return node_child_position((node_t)father, (node_t)node); - } - return UINT_MAX; -} - -static void _plist_array_post_insert(plist_t node, plist_t item, long n) -{ - ptrarray_t *pa = (ptrarray_t*)((plist_data_t)((node_t)node)->data)->hashtable; - if (pa) { - /* store pointer to item in array */ - ptr_array_insert(pa, item, n); - } else { - if (((node_t)node)->count > 100) { - /* make new lookup array */ - pa = ptr_array_new(128); - plist_t current = NULL; - for (current = (plist_t)node_first_child((node_t)node); - pa && current; - current = (plist_t)node_next_sibling((node_t)current)) - { - ptr_array_add(pa, current); - } - ((plist_data_t)((node_t)node)->data)->hashtable = pa; - } - } -} - -void plist_array_set_item(plist_t node, plist_t item, uint32_t n) -{ - if (!item) { - return; - } - if (node && PLIST_ARRAY == plist_get_node_type(node) && n < INT_MAX) - { - plist_t old_item = plist_array_get_item(node, n); - if (old_item) - { - int idx = plist_free_node((node_t)old_item); - assert(idx >= 0); - if (idx < 0) { - return; - } - node_insert((node_t)node, idx, (node_t)item); - ptrarray_t* pa = (ptrarray_t*)((plist_data_t)((node_t)node)->data)->hashtable; - if (pa) { - ptr_array_set(pa, item, idx); - } - } - } -} - -void plist_array_append_item(plist_t node, plist_t item) -{ - if (!item) { - return; - } - if (node && PLIST_ARRAY == plist_get_node_type(node)) - { - node_attach((node_t)node, (node_t)item); - _plist_array_post_insert(node, item, -1); - } -} - -void plist_array_insert_item(plist_t node, plist_t item, uint32_t n) -{ - if (!item) { - return; - } - if (node && PLIST_ARRAY == plist_get_node_type(node) && n < INT_MAX) - { - node_insert((node_t)node, n, (node_t)item); - _plist_array_post_insert(node, item, (long)n); - } -} - -void plist_array_remove_item(plist_t node, uint32_t n) -{ - if (node && PLIST_ARRAY == plist_get_node_type(node) && n < INT_MAX) - { - plist_t old_item = plist_array_get_item(node, n); - if (old_item) - { - ptrarray_t* pa = (ptrarray_t*)((plist_data_t)((node_t)node)->data)->hashtable; - if (pa) { - ptr_array_remove(pa, n); - } - plist_free(old_item); - } - } -} - -void plist_array_item_remove(plist_t node) -{ - plist_t father = plist_get_parent(node); - if (PLIST_ARRAY == plist_get_node_type(father)) - { - int n = node_child_position((node_t)father, (node_t)node); - if (n < 0) return; - ptrarray_t* pa = (ptrarray_t*)((plist_data_t)((node_t)father)->data)->hashtable; - if (pa) { - ptr_array_remove(pa, n); - } - plist_free(node); - } -} - -void plist_array_new_iter(plist_t node, plist_array_iter *iter) -{ - if (iter) - { - *iter = malloc(sizeof(node_t)); - *((node_t*)(*iter)) = node_first_child((node_t)node); - } -} - -void plist_array_next_item(plist_t node, plist_array_iter iter, plist_t *item) -{ - node_t* iter_node = (node_t*)iter; - - if (item) - { - *item = NULL; - } - - if (node && PLIST_ARRAY == plist_get_node_type(node) && *iter_node) - { - if (item) - { - *item = (plist_t)(*iter_node); - } - *iter_node = node_next_sibling(*iter_node); - } -} - -uint32_t plist_dict_get_size(plist_t node) -{ - uint32_t ret = 0; - if (node && PLIST_DICT == plist_get_node_type(node)) - { - ret = node_n_children((node_t)node) / 2; - } - return ret; -} - -void plist_dict_new_iter(plist_t node, plist_dict_iter *iter) -{ - if (iter) - { - *iter = malloc(sizeof(node_t)); - *((node_t*)(*iter)) = node_first_child((node_t)node); - } -} - -void plist_dict_next_item(plist_t node, plist_dict_iter iter, char **key, plist_t *val) -{ - node_t* iter_node = (node_t*)iter; - - if (key) - { - *key = NULL; - } - if (val) - { - *val = NULL; - } - - if (node && PLIST_DICT == plist_get_node_type(node) && *iter_node) - { - if (key) - { - plist_get_key_val((plist_t)(*iter_node), key); - } - *iter_node = node_next_sibling(*iter_node); - if (val) - { - *val = (plist_t)(*iter_node); - } - *iter_node = node_next_sibling(*iter_node); - } -} - -void plist_dict_get_item_key(plist_t node, char **key) -{ - plist_t father = plist_get_parent(node); - if (PLIST_DICT == plist_get_node_type(father)) - { - plist_get_key_val( (plist_t) node_prev_sibling((node_t)node), key); - } -} - -plist_t plist_dict_item_get_key(plist_t node) -{ - plist_t ret = NULL; - plist_t father = plist_get_parent(node); - if (PLIST_DICT == plist_get_node_type(father)) - { - ret = (plist_t)node_prev_sibling((node_t)node); - } - return ret; -} - -plist_t plist_dict_get_item(plist_t node, const char* key) -{ - plist_t ret = NULL; - - if (node && PLIST_DICT == plist_get_node_type(node)) - { - plist_data_t data = plist_get_data(node); - hashtable_t *ht = (hashtable_t*)data->hashtable; - if (ht) { - struct plist_data_s sdata; - sdata.strval = (char*)key; - sdata.length = strlen(key); - ret = (plist_t)hash_table_lookup(ht, &sdata); - } else { - plist_t current = NULL; - for (current = (plist_t)node_first_child((node_t)node); - current; - current = (plist_t)node_next_sibling(node_next_sibling((node_t)current))) - { - data = plist_get_data(current); - assert( PLIST_KEY == plist_get_node_type(current) ); - - if (data && !strcmp(key, data->strval)) - { - ret = (plist_t)node_next_sibling((node_t)current); - break; - } - } - } - } - return ret; -} - -void plist_dict_set_item(plist_t node, const char* key, plist_t item) -{ - if (!item) { - return; - } - if (node && PLIST_DICT == plist_get_node_type(node)) { - plist_t old_item = plist_dict_get_item(node, key); - plist_t key_node = NULL; - if (old_item) { - int idx = plist_free_node((node_t)old_item); - assert(idx >= 0); - if (idx < 0) { - return; - } - node_insert((node_t)node, idx, (node_t)item); - key_node = node_prev_sibling((node_t)item); - } else { - key_node = plist_new_key(key); - node_attach((node_t)node, (node_t)key_node); - node_attach((node_t)node, (node_t)item); - } - - hashtable_t *ht = (hashtable_t*)((plist_data_t)((node_t)node)->data)->hashtable; - if (ht) { - /* store pointer to item in hash table */ - hash_table_insert(ht, (plist_data_t)((node_t)key_node)->data, item); - } else { - if (((node_t)node)->count > 500) { - /* make new hash table */ - ht = hash_table_new(dict_key_hash, dict_key_compare, NULL); - /* calculate the hashes for all entries we have so far */ - plist_t current = NULL; - for (current = (plist_t)node_first_child((node_t)node); - ht && current; - current = (plist_t)node_next_sibling(node_next_sibling((node_t)current))) - { - hash_table_insert(ht, ((node_t)current)->data, node_next_sibling((node_t)current)); - } - ((plist_data_t)((node_t)node)->data)->hashtable = ht; - } - } - } -} - -void plist_dict_remove_item(plist_t node, const char* key) -{ - if (node && PLIST_DICT == plist_get_node_type(node)) - { - plist_t old_item = plist_dict_get_item(node, key); - if (old_item) - { - plist_t key_node = node_prev_sibling((node_t)old_item); - hashtable_t* ht = (hashtable_t*)((plist_data_t)((node_t)node)->data)->hashtable; - if (ht) { - hash_table_remove(ht, ((node_t)key_node)->data); - } - plist_free(key_node); - plist_free(old_item); - } - } -} - -void plist_dict_merge(plist_t *target, plist_t source) -{ - if (!target || !*target || (plist_get_node_type(*target) != PLIST_DICT) || !source || (plist_get_node_type(source) != PLIST_DICT)) - return; - - char* key = NULL; - plist_dict_iter it = NULL; - plist_t subnode = NULL; - plist_dict_new_iter(source, &it); - if (!it) - return; - - do { - plist_dict_next_item(source, it, &key, &subnode); - if (!key) - break; - - plist_dict_set_item(*target, key, plist_copy(subnode)); - free(key); - key = NULL; - } while (1); - free(it); -} - -static void plist_get_type_and_value(plist_t node, plist_type * type, void *value, uint64_t * length) -{ - plist_data_t data = NULL; - - if (!node) - return; - - data = plist_get_data(node); - - *type = data->type; - *length = data->length; - - switch (*type) - { - case PLIST_BOOLEAN: - *((char *) value) = data->boolval; - break; - case PLIST_INT: - case PLIST_UID: - *((uint64_t *) value) = data->intval; - break; - case PLIST_REAL: - case PLIST_DATE: - *((double *) value) = data->realval; - break; - case PLIST_KEY: - case PLIST_STRING: - *((char **) value) = strdup(data->strval); - break; - case PLIST_DATA: - *((uint8_t **) value) = (uint8_t *) malloc(*length * sizeof(uint8_t)); - memcpy(*((uint8_t **) value), data->buff, *length * sizeof(uint8_t)); - break; - case PLIST_ARRAY: - case PLIST_DICT: - default: - break; - } -} - -uint8_t plist_dict_get_bool(plist_t dict, const char *key) -{ - uint8_t bval = 0; - uint64_t uintval = 0; - const char *strval = NULL; - uint64_t strsz = 0; - plist_t node = plist_dict_get_item(dict, key); - if (!node) { - return 0; - } - switch (plist_get_node_type(node)) { - case PLIST_BOOLEAN: - { - uint64_t temp = 0; - plist_get_type_and_value(node, NULL, &temp, NULL); - bval = (uint8_t)temp; - } - break; - case PLIST_INT: - plist_get_uint_val(node, &uintval); - bval = (uintval) ? 1 : 0; - break; - case PLIST_STRING: - strval = plist_get_string_ptr(node, NULL); - if (strval) { - if (strcmp(strval, "true")) { - bval = 1; - } else if (strcmp(strval, "false")) { - bval = 0; - } else { - PLIST_ERR("%s: invalid string '%s' for string to boolean conversion\n", __func__, strval); - } - } - break; - case PLIST_DATA: - strval = (const char*)plist_get_data_ptr(node, &strsz); - if (strval) { - if (strsz == 1) { - bval = (strval[0]) ? 1 : 0; - } else { - PLIST_ERR("%s: invalid size %" PRIu64 " for data to boolean conversion\n", __func__, strsz); - } - } - break; - default: - break; - } - return bval; -} - -int64_t plist_dict_get_int(plist_t dict, const char *key) -{ - int64_t intval = 0; - const char *strval = NULL; - uint64_t strsz = 0; - plist_t node = plist_dict_get_item(dict, key); - if (!node) { - return intval; - } - switch (plist_get_node_type(node)) { - case PLIST_INT: - plist_get_int_val(node, &intval); - break; - case PLIST_STRING: - strval = plist_get_string_ptr(node, NULL); - if (strval) { - intval = strtoll(strval, NULL, 0); - } - break; - case PLIST_DATA: - strval = (const char*)plist_get_data_ptr(node, &strsz); - if (strval) { - if (strsz == 8) { - intval = le64toh(*(int64_t*)strval); - } else if (strsz == 4) { - intval = le32toh(*(int32_t*)strval); - } else if (strsz == 2) { - intval = le16toh(*(int16_t*)strval); - } else if (strsz == 1) { - intval = strval[0]; - } else { - PLIST_ERR("%s: invalid size %" PRIu64 " for data to integer conversion\n", __func__, strsz); - } - } - break; - default: - break; - } - return intval; -} - - -uint64_t plist_dict_get_uint(plist_t dict, const char *key) -{ - uint64_t uintval = 0; - const char *strval = NULL; - uint64_t strsz = 0; - plist_t node = plist_dict_get_item(dict, key); - if (!node) { - return uintval; - } - switch (plist_get_node_type(node)) { - case PLIST_INT: - plist_get_uint_val(node, &uintval); - break; - case PLIST_STRING: - strval = plist_get_string_ptr(node, NULL); - if (strval) { - uintval = strtoull(strval, NULL, 0); - } - break; - case PLIST_DATA: - strval = (const char*)plist_get_data_ptr(node, &strsz); - if (strval) { - if (strsz == 8) { - uintval = le64toh(*(uint64_t*)strval); - } else if (strsz == 4) { - uintval = le32toh(*(uint32_t*)strval); - } else if (strsz == 2) { - uintval = le16toh(*(uint16_t*)strval); - } else if (strsz == 1) { - uintval = strval[0]; - } else { - PLIST_ERR("%s: invalid size %" PRIu64 " for data to integer conversion\n", __func__, strsz); - } - } - break; - default: - break; - } - return uintval; -} - -plist_err_t plist_dict_copy_item(plist_t target_dict, plist_t source_dict, const char *key, const char *alt_source_key) -{ - plist_t node = plist_dict_get_item(source_dict, (alt_source_key) ? alt_source_key : key); - if (!node) { - return PLIST_ERR_INVALID_ARG; - } - plist_dict_set_item(target_dict, key, plist_copy(node)); - return PLIST_ERR_SUCCESS; -} - -plist_err_t plist_dict_copy_bool(plist_t target_dict, plist_t source_dict, const char *key, const char *alt_source_key) -{ - if (plist_dict_get_item(source_dict, (alt_source_key) ? alt_source_key : key) == NULL) { - return PLIST_ERR_INVALID_ARG; - } - uint8_t bval = plist_dict_get_bool(source_dict, (alt_source_key) ? alt_source_key : key); - plist_dict_set_item(target_dict, key, plist_new_bool(bval)); - return PLIST_ERR_SUCCESS; -} - -plist_err_t plist_dict_copy_int(plist_t target_dict, plist_t source_dict, const char *key, const char *alt_source_key) -{ - if (plist_dict_get_item(source_dict, (alt_source_key) ? alt_source_key : key) == NULL) { - return PLIST_ERR_INVALID_ARG; - } - int64_t i64val = plist_dict_get_int(source_dict, (alt_source_key) ? alt_source_key : key); - plist_dict_set_item(target_dict, key, plist_new_int(i64val)); - return PLIST_ERR_SUCCESS; -} - -plist_err_t plist_dict_copy_uint(plist_t target_dict, plist_t source_dict, const char *key, const char *alt_source_key) -{ - if (plist_dict_get_item(source_dict, (alt_source_key) ? alt_source_key : key) == NULL) { - return PLIST_ERR_INVALID_ARG; - } - uint64_t u64val = plist_dict_get_uint(source_dict, (alt_source_key) ? alt_source_key : key); - plist_dict_set_item(target_dict, key, plist_new_uint(u64val)); - return PLIST_ERR_SUCCESS; -} - -plist_err_t plist_dict_copy_data(plist_t target_dict, plist_t source_dict, const char *key, const char *alt_source_key) -{ - plist_t node = plist_dict_get_item(source_dict, (alt_source_key) ? alt_source_key : key); - if (!PLIST_IS_DATA(node)) { - return PLIST_ERR_INVALID_ARG; - } - plist_dict_set_item(target_dict, key, plist_copy(node)); - return PLIST_ERR_SUCCESS; -} - -plist_err_t plist_dict_copy_string(plist_t target_dict, plist_t source_dict, const char *key, const char *alt_source_key) -{ - plist_t node = plist_dict_get_item(source_dict, (alt_source_key) ? alt_source_key : key); - if (!PLIST_IS_STRING(node)) { - return PLIST_ERR_INVALID_ARG; - } - plist_dict_set_item(target_dict, key, plist_copy(node)); - return PLIST_ERR_SUCCESS; -} - -plist_t plist_access_pathv(plist_t plist, uint32_t length, va_list v) -{ - plist_t current = plist; - plist_type type = PLIST_NONE; - uint32_t i = 0; - - for (i = 0; i < length && current; i++) - { - type = plist_get_node_type(current); - - if (type == PLIST_ARRAY) - { - uint32_t n = va_arg(v, uint32_t); - current = plist_array_get_item(current, n); - } - else if (type == PLIST_DICT) - { - const char* key = va_arg(v, const char*); - current = plist_dict_get_item(current, key); - } - } - return current; -} - -plist_t plist_access_path(plist_t plist, uint32_t length, ...) -{ - plist_t ret = NULL; - va_list v; - - va_start(v, length); - ret = plist_access_pathv(plist, length, v); - va_end(v); - return ret; -} - -plist_t plist_get_parent(plist_t node) -{ - return node ? (plist_t) ((node_t) node)->parent : NULL; -} - -plist_type plist_get_node_type(plist_t node) -{ - if (node) - { - plist_data_t data = plist_get_data(node); - if (data) - return data->type; - } - return PLIST_NONE; -} - -void plist_get_key_val(plist_t node, char **val) -{ - if (!node || !val) - return; - plist_type type = plist_get_node_type(node); - uint64_t length = 0; - if (PLIST_KEY != type) - return; - plist_get_type_and_value(node, &type, (void *) val, &length); - if (!*val) - return; - assert(length == strlen(*val)); -} - -void plist_get_string_val(plist_t node, char **val) -{ - if (!node || !val) - return; - plist_type type = plist_get_node_type(node); - uint64_t length = 0; - if (PLIST_STRING != type) - return; - plist_get_type_and_value(node, &type, (void *) val, &length); - if (!*val) - return; - assert(length == strlen(*val)); -} - -const char* plist_get_string_ptr(plist_t node, uint64_t* length) -{ - if (!node) - return NULL; - plist_type type = plist_get_node_type(node); - if (PLIST_STRING != type) - return NULL; - plist_data_t data = plist_get_data(node); - if (length) - *length = data->length; - return (const char*)data->strval; -} - -void plist_get_bool_val(plist_t node, uint8_t * val) -{ - if (!node || !val) - return; - plist_type type = plist_get_node_type(node); - uint64_t length = 0; - if (PLIST_BOOLEAN != type) - return; - plist_get_type_and_value(node, &type, (void *) val, &length); - assert(length == sizeof(uint8_t)); -} - -void plist_get_uint_val(plist_t node, uint64_t * val) -{ - if (!node || !val) - return; - plist_type type = plist_get_node_type(node); - uint64_t length = 0; - if (PLIST_INT != type) - return; - plist_get_type_and_value(node, &type, (void *) val, &length); - assert(length == sizeof(uint64_t) || length == 16); -} - -void plist_get_int_val(plist_t node, int64_t * val) -{ - plist_get_uint_val(node, (uint64_t*)val); -} - -void plist_get_uid_val(plist_t node, uint64_t * val) -{ - if (!node || !val) - return; - plist_type type = plist_get_node_type(node); - uint64_t length = 0; - if (PLIST_UID != type) - return; - plist_get_type_and_value(node, &type, (void *) val, &length); - assert(length == sizeof(uint64_t)); -} - -void plist_get_real_val(plist_t node, double *val) -{ - if (!node || !val) - return; - plist_type type = plist_get_node_type(node); - uint64_t length = 0; - if (PLIST_REAL != type) - return; - plist_get_type_and_value(node, &type, (void *) val, &length); - assert(length == sizeof(double)); -} - -void plist_get_data_val(plist_t node, char **val, uint64_t * length) -{ - if (!node || !val || !length) - return; - plist_type type = plist_get_node_type(node); - if (PLIST_DATA != type) - return; - plist_get_type_and_value(node, &type, (void *) val, length); -} - -const char* plist_get_data_ptr(plist_t node, uint64_t* length) -{ - if (!node || !length) - return NULL; - plist_type type = plist_get_node_type(node); - if (PLIST_DATA != type) - return NULL; - plist_data_t data = plist_get_data(node); - *length = data->length; - return (const char*)data->buff; -} - -void plist_get_date_val(plist_t node, int32_t * sec, int32_t * usec) -{ - if (!node) - return; - plist_type type = plist_get_node_type(node); - uint64_t length = 0; - double val = 0; - if (PLIST_DATE != type) - return; - plist_get_type_and_value(node, &type, (void *) &val, &length); - assert(length == sizeof(double)); - if (sec) - *sec = (int32_t)val; - if (usec) - { - val = fabs((val - (int64_t)val) * 1000000); - *usec = (int32_t)val; - } -} - -int plist_data_compare(const void *a, const void *b) -{ - plist_data_t val_a = NULL; - plist_data_t val_b = NULL; - - if (!a || !b) - return FALSE; - - if (!((node_t) a)->data || !((node_t) b)->data) - return FALSE; - - val_a = plist_get_data((plist_t) a); - val_b = plist_get_data((plist_t) b); - - if (val_a->type != val_b->type) - return FALSE; - - switch (val_a->type) - { - case PLIST_BOOLEAN: - case PLIST_NULL: - case PLIST_INT: - case PLIST_REAL: - case PLIST_DATE: - case PLIST_UID: - if (val_a->length != val_b->length) - return FALSE; - return val_a->intval == val_b->intval; //it is an union so this is sufficient - - case PLIST_KEY: - case PLIST_STRING: - return strcmp(val_a->strval, val_b->strval) == 0; - - case PLIST_DATA: - if (val_a->length != val_b->length) - return FALSE; - return memcmp(val_a->buff, val_b->buff, val_a->length) == 0; - - case PLIST_ARRAY: - case PLIST_DICT: - //compare pointer - return a == b; - - default: - break; - } - return FALSE; -} - -char plist_compare_node_value(plist_t node_l, plist_t node_r) -{ - return plist_data_compare(node_l, node_r); -} - -static void plist_set_element_val(plist_t node, plist_type type, const void *value, uint64_t length) -{ - //free previous allocated buffer - plist_data_t data = plist_get_data(node); - assert(data); // a node should always have data attached - - switch (data->type) - { - case PLIST_KEY: - case PLIST_STRING: - free(data->strval); - data->strval = NULL; - break; - case PLIST_DATA: - free(data->buff); - data->buff = NULL; - break; - default: - break; - } - - //now handle value - - data->type = type; - data->length = length; - - switch (type) - { - case PLIST_BOOLEAN: - data->boolval = *((char *) value); - break; - case PLIST_INT: - case PLIST_UID: - data->intval = *((uint64_t *) value); - break; - case PLIST_REAL: - case PLIST_DATE: - data->realval = *((double *) value); - break; - case PLIST_KEY: - case PLIST_STRING: - data->strval = strdup((char *) value); - break; - case PLIST_DATA: - data->buff = (uint8_t *) malloc(length); - memcpy(data->buff, value, length); - break; - case PLIST_ARRAY: - case PLIST_DICT: - default: - break; - } -} - -void plist_set_key_val(plist_t node, const char *val) -{ - plist_t father = plist_get_parent(node); - plist_t item = plist_dict_get_item(father, val); - if (item) { - return; - } - plist_set_element_val(node, PLIST_KEY, val, strlen(val)); -} - -void plist_set_string_val(plist_t node, const char *val) -{ - plist_set_element_val(node, PLIST_STRING, val, strlen(val)); -} - -void plist_set_bool_val(plist_t node, uint8_t val) -{ - plist_set_element_val(node, PLIST_BOOLEAN, &val, sizeof(uint8_t)); -} - -void plist_set_uint_val(plist_t node, uint64_t val) -{ - plist_set_element_val(node, PLIST_INT, &val, (val > INT64_MAX) ? sizeof(uint64_t)*2 : sizeof(uint64_t)); -} - -void plist_set_int_val(plist_t node, int64_t val) -{ - plist_set_element_val(node, PLIST_INT, &val, sizeof(uint64_t)); -} - -void plist_set_uid_val(plist_t node, uint64_t val) -{ - plist_set_element_val(node, PLIST_UID, &val, sizeof(uint64_t)); -} - -void plist_set_real_val(plist_t node, double val) -{ - plist_set_element_val(node, PLIST_REAL, &val, sizeof(double)); -} - -void plist_set_data_val(plist_t node, const char *val, uint64_t length) -{ - plist_set_element_val(node, PLIST_DATA, val, length); -} - -void plist_set_date_val(plist_t node, int32_t sec, int32_t usec) -{ - double val = (double)sec + (double)usec / 1000000; - plist_set_element_val(node, PLIST_DATE, &val, sizeof(struct timeval)); -} - -int plist_bool_val_is_true(plist_t boolnode) -{ - if (!PLIST_IS_BOOLEAN(boolnode)) { - return 0; - } - uint8_t bv = 0; - plist_get_bool_val(boolnode, &bv); - return (bv == 1); -} - -int plist_int_val_is_negative(plist_t intnode) -{ - if (!PLIST_IS_INT(intnode)) { - return 0; - } - plist_data_t data = plist_get_data(intnode); - if (data->length == 16) { - return 0; - } - if ((int64_t)data->intval < 0) { - return 1; - } - return 0; -} - -int plist_int_val_compare(plist_t uintnode, int64_t cmpval) -{ - if (!PLIST_IS_INT(uintnode)) { - return -1; - } - int64_t uintval = 0; - plist_get_int_val(uintnode, &uintval); - if (uintval == cmpval) { - return 0; - } - - if (uintval < cmpval) { - return -1; - } - - return 1; -} - -int plist_uint_val_compare(plist_t uintnode, uint64_t cmpval) -{ - if (!PLIST_IS_INT(uintnode)) { - return -1; - } - uint64_t uintval = 0; - plist_get_uint_val(uintnode, &uintval); - if (uintval == cmpval) { - return 0; - } - - if (uintval < cmpval) { - return -1; - } - - return 1; -} - -int plist_uid_val_compare(plist_t uidnode, uint64_t cmpval) -{ - if (!PLIST_IS_UID(uidnode)) { - return -1; - } - uint64_t uidval = 0; - plist_get_uid_val(uidnode, &uidval); - if (uidval == cmpval) { - return 0; - } - - if (uidval < cmpval) { - return -1; - } - - return 1; -} - -int plist_real_val_compare(plist_t realnode, double cmpval) -{ - if (!PLIST_IS_REAL(realnode)) { - return -1; - } - double a = 0; - double b = cmpval; - plist_get_real_val(realnode, &a); - double abs_a = fabs(a); - double abs_b = fabs(b); - double diff = fabs(a - b); - if (a == b) { - return 0; - } - - if (a == 0 || b == 0 || (abs_a + abs_b < DBL_MIN)) { - if (diff < (DBL_EPSILON * DBL_MIN)) { - return 0; - } - - if (a < b) { - return -1; - } - } else { - if ((diff / fmin(abs_a + abs_b, DBL_MAX)) < DBL_EPSILON) { - return 0; - } - - if (a < b) { - return -1; - } - } - return 1; -} - -int plist_date_val_compare(plist_t datenode, int32_t cmpsec, int32_t cmpusec) -{ - if (!PLIST_IS_DATE(datenode)) { - return -1; - } - int32_t sec = 0; - int32_t usec = 0; - plist_get_date_val(datenode, &sec, &usec); - uint64_t dateval = ((int64_t)sec << 32) | usec; - uint64_t cmpval = ((int64_t)cmpsec << 32) | cmpusec; - if (dateval == cmpval) { - return 0; - } - - if (dateval < cmpval) { - return -1; - } - - return 1; -} - -int plist_string_val_compare(plist_t strnode, const char* cmpval) -{ - if (!PLIST_IS_STRING(strnode)) { - return -1; - } - plist_data_t data = plist_get_data(strnode); - return strcmp(data->strval, cmpval); -} - -int plist_string_val_compare_with_size(plist_t strnode, const char* cmpval, size_t n) -{ - if (!PLIST_IS_STRING(strnode)) { - return -1; - } - plist_data_t data = plist_get_data(strnode); - return strncmp(data->strval, cmpval, n); -} - -int plist_string_val_contains(plist_t strnode, const char* substr) -{ - if (!PLIST_IS_STRING(strnode)) { - return 0; - } - plist_data_t data = plist_get_data(strnode); - return (strstr(data->strval, substr) != NULL); -} - -int plist_key_val_compare(plist_t keynode, const char* cmpval) -{ - if (!PLIST_IS_KEY(keynode)) { - return -1; - } - plist_data_t data = plist_get_data(keynode); - return strcmp(data->strval, cmpval); -} - -int plist_key_val_compare_with_size(plist_t keynode, const char* cmpval, size_t n) -{ - if (!PLIST_IS_KEY(keynode)) { - return -1; - } - plist_data_t data = plist_get_data(keynode); - return strncmp(data->strval, cmpval, n); -} - -int plist_key_val_contains(plist_t keynode, const char* substr) -{ - if (!PLIST_IS_KEY(keynode)) { - return 0; - } - plist_data_t data = plist_get_data(keynode); - return (strstr(data->strval, substr) != NULL); -} - -int plist_data_val_compare(plist_t datanode, const uint8_t* cmpval, size_t n) -{ - if (!PLIST_IS_DATA(datanode)) { - return -1; - } - plist_data_t data = plist_get_data(datanode); - if (data->length < n) { - return -1; - } - - if (data->length > n) { - return 1; - } - - return memcmp(data->buff, cmpval, n); -} - -int plist_data_val_compare_with_size(plist_t datanode, const uint8_t* cmpval, size_t n) -{ - if (!PLIST_IS_DATA(datanode)) { - return -1; - } - plist_data_t data = plist_get_data(datanode); - if (data->length < n) { - return -1; - } - return memcmp(data->buff, cmpval, n); -} - -int plist_data_val_contains(plist_t datanode, const uint8_t* cmpval, size_t n) -{ - if (!PLIST_IS_DATA(datanode)) { - return -1; - } - plist_data_t data = plist_get_data(datanode); - return (memmem(data->buff, data->length, cmpval, n) != NULL); -} - -extern void plist_xml_set_debug(int debug); -extern void plist_bin_set_debug(int debug); -extern void plist_json_set_debug(int debug); -extern void plist_ostep_set_debug(int debug); - -void plist_set_debug(int debug) -{ -#if DEBUG - plist_debug = debug; -#endif - plist_xml_set_debug(debug); - plist_bin_set_debug(debug); - plist_json_set_debug(debug); - plist_ostep_set_debug(debug); -} - -void plist_sort(plist_t plist) -{ - if (!plist) { - return; - } - if (PLIST_IS_ARRAY(plist)) { - uint32_t n = plist_array_get_size(plist); - uint32_t i = 0; - for (i = 0; i < n; i++) { - plist_sort(plist_array_get_item(plist, i)); - } - } else if (PLIST_IS_DICT(plist)) { - node_t node = (node_t)plist; - node_t ch; - if (!node_first_child(node)) { - return; - } - for (ch = node_first_child(node); ch; ch = node_next_sibling(ch)) { - ch = node_next_sibling(ch); - plist_sort((plist_t)ch); - } - #define KEY_DATA(x) (x->data) - #define NEXT_KEY(x) (x->next->next) - #define KEY_STRVAL(x) ((plist_data_t)(KEY_DATA(x)))->strval - int swapped = 0; - do { - swapped = 0; - node_t lptr = NULL; - node_t cur_key = node_first_child((node_t)plist); - - while (NEXT_KEY(cur_key) != lptr) { - node_t next_key = NEXT_KEY(cur_key); - if (strcmp(KEY_STRVAL(cur_key), KEY_STRVAL(next_key)) > 0) { - node_t cur_val = cur_key->next; - node_t next_val = next_key->next; - // we need to swap 2 consecutive nodes with the 2 after them - // a -> b -> [c] -> [d] -> [e] -> [f] -> g -> h - // cur next - // swapped: - // a -> b -> [e] -> [f] -> [c] -> [d] -> g -> h - // next cur - node_t tmp_prev = cur_key->prev; - node_t tmp_next = next_val->next; - cur_key->prev = next_val; - cur_val->next = tmp_next; - next_val->next = cur_key; - next_key->prev = tmp_prev; - if (tmp_prev) { - tmp_prev->next = next_key; - } else { - ((node_t)plist)->children->begin = next_key; - } - if (tmp_next) { - tmp_next->prev = cur_val; - } else { - ((node_t)plist)->children->end = cur_val; - } - cur_key = next_key; - swapped = 1; - } - cur_key = NEXT_KEY(cur_key); - } - lptr = cur_key; - } while (swapped); - } -} - -plist_err_t plist_write_to_string(plist_t plist, char **output, uint32_t* length, plist_format_t format, plist_write_options_t options) -{ - plist_err_t err = PLIST_ERR_UNKNOWN; - switch (format) { - case PLIST_FORMAT_XML: - err = plist_to_xml(plist, output, length); - break; - case PLIST_FORMAT_JSON: - err = plist_to_json(plist, output, length, ((options & PLIST_OPT_COMPACT) == 0)); - break; - case PLIST_FORMAT_OSTEP: - err = plist_to_openstep(plist, output, length, ((options & PLIST_OPT_COMPACT) == 0)); - break; - case PLIST_FORMAT_PRINT: - err = plist_write_to_string_default(plist, output, length, options); - break; - case PLIST_FORMAT_LIMD: - err = plist_write_to_string_limd(plist, output, length, options); - break; - case PLIST_FORMAT_PLUTIL: - err = plist_write_to_string_plutil(plist, output, length, options); - break; - default: - // unsupported output format - err = PLIST_ERR_FORMAT; - break; - } - return err; -} - -plist_err_t plist_write_to_stream(plist_t plist, FILE *stream, plist_format_t format, plist_write_options_t options) -{ - if (!plist || !stream) { - return PLIST_ERR_INVALID_ARG; - } - plist_err_t err = PLIST_ERR_UNKNOWN; - char *output = NULL; - uint32_t length = 0; - switch (format) { - case PLIST_FORMAT_BINARY: - err = plist_to_bin(plist, &output, &length); - break; - case PLIST_FORMAT_XML: - err = plist_to_xml(plist, &output, &length); - break; - case PLIST_FORMAT_JSON: - err = plist_to_json(plist, &output, &length, ((options & PLIST_OPT_COMPACT) == 0)); - break; - case PLIST_FORMAT_OSTEP: - err = plist_to_openstep(plist, &output, &length, ((options & PLIST_OPT_COMPACT) == 0)); - break; - case PLIST_FORMAT_PRINT: - err = plist_write_to_stream_default(plist, stream, options); - break; - case PLIST_FORMAT_LIMD: - err = plist_write_to_stream_limd(plist, stream, options); - break; - case PLIST_FORMAT_PLUTIL: - err = plist_write_to_stream_plutil(plist, stream, options); - break; - default: - // unsupported output format - err = PLIST_ERR_FORMAT; - break; - } - if (output && err == PLIST_ERR_SUCCESS) { - if (fwrite(output, 1, length, stream) < length) { - err = PLIST_ERR_IO; - } - free(output); - } - return err; -} - -plist_err_t plist_write_to_file(plist_t plist, const char* filename, plist_format_t format, plist_write_options_t options) -{ - if (!plist || !filename) { - return PLIST_ERR_INVALID_ARG; - } - FILE* f = fopen(filename, "wb"); - if (!f) { - return PLIST_ERR_IO; - } - plist_err_t err = plist_write_to_stream(plist, f, format, options); - fclose(f); - return err; -} - -void plist_print(plist_t plist) -{ - plist_write_to_stream(plist, stdout, PLIST_FORMAT_PRINT, PLIST_OPT_PARTIAL_DATA); -} - -const char* libplist_version() -{ -#ifndef PACKAGE_VERSION -#error PACKAGE_VERSION is not defined! -#endif - return PACKAGE_VERSION; -} - - diff --git a/vmax2bella.cpp b/vmax2bella.cpp index ebad386..4ec0ef7 100644 --- a/vmax2bella.cpp +++ b/vmax2bella.cpp @@ -173,8 +173,9 @@ The 't' field in the snapshot's 's.id' dictionary indicates the type of snapshot #include // For input/output operations (cout, cin, etc.) // Bella SDK includes - external libraries for 3D rendering -#include "../bella_scene_sdk/src/bella_sdk/bella_scene.h" // For creating and manipulating 3D scenes in Bella -#include "../bella_scene_sdk/src/dl_core/dl_main.inl" // Core functionality from the Diffuse Logic engine +#include "../bella_engine_sdk/src/bella_sdk/bella_scene.h" // For creating and manipulating 3D scenes in Bella +#include "../bella_engine_sdk/src/bella_sdk/bella_engine.h" // For Engine class and rendering functionality +#include "../bella_engine_sdk/src/dl_core/dl_main.inl" // Core functionality from the Diffuse Logic engine #ifdef _WIN32 #include // For ShellExecuteW