diff --git a/.codecov.yml b/.codecov.yml new file mode 100644 index 000000000..191144aae --- /dev/null +++ b/.codecov.yml @@ -0,0 +1,6 @@ +coverage: + status: + project: + default: + target: 60% + threshold: 2% diff --git a/.github/actions/xahau-ga-build/action.yml b/.github/actions/xahau-ga-build/action.yml index b4e8a6d11..242e5be19 100644 --- a/.github/actions/xahau-ga-build/action.yml +++ b/.github/actions/xahau-ga-build/action.yml @@ -2,6 +2,14 @@ name: build description: 'Builds the project with ccache integration' inputs: + cmake-target: + description: 'CMake target to build' + required: false + default: all + cmake-args: + description: 'Additional CMake arguments' + required: false + default: null generator: description: 'CMake generator to use' required: true @@ -20,6 +28,10 @@ inputs: description: 'C++ compiler to use' required: false default: '' + gcov: + description: 'Gcov to use' + required: false + default: '' compiler-id: description: 'Unique identifier: compiler-version-stdlib[-gccversion] (e.g. clang-14-libstdcxx-gcc11, gcc-13-libstdcxx)' required: false @@ -41,10 +53,11 @@ inputs: required: false default: 'dev' stdlib: - description: 'C++ standard library to use' + description: 'C++ standard library to use (default = compiler default, e.g. GCC always uses libstdc++)' required: true type: choice options: + - default - libstdcxx - libcxx clang_gcc_toolchain: @@ -87,11 +100,6 @@ runs: export CCACHE_CONFIGPATH="$HOME/.config/ccache/ccache.conf" echo "CCACHE_CONFIGPATH=$CCACHE_CONFIGPATH" >> $GITHUB_ENV - # Keep config separate from cache_dir so configs aren't swapped when CCACHE_DIR changes between steps - mkdir -p ~/.config/ccache - export CCACHE_CONFIGPATH="$HOME/.config/ccache/ccache.conf" - echo "CCACHE_CONFIGPATH=$CCACHE_CONFIGPATH" >> $GITHUB_ENV - # Configure ccache settings AFTER cache restore (prevents stale cached config) ccache --set-config=max_size=${{ inputs.ccache_max_size }} ccache --set-config=hash_dir=${{ inputs.ccache_hash_dir }} @@ -122,6 +130,10 @@ runs: export CXX="${{ inputs.cxx }}" fi + if [ -n "${{ inputs.gcov }}" ]; then + ln -sf /usr/bin/${{ inputs.gcov }} /usr/local/bin/gcov + fi + # Create wrapper toolchain that overlays ccache on top of Conan's toolchain # This enables ccache for the main app build without affecting Conan dependency builds if [ "${{ inputs.ccache_enabled }}" = "true" ]; then @@ -185,7 +197,8 @@ runs: -DCMAKE_TOOLCHAIN_FILE:FILEPATH=${TOOLCHAIN_FILE} \ -DCMAKE_BUILD_TYPE=${{ inputs.configuration }} \ -Dtests=TRUE \ - -Dxrpld=TRUE + -Dxrpld=TRUE \ + ${{ inputs.cmake-args }} - name: Show ccache config before build if: inputs.ccache_enabled == 'true' @@ -209,7 +222,7 @@ runs: VERBOSE_FLAG="-- -v" fi - cmake --build . --config ${{ inputs.configuration }} --parallel $(nproc) ${VERBOSE_FLAG} + cmake --build . --config ${{ inputs.configuration }} --parallel $(nproc) --target ${{ inputs.cmake-target }} ${VERBOSE_FLAG} - name: Show ccache statistics if: inputs.ccache_enabled == 'true' diff --git a/.github/workflows/check-genesis-hooks.yml b/.github/workflows/check-genesis-hooks.yml new file mode 100644 index 000000000..8b6590733 --- /dev/null +++ b/.github/workflows/check-genesis-hooks.yml @@ -0,0 +1,107 @@ +name: Check Genesis Hooks + +on: + push: + pull_request: + +jobs: + check-genesis-hooks: + runs-on: ubuntu-24.04 + env: + CLANG_VERSION: 18 + name: Verify xahau.h is in sync with genesis hooks + + steps: + - name: Checkout repository + uses: actions/checkout@v6 + + # Install binaryen from GitHub Releases (pinned to version 100) + - name: Install binaryen (version 100) + run: | + curl -LO https://github.com/WebAssembly/binaryen/releases/download/version_100/binaryen-version_100-x86_64-linux.tar.gz + tar -xzf binaryen-version_100-x86_64-linux.tar.gz + sudo cp binaryen-version_100/bin/* /usr/local/bin/ + wasm-opt --version + + - name: Install clang-format + run: | + codename=$( lsb_release --codename --short ) + sudo tee /etc/apt/sources.list.d/llvm.list >/dev/null <> $GITHUB_PATH + wasmcc -v || true + + # Build and install hook-cleaner tool + - name: Build and install hook-cleaner + run: | + git clone https://github.com/richardah/hook-cleaner-c.git /tmp/hook-cleaner + cd /tmp/hook-cleaner + make + cp hook-cleaner /usr/local/bin/ + chmod +x /usr/local/bin/hook-cleaner + + # Build and install guard_checker tool + - name: Build and install guard_checker + run: | + cd include/xrpl/hook + make + cp guard_checker /usr/local/bin/ + chmod +x /usr/local/bin/guard_checker + + # Verify all required tools are available + - name: Verify required tools + run: | + echo "Checking tool availability..." + command -v wasmcc || (echo "Error: wasmcc not found" && exit 1) + command -v wasm-opt || (echo "Error: wasm-opt not found" && exit 1) + command -v hook-cleaner || (echo "Error: hook-cleaner not found" && exit 1) + command -v guard_checker || (echo "Error: guard_checker not found" && exit 1) + command -v xxd || (echo "Error: xxd not found" && exit 1) + command -v clang-format || (echo "Error: clang-format not found" && exit 1) + echo "All tools verified successfully" + + # Execute build script to regenerate xahau.h + - name: Run build_xahau_h.sh + run: | + cd hook/genesis + ./build_xahau_h.sh + + # Check if xahau.h has changed (fail if out of sync) + - name: Verify xahau.h is in sync + run: | + if ! git diff --exit-code include/xrpl/hook/xahau.h; then + echo "" + echo "❌ ERROR: xahau.h is out of sync with genesis hooks" + echo "" + echo "The generated xahau.h differs from the committed version." + echo "Please run the following command and commit the changes:" + echo "" + echo " cd hook/genesis && ./build_xahau_h.sh" + echo "" + echo "Diff:" + git diff include/xrpl/hook/xahau.h + exit 1 + fi + echo "✅ xahau.h is in sync with genesis hooks" diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml index c17607612..107b32fbf 100644 --- a/.github/workflows/clang-format.yml +++ b/.github/workflows/clang-format.yml @@ -20,7 +20,7 @@ jobs: sudo apt-get update sudo apt-get install clang-format-${CLANG_VERSION} - name: Format first-party sources - run: find include src -type f \( -name '*.cpp' -o -name '*.hpp' -o -name '*.h' -o -name '*.ipp' \) -not -path "src/magic/magic_enum.h" -exec clang-format-${CLANG_VERSION} -i {} + + run: find include src -type f \( -name '*.cpp' -o -name '*.hpp' -o -name '*.h' -o -name '*.ipp' \) -exec clang-format-${CLANG_VERSION} -i {} + - name: Check for differences id: assert run: | diff --git a/.github/workflows/verify-generated-headers.yml b/.github/workflows/verify-generated-headers.yml index 861d1d2a1..2d682fb58 100644 --- a/.github/workflows/verify-generated-headers.yml +++ b/.github/workflows/verify-generated-headers.yml @@ -18,6 +18,10 @@ jobs: generator: bash ./hook/generate_sfcodes.sh - target: hook/tts.h generator: ./hook/generate_tts.sh + - target: hook/ls_flags.h + generator: ./hook/generate_lsflags.sh + - target: hook/tx_flags.h + generator: ./hook/generate_txflags.sh runs-on: ubuntu-24.04 env: CLANG_VERSION: 18 diff --git a/.github/workflows/xahau-ga-nix.yml b/.github/workflows/xahau-ga-nix.yml index efce25092..d473630a0 100644 --- a/.github/workflows/xahau-ga-nix.yml +++ b/.github/workflows/xahau-ga-nix.yml @@ -57,8 +57,9 @@ jobs: "cc": "gcc-11", "cxx": "g++-11", "compiler_version": 11, - "stdlib": "libstdcxx", - "configuration": "Debug" + "stdlib": "default", + "configuration": "Debug", + "job_type": "build" }, { "compiler_id": "gcc-13-libstdcxx", @@ -66,8 +67,20 @@ jobs: "cc": "gcc-13", "cxx": "g++-13", "compiler_version": 13, - "stdlib": "libstdcxx", - "configuration": "Debug" + "stdlib": "default", + "configuration": "Debug", + "job_type": "build" + }, + { + "compiler_id": "gcc-13-libstdcxx", + "compiler": "gcc", + "cc": "gcc-13", + "cxx": "g++-13", + "gcov": "gcov-13", + "compiler_version": 13, + "stdlib": "default", + "configuration": "Debug", + "job_type": "coverage" }, { "compiler_id": "clang-14-libstdcxx-gcc11", @@ -77,7 +90,8 @@ jobs: "compiler_version": 14, "stdlib": "libstdcxx", "clang_gcc_toolchain": 11, - "configuration": "Debug" + "configuration": "Debug", + "job_type": "build" }, { "compiler_id": "clang-16-libstdcxx-gcc13", @@ -87,7 +101,8 @@ jobs: "compiler_version": 16, "stdlib": "libstdcxx", "clang_gcc_toolchain": 13, - "configuration": "Debug" + "configuration": "Debug", + "job_type": "build" }, { "compiler_id": "clang-17-libcxx", @@ -96,7 +111,8 @@ jobs: "cxx": "clang++-17", "compiler_version": 17, "stdlib": "libcxx", - "configuration": "Debug" + "configuration": "Debug", + "job_type": "build" }, { # Clang 18 - testing if it's faster than Clang 17 with libc++ @@ -107,14 +123,16 @@ jobs: "cxx": "clang++-18", "compiler_version": 18, "stdlib": "libcxx", - "configuration": "Debug" + "configuration": "Debug", + "job_type": "build" } ] # Minimal matrix for PRs and feature branches minimal_matrix = [ full_matrix[1], # gcc-13 (middle-ground gcc) - full_matrix[2] # clang-14 (mature, stable clang) + full_matrix[2], # gcc-13 coverage + full_matrix[3] # clang-14 (mature, stable clang) ] # Determine which matrix to use based on the target branch @@ -189,14 +207,21 @@ jobs: # Select the appropriate matrix if use_full: if force_full: - print(f"Using FULL matrix (6 configs) - forced by [ci-nix-full-matrix] tag") + print(f"Using FULL matrix (7 configs) - forced by [ci-nix-full-matrix] tag") else: - print(f"Using FULL matrix (6 configs) - targeting main branch") + print(f"Using FULL matrix (7 configs) - targeting main branch") matrix = full_matrix else: - print(f"Using MINIMAL matrix (2 configs) - feature branch/PR") + print(f"Using MINIMAL matrix (3 configs) - feature branch/PR") matrix = minimal_matrix - + + # Add runs_on based on job_type + for entry in matrix: + if entry.get("job_type") == "coverage": + entry["runs_on"] = '["self-hosted", "generic", 24.04]' + else: + entry["runs_on"] = '["self-hosted", "generic", 20.04]' + # Output the matrix as JSON output = json.dumps({"include": matrix}) with open(os.environ['GITHUB_OUTPUT'], 'a') as f: @@ -204,7 +229,10 @@ jobs: build: needs: matrix-setup - runs-on: [self-hosted, generic, 20.04] + runs-on: ${{ fromJSON(matrix.runs_on) }} + permissions: + id-token: write + contents: read container: image: ubuntu:24.04 volumes: @@ -233,7 +261,7 @@ jobs: apt-get install -y software-properties-common add-apt-repository ppa:ubuntu-toolchain-r/test -y apt-get update - apt-get install -y python3 python-is-python3 pipx + apt-get install -y git python3 python-is-python3 pipx pipx ensurepath apt-get install -y cmake ninja-build ${{ matrix.cc }} ${{ matrix.cxx }} ccache apt-get install -y perl # for openssl build @@ -304,6 +332,12 @@ jobs: pipx install "conan>=2.0,<3" echo "$HOME/.local/bin" >> $GITHUB_PATH + # Install gcovr for coverage jobs + if [ "${{ matrix.job_type }}" = "coverage" ]; then + pipx install "gcovr>=7,<9" + apt-get install -y curl lcov + fi + - name: Check environment run: | echo "PATH:" @@ -313,6 +347,13 @@ jobs: which ${{ matrix.cc }} && ${{ matrix.cc }} --version || echo "${{ matrix.cc }} not found" which ${{ matrix.cxx }} && ${{ matrix.cxx }} --version || echo "${{ matrix.cxx }} not found" which ccache && ccache --version || echo "ccache not found" + + # Check gcovr for coverage jobs + if [ "${{ matrix.job_type }}" = "coverage" ]; then + which gcov && gcov --version || echo "gcov not found" + which gcovr && gcovr --version || echo "gcovr not found" + fi + echo "---- Full Environment ----" env @@ -340,6 +381,7 @@ jobs: gha_cache_enabled: 'false' # Disable caching for self hosted runner - name: Build + if: matrix.job_type == 'build' uses: ./.github/actions/xahau-ga-build with: generator: Ninja @@ -354,7 +396,27 @@ jobs: clang_gcc_toolchain: ${{ matrix.clang_gcc_toolchain || '' }} ccache_max_size: '100G' + - name: Build (Coverage) + if: matrix.job_type == 'coverage' + uses: ./.github/actions/xahau-ga-build + with: + generator: Ninja + configuration: ${{ matrix.configuration }} + build_dir: ${{ env.build_dir }} + cc: ${{ matrix.cc }} + cxx: ${{ matrix.cxx }} + gcov: ${{ matrix.gcov }} + compiler-id: ${{ matrix.compiler_id }} + cache_version: ${{ env.CACHE_VERSION }} + main_branch: ${{ env.MAIN_BRANCH_NAME }} + stdlib: ${{ matrix.stdlib }} + # Coverage builds are slower due to instrumentation; use fewer parallel jobs to avoid flakiness + cmake-args: '-Dcoverage=ON -Dcoverage_format=xml -Dcoverage_test_parallelism=$(($(nproc)/2)) -DCODE_COVERAGE_VERBOSE=ON -DCMAKE_CXX_FLAGS="-O0" -DCMAKE_C_FLAGS="-O0"' + cmake-target: 'coverage' + ccache_max_size: '100G' + - name: Set artifact name + if: matrix.job_type == 'build' id: set-artifact-name run: | ARTIFACT_NAME="build-output-nix-${{ github.run_id }}-${{ matrix.compiler }}-${{ matrix.configuration }}" @@ -367,6 +429,7 @@ jobs: ls -la ${{ env.build_dir }} || echo "Build directory not found or empty" - name: Run tests + if: matrix.job_type == 'build' run: | # Ensure the binary exists before trying to run if [ -f "${{ env.build_dir }}/rippled" ]; then @@ -375,3 +438,29 @@ jobs: echo "Error: rippled executable not found in ${{ env.build_dir }}" exit 1 fi + + # Coverage-specific steps + - name: Move coverage report + if: matrix.job_type == 'coverage' + shell: bash + run: | + mv "${{ env.build_dir }}/coverage.xml" ./ + + - name: Archive coverage report + if: matrix.job_type == 'coverage' + uses: actions/upload-artifact@v4 + with: + name: coverage.xml + path: coverage.xml + retention-days: 30 + + - name: Upload coverage report + if: matrix.job_type == 'coverage' + uses: codecov/codecov-action@v5 + with: + files: coverage.xml + fail_ci_if_error: true + disable_search: true + verbose: true + plugins: noop + use_oidc: true diff --git a/CMakeLists.txt b/CMakeLists.txt index e7cb9ddc4..532ad14d8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -122,6 +122,7 @@ endif() find_package(nudb REQUIRED) find_package(date REQUIRED) find_package(xxHash REQUIRED) +find_package(magic_enum REQUIRED) include(deps/WasmEdge) if(TARGET nudb::core) diff --git a/cmake/CodeCoverage.cmake b/cmake/CodeCoverage.cmake index d2af481d8..d6323c5cc 100644 --- a/cmake/CodeCoverage.cmake +++ b/cmake/CodeCoverage.cmake @@ -380,6 +380,7 @@ function(setup_target_for_coverage_gcovr) ${GCOVR_PATH} --gcov-executable ${GCOV_TOOL} --gcov-ignore-parse-errors=negative_hits.warn_once_per_file + --gcov-ignore-parse-errors=suspicious_hits.warn_once_per_file -r ${BASEDIR} ${GCOVR_ADDITIONAL_ARGS} ${GCOVR_EXCLUDE_ARGS} diff --git a/cmake/RippledCore.cmake b/cmake/RippledCore.cmake index f4b070e0f..2d593599c 100644 --- a/cmake/RippledCore.cmake +++ b/cmake/RippledCore.cmake @@ -54,6 +54,7 @@ add_library(xrpl.imports.main INTERFACE) target_link_libraries(xrpl.imports.main INTERFACE LibArchive::LibArchive + magic_enum::magic_enum OpenSSL::Crypto Ripple::boost wasmedge::wasmedge diff --git a/conanfile.py b/conanfile.py index ffbae750d..ccf8332a5 100644 --- a/conanfile.py +++ b/conanfile.py @@ -29,6 +29,7 @@ class Xrpl(ConanFile): 'date/3.0.3', 'grpc/1.50.1', 'libarchive/3.7.6', + 'magic_enum/0.9.5', 'nudb/2.0.8', 'openssl/3.6.0', 'soci/4.0.3@xahaud/stable', diff --git a/hook/generate_lsflags.sh b/hook/generate_lsflags.sh new file mode 100755 index 000000000..50a69e8b8 --- /dev/null +++ b/hook/generate_lsflags.sh @@ -0,0 +1,82 @@ +#!/bin/bash +set -eu + +SCRIPT_DIR=$(dirname "$0") +SCRIPT_DIR=$(cd "$SCRIPT_DIR" && pwd) + +RIPPLED_ROOT="$SCRIPT_DIR/../include/xrpl" +LEDGER_FORMATS="$RIPPLED_ROOT/protocol/LedgerFormats.h" + +echo '// Generated using generate_lsflags.sh' +echo '' +echo '#ifndef HOOKLSFLAGS_INCLUDED' +echo '#define HOOKLSFLAGS_INCLUDED 1' +echo '' +awk ' + function ltrim(s) { sub(/^[[:space:]]+/, "", s); return s } + function rtrim(s) { sub(/[[:space:]]+$/, "", s); return s } + function trim(s) { return rtrim(ltrim(s)) } + + function flush_group() { + if (entry_count > 0 && group != "") { + printf "enum %s {\n", group + for (i = 1; i <= entry_count; i++) { + printf " %s,\n", entries[i] + } + printf "};\n" + } + delete entries + entry_count = 0 + } + + /enum LedgerSpecificFlags \{/ { inside = 1; next } + inside && /^\};/ { inside = 0; flush_group(); next } + !inside { next } + + # Group header comments: // ltFOO or // remarks + /^[[:space:]]*\/\/[[:space:]]*(lt[A-Z_]+|remarks)[[:space:]]*$/ { + flush_group() + line = $0 + sub(/.*\/\/[[:space:]]*/, "", line) + group = trim(line) + next + } + + # Skip pure comment lines (not group headers) + /^[[:space:]]*\/\// { next } + + # Skip blank lines + /^[[:space:]]*$/ { next } + + # Accumulate flag lines (handle multi-line values) + { + line = $0 + # Strip inline comments + sub(/\/\/.*/, "", line) + line = trim(line) + if (line == "") next + + if (pending != "") { + pending = pending " " line + } else { + pending = line + } + + # If line ends with comma, the entry is complete + if (pending ~ /,$/) { + # Remove trailing comma + sub(/,$/, "", pending) + entries[++entry_count] = pending + pending = "" + } + } + + BEGIN { + inside = 0 + group = "" + pending = "" + entry_count = 0 + } +' "$LEDGER_FORMATS" +echo '' +echo '#endif // HOOKLSFLAGS_INCLUDED' diff --git a/hook/generate_txflags.sh b/hook/generate_txflags.sh new file mode 100755 index 000000000..f20fcac66 --- /dev/null +++ b/hook/generate_txflags.sh @@ -0,0 +1,25 @@ +#!/bin/bash +set -eu + +SCRIPT_DIR=$(dirname "$0") +SCRIPT_DIR=$(cd "$SCRIPT_DIR" && pwd) + +RIPPLED_ROOT="$SCRIPT_DIR/../include/xrpl" +TX_FLAGS="$RIPPLED_ROOT/protocol/TxFlags.h" + +echo '// Generated using generate_txflags.sh' +echo '#include "ls_flags.h"' +echo '#include ' +echo '' +cat "$TX_FLAGS" | + awk ' + /^[[:space:]]*enum / { + if (count > 0) print "" + inside = 1 + count++ + } + inside { + print + if (/};/) inside = 0 + } + ' diff --git a/hook/genesis/build_xahau_h.sh b/hook/genesis/build_xahau_h.sh new file mode 100755 index 000000000..08e1547fe --- /dev/null +++ b/hook/genesis/build_xahau_h.sh @@ -0,0 +1,203 @@ +#!/bin/bash + +# build_xahau_h.sh +# Builds genesis hook WASMs and updates xahau.h with hex arrays + +set -euo pipefail + +# Color codes for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Script directory and path constants +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +XAHAU_H="${SCRIPT_DIR}/../../include/xrpl/hook/xahau.h" +TEMP_DIR="${SCRIPT_DIR}/.temp" + +# Hook file mappings (space-separated: name:file) +HOOK_FILES=( + "GovernanceHook:govern.wasm" + "RewardHook:reward.wasm" + # "MintHook:mint.wasm" +) + +# Cleanup function +cleanup() { + local exit_code=$? + if [ ${exit_code} -eq 0 ] && [ -d "${TEMP_DIR}" ]; then + rm -rf "${TEMP_DIR}" + elif [ ${exit_code} -ne 0 ]; then + echo -e "${RED}Error: Script failed with exit code ${exit_code}${NC}" >&2 + if [ -d "${TEMP_DIR}" ]; then + echo -e "${YELLOW}Temp files preserved at: ${TEMP_DIR}${NC}" >&2 + fi + fi + exit ${exit_code} +} + +trap cleanup EXIT INT TERM + +# Tool verification +echo -e "${BLUE}==> Checking required tools...${NC}" +REQUIRED_TOOLS=("make" "xxd" "sed" "clang-format" "wasm-opt") +for tool in "${REQUIRED_TOOLS[@]}"; do + if ! command -v "${tool}" &> /dev/null; then + echo -e "${RED}Error: Required tool '${tool}' not found${NC}" >&2 + exit 1 + fi + echo -e "${GREEN} ✓ ${tool}${NC}" +done + +# Verify wasm-opt version is exactly 100 +WASM_OPT_VERSION=$(wasm-opt --version | grep -oE '[0-9]+' | head -1) +if [ "${WASM_OPT_VERSION}" != "100" ]; then + echo -e "${RED}Error: wasm-opt version must be 100, but found ${WASM_OPT_VERSION}${NC}" >&2 + exit 1 +fi +echo -e "${GREEN} ✓ wasm-opt version 100${NC}" + +# Verify xahau.h exists +if [ ! -f "${XAHAU_H}" ]; then + echo -e "${RED}Error: xahau.h not found at ${XAHAU_H}${NC}" >&2 + exit 1 +fi + +# Create temp directory +mkdir -p "${TEMP_DIR}" + +# Build all WASM files +echo -e "${BLUE}==> Building WASM files with 'make all'...${NC}" +cd "${SCRIPT_DIR}" +make all +echo -e "${GREEN} Build completed successfully${NC}" + +# Function to convert WASM to hex array +wasm_to_hex_array() { + local wasm_file="$1" + local indent=" " + + if [ ! -f "${wasm_file}" ]; then + echo -e "${RED}Error: WASM file not found: ${wasm_file}${NC}" >&2 + return 1 + fi + + # Convert to hex with xxd, format with sed + xxd -p -u -c 10 "${wasm_file}" | \ + sed 's/../0x&U,/g' | \ + sed "s/^/${indent}/g" | \ + sed '$ s/,$//' +} + +# Function to update hook array in xahau.h +update_hook_array() { + local hook_name="$1" + local hex_array="$2" + local temp_file="${TEMP_DIR}/xahau.h.tmp" + + echo -e "${BLUE}==> Updating ${hook_name}...${NC}" + + # Check if hook already exists + if grep -q "static const std::vector ${hook_name} = {" "${XAHAU_H}"; then + echo -e "${YELLOW} Replacing existing ${hook_name}${NC}" + + # Use awk to replace the array content + awk -v hook="${hook_name}" -v hex="${hex_array}" ' + BEGIN { in_array=0 } + { + if ($0 ~ "static const std::vector " hook " = {") { + print $0 + print hex + in_array=1 + next + } + if (in_array && $0 ~ /};/) { + print "};" + in_array=0 + next + } + if (!in_array) { + print $0 + } + } + ' "${XAHAU_H}" > "${temp_file}" + + mv "${temp_file}" "${XAHAU_H}" + else + echo -e "${YELLOW} Adding new ${hook_name}${NC}" + + # Find the position before #endif and add the new hook + awk -v hook="${hook_name}" -v hex="${hex_array}" ' + { + if ($0 ~ /#endif.*XAHAU_GENESIS_HOOKS/) { + print "" + print "static const std::vector " hook " = {" + print hex + print "};" + print "" + print $0 + } else { + print $0 + } + } + ' "${XAHAU_H}" > "${temp_file}" + + mv "${temp_file}" "${XAHAU_H}" + fi + + echo -e "${GREEN} ✓ ${hook_name} updated${NC}" +} + +# Process each hook +for hook_entry in "${HOOK_FILES[@]}"; do + hook_name="${hook_entry%%:*}" + wasm_file="${SCRIPT_DIR}/${hook_entry##*:}" + + echo -e "${BLUE}==> Converting ${wasm_file} to hex array...${NC}" + hex_array=$(wasm_to_hex_array "${wasm_file}") + + if [ $? -ne 0 ]; then + echo -e "${RED}Error: Failed to convert ${wasm_file}${NC}" >&2 + exit 1 + fi + + echo -e "${GREEN} Conversion successful ($(echo "${hex_array}" | wc -l) lines)${NC}" + + update_hook_array "${hook_name}" "${hex_array}" +done + +# Format with clang-format +echo -e "${BLUE}==> Formatting with clang-format...${NC}" +cp "${XAHAU_H}" "${TEMP_DIR}/xahau.h.before_format" +clang-format -i "${XAHAU_H}" +echo -e "${GREEN} Formatting completed${NC}" + +# Verification +echo -e "${BLUE}==> Verifying changes...${NC}" +for hook_entry in "${HOOK_FILES[@]}"; do + hook_name="${hook_entry%%:*}" + if grep -q "static const std::vector ${hook_name} = {" "${XAHAU_H}"; then + echo -e "${GREEN} ✓ ${hook_name} found in xahau.h${NC}" + else + echo -e "${RED} ✗ ${hook_name} NOT found in xahau.h${NC}" >&2 + exit 1 + fi +done + +# Show summary +echo "" +echo -e "${GREEN}========================================${NC}" +echo -e "${GREEN}Successfully updated xahau.h${NC}" +echo -e "${GREEN}========================================${NC}" +echo -e "Updated hooks:" +for hook_entry in "${HOOK_FILES[@]}"; do + hook_name="${hook_entry%%:*}" + wasm_file="${SCRIPT_DIR}/${hook_entry##*:}" + size=$(wc -c < "${wasm_file}" | tr -d ' ') + echo -e " - ${hook_name}: ${size} bytes" +done +echo "" +echo -e "File location: ${XAHAU_H}" +echo "" diff --git a/hook/genesis/headers/error.h b/hook/genesis/headers/error.h new file mode 100644 index 000000000..d423cfbbf --- /dev/null +++ b/hook/genesis/headers/error.h @@ -0,0 +1,46 @@ +// For documentation please see: https://xrpl-hooks.readme.io/reference/ +// Generated using generate_error.sh +#ifndef HOOK_ERROR_CODES +#define SUCCESS 0 +#define OUT_OF_BOUNDS -1 +#define INTERNAL_ERROR -2 +#define TOO_BIG -3 +#define TOO_SMALL -4 +#define DOESNT_EXIST -5 +#define NO_FREE_SLOTS -6 +#define INVALID_ARGUMENT -7 +#define ALREADY_SET -8 +#define PREREQUISITE_NOT_MET -9 +#define FEE_TOO_LARGE -10 +#define EMISSION_FAILURE -11 +#define TOO_MANY_NONCES -12 +#define TOO_MANY_EMITTED_TXN -13 +#define NOT_IMPLEMENTED -14 +#define INVALID_ACCOUNT -15 +#define GUARD_VIOLATION -16 +#define INVALID_FIELD -17 +#define PARSE_ERROR -18 +#define RC_ROLLBACK -19 +#define RC_ACCEPT -20 +#define NO_SUCH_KEYLET -21 +#define NOT_AN_ARRAY -22 +#define NOT_AN_OBJECT -23 +#define INVALID_FLOAT -10024 +#define DIVISION_BY_ZERO -25 +#define MANTISSA_OVERSIZED -26 +#define MANTISSA_UNDERSIZED -27 +#define EXPONENT_OVERSIZED -28 +#define EXPONENT_UNDERSIZED -29 +#define OVERFLOW -30 +#define NOT_IOU_AMOUNT -31 +#define NOT_AN_AMOUNT -32 +#define CANT_RETURN_NEGATIVE -33 +#define NOT_AUTHORIZED -34 +#define PREVIOUS_FAILURE_PREVENTS_RETRY -35 +#define TOO_MANY_PARAMS -36 +#define INVALID_TXN -37 +#define RESERVE_INSUFFICIENT -38 +#define COMPLEX_NOT_SUPPORTED -39 +#define DOES_NOT_MATCH -40 +#define HOOK_ERROR_CODES +#endif //HOOK_ERROR_CODES \ No newline at end of file diff --git a/hook/genesis/headers/extern.h b/hook/genesis/headers/extern.h new file mode 100644 index 000000000..5a7dc7711 --- /dev/null +++ b/hook/genesis/headers/extern.h @@ -0,0 +1,352 @@ +// For documentation please see: https://xrpl-hooks.readme.io/reference/ +// Generated using generate_extern.sh +#include +#ifndef HOOK_EXTERN + +extern int32_t __attribute__((noduplicate)) +_g(uint32_t guard_id, uint32_t maxiter); + +extern int64_t +accept(uint32_t read_ptr, uint32_t read_len, int64_t error_code); + +extern int64_t +emit( + uint32_t write_ptr, + uint32_t write_len, + uint32_t read_ptr, + uint32_t read_len); + +extern int64_t +etxn_burden(void); + +extern int64_t +etxn_details(uint32_t write_ptr, uint32_t write_len); + +extern int64_t +etxn_fee_base(uint32_t read_ptr, uint32_t read_len); + +extern int64_t +etxn_generation(void); + +extern int64_t +etxn_nonce(uint32_t write_ptr, uint32_t write_len); + +extern int64_t +etxn_reserve(uint32_t count); + +extern int64_t +fee_base(void); + +extern int64_t +float_compare(int64_t float1, int64_t float2, uint32_t mode); + +extern int64_t +float_divide(int64_t float1, int64_t float2); + +extern int64_t +float_exponent(int64_t float1); + +extern int64_t +float_exponent_set(int64_t float1, int32_t exponent); + +extern int64_t +float_int(int64_t float1, uint32_t decimal_places, uint32_t abs); + +extern int64_t +float_invert(int64_t float1); + +extern int64_t +float_log(int64_t float1); + +extern int64_t +float_mantissa(int64_t float1); + +extern int64_t +float_mantissa_set(int64_t float1, int64_t mantissa); + +extern int64_t +float_mulratio( + int64_t float1, + uint32_t round_up, + uint32_t numerator, + uint32_t denominator); + +extern int64_t +float_multiply(int64_t float1, int64_t float2); + +extern int64_t +float_negate(int64_t float1); + +extern int64_t +float_one(void); + +extern int64_t +float_root(int64_t float1, uint32_t n); + +extern int64_t +float_set(int32_t exponent, int64_t mantissa); + +extern int64_t +float_sign(int64_t float1); + +extern int64_t +float_sign_set(int64_t float1, uint32_t negative); + +extern int64_t +float_sto( + uint32_t write_ptr, + uint32_t write_len, + uint32_t cread_ptr, + uint32_t cread_len, + uint32_t iread_ptr, + uint32_t iread_len, + int64_t float1, + uint32_t field_code); + +extern int64_t +float_sto_set(uint32_t read_ptr, uint32_t read_len); + +extern int64_t +float_sum(int64_t float1, int64_t float2); + +extern int64_t +hook_account(uint32_t write_ptr, uint32_t write_len); + +extern int64_t +hook_again(void); + +extern int64_t +hook_hash(uint32_t write_ptr, uint32_t write_len, int32_t hook_no); + +extern int64_t +hook_param( + uint32_t write_ptr, + uint32_t write_len, + uint32_t read_ptr, + uint32_t read_len); + +extern int64_t +otxn_param( + uint32_t write_ptr, + uint32_t write_len, + uint32_t read_ptr, + uint32_t read_len); + +extern int64_t +hook_param_set( + uint32_t read_ptr, + uint32_t read_len, + uint32_t kread_ptr, + uint32_t kread_len, + uint32_t hread_ptr, + uint32_t hread_len); + +extern int64_t +hook_pos(void); + +extern int64_t +hook_skip(uint32_t read_ptr, uint32_t read_len, uint32_t flags); + +extern int64_t +ledger_keylet( + uint32_t write_ptr, + uint32_t write_len, + uint32_t lread_ptr, + uint32_t lread_len, + uint32_t hread_ptr, + uint32_t hread_len); + +extern int64_t +ledger_last_hash(uint32_t write_ptr, uint32_t write_len); + +extern int64_t +ledger_last_time(void); + +extern int64_t +ledger_nonce(uint32_t write_ptr, uint32_t write_len); + +extern int64_t +ledger_seq(void); + +extern int64_t +meta_slot(uint32_t slot_no); + +extern int64_t +otxn_burden(void); + +extern int64_t +otxn_field(uint32_t write_ptr, uint32_t write_len, uint32_t field_id); + +extern int64_t +otxn_field_txt(uint32_t write_ptr, uint32_t write_len, uint32_t field_id); + +extern int64_t +otxn_generation(void); + +extern int64_t +otxn_id(uint32_t write_ptr, uint32_t write_len, uint32_t flags); + +extern int64_t +otxn_slot(uint32_t slot_no); + +extern int64_t +otxn_type(void); + +extern int64_t +rollback(uint32_t read_ptr, uint32_t read_len, int64_t error_code); + +extern int64_t +slot(uint32_t write_ptr, uint32_t write_len, uint32_t slot); + +extern int64_t +slot_clear(uint32_t slot); + +extern int64_t +slot_count(uint32_t slot); + +extern int64_t +slot_float(uint32_t slot_no); + +extern int64_t +slot_id(uint32_t write_ptr, uint32_t write_len, uint32_t slot); + +extern int64_t +slot_set(uint32_t read_ptr, uint32_t read_len, uint32_t slot); + +extern int64_t +slot_size(uint32_t slot); + +extern int64_t +slot_subarray(uint32_t parent_slot, uint32_t array_id, uint32_t new_slot); + +extern int64_t +slot_subfield(uint32_t parent_slot, uint32_t field_id, uint32_t new_slot); + +extern int64_t +slot_type(uint32_t slot_no, uint32_t flags); + +extern int64_t +state( + uint32_t write_ptr, + uint32_t write_len, + uint32_t kread_ptr, + uint32_t kread_len); + +extern int64_t +state_foreign( + uint32_t write_ptr, + uint32_t write_len, + uint32_t kread_ptr, + uint32_t kread_len, + uint32_t nread_ptr, + uint32_t nread_len, + uint32_t aread_ptr, + uint32_t aread_len); + +extern int64_t +state_foreign_set( + uint32_t read_ptr, + uint32_t read_len, + uint32_t kread_ptr, + uint32_t kread_len, + uint32_t nread_ptr, + uint32_t nread_len, + uint32_t aread_ptr, + uint32_t aread_len); + +extern int64_t +state_set( + uint32_t read_ptr, + uint32_t read_len, + uint32_t kread_ptr, + uint32_t kread_len); + +extern int64_t +sto_emplace( + uint32_t write_ptr, + uint32_t write_len, + uint32_t sread_ptr, + uint32_t sread_len, + uint32_t fread_ptr, + uint32_t fread_len, + uint32_t field_id); + +extern int64_t +sto_erase( + uint32_t write_ptr, + uint32_t write_len, + uint32_t read_ptr, + uint32_t read_len, + uint32_t field_id); + +extern int64_t +sto_subarray(uint32_t read_ptr, uint32_t read_len, uint32_t array_id); + +extern int64_t +sto_subfield(uint32_t read_ptr, uint32_t read_len, uint32_t field_id); + +extern int64_t +sto_validate(uint32_t tread_ptr, uint32_t tread_len); + +extern int64_t +trace( + uint32_t mread_ptr, + uint32_t mread_len, + uint32_t dread_ptr, + uint32_t dread_len, + uint32_t as_hex); + +extern int64_t +trace_float(uint32_t read_ptr, uint32_t read_len, int64_t float1); + +extern int64_t +trace_num(uint32_t read_ptr, uint32_t read_len, int64_t number); + +extern int64_t +trace_slot(uint32_t read_ptr, uint32_t read_len, uint32_t slot); + +extern int64_t +util_accid( + uint32_t write_ptr, + uint32_t write_len, + uint32_t read_ptr, + uint32_t read_len); + +extern int64_t +util_keylet( + uint32_t write_ptr, + uint32_t write_len, + uint32_t keylet_type, + uint32_t a, + uint32_t b, + uint32_t c, + uint32_t d, + uint32_t e, + uint32_t f); + +extern int64_t +util_raddr( + uint32_t write_ptr, + uint32_t write_len, + uint32_t read_ptr, + uint32_t read_len); + +extern int64_t +util_sha512h( + uint32_t write_ptr, + uint32_t write_len, + uint32_t read_ptr, + uint32_t read_len); + +extern int64_t +util_verify( + uint32_t dread_ptr, + uint32_t dread_len, + uint32_t sread_ptr, + uint32_t sread_len, + uint32_t kread_ptr, + uint32_t kread_len); + +extern int64_t xpop_slot(uint32_t, uint32_t); +#define HOOK_EXTERN +#endif // HOOK_EXTERN \ No newline at end of file diff --git a/hook/genesis/headers/hookapi.h b/hook/genesis/headers/hookapi.h new file mode 100644 index 000000000..c42ebe655 --- /dev/null +++ b/hook/genesis/headers/hookapi.h @@ -0,0 +1,50 @@ +/** + * Hook API include file + * + * Note to the reader: + * This include defines two types of things: external functions and macros + * Functions are used sparingly because a non-inlining compiler may produce + * undesirable output. + * + * Find documentation here: https://xrpl-hooks.readme.io/reference/ + */ + +#ifndef HOOKAPI_INCLUDED +#define HOOKAPI_INCLUDED 1 + +#define KEYLET_HOOK 1 +#define KEYLET_HOOK_STATE 2 +#define KEYLET_ACCOUNT 3 +#define KEYLET_AMENDMENTS 4 +#define KEYLET_CHILD 5 +#define KEYLET_SKIP 6 +#define KEYLET_FEES 7 +#define KEYLET_NEGATIVE_UNL 8 +#define KEYLET_LINE 9 +#define KEYLET_OFFER 10 +#define KEYLET_QUALITY 11 +#define KEYLET_EMITTED_DIR 12 +#define KEYLET_TICKET 13 +#define KEYLET_SIGNERS 14 +#define KEYLET_CHECK 15 +#define KEYLET_DEPOSIT_PREAUTH 16 +#define KEYLET_UNCHECKED 17 +#define KEYLET_OWNER_DIR 18 +#define KEYLET_PAGE 19 +#define KEYLET_ESCROW 20 +#define KEYLET_PAYCHAN 21 +#define KEYLET_EMITTED 22 +#define KEYLET_NFT_OFFER 23 +#define KEYLET_HOOK_DEFINITION 24 + +#define COMPARE_EQUAL 1U +#define COMPARE_LESS 2U +#define COMPARE_GREATER 4U + +#include "error.h" +#include "extern.h" +#include "sfcodes.h" +#include "macro.h" +#include "types.h" + +#endif \ No newline at end of file diff --git a/hook/genesis/headers/macro.h b/hook/genesis/headers/macro.h new file mode 100644 index 000000000..03bda4363 --- /dev/null +++ b/hook/genesis/headers/macro.h @@ -0,0 +1,668 @@ +/** + * These are helper macros for writing hooks, all of them are optional as is including hookmacro.h at all + */ + +#include +#include "hookapi.h" +#include "sfcodes.h" + +#ifndef HOOKMACROS_INCLUDED +#define HOOKMACROS_INCLUDED 1 + + +#ifdef NDEBUG +#define DEBUG 0 +#else +#define DEBUG 1 +#endif + +#define TRACEVAR(v) if (DEBUG) trace_num((uint32_t)(#v), (uint32_t)(sizeof(#v) - 1), (int64_t)v); +#define TRACEHEX(v) if (DEBUG) trace((uint32_t)(#v), (uint32_t)(sizeof(#v) - 1), (uint32_t)(v), (uint32_t)(sizeof(v)), 1); +#define TRACEXFL(v) if (DEBUG) trace_float((uint32_t)(#v), (uint32_t)(sizeof(#v) - 1), (int64_t)v); +#define TRACESTR(v) if (DEBUG) trace((uint32_t)(#v), (uint32_t)(sizeof(#v) - 1), (uint32_t)(v), sizeof(v), 0); + +// hook developers should use this guard macro, simply GUARD() +#define GUARD(maxiter) _g((1ULL << 31U) + __LINE__, (maxiter)+1) +#define GUARDM(maxiter, n) _g(( (1ULL << 31U) + (__LINE__ << 16) + n), (maxiter)+1) + +#define SBUF(str) (uint32_t)(str), sizeof(str) + +#define REQUIRE(cond, str)\ +{\ + if (!(cond))\ + rollback(SBUF(str), __LINE__);\ +} + +// make a report buffer as a c-string +// provide a name for a buffer to declare (buf) +// provide a static string +// provide an integer to print after the string +#define RBUF(buf, out_len, str, num)\ +unsigned char buf[sizeof(str) + 21];\ +int out_len = 0;\ +{\ + int i = 0;\ + for (; GUARDM(sizeof(str),1),i < sizeof(str); ++i)\ + (buf)[i] = str[i];\ + if ((buf)[sizeof(str)-1] == 0) i--;\ + if ((num) < 0) (buf)[i++] = '-';\ + uint64_t unsigned_num = (uint64_t)( (num) < 0 ? (num) * -1 : (num) );\ + uint64_t j = 10000000000000000000ULL;\ + int start = 1;\ + for (; GUARDM(20,2), unsigned_num > 0 && j > 0; j /= 10)\ + {\ + unsigned char digit = ( unsigned_num / j ) % 10;\ + if (digit == 0 && start)\ + continue;\ + start = 0;\ + (buf)[i++] = '0' + digit;\ + }\ + (buf)[i] = '\0';\ + out_len = i;\ +} + +#define RBUF2(buff, out_len, str, num, str2, num2)\ +unsigned char buff[sizeof(str) + sizeof(str2) + 42];\ +int out_len = 0;\ +{\ + unsigned char* buf = buff;\ + int i = 0;\ + for (; GUARDM(sizeof(str),1),i < sizeof(str); ++i)\ + (buf)[i] = str[i];\ + if ((buf)[sizeof(str)-1] == 0) i--;\ + if ((num) < 0) (buf)[i++] = '-';\ + uint64_t unsigned_num = (uint64_t)( (num) < 0 ? (num) * -1 : (num) );\ + uint64_t j = 10000000000000000000ULL;\ + int start = 1;\ + for (; GUARDM(20,2), unsigned_num > 0 && j > 0; j /= 10)\ + {\ + unsigned char digit = ( unsigned_num / j ) % 10;\ + if (digit == 0 && start)\ + continue;\ + start = 0;\ + (buf)[i++] = '0' + digit;\ + }\ + buf += i;\ + out_len += i;\ + i = 0;\ + for (; GUARDM(sizeof(str2),3),i < sizeof(str2); ++i)\ + (buf)[i] = str2[i];\ + if ((buf)[sizeof(str2)-1] == 0) i--;\ + if ((num2) < 0) (buf)[i++] = '-';\ + unsigned_num = (uint64_t)( (num2) < 0 ? (num2) * -1 : (num2) );\ + j = 10000000000000000000ULL;\ + start = 1;\ + for (; GUARDM(20,4), unsigned_num > 0 && j > 0; j /= 10)\ + {\ + unsigned char digit = ( unsigned_num / j ) % 10;\ + if (digit == 0 && start)\ + continue;\ + start = 0;\ + (buf)[i++] = '0' + digit;\ + }\ + (buf)[i] = '\0';\ + out_len += i;\ +} + +#define CLEARBUF(b)\ +{\ + for (int x = 0; GUARD(sizeof(b)), x < sizeof(b); ++x)\ + b[x] = 0;\ +} + +// returns an in64_t, negative if error, non-negative if valid drops +#define AMOUNT_TO_DROPS(amount_buffer)\ + (((amount_buffer)[0] >> 7) ? -2 : (\ + ((((uint64_t)((amount_buffer)[0])) & 0xb00111111) << 56) +\ + (((uint64_t)((amount_buffer)[1])) << 48) +\ + (((uint64_t)((amount_buffer)[2])) << 40) +\ + (((uint64_t)((amount_buffer)[3])) << 32) +\ + (((uint64_t)((amount_buffer)[4])) << 24) +\ + (((uint64_t)((amount_buffer)[5])) << 16) +\ + (((uint64_t)((amount_buffer)[6])) << 8) +\ + (((uint64_t)((amount_buffer)[7]))))) + +#define SUB_OFFSET(x) ((int32_t)(x >> 32)) +#define SUB_LENGTH(x) ((int32_t)(x & 0xFFFFFFFFULL)) + +#define BUFFER_EQUAL_20(buf1, buf2)\ + (\ + *(((uint64_t*)(buf1)) + 0) == *(((uint64_t*)(buf2)) + 0) &&\ + *(((uint64_t*)(buf1)) + 1) == *(((uint64_t*)(buf2)) + 1) &&\ + *(((uint32_t*)(buf1)) + 4) == *(((uint32_t*)(buf2)) + 4)) + +#define BUFFER_EQUAL_32(buf1, buf2)\ + (\ + *(((uint64_t*)(buf1)) + 0) == *(((uint64_t*)(buf2)) + 0) &&\ + *(((uint64_t*)(buf1)) + 1) == *(((uint64_t*)(buf2)) + 1) &&\ + *(((uint64_t*)(buf1)) + 2) == *(((uint64_t*)(buf2)) + 2) &&\ + *(((uint64_t*)(buf1)) + 3) == *(((uint64_t*)(buf2)) + 3)) + + +// when using this macro buf1len may be dynamic but buf2len must be static +// provide n >= 1 to indicate how many times the macro will be hit on the line of code +// e.g. if it is in a loop that loops 10 times n = 10 + +#define BUFFER_EQUAL_GUARD(output, buf1, buf1len, buf2, buf2len, n)\ +{\ + output = ((buf1len) == (buf2len) ? 1 : 0);\ + for (int x = 0; GUARDM( (buf2len) * (n), 1 ), output && x < (buf2len);\ + ++x)\ + output = *(((uint8_t*)(buf1)) + x) == *(((uint8_t*)(buf2)) + x);\ +} + +#define BUFFER_SWAP(x,y)\ +{\ + uint8_t* z = x;\ + x = y;\ + y = z;\ +} + +#define ACCOUNT_COMPARE(compare_result, buf1, buf2)\ +{\ + compare_result = 0;\ + for (int i = 0; GUARD(20), i < 20; ++i)\ + {\ + if (buf1[i] > buf2[i])\ + {\ + compare_result = 1;\ + break;\ + }\ + else if (buf1[i] < buf2[i])\ + {\ + compare_result = -1;\ + break;\ + }\ + }\ +} + +#define BUFFER_EQUAL_STR_GUARD(output, buf1, buf1len, str, n)\ + BUFFER_EQUAL_GUARD(output, buf1, buf1len, str, (sizeof(str)-1), n) + +#define BUFFER_EQUAL_STR(output, buf1, buf1len, str)\ + BUFFER_EQUAL_GUARD(output, buf1, buf1len, str, (sizeof(str)-1), 1) + +#define BUFFER_EQUAL(output, buf1, buf2, compare_len)\ + BUFFER_EQUAL_GUARD(output, buf1, compare_len, buf2, compare_len, 1) + +#define UINT16_TO_BUF(buf_raw, i)\ +{\ + unsigned char* buf = (unsigned char*)buf_raw;\ + buf[0] = (((uint64_t)i) >> 8) & 0xFFUL;\ + buf[1] = (((uint64_t)i) >> 0) & 0xFFUL;\ +} + +#define UINT16_FROM_BUF(buf)\ + (((uint64_t)((buf)[0]) << 8) +\ + ((uint64_t)((buf)[1]) << 0)) + +#define UINT32_TO_BUF(buf_raw, i)\ +{\ + unsigned char* buf = (unsigned char*)buf_raw;\ + buf[0] = (((uint64_t)i) >> 24) & 0xFFUL;\ + buf[1] = (((uint64_t)i) >> 16) & 0xFFUL;\ + buf[2] = (((uint64_t)i) >> 8) & 0xFFUL;\ + buf[3] = (((uint64_t)i) >> 0) & 0xFFUL;\ +} + + +#define UINT32_FROM_BUF(buf)\ + (((uint64_t)((buf)[0]) << 24) +\ + ((uint64_t)((buf)[1]) << 16) +\ + ((uint64_t)((buf)[2]) << 8) +\ + ((uint64_t)((buf)[3]) << 0)) + +#define UINT64_TO_BUF(buf_raw, i)\ +{\ + unsigned char* buf = (unsigned char*)buf_raw;\ + buf[0] = (((uint64_t)i) >> 56) & 0xFFUL;\ + buf[1] = (((uint64_t)i) >> 48) & 0xFFUL;\ + buf[2] = (((uint64_t)i) >> 40) & 0xFFUL;\ + buf[3] = (((uint64_t)i) >> 32) & 0xFFUL;\ + buf[4] = (((uint64_t)i) >> 24) & 0xFFUL;\ + buf[5] = (((uint64_t)i) >> 16) & 0xFFUL;\ + buf[6] = (((uint64_t)i) >> 8) & 0xFFUL;\ + buf[7] = (((uint64_t)i) >> 0) & 0xFFUL;\ +} + + +#define UINT64_FROM_BUF(buf)\ + (((uint64_t)((buf)[0]) << 56) +\ + ((uint64_t)((buf)[1]) << 48) +\ + ((uint64_t)((buf)[2]) << 40) +\ + ((uint64_t)((buf)[3]) << 32) +\ + ((uint64_t)((buf)[4]) << 24) +\ + ((uint64_t)((buf)[5]) << 16) +\ + ((uint64_t)((buf)[6]) << 8) +\ + ((uint64_t)((buf)[7]) << 0)) + + +#define INT64_FROM_BUF(buf)\ + ((((uint64_t)((buf)[0] & 0x7FU) << 56) +\ + ((uint64_t)((buf)[1]) << 48) +\ + ((uint64_t)((buf)[2]) << 40) +\ + ((uint64_t)((buf)[3]) << 32) +\ + ((uint64_t)((buf)[4]) << 24) +\ + ((uint64_t)((buf)[5]) << 16) +\ + ((uint64_t)((buf)[6]) << 8) +\ + ((uint64_t)((buf)[7]) << 0)) * (buf[0] & 0x80U ? -1 : 1)) + +#define INT64_TO_BUF(buf_raw, i)\ +{\ + unsigned char* buf = (unsigned char*)buf_raw;\ + buf[0] = (((uint64_t)i) >> 56) & 0x7FUL;\ + buf[1] = (((uint64_t)i) >> 48) & 0xFFUL;\ + buf[2] = (((uint64_t)i) >> 40) & 0xFFUL;\ + buf[3] = (((uint64_t)i) >> 32) & 0xFFUL;\ + buf[4] = (((uint64_t)i) >> 24) & 0xFFUL;\ + buf[5] = (((uint64_t)i) >> 16) & 0xFFUL;\ + buf[6] = (((uint64_t)i) >> 8) & 0xFFUL;\ + buf[7] = (((uint64_t)i) >> 0) & 0xFFUL;\ + if (i < 0) buf[0] |= 0x80U;\ +} + +#define ttPAYMENT 0 +#define ttESCROW_CREATE 1 +#define ttESCROW_FINISH 2 +#define ttACCOUNT_SET 3 +#define ttESCROW_CANCEL 4 +#define ttREGULAR_KEY_SET 5 +#define ttOFFER_CREATE 7 +#define ttOFFER_CANCEL 8 +#define ttTICKET_CREATE 10 +#define ttSIGNER_LIST_SET 12 +#define ttPAYCHAN_CREATE 13 +#define ttPAYCHAN_FUND 14 +#define ttPAYCHAN_CLAIM 15 +#define ttCHECK_CREATE 16 +#define ttCHECK_CASH 17 +#define ttCHECK_CANCEL 18 +#define ttDEPOSIT_PREAUTH 19 +#define ttTRUST_SET 20 +#define ttACCOUNT_DELETE 21 +#define ttHOOK_SET 22 +#define ttNFTOKEN_MINT 25 +#define ttNFTOKEN_BURN 26 +#define ttNFTOKEN_CREATE_OFFER 27 +#define ttNFTOKEN_CANCEL_OFFER 28 +#define ttNFTOKEN_ACCEPT_OFFER 29 +#define ttURITOKEN_MINT 45 +#define ttURITOKEN_BURN 46 +#define ttURITOKEN_BUY 47 +#define ttURITOKEN_CREATE_SELL_OFFER 48 +#define ttURITOKEN_CANCEL_SELL_OFFER 49 +#define ttCLAIM_REWARD 98 +#define ttINVOKE 99 +#define ttAMENDMENT 100 +#define ttFEE 101 +#define ttUNL_MODIFY 102 +#define ttEMIT_FAILURE 103 +#define tfCANONICAL 0x80000000UL + +#define atACCOUNT 1U +#define atOWNER 2U +#define atDESTINATION 3U +#define atISSUER 4U +#define atAUTHORIZE 5U +#define atUNAUTHORIZE 6U +#define atTARGET 7U +#define atREGULARKEY 8U +#define atPSEUDOCALLBACK 9U + +#define amAMOUNT 1U +#define amBALANCE 2U +#define amLIMITAMOUNT 3U +#define amTAKERPAYS 4U +#define amTAKERGETS 5U +#define amLOWLIMIT 6U +#define amHIGHLIMIT 7U +#define amFEE 8U +#define amSENDMAX 9U +#define amDELIVERMIN 10U +#define amMINIMUMOFFER 16U +#define amRIPPLEESCROW 17U +#define amDELIVEREDAMOUNT 18U + +/** + * RH NOTE -- PAY ATTENTION + * + * ALL 'ENCODE' MACROS INCREMENT BUF_OUT + * THIS IS TO MAKE CHAINING EASY + * BUF_OUT IS A SACRIFICIAL POINTER + * + * 'ENCODE' MACROS WITH CONSTANTS HAVE + * ALIASING TO ASSIST YOU WITH ORDER + * _TYPECODE_FIELDCODE_ENCODE_MACRO + * TO PRODUCE A SERIALIZED OBJECT + * IN CANONICAL FORMAT YOU MUST ORDER + * FIRST BY TYPE CODE THEN BY FIELD CODE + * + * ALL 'PREPARE' MACROS PRESERVE POINTERS + * + **/ + + +#define ENCODE_TL_SIZE 49 +#define ENCODE_TL(buf_out, tlamt, amount_type)\ +{\ + uint8_t uat = amount_type; \ + buf_out[0] = 0x60U +(uat & 0x0FU ); \ + for (int i = 1; GUARDM(48, 1), i < 49; ++i)\ + buf_out[i] = tlamt[i-1];\ + buf_out += ENCODE_TL_SIZE;\ +} +#define _06_XX_ENCODE_TL(buf_out, drops, amount_type )\ + ENCODE_TL(buf_out, drops, amount_type ); +#define ENCODE_TL_AMOUNT(buf_out, drops )\ + ENCODE_TL(buf_out, drops, amAMOUNT ); +#define _06_01_ENCODE_TL_AMOUNT(buf_out, drops )\ + ENCODE_TL_AMOUNT(buf_out, drops ); + + +// Encode drops to serialization format +// consumes 9 bytes +#define ENCODE_DROPS_SIZE 9 +#define ENCODE_DROPS(buf_out, drops, amount_type ) \ + {\ + uint8_t uat = amount_type; \ + uint64_t udrops = drops; \ + buf_out[0] = 0x60U +(uat & 0x0FU ); \ + buf_out[1] = 0b01000000 + (( udrops >> 56 ) & 0b00111111 ); \ + buf_out[2] = (udrops >> 48) & 0xFFU; \ + buf_out[3] = (udrops >> 40) & 0xFFU; \ + buf_out[4] = (udrops >> 32) & 0xFFU; \ + buf_out[5] = (udrops >> 24) & 0xFFU; \ + buf_out[6] = (udrops >> 16) & 0xFFU; \ + buf_out[7] = (udrops >> 8) & 0xFFU; \ + buf_out[8] = (udrops >> 0) & 0xFFU; \ + buf_out += ENCODE_DROPS_SIZE; \ + } + +#define _06_XX_ENCODE_DROPS(buf_out, drops, amount_type )\ + ENCODE_DROPS(buf_out, drops, amount_type ); + +#define ENCODE_DROPS_AMOUNT(buf_out, drops )\ + ENCODE_DROPS(buf_out, drops, amAMOUNT ); +#define _06_01_ENCODE_DROPS_AMOUNT(buf_out, drops )\ + ENCODE_DROPS_AMOUNT(buf_out, drops ); + +#define ENCODE_DROPS_FEE(buf_out, drops )\ + ENCODE_DROPS(buf_out, drops, amFEE ); +#define _06_08_ENCODE_DROPS_FEE(buf_out, drops )\ + ENCODE_DROPS_FEE(buf_out, drops ); + +#define ENCODE_TT_SIZE 3 +#define ENCODE_TT(buf_out, tt )\ + {\ + uint8_t utt = tt;\ + buf_out[0] = 0x12U;\ + buf_out[1] =(utt >> 8 ) & 0xFFU;\ + buf_out[2] =(utt >> 0 ) & 0xFFU;\ + buf_out += ENCODE_TT_SIZE; \ + } +#define _01_02_ENCODE_TT(buf_out, tt)\ + ENCODE_TT(buf_out, tt); + + +#define ENCODE_ACCOUNT_SIZE 22 +#define ENCODE_ACCOUNT(buf_out, account_id, account_type)\ + {\ + uint8_t uat = account_type;\ + buf_out[0] = 0x80U + uat;\ + buf_out[1] = 0x14U;\ + *(uint64_t*)(buf_out + 2) = *(uint64_t*)(account_id + 0);\ + *(uint64_t*)(buf_out + 10) = *(uint64_t*)(account_id + 8);\ + *(uint32_t*)(buf_out + 18) = *(uint32_t*)(account_id + 16);\ + buf_out += ENCODE_ACCOUNT_SIZE;\ + } +#define _08_XX_ENCODE_ACCOUNT(buf_out, account_id, account_type)\ + ENCODE_ACCOUNT(buf_out, account_id, account_type); + +#define ENCODE_ACCOUNT_SRC_SIZE 22 +#define ENCODE_ACCOUNT_SRC(buf_out, account_id)\ + ENCODE_ACCOUNT(buf_out, account_id, atACCOUNT); +#define _08_01_ENCODE_ACCOUNT_SRC(buf_out, account_id)\ + ENCODE_ACCOUNT_SRC(buf_out, account_id); + +#define ENCODE_ACCOUNT_DST_SIZE 22 +#define ENCODE_ACCOUNT_DST(buf_out, account_id)\ + ENCODE_ACCOUNT(buf_out, account_id, atDESTINATION); +#define _08_03_ENCODE_ACCOUNT_DST(buf_out, account_id)\ + ENCODE_ACCOUNT_DST(buf_out, account_id); + +#define ENCODE_ACCOUNT_OWNER_SIZE 22 +#define ENCODE_ACCOUNT_OWNER(buf_out, account_id) \ + ENCODE_ACCOUNT(buf_out, account_id, atOWNER); +#define _08_02_ENCODE_ACCOUNT_OWNER(buf_out, account_id) \ + ENCODE_ACCOUNT_OWNER(buf_out, account_id); + +#define ENCODE_UINT32_COMMON_SIZE 5U +#define ENCODE_UINT32_COMMON(buf_out, i, field)\ + {\ + uint32_t ui = i; \ + uint8_t uf = field; \ + buf_out[0] = 0x20U +(uf & 0x0FU); \ + buf_out[1] =(ui >> 24 ) & 0xFFU; \ + buf_out[2] =(ui >> 16 ) & 0xFFU; \ + buf_out[3] =(ui >> 8 ) & 0xFFU; \ + buf_out[4] =(ui >> 0 ) & 0xFFU; \ + buf_out += ENCODE_UINT32_COMMON_SIZE; \ + } +#define _02_XX_ENCODE_UINT32_COMMON(buf_out, i, field)\ + ENCODE_UINT32_COMMON(buf_out, i, field)\ + +#define ENCODE_UINT32_UNCOMMON_SIZE 6U +#define ENCODE_UINT32_UNCOMMON(buf_out, i, field)\ + {\ + uint32_t ui = i; \ + uint8_t uf = field; \ + buf_out[0] = 0x20U; \ + buf_out[1] = uf; \ + buf_out[2] =(ui >> 24 ) & 0xFFU; \ + buf_out[3] =(ui >> 16 ) & 0xFFU; \ + buf_out[4] =(ui >> 8 ) & 0xFFU; \ + buf_out[5] =(ui >> 0 ) & 0xFFU; \ + buf_out += ENCODE_UINT32_UNCOMMON_SIZE; \ + } +#define _02_XX_ENCODE_UINT32_UNCOMMON(buf_out, i, field)\ + ENCODE_UINT32_UNCOMMON(buf_out, i, field)\ + +#define ENCODE_LLS_SIZE 6U +#define ENCODE_LLS(buf_out, lls )\ + ENCODE_UINT32_UNCOMMON(buf_out, lls, 0x1B ); +#define _02_27_ENCODE_LLS(buf_out, lls )\ + ENCODE_LLS(buf_out, lls ); + +#define ENCODE_FLS_SIZE 6U +#define ENCODE_FLS(buf_out, fls )\ + ENCODE_UINT32_UNCOMMON(buf_out, fls, 0x1A ); +#define _02_26_ENCODE_FLS(buf_out, fls )\ + ENCODE_FLS(buf_out, fls ); + +#define ENCODE_TAG_SRC_SIZE 5 +#define ENCODE_TAG_SRC(buf_out, tag )\ + ENCODE_UINT32_COMMON(buf_out, tag, 0x3U ); +#define _02_03_ENCODE_TAG_SRC(buf_out, tag )\ + ENCODE_TAG_SRC(buf_out, tag ); + +#define ENCODE_TAG_DST_SIZE 5 +#define ENCODE_TAG_DST(buf_out, tag )\ + ENCODE_UINT32_COMMON(buf_out, tag, 0xEU ); +#define _02_14_ENCODE_TAG_DST(buf_out, tag )\ + ENCODE_TAG_DST(buf_out, tag ); + +#define ENCODE_SEQUENCE_SIZE 5 +#define ENCODE_SEQUENCE(buf_out, sequence )\ + ENCODE_UINT32_COMMON(buf_out, sequence, 0x4U ); +#define _02_04_ENCODE_SEQUENCE(buf_out, sequence )\ + ENCODE_SEQUENCE(buf_out, sequence ); + +#define ENCODE_FLAGS_SIZE 5 +#define ENCODE_FLAGS(buf_out, tag )\ + ENCODE_UINT32_COMMON(buf_out, tag, 0x2U ); +#define _02_02_ENCODE_FLAGS(buf_out, tag )\ + ENCODE_FLAGS(buf_out, tag ); + +#define ENCODE_SIGNING_PUBKEY_SIZE 35 +#define ENCODE_SIGNING_PUBKEY(buf_out, pkey )\ + {\ + buf_out[0] = 0x73U;\ + buf_out[1] = 0x21U;\ + *(uint64_t*)(buf_out + 2) = *(uint64_t*)(pkey + 0);\ + *(uint64_t*)(buf_out + 10) = *(uint64_t*)(pkey + 8);\ + *(uint64_t*)(buf_out + 18) = *(uint64_t*)(pkey + 16);\ + *(uint64_t*)(buf_out + 26) = *(uint64_t*)(pkey + 24);\ + buf[34] = pkey[32];\ + buf_out += ENCODE_SIGNING_PUBKEY_SIZE;\ + } + +#define _07_03_ENCODE_SIGNING_PUBKEY(buf_out, pkey )\ + ENCODE_SIGNING_PUBKEY(buf_out, pkey ); + +#define ENCODE_SIGNING_PUBKEY_NULL_SIZE 2 +#define ENCODE_SIGNING_PUBKEY_NULL(buf_out )\ + {\ + *buf_out++ = 0x73U;\ + *buf_out++ = 0x00U;\ + } + +#define _07_03_ENCODE_SIGNING_PUBKEY_NULL(buf_out )\ + ENCODE_SIGNING_PUBKEY_NULL(buf_out ); + + +#define _0E_0E_ENCODE_HOOKOBJ(buf_out, hhash)\ +{\ + uint8_t* hook0 = (hhash);\ + *buf_out++ = 0xEEU; /* hook obj start */ \ + if (hook0 == 0) /* noop */\ + {\ + /* do nothing */ \ + }\ + else\ + {\ + *buf_out++ = 0x22U; /* flags = override */\ + *buf_out++ = 0x00U;\ + *buf_out++ = 0x00U;\ + *buf_out++ = 0x00U;\ + *buf_out++ = 0x01U;\ + if (hook0 == 0xFFFFFFFFUL) /* delete operation */ \ + {\ + *buf_out++ = 0x7BU; /* empty createcode */ \ + *buf_out++ = 0x00U;\ + }\ + else\ + {\ + *buf_out++ = 0x50U; /* HookHash */\ + *buf_out++ = 0x1FU;\ + uint64_t* d = (uint64_t*)buf_out;\ + uint64_t* s = (uint64_t*)hook0;\ + *d++ = *s++;\ + *d++ = *s++;\ + *d++ = *s++;\ + *d++ = *s++;\ + buf_out+=32;\ + }\ + }\ + *buf_out++ = 0xE1U;\ +} + +#define PREPARE_HOOKSET(buf_out_master, maxlen, h, sizeout)\ + {\ + uint8_t* buf_out = (buf_out_master); \ + uint8_t acc[20]; \ + uint32_t cls = (uint32_t)ledger_seq(); \ + hook_account(SBUF(acc)); \ + _01_02_ENCODE_TT (buf_out, ttHOOK_SET ); \ + _02_02_ENCODE_FLAGS (buf_out, tfCANONICAL ); \ + _02_04_ENCODE_SEQUENCE (buf_out, 0 ); \ + _02_26_ENCODE_FLS (buf_out, cls + 1 ); \ + _02_27_ENCODE_LLS (buf_out, cls + 5 ); \ + uint8_t* fee_ptr = buf_out; \ + _06_08_ENCODE_DROPS_FEE (buf_out, 0 ); \ + _07_03_ENCODE_SIGNING_PUBKEY_NULL (buf_out ); \ + _08_01_ENCODE_ACCOUNT_SRC (buf_out, acc ); \ + uint32_t remaining_size = (maxlen) - (buf_out - (buf_out_master)); \ + int64_t edlen = etxn_details((uint32_t)buf_out, remaining_size); \ + buf_out += edlen; \ + *buf_out++ = 0xFBU; /* hook array start */ \ + _0E_0E_ENCODE_HOOKOBJ (buf_out, h[0]); \ + _0E_0E_ENCODE_HOOKOBJ (buf_out, h[1]); \ + _0E_0E_ENCODE_HOOKOBJ (buf_out, h[2]); \ + _0E_0E_ENCODE_HOOKOBJ (buf_out, h[3]); \ + _0E_0E_ENCODE_HOOKOBJ (buf_out, h[4]); \ + _0E_0E_ENCODE_HOOKOBJ (buf_out, h[5]); \ + _0E_0E_ENCODE_HOOKOBJ (buf_out, h[6]); \ + _0E_0E_ENCODE_HOOKOBJ (buf_out, h[7]); \ + _0E_0E_ENCODE_HOOKOBJ (buf_out, h[8]); \ + _0E_0E_ENCODE_HOOKOBJ (buf_out, h[9]); \ + *buf_out++ = 0xF1U; /* hook array end */ \ + sizeout = (buf_out - (buf_out_master)); \ + int64_t fee = etxn_fee_base(buf_out_master, sizeout); \ + _06_08_ENCODE_DROPS_FEE (fee_ptr, fee ); \ + } + +#ifdef HAS_CALLBACK +#define PREPARE_PAYMENT_SIMPLE_SIZE 270U +#else +#define PREPARE_PAYMENT_SIMPLE_SIZE 248U +#endif + +#define PREPARE_PAYMENT_SIMPLE(buf_out_master, drops_amount_raw, to_address, dest_tag_raw, src_tag_raw)\ + {\ + uint8_t* buf_out = buf_out_master;\ + uint8_t acc[20];\ + uint64_t drops_amount = (drops_amount_raw);\ + uint32_t dest_tag = (dest_tag_raw);\ + uint32_t src_tag = (src_tag_raw);\ + uint32_t cls = (uint32_t)ledger_seq();\ + hook_account(SBUF(acc));\ + _01_02_ENCODE_TT (buf_out, ttPAYMENT ); /* uint16 | size 3 */ \ + _02_02_ENCODE_FLAGS (buf_out, tfCANONICAL ); /* uint32 | size 5 */ \ + _02_03_ENCODE_TAG_SRC (buf_out, src_tag ); /* uint32 | size 5 */ \ + _02_04_ENCODE_SEQUENCE (buf_out, 0 ); /* uint32 | size 5 */ \ + _02_14_ENCODE_TAG_DST (buf_out, dest_tag ); /* uint32 | size 5 */ \ + _02_26_ENCODE_FLS (buf_out, cls + 1 ); /* uint32 | size 6 */ \ + _02_27_ENCODE_LLS (buf_out, cls + 5 ); /* uint32 | size 6 */ \ + _06_01_ENCODE_DROPS_AMOUNT (buf_out, drops_amount ); /* amount | size 9 */ \ + uint8_t* fee_ptr = buf_out;\ + _06_08_ENCODE_DROPS_FEE (buf_out, 0 ); /* amount | size 9 */ \ + _07_03_ENCODE_SIGNING_PUBKEY_NULL (buf_out ); /* pk | size 35 */ \ + _08_01_ENCODE_ACCOUNT_SRC (buf_out, acc ); /* account | size 22 */ \ + _08_03_ENCODE_ACCOUNT_DST (buf_out, to_address ); /* account | size 22 */ \ + int64_t edlen = etxn_details((uint32_t)buf_out, PREPARE_PAYMENT_SIMPLE_SIZE); /* emitdet | size 1?? */ \ + int64_t fee = etxn_fee_base(buf_out_master, PREPARE_PAYMENT_SIMPLE_SIZE); \ + _06_08_ENCODE_DROPS_FEE (fee_ptr, fee ); \ + } + +#ifdef HAS_CALLBACK +#define PREPARE_PAYMENT_SIMPLE_TRUSTLINE_SIZE 309 +#else +#define PREPARE_PAYMENT_SIMPLE_TRUSTLINE_SIZE 287 +#endif +#define PREPARE_PAYMENT_SIMPLE_TRUSTLINE(buf_out_master, tlamt, to_address, dest_tag_raw, src_tag_raw)\ + {\ + uint8_t* buf_out = buf_out_master;\ + uint8_t acc[20];\ + uint32_t dest_tag = (dest_tag_raw);\ + uint32_t src_tag = (src_tag_raw);\ + uint32_t cls = (uint32_t)ledger_seq();\ + hook_account(SBUF(acc));\ + _01_02_ENCODE_TT (buf_out, ttPAYMENT ); /* uint16 | size 3 */ \ + _02_02_ENCODE_FLAGS (buf_out, tfCANONICAL ); /* uint32 | size 5 */ \ + _02_03_ENCODE_TAG_SRC (buf_out, src_tag ); /* uint32 | size 5 */ \ + _02_04_ENCODE_SEQUENCE (buf_out, 0 ); /* uint32 | size 5 */ \ + _02_14_ENCODE_TAG_DST (buf_out, dest_tag ); /* uint32 | size 5 */ \ + _02_26_ENCODE_FLS (buf_out, cls + 1 ); /* uint32 | size 6 */ \ + _02_27_ENCODE_LLS (buf_out, cls + 5 ); /* uint32 | size 6 */ \ + _06_01_ENCODE_TL_AMOUNT (buf_out, tlamt ); /* amount | size 48 */ \ + uint8_t* fee_ptr = buf_out;\ + _06_08_ENCODE_DROPS_FEE (buf_out, 0 ); /* amount | size 9 */ \ + _07_03_ENCODE_SIGNING_PUBKEY_NULL (buf_out ); /* pk | size 35 */ \ + _08_01_ENCODE_ACCOUNT_SRC (buf_out, acc ); /* account | size 22 */ \ + _08_03_ENCODE_ACCOUNT_DST (buf_out, to_address ); /* account | size 22 */ \ + etxn_details((uint32_t)buf_out, PREPARE_PAYMENT_SIMPLE_TRUSTLINE_SIZE); /* emitdet | size 1?? */ \ + int64_t fee = etxn_fee_base(buf_out_master, PREPARE_PAYMENT_SIMPLE_TRUSTLINE_SIZE); \ + _06_08_ENCODE_DROPS_FEE (fee_ptr, fee ); \ + } + +#endif diff --git a/hook/genesis/headers/sfcodes.h b/hook/genesis/headers/sfcodes.h new file mode 100644 index 000000000..17f2230ad --- /dev/null +++ b/hook/genesis/headers/sfcodes.h @@ -0,0 +1,215 @@ +// For documentation please see: https://xrpl-hooks.readme.io/reference/ +// Generated using generate_sfcodes.sh +#define sfCloseResolution ((16U << 16U) + 1U) +#define sfMethod ((16U << 16U) + 2U) +#define sfTransactionResult ((16U << 16U) + 3U) +#define sfTickSize ((16U << 16U) + 16U) +#define sfUNLModifyDisabling ((16U << 16U) + 17U) +#define sfHookResult ((16U << 16U) + 18U) +#define sfLedgerEntryType ((1U << 16U) + 1U) +#define sfTransactionType ((1U << 16U) + 2U) +#define sfSignerWeight ((1U << 16U) + 3U) +#define sfTransferFee ((1U << 16U) + 4U) +#define sfVersion ((1U << 16U) + 16U) +#define sfHookStateChangeCount ((1U << 16U) + 17U) +#define sfHookEmitCount ((1U << 16U) + 18U) +#define sfHookExecutionIndex ((1U << 16U) + 19U) +#define sfHookApiVersion ((1U << 16U) + 20U) +#define sfNetworkID ((2U << 16U) + 1U) +#define sfFlags ((2U << 16U) + 2U) +#define sfSourceTag ((2U << 16U) + 3U) +#define sfSequence ((2U << 16U) + 4U) +#define sfPreviousTxnLgrSeq ((2U << 16U) + 5U) +#define sfLedgerSequence ((2U << 16U) + 6U) +#define sfCloseTime ((2U << 16U) + 7U) +#define sfParentCloseTime ((2U << 16U) + 8U) +#define sfSigningTime ((2U << 16U) + 9U) +#define sfExpiration ((2U << 16U) + 10U) +#define sfTransferRate ((2U << 16U) + 11U) +#define sfWalletSize ((2U << 16U) + 12U) +#define sfOwnerCount ((2U << 16U) + 13U) +#define sfDestinationTag ((2U << 16U) + 14U) +#define sfHighQualityIn ((2U << 16U) + 16U) +#define sfHighQualityOut ((2U << 16U) + 17U) +#define sfLowQualityIn ((2U << 16U) + 18U) +#define sfLowQualityOut ((2U << 16U) + 19U) +#define sfQualityIn ((2U << 16U) + 20U) +#define sfQualityOut ((2U << 16U) + 21U) +#define sfStampEscrow ((2U << 16U) + 22U) +#define sfBondAmount ((2U << 16U) + 23U) +#define sfLoadFee ((2U << 16U) + 24U) +#define sfOfferSequence ((2U << 16U) + 25U) +#define sfFirstLedgerSequence ((2U << 16U) + 26U) +#define sfLastLedgerSequence ((2U << 16U) + 27U) +#define sfTransactionIndex ((2U << 16U) + 28U) +#define sfOperationLimit ((2U << 16U) + 29U) +#define sfReferenceFeeUnits ((2U << 16U) + 30U) +#define sfReserveBase ((2U << 16U) + 31U) +#define sfReserveIncrement ((2U << 16U) + 32U) +#define sfSetFlag ((2U << 16U) + 33U) +#define sfClearFlag ((2U << 16U) + 34U) +#define sfSignerQuorum ((2U << 16U) + 35U) +#define sfCancelAfter ((2U << 16U) + 36U) +#define sfFinishAfter ((2U << 16U) + 37U) +#define sfSignerListID ((2U << 16U) + 38U) +#define sfSettleDelay ((2U << 16U) + 39U) +#define sfTicketCount ((2U << 16U) + 40U) +#define sfTicketSequence ((2U << 16U) + 41U) +#define sfNFTokenTaxon ((2U << 16U) + 42U) +#define sfMintedNFTokens ((2U << 16U) + 43U) +#define sfBurnedNFTokens ((2U << 16U) + 44U) +#define sfHookStateCount ((2U << 16U) + 45U) +#define sfEmitGeneration ((2U << 16U) + 46U) +#define sfLockCount ((2U << 16U) + 47U) +#define sfRewardTime ((2U << 16U) + 98U) +#define sfRewardLgrFirst ((2U << 16U) + 99U) +#define sfRewardLgrLast ((2U << 16U) + 100U) +#define sfIndexNext ((3U << 16U) + 1U) +#define sfIndexPrevious ((3U << 16U) + 2U) +#define sfBookNode ((3U << 16U) + 3U) +#define sfOwnerNode ((3U << 16U) + 4U) +#define sfBaseFee ((3U << 16U) + 5U) +#define sfExchangeRate ((3U << 16U) + 6U) +#define sfLowNode ((3U << 16U) + 7U) +#define sfHighNode ((3U << 16U) + 8U) +#define sfDestinationNode ((3U << 16U) + 9U) +#define sfCookie ((3U << 16U) + 10U) +#define sfServerVersion ((3U << 16U) + 11U) +#define sfNFTokenOfferNode ((3U << 16U) + 12U) +#define sfEmitBurden ((3U << 16U) + 13U) +#define sfHookInstructionCount ((3U << 16U) + 17U) +#define sfHookReturnCode ((3U << 16U) + 18U) +#define sfReferenceCount ((3U << 16U) + 19U) +#define sfRewardAccumulator ((3U << 16U) + 100U) +#define sfEmailHash ((4U << 16U) + 1U) +#define sfTakerPaysCurrency ((10U << 16U) + 1U) +#define sfTakerPaysIssuer ((10U << 16U) + 2U) +#define sfTakerGetsCurrency ((10U << 16U) + 3U) +#define sfTakerGetsIssuer ((10U << 16U) + 4U) +#define sfLedgerHash ((5U << 16U) + 1U) +#define sfParentHash ((5U << 16U) + 2U) +#define sfTransactionHash ((5U << 16U) + 3U) +#define sfAccountHash ((5U << 16U) + 4U) +#define sfPreviousTxnID ((5U << 16U) + 5U) +#define sfLedgerIndex ((5U << 16U) + 6U) +#define sfWalletLocator ((5U << 16U) + 7U) +#define sfRootIndex ((5U << 16U) + 8U) +#define sfAccountTxnID ((5U << 16U) + 9U) +#define sfNFTokenID ((5U << 16U) + 10U) +#define sfEmitParentTxnID ((5U << 16U) + 11U) +#define sfEmitNonce ((5U << 16U) + 12U) +#define sfEmitHookHash ((5U << 16U) + 13U) +#define sfBookDirectory ((5U << 16U) + 16U) +#define sfInvoiceID ((5U << 16U) + 17U) +#define sfNickname ((5U << 16U) + 18U) +#define sfAmendment ((5U << 16U) + 19U) +#define sfHookOn ((5U << 16U) + 20U) +#define sfDigest ((5U << 16U) + 21U) +#define sfChannel ((5U << 16U) + 22U) +#define sfConsensusHash ((5U << 16U) + 23U) +#define sfCheckID ((5U << 16U) + 24U) +#define sfValidatedHash ((5U << 16U) + 25U) +#define sfPreviousPageMin ((5U << 16U) + 26U) +#define sfNextPageMin ((5U << 16U) + 27U) +#define sfNFTokenBuyOffer ((5U << 16U) + 28U) +#define sfNFTokenSellOffer ((5U << 16U) + 29U) +#define sfHookStateKey ((5U << 16U) + 30U) +#define sfHookHash ((5U << 16U) + 31U) +#define sfHookNamespace ((5U << 16U) + 32U) +#define sfHookSetTxnID ((5U << 16U) + 33U) +#define sfOfferID ((5U << 16U) + 34U) +#define sfEscrowID ((5U << 16U) + 35U) +#define sfURITokenID ((5U << 16U) + 36U) +#define sfAmount ((6U << 16U) + 1U) +#define sfBalance ((6U << 16U) + 2U) +#define sfLimitAmount ((6U << 16U) + 3U) +#define sfTakerPays ((6U << 16U) + 4U) +#define sfTakerGets ((6U << 16U) + 5U) +#define sfLowLimit ((6U << 16U) + 6U) +#define sfHighLimit ((6U << 16U) + 7U) +#define sfFee ((6U << 16U) + 8U) +#define sfSendMax ((6U << 16U) + 9U) +#define sfDeliverMin ((6U << 16U) + 10U) +#define sfMinimumOffer ((6U << 16U) + 16U) +#define sfRippleEscrow ((6U << 16U) + 17U) +#define sfDeliveredAmount ((6U << 16U) + 18U) +#define sfNFTokenBrokerFee ((6U << 16U) + 19U) +#define sfHookCallbackFee ((6U << 16U) + 20U) +#define sfLockedBalance ((6U << 16U) + 21U) +#define sfPublicKey ((7U << 16U) + 1U) +#define sfMessageKey ((7U << 16U) + 2U) +#define sfSigningPubKey ((7U << 16U) + 3U) +#define sfTxnSignature ((7U << 16U) + 4U) +#define sfURI ((7U << 16U) + 5U) +#define sfSignature ((7U << 16U) + 6U) +#define sfDomain ((7U << 16U) + 7U) +#define sfFundCode ((7U << 16U) + 8U) +#define sfRemoveCode ((7U << 16U) + 9U) +#define sfExpireCode ((7U << 16U) + 10U) +#define sfCreateCode ((7U << 16U) + 11U) +#define sfMemoType ((7U << 16U) + 12U) +#define sfMemoData ((7U << 16U) + 13U) +#define sfMemoFormat ((7U << 16U) + 14U) +#define sfFulfillment ((7U << 16U) + 16U) +#define sfCondition ((7U << 16U) + 17U) +#define sfMasterSignature ((7U << 16U) + 18U) +#define sfUNLModifyValidator ((7U << 16U) + 19U) +#define sfValidatorToDisable ((7U << 16U) + 20U) +#define sfValidatorToReEnable ((7U << 16U) + 21U) +#define sfHookStateData ((7U << 16U) + 22U) +#define sfHookReturnString ((7U << 16U) + 23U) +#define sfHookParameterName ((7U << 16U) + 24U) +#define sfHookParameterValue ((7U << 16U) + 25U) +#define sfBlob ((7U << 16U) + 26U) +#define sfAccount ((8U << 16U) + 1U) +#define sfOwner ((8U << 16U) + 2U) +#define sfDestination ((8U << 16U) + 3U) +#define sfIssuer ((8U << 16U) + 4U) +#define sfAuthorize ((8U << 16U) + 5U) +#define sfUnauthorize ((8U << 16U) + 6U) +#define sfRegularKey ((8U << 16U) + 8U) +#define sfNFTokenMinter ((8U << 16U) + 9U) +#define sfEmitCallback ((8U << 16U) + 10U) +#define sfHookAccount ((8U << 16U) + 16U) +#define sfIndexes ((19U << 16U) + 1U) +#define sfHashes ((19U << 16U) + 2U) +#define sfAmendments ((19U << 16U) + 3U) +#define sfNFTokenOffers ((19U << 16U) + 4U) +#define sfHookNamespaces ((19U << 16U) + 5U) +#define sfPaths ((18U << 16U) + 1U) +#define sfTransactionMetaData ((14U << 16U) + 2U) +#define sfCreatedNode ((14U << 16U) + 3U) +#define sfDeletedNode ((14U << 16U) + 4U) +#define sfModifiedNode ((14U << 16U) + 5U) +#define sfPreviousFields ((14U << 16U) + 6U) +#define sfFinalFields ((14U << 16U) + 7U) +#define sfNewFields ((14U << 16U) + 8U) +#define sfTemplateEntry ((14U << 16U) + 9U) +#define sfMemo ((14U << 16U) + 10U) +#define sfSignerEntry ((14U << 16U) + 11U) +#define sfNFToken ((14U << 16U) + 12U) +#define sfEmitDetails ((14U << 16U) + 13U) +#define sfHook ((14U << 16U) + 14U) +#define sfSigner ((14U << 16U) + 16U) +#define sfMajority ((14U << 16U) + 18U) +#define sfDisabledValidator ((14U << 16U) + 19U) +#define sfEmittedTxn ((14U << 16U) + 20U) +#define sfHookExecution ((14U << 16U) + 21U) +#define sfHookDefinition ((14U << 16U) + 22U) +#define sfHookParameter ((14U << 16U) + 23U) +#define sfHookGrant ((14U << 16U) + 24U) +#define sfSigners ((15U << 16U) + 3U) +#define sfSignerEntries ((15U << 16U) + 4U) +#define sfTemplate ((15U << 16U) + 5U) +#define sfNecessary ((15U << 16U) + 6U) +#define sfSufficient ((15U << 16U) + 7U) +#define sfAffectedNodes ((15U << 16U) + 8U) +#define sfMemos ((15U << 16U) + 9U) +#define sfNFTokens ((15U << 16U) + 10U) +#define sfHooks ((15U << 16U) + 11U) +#define sfMajorities ((15U << 16U) + 16U) +#define sfDisabledValidators ((15U << 16U) + 17U) +#define sfHookExecutions ((15U << 16U) + 18U) +#define sfHookParameters ((15U << 16U) + 19U) +#define sfHookGrants ((15U << 16U) + 20U) +#define sfActiveValidators ((15U << 16U) + 95U) \ No newline at end of file diff --git a/hook/genesis/headers/types.h b/hook/genesis/headers/types.h new file mode 100644 index 000000000..2a3c66f98 --- /dev/null +++ b/hook/genesis/headers/types.h @@ -0,0 +1,239 @@ +#include + +// 8 byte-int = 1 bytes +#define SFL_CLOSERESOLUTION 1 +#define SFL_METHOD 1 +#define SFL_TRANSACTIONRESULT 1 +#define SFL_TICKSIZE 1 +#define SFL_UNLMODIFYDISABLING 1 +#define SFL_HOOKRESULT 1 +// 16 byte-int = 2 bytes +#define SFL_LEDGERENTRYTYPE 2 +#define SFL_TRANSACTIONTYPE 2 +#define SFL_SIGNERWEIGHT 2 +#define SFL_TRANSFERFEE 2 +#define SFL_VERSION 2 +#define SFL_HOOKSTATECHANGECOUNT 2 +#define SFL_HOOKEMITCOUNT 2 +#define SFL_HOOKEXECUTIONINDEX 2 +#define SFL_HOOKAPIVERSION 2 +// 32 byte-int = 4 bytes +#define SFL_NETWORKID 4 +#define SFL_FLAGS 4 +#define SFL_SOURCETAG 4 +#define SFL_SEQUENCE 4 +#define SFL_PREVIOUSTXNLGRSEQ 4 +#define SFL_LEDGERSEQUENCE 4 +#define SFL_CLOSETIME 4 +#define SFL_PARENTCLOSETIME 4 +#define SFL_SIGNINGTIME 4 +#define SFL_EXPIRATION 4 +#define SFL_TRANSFERRATE 4 +#define SFL_WALLETSIZE 4 +#define SFL_OWNERCOUNT 4 +#define SFL_DESTINATIONTAG 4 +#define SFL_HIGHQUALITYIN 4 +#define SFL_HIGHQUALITYOUT 4 +#define SFL_LOWQUALITYIN 4 +#define SFL_LOWQUALITYOUT 4 +#define SFL_QUALITYIN 4 +#define SFL_QUALITYOUT 4 +#define SFL_STAMPESCROW 4 +#define SFL_BONDAMOUNT 4 +#define SFL_LOADFEE 4 +#define SFL_OFFERSEQUENCE 4 +#define SFL_FIRSTLEDGERSEQUENCE 4 +#define SFL_LASTLEDGERSEQUENCE 4 +#define SFL_TRANSACTIONINDEX 4 +#define SFL_OPERATIONLIMIT 4 +#define SFL_REFERENCEFEEUNITS 4 +#define SFL_RESERVEBASE 4 +#define SFL_RESERVEINCREMENT 4 +#define SFL_SETFLAG 4 +#define SFL_CLEARFLAG 4 +#define SFL_SIGNERQUORUM 4 +#define SFL_CANCELAFTER 4 +#define SFL_FINISHAFTER 4 +#define SFL_SIGNERLISTID 4 +#define SFL_SETTLEDELAY 4 +#define SFL_TICKETCOUNT 4 +#define SFL_TICKETSEQUENCE 4 +#define SFL_NFTOKENTAXON 4 +#define SFL_MINTEDNFTOKENS 4 +#define SFL_BURNEDNFTOKENS 4 +#define SFL_HOOKSTATECOUNT 4 +#define SFL_EMITGENERATION 4 +#define SFL_LOCKCOUNT 4 +#define SFL_REWARDTIME 4 +#define SFL_REWARDLGRFIRST 4 +#define SFL_REWARDLGRLAST 4 +#define SFL_FIRSTNFTOKENSEQUENCE 4 +// 64 byte-int = 8 bytes +#define SFL_INDEX_NEXT 8 +#define SFL_INDEX_PREVIOUS 8 +#define SFL_BOOK_NODE 8 +#define SFL_OWNER_NODE 8 +#define SFL_BASE_FEE 8 +#define SFL_EXCHANGE_RATE 8 +#define SFL_LOW_NODE 8 +#define SFL_HIGH_NODE 8 +#define SFL_DESTINATION_NODE 8 +#define SFL_COOKIE 8 +#define SFL_SERVER_VERSION 8 +#define SFL_EMIT_BURDEN 8 +#define SFL_NFTOKEN_OFFER_NODE 8 +#define SFL_HOOK_INSTRUCTION_COUNT 8 +#define SFL_HOOK_RETURN_CODE 8 +#define SFL_REFERENCE_COUNT 8 +#define SFL_REWARD_ACCUMULATOR 8 +// 128 byte-int = 4 bytes +#define SFL_EMAIL_HASH 128 +// 160 byte-int = 4 bytes +#define SFL_TAKER_PAYS_CURRENCY 160 +#define SFL_TAKER_PAYS_ISSUER 160 +#define SFL_TAKER_GETS_CURRENCY 160 +#define SFL_TAKER_GETS_ISSUER 160 +// 256 byte-int = ??? bytes +#define SFL_LEDGER_HASH 256 +#define SFL_PARENT_HASH 256 +#define SFL_TRANSACTION_HASH 256 +#define SFL_ACCOUNT_HASH 256 +#define SFL_HOOK_ON 256 +#define SFL_PREVIOUS_TXN_ID 256 +#define SFL_LEDGER_INDEX 256 +#define SFL_WALLET_LOCATOR 256 +#define SFL_ROOT_INDEX 256 +#define SFL_ACCOUNT_TXN_ID 256 +#define SFL_NFTOKEN_ID 256 +#define SFL_EMIT_PARENT_TXN_ID 256 +#define SFL_EMIT_NONCE 256 +#define SFL_EMIT_HOOK_HASH 256 +// 256 byte-int = ??? bytes +#define SFL_BOOK_DIRECTORY 256 +#define SFL_INVOICE_ID 256 +#define SFL_NICKNAME 256 +#define SFL_AMENDMENT 256 +#define SFL_DIGEST 256 +#define SFL_CHANNEL 256 +#define SFL_CONSENSUS_HASH 256 +#define SFL_CHECK_ID 256 +#define SFL_VALIDATED_HASH 256 +#define SFL_PREVIOUS_PAGE_MIN 256 +#define SFL_NEXT_PAGE_MIN 256 +#define SFL_NFTOKEN_BUY_OFFER 256 +#define SFL_NFTOKEN_SELL_OFFER 256 +#define SFL_HOOK_STATE_KEY 256 +#define SFL_HOOK_HASH 256 +#define SFL_HOOK_NAMESPACE 256 +#define SFL_HOOK_SET_TXN_ID 256 +#define SFL_OFFER_ID 256 +#define SFL_ESCROW_ID 256 +#define SFL_URITOKEN_ID 256 +// 20 bytes +#define SFL_AMOUNT 20 +#define SFL_BALANCE 20 +#define SFL_LIMIT_AMOUNT 20 +#define SFL_TAKER_PAYS 20 +#define SFL_TAKER_GETS 20 +#define SFL_LOW_LIMIT 20 +#define SFL_HIGH_LIMIT 20 +#define SFL_FEE 20 +#define SFL_SEND_MAX 20 +#define SFL_DELIVER_MIN 20 +#define SFL_LOCKED_BALANCE 20 +// Unimplemented +#define SFL_AMOUNT_MINIMUM_OFFER 8 +#define SFL_AMOUNT_RIPPLE_ESCROW 8 +#define SFL_AMOUNT_DELIVERED_AMOUNT 8 +#define SFL_AMOUNT_NFTOKEN_BROKER_FEE 8 +#define SFL_AMOUNT_HOOK_CALLBACK_FEE 8 +#define SFL_AMOUNT_BASE_FEE_DROPS 8 +#define SFL_AMOUNT_RESERVE_BASE_DROPS 8 +#define SFL_AMOUNT_RESERVE_INCREMENT_DROPS 8 +// Unimplemented +#define SFL_VL_PUBLIC_KEY 64 +#define SFL_VL_MESSAGE_KEY 64 +#define SFL_VL_SIGNING_PUB_KEY 64 +// Unimplemented +#define SFL_VL_TXN_SIGNATURE 96 +// Unimplemented +#define SFL_VL_URI 256 +// Unimplemented +#define SFL_VL_SIGNATURE 96 +// Unimplemented +#define SFL_VL_DOMAIN 256 +#define SFL_VL_FUND_CODE 256 +#define SFL_VL_REMOVE_CODE 256 +#define SFL_VL_EXPIRE_CODE 256 +#define SFL_VL_CREATE_CODE 256 +#define SFL_VL_MEMO_TYPE 256 +#define SFL_VL_MEMO_DATA 256 +#define SFL_VL_MEMO_FORMAT 256 +#define SFL_VL_FULFILLMENT 256 +#define SFL_VL_CONDITION 256 +// Unimplemented +#define SFL_VL_MASTER_SIGNATURE 96 +// Unimplemented +#define SFL_VL_UNL_MODIFY_VALIDATOR 256 +#define SFL_VL_VALIDATOR_TO_DISABLE 256 +#define SFL_VL_VALIDATOR_TO_RE_ENABLE 256 +#define SFL_VL_HOOK_STATE_DATA 256 +#define SFL_VL_HOOK_RETURN_STRING 256 +#define SFL_VL_HOOK_PARAMETER_NAME 256 +#define SFL_VL_HOOK_PARAMETER_VALUE 256 +#define SFL_VL_BLOB 256 +// 20 bytes +#define SFL_ACCOUNT 20 +#define SFL_OWNER 20 +#define SFL_DESTINATION 20 +#define SFL_ISSUER 20 +#define SFL_AUTHORIZE 20 +#define SFL_UNAUTHORIZE 20 +#define SFL_REGULAR_KEY 20 +#define SFL_NFTOKEN_MINTER 20 +#define SFL_EMIT_CALLBACK 20 +#define SFL_HOOK_ACCOUNT 20 +#define SFL_NFTOKEN_MINTER 20 +// Unimplemented +#define SFL_PATHS 1 +// Unimplemented +#define SFL_VECTOR256_INDEXES 32 +#define SFL_VECTOR256_HASHES 32 +#define SFL_VECTOR256_AMENDMENTS 32 +#define SFL_VECTOR256_NFTOKEN_OFFERS 32 +#define SFL_VECTOR256_HOOK_NAMESPACES 32 +// Unimplemented +#define SFL_TRANSACTION_META_DATA 1 +#define SFL_CREATED_NODE 1 +#define SFL_DELETED_NODE 1 +#define SFL_MODIFIED_NODE 1 +#define SFL_PREVIOUS_FIELDS 1 +#define SFL_FINAL_FIELDS 1 +#define SFL_NEW_FIELDS 1 +#define SFL_TEMPLATE_ENTRY 1 +#define SFL_MEMO 1 +#define SFL_SIGNER_ENTRY 1 +#define SFL_NFTOKEN 1 +#define SFL_EMIT_DETAILS 1 +#define SFL_HOOK 1 +#define SFL_SIGNER 1 +#define SFL_MAJORITY 1 +#define SFL_DISABLED_VALIDATOR 1 +#define SFL_EMITTED_TXN 1 +#define SFL_HOOK_EXECUTION 1 +#define SFL_HOOK_DEFINITION 1 +#define SFL_HOOK_PARAMETER 1 +#define SFL_HOOK_GRANT 1 +#define SFL_SIGNERS 1 +#define SFL_SIGNER_ENTRIES 1 +#define SFL_TEMPLATE 1 +#define SFL_NECESSARY 1 +#define SFL_SUFFICIENT 1 +#define SFL_AFFECTED_NODES 1 +#define SFL_MEMOS 1 +#define SFL_NFTOKENS 1 +#define SFL_HOOKS 1 +#define SFL_MAJORITIES 1 +#define SFL_DISABLED_VALIDATORS 1 +#define SFL_HOOK_EXECUTIONS 1 +#define SFL_HOOK_EXECUTION 1 diff --git a/hook/genesis/makefile b/hook/genesis/makefile index 953e86441..7df39f21a 100644 --- a/hook/genesis/makefile +++ b/hook/genesis/makefile @@ -1,9 +1,9 @@ all: reward govern mint accept: - wasmcc accept.c -o accept.wasm -Oz -Wl,--allow-undefined -I../ + wasmcc accept.c -o accept.wasm -Oz -Wl,--allow-undefined -I./headers hook-cleaner accept.wasm reward: - wasmcc reward.c -o reward.wasm -Oz -Wl,--allow-undefined -I../ + wasmcc reward.c -o reward.wasm -Oz -Wl,--allow-undefined -I./headers wasm-opt reward.wasm -o reward.wasm \ --shrink-level=100000000 \ --coalesce-locals-learning \ @@ -58,7 +58,7 @@ reward: hook-cleaner reward.wasm guard_checker reward.wasm govern: - wasmcc govern.c -o govern.wasm -Oz -Wl,--allow-undefined -I../ + wasmcc govern.c -o govern.wasm -Oz -Wl,--allow-undefined -I./headers wasm-opt govern.wasm -o govern.wasm \ --shrink-level=100000000 \ --coalesce-locals-learning \ @@ -113,7 +113,7 @@ govern: hook-cleaner govern.wasm guard_checker govern.wasm mint: - wasmcc mint.c -o mint.wasm -Oz -Wl,--allow-undefined -I../ + wasmcc mint.c -o mint.wasm -Oz -Wl,--allow-undefined -I./headers wasm-opt mint.wasm -o mint.wasm \ --shrink-level=100000000 \ --coalesce-locals-learning \ @@ -142,5 +142,5 @@ mint: hook-cleaner mint.wasm guard_checker mint.wasm nftoken: - wasmcc nftoken.c -o nftoken.wasm -Oz -Wl,--allow-undefined -I../ + wasmcc nftoken.c -o nftoken.wasm -Oz -Wl,--allow-undefined -I./headers hook-cleaner nftoken.wasm diff --git a/hook/hookapi.h b/hook/hookapi.h index eb9751f14..69890544b 100644 --- a/hook/hookapi.h +++ b/hook/hookapi.h @@ -49,4 +49,7 @@ #include "macro.h" #include "tts.h" +#include "ls_flags.h" +#include "tx_flags.h" + #endif diff --git a/hook/ls_flags.h b/hook/ls_flags.h new file mode 100644 index 000000000..2ce87f081 --- /dev/null +++ b/hook/ls_flags.h @@ -0,0 +1,75 @@ +// Generated using generate_lsflags.sh + +#ifndef HOOKLSFLAGS_INCLUDED +#define HOOKLSFLAGS_INCLUDED 1 + +enum ltACCOUNT_ROOT { + lsfPasswordSpent = 0x00010000, + lsfRequireDestTag = 0x00020000, + lsfRequireAuth = 0x00040000, + lsfDisallowXRP = 0x00080000, + lsfDisableMaster = 0x00100000, + lsfNoFreeze = 0x00200000, + lsfGlobalFreeze = 0x00400000, + lsfDefaultRipple = 0x00800000, + lsfDepositAuth = 0x01000000, + lsfTshCollect = 0x02000000, + lsfDisallowIncomingNFTokenOffer = 0x04000000, + lsfDisallowIncomingCheck = 0x08000000, + lsfDisallowIncomingPayChan = 0x10000000, + lsfDisallowIncomingTrustline = 0x20000000, + lsfURITokenIssuer = 0x40000000, + lsfDisallowIncomingRemit = 0x80000000, + lsfAllowTrustLineClawback = 0x00001000, +}; +enum ltOFFER { + lsfPassive = 0x00010000, + lsfSell = 0x00020000, +}; +enum ltRIPPLE_STATE { + lsfLowReserve = 0x00010000, + lsfHighReserve = 0x00020000, + lsfLowAuth = 0x00040000, + lsfHighAuth = 0x00080000, + lsfLowNoRipple = 0x00100000, + lsfHighNoRipple = 0x00200000, + lsfLowFreeze = 0x00400000, + lsfHighFreeze = 0x00800000, + lsfLowDeepFreeze = 0x02000000, + lsfHighDeepFreeze = 0x04000000, + lsfAMMNode = 0x01000000, +}; +enum ltSIGNER_LIST { + lsfOneOwnerCount = 0x00010000, +}; +enum ltDIR_NODE { + lsfNFTokenBuyOffers = 0x00000001, + lsfNFTokenSellOffers = 0x00000002, + lsfEmittedDir = 0x00000004, +}; +enum ltNFTOKEN_OFFER { + lsfSellNFToken = 0x00000001, +}; +enum ltURI_TOKEN { + lsfBurnable = 0x00000001, +}; +enum remarks { + lsfImmutable = 1, +}; +enum ltMPTOKEN_ISSUANCE { + lsfMPTLocked = 0x00000001, + lsfMPTCanLock = 0x00000002, + lsfMPTRequireAuth = 0x00000004, + lsfMPTCanEscrow = 0x00000008, + lsfMPTCanTrade = 0x00000010, + lsfMPTCanTransfer = 0x00000020, + lsfMPTCanClawback = 0x00000040, +}; +enum ltMPTOKEN { + lsfMPTAuthorized = 0x00000002, +}; +enum ltCREDENTIAL { + lsfAccepted = 0x00010000, +}; + +#endif // HOOKLSFLAGS_INCLUDED diff --git a/hook/sfcodes.h b/hook/sfcodes.h index bd0cb773a..bc85248c8 100644 --- a/hook/sfcodes.h +++ b/hook/sfcodes.h @@ -279,7 +279,6 @@ #define sfDisabledValidator ((14U << 16U) + 19U) #define sfEmittedTxn ((14U << 16U) + 20U) #define sfHookExecution ((14U << 16U) + 21U) -#define sfHookDefinition ((14U << 16U) + 22U) #define sfHookParameter ((14U << 16U) + 23U) #define sfHookGrant ((14U << 16U) + 24U) #define sfVoteEntry ((14U << 16U) + 25U) diff --git a/hook/tx_flags.h b/hook/tx_flags.h new file mode 100644 index 000000000..79ecd9be8 --- /dev/null +++ b/hook/tx_flags.h @@ -0,0 +1,117 @@ +// Generated using generate_txflags.sh +#include "ls_flags.h" +#include + +enum UniversalFlags : uint32_t { + tfFullyCanonicalSig = 0x80000000, +}; + +enum AccountSetFlags : uint32_t { + tfRequireDestTag = 0x00010000, + tfOptionalDestTag = 0x00020000, + tfRequireAuth = 0x00040000, + tfOptionalAuth = 0x00080000, + tfDisallowXRP = 0x00100000, + tfAllowXRP = 0x00200000, +}; + +enum AccountFlags : uint32_t { + asfRequireDest = 1, + asfRequireAuth = 2, + asfDisallowXRP = 3, + asfDisableMaster = 4, + asfAccountTxnID = 5, + asfNoFreeze = 6, + asfGlobalFreeze = 7, + asfDefaultRipple = 8, + asfDepositAuth = 9, + asfAuthorizedNFTokenMinter = 10, + asfTshCollect = 11, + asfDisallowIncomingNFTokenOffer = 12, + asfDisallowIncomingCheck = 13, + asfDisallowIncomingPayChan = 14, + asfDisallowIncomingTrustline = 15, + asfDisallowIncomingRemit = 16, + asfAllowTrustLineClawback = 17, +}; + +enum OfferCreateFlags : uint32_t { + tfPassive = 0x00010000, + tfImmediateOrCancel = 0x00020000, + tfFillOrKill = 0x00040000, + tfSell = 0x00080000, +}; + +enum PaymentFlags : uint32_t { + tfNoRippleDirect = 0x00010000, + tfPartialPayment = 0x00020000, + tfLimitQuality = 0x00040000, +}; + +enum TrustSetFlags : uint32_t { + tfSetfAuth = 0x00010000, + tfSetNoRipple = 0x00020000, + tfClearNoRipple = 0x00040000, + tfSetFreeze = 0x00100000, + tfClearFreeze = 0x00200000, + tfSetDeepFreeze = 0x00400000, + tfClearDeepFreeze = 0x00800000 +}; + +enum EnableAmendmentFlags : uint32_t { + tfGotMajority = 0x00010000, + tfLostMajority = 0x00020000, + tfTestSuite = 0x80000000, +}; + +enum PaymentChannelClaimFlags : uint32_t { + tfRenew = 0x00010000, + tfClose = 0x00020000, +}; + +enum NFTokenMintFlags : uint32_t { + tfBurnable = 0x00000001, + tfOnlyXRP = 0x00000002, + tfTrustLine = 0x00000004, + tfTransferable = 0x00000008, + tfMutable = 0x00000010, + tfStrongTSH = 0x00008000, +}; + +enum MPTokenIssuanceCreateFlags : uint32_t { + tfMPTCanLock = lsfMPTCanLock, + tfMPTRequireAuth = lsfMPTRequireAuth, + tfMPTCanEscrow = lsfMPTCanEscrow, + tfMPTCanTrade = lsfMPTCanTrade, + tfMPTCanTransfer = lsfMPTCanTransfer, + tfMPTCanClawback = lsfMPTCanClawback, +}; + +enum MPTokenAuthorizeFlags : uint32_t { + tfMPTUnauthorize = 0x00000001, +}; + +enum MPTokenIssuanceSetFlags : uint32_t { + tfMPTLock = 0x00000001, + tfMPTUnlock = 0x00000002, +}; + +enum NFTokenCreateOfferFlags : uint32_t { + tfSellNFToken = 0x00000001, +}; + +enum ClaimRewardFlags : uint32_t { + tfOptOut = 0x00000001, +}; + +enum CronSetFlags : uint32_t { + tfCronUnset = 0x00000001, +}; + +enum AMMClawbackFlags : uint32_t { + tfClawTwoAssets = 0x00000001, +}; + +enum BridgeModifyFlags : uint32_t { + tfClearAccountCreateAmount = 0x00010000, +}; diff --git a/include/xrpl/hook/xahau.h b/include/xrpl/hook/xahau.h index 2ebb5baca..0ac449db4 100644 --- a/include/xrpl/hook/xahau.h +++ b/include/xrpl/hook/xahau.h @@ -43,22 +43,22 @@ static const std::vector GovernanceHook = { 0x5FU, 0x73U, 0x75U, 0x62U, 0x61U, 0x72U, 0x72U, 0x61U, 0x79U, 0x00U, 0x05U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x04U, 0x73U, 0x6CU, 0x6FU, 0x74U, 0x00U, 0x05U, 0x03U, 0x02U, 0x01U, 0x01U, 0x05U, 0x03U, 0x01U, 0x00U, 0x02U, 0x06U, 0x08U, - 0x01U, 0x7FU, 0x01U, 0x41U, 0xF0U, 0x9AU, 0x04U, 0x0BU, 0x07U, 0x08U, 0x01U, - 0x04U, 0x68U, 0x6FU, 0x6FU, 0x6BU, 0x00U, 0x16U, 0x0AU, 0xA5U, 0xAFU, 0x00U, - 0x01U, 0xA1U, 0xAFU, 0x00U, 0x03U, 0x09U, 0x7FU, 0x05U, 0x7EU, 0x01U, 0x7CU, + 0x01U, 0x7FU, 0x01U, 0x41U, 0x90U, 0x9BU, 0x04U, 0x0BU, 0x07U, 0x08U, 0x01U, + 0x04U, 0x68U, 0x6FU, 0x6FU, 0x6BU, 0x00U, 0x16U, 0x0AU, 0xB2U, 0xAFU, 0x00U, + 0x01U, 0xAEU, 0xAFU, 0x00U, 0x03U, 0x0AU, 0x7FU, 0x05U, 0x7EU, 0x02U, 0x7CU, 0x23U, 0x00U, 0x41U, 0xB0U, 0x0AU, 0x6BU, 0x22U, 0x00U, 0x24U, 0x00U, 0x41U, 0x01U, 0x41U, 0x01U, 0x10U, 0x00U, 0x1AU, 0x41U, 0x01U, 0x10U, 0x01U, 0x1AU, - 0x20U, 0x00U, 0x41U, 0x80U, 0x01U, 0x6AU, 0x41U, 0x02U, 0x41U, 0xD2U, 0x0AU, - 0x41U, 0x01U, 0x10U, 0x02U, 0x42U, 0x02U, 0x51U, 0x04U, 0x40U, 0x41U, 0xC4U, - 0x0AU, 0x41U, 0x06U, 0x20U, 0x00U, 0x31U, 0x00U, 0x81U, 0x01U, 0x20U, 0x00U, + 0x20U, 0x00U, 0x41U, 0x80U, 0x01U, 0x6AU, 0x41U, 0x02U, 0x41U, 0x94U, 0x08U, + 0x41U, 0x01U, 0x10U, 0x02U, 0x42U, 0x02U, 0x51U, 0x04U, 0x40U, 0x41U, 0x96U, + 0x08U, 0x41U, 0x06U, 0x20U, 0x00U, 0x31U, 0x00U, 0x81U, 0x01U, 0x20U, 0x00U, 0x31U, 0x00U, 0x80U, 0x01U, 0x42U, 0x08U, 0x86U, 0x84U, 0x10U, 0x03U, 0x1AU, - 0x0BU, 0x10U, 0x04U, 0x42U, 0xE3U, 0x00U, 0x52U, 0x04U, 0x40U, 0x41U, 0xADU, - 0x0DU, 0x41U, 0xCCU, 0x00U, 0x42U, 0x81U, 0x01U, 0x10U, 0x05U, 0x1AU, 0x0BU, - 0x20U, 0x00U, 0x41U, 0x90U, 0x0AU, 0x6AU, 0x41U, 0x0CU, 0x72U, 0x22U, 0x02U, + 0x0BU, 0x10U, 0x04U, 0x42U, 0xE3U, 0x00U, 0x52U, 0x04U, 0x40U, 0x41U, 0x9CU, + 0x08U, 0x41U, 0xCCU, 0x00U, 0x42U, 0x81U, 0x01U, 0x10U, 0x05U, 0x1AU, 0x0BU, + 0x20U, 0x00U, 0x41U, 0x90U, 0x0AU, 0x6AU, 0x41U, 0x0CU, 0x72U, 0x22U, 0x04U, 0x41U, 0x14U, 0x41U, 0x81U, 0x80U, 0x20U, 0x10U, 0x06U, 0x1AU, 0x20U, 0x00U, 0x41U, 0xF0U, 0x09U, 0x6AU, 0x41U, 0x0CU, 0x72U, 0x22U, 0x08U, 0x41U, 0x14U, 0x10U, 0x07U, 0x1AU, 0x02U, 0x40U, 0x20U, 0x00U, 0x29U, 0x03U, 0xFCU, 0x09U, - 0x22U, 0x0BU, 0x20U, 0x00U, 0x29U, 0x03U, 0x9CU, 0x0AU, 0x51U, 0x04U, 0x40U, + 0x22U, 0x0CU, 0x20U, 0x00U, 0x29U, 0x03U, 0x9CU, 0x0AU, 0x51U, 0x04U, 0x40U, 0x20U, 0x00U, 0x28U, 0x02U, 0x8CU, 0x0AU, 0x20U, 0x00U, 0x28U, 0x02U, 0xACU, 0x0AU, 0x47U, 0x20U, 0x00U, 0x29U, 0x03U, 0x84U, 0x0AU, 0x20U, 0x00U, 0x29U, 0x03U, 0xA4U, 0x0AU, 0x52U, 0x72U, 0x0DU, 0x01U, 0x20U, 0x00U, 0x41U, 0x80U, @@ -67,751 +67,757 @@ static const std::vector GovernanceHook = { 0x09U, 0x20U, 0x00U, 0x29U, 0x03U, 0x80U, 0x01U, 0x51U, 0x04U, 0x40U, 0x20U, 0x00U, 0x29U, 0x03U, 0x84U, 0x0AU, 0x20U, 0x00U, 0x29U, 0x03U, 0x88U, 0x01U, 0x51U, 0x04U, 0x40U, 0x20U, 0x00U, 0x28U, 0x02U, 0x8CU, 0x0AU, 0x20U, 0x00U, - 0x28U, 0x02U, 0x90U, 0x01U, 0x46U, 0x0DU, 0x02U, 0x0BU, 0x0BU, 0x41U, 0xA5U, - 0x0FU, 0x41U, 0x21U, 0x42U, 0x8FU, 0x01U, 0x10U, 0x05U, 0x1AU, 0x0BU, 0x0BU, - 0x20U, 0x00U, 0x29U, 0x03U, 0xFCU, 0x09U, 0x21U, 0x0BU, 0x0BU, 0x0BU, 0x02U, - 0x7FU, 0x41U, 0xB0U, 0x1AU, 0x29U, 0x03U, 0x00U, 0x20U, 0x0BU, 0x51U, 0x04U, - 0x40U, 0x20U, 0x00U, 0x28U, 0x02U, 0x8CU, 0x0AU, 0x41U, 0xC0U, 0x1AU, 0x28U, - 0x02U, 0x00U, 0x47U, 0x20U, 0x00U, 0x29U, 0x03U, 0x84U, 0x0AU, 0x41U, 0xB8U, - 0x1AU, 0x29U, 0x03U, 0x00U, 0x52U, 0x72U, 0x45U, 0x04U, 0x40U, 0x41U, 0x01U, - 0x21U, 0x04U, 0x41U, 0x93U, 0x13U, 0x0CU, 0x02U, 0x0BU, 0x0BU, 0x41U, 0xE0U, - 0x12U, 0x0BU, 0x41U, 0x33U, 0x41U, 0x00U, 0x41U, 0x00U, 0x41U, 0x00U, 0x10U, - 0x08U, 0x1AU, 0x41U, 0x00U, 0x41U, 0x00U, 0x41U, 0xD5U, 0x0AU, 0x41U, 0x02U, - 0x10U, 0x09U, 0x22U, 0x0BU, 0x42U, 0x7BU, 0x51U, 0x04U, 0x40U, 0x20U, 0x00U, - 0x41U, 0x90U, 0x09U, 0x6AU, 0x41U, 0x01U, 0x41U, 0xD4U, 0x0AU, 0x41U, 0x03U, - 0x10U, 0x0AU, 0x42U, 0x00U, 0x53U, 0x04U, 0x40U, 0x41U, 0x9EU, 0x18U, 0x41U, - 0x3AU, 0x42U, 0xA3U, 0x01U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x41U, 0x9CU, 0x0AU, + 0x28U, 0x02U, 0x90U, 0x01U, 0x46U, 0x0DU, 0x02U, 0x0BU, 0x0BU, 0x41U, 0xE8U, + 0x08U, 0x41U, 0x21U, 0x42U, 0x8FU, 0x01U, 0x10U, 0x05U, 0x1AU, 0x0BU, 0x0BU, + 0x20U, 0x00U, 0x29U, 0x03U, 0xFCU, 0x09U, 0x21U, 0x0CU, 0x0BU, 0x0BU, 0x02U, + 0x7FU, 0x41U, 0x80U, 0x08U, 0x29U, 0x03U, 0x00U, 0x20U, 0x0CU, 0x51U, 0x04U, + 0x40U, 0x20U, 0x00U, 0x28U, 0x02U, 0x8CU, 0x0AU, 0x41U, 0x90U, 0x08U, 0x28U, + 0x02U, 0x00U, 0x47U, 0x20U, 0x00U, 0x29U, 0x03U, 0x84U, 0x0AU, 0x41U, 0x88U, + 0x08U, 0x29U, 0x03U, 0x00U, 0x52U, 0x72U, 0x45U, 0x04U, 0x40U, 0x41U, 0x01U, + 0x21U, 0x02U, 0x41U, 0x89U, 0x09U, 0x0CU, 0x02U, 0x0BU, 0x0BU, 0x41U, 0xBCU, + 0x09U, 0x0BU, 0x41U, 0x33U, 0x41U, 0x00U, 0x41U, 0x00U, 0x41U, 0x00U, 0x10U, + 0x08U, 0x1AU, 0x41U, 0x00U, 0x41U, 0x00U, 0x41U, 0xEFU, 0x09U, 0x41U, 0x02U, + 0x10U, 0x09U, 0x22U, 0x0CU, 0x42U, 0x7BU, 0x51U, 0x04U, 0x40U, 0x20U, 0x00U, + 0x41U, 0x90U, 0x09U, 0x6AU, 0x41U, 0x01U, 0x41U, 0xF2U, 0x09U, 0x41U, 0x03U, + 0x10U, 0x0AU, 0x42U, 0x7FU, 0x57U, 0x04U, 0x40U, 0x41U, 0xF6U, 0x09U, 0x41U, + 0x3AU, 0x42U, 0xA3U, 0x01U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x41U, 0xB0U, 0x0AU, 0x41U, 0x03U, 0x20U, 0x00U, 0x31U, 0x00U, 0x90U, 0x09U, 0x10U, 0x03U, 0x1AU, - 0x20U, 0x00U, 0x41U, 0x90U, 0x09U, 0x6AU, 0x41U, 0x01U, 0x41U, 0xD5U, 0x0AU, - 0x41U, 0x02U, 0x10U, 0x0CU, 0x42U, 0x00U, 0x57U, 0x04U, 0x40U, 0x41U, 0x83U, - 0x14U, 0x41U, 0x1AU, 0x42U, 0xA7U, 0x01U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x41U, - 0x80U, 0x08U, 0x41U, 0x0CU, 0x20U, 0x00U, 0x2DU, 0x00U, 0x90U, 0x09U, 0x22U, - 0x05U, 0xADU, 0x42U, 0xFFU, 0x01U, 0x83U, 0x22U, 0x0BU, 0x10U, 0x03U, 0x1AU, + 0x20U, 0x00U, 0x41U, 0x90U, 0x09U, 0x6AU, 0x41U, 0x01U, 0x41U, 0xEFU, 0x09U, + 0x41U, 0x02U, 0x10U, 0x0CU, 0x42U, 0x00U, 0x57U, 0x04U, 0x40U, 0x41U, 0xB4U, + 0x0AU, 0x41U, 0x1AU, 0x42U, 0xA7U, 0x01U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x41U, + 0xCEU, 0x0AU, 0x41U, 0x0CU, 0x20U, 0x00U, 0x2DU, 0x00U, 0x90U, 0x09U, 0x22U, + 0x03U, 0xADU, 0x42U, 0xFFU, 0x01U, 0x83U, 0x22U, 0x0CU, 0x10U, 0x03U, 0x1AU, 0x20U, 0x00U, 0x2DU, 0x00U, 0x90U, 0x09U, 0x22U, 0x01U, 0x45U, 0x04U, 0x40U, - 0x41U, 0x8EU, 0x16U, 0x41U, 0x2EU, 0x42U, 0xAEU, 0x01U, 0x10U, 0x0BU, 0x1AU, + 0x41U, 0xDBU, 0x0AU, 0x41U, 0x2EU, 0x42U, 0xAEU, 0x01U, 0x10U, 0x0BU, 0x1AU, 0x20U, 0x00U, 0x2DU, 0x00U, 0x90U, 0x09U, 0x21U, 0x01U, 0x0BU, 0x20U, 0x01U, - 0x41U, 0xFFU, 0x01U, 0x71U, 0x41U, 0x15U, 0x4FU, 0x04U, 0x40U, 0x41U, 0xD8U, - 0x18U, 0x41U, 0x3DU, 0x42U, 0xB1U, 0x01U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x20U, - 0x04U, 0x04U, 0x40U, 0x02U, 0x40U, 0x20U, 0x00U, 0x41U, 0xB0U, 0x09U, 0x6AU, - 0x41U, 0x08U, 0x41U, 0xC0U, 0x0AU, 0x41U, 0x03U, 0x10U, 0x0AU, 0x42U, 0x00U, - 0x53U, 0x04U, 0x40U, 0x41U, 0xAEU, 0x17U, 0x41U, 0x39U, 0x42U, 0xB6U, 0x01U, + 0x41U, 0xFFU, 0x01U, 0x71U, 0x41U, 0x15U, 0x4FU, 0x04U, 0x40U, 0x41U, 0x89U, + 0x0BU, 0x41U, 0x3DU, 0x42U, 0xB1U, 0x01U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x20U, + 0x02U, 0x04U, 0x40U, 0x02U, 0x40U, 0x20U, 0x00U, 0x41U, 0xB0U, 0x09U, 0x6AU, + 0x41U, 0x08U, 0x41U, 0xC6U, 0x0BU, 0x41U, 0x03U, 0x10U, 0x0AU, 0x42U, 0x7FU, + 0x57U, 0x04U, 0x40U, 0x41U, 0xCAU, 0x0BU, 0x41U, 0x39U, 0x42U, 0xB6U, 0x01U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x20U, 0x00U, 0x41U, 0x20U, 0x6AU, 0x41U, 0x08U, - 0x41U, 0xD0U, 0x0AU, 0x41U, 0x03U, 0x10U, 0x0AU, 0x42U, 0x00U, 0x53U, 0x04U, - 0x40U, 0x41U, 0xE7U, 0x17U, 0x41U, 0x37U, 0x42U, 0xB9U, 0x01U, 0x10U, 0x0BU, + 0x41U, 0x83U, 0x0CU, 0x41U, 0x03U, 0x10U, 0x0AU, 0x42U, 0x7FU, 0x57U, 0x04U, + 0x40U, 0x41U, 0x87U, 0x0CU, 0x41U, 0x37U, 0x42U, 0xB9U, 0x01U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x20U, 0x00U, 0x29U, 0x03U, 0x20U, 0x50U, 0x04U, 0x40U, 0x41U, - 0xE0U, 0x15U, 0x41U, 0x2EU, 0x42U, 0xBCU, 0x01U, 0x10U, 0x0BU, 0x1AU, 0x0BU, - 0x20U, 0x00U, 0x41U, 0xB0U, 0x09U, 0x6AU, 0x41U, 0x08U, 0x41U, 0xC1U, 0x0AU, - 0x41U, 0x02U, 0x10U, 0x0CU, 0x42U, 0x00U, 0x57U, 0x04U, 0x40U, 0x41U, 0x83U, - 0x14U, 0x41U, 0x1AU, 0x42U, 0xBFU, 0x01U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x20U, - 0x00U, 0x41U, 0x20U, 0x6AU, 0x41U, 0x08U, 0x41U, 0xD1U, 0x0AU, 0x41U, 0x02U, - 0x10U, 0x0CU, 0x42U, 0x00U, 0x55U, 0x0DU, 0x00U, 0x41U, 0x83U, 0x14U, 0x41U, - 0x1AU, 0x42U, 0xC2U, 0x01U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x0BU, 0x03U, 0x40U, - 0x41U, 0xC5U, 0x81U, 0x80U, 0x80U, 0x78U, 0x41U, 0x15U, 0x10U, 0x00U, 0x1AU, - 0x02U, 0x40U, 0x20U, 0x00U, 0x20U, 0x03U, 0x3AU, 0x00U, 0x00U, 0x20U, 0x00U, - 0x2DU, 0x00U, 0x00U, 0x22U, 0x01U, 0x20U, 0x05U, 0x4FU, 0x0DU, 0x00U, 0x20U, - 0x00U, 0x20U, 0x01U, 0x3AU, 0x00U, 0x52U, 0x20U, 0x00U, 0x41U, 0xC9U, 0xA6U, - 0x01U, 0x3BU, 0x00U, 0x50U, 0x20U, 0x00U, 0x41U, 0x80U, 0x01U, 0x6AU, 0x41U, - 0x14U, 0x20U, 0x00U, 0x41U, 0xD0U, 0x00U, 0x6AU, 0x41U, 0x03U, 0x10U, 0x0AU, - 0x42U, 0x14U, 0x52U, 0x04U, 0x40U, 0x41U, 0x99U, 0x09U, 0x41U, 0x3FU, 0x42U, - 0xCAU, 0x01U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x41U, 0xEEU, 0x0BU, 0x41U, 0x08U, - 0x20U, 0x00U, 0x41U, 0x80U, 0x01U, 0x6AU, 0x22U, 0x01U, 0x41U, 0x14U, 0x41U, - 0x01U, 0x10U, 0x08U, 0x1AU, 0x20U, 0x01U, 0x41U, 0x14U, 0x20U, 0x00U, 0x41U, - 0x01U, 0x10U, 0x0CU, 0x42U, 0x14U, 0x52U, 0x04U, 0x40U, 0x41U, 0x83U, 0x14U, - 0x41U, 0x1AU, 0x42U, 0xD0U, 0x01U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x20U, 0x00U, - 0x41U, 0x01U, 0x20U, 0x00U, 0x41U, 0x80U, 0x01U, 0x6AU, 0x41U, 0x14U, 0x10U, - 0x0CU, 0x42U, 0x01U, 0x52U, 0x04U, 0x40U, 0x41U, 0x83U, 0x14U, 0x41U, 0x1AU, - 0x42U, 0xD4U, 0x01U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x20U, 0x00U, 0x2DU, 0x00U, - 0x00U, 0x41U, 0x01U, 0x6AU, 0x21U, 0x03U, 0x0CU, 0x01U, 0x0BU, 0x0BU, 0x41U, - 0xD3U, 0x0CU, 0x41U, 0x2AU, 0x42U, 0xD7U, 0x01U, 0x10U, 0x05U, 0x1AU, 0x0BU, - 0x41U, 0x80U, 0x08U, 0x41U, 0x0CU, 0x20U, 0x0BU, 0x10U, 0x03U, 0x1AU, 0x41U, - 0x00U, 0x41U, 0x00U, 0x20U, 0x02U, 0x41U, 0x14U, 0x10U, 0x09U, 0x42U, 0x00U, - 0x53U, 0x04U, 0x40U, 0x41U, 0x9BU, 0x12U, 0x41U, 0xC5U, 0x00U, 0x42U, 0xE3U, - 0x01U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x20U, 0x00U, 0x41U, 0xEEU, 0x09U, 0x6AU, - 0x41U, 0x02U, 0x41U, 0xBEU, 0x0AU, 0x41U, 0x01U, 0x10U, 0x02U, 0x21U, 0x0AU, - 0x20U, 0x00U, 0x2DU, 0x00U, 0xEEU, 0x09U, 0x21U, 0x02U, 0x20U, 0x00U, 0x20U, - 0x00U, 0x2DU, 0x00U, 0xEFU, 0x09U, 0x22U, 0x01U, 0x3AU, 0x00U, 0xEDU, 0x09U, - 0x02U, 0x40U, 0x20U, 0x0AU, 0x42U, 0x02U, 0x51U, 0x04U, 0x40U, 0x02U, 0x40U, - 0x20U, 0x02U, 0x41U, 0xC8U, 0x00U, 0x6BU, 0x22U, 0x03U, 0x41U, 0x0BU, 0x4BU, - 0x0DU, 0x00U, 0x41U, 0x01U, 0x20U, 0x03U, 0x74U, 0x41U, 0x81U, 0x18U, 0x71U, - 0x0DU, 0x02U, 0x0BU, 0x0BU, 0x41U, 0x9BU, 0x0EU, 0x41U, 0x3DU, 0x42U, 0xF2U, - 0x01U, 0x10U, 0x0BU, 0x1AU, 0x20U, 0x00U, 0x2DU, 0x00U, 0xEDU, 0x09U, 0x21U, - 0x01U, 0x0BU, 0x20U, 0x02U, 0x41U, 0xD3U, 0x00U, 0x47U, 0x20U, 0x01U, 0x41U, - 0xFFU, 0x01U, 0x71U, 0x41U, 0x14U, 0x49U, 0x72U, 0x04U, 0x40U, 0x02U, 0x40U, - 0x20U, 0x02U, 0x41U, 0xC8U, 0x00U, 0x46U, 0x21U, 0x03U, 0x20U, 0x02U, 0x41U, - 0xC8U, 0x00U, 0x47U, 0x20U, 0x01U, 0x41U, 0xFFU, 0x01U, 0x71U, 0x41U, 0x0BU, - 0x49U, 0x72U, 0x45U, 0x04U, 0x40U, 0x41U, 0xB1U, 0x15U, 0x41U, 0x2FU, 0x42U, - 0xF9U, 0x01U, 0x10U, 0x0BU, 0x1AU, 0x0CU, 0x01U, 0x0BU, 0x20U, 0x02U, 0x41U, - 0xD2U, 0x00U, 0x47U, 0x0DU, 0x00U, 0x41U, 0x01U, 0x21U, 0x06U, 0x20U, 0x01U, - 0x41U, 0xFFU, 0x01U, 0x71U, 0x22U, 0x01U, 0x41U, 0xC4U, 0x00U, 0x46U, 0x20U, - 0x01U, 0x41U, 0xD2U, 0x00U, 0x46U, 0x72U, 0x0DU, 0x00U, 0x41U, 0xF2U, 0x16U, - 0x41U, 0x3CU, 0x42U, 0xFCU, 0x01U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x05U, 0x41U, - 0x81U, 0x15U, 0x41U, 0x30U, 0x42U, 0xF6U, 0x01U, 0x10U, 0x0BU, 0x1AU, 0x41U, - 0x00U, 0x21U, 0x03U, 0x0BU, 0x20U, 0x00U, 0x41U, 0x01U, 0x3AU, 0x00U, 0xECU, - 0x09U, 0x20U, 0x04U, 0x45U, 0x04U, 0x40U, 0x02U, 0x40U, 0x20U, 0x00U, 0x41U, - 0xECU, 0x09U, 0x6AU, 0x41U, 0x01U, 0x41U, 0xCCU, 0x0AU, 0x41U, 0x01U, 0x10U, - 0x02U, 0x42U, 0x01U, 0x52U, 0x04U, 0x40U, 0x41U, 0xD8U, 0x0AU, 0x41U, 0xC1U, - 0x00U, 0x42U, 0x84U, 0x02U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x41U, 0x88U, 0x09U, - 0x41U, 0x01U, 0x20U, 0x00U, 0x31U, 0x00U, 0xECU, 0x09U, 0x10U, 0x03U, 0x1AU, - 0x20U, 0x06U, 0x45U, 0x21U, 0x06U, 0x20U, 0x00U, 0x2DU, 0x00U, 0xECU, 0x09U, - 0x22U, 0x01U, 0x41U, 0x03U, 0x6BU, 0x41U, 0xFFU, 0x01U, 0x71U, 0x41U, 0xFDU, - 0x01U, 0x4DU, 0x04U, 0x40U, 0x41U, 0x95U, 0x19U, 0x41U, 0x30U, 0x42U, 0x89U, - 0x02U, 0x10U, 0x0BU, 0x1AU, 0x20U, 0x00U, 0x2DU, 0x00U, 0xECU, 0x09U, 0x21U, - 0x01U, 0x0BU, 0x20U, 0x01U, 0x41U, 0xFFU, 0x01U, 0x71U, 0x41U, 0x02U, 0x47U, - 0x20U, 0x06U, 0x72U, 0x0DU, 0x00U, 0x41U, 0x99U, 0x0BU, 0x41U, 0xC5U, 0x00U, + 0xBEU, 0x0CU, 0x41U, 0x2EU, 0x42U, 0xBCU, 0x01U, 0x10U, 0x0BU, 0x1AU, 0x0BU, + 0x20U, 0x00U, 0x41U, 0xB0U, 0x09U, 0x6AU, 0x41U, 0x08U, 0x41U, 0xECU, 0x0CU, + 0x41U, 0x02U, 0x10U, 0x0CU, 0x42U, 0x00U, 0x57U, 0x04U, 0x40U, 0x41U, 0xB4U, + 0x0AU, 0x41U, 0x1AU, 0x42U, 0xBFU, 0x01U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x20U, + 0x00U, 0x41U, 0x20U, 0x6AU, 0x41U, 0x08U, 0x41U, 0xEFU, 0x0CU, 0x41U, 0x02U, + 0x10U, 0x0CU, 0x42U, 0x00U, 0x55U, 0x0DU, 0x00U, 0x41U, 0xB4U, 0x0AU, 0x41U, + 0x1AU, 0x42U, 0xC2U, 0x01U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x0BU, 0x41U, 0x00U, + 0x21U, 0x01U, 0x03U, 0x40U, 0x41U, 0xC5U, 0x81U, 0x80U, 0x80U, 0x78U, 0x41U, + 0x15U, 0x10U, 0x00U, 0x1AU, 0x02U, 0x40U, 0x20U, 0x00U, 0x20U, 0x01U, 0x3AU, + 0x00U, 0x00U, 0x20U, 0x00U, 0x2DU, 0x00U, 0x00U, 0x22U, 0x01U, 0x20U, 0x03U, + 0x4FU, 0x0DU, 0x00U, 0x20U, 0x00U, 0x20U, 0x01U, 0x3AU, 0x00U, 0x52U, 0x20U, + 0x00U, 0x41U, 0xC9U, 0xA6U, 0x01U, 0x3BU, 0x00U, 0x50U, 0x20U, 0x00U, 0x41U, + 0x80U, 0x01U, 0x6AU, 0x41U, 0x14U, 0x20U, 0x00U, 0x41U, 0xD0U, 0x00U, 0x6AU, + 0x41U, 0x03U, 0x10U, 0x0AU, 0x42U, 0x14U, 0x52U, 0x04U, 0x40U, 0x41U, 0xF2U, + 0x0CU, 0x41U, 0x3FU, 0x42U, 0xCAU, 0x01U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x41U, + 0xB1U, 0x0DU, 0x41U, 0x08U, 0x20U, 0x00U, 0x41U, 0x80U, 0x01U, 0x6AU, 0x22U, + 0x01U, 0x41U, 0x14U, 0x41U, 0x01U, 0x10U, 0x08U, 0x1AU, 0x20U, 0x01U, 0x41U, + 0x14U, 0x20U, 0x00U, 0x41U, 0x01U, 0x10U, 0x0CU, 0x42U, 0x14U, 0x52U, 0x04U, + 0x40U, 0x41U, 0xB4U, 0x0AU, 0x41U, 0x1AU, 0x42U, 0xD0U, 0x01U, 0x10U, 0x0BU, + 0x1AU, 0x0BU, 0x20U, 0x00U, 0x41U, 0x01U, 0x20U, 0x00U, 0x41U, 0x80U, 0x01U, + 0x6AU, 0x41U, 0x14U, 0x10U, 0x0CU, 0x42U, 0x01U, 0x52U, 0x04U, 0x40U, 0x41U, + 0xB4U, 0x0AU, 0x41U, 0x1AU, 0x42U, 0xD4U, 0x01U, 0x10U, 0x0BU, 0x1AU, 0x0BU, + 0x20U, 0x00U, 0x2DU, 0x00U, 0x00U, 0x41U, 0x01U, 0x6AU, 0x21U, 0x01U, 0x0CU, + 0x01U, 0x0BU, 0x0BU, 0x41U, 0xB9U, 0x0DU, 0x41U, 0x2AU, 0x42U, 0xD7U, 0x01U, + 0x10U, 0x05U, 0x1AU, 0x0BU, 0x41U, 0xCEU, 0x0AU, 0x41U, 0x0CU, 0x20U, 0x0CU, + 0x10U, 0x03U, 0x1AU, 0x41U, 0x00U, 0x41U, 0x00U, 0x20U, 0x04U, 0x41U, 0x14U, + 0x10U, 0x09U, 0x42U, 0x7FU, 0x57U, 0x04U, 0x40U, 0x41U, 0xE3U, 0x0DU, 0x41U, + 0xC5U, 0x00U, 0x42U, 0xE3U, 0x01U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x20U, 0x00U, + 0x41U, 0xEEU, 0x09U, 0x6AU, 0x41U, 0x02U, 0x41U, 0xA8U, 0x0EU, 0x41U, 0x01U, + 0x10U, 0x02U, 0x21U, 0x0BU, 0x20U, 0x00U, 0x2DU, 0x00U, 0xEEU, 0x09U, 0x21U, + 0x04U, 0x20U, 0x00U, 0x20U, 0x00U, 0x2DU, 0x00U, 0xEFU, 0x09U, 0x22U, 0x01U, + 0x3AU, 0x00U, 0xEDU, 0x09U, 0x02U, 0x40U, 0x20U, 0x0BU, 0x42U, 0x02U, 0x51U, + 0x04U, 0x40U, 0x02U, 0x40U, 0x20U, 0x04U, 0x41U, 0xC8U, 0x00U, 0x6BU, 0x22U, + 0x03U, 0x41U, 0x0BU, 0x4BU, 0x0DU, 0x00U, 0x41U, 0x01U, 0x20U, 0x03U, 0x74U, + 0x41U, 0x81U, 0x18U, 0x71U, 0x0DU, 0x02U, 0x0BU, 0x0BU, 0x41U, 0xAAU, 0x0EU, + 0x41U, 0x3DU, 0x42U, 0xF2U, 0x01U, 0x10U, 0x0BU, 0x1AU, 0x20U, 0x00U, 0x2DU, + 0x00U, 0xEDU, 0x09U, 0x21U, 0x01U, 0x0BU, 0x02U, 0x40U, 0x20U, 0x04U, 0x41U, + 0xD3U, 0x00U, 0x46U, 0x04U, 0x40U, 0x20U, 0x01U, 0x41U, 0x14U, 0x4FU, 0x04U, + 0x40U, 0x41U, 0xE7U, 0x0EU, 0x41U, 0x30U, 0x42U, 0xF6U, 0x01U, 0x10U, 0x0BU, + 0x1AU, 0x41U, 0x00U, 0x21U, 0x03U, 0x41U, 0x01U, 0x21U, 0x05U, 0x0CU, 0x02U, + 0x0BU, 0x0BU, 0x20U, 0x04U, 0x41U, 0xC8U, 0x00U, 0x46U, 0x04U, 0x40U, 0x20U, + 0x01U, 0x41U, 0x0BU, 0x4FU, 0x04U, 0x40U, 0x41U, 0x97U, 0x0FU, 0x41U, 0x2FU, + 0x42U, 0xF9U, 0x01U, 0x10U, 0x0BU, 0x1AU, 0x41U, 0x01U, 0x21U, 0x05U, 0x41U, + 0x01U, 0x21U, 0x03U, 0x0CU, 0x02U, 0x0BU, 0x0BU, 0x20U, 0x04U, 0x41U, 0xC8U, + 0x00U, 0x46U, 0x21U, 0x03U, 0x41U, 0x01U, 0x21U, 0x05U, 0x20U, 0x04U, 0x41U, + 0xD2U, 0x00U, 0x47U, 0x0DU, 0x00U, 0x41U, 0x00U, 0x21U, 0x05U, 0x20U, 0x01U, + 0x41U, 0xC4U, 0x00U, 0x46U, 0x20U, 0x01U, 0x41U, 0xD2U, 0x00U, 0x46U, 0x72U, + 0x0DU, 0x00U, 0x41U, 0xC6U, 0x0FU, 0x41U, 0x3CU, 0x42U, 0xFCU, 0x01U, 0x10U, + 0x0BU, 0x1AU, 0x0BU, 0x20U, 0x00U, 0x41U, 0x01U, 0x3AU, 0x00U, 0xECU, 0x09U, + 0x20U, 0x02U, 0x45U, 0x04U, 0x40U, 0x02U, 0x40U, 0x20U, 0x00U, 0x41U, 0xECU, + 0x09U, 0x6AU, 0x41U, 0x01U, 0x41U, 0x82U, 0x10U, 0x41U, 0x01U, 0x10U, 0x02U, + 0x42U, 0x01U, 0x52U, 0x04U, 0x40U, 0x41U, 0x84U, 0x10U, 0x41U, 0xC1U, 0x00U, + 0x42U, 0x84U, 0x02U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x41U, 0xC5U, 0x10U, 0x41U, + 0x01U, 0x20U, 0x00U, 0x31U, 0x00U, 0xECU, 0x09U, 0x10U, 0x03U, 0x1AU, 0x20U, + 0x00U, 0x2DU, 0x00U, 0xECU, 0x09U, 0x22U, 0x01U, 0x41U, 0x01U, 0x6BU, 0x41U, + 0xFFU, 0x01U, 0x71U, 0x41U, 0x02U, 0x4FU, 0x04U, 0x40U, 0x41U, 0xC7U, 0x10U, + 0x41U, 0x30U, 0x42U, 0x89U, 0x02U, 0x10U, 0x0BU, 0x1AU, 0x20U, 0x00U, 0x2DU, + 0x00U, 0xECU, 0x09U, 0x21U, 0x01U, 0x0BU, 0x20U, 0x01U, 0x41U, 0x02U, 0x47U, + 0x20U, 0x05U, 0x72U, 0x0DU, 0x00U, 0x41U, 0xF7U, 0x10U, 0x41U, 0xC5U, 0x00U, 0x42U, 0x8DU, 0x02U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x0BU, 0x41U, 0x20U, 0x41U, - 0x20U, 0x41U, 0x14U, 0x41U, 0x08U, 0x20U, 0x02U, 0x41U, 0xD3U, 0x00U, 0x46U, + 0x20U, 0x41U, 0x14U, 0x41U, 0x08U, 0x20U, 0x04U, 0x41U, 0xD3U, 0x00U, 0x46U, 0x1BU, 0x20U, 0x03U, 0x1BU, 0x22U, 0x03U, 0x6BU, 0x22U, 0x01U, 0x41U, 0xFCU, - 0x01U, 0x71U, 0x22U, 0x07U, 0x20U, 0x00U, 0x41U, 0xB0U, 0x09U, 0x6AU, 0x6AU, - 0x22U, 0x05U, 0x20U, 0x03U, 0x41U, 0xBCU, 0x0AU, 0x41U, 0x01U, 0x10U, 0x02U, - 0x20U, 0x03U, 0xADU, 0x22U, 0x0AU, 0x52U, 0x04U, 0x40U, 0x41U, 0xD8U, 0x11U, - 0x41U, 0xC3U, 0x00U, 0x42U, 0x9BU, 0x02U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x41U, - 0x00U, 0x21U, 0x06U, 0x02U, 0x40U, 0x20U, 0x00U, 0x29U, 0x03U, 0xB0U, 0x09U, - 0x50U, 0x04U, 0x40U, 0x20U, 0x00U, 0x29U, 0x03U, 0xB8U, 0x09U, 0x20U, 0x00U, - 0x29U, 0x03U, 0xC0U, 0x09U, 0x84U, 0x42U, 0x00U, 0x52U, 0x0DU, 0x01U, 0x20U, - 0x00U, 0x29U, 0x03U, 0xC8U, 0x09U, 0x50U, 0x21U, 0x06U, 0x0BU, 0x0BU, 0x41U, - 0xDEU, 0x0BU, 0x41U, 0x10U, 0x20U, 0x00U, 0x41U, 0xB0U, 0x09U, 0x6AU, 0x22U, - 0x09U, 0x41U, 0x38U, 0x41U, 0x01U, 0x10U, 0x08U, 0x1AU, 0x41U, 0xF6U, 0x0BU, - 0x41U, 0x0FU, 0x20U, 0x01U, 0xADU, 0x42U, 0xFFU, 0x01U, 0x83U, 0x10U, 0x03U, - 0x1AU, 0x41U, 0x85U, 0x0CU, 0x41U, 0x0CU, 0x20U, 0x0AU, 0x10U, 0x03U, 0x1AU, - 0x41U, 0x91U, 0x0CU, 0x41U, 0x0CU, 0x20U, 0x05U, 0x20U, 0x03U, 0x41U, 0x01U, - 0x10U, 0x08U, 0x1AU, 0x20U, 0x00U, 0x20U, 0x02U, 0x3AU, 0x00U, 0x91U, 0x0AU, - 0x20U, 0x00U, 0x41U, 0xD6U, 0x00U, 0x3AU, 0x00U, 0x90U, 0x0AU, 0x20U, 0x00U, - 0x20U, 0x00U, 0x2DU, 0x00U, 0xEDU, 0x09U, 0x3AU, 0x00U, 0x92U, 0x0AU, 0x20U, - 0x00U, 0x20U, 0x00U, 0x2DU, 0x00U, 0xECU, 0x09U, 0x3AU, 0x00U, 0x93U, 0x0AU, - 0x20U, 0x00U, 0x41U, 0x90U, 0x09U, 0x6AU, 0x22U, 0x01U, 0x20U, 0x07U, 0x6AU, - 0x20U, 0x03U, 0x20U, 0x00U, 0x41U, 0x90U, 0x0AU, 0x6AU, 0x41U, 0x20U, 0x10U, - 0x09U, 0x21U, 0x0CU, 0x41U, 0xA6U, 0x0AU, 0x41U, 0x14U, 0x20U, 0x01U, 0x41U, - 0x20U, 0x41U, 0x01U, 0x10U, 0x08U, 0x1AU, 0x41U, 0xAFU, 0x0AU, 0x41U, 0x0BU, - 0x20U, 0x09U, 0x41U, 0x20U, 0x41U, 0x01U, 0x10U, 0x08U, 0x1AU, 0x41U, 0xD8U, - 0x09U, 0x41U, 0x14U, 0x20U, 0x0CU, 0x10U, 0x03U, 0x1AU, 0x41U, 0xE1U, 0x09U, - 0x41U, 0x0BU, 0x20U, 0x0AU, 0x10U, 0x03U, 0x1AU, 0x20U, 0x0AU, 0x20U, 0x0CU, - 0x51U, 0x04U, 0x40U, 0x02U, 0x40U, 0x20U, 0x00U, 0x29U, 0x03U, 0x90U, 0x09U, - 0x20U, 0x00U, 0x29U, 0x03U, 0xB0U, 0x09U, 0x52U, 0x20U, 0x00U, 0x29U, 0x03U, - 0x98U, 0x09U, 0x20U, 0x00U, 0x29U, 0x03U, 0xB8U, 0x09U, 0x52U, 0x72U, 0x20U, - 0x00U, 0x29U, 0x03U, 0xA0U, 0x09U, 0x20U, 0x00U, 0x29U, 0x03U, 0xC0U, 0x09U, - 0x52U, 0x20U, 0x00U, 0x29U, 0x03U, 0xA8U, 0x09U, 0x20U, 0x00U, 0x29U, 0x03U, - 0xC8U, 0x09U, 0x52U, 0x72U, 0x72U, 0x0DU, 0x00U, 0x41U, 0xC2U, 0x14U, 0x41U, - 0x3FU, 0x42U, 0xBBU, 0x02U, 0x10U, 0x05U, 0x1AU, 0x0BU, 0x0BU, 0x20U, 0x05U, - 0x20U, 0x03U, 0x20U, 0x00U, 0x41U, 0x90U, 0x0AU, 0x6AU, 0x41U, 0x20U, 0x10U, - 0x0CU, 0x20U, 0x0AU, 0x52U, 0x04U, 0x40U, 0x41U, 0x83U, 0x14U, 0x41U, 0x1AU, - 0x42U, 0xC2U, 0x02U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x20U, 0x0CU, 0x42U, 0x00U, - 0x55U, 0x04U, 0x40U, 0x02U, 0x40U, 0x20U, 0x00U, 0x20U, 0x02U, 0x3AU, 0x00U, - 0x91U, 0x09U, 0x20U, 0x00U, 0x41U, 0xC3U, 0x00U, 0x3AU, 0x00U, 0x90U, 0x09U, - 0x20U, 0x00U, 0x41U, 0x00U, 0x3AU, 0x00U, 0x80U, 0x01U, 0x20U, 0x00U, 0x20U, - 0x00U, 0x2DU, 0x00U, 0xEDU, 0x09U, 0x3AU, 0x00U, 0x92U, 0x09U, 0x20U, 0x00U, - 0x20U, 0x00U, 0x2DU, 0x00U, 0xECU, 0x09U, 0x3AU, 0x00U, 0x93U, 0x09U, 0x20U, - 0x00U, 0x41U, 0x80U, 0x01U, 0x6AU, 0x41U, 0x01U, 0x20U, 0x00U, 0x41U, 0x90U, - 0x09U, 0x6AU, 0x41U, 0x20U, 0x10U, 0x09U, 0x42U, 0x01U, 0x52U, 0x04U, 0x40U, - 0x41U, 0x83U, 0x14U, 0x41U, 0x1AU, 0x42U, 0xCFU, 0x02U, 0x10U, 0x0BU, 0x1AU, - 0x0BU, 0x20U, 0x00U, 0x2DU, 0x00U, 0x80U, 0x01U, 0x22U, 0x01U, 0x45U, 0x04U, - 0x40U, 0x41U, 0x83U, 0x14U, 0x41U, 0x1AU, 0x42U, 0xD0U, 0x02U, 0x10U, 0x0BU, - 0x1AU, 0x20U, 0x00U, 0x2DU, 0x00U, 0x80U, 0x01U, 0x21U, 0x01U, 0x0BU, 0x20U, - 0x00U, 0x20U, 0x01U, 0x41U, 0x01U, 0x6BU, 0x22U, 0x01U, 0x3AU, 0x00U, 0x80U, - 0x01U, 0x20U, 0x00U, 0x41U, 0x80U, 0x01U, 0x6AU, 0x41U, 0x00U, 0x20U, 0x01U, - 0x41U, 0xFFU, 0x01U, 0x71U, 0x22U, 0x01U, 0x1BU, 0x20U, 0x01U, 0x41U, 0x00U, - 0x47U, 0x20U, 0x00U, 0x41U, 0x90U, 0x09U, 0x6AU, 0x41U, 0x20U, 0x10U, 0x0CU, - 0x42U, 0x00U, 0x59U, 0x0DU, 0x00U, 0x41U, 0x83U, 0x14U, 0x41U, 0x1AU, 0x42U, - 0xD4U, 0x02U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x0BU, 0x20U, 0x00U, 0x41U, 0x00U, - 0x3AU, 0x00U, 0x8FU, 0x09U, 0x20U, 0x00U, 0x29U, 0x03U, 0xB0U, 0x09U, 0x21U, - 0x0AU, 0x20U, 0x00U, 0x41U, 0xC3U, 0x00U, 0x3AU, 0x00U, 0xB0U, 0x09U, 0x20U, - 0x00U, 0x20U, 0x00U, 0x2DU, 0x00U, 0xECU, 0x09U, 0x3AU, 0x00U, 0xB3U, 0x09U, - 0x20U, 0x00U, 0x20U, 0x00U, 0x2DU, 0x00U, 0xEDU, 0x09U, 0x3AU, 0x00U, 0xB2U, - 0x09U, 0x20U, 0x00U, 0x20U, 0x02U, 0x3AU, 0x00U, 0xB1U, 0x09U, 0x20U, 0x00U, - 0x41U, 0x8FU, 0x09U, 0x6AU, 0x22U, 0x01U, 0x41U, 0x01U, 0x20U, 0x00U, 0x41U, - 0xB0U, 0x09U, 0x6AU, 0x22U, 0x07U, 0x41U, 0x20U, 0x10U, 0x09U, 0x1AU, 0x20U, - 0x00U, 0x20U, 0x00U, 0x2DU, 0x00U, 0x8FU, 0x09U, 0x41U, 0x01U, 0x6AU, 0x3AU, - 0x00U, 0x8FU, 0x09U, 0x20U, 0x01U, 0x41U, 0x01U, 0x20U, 0x07U, 0x41U, 0x20U, - 0x10U, 0x0CU, 0x42U, 0x00U, 0x57U, 0x04U, 0x40U, 0x41U, 0x83U, 0x14U, 0x41U, - 0x1AU, 0x42U, 0xE4U, 0x02U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x20U, 0x00U, 0x20U, - 0x0AU, 0x37U, 0x03U, 0xB0U, 0x09U, 0x41U, 0xEDU, 0x08U, 0x41U, 0x0FU, 0x20U, - 0x06U, 0xADU, 0x22U, 0x0DU, 0x10U, 0x03U, 0x1AU, 0x41U, 0xCCU, 0x08U, 0x41U, - 0x05U, 0x20U, 0x00U, 0x31U, 0x00U, 0x8FU, 0x09U, 0x10U, 0x03U, 0x1AU, 0x41U, - 0x80U, 0x08U, 0x41U, 0x0CU, 0x20U, 0x0BU, 0x10U, 0x03U, 0x1AU, 0x41U, 0xA0U, - 0x0AU, 0x41U, 0x06U, 0x20U, 0x00U, 0x41U, 0xEEU, 0x09U, 0x6AU, 0x41U, 0x02U, - 0x41U, 0x01U, 0x10U, 0x08U, 0x1AU, 0x20U, 0x0BU, 0xB9U, 0x21U, 0x0FU, 0x02U, - 0x40U, 0x20U, 0x00U, 0x2DU, 0x00U, 0xECU, 0x09U, 0x41U, 0x02U, 0x46U, 0x20U, - 0x04U, 0x72U, 0x41U, 0x01U, 0x46U, 0x04U, 0x40U, 0x20U, 0x00U, 0x31U, 0x00U, - 0x8FU, 0x09U, 0x20U, 0x0FU, 0x44U, 0x9AU, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U, - 0xE9U, 0x3FU, 0xA2U, 0x22U, 0x0FU, 0x99U, 0x44U, 0x00U, 0x00U, 0x00U, 0x00U, - 0x00U, 0x00U, 0xE0U, 0x43U, 0x63U, 0x04U, 0x7EU, 0x20U, 0x0FU, 0xB0U, 0x05U, + 0x01U, 0x71U, 0x22U, 0x06U, 0x20U, 0x00U, 0x41U, 0xB0U, 0x09U, 0x6AU, 0x6AU, + 0x22U, 0x05U, 0x20U, 0x03U, 0x41U, 0xBCU, 0x11U, 0x41U, 0x01U, 0x10U, 0x02U, + 0x20U, 0x03U, 0xADU, 0x22U, 0x0BU, 0x52U, 0x04U, 0x40U, 0x41U, 0xBEU, 0x11U, + 0x41U, 0xC3U, 0x00U, 0x42U, 0x9BU, 0x02U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x20U, + 0x00U, 0x29U, 0x03U, 0xB0U, 0x09U, 0x50U, 0x04U, 0x40U, 0x20U, 0x00U, 0x29U, + 0x03U, 0xB8U, 0x09U, 0x42U, 0x00U, 0x52U, 0x20U, 0x00U, 0x29U, 0x03U, 0xC0U, + 0x09U, 0x42U, 0x00U, 0x52U, 0x72U, 0x45U, 0x04U, 0x40U, 0x20U, 0x00U, 0x29U, + 0x03U, 0xC8U, 0x09U, 0x50U, 0x21U, 0x07U, 0x0BU, 0x0BU, 0x41U, 0x81U, 0x12U, + 0x41U, 0x10U, 0x20U, 0x00U, 0x41U, 0xB0U, 0x09U, 0x6AU, 0x22U, 0x09U, 0x41U, + 0x38U, 0x41U, 0x01U, 0x10U, 0x08U, 0x1AU, 0x41U, 0x91U, 0x12U, 0x41U, 0x0FU, + 0x20U, 0x01U, 0xADU, 0x42U, 0xFFU, 0x01U, 0x83U, 0x10U, 0x03U, 0x1AU, 0x41U, + 0xA0U, 0x12U, 0x41U, 0x0CU, 0x20U, 0x0BU, 0x10U, 0x03U, 0x1AU, 0x41U, 0xACU, + 0x12U, 0x41U, 0x0CU, 0x20U, 0x05U, 0x20U, 0x03U, 0x41U, 0x01U, 0x10U, 0x08U, + 0x1AU, 0x20U, 0x00U, 0x20U, 0x04U, 0x3AU, 0x00U, 0x91U, 0x0AU, 0x20U, 0x00U, + 0x41U, 0xD6U, 0x00U, 0x3AU, 0x00U, 0x90U, 0x0AU, 0x20U, 0x00U, 0x20U, 0x00U, + 0x2DU, 0x00U, 0xEDU, 0x09U, 0x3AU, 0x00U, 0x92U, 0x0AU, 0x20U, 0x00U, 0x20U, + 0x00U, 0x2DU, 0x00U, 0xECU, 0x09U, 0x3AU, 0x00U, 0x93U, 0x0AU, 0x20U, 0x00U, + 0x41U, 0x90U, 0x09U, 0x6AU, 0x22U, 0x01U, 0x20U, 0x06U, 0x6AU, 0x20U, 0x03U, + 0x20U, 0x00U, 0x41U, 0x90U, 0x0AU, 0x6AU, 0x41U, 0x20U, 0x10U, 0x09U, 0x21U, + 0x0DU, 0x41U, 0xB8U, 0x12U, 0x41U, 0x14U, 0x20U, 0x01U, 0x41U, 0x20U, 0x41U, + 0x01U, 0x10U, 0x08U, 0x1AU, 0x41U, 0xCCU, 0x12U, 0x41U, 0x0BU, 0x20U, 0x09U, + 0x41U, 0x20U, 0x41U, 0x01U, 0x10U, 0x08U, 0x1AU, 0x41U, 0xD7U, 0x12U, 0x41U, + 0x14U, 0x20U, 0x0DU, 0x10U, 0x03U, 0x1AU, 0x41U, 0xEBU, 0x12U, 0x41U, 0x0BU, + 0x20U, 0x0BU, 0x10U, 0x03U, 0x1AU, 0x20U, 0x0BU, 0x20U, 0x0DU, 0x51U, 0x04U, + 0x40U, 0x02U, 0x40U, 0x20U, 0x00U, 0x29U, 0x03U, 0x90U, 0x09U, 0x20U, 0x00U, + 0x29U, 0x03U, 0xB0U, 0x09U, 0x52U, 0x20U, 0x00U, 0x29U, 0x03U, 0x98U, 0x09U, + 0x20U, 0x00U, 0x29U, 0x03U, 0xB8U, 0x09U, 0x52U, 0x72U, 0x20U, 0x00U, 0x29U, + 0x03U, 0xA0U, 0x09U, 0x20U, 0x00U, 0x29U, 0x03U, 0xC0U, 0x09U, 0x52U, 0x20U, + 0x00U, 0x29U, 0x03U, 0xA8U, 0x09U, 0x20U, 0x00U, 0x29U, 0x03U, 0xC8U, 0x09U, + 0x52U, 0x72U, 0x72U, 0x0DU, 0x00U, 0x41U, 0xF6U, 0x12U, 0x41U, 0x3FU, 0x42U, + 0xBBU, 0x02U, 0x10U, 0x05U, 0x1AU, 0x0BU, 0x0BU, 0x20U, 0x05U, 0x20U, 0x03U, + 0x20U, 0x00U, 0x41U, 0x90U, 0x0AU, 0x6AU, 0x41U, 0x20U, 0x10U, 0x0CU, 0x20U, + 0x0BU, 0x52U, 0x04U, 0x40U, 0x41U, 0xB4U, 0x0AU, 0x41U, 0x1AU, 0x42U, 0xC2U, + 0x02U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x20U, 0x0DU, 0x42U, 0x01U, 0x59U, 0x04U, + 0x40U, 0x02U, 0x40U, 0x20U, 0x00U, 0x20U, 0x04U, 0x3AU, 0x00U, 0x91U, 0x09U, + 0x20U, 0x00U, 0x41U, 0xC3U, 0x00U, 0x3AU, 0x00U, 0x90U, 0x09U, 0x20U, 0x00U, + 0x41U, 0x00U, 0x3AU, 0x00U, 0x80U, 0x01U, 0x20U, 0x00U, 0x20U, 0x00U, 0x2DU, + 0x00U, 0xEDU, 0x09U, 0x3AU, 0x00U, 0x92U, 0x09U, 0x20U, 0x00U, 0x20U, 0x00U, + 0x2DU, 0x00U, 0xECU, 0x09U, 0x3AU, 0x00U, 0x93U, 0x09U, 0x20U, 0x00U, 0x41U, + 0x80U, 0x01U, 0x6AU, 0x41U, 0x01U, 0x20U, 0x00U, 0x41U, 0x90U, 0x09U, 0x6AU, + 0x41U, 0x20U, 0x10U, 0x09U, 0x42U, 0x01U, 0x52U, 0x04U, 0x40U, 0x41U, 0xB4U, + 0x0AU, 0x41U, 0x1AU, 0x42U, 0xCFU, 0x02U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x20U, + 0x00U, 0x2DU, 0x00U, 0x80U, 0x01U, 0x22U, 0x01U, 0x45U, 0x04U, 0x40U, 0x41U, + 0xB4U, 0x0AU, 0x41U, 0x1AU, 0x42U, 0xD0U, 0x02U, 0x10U, 0x0BU, 0x1AU, 0x20U, + 0x00U, 0x2DU, 0x00U, 0x80U, 0x01U, 0x21U, 0x01U, 0x0BU, 0x20U, 0x00U, 0x20U, + 0x01U, 0x41U, 0x01U, 0x6BU, 0x22U, 0x01U, 0x3AU, 0x00U, 0x80U, 0x01U, 0x20U, + 0x00U, 0x41U, 0x80U, 0x01U, 0x6AU, 0x41U, 0x00U, 0x20U, 0x01U, 0x41U, 0xFFU, + 0x01U, 0x71U, 0x22U, 0x01U, 0x1BU, 0x20U, 0x01U, 0x41U, 0x00U, 0x47U, 0x20U, + 0x00U, 0x41U, 0x90U, 0x09U, 0x6AU, 0x41U, 0x20U, 0x10U, 0x0CU, 0x42U, 0x7FU, + 0x55U, 0x0DU, 0x00U, 0x41U, 0xB4U, 0x0AU, 0x41U, 0x1AU, 0x42U, 0xD4U, 0x02U, + 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x0BU, 0x20U, 0x00U, 0x41U, 0x00U, 0x3AU, 0x00U, + 0x8FU, 0x09U, 0x20U, 0x00U, 0x29U, 0x03U, 0xB0U, 0x09U, 0x21U, 0x0BU, 0x20U, + 0x00U, 0x41U, 0xC3U, 0x00U, 0x3AU, 0x00U, 0xB0U, 0x09U, 0x20U, 0x00U, 0x20U, + 0x00U, 0x2DU, 0x00U, 0xECU, 0x09U, 0x3AU, 0x00U, 0xB3U, 0x09U, 0x20U, 0x00U, + 0x20U, 0x00U, 0x2DU, 0x00U, 0xEDU, 0x09U, 0x3AU, 0x00U, 0xB2U, 0x09U, 0x20U, + 0x00U, 0x20U, 0x04U, 0x3AU, 0x00U, 0xB1U, 0x09U, 0x20U, 0x00U, 0x41U, 0x8FU, + 0x09U, 0x6AU, 0x22U, 0x01U, 0x41U, 0x01U, 0x20U, 0x00U, 0x41U, 0xB0U, 0x09U, + 0x6AU, 0x22U, 0x06U, 0x41U, 0x20U, 0x10U, 0x09U, 0x1AU, 0x20U, 0x00U, 0x20U, + 0x00U, 0x2DU, 0x00U, 0x8FU, 0x09U, 0x41U, 0x01U, 0x6AU, 0x3AU, 0x00U, 0x8FU, + 0x09U, 0x20U, 0x01U, 0x41U, 0x01U, 0x20U, 0x06U, 0x41U, 0x20U, 0x10U, 0x0CU, + 0x42U, 0x00U, 0x57U, 0x04U, 0x40U, 0x41U, 0xB4U, 0x0AU, 0x41U, 0x1AU, 0x42U, + 0xE4U, 0x02U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x20U, 0x00U, 0x20U, 0x0BU, 0x37U, + 0x03U, 0xB0U, 0x09U, 0x41U, 0xB5U, 0x13U, 0x41U, 0x0FU, 0x20U, 0x07U, 0xADU, + 0x22U, 0x0FU, 0x10U, 0x03U, 0x1AU, 0x41U, 0xC5U, 0x13U, 0x41U, 0x05U, 0x20U, + 0x00U, 0x31U, 0x00U, 0x8FU, 0x09U, 0x10U, 0x03U, 0x1AU, 0x41U, 0xCEU, 0x0AU, + 0x41U, 0x0CU, 0x20U, 0x0CU, 0x10U, 0x03U, 0x1AU, 0x41U, 0xCBU, 0x13U, 0x41U, + 0x06U, 0x20U, 0x00U, 0x41U, 0xEEU, 0x09U, 0x6AU, 0x41U, 0x02U, 0x41U, 0x01U, + 0x10U, 0x08U, 0x1AU, 0x20U, 0x00U, 0x2DU, 0x00U, 0xECU, 0x09U, 0x41U, 0x02U, + 0x47U, 0x20U, 0x0CU, 0xB9U, 0x22U, 0x10U, 0x44U, 0x52U, 0xB8U, 0x1EU, 0x85U, + 0xEBU, 0x51U, 0xE0U, 0x3FU, 0xA2U, 0x22U, 0x11U, 0x99U, 0x44U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0xE0U, 0x43U, 0x63U, 0x04U, 0x7EU, 0x20U, 0x11U, + 0xB0U, 0x05U, 0x42U, 0x80U, 0x80U, 0x80U, 0x80U, 0x80U, 0x80U, 0x80U, 0x80U, + 0x80U, 0x7FU, 0x0BU, 0x21U, 0x0BU, 0x20U, 0x02U, 0x41U, 0x7FU, 0x73U, 0x71U, + 0x21U, 0x01U, 0x20U, 0x10U, 0x44U, 0x9AU, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U, + 0xE9U, 0x3FU, 0xA2U, 0x22U, 0x10U, 0x99U, 0x44U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0xE0U, 0x43U, 0x63U, 0x04U, 0x7EU, 0x20U, 0x10U, 0xB0U, 0x05U, 0x42U, 0x80U, 0x80U, 0x80U, 0x80U, 0x80U, 0x80U, 0x80U, 0x80U, 0x80U, 0x7FU, - 0x0BU, 0x22U, 0x0AU, 0x42U, 0x02U, 0x20U, 0x0AU, 0x42U, 0x02U, 0x55U, 0x1BU, - 0x20U, 0x0BU, 0x20U, 0x02U, 0x41U, 0xD3U, 0x00U, 0x46U, 0x1BU, 0x59U, 0x0DU, - 0x01U, 0x41U, 0xC6U, 0x0FU, 0x41U, 0x39U, 0x42U, 0x83U, 0x03U, 0x10U, 0x05U, - 0x1AU, 0x05U, 0x20U, 0x00U, 0x31U, 0x00U, 0x8FU, 0x09U, 0x20U, 0x0FU, 0x44U, - 0x52U, 0xB8U, 0x1EU, 0x85U, 0xEBU, 0x51U, 0xE0U, 0x3FU, 0xA2U, 0x22U, 0x0FU, - 0x99U, 0x44U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0xE0U, 0x43U, 0x63U, - 0x04U, 0x7EU, 0x20U, 0x0FU, 0xB0U, 0x05U, 0x42U, 0x80U, 0x80U, 0x80U, 0x80U, - 0x80U, 0x80U, 0x80U, 0x80U, 0x80U, 0x7FU, 0x0BU, 0x22U, 0x0AU, 0x42U, 0x02U, - 0x20U, 0x0AU, 0x42U, 0x02U, 0x55U, 0x1BU, 0x5AU, 0x0DU, 0x01U, 0x41U, 0xBCU, - 0x16U, 0x41U, 0x36U, 0x42U, 0x88U, 0x03U, 0x10U, 0x05U, 0x1AU, 0x0BU, 0x0BU, - 0x41U, 0xC5U, 0x19U, 0x41U, 0x11U, 0x41U, 0xC2U, 0x08U, 0x41U, 0x10U, 0x41U, - 0x00U, 0x10U, 0x08U, 0x1AU, 0x20U, 0x00U, 0x2DU, 0x00U, 0xECU, 0x09U, 0x41U, - 0x01U, 0x47U, 0x20U, 0x04U, 0x72U, 0x45U, 0x04U, 0x40U, 0x10U, 0x0DU, 0x21U, - 0x0AU, 0x20U, 0x00U, 0x41U, 0x9EU, 0x01U, 0x6AU, 0x22U, 0x07U, 0x42U, 0x80U, - 0x80U, 0x80U, 0x80U, 0xB0U, 0x8EU, 0xC0U, 0xC0U, 0x14U, 0x37U, 0x00U, 0x00U, - 0x20U, 0x00U, 0x41U, 0xE8U, 0x80U, 0x01U, 0x3BU, 0x00U, 0x99U, 0x01U, 0x20U, - 0x00U, 0x41U, 0xA0U, 0x36U, 0x3BU, 0x00U, 0x93U, 0x01U, 0x20U, 0x00U, 0x41U, - 0xA0U, 0x34U, 0x3BU, 0x00U, 0x8DU, 0x01U, 0x20U, 0x00U, 0x41U, 0x00U, 0x36U, - 0x00U, 0x89U, 0x01U, 0x20U, 0x00U, 0x41U, 0x24U, 0x3AU, 0x00U, 0x88U, 0x01U, - 0x20U, 0x00U, 0x42U, 0x92U, 0x80U, 0x8CU, 0x93U, 0x82U, 0x10U, 0x37U, 0x03U, - 0x80U, 0x01U, 0x20U, 0x00U, 0x41U, 0x00U, 0x36U, 0x00U, 0x9BU, 0x01U, 0x20U, - 0x00U, 0x20U, 0x0AU, 0xA7U, 0x22U, 0x04U, 0x41U, 0x05U, 0x6AU, 0x22U, 0x01U, - 0x3AU, 0x00U, 0x98U, 0x01U, 0x20U, 0x00U, 0x20U, 0x01U, 0x41U, 0x08U, 0x76U, - 0x3AU, 0x00U, 0x97U, 0x01U, 0x20U, 0x00U, 0x20U, 0x01U, 0x41U, 0x10U, 0x76U, - 0x3AU, 0x00U, 0x96U, 0x01U, 0x20U, 0x00U, 0x20U, 0x01U, 0x41U, 0x18U, 0x76U, - 0x3AU, 0x00U, 0x95U, 0x01U, 0x20U, 0x00U, 0x20U, 0x04U, 0x41U, 0x01U, 0x6AU, - 0x22U, 0x01U, 0x3AU, 0x00U, 0x92U, 0x01U, 0x20U, 0x00U, 0x20U, 0x01U, 0x41U, - 0x08U, 0x76U, 0x3AU, 0x00U, 0x91U, 0x01U, 0x20U, 0x00U, 0x20U, 0x01U, 0x41U, - 0x10U, 0x76U, 0x3AU, 0x00U, 0x90U, 0x01U, 0x20U, 0x00U, 0x20U, 0x01U, 0x41U, - 0x18U, 0x76U, 0x3AU, 0x00U, 0x8FU, 0x01U, 0x20U, 0x00U, 0x20U, 0x00U, 0x29U, - 0x03U, 0xFCU, 0x09U, 0x37U, 0x03U, 0xA6U, 0x01U, 0x20U, 0x00U, 0x41U, 0x83U, - 0x29U, 0x3BU, 0x01U, 0xBAU, 0x01U, 0x20U, 0x00U, 0x20U, 0x00U, 0x29U, 0x03U, - 0x84U, 0x0AU, 0x37U, 0x03U, 0xAEU, 0x01U, 0x20U, 0x00U, 0x20U, 0x00U, 0x28U, - 0x02U, 0x8CU, 0x0AU, 0x36U, 0x02U, 0xB6U, 0x01U, 0x20U, 0x00U, 0x41U, 0xB0U, - 0x1AU, 0x29U, 0x03U, 0x00U, 0x37U, 0x03U, 0xBCU, 0x01U, 0x20U, 0x00U, 0x41U, - 0xB8U, 0x1AU, 0x29U, 0x03U, 0x00U, 0x37U, 0x03U, 0xC4U, 0x01U, 0x20U, 0x00U, - 0x41U, 0xC0U, 0x1AU, 0x28U, 0x02U, 0x00U, 0x36U, 0x02U, 0xCCU, 0x01U, 0x20U, - 0x00U, 0x41U, 0xD0U, 0x01U, 0x6AU, 0x22U, 0x01U, 0x41U, 0x80U, 0x04U, 0x10U, - 0x0EU, 0xA7U, 0x20U, 0x01U, 0x6AU, 0x22U, 0x01U, 0x41U, 0xF0U, 0xB2U, 0x08U, - 0x36U, 0x02U, 0x08U, 0x20U, 0x01U, 0x41U, 0x0BU, 0x6AU, 0x20U, 0x02U, 0x3AU, - 0x00U, 0x00U, 0x20U, 0x01U, 0x41U, 0x16U, 0x6AU, 0x20U, 0x03U, 0x3AU, 0x00U, - 0x00U, 0x20U, 0x01U, 0x41U, 0x15U, 0x6AU, 0x41U, 0x19U, 0x3AU, 0x00U, 0x00U, - 0x20U, 0x01U, 0x41U, 0x0CU, 0x6AU, 0x20U, 0x00U, 0x2DU, 0x00U, 0xEDU, 0x09U, - 0x3AU, 0x00U, 0x00U, 0x20U, 0x01U, 0x42U, 0xF0U, 0xA7U, 0x80U, 0xBFU, 0x81U, - 0x8EU, 0xC6U, 0x80U, 0xD4U, 0x00U, 0x37U, 0x03U, 0x00U, 0x20U, 0x01U, 0x41U, - 0x0DU, 0x6AU, 0x42U, 0xE1U, 0xC1U, 0xDFU, 0x80U, 0x87U, 0xA3U, 0x80U, 0xABU, - 0xF0U, 0x00U, 0x37U, 0x03U, 0x00U, 0x20U, 0x01U, 0x41U, 0x17U, 0x6AU, 0x22U, - 0x04U, 0x20U, 0x05U, 0x29U, 0x03U, 0x00U, 0x37U, 0x03U, 0x00U, 0x20U, 0x01U, - 0x41U, 0x1FU, 0x6AU, 0x20U, 0x05U, 0x29U, 0x03U, 0x08U, 0x37U, 0x03U, 0x00U, - 0x20U, 0x01U, 0x41U, 0x27U, 0x6AU, 0x20U, 0x05U, 0x41U, 0x10U, 0x6AU, 0x29U, - 0x03U, 0x00U, 0x37U, 0x03U, 0x00U, 0x20U, 0x01U, 0x41U, 0x2FU, 0x6AU, 0x20U, - 0x05U, 0x41U, 0x18U, 0x6AU, 0x29U, 0x03U, 0x00U, 0x37U, 0x03U, 0x00U, 0x20U, - 0x03U, 0x20U, 0x04U, 0x6AU, 0x22U, 0x01U, 0x41U, 0xE1U, 0xE3U, 0x03U, 0x3BU, - 0x01U, 0x00U, 0x20U, 0x01U, 0x20U, 0x00U, 0x41U, 0x80U, 0x01U, 0x6AU, 0x22U, - 0x01U, 0x6BU, 0x21U, 0x04U, 0x20U, 0x07U, 0x20U, 0x01U, 0x20U, 0x04U, 0x10U, - 0x0FU, 0x22U, 0x0AU, 0x42U, 0x18U, 0x88U, 0x3CU, 0x00U, 0x00U, 0x20U, 0x00U, - 0x20U, 0x0AU, 0x3CU, 0x00U, 0xA1U, 0x01U, 0x20U, 0x00U, 0x41U, 0xE8U, 0x00U, - 0x3AU, 0x00U, 0x99U, 0x01U, 0x20U, 0x00U, 0x20U, 0x0AU, 0x42U, 0x08U, 0x88U, - 0x3CU, 0x00U, 0xA0U, 0x01U, 0x20U, 0x00U, 0x20U, 0x0AU, 0x42U, 0x10U, 0x88U, - 0x3CU, 0x00U, 0x9FU, 0x01U, 0x20U, 0x00U, 0x20U, 0x0AU, 0x42U, 0x20U, 0x88U, - 0x3CU, 0x00U, 0x9DU, 0x01U, 0x20U, 0x00U, 0x20U, 0x0AU, 0x42U, 0x28U, 0x88U, - 0x3CU, 0x00U, 0x9CU, 0x01U, 0x20U, 0x00U, 0x20U, 0x0AU, 0x42U, 0x30U, 0x88U, - 0x3CU, 0x00U, 0x9BU, 0x01U, 0x20U, 0x00U, 0x20U, 0x0AU, 0x42U, 0x38U, 0x88U, - 0xA7U, 0x41U, 0x3FU, 0x71U, 0x41U, 0xC0U, 0x00U, 0x72U, 0x3AU, 0x00U, 0x9AU, - 0x01U, 0x41U, 0xB1U, 0x0CU, 0x41U, 0x22U, 0x20U, 0x01U, 0x20U, 0x04U, 0x41U, - 0x01U, 0x10U, 0x08U, 0x1AU, 0x41U, 0xAAU, 0x08U, 0x41U, 0x18U, 0x20U, 0x00U, - 0x41U, 0x20U, 0x6AU, 0x41U, 0x20U, 0x20U, 0x01U, 0x20U, 0x04U, 0x10U, 0x10U, - 0x22U, 0x0AU, 0x10U, 0x03U, 0x1AU, 0x20U, 0x0AU, 0x42U, 0x20U, 0x51U, 0x04U, - 0x40U, 0x41U, 0xAEU, 0x11U, 0x41U, 0x2AU, 0x42U, 0xD6U, 0x03U, 0x10U, 0x05U, - 0x1AU, 0x0BU, 0x41U, 0x9DU, 0x14U, 0x41U, 0x25U, 0x42U, 0xD8U, 0x03U, 0x10U, - 0x0BU, 0x1AU, 0x0BU, 0x02U, 0x40U, 0x02U, 0x40U, 0x02U, 0x40U, 0x02U, 0x40U, - 0x02U, 0x40U, 0x20U, 0x02U, 0x41U, 0xD2U, 0x00U, 0x6BU, 0x0EU, 0x02U, 0x00U, - 0x03U, 0x01U, 0x0BU, 0x41U, 0xBBU, 0x08U, 0x41U, 0x06U, 0x20U, 0x05U, 0x20U, - 0x03U, 0x20U, 0x00U, 0x41U, 0xEEU, 0x09U, 0x6AU, 0x41U, 0x02U, 0x10U, 0x0CU, - 0x22U, 0x0AU, 0x10U, 0x03U, 0x1AU, 0x20U, 0x0AU, 0x42U, 0x00U, 0x57U, 0x04U, - 0x40U, 0x41U, 0x83U, 0x14U, 0x41U, 0x1AU, 0x42U, 0xE2U, 0x03U, 0x10U, 0x0BU, - 0x1AU, 0x0BU, 0x20U, 0x00U, 0x2DU, 0x00U, 0xEDU, 0x09U, 0x41U, 0xD2U, 0x00U, - 0x46U, 0x04U, 0x40U, 0x41U, 0x81U, 0x1AU, 0x41U, 0x29U, 0x42U, 0xE4U, 0x03U, - 0x10U, 0x05U, 0x1AU, 0x0BU, 0x41U, 0xD7U, 0x19U, 0x41U, 0x2AU, 0x42U, 0xE6U, - 0x03U, 0x10U, 0x05U, 0x1AU, 0x0CU, 0x01U, 0x0BU, 0x20U, 0x02U, 0x41U, 0xC8U, - 0x00U, 0x47U, 0x0DU, 0x02U, 0x0BU, 0x20U, 0x00U, 0x41U, 0xD0U, 0x00U, 0x6AU, - 0x22U, 0x01U, 0x41U, 0x22U, 0x41U, 0x01U, 0x20U, 0x08U, 0x41U, 0x14U, 0x41U, - 0x00U, 0x41U, 0x00U, 0x41U, 0x00U, 0x41U, 0x00U, 0x10U, 0x11U, 0x1AU, 0x20U, - 0x01U, 0x41U, 0x22U, 0x41U, 0x05U, 0x10U, 0x12U, 0x1AU, 0x41U, 0x05U, 0x41U, - 0x8BU, 0x80U, 0x3CU, 0x41U, 0x06U, 0x10U, 0x13U, 0x1AU, 0x41U, 0x06U, 0x20U, - 0x00U, 0x2DU, 0x00U, 0xEDU, 0x09U, 0x41U, 0x07U, 0x10U, 0x14U, 0x42U, 0x07U, - 0x51U, 0x04U, 0x40U, 0x02U, 0x40U, 0x41U, 0x07U, 0x41U, 0x9FU, 0x80U, 0x14U, - 0x41U, 0x08U, 0x10U, 0x13U, 0x42U, 0x08U, 0x52U, 0x0DU, 0x00U, 0x20U, 0x00U, - 0x41U, 0x80U, 0x01U, 0x6AU, 0x41U, 0x20U, 0x41U, 0x08U, 0x10U, 0x15U, 0x42U, - 0x20U, 0x52U, 0x04U, 0x40U, 0x41U, 0x83U, 0x14U, 0x41U, 0x1AU, 0x42U, 0xFDU, - 0x03U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x20U, 0x00U, 0x29U, 0x03U, 0x80U, 0x01U, - 0x20U, 0x00U, 0x29U, 0x03U, 0xB0U, 0x09U, 0x52U, 0x20U, 0x00U, 0x29U, 0x03U, - 0x88U, 0x01U, 0x20U, 0x00U, 0x29U, 0x03U, 0xB8U, 0x09U, 0x52U, 0x72U, 0x20U, - 0x00U, 0x29U, 0x03U, 0x90U, 0x01U, 0x20U, 0x00U, 0x29U, 0x03U, 0xC0U, 0x09U, - 0x52U, 0x20U, 0x00U, 0x29U, 0x03U, 0x98U, 0x01U, 0x20U, 0x00U, 0x29U, 0x03U, - 0xC8U, 0x09U, 0x52U, 0x72U, 0x72U, 0x0DU, 0x00U, 0x41U, 0xC2U, 0x10U, 0x41U, - 0x3DU, 0x42U, 0x81U, 0x04U, 0x10U, 0x05U, 0x1AU, 0x0BU, 0x0BU, 0x41U, 0x7FU, - 0x21U, 0x03U, 0x20U, 0x06U, 0x45U, 0x04U, 0x40U, 0x02U, 0x40U, 0x20U, 0x00U, - 0x41U, 0xD0U, 0x00U, 0x6AU, 0x22U, 0x01U, 0x41U, 0x22U, 0x41U, 0x18U, 0x20U, - 0x00U, 0x41U, 0xB0U, 0x09U, 0x6AU, 0x22U, 0x03U, 0x41U, 0x20U, 0x41U, 0x00U, - 0x41U, 0x00U, 0x41U, 0x00U, 0x41U, 0x00U, 0x10U, 0x11U, 0x1AU, 0x20U, 0x01U, - 0x41U, 0x22U, 0x41U, 0x09U, 0x10U, 0x12U, 0x42U, 0x09U, 0x51U, 0x0DU, 0x00U, - 0x41U, 0xFFU, 0x0FU, 0x41U, 0xC3U, 0x00U, 0x42U, 0x8CU, 0x04U, 0x10U, 0x0BU, - 0x1AU, 0x0BU, 0x0BU, 0x20U, 0x00U, 0x41U, 0x20U, 0x6AU, 0x20U, 0x00U, 0x2DU, - 0x00U, 0xEDU, 0x09U, 0x41U, 0x02U, 0x74U, 0x6AU, 0x20U, 0x03U, 0x36U, 0x02U, - 0x00U, 0x10U, 0x0DU, 0x21U, 0x0AU, 0x20U, 0x00U, 0x41U, 0x14U, 0x10U, 0x07U, - 0x1AU, 0x20U, 0x00U, 0x41U, 0x9EU, 0x01U, 0x6AU, 0x42U, 0x80U, 0x80U, 0x80U, - 0x80U, 0xB0U, 0x8EU, 0xC0U, 0xC0U, 0x14U, 0x37U, 0x00U, 0x00U, 0x20U, 0x00U, - 0x41U, 0xE8U, 0x80U, 0x01U, 0x3BU, 0x00U, 0x99U, 0x01U, 0x20U, 0x00U, 0x41U, - 0xA0U, 0x36U, 0x3BU, 0x00U, 0x93U, 0x01U, 0x20U, 0x00U, 0x41U, 0xA0U, 0x34U, - 0x3BU, 0x00U, 0x8DU, 0x01U, 0x20U, 0x00U, 0x41U, 0x00U, 0x36U, 0x00U, 0x89U, - 0x01U, 0x20U, 0x00U, 0x41U, 0x24U, 0x3AU, 0x00U, 0x88U, 0x01U, 0x20U, 0x00U, - 0x42U, 0x92U, 0x80U, 0xD8U, 0x90U, 0x82U, 0x10U, 0x37U, 0x03U, 0x80U, 0x01U, - 0x20U, 0x00U, 0x41U, 0x00U, 0x36U, 0x00U, 0x9BU, 0x01U, 0x20U, 0x00U, 0x20U, - 0x0AU, 0xA7U, 0x22U, 0x03U, 0x41U, 0x05U, 0x6AU, 0x22U, 0x01U, 0x3AU, 0x00U, - 0x98U, 0x01U, 0x20U, 0x00U, 0x20U, 0x01U, 0x41U, 0x08U, 0x76U, 0x3AU, 0x00U, - 0x97U, 0x01U, 0x20U, 0x00U, 0x20U, 0x01U, 0x41U, 0x10U, 0x76U, 0x3AU, 0x00U, - 0x96U, 0x01U, 0x20U, 0x00U, 0x20U, 0x01U, 0x41U, 0x18U, 0x76U, 0x3AU, 0x00U, - 0x95U, 0x01U, 0x20U, 0x00U, 0x20U, 0x03U, 0x41U, 0x01U, 0x6AU, 0x22U, 0x01U, - 0x3AU, 0x00U, 0x92U, 0x01U, 0x20U, 0x00U, 0x20U, 0x01U, 0x41U, 0x08U, 0x76U, - 0x3AU, 0x00U, 0x91U, 0x01U, 0x20U, 0x00U, 0x20U, 0x01U, 0x41U, 0x10U, 0x76U, - 0x3AU, 0x00U, 0x90U, 0x01U, 0x20U, 0x00U, 0x20U, 0x01U, 0x41U, 0x18U, 0x76U, - 0x3AU, 0x00U, 0x8FU, 0x01U, 0x20U, 0x00U, 0x20U, 0x00U, 0x29U, 0x03U, 0x00U, - 0x37U, 0x03U, 0xA6U, 0x01U, 0x20U, 0x00U, 0x20U, 0x00U, 0x29U, 0x03U, 0x08U, - 0x37U, 0x03U, 0xAEU, 0x01U, 0x20U, 0x00U, 0x20U, 0x00U, 0x28U, 0x02U, 0x10U, - 0x36U, 0x02U, 0xB6U, 0x01U, 0x20U, 0x00U, 0x41U, 0xBAU, 0x01U, 0x6AU, 0x22U, - 0x01U, 0x41U, 0xC6U, 0x07U, 0x10U, 0x0EU, 0xA7U, 0x20U, 0x01U, 0x6AU, 0x22U, - 0x01U, 0x41U, 0xFBU, 0xDDU, 0x03U, 0x3BU, 0x00U, 0x00U, 0x20U, 0x01U, 0x41U, - 0x02U, 0x6AU, 0x21U, 0x01U, 0x20U, 0x00U, 0x28U, 0x02U, 0x20U, 0x22U, 0x03U, - 0x04U, 0x40U, 0x20U, 0x01U, 0x41U, 0x22U, 0x36U, 0x00U, 0x00U, 0x20U, 0x01U, - 0x41U, 0x04U, 0x6AU, 0x41U, 0x01U, 0x3AU, 0x00U, 0x00U, 0x20U, 0x01U, 0x41U, - 0x06U, 0x6AU, 0x21U, 0x02U, 0x20U, 0x01U, 0x41U, 0x05U, 0x6AU, 0x21U, 0x01U, - 0x20U, 0x03U, 0x41U, 0x7FU, 0x46U, 0x04U, 0x7FU, 0x20U, 0x01U, 0x41U, 0xFBU, - 0x00U, 0x3BU, 0x00U, 0x00U, 0x20U, 0x02U, 0x41U, 0x01U, 0x6AU, 0x05U, 0x20U, - 0x01U, 0x41U, 0xD0U, 0x3EU, 0x3BU, 0x00U, 0x00U, 0x20U, 0x01U, 0x20U, 0x03U, - 0x29U, 0x03U, 0x00U, 0x37U, 0x03U, 0x02U, 0x20U, 0x01U, 0x20U, 0x03U, 0x29U, - 0x03U, 0x08U, 0x37U, 0x03U, 0x0AU, 0x20U, 0x01U, 0x20U, 0x03U, 0x29U, 0x03U, - 0x10U, 0x37U, 0x03U, 0x12U, 0x20U, 0x01U, 0x20U, 0x03U, 0x29U, 0x03U, 0x18U, - 0x37U, 0x03U, 0x1AU, 0x20U, 0x02U, 0x41U, 0x21U, 0x6AU, 0x0BU, 0x21U, 0x01U, - 0x0BU, 0x20U, 0x01U, 0x41U, 0xE1U, 0xDDU, 0x03U, 0x3BU, 0x00U, 0x00U, 0x20U, - 0x01U, 0x41U, 0x02U, 0x6AU, 0x21U, 0x03U, 0x20U, 0x00U, 0x28U, 0x02U, 0x24U, - 0x22U, 0x02U, 0x04U, 0x7FU, 0x20U, 0x01U, 0x41U, 0x01U, 0x3AU, 0x00U, 0x06U, - 0x20U, 0x01U, 0x41U, 0x22U, 0x36U, 0x00U, 0x02U, 0x20U, 0x02U, 0x41U, 0x7FU, - 0x46U, 0x04U, 0x7FU, 0x20U, 0x01U, 0x41U, 0xFBU, 0x00U, 0x3BU, 0x00U, 0x07U, - 0x20U, 0x01U, 0x41U, 0x09U, 0x6AU, 0x05U, 0x20U, 0x01U, 0x41U, 0xD0U, 0x3EU, - 0x3BU, 0x00U, 0x07U, 0x20U, 0x01U, 0x20U, 0x02U, 0x29U, 0x03U, 0x00U, 0x37U, - 0x03U, 0x09U, 0x20U, 0x01U, 0x41U, 0x11U, 0x6AU, 0x20U, 0x02U, 0x29U, 0x03U, - 0x08U, 0x37U, 0x03U, 0x00U, 0x20U, 0x01U, 0x41U, 0x19U, 0x6AU, 0x20U, 0x02U, - 0x29U, 0x03U, 0x10U, 0x37U, 0x03U, 0x00U, 0x20U, 0x01U, 0x41U, 0x21U, 0x6AU, - 0x20U, 0x02U, 0x29U, 0x03U, 0x18U, 0x37U, 0x03U, 0x00U, 0x20U, 0x01U, 0x41U, - 0x29U, 0x6AU, 0x0BU, 0x05U, 0x20U, 0x03U, 0x0BU, 0x22U, 0x01U, 0x41U, 0xE1U, - 0x01U, 0x3AU, 0x00U, 0x00U, 0x20U, 0x00U, 0x28U, 0x02U, 0x28U, 0x21U, 0x02U, - 0x20U, 0x01U, 0x41U, 0xEEU, 0x01U, 0x3AU, 0x00U, 0x01U, 0x20U, 0x01U, 0x41U, - 0x02U, 0x6AU, 0x21U, 0x03U, 0x20U, 0x02U, 0x04U, 0x7FU, 0x20U, 0x01U, 0x41U, - 0x01U, 0x3AU, 0x00U, 0x06U, 0x20U, 0x01U, 0x41U, 0x22U, 0x36U, 0x00U, 0x02U, - 0x20U, 0x02U, 0x41U, 0x7FU, 0x46U, 0x04U, 0x7FU, 0x20U, 0x01U, 0x41U, 0xFBU, - 0x00U, 0x3BU, 0x00U, 0x07U, 0x20U, 0x01U, 0x41U, 0x09U, 0x6AU, 0x05U, 0x20U, - 0x01U, 0x41U, 0xD0U, 0x3EU, 0x3BU, 0x00U, 0x07U, 0x20U, 0x01U, 0x20U, 0x02U, - 0x29U, 0x03U, 0x00U, 0x37U, 0x03U, 0x09U, 0x20U, 0x01U, 0x41U, 0x11U, 0x6AU, - 0x20U, 0x02U, 0x29U, 0x03U, 0x08U, 0x37U, 0x03U, 0x00U, 0x20U, 0x01U, 0x41U, - 0x19U, 0x6AU, 0x20U, 0x02U, 0x29U, 0x03U, 0x10U, 0x37U, 0x03U, 0x00U, 0x20U, - 0x01U, 0x41U, 0x21U, 0x6AU, 0x20U, 0x02U, 0x29U, 0x03U, 0x18U, 0x37U, 0x03U, - 0x00U, 0x20U, 0x01U, 0x41U, 0x29U, 0x6AU, 0x0BU, 0x05U, 0x20U, 0x03U, 0x0BU, - 0x22U, 0x01U, 0x41U, 0xE1U, 0x01U, 0x3AU, 0x00U, 0x00U, 0x20U, 0x00U, 0x28U, - 0x02U, 0x2CU, 0x21U, 0x02U, 0x20U, 0x01U, 0x41U, 0xEEU, 0x01U, 0x3AU, 0x00U, - 0x01U, 0x20U, 0x01U, 0x41U, 0x02U, 0x6AU, 0x21U, 0x03U, 0x20U, 0x02U, 0x04U, - 0x7FU, 0x20U, 0x01U, 0x41U, 0x01U, 0x3AU, 0x00U, 0x06U, 0x20U, 0x01U, 0x41U, - 0x22U, 0x36U, 0x00U, 0x02U, 0x20U, 0x02U, 0x41U, 0x7FU, 0x46U, 0x04U, 0x7FU, - 0x20U, 0x01U, 0x41U, 0xFBU, 0x00U, 0x3BU, 0x00U, 0x07U, 0x20U, 0x01U, 0x41U, - 0x09U, 0x6AU, 0x05U, 0x20U, 0x01U, 0x41U, 0xD0U, 0x3EU, 0x3BU, 0x00U, 0x07U, - 0x20U, 0x01U, 0x20U, 0x02U, 0x29U, 0x03U, 0x00U, 0x37U, 0x03U, 0x09U, 0x20U, - 0x01U, 0x41U, 0x11U, 0x6AU, 0x20U, 0x02U, 0x29U, 0x03U, 0x08U, 0x37U, 0x03U, - 0x00U, 0x20U, 0x01U, 0x41U, 0x19U, 0x6AU, 0x20U, 0x02U, 0x29U, 0x03U, 0x10U, - 0x37U, 0x03U, 0x00U, 0x20U, 0x01U, 0x41U, 0x21U, 0x6AU, 0x20U, 0x02U, 0x29U, - 0x03U, 0x18U, 0x37U, 0x03U, 0x00U, 0x20U, 0x01U, 0x41U, 0x29U, 0x6AU, 0x0BU, - 0x05U, 0x20U, 0x03U, 0x0BU, 0x22U, 0x01U, 0x41U, 0xE1U, 0x01U, 0x3AU, 0x00U, - 0x00U, 0x20U, 0x00U, 0x28U, 0x02U, 0x30U, 0x21U, 0x02U, 0x20U, 0x01U, 0x41U, - 0xEEU, 0x01U, 0x3AU, 0x00U, 0x01U, 0x20U, 0x01U, 0x41U, 0x02U, 0x6AU, 0x21U, - 0x03U, 0x20U, 0x02U, 0x04U, 0x7FU, 0x20U, 0x01U, 0x41U, 0x01U, 0x3AU, 0x00U, - 0x06U, 0x20U, 0x01U, 0x41U, 0x22U, 0x36U, 0x00U, 0x02U, 0x20U, 0x02U, 0x41U, - 0x7FU, 0x46U, 0x04U, 0x7FU, 0x20U, 0x01U, 0x41U, 0xFBU, 0x00U, 0x3BU, 0x00U, - 0x07U, 0x20U, 0x01U, 0x41U, 0x09U, 0x6AU, 0x05U, 0x20U, 0x01U, 0x41U, 0xD0U, - 0x3EU, 0x3BU, 0x00U, 0x07U, 0x20U, 0x01U, 0x20U, 0x02U, 0x29U, 0x03U, 0x00U, - 0x37U, 0x03U, 0x09U, 0x20U, 0x01U, 0x41U, 0x11U, 0x6AU, 0x20U, 0x02U, 0x29U, - 0x03U, 0x08U, 0x37U, 0x03U, 0x00U, 0x20U, 0x01U, 0x41U, 0x19U, 0x6AU, 0x20U, - 0x02U, 0x29U, 0x03U, 0x10U, 0x37U, 0x03U, 0x00U, 0x20U, 0x01U, 0x41U, 0x21U, - 0x6AU, 0x20U, 0x02U, 0x29U, 0x03U, 0x18U, 0x37U, 0x03U, 0x00U, 0x20U, 0x01U, - 0x41U, 0x29U, 0x6AU, 0x0BU, 0x05U, 0x20U, 0x03U, 0x0BU, 0x22U, 0x01U, 0x41U, - 0xE1U, 0x01U, 0x3AU, 0x00U, 0x00U, 0x20U, 0x00U, 0x28U, 0x02U, 0x34U, 0x21U, - 0x02U, 0x20U, 0x01U, 0x41U, 0xEEU, 0x01U, 0x3AU, 0x00U, 0x01U, 0x20U, 0x01U, - 0x41U, 0x02U, 0x6AU, 0x21U, 0x03U, 0x20U, 0x02U, 0x04U, 0x7FU, 0x20U, 0x01U, - 0x41U, 0x01U, 0x3AU, 0x00U, 0x06U, 0x20U, 0x01U, 0x41U, 0x22U, 0x36U, 0x00U, - 0x02U, 0x20U, 0x02U, 0x41U, 0x7FU, 0x46U, 0x04U, 0x7FU, 0x20U, 0x01U, 0x41U, - 0xFBU, 0x00U, 0x3BU, 0x00U, 0x07U, 0x20U, 0x01U, 0x41U, 0x09U, 0x6AU, 0x05U, - 0x20U, 0x01U, 0x41U, 0xD0U, 0x3EU, 0x3BU, 0x00U, 0x07U, 0x20U, 0x01U, 0x20U, - 0x02U, 0x29U, 0x03U, 0x00U, 0x37U, 0x03U, 0x09U, 0x20U, 0x01U, 0x41U, 0x11U, - 0x6AU, 0x20U, 0x02U, 0x29U, 0x03U, 0x08U, 0x37U, 0x03U, 0x00U, 0x20U, 0x01U, - 0x41U, 0x19U, 0x6AU, 0x20U, 0x02U, 0x29U, 0x03U, 0x10U, 0x37U, 0x03U, 0x00U, - 0x20U, 0x01U, 0x41U, 0x21U, 0x6AU, 0x20U, 0x02U, 0x29U, 0x03U, 0x18U, 0x37U, - 0x03U, 0x00U, 0x20U, 0x01U, 0x41U, 0x29U, 0x6AU, 0x0BU, 0x05U, 0x20U, 0x03U, - 0x0BU, 0x22U, 0x01U, 0x41U, 0xE1U, 0x01U, 0x3AU, 0x00U, 0x00U, 0x20U, 0x00U, - 0x28U, 0x02U, 0x38U, 0x21U, 0x02U, 0x20U, 0x01U, 0x41U, 0xEEU, 0x01U, 0x3AU, - 0x00U, 0x01U, 0x20U, 0x01U, 0x41U, 0x02U, 0x6AU, 0x21U, 0x03U, 0x20U, 0x02U, - 0x04U, 0x7FU, 0x20U, 0x01U, 0x41U, 0x01U, 0x3AU, 0x00U, 0x06U, 0x20U, 0x01U, - 0x41U, 0x22U, 0x36U, 0x00U, 0x02U, 0x20U, 0x02U, 0x41U, 0x7FU, 0x46U, 0x04U, - 0x7FU, 0x20U, 0x01U, 0x41U, 0xFBU, 0x00U, 0x3BU, 0x00U, 0x07U, 0x20U, 0x01U, - 0x41U, 0x09U, 0x6AU, 0x05U, 0x20U, 0x01U, 0x41U, 0xD0U, 0x3EU, 0x3BU, 0x00U, - 0x07U, 0x20U, 0x01U, 0x20U, 0x02U, 0x29U, 0x03U, 0x00U, 0x37U, 0x03U, 0x09U, - 0x20U, 0x01U, 0x41U, 0x11U, 0x6AU, 0x20U, 0x02U, 0x29U, 0x03U, 0x08U, 0x37U, - 0x03U, 0x00U, 0x20U, 0x01U, 0x41U, 0x19U, 0x6AU, 0x20U, 0x02U, 0x29U, 0x03U, - 0x10U, 0x37U, 0x03U, 0x00U, 0x20U, 0x01U, 0x41U, 0x21U, 0x6AU, 0x20U, 0x02U, - 0x29U, 0x03U, 0x18U, 0x37U, 0x03U, 0x00U, 0x20U, 0x01U, 0x41U, 0x29U, 0x6AU, - 0x0BU, 0x05U, 0x20U, 0x03U, 0x0BU, 0x22U, 0x01U, 0x41U, 0xE1U, 0x01U, 0x3AU, - 0x00U, 0x00U, 0x20U, 0x00U, 0x28U, 0x02U, 0x3CU, 0x21U, 0x02U, 0x20U, 0x01U, - 0x41U, 0xEEU, 0x01U, 0x3AU, 0x00U, 0x01U, 0x20U, 0x01U, 0x41U, 0x02U, 0x6AU, - 0x21U, 0x03U, 0x20U, 0x02U, 0x04U, 0x7FU, 0x20U, 0x01U, 0x41U, 0x01U, 0x3AU, - 0x00U, 0x06U, 0x20U, 0x01U, 0x41U, 0x22U, 0x36U, 0x00U, 0x02U, 0x20U, 0x02U, - 0x41U, 0x7FU, 0x46U, 0x04U, 0x7FU, 0x20U, 0x01U, 0x41U, 0xFBU, 0x00U, 0x3BU, - 0x00U, 0x07U, 0x20U, 0x01U, 0x41U, 0x09U, 0x6AU, 0x05U, 0x20U, 0x01U, 0x41U, - 0xD0U, 0x3EU, 0x3BU, 0x00U, 0x07U, 0x20U, 0x01U, 0x20U, 0x02U, 0x29U, 0x03U, - 0x00U, 0x37U, 0x03U, 0x09U, 0x20U, 0x01U, 0x41U, 0x11U, 0x6AU, 0x20U, 0x02U, - 0x29U, 0x03U, 0x08U, 0x37U, 0x03U, 0x00U, 0x20U, 0x01U, 0x41U, 0x19U, 0x6AU, - 0x20U, 0x02U, 0x29U, 0x03U, 0x10U, 0x37U, 0x03U, 0x00U, 0x20U, 0x01U, 0x41U, - 0x21U, 0x6AU, 0x20U, 0x02U, 0x29U, 0x03U, 0x18U, 0x37U, 0x03U, 0x00U, 0x20U, - 0x01U, 0x41U, 0x29U, 0x6AU, 0x0BU, 0x05U, 0x20U, 0x03U, 0x0BU, 0x22U, 0x01U, - 0x41U, 0xE1U, 0x01U, 0x3AU, 0x00U, 0x00U, 0x20U, 0x00U, 0x28U, 0x02U, 0x40U, + 0x0BU, 0x21U, 0x0DU, 0x20U, 0x00U, 0x31U, 0x00U, 0x8FU, 0x09U, 0x21U, 0x0EU, + 0x02U, 0x40U, 0x20U, 0x01U, 0x04U, 0x40U, 0x20U, 0x0EU, 0x20U, 0x0BU, 0x42U, + 0x02U, 0x20U, 0x0BU, 0x42U, 0x02U, 0x55U, 0x1BU, 0x59U, 0x0DU, 0x01U, 0x41U, + 0x8AU, 0x14U, 0x41U, 0x36U, 0x42U, 0x88U, 0x03U, 0x10U, 0x05U, 0x1AU, 0x05U, + 0x20U, 0x0EU, 0x20U, 0x0DU, 0x42U, 0x02U, 0x20U, 0x0DU, 0x42U, 0x02U, 0x55U, + 0x1BU, 0x20U, 0x0CU, 0x20U, 0x04U, 0x41U, 0xD3U, 0x00U, 0x46U, 0x1BU, 0x59U, + 0x0DU, 0x01U, 0x41U, 0xD1U, 0x13U, 0x41U, 0x39U, 0x42U, 0x83U, 0x03U, 0x10U, + 0x05U, 0x1AU, 0x0BU, 0x0BU, 0x41U, 0xC0U, 0x14U, 0x41U, 0x11U, 0x41U, 0xD2U, + 0x14U, 0x41U, 0x10U, 0x41U, 0x00U, 0x10U, 0x08U, 0x1AU, 0x20U, 0x00U, 0x2DU, + 0x00U, 0xECU, 0x09U, 0x41U, 0x01U, 0x47U, 0x20U, 0x02U, 0x72U, 0x45U, 0x04U, + 0x40U, 0x10U, 0x0DU, 0x21U, 0x0BU, 0x20U, 0x00U, 0x41U, 0xE8U, 0x80U, 0x01U, + 0x3BU, 0x00U, 0x99U, 0x01U, 0x20U, 0x00U, 0x41U, 0xA0U, 0x36U, 0x3BU, 0x00U, + 0x93U, 0x01U, 0x20U, 0x00U, 0x41U, 0xA0U, 0x34U, 0x3BU, 0x00U, 0x8DU, 0x01U, + 0x20U, 0x00U, 0x41U, 0x00U, 0x36U, 0x00U, 0x89U, 0x01U, 0x20U, 0x00U, 0x41U, + 0x24U, 0x3AU, 0x00U, 0x88U, 0x01U, 0x20U, 0x00U, 0x42U, 0x92U, 0x80U, 0x8CU, + 0x93U, 0x82U, 0x10U, 0x37U, 0x03U, 0x80U, 0x01U, 0x20U, 0x00U, 0x41U, 0x00U, + 0x36U, 0x00U, 0x9BU, 0x01U, 0x20U, 0x00U, 0x42U, 0x80U, 0x80U, 0x80U, 0x80U, + 0xB0U, 0x8EU, 0xC0U, 0xC0U, 0x14U, 0x37U, 0x00U, 0x9EU, 0x01U, 0x20U, 0x00U, + 0x20U, 0x0BU, 0xA7U, 0x22U, 0x02U, 0x41U, 0x05U, 0x6AU, 0x22U, 0x01U, 0x3AU, + 0x00U, 0x98U, 0x01U, 0x20U, 0x00U, 0x20U, 0x01U, 0x41U, 0x08U, 0x76U, 0x3AU, + 0x00U, 0x97U, 0x01U, 0x20U, 0x00U, 0x20U, 0x01U, 0x41U, 0x10U, 0x76U, 0x3AU, + 0x00U, 0x96U, 0x01U, 0x20U, 0x00U, 0x20U, 0x01U, 0x41U, 0x18U, 0x76U, 0x3AU, + 0x00U, 0x95U, 0x01U, 0x20U, 0x00U, 0x20U, 0x02U, 0x41U, 0x01U, 0x6AU, 0x22U, + 0x01U, 0x3AU, 0x00U, 0x92U, 0x01U, 0x20U, 0x00U, 0x20U, 0x01U, 0x41U, 0x08U, + 0x76U, 0x3AU, 0x00U, 0x91U, 0x01U, 0x20U, 0x00U, 0x20U, 0x01U, 0x41U, 0x10U, + 0x76U, 0x3AU, 0x00U, 0x90U, 0x01U, 0x20U, 0x00U, 0x20U, 0x01U, 0x41U, 0x18U, + 0x76U, 0x3AU, 0x00U, 0x8FU, 0x01U, 0x20U, 0x00U, 0x20U, 0x00U, 0x29U, 0x03U, + 0xFCU, 0x09U, 0x37U, 0x03U, 0xA6U, 0x01U, 0x20U, 0x00U, 0x41U, 0x83U, 0x29U, + 0x3BU, 0x01U, 0xBAU, 0x01U, 0x20U, 0x00U, 0x20U, 0x00U, 0x29U, 0x03U, 0x84U, + 0x0AU, 0x37U, 0x03U, 0xAEU, 0x01U, 0x20U, 0x00U, 0x20U, 0x00U, 0x28U, 0x02U, + 0x8CU, 0x0AU, 0x36U, 0x02U, 0xB6U, 0x01U, 0x20U, 0x00U, 0x41U, 0x80U, 0x08U, + 0x29U, 0x03U, 0x00U, 0x37U, 0x03U, 0xBCU, 0x01U, 0x20U, 0x00U, 0x41U, 0x88U, + 0x08U, 0x29U, 0x03U, 0x00U, 0x37U, 0x03U, 0xC4U, 0x01U, 0x20U, 0x00U, 0x41U, + 0x90U, 0x08U, 0x28U, 0x02U, 0x00U, 0x36U, 0x02U, 0xCCU, 0x01U, 0x20U, 0x00U, + 0x41U, 0xD0U, 0x01U, 0x6AU, 0x22U, 0x01U, 0x41U, 0x80U, 0x04U, 0x10U, 0x0EU, + 0xA7U, 0x20U, 0x01U, 0x6AU, 0x22U, 0x01U, 0x41U, 0xF0U, 0xB2U, 0x08U, 0x36U, + 0x02U, 0x08U, 0x20U, 0x01U, 0x41U, 0x0BU, 0x6AU, 0x20U, 0x04U, 0x3AU, 0x00U, + 0x00U, 0x20U, 0x01U, 0x41U, 0x16U, 0x6AU, 0x20U, 0x03U, 0x3AU, 0x00U, 0x00U, + 0x20U, 0x01U, 0x41U, 0x15U, 0x6AU, 0x41U, 0x19U, 0x3AU, 0x00U, 0x00U, 0x20U, + 0x01U, 0x41U, 0x0CU, 0x6AU, 0x20U, 0x00U, 0x2DU, 0x00U, 0xEDU, 0x09U, 0x3AU, + 0x00U, 0x00U, 0x20U, 0x01U, 0x42U, 0xF0U, 0xA7U, 0x80U, 0xBFU, 0x81U, 0x8EU, + 0xC6U, 0x80U, 0xD4U, 0x00U, 0x37U, 0x03U, 0x00U, 0x20U, 0x01U, 0x41U, 0x0DU, + 0x6AU, 0x42U, 0xE1U, 0xC1U, 0xDFU, 0x80U, 0x87U, 0xA3U, 0x80U, 0xABU, 0xF0U, + 0x00U, 0x37U, 0x03U, 0x00U, 0x20U, 0x01U, 0x41U, 0x17U, 0x6AU, 0x22U, 0x02U, + 0x20U, 0x05U, 0x29U, 0x03U, 0x00U, 0x37U, 0x03U, 0x00U, 0x20U, 0x01U, 0x41U, + 0x1FU, 0x6AU, 0x20U, 0x05U, 0x29U, 0x03U, 0x08U, 0x37U, 0x03U, 0x00U, 0x20U, + 0x01U, 0x41U, 0x27U, 0x6AU, 0x20U, 0x05U, 0x29U, 0x03U, 0x10U, 0x37U, 0x03U, + 0x00U, 0x20U, 0x01U, 0x41U, 0x2FU, 0x6AU, 0x20U, 0x05U, 0x29U, 0x03U, 0x18U, + 0x37U, 0x03U, 0x00U, 0x20U, 0x02U, 0x20U, 0x03U, 0x6AU, 0x22U, 0x01U, 0x41U, + 0xE1U, 0xE3U, 0x03U, 0x3BU, 0x01U, 0x00U, 0x20U, 0x01U, 0x20U, 0x00U, 0x41U, + 0x80U, 0x01U, 0x6AU, 0x22U, 0x01U, 0x6BU, 0x21U, 0x02U, 0x20U, 0x00U, 0x20U, + 0x01U, 0x20U, 0x02U, 0x10U, 0x0FU, 0x22U, 0x0BU, 0x3CU, 0x00U, 0xA1U, 0x01U, + 0x20U, 0x00U, 0x41U, 0xE8U, 0x00U, 0x3AU, 0x00U, 0x99U, 0x01U, 0x20U, 0x00U, + 0x20U, 0x0BU, 0x42U, 0x08U, 0x88U, 0x3CU, 0x00U, 0xA0U, 0x01U, 0x20U, 0x00U, + 0x20U, 0x0BU, 0x42U, 0x10U, 0x88U, 0x3CU, 0x00U, 0x9FU, 0x01U, 0x20U, 0x00U, + 0x20U, 0x0BU, 0x42U, 0x18U, 0x88U, 0x3CU, 0x00U, 0x9EU, 0x01U, 0x20U, 0x00U, + 0x20U, 0x0BU, 0x42U, 0x20U, 0x88U, 0x3CU, 0x00U, 0x9DU, 0x01U, 0x20U, 0x00U, + 0x20U, 0x0BU, 0x42U, 0x28U, 0x88U, 0x3CU, 0x00U, 0x9CU, 0x01U, 0x20U, 0x00U, + 0x20U, 0x0BU, 0x42U, 0x30U, 0x88U, 0x3CU, 0x00U, 0x9BU, 0x01U, 0x20U, 0x00U, + 0x20U, 0x0BU, 0x42U, 0x38U, 0x88U, 0xA7U, 0x41U, 0x3FU, 0x71U, 0x41U, 0xC0U, + 0x00U, 0x72U, 0x3AU, 0x00U, 0x9AU, 0x01U, 0x41U, 0xE2U, 0x14U, 0x41U, 0x22U, + 0x20U, 0x01U, 0x20U, 0x02U, 0x41U, 0x01U, 0x10U, 0x08U, 0x1AU, 0x41U, 0x84U, + 0x15U, 0x41U, 0x18U, 0x20U, 0x00U, 0x41U, 0x20U, 0x6AU, 0x41U, 0x20U, 0x20U, + 0x01U, 0x20U, 0x02U, 0x10U, 0x10U, 0x22U, 0x0BU, 0x10U, 0x03U, 0x1AU, 0x20U, + 0x0BU, 0x42U, 0x20U, 0x51U, 0x04U, 0x40U, 0x41U, 0x9CU, 0x15U, 0x41U, 0x2AU, + 0x42U, 0xD6U, 0x03U, 0x10U, 0x05U, 0x1AU, 0x0BU, 0x41U, 0xC6U, 0x15U, 0x41U, + 0x25U, 0x42U, 0xD8U, 0x03U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x02U, 0x40U, 0x02U, + 0x40U, 0x20U, 0x04U, 0x41U, 0xD2U, 0x00U, 0x6BU, 0x22U, 0x01U, 0x41U, 0x01U, + 0x4DU, 0x04U, 0x40U, 0x20U, 0x01U, 0x41U, 0x01U, 0x46U, 0x0DU, 0x01U, 0x41U, + 0xEBU, 0x15U, 0x41U, 0x06U, 0x20U, 0x05U, 0x20U, 0x03U, 0x20U, 0x00U, 0x41U, + 0xEEU, 0x09U, 0x6AU, 0x41U, 0x02U, 0x10U, 0x0CU, 0x22U, 0x0BU, 0x10U, 0x03U, + 0x1AU, 0x20U, 0x0BU, 0x42U, 0x00U, 0x57U, 0x04U, 0x40U, 0x41U, 0xB4U, 0x0AU, + 0x41U, 0x1AU, 0x42U, 0xE2U, 0x03U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x20U, 0x00U, + 0x2DU, 0x00U, 0xEDU, 0x09U, 0x41U, 0xD2U, 0x00U, 0x46U, 0x04U, 0x40U, 0x41U, + 0xF2U, 0x15U, 0x41U, 0x29U, 0x42U, 0xE4U, 0x03U, 0x10U, 0x05U, 0x1AU, 0x0BU, + 0x41U, 0x9BU, 0x16U, 0x41U, 0x2AU, 0x42U, 0xE6U, 0x03U, 0x10U, 0x05U, 0x1AU, + 0x05U, 0x20U, 0x04U, 0x41U, 0xC8U, 0x00U, 0x47U, 0x0DU, 0x02U, 0x0BU, 0x20U, + 0x00U, 0x41U, 0xD0U, 0x00U, 0x6AU, 0x22U, 0x01U, 0x41U, 0x22U, 0x41U, 0x01U, + 0x20U, 0x08U, 0x41U, 0x14U, 0x41U, 0x00U, 0x41U, 0x00U, 0x41U, 0x00U, 0x41U, + 0x00U, 0x10U, 0x11U, 0x1AU, 0x20U, 0x01U, 0x41U, 0x22U, 0x41U, 0x05U, 0x10U, + 0x12U, 0x1AU, 0x41U, 0x05U, 0x41U, 0x8BU, 0x80U, 0x3CU, 0x41U, 0x06U, 0x10U, + 0x13U, 0x1AU, 0x41U, 0x06U, 0x20U, 0x00U, 0x2DU, 0x00U, 0xEDU, 0x09U, 0x41U, + 0x07U, 0x10U, 0x14U, 0x42U, 0x07U, 0x51U, 0x04U, 0x40U, 0x02U, 0x40U, 0x41U, + 0x07U, 0x41U, 0x9FU, 0x80U, 0x14U, 0x41U, 0x08U, 0x10U, 0x13U, 0x42U, 0x08U, + 0x52U, 0x0DU, 0x00U, 0x20U, 0x00U, 0x41U, 0x80U, 0x01U, 0x6AU, 0x41U, 0x20U, + 0x41U, 0x08U, 0x10U, 0x15U, 0x42U, 0x20U, 0x52U, 0x04U, 0x40U, 0x41U, 0xB4U, + 0x0AU, 0x41U, 0x1AU, 0x42U, 0xFDU, 0x03U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x20U, + 0x00U, 0x29U, 0x03U, 0x80U, 0x01U, 0x20U, 0x00U, 0x29U, 0x03U, 0xB0U, 0x09U, + 0x52U, 0x20U, 0x00U, 0x29U, 0x03U, 0x88U, 0x01U, 0x20U, 0x00U, 0x29U, 0x03U, + 0xB8U, 0x09U, 0x52U, 0x72U, 0x20U, 0x00U, 0x29U, 0x03U, 0x90U, 0x01U, 0x20U, + 0x00U, 0x29U, 0x03U, 0xC0U, 0x09U, 0x52U, 0x20U, 0x00U, 0x29U, 0x03U, 0x98U, + 0x01U, 0x20U, 0x00U, 0x29U, 0x03U, 0xC8U, 0x09U, 0x52U, 0x72U, 0x72U, 0x0DU, + 0x00U, 0x41U, 0xC5U, 0x16U, 0x41U, 0x3DU, 0x42U, 0x81U, 0x04U, 0x10U, 0x05U, + 0x1AU, 0x0BU, 0x0BU, 0x20U, 0x07U, 0x45U, 0x04U, 0x40U, 0x02U, 0x40U, 0x20U, + 0x00U, 0x41U, 0xD0U, 0x00U, 0x6AU, 0x22U, 0x01U, 0x41U, 0x22U, 0x41U, 0x18U, + 0x20U, 0x00U, 0x41U, 0xB0U, 0x09U, 0x6AU, 0x41U, 0x20U, 0x41U, 0x00U, 0x41U, + 0x00U, 0x41U, 0x00U, 0x41U, 0x00U, 0x10U, 0x11U, 0x1AU, 0x20U, 0x01U, 0x41U, + 0x22U, 0x41U, 0x09U, 0x10U, 0x12U, 0x42U, 0x09U, 0x51U, 0x0DU, 0x00U, 0x41U, + 0x82U, 0x17U, 0x41U, 0xC3U, 0x00U, 0x42U, 0x8CU, 0x04U, 0x10U, 0x0BU, 0x1AU, + 0x0BU, 0x0BU, 0x20U, 0x00U, 0x41U, 0x20U, 0x6AU, 0x20U, 0x00U, 0x2DU, 0x00U, + 0xEDU, 0x09U, 0x41U, 0x02U, 0x74U, 0x6AU, 0x41U, 0x7FU, 0x20U, 0x00U, 0x41U, + 0xB0U, 0x09U, 0x6AU, 0x20U, 0x07U, 0x1BU, 0x36U, 0x02U, 0x00U, 0x10U, 0x0DU, + 0x21U, 0x0BU, 0x20U, 0x00U, 0x41U, 0x14U, 0x10U, 0x07U, 0x1AU, 0x20U, 0x00U, + 0x41U, 0x9EU, 0x01U, 0x6AU, 0x42U, 0x80U, 0x80U, 0x80U, 0x80U, 0xB0U, 0x8EU, + 0xC0U, 0xC0U, 0x14U, 0x37U, 0x00U, 0x00U, 0x20U, 0x00U, 0x41U, 0xE8U, 0x80U, + 0x01U, 0x3BU, 0x00U, 0x99U, 0x01U, 0x20U, 0x00U, 0x41U, 0xA0U, 0x36U, 0x3BU, + 0x00U, 0x93U, 0x01U, 0x20U, 0x00U, 0x41U, 0xA0U, 0x34U, 0x3BU, 0x00U, 0x8DU, + 0x01U, 0x20U, 0x00U, 0x41U, 0x00U, 0x36U, 0x00U, 0x89U, 0x01U, 0x20U, 0x00U, + 0x41U, 0x24U, 0x3AU, 0x00U, 0x88U, 0x01U, 0x20U, 0x00U, 0x42U, 0x92U, 0x80U, + 0xD8U, 0x90U, 0x82U, 0x10U, 0x37U, 0x03U, 0x80U, 0x01U, 0x20U, 0x00U, 0x41U, + 0x00U, 0x36U, 0x00U, 0x9BU, 0x01U, 0x20U, 0x00U, 0x20U, 0x0BU, 0xA7U, 0x22U, + 0x02U, 0x41U, 0x05U, 0x6AU, 0x22U, 0x01U, 0x3AU, 0x00U, 0x98U, 0x01U, 0x20U, + 0x00U, 0x20U, 0x01U, 0x41U, 0x08U, 0x76U, 0x3AU, 0x00U, 0x97U, 0x01U, 0x20U, + 0x00U, 0x20U, 0x01U, 0x41U, 0x10U, 0x76U, 0x3AU, 0x00U, 0x96U, 0x01U, 0x20U, + 0x00U, 0x20U, 0x01U, 0x41U, 0x18U, 0x76U, 0x3AU, 0x00U, 0x95U, 0x01U, 0x20U, + 0x00U, 0x20U, 0x02U, 0x41U, 0x01U, 0x6AU, 0x22U, 0x01U, 0x3AU, 0x00U, 0x92U, + 0x01U, 0x20U, 0x00U, 0x20U, 0x01U, 0x41U, 0x08U, 0x76U, 0x3AU, 0x00U, 0x91U, + 0x01U, 0x20U, 0x00U, 0x20U, 0x01U, 0x41U, 0x10U, 0x76U, 0x3AU, 0x00U, 0x90U, + 0x01U, 0x20U, 0x00U, 0x20U, 0x01U, 0x41U, 0x18U, 0x76U, 0x3AU, 0x00U, 0x8FU, + 0x01U, 0x20U, 0x00U, 0x20U, 0x00U, 0x29U, 0x03U, 0x00U, 0x37U, 0x03U, 0xA6U, + 0x01U, 0x20U, 0x00U, 0x20U, 0x00U, 0x29U, 0x03U, 0x08U, 0x37U, 0x03U, 0xAEU, + 0x01U, 0x20U, 0x00U, 0x20U, 0x00U, 0x28U, 0x02U, 0x10U, 0x36U, 0x02U, 0xB6U, + 0x01U, 0x20U, 0x00U, 0x41U, 0xBAU, 0x01U, 0x6AU, 0x22U, 0x01U, 0x41U, 0xC6U, + 0x07U, 0x10U, 0x0EU, 0xA7U, 0x20U, 0x01U, 0x6AU, 0x22U, 0x01U, 0x41U, 0xFBU, + 0xDDU, 0x03U, 0x3BU, 0x00U, 0x00U, 0x20U, 0x01U, 0x41U, 0x02U, 0x6AU, 0x21U, + 0x01U, 0x20U, 0x00U, 0x28U, 0x02U, 0x20U, 0x22U, 0x02U, 0x04U, 0x40U, 0x20U, + 0x01U, 0x41U, 0x22U, 0x36U, 0x00U, 0x00U, 0x20U, 0x01U, 0x41U, 0x04U, 0x6AU, + 0x41U, 0x01U, 0x3AU, 0x00U, 0x00U, 0x20U, 0x01U, 0x41U, 0x06U, 0x6AU, 0x21U, + 0x04U, 0x20U, 0x01U, 0x41U, 0x05U, 0x6AU, 0x21U, 0x01U, 0x20U, 0x02U, 0x41U, + 0x7FU, 0x47U, 0x04U, 0x7FU, 0x20U, 0x01U, 0x41U, 0xD0U, 0x3EU, 0x3BU, 0x00U, + 0x00U, 0x20U, 0x01U, 0x20U, 0x02U, 0x29U, 0x03U, 0x00U, 0x37U, 0x03U, 0x02U, + 0x20U, 0x01U, 0x20U, 0x02U, 0x29U, 0x03U, 0x08U, 0x37U, 0x03U, 0x0AU, 0x20U, + 0x01U, 0x20U, 0x02U, 0x29U, 0x03U, 0x10U, 0x37U, 0x03U, 0x12U, 0x20U, 0x01U, + 0x20U, 0x02U, 0x29U, 0x03U, 0x18U, 0x37U, 0x03U, 0x1AU, 0x20U, 0x04U, 0x41U, + 0x21U, 0x6AU, 0x05U, 0x20U, 0x01U, 0x41U, 0xFBU, 0x00U, 0x3BU, 0x00U, 0x00U, + 0x20U, 0x04U, 0x41U, 0x01U, 0x6AU, 0x0BU, 0x21U, 0x01U, 0x0BU, 0x20U, 0x01U, + 0x41U, 0xE1U, 0x01U, 0x3AU, 0x00U, 0x00U, 0x20U, 0x00U, 0x28U, 0x02U, 0x24U, 0x21U, 0x02U, 0x20U, 0x01U, 0x41U, 0xEEU, 0x01U, 0x3AU, 0x00U, 0x01U, 0x20U, - 0x01U, 0x41U, 0x02U, 0x6AU, 0x21U, 0x03U, 0x20U, 0x02U, 0x04U, 0x7FU, 0x20U, - 0x01U, 0x41U, 0x01U, 0x3AU, 0x00U, 0x06U, 0x20U, 0x01U, 0x41U, 0x22U, 0x36U, - 0x00U, 0x02U, 0x20U, 0x02U, 0x41U, 0x7FU, 0x46U, 0x04U, 0x7FU, 0x20U, 0x01U, + 0x02U, 0x04U, 0x7FU, 0x20U, 0x01U, 0x41U, 0x01U, 0x3AU, 0x00U, 0x06U, 0x20U, + 0x01U, 0x41U, 0x22U, 0x36U, 0x00U, 0x02U, 0x20U, 0x02U, 0x41U, 0x7FU, 0x47U, + 0x04U, 0x7FU, 0x20U, 0x01U, 0x41U, 0xD0U, 0x3EU, 0x3BU, 0x00U, 0x07U, 0x20U, + 0x01U, 0x20U, 0x02U, 0x29U, 0x03U, 0x00U, 0x37U, 0x03U, 0x09U, 0x20U, 0x01U, + 0x20U, 0x02U, 0x29U, 0x03U, 0x08U, 0x37U, 0x03U, 0x11U, 0x20U, 0x01U, 0x20U, + 0x02U, 0x29U, 0x03U, 0x10U, 0x37U, 0x03U, 0x19U, 0x20U, 0x01U, 0x20U, 0x02U, + 0x29U, 0x03U, 0x18U, 0x37U, 0x03U, 0x21U, 0x20U, 0x01U, 0x41U, 0x29U, 0x6AU, + 0x05U, 0x20U, 0x01U, 0x41U, 0xFBU, 0x00U, 0x3BU, 0x00U, 0x07U, 0x20U, 0x01U, + 0x41U, 0x09U, 0x6AU, 0x0BU, 0x05U, 0x20U, 0x01U, 0x41U, 0x02U, 0x6AU, 0x0BU, + 0x22U, 0x01U, 0x41U, 0xE1U, 0x01U, 0x3AU, 0x00U, 0x00U, 0x20U, 0x00U, 0x28U, + 0x02U, 0x28U, 0x21U, 0x02U, 0x20U, 0x01U, 0x41U, 0xEEU, 0x01U, 0x3AU, 0x00U, + 0x01U, 0x20U, 0x02U, 0x04U, 0x7FU, 0x20U, 0x01U, 0x41U, 0x01U, 0x3AU, 0x00U, + 0x06U, 0x20U, 0x01U, 0x41U, 0x22U, 0x36U, 0x00U, 0x02U, 0x20U, 0x02U, 0x41U, + 0x7FU, 0x47U, 0x04U, 0x7FU, 0x20U, 0x01U, 0x41U, 0xD0U, 0x3EU, 0x3BU, 0x00U, + 0x07U, 0x20U, 0x01U, 0x20U, 0x02U, 0x29U, 0x03U, 0x00U, 0x37U, 0x03U, 0x09U, + 0x20U, 0x01U, 0x20U, 0x02U, 0x29U, 0x03U, 0x08U, 0x37U, 0x03U, 0x11U, 0x20U, + 0x01U, 0x20U, 0x02U, 0x29U, 0x03U, 0x10U, 0x37U, 0x03U, 0x19U, 0x20U, 0x01U, + 0x20U, 0x02U, 0x29U, 0x03U, 0x18U, 0x37U, 0x03U, 0x21U, 0x20U, 0x01U, 0x41U, + 0x29U, 0x6AU, 0x05U, 0x20U, 0x01U, 0x41U, 0xFBU, 0x00U, 0x3BU, 0x00U, 0x07U, + 0x20U, 0x01U, 0x41U, 0x09U, 0x6AU, 0x0BU, 0x05U, 0x20U, 0x01U, 0x41U, 0x02U, + 0x6AU, 0x0BU, 0x22U, 0x01U, 0x41U, 0xE1U, 0x01U, 0x3AU, 0x00U, 0x00U, 0x20U, + 0x00U, 0x28U, 0x02U, 0x2CU, 0x21U, 0x02U, 0x20U, 0x01U, 0x41U, 0xEEU, 0x01U, + 0x3AU, 0x00U, 0x01U, 0x20U, 0x02U, 0x04U, 0x7FU, 0x20U, 0x01U, 0x41U, 0x01U, + 0x3AU, 0x00U, 0x06U, 0x20U, 0x01U, 0x41U, 0x22U, 0x36U, 0x00U, 0x02U, 0x20U, + 0x02U, 0x41U, 0x7FU, 0x47U, 0x04U, 0x7FU, 0x20U, 0x01U, 0x41U, 0xD0U, 0x3EU, + 0x3BU, 0x00U, 0x07U, 0x20U, 0x01U, 0x20U, 0x02U, 0x29U, 0x03U, 0x00U, 0x37U, + 0x03U, 0x09U, 0x20U, 0x01U, 0x20U, 0x02U, 0x29U, 0x03U, 0x08U, 0x37U, 0x03U, + 0x11U, 0x20U, 0x01U, 0x20U, 0x02U, 0x29U, 0x03U, 0x10U, 0x37U, 0x03U, 0x19U, + 0x20U, 0x01U, 0x20U, 0x02U, 0x29U, 0x03U, 0x18U, 0x37U, 0x03U, 0x21U, 0x20U, + 0x01U, 0x41U, 0x29U, 0x6AU, 0x05U, 0x20U, 0x01U, 0x41U, 0xFBU, 0x00U, 0x3BU, + 0x00U, 0x07U, 0x20U, 0x01U, 0x41U, 0x09U, 0x6AU, 0x0BU, 0x05U, 0x20U, 0x01U, + 0x41U, 0x02U, 0x6AU, 0x0BU, 0x22U, 0x01U, 0x41U, 0xE1U, 0x01U, 0x3AU, 0x00U, + 0x00U, 0x20U, 0x00U, 0x28U, 0x02U, 0x30U, 0x21U, 0x02U, 0x20U, 0x01U, 0x41U, + 0xEEU, 0x01U, 0x3AU, 0x00U, 0x01U, 0x20U, 0x02U, 0x04U, 0x7FU, 0x20U, 0x01U, + 0x41U, 0x01U, 0x3AU, 0x00U, 0x06U, 0x20U, 0x01U, 0x41U, 0x22U, 0x36U, 0x00U, + 0x02U, 0x20U, 0x02U, 0x41U, 0x7FU, 0x47U, 0x04U, 0x7FU, 0x20U, 0x01U, 0x41U, + 0xD0U, 0x3EU, 0x3BU, 0x00U, 0x07U, 0x20U, 0x01U, 0x20U, 0x02U, 0x29U, 0x03U, + 0x00U, 0x37U, 0x03U, 0x09U, 0x20U, 0x01U, 0x20U, 0x02U, 0x29U, 0x03U, 0x08U, + 0x37U, 0x03U, 0x11U, 0x20U, 0x01U, 0x20U, 0x02U, 0x29U, 0x03U, 0x10U, 0x37U, + 0x03U, 0x19U, 0x20U, 0x01U, 0x20U, 0x02U, 0x29U, 0x03U, 0x18U, 0x37U, 0x03U, + 0x21U, 0x20U, 0x01U, 0x41U, 0x29U, 0x6AU, 0x05U, 0x20U, 0x01U, 0x41U, 0xFBU, + 0x00U, 0x3BU, 0x00U, 0x07U, 0x20U, 0x01U, 0x41U, 0x09U, 0x6AU, 0x0BU, 0x05U, + 0x20U, 0x01U, 0x41U, 0x02U, 0x6AU, 0x0BU, 0x22U, 0x01U, 0x41U, 0xE1U, 0x01U, + 0x3AU, 0x00U, 0x00U, 0x20U, 0x00U, 0x28U, 0x02U, 0x34U, 0x21U, 0x02U, 0x20U, + 0x01U, 0x41U, 0xEEU, 0x01U, 0x3AU, 0x00U, 0x01U, 0x20U, 0x02U, 0x04U, 0x7FU, + 0x20U, 0x01U, 0x41U, 0x01U, 0x3AU, 0x00U, 0x06U, 0x20U, 0x01U, 0x41U, 0x22U, + 0x36U, 0x00U, 0x02U, 0x20U, 0x02U, 0x41U, 0x7FU, 0x47U, 0x04U, 0x7FU, 0x20U, + 0x01U, 0x41U, 0xD0U, 0x3EU, 0x3BU, 0x00U, 0x07U, 0x20U, 0x01U, 0x20U, 0x02U, + 0x29U, 0x03U, 0x00U, 0x37U, 0x03U, 0x09U, 0x20U, 0x01U, 0x20U, 0x02U, 0x29U, + 0x03U, 0x08U, 0x37U, 0x03U, 0x11U, 0x20U, 0x01U, 0x20U, 0x02U, 0x29U, 0x03U, + 0x10U, 0x37U, 0x03U, 0x19U, 0x20U, 0x01U, 0x20U, 0x02U, 0x29U, 0x03U, 0x18U, + 0x37U, 0x03U, 0x21U, 0x20U, 0x01U, 0x41U, 0x29U, 0x6AU, 0x05U, 0x20U, 0x01U, 0x41U, 0xFBU, 0x00U, 0x3BU, 0x00U, 0x07U, 0x20U, 0x01U, 0x41U, 0x09U, 0x6AU, - 0x05U, 0x20U, 0x01U, 0x41U, 0xD0U, 0x3EU, 0x3BU, 0x00U, 0x07U, 0x20U, 0x01U, - 0x20U, 0x02U, 0x29U, 0x03U, 0x00U, 0x37U, 0x03U, 0x09U, 0x20U, 0x01U, 0x41U, - 0x11U, 0x6AU, 0x20U, 0x02U, 0x29U, 0x03U, 0x08U, 0x37U, 0x03U, 0x00U, 0x20U, - 0x01U, 0x41U, 0x19U, 0x6AU, 0x20U, 0x02U, 0x29U, 0x03U, 0x10U, 0x37U, 0x03U, - 0x00U, 0x20U, 0x01U, 0x41U, 0x21U, 0x6AU, 0x20U, 0x02U, 0x29U, 0x03U, 0x18U, - 0x37U, 0x03U, 0x00U, 0x20U, 0x01U, 0x41U, 0x29U, 0x6AU, 0x0BU, 0x05U, 0x20U, - 0x03U, 0x0BU, 0x22U, 0x01U, 0x41U, 0xE1U, 0x01U, 0x3AU, 0x00U, 0x00U, 0x20U, - 0x00U, 0x28U, 0x02U, 0x44U, 0x21U, 0x02U, 0x20U, 0x01U, 0x41U, 0xEEU, 0x01U, - 0x3AU, 0x00U, 0x01U, 0x20U, 0x01U, 0x41U, 0x02U, 0x6AU, 0x21U, 0x03U, 0x20U, - 0x02U, 0x04U, 0x40U, 0x20U, 0x01U, 0x41U, 0x01U, 0x3AU, 0x00U, 0x06U, 0x20U, - 0x01U, 0x41U, 0x22U, 0x36U, 0x00U, 0x02U, 0x20U, 0x02U, 0x41U, 0x7FU, 0x46U, - 0x04U, 0x7FU, 0x20U, 0x01U, 0x41U, 0xFBU, 0x00U, 0x3BU, 0x00U, 0x07U, 0x20U, - 0x01U, 0x41U, 0x09U, 0x6AU, 0x05U, 0x20U, 0x01U, 0x41U, 0xD0U, 0x3EU, 0x3BU, + 0x0BU, 0x05U, 0x20U, 0x01U, 0x41U, 0x02U, 0x6AU, 0x0BU, 0x22U, 0x01U, 0x41U, + 0xE1U, 0x01U, 0x3AU, 0x00U, 0x00U, 0x20U, 0x00U, 0x28U, 0x02U, 0x38U, 0x21U, + 0x02U, 0x20U, 0x01U, 0x41U, 0xEEU, 0x01U, 0x3AU, 0x00U, 0x01U, 0x20U, 0x02U, + 0x04U, 0x7FU, 0x20U, 0x01U, 0x41U, 0x01U, 0x3AU, 0x00U, 0x06U, 0x20U, 0x01U, + 0x41U, 0x22U, 0x36U, 0x00U, 0x02U, 0x20U, 0x02U, 0x41U, 0x7FU, 0x47U, 0x04U, + 0x7FU, 0x20U, 0x01U, 0x41U, 0xD0U, 0x3EU, 0x3BU, 0x00U, 0x07U, 0x20U, 0x01U, + 0x20U, 0x02U, 0x29U, 0x03U, 0x00U, 0x37U, 0x03U, 0x09U, 0x20U, 0x01U, 0x20U, + 0x02U, 0x29U, 0x03U, 0x08U, 0x37U, 0x03U, 0x11U, 0x20U, 0x01U, 0x20U, 0x02U, + 0x29U, 0x03U, 0x10U, 0x37U, 0x03U, 0x19U, 0x20U, 0x01U, 0x20U, 0x02U, 0x29U, + 0x03U, 0x18U, 0x37U, 0x03U, 0x21U, 0x20U, 0x01U, 0x41U, 0x29U, 0x6AU, 0x05U, + 0x20U, 0x01U, 0x41U, 0xFBU, 0x00U, 0x3BU, 0x00U, 0x07U, 0x20U, 0x01U, 0x41U, + 0x09U, 0x6AU, 0x0BU, 0x05U, 0x20U, 0x01U, 0x41U, 0x02U, 0x6AU, 0x0BU, 0x22U, + 0x01U, 0x41U, 0xE1U, 0x01U, 0x3AU, 0x00U, 0x00U, 0x20U, 0x00U, 0x28U, 0x02U, + 0x3CU, 0x21U, 0x02U, 0x20U, 0x01U, 0x41U, 0xEEU, 0x01U, 0x3AU, 0x00U, 0x01U, + 0x20U, 0x02U, 0x04U, 0x7FU, 0x20U, 0x01U, 0x41U, 0x01U, 0x3AU, 0x00U, 0x06U, + 0x20U, 0x01U, 0x41U, 0x22U, 0x36U, 0x00U, 0x02U, 0x20U, 0x02U, 0x41U, 0x7FU, + 0x47U, 0x04U, 0x7FU, 0x20U, 0x01U, 0x41U, 0xD0U, 0x3EU, 0x3BU, 0x00U, 0x07U, + 0x20U, 0x01U, 0x20U, 0x02U, 0x29U, 0x03U, 0x00U, 0x37U, 0x03U, 0x09U, 0x20U, + 0x01U, 0x20U, 0x02U, 0x29U, 0x03U, 0x08U, 0x37U, 0x03U, 0x11U, 0x20U, 0x01U, + 0x20U, 0x02U, 0x29U, 0x03U, 0x10U, 0x37U, 0x03U, 0x19U, 0x20U, 0x01U, 0x20U, + 0x02U, 0x29U, 0x03U, 0x18U, 0x37U, 0x03U, 0x21U, 0x20U, 0x01U, 0x41U, 0x29U, + 0x6AU, 0x05U, 0x20U, 0x01U, 0x41U, 0xFBU, 0x00U, 0x3BU, 0x00U, 0x07U, 0x20U, + 0x01U, 0x41U, 0x09U, 0x6AU, 0x0BU, 0x05U, 0x20U, 0x01U, 0x41U, 0x02U, 0x6AU, + 0x0BU, 0x22U, 0x01U, 0x41U, 0xE1U, 0x01U, 0x3AU, 0x00U, 0x00U, 0x20U, 0x00U, + 0x28U, 0x02U, 0x40U, 0x21U, 0x02U, 0x20U, 0x01U, 0x41U, 0xEEU, 0x01U, 0x3AU, + 0x00U, 0x01U, 0x20U, 0x02U, 0x04U, 0x7FU, 0x20U, 0x01U, 0x41U, 0x01U, 0x3AU, + 0x00U, 0x06U, 0x20U, 0x01U, 0x41U, 0x22U, 0x36U, 0x00U, 0x02U, 0x20U, 0x02U, + 0x41U, 0x7FU, 0x47U, 0x04U, 0x7FU, 0x20U, 0x01U, 0x41U, 0xD0U, 0x3EU, 0x3BU, 0x00U, 0x07U, 0x20U, 0x01U, 0x20U, 0x02U, 0x29U, 0x03U, 0x00U, 0x37U, 0x03U, - 0x09U, 0x20U, 0x01U, 0x41U, 0x11U, 0x6AU, 0x20U, 0x02U, 0x29U, 0x03U, 0x08U, - 0x37U, 0x03U, 0x00U, 0x20U, 0x01U, 0x41U, 0x19U, 0x6AU, 0x20U, 0x02U, 0x29U, - 0x03U, 0x10U, 0x37U, 0x03U, 0x00U, 0x20U, 0x01U, 0x41U, 0x21U, 0x6AU, 0x20U, - 0x02U, 0x29U, 0x03U, 0x18U, 0x37U, 0x03U, 0x00U, 0x20U, 0x01U, 0x41U, 0x29U, - 0x6AU, 0x0BU, 0x21U, 0x03U, 0x0BU, 0x20U, 0x03U, 0x41U, 0xE1U, 0xE3U, 0x03U, - 0x3BU, 0x00U, 0x00U, 0x20U, 0x00U, 0x20U, 0x00U, 0x41U, 0x80U, 0x01U, 0x6AU, - 0x22U, 0x01U, 0x20U, 0x03U, 0x20U, 0x00U, 0x6BU, 0x41U, 0xFEU, 0x00U, 0x6BU, - 0x22U, 0x03U, 0x10U, 0x0FU, 0x22U, 0x0AU, 0x3CU, 0x00U, 0xA1U, 0x01U, 0x20U, - 0x00U, 0x41U, 0xE8U, 0x00U, 0x3AU, 0x00U, 0x99U, 0x01U, 0x20U, 0x00U, 0x20U, - 0x0AU, 0x42U, 0x08U, 0x88U, 0x3CU, 0x00U, 0xA0U, 0x01U, 0x20U, 0x00U, 0x20U, - 0x0AU, 0x42U, 0x10U, 0x88U, 0x3CU, 0x00U, 0x9FU, 0x01U, 0x20U, 0x00U, 0x20U, - 0x0AU, 0x42U, 0x18U, 0x88U, 0x3CU, 0x00U, 0x9EU, 0x01U, 0x20U, 0x00U, 0x20U, - 0x0AU, 0x42U, 0x20U, 0x88U, 0x3CU, 0x00U, 0x9DU, 0x01U, 0x20U, 0x00U, 0x20U, - 0x0AU, 0x42U, 0x28U, 0x88U, 0x3CU, 0x00U, 0x9CU, 0x01U, 0x20U, 0x00U, 0x20U, - 0x0AU, 0x42U, 0x30U, 0x88U, 0x3CU, 0x00U, 0x9BU, 0x01U, 0x20U, 0x00U, 0x20U, - 0x0AU, 0x42U, 0x38U, 0x88U, 0xA7U, 0x41U, 0x3FU, 0x71U, 0x41U, 0xC0U, 0x00U, - 0x72U, 0x3AU, 0x00U, 0x9AU, 0x01U, 0x41U, 0xFDU, 0x08U, 0x41U, 0x0BU, 0x20U, - 0x01U, 0x20U, 0x03U, 0x41U, 0x01U, 0x10U, 0x08U, 0x1AU, 0x41U, 0x9EU, 0x08U, - 0x41U, 0x0BU, 0x20U, 0x00U, 0x41U, 0x20U, 0x20U, 0x01U, 0x20U, 0x03U, 0x10U, - 0x10U, 0x22U, 0x0AU, 0x10U, 0x03U, 0x1AU, 0x20U, 0x0AU, 0x42U, 0x20U, 0x52U, - 0x04U, 0x40U, 0x41U, 0xFFU, 0x10U, 0x41U, 0x2FU, 0x42U, 0xA7U, 0x04U, 0x10U, - 0x0BU, 0x1AU, 0x0BU, 0x41U, 0x8AU, 0x09U, 0x41U, 0x0FU, 0x20U, 0x00U, 0x41U, - 0x20U, 0x41U, 0x01U, 0x10U, 0x08U, 0x1AU, 0x41U, 0xE8U, 0x13U, 0x41U, 0x1BU, - 0x42U, 0xAAU, 0x04U, 0x10U, 0x05U, 0x1AU, 0x0BU, 0x20U, 0x00U, 0x41U, 0x80U, - 0x01U, 0x6AU, 0x41U, 0x0CU, 0x72U, 0x22U, 0x05U, 0x41U, 0x14U, 0x20U, 0x00U, - 0x41U, 0xEDU, 0x09U, 0x6AU, 0x41U, 0x01U, 0x10U, 0x09U, 0x22U, 0x0AU, 0x42U, - 0x14U, 0x51U, 0x04U, 0x40U, 0x41U, 0x9DU, 0x0CU, 0x41U, 0x14U, 0x20U, 0x00U, - 0x41U, 0x80U, 0x01U, 0x6AU, 0x41U, 0x20U, 0x41U, 0x01U, 0x10U, 0x08U, 0x1AU, - 0x0BU, 0x20U, 0x00U, 0x41U, 0xB0U, 0x09U, 0x6AU, 0x41U, 0x0CU, 0x72U, 0x21U, - 0x02U, 0x20U, 0x00U, 0x29U, 0x03U, 0x8CU, 0x01U, 0x20U, 0x00U, 0x29U, 0x03U, - 0xBCU, 0x09U, 0x51U, 0x04U, 0x40U, 0x02U, 0x40U, 0x20U, 0x00U, 0x28U, 0x02U, - 0x9CU, 0x01U, 0x20U, 0x00U, 0x28U, 0x02U, 0xCCU, 0x09U, 0x47U, 0x20U, 0x00U, - 0x29U, 0x03U, 0x94U, 0x01U, 0x20U, 0x00U, 0x29U, 0x03U, 0xC4U, 0x09U, 0x52U, - 0x72U, 0x0DU, 0x00U, 0x41U, 0xD8U, 0x0EU, 0x41U, 0xCDU, 0x00U, 0x42U, 0xB9U, - 0x04U, 0x10U, 0x05U, 0x1AU, 0x0BU, 0x0BU, 0x41U, 0x00U, 0x41U, 0x00U, 0x20U, - 0x02U, 0x41U, 0x14U, 0x10U, 0x09U, 0x22U, 0x0CU, 0x42U, 0x3FU, 0x88U, 0x50U, - 0x21U, 0x03U, 0x20U, 0x0CU, 0x42U, 0x00U, 0x59U, 0x04U, 0x40U, 0x41U, 0xFDU, - 0x0CU, 0x41U, 0x30U, 0x41U, 0x00U, 0x41U, 0x00U, 0x41U, 0x00U, 0x10U, 0x08U, - 0x1AU, 0x0BU, 0x20U, 0x03U, 0x20U, 0x0AU, 0x42U, 0x14U, 0x52U, 0x22U, 0x04U, - 0x41U, 0x02U, 0x74U, 0x41U, 0x02U, 0x41U, 0x00U, 0x20U, 0x06U, 0x1BU, 0x72U, - 0x72U, 0x22U, 0x01U, 0xADU, 0x21U, 0x0EU, 0x20U, 0x01U, 0x41U, 0x03U, 0x71U, - 0x41U, 0x03U, 0x46U, 0x04U, 0x40U, 0x41U, 0x83U, 0x14U, 0x41U, 0x1AU, 0x42U, - 0xC5U, 0x04U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x41U, 0xD2U, 0x08U, 0x41U, 0x02U, - 0x20U, 0x0EU, 0x10U, 0x03U, 0x1AU, 0x41U, 0xCEU, 0x0AU, 0x41U, 0x02U, 0x20U, - 0x04U, 0xADU, 0x10U, 0x03U, 0x1AU, 0x41U, 0xBAU, 0x0AU, 0x41U, 0x02U, 0x20U, - 0x0DU, 0x10U, 0x03U, 0x1AU, 0x41U, 0xCAU, 0x0AU, 0x41U, 0x02U, 0x20U, 0x03U, - 0xADU, 0x10U, 0x03U, 0x1AU, 0x41U, 0x8DU, 0x08U, 0x41U, 0x10U, 0x20U, 0x0AU, - 0x42U, 0x14U, 0x51U, 0xADU, 0x10U, 0x03U, 0x1AU, 0x41U, 0xEDU, 0x08U, 0x41U, - 0x0FU, 0x20U, 0x0DU, 0x10U, 0x03U, 0x1AU, 0x41U, 0x80U, 0x08U, 0x41U, 0x0CU, - 0x42U, 0x7FU, 0x20U, 0x01U, 0x41U, 0x04U, 0x46U, 0xADU, 0x20U, 0x01U, 0x41U, - 0x01U, 0x6BU, 0x41U, 0x02U, 0x49U, 0x1BU, 0x20U, 0x0BU, 0x7CU, 0x22U, 0x0BU, - 0x10U, 0x03U, 0x1AU, 0x20U, 0x0BU, 0x42U, 0x01U, 0x57U, 0x04U, 0x40U, 0x41U, - 0x83U, 0x14U, 0x41U, 0x1AU, 0x42U, 0xE7U, 0x04U, 0x10U, 0x0BU, 0x1AU, 0x0BU, - 0x20U, 0x00U, 0x20U, 0x0BU, 0x3CU, 0x00U, 0x20U, 0x20U, 0x00U, 0x41U, 0x20U, - 0x6AU, 0x41U, 0x01U, 0x41U, 0xD5U, 0x0AU, 0x41U, 0x02U, 0x10U, 0x0CU, 0x42U, - 0x01U, 0x52U, 0x04U, 0x40U, 0x41U, 0x83U, 0x14U, 0x41U, 0x1AU, 0x42U, 0xEAU, - 0x04U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x20U, 0x0CU, 0x42U, 0x00U, 0x59U, 0x04U, - 0x40U, 0x02U, 0x40U, 0x20U, 0x00U, 0x20U, 0x0CU, 0x3CU, 0x00U, 0x20U, 0x41U, - 0x00U, 0x41U, 0x00U, 0x20U, 0x00U, 0x41U, 0x20U, 0x6AU, 0x41U, 0x01U, 0x10U, - 0x0CU, 0x50U, 0x45U, 0x04U, 0x40U, 0x41U, 0x83U, 0x14U, 0x41U, 0x1AU, 0x42U, - 0xF4U, 0x04U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x41U, 0x00U, 0x41U, 0x00U, 0x20U, - 0x02U, 0x41U, 0x14U, 0x10U, 0x0CU, 0x50U, 0x0DU, 0x00U, 0x41U, 0x83U, 0x14U, - 0x41U, 0x1AU, 0x42U, 0xF7U, 0x04U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x0BU, 0x20U, - 0x0AU, 0x42U, 0x14U, 0x51U, 0x04U, 0x40U, 0x02U, 0x40U, 0x20U, 0x00U, 0x41U, - 0xD6U, 0x00U, 0x3AU, 0x00U, 0x80U, 0x01U, 0x41U, 0x01U, 0x21U, 0x04U, 0x03U, - 0x40U, 0x41U, 0x80U, 0x85U, 0x80U, 0x80U, 0x78U, 0x41U, 0x03U, 0x10U, 0x00U, - 0x1AU, 0x20U, 0x04U, 0x41U, 0x03U, 0x46U, 0x45U, 0x04U, 0x40U, 0x41U, 0x00U, - 0x21U, 0x03U, 0x03U, 0x40U, 0x41U, 0x82U, 0x85U, 0x80U, 0x80U, 0x78U, 0x41U, - 0xC3U, 0x00U, 0x10U, 0x00U, 0x1AU, 0x02U, 0x40U, 0x20U, 0x03U, 0x41U, 0x20U, - 0x46U, 0x0DU, 0x00U, 0x41U, 0xD2U, 0x00U, 0x21U, 0x01U, 0x20U, 0x00U, 0x41U, - 0xD2U, 0x00U, 0x41U, 0xC8U, 0x00U, 0x41U, 0xD3U, 0x00U, 0x20U, 0x03U, 0x41U, - 0x0CU, 0x49U, 0x22U, 0x08U, 0x1BU, 0x20U, 0x03U, 0x41U, 0x02U, 0x49U, 0x1BU, - 0x3AU, 0x00U, 0x81U, 0x01U, 0x02U, 0x40U, 0x02U, 0x40U, 0x02U, 0x40U, 0x20U, - 0x03U, 0x0EU, 0x02U, 0x02U, 0x00U, 0x01U, 0x0BU, 0x41U, 0xC4U, 0x00U, 0x21U, - 0x01U, 0x0CU, 0x01U, 0x0BU, 0x41U, 0x7EU, 0x41U, 0x74U, 0x20U, 0x08U, 0x1BU, - 0x20U, 0x03U, 0x6AU, 0x21U, 0x01U, 0x0BU, 0x20U, 0x00U, 0x20U, 0x04U, 0x3AU, - 0x00U, 0x83U, 0x01U, 0x20U, 0x00U, 0x20U, 0x01U, 0x3AU, 0x00U, 0x82U, 0x01U, - 0x20U, 0x00U, 0x41U, 0x20U, 0x6AU, 0x41U, 0x20U, 0x20U, 0x00U, 0x41U, 0x80U, - 0x01U, 0x6AU, 0x41U, 0x20U, 0x10U, 0x09U, 0x42U, 0x00U, 0x55U, 0x04U, 0x40U, - 0x20U, 0x00U, 0x41U, 0xC3U, 0x00U, 0x3AU, 0x00U, 0x20U, 0x20U, 0x00U, 0x41U, - 0x00U, 0x3AU, 0x00U, 0x50U, 0x20U, 0x00U, 0x20U, 0x04U, 0x3AU, 0x00U, 0x23U, - 0x20U, 0x00U, 0x20U, 0x00U, 0x2FU, 0x00U, 0x81U, 0x01U, 0x3BU, 0x00U, 0x21U, - 0x20U, 0x00U, 0x41U, 0xD0U, 0x00U, 0x6AU, 0x41U, 0x01U, 0x20U, 0x00U, 0x41U, - 0x20U, 0x6AU, 0x41U, 0x20U, 0x10U, 0x09U, 0x42U, 0x01U, 0x51U, 0x04U, 0x40U, - 0x20U, 0x00U, 0x2DU, 0x00U, 0x50U, 0x22U, 0x01U, 0x41U, 0x01U, 0x4DU, 0x04U, - 0x40U, 0x41U, 0x00U, 0x41U, 0x00U, 0x20U, 0x00U, 0x41U, 0x20U, 0x6AU, 0x41U, - 0x20U, 0x10U, 0x0CU, 0x50U, 0x45U, 0x04U, 0x40U, 0x41U, 0x83U, 0x14U, 0x41U, - 0x1AU, 0x42U, 0x9BU, 0x05U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x41U, 0xFFU, 0x09U, - 0x41U, 0x1DU, 0x20U, 0x00U, 0x31U, 0x00U, 0x50U, 0x10U, 0x03U, 0x1AU, 0x05U, - 0x20U, 0x00U, 0x20U, 0x01U, 0x41U, 0x01U, 0x6BU, 0x3AU, 0x00U, 0x50U, 0x20U, - 0x00U, 0x41U, 0xD0U, 0x00U, 0x6AU, 0x41U, 0x01U, 0x20U, 0x00U, 0x41U, 0x20U, - 0x6AU, 0x41U, 0x20U, 0x10U, 0x0CU, 0x42U, 0x01U, 0x52U, 0x04U, 0x40U, 0x41U, - 0x83U, 0x14U, 0x41U, 0x1AU, 0x42U, 0xA1U, 0x05U, 0x10U, 0x0BU, 0x1AU, 0x0BU, - 0x41U, 0xD5U, 0x08U, 0x41U, 0x18U, 0x20U, 0x00U, 0x31U, 0x00U, 0x50U, 0x10U, - 0x03U, 0x1AU, 0x0BU, 0x0BU, 0x41U, 0x00U, 0x41U, 0x00U, 0x20U, 0x00U, 0x41U, - 0x80U, 0x01U, 0x6AU, 0x41U, 0x20U, 0x10U, 0x0CU, 0x50U, 0x45U, 0x04U, 0x40U, - 0x41U, 0x83U, 0x14U, 0x41U, 0x1AU, 0x42U, 0xA7U, 0x05U, 0x10U, 0x0BU, 0x1AU, - 0x0BU, 0x41U, 0xECU, 0x09U, 0x41U, 0x13U, 0x20U, 0x00U, 0x41U, 0x20U, 0x6AU, - 0x41U, 0x20U, 0x41U, 0x01U, 0x10U, 0x08U, 0x1AU, 0x0BU, 0x20U, 0x03U, 0x41U, - 0x01U, 0x6AU, 0x21U, 0x03U, 0x0CU, 0x01U, 0x0BU, 0x0BU, 0x20U, 0x04U, 0x41U, - 0x01U, 0x6AU, 0x21U, 0x04U, 0x0CU, 0x01U, 0x0BU, 0x0BU, 0x41U, 0x00U, 0x41U, - 0x00U, 0x20U, 0x00U, 0x41U, 0xEDU, 0x09U, 0x6AU, 0x41U, 0x01U, 0x10U, 0x0CU, - 0x50U, 0x45U, 0x04U, 0x40U, 0x41U, 0x83U, 0x14U, 0x41U, 0x1AU, 0x42U, 0xAFU, - 0x05U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x41U, 0x00U, 0x41U, 0x00U, 0x20U, 0x05U, - 0x41U, 0x14U, 0x10U, 0x0CU, 0x50U, 0x0DU, 0x00U, 0x41U, 0x83U, 0x14U, 0x41U, - 0x1AU, 0x42U, 0xB2U, 0x05U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x0BU, 0x20U, 0x06U, - 0x45U, 0x04U, 0x40U, 0x02U, 0x40U, 0x20U, 0x02U, 0x41U, 0x14U, 0x20U, 0x00U, - 0x41U, 0xEDU, 0x09U, 0x6AU, 0x41U, 0x01U, 0x10U, 0x0CU, 0x42U, 0x14U, 0x52U, - 0x04U, 0x40U, 0x41U, 0x83U, 0x14U, 0x41U, 0x1AU, 0x42U, 0xB9U, 0x05U, 0x10U, - 0x0BU, 0x1AU, 0x0BU, 0x20U, 0x00U, 0x41U, 0xEDU, 0x09U, 0x6AU, 0x41U, 0x01U, - 0x20U, 0x02U, 0x41U, 0x14U, 0x10U, 0x0CU, 0x42U, 0x01U, 0x51U, 0x0DU, 0x00U, - 0x41U, 0x83U, 0x14U, 0x41U, 0x1AU, 0x42U, 0xBCU, 0x05U, 0x10U, 0x0BU, 0x1AU, - 0x0BU, 0x0BU, 0x41U, 0xC6U, 0x13U, 0x41U, 0x22U, 0x42U, 0xBFU, 0x05U, 0x10U, - 0x05U, 0x1AU, 0x0BU, 0x41U, 0xF9U, 0x0DU, 0x41U, 0x22U, 0x42U, 0xC3U, 0x05U, - 0x10U, 0x0BU, 0x1AU, 0x20U, 0x00U, 0x41U, 0xB0U, 0x0AU, 0x6AU, 0x24U, 0x00U, - 0x20U, 0x0BU, 0x0BU, 0x0BU, 0xCBU, 0x12U, 0x02U, 0x00U, 0x41U, 0x80U, 0x08U, - 0x0BU, 0xA9U, 0x12U, 0x6DU, 0x65U, 0x6DU, 0x62U, 0x65U, 0x72U, 0x5FU, 0x63U, - 0x6FU, 0x75U, 0x6EU, 0x74U, 0x00U, 0x70U, 0x72U, 0x65U, 0x76U, 0x69U, 0x6FU, - 0x75U, 0x73U, 0x5FU, 0x70U, 0x72U, 0x65U, 0x73U, 0x65U, 0x6EU, 0x74U, 0x00U, - 0x65U, 0x6DU, 0x69U, 0x74U, 0x5FU, 0x72U, 0x65U, 0x73U, 0x75U, 0x6CU, 0x74U, - 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, - 0x3AU, 0x20U, 0x45U, 0x6DU, 0x69U, 0x74U, 0x20U, 0x72U, 0x65U, 0x73U, 0x75U, - 0x6CU, 0x74U, 0x00U, 0x41U, 0x63U, 0x74U, 0x69U, 0x6FU, 0x6EU, 0x69U, 0x6EU, - 0x67U, 0x20U, 0x76U, 0x6FU, 0x74U, 0x65U, 0x73U, 0x00U, 0x6FU, 0x70U, 0x00U, - 0x44U, 0x65U, 0x63U, 0x72U, 0x65U, 0x6DU, 0x65U, 0x6EU, 0x74U, 0x20U, 0x76U, - 0x6FU, 0x74U, 0x65U, 0x20U, 0x63U, 0x6FU, 0x75U, 0x6EU, 0x74U, 0x20U, 0x74U, - 0x6FU, 0x00U, 0x74U, 0x6FU, 0x70U, 0x69U, 0x63U, 0x5FU, 0x64U, 0x61U, 0x74U, - 0x61U, 0x5FU, 0x7AU, 0x65U, 0x72U, 0x6FU, 0x00U, 0x45U, 0x6DU, 0x69U, 0x74U, - 0x74U, 0x65U, 0x64U, 0x54U, 0x78U, 0x6EU, 0x00U, 0x6CU, 0x00U, 0x45U, 0x6DU, - 0x69U, 0x74U, 0x74U, 0x65U, 0x64U, 0x54U, 0x78U, 0x6EU, 0x48U, 0x61U, 0x73U, - 0x68U, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, - 0x65U, 0x3AU, 0x20U, 0x4FU, 0x6EU, 0x65U, 0x20U, 0x6FU, 0x72U, 0x20U, 0x6DU, - 0x6FU, 0x72U, 0x65U, 0x20U, 0x69U, 0x6EU, 0x69U, 0x74U, 0x69U, 0x61U, 0x6CU, - 0x20U, 0x6DU, 0x65U, 0x6DU, 0x62U, 0x65U, 0x72U, 0x20U, 0x61U, 0x63U, 0x63U, - 0x6FU, 0x75U, 0x6EU, 0x74U, 0x20U, 0x49U, 0x44U, 0x27U, 0x73U, 0x20U, 0x69U, - 0x73U, 0x20U, 0x6DU, 0x69U, 0x73U, 0x73U, 0x69U, 0x6EU, 0x67U, 0x00U, 0x70U, - 0x72U, 0x65U, 0x76U, 0x69U, 0x6FU, 0x75U, 0x73U, 0x5FU, 0x74U, 0x6FU, 0x70U, - 0x69U, 0x63U, 0x5FU, 0x73U, 0x69U, 0x7AU, 0x65U, 0x00U, 0x56U, 0x6FU, 0x74U, - 0x65U, 0x20U, 0x65U, 0x6EU, 0x74U, 0x72U, 0x79U, 0x20U, 0x64U, 0x65U, 0x6CU, - 0x65U, 0x74U, 0x65U, 0x64U, 0x00U, 0x44U, 0x65U, 0x63U, 0x72U, 0x65U, 0x6DU, - 0x65U, 0x6EU, 0x74U, 0x20U, 0x76U, 0x6FU, 0x74U, 0x65U, 0x20U, 0x63U, 0x6FU, - 0x75U, 0x6EU, 0x74U, 0x20U, 0x64U, 0x65U, 0x6CU, 0x65U, 0x74U, 0x65U, 0x64U, - 0x00U, 0x69U, 0x6DU, 0x63U, 0x00U, 0x74U, 0x6FU, 0x70U, 0x69U, 0x63U, 0x00U, - 0x70U, 0x72U, 0x65U, 0x76U, 0x69U, 0x6FU, 0x75U, 0x73U, 0x5FU, 0x74U, 0x6FU, - 0x70U, 0x69U, 0x63U, 0x5FU, 0x64U, 0x61U, 0x74U, 0x61U, 0x00U, 0x5AU, 0x00U, - 0x56U, 0x00U, 0x54U, 0x00U, 0x49U, 0x52U, 0x52U, 0x00U, 0x44U, 0x42U, 0x47U, - 0x4CU, 0x4EU, 0x00U, 0x4DU, 0x00U, 0x4CU, 0x00U, 0x45U, 0x00U, 0x49U, 0x52U, - 0x44U, 0x00U, 0x49U, 0x4DU, 0x43U, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, - 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x4DU, 0x69U, 0x73U, 0x73U, - 0x69U, 0x6EU, 0x67U, 0x20U, 0x4CU, 0x20U, 0x70U, 0x61U, 0x72U, 0x61U, 0x6DU, - 0x65U, 0x74U, 0x65U, 0x72U, 0x2EU, 0x20U, 0x57U, 0x68U, 0x69U, 0x63U, 0x68U, - 0x20U, 0x6CU, 0x61U, 0x79U, 0x65U, 0x72U, 0x20U, 0x61U, 0x72U, 0x65U, 0x20U, - 0x79U, 0x6FU, 0x75U, 0x20U, 0x76U, 0x6FU, 0x74U, 0x69U, 0x6EU, 0x67U, 0x20U, - 0x66U, 0x6FU, 0x72U, 0x3FU, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, - 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x4CU, 0x32U, 0x73U, 0x20U, 0x63U, - 0x61U, 0x6EU, 0x6EU, 0x6FU, 0x74U, 0x20U, 0x76U, 0x6FU, 0x74U, 0x65U, 0x20U, - 0x6FU, 0x6EU, 0x20U, 0x52U, 0x52U, 0x2FU, 0x52U, 0x44U, 0x20U, 0x61U, 0x74U, - 0x20U, 0x4CU, 0x32U, 0x2CU, 0x20U, 0x64U, 0x69U, 0x64U, 0x20U, 0x79U, 0x6FU, - 0x75U, 0x20U, 0x6DU, 0x65U, 0x61U, 0x6EU, 0x20U, 0x74U, 0x6FU, 0x20U, 0x73U, - 0x65U, 0x74U, 0x20U, 0x4CU, 0x3DU, 0x31U, 0x3FU, 0x00U, 0x74U, 0x6FU, 0x70U, - 0x69U, 0x63U, 0x5FU, 0x64U, 0x61U, 0x74U, 0x61U, 0x5FU, 0x72U, 0x61U, 0x77U, - 0x3AU, 0x00U, 0x4DU, 0x65U, 0x6DU, 0x62U, 0x65U, 0x72U, 0x3AU, 0x00U, 0x74U, - 0x6FU, 0x70U, 0x69U, 0x63U, 0x5FU, 0x70U, 0x61U, 0x64U, 0x64U, 0x69U, 0x6EU, - 0x67U, 0x3AU, 0x00U, 0x74U, 0x6FU, 0x70U, 0x69U, 0x63U, 0x5FU, 0x73U, 0x69U, - 0x7AU, 0x65U, 0x3AU, 0x00U, 0x74U, 0x6FU, 0x70U, 0x69U, 0x63U, 0x5FU, 0x64U, - 0x61U, 0x74U, 0x61U, 0x3AU, 0x00U, 0x50U, 0x72U, 0x65U, 0x76U, 0x69U, 0x6FU, - 0x75U, 0x73U, 0x20U, 0x70U, 0x72U, 0x65U, 0x73U, 0x65U, 0x6EU, 0x74U, 0x3DU, - 0x3DU, 0x3AU, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, 0x6EU, - 0x63U, 0x65U, 0x3AU, 0x20U, 0x45U, 0x6DU, 0x69U, 0x74U, 0x74U, 0x69U, 0x6EU, - 0x67U, 0x20U, 0x69U, 0x6EU, 0x76U, 0x6FU, 0x6BU, 0x65U, 0x20U, 0x74U, 0x6FU, - 0x20U, 0x4CU, 0x31U, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, - 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x53U, 0x65U, 0x74U, 0x75U, 0x70U, 0x20U, - 0x63U, 0x6FU, 0x6DU, 0x70U, 0x6CU, 0x65U, 0x74U, 0x65U, 0x64U, 0x20U, 0x73U, - 0x75U, 0x63U, 0x63U, 0x65U, 0x73U, 0x73U, 0x66U, 0x75U, 0x6CU, 0x6CU, 0x79U, - 0x2EU, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, - 0x65U, 0x3AU, 0x20U, 0x4DU, 0x6FU, 0x76U, 0x69U, 0x6EU, 0x67U, 0x20U, 0x65U, - 0x78U, 0x69U, 0x73U, 0x74U, 0x69U, 0x6EU, 0x67U, 0x20U, 0x6DU, 0x65U, 0x6DU, - 0x62U, 0x65U, 0x72U, 0x20U, 0x74U, 0x6FU, 0x20U, 0x6EU, 0x65U, 0x77U, 0x20U, - 0x73U, 0x65U, 0x61U, 0x74U, 0x2EU, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, + 0x09U, 0x20U, 0x01U, 0x20U, 0x02U, 0x29U, 0x03U, 0x08U, 0x37U, 0x03U, 0x11U, + 0x20U, 0x01U, 0x20U, 0x02U, 0x29U, 0x03U, 0x10U, 0x37U, 0x03U, 0x19U, 0x20U, + 0x01U, 0x20U, 0x02U, 0x29U, 0x03U, 0x18U, 0x37U, 0x03U, 0x21U, 0x20U, 0x01U, + 0x41U, 0x29U, 0x6AU, 0x05U, 0x20U, 0x01U, 0x41U, 0xFBU, 0x00U, 0x3BU, 0x00U, + 0x07U, 0x20U, 0x01U, 0x41U, 0x09U, 0x6AU, 0x0BU, 0x05U, 0x20U, 0x01U, 0x41U, + 0x02U, 0x6AU, 0x0BU, 0x22U, 0x01U, 0x41U, 0xE1U, 0x01U, 0x3AU, 0x00U, 0x00U, + 0x20U, 0x00U, 0x28U, 0x02U, 0x44U, 0x21U, 0x02U, 0x20U, 0x01U, 0x41U, 0xEEU, + 0x01U, 0x3AU, 0x00U, 0x01U, 0x20U, 0x02U, 0x04U, 0x7FU, 0x20U, 0x01U, 0x41U, + 0x01U, 0x3AU, 0x00U, 0x06U, 0x20U, 0x01U, 0x41U, 0x22U, 0x36U, 0x00U, 0x02U, + 0x20U, 0x02U, 0x41U, 0x7FU, 0x47U, 0x04U, 0x7FU, 0x20U, 0x01U, 0x41U, 0xD0U, + 0x3EU, 0x3BU, 0x00U, 0x07U, 0x20U, 0x01U, 0x20U, 0x02U, 0x29U, 0x03U, 0x00U, + 0x37U, 0x03U, 0x09U, 0x20U, 0x01U, 0x20U, 0x02U, 0x29U, 0x03U, 0x08U, 0x37U, + 0x03U, 0x11U, 0x20U, 0x01U, 0x20U, 0x02U, 0x29U, 0x03U, 0x10U, 0x37U, 0x03U, + 0x19U, 0x20U, 0x01U, 0x20U, 0x02U, 0x29U, 0x03U, 0x18U, 0x37U, 0x03U, 0x21U, + 0x20U, 0x01U, 0x41U, 0x29U, 0x6AU, 0x05U, 0x20U, 0x01U, 0x41U, 0xFBU, 0x00U, + 0x3BU, 0x00U, 0x07U, 0x20U, 0x01U, 0x41U, 0x09U, 0x6AU, 0x0BU, 0x05U, 0x20U, + 0x01U, 0x41U, 0x02U, 0x6AU, 0x0BU, 0x22U, 0x01U, 0x41U, 0xE1U, 0xE3U, 0x03U, + 0x3BU, 0x00U, 0x00U, 0x20U, 0x01U, 0x20U, 0x00U, 0x41U, 0x80U, 0x01U, 0x6AU, + 0x22U, 0x01U, 0x6BU, 0x41U, 0x02U, 0x6AU, 0x21U, 0x02U, 0x20U, 0x00U, 0x20U, + 0x01U, 0x20U, 0x02U, 0x10U, 0x0FU, 0x22U, 0x0BU, 0x3CU, 0x00U, 0xA1U, 0x01U, + 0x20U, 0x00U, 0x41U, 0xE8U, 0x00U, 0x3AU, 0x00U, 0x99U, 0x01U, 0x20U, 0x00U, + 0x20U, 0x0BU, 0x42U, 0x08U, 0x88U, 0x3CU, 0x00U, 0xA0U, 0x01U, 0x20U, 0x00U, + 0x20U, 0x0BU, 0x42U, 0x10U, 0x88U, 0x3CU, 0x00U, 0x9FU, 0x01U, 0x20U, 0x00U, + 0x20U, 0x0BU, 0x42U, 0x18U, 0x88U, 0x3CU, 0x00U, 0x9EU, 0x01U, 0x20U, 0x00U, + 0x20U, 0x0BU, 0x42U, 0x20U, 0x88U, 0x3CU, 0x00U, 0x9DU, 0x01U, 0x20U, 0x00U, + 0x20U, 0x0BU, 0x42U, 0x28U, 0x88U, 0x3CU, 0x00U, 0x9CU, 0x01U, 0x20U, 0x00U, + 0x20U, 0x0BU, 0x42U, 0x30U, 0x88U, 0x3CU, 0x00U, 0x9BU, 0x01U, 0x20U, 0x00U, + 0x20U, 0x0BU, 0x42U, 0x38U, 0x88U, 0xA7U, 0x41U, 0x3FU, 0x71U, 0x41U, 0xC0U, + 0x00U, 0x72U, 0x3AU, 0x00U, 0x9AU, 0x01U, 0x41U, 0xC5U, 0x17U, 0x41U, 0x0BU, + 0x20U, 0x01U, 0x20U, 0x02U, 0x41U, 0x01U, 0x10U, 0x08U, 0x1AU, 0x41U, 0xD0U, + 0x17U, 0x41U, 0x0BU, 0x20U, 0x00U, 0x41U, 0x20U, 0x20U, 0x01U, 0x20U, 0x02U, + 0x10U, 0x10U, 0x22U, 0x0BU, 0x10U, 0x03U, 0x1AU, 0x20U, 0x0BU, 0x42U, 0x20U, + 0x52U, 0x04U, 0x40U, 0x41U, 0xDCU, 0x17U, 0x41U, 0x2FU, 0x42U, 0xA7U, 0x04U, + 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x41U, 0x8BU, 0x18U, 0x41U, 0x0FU, 0x20U, 0x00U, + 0x41U, 0x20U, 0x41U, 0x01U, 0x10U, 0x08U, 0x1AU, 0x41U, 0x9AU, 0x18U, 0x41U, + 0x1BU, 0x42U, 0xAAU, 0x04U, 0x10U, 0x05U, 0x1AU, 0x0BU, 0x20U, 0x00U, 0x41U, + 0x80U, 0x01U, 0x6AU, 0x41U, 0x0CU, 0x72U, 0x22U, 0x08U, 0x41U, 0x14U, 0x20U, + 0x00U, 0x41U, 0xEDU, 0x09U, 0x6AU, 0x41U, 0x01U, 0x10U, 0x09U, 0x22U, 0x0BU, + 0x42U, 0x14U, 0x51U, 0x04U, 0x40U, 0x41U, 0xB5U, 0x18U, 0x41U, 0x14U, 0x20U, + 0x00U, 0x41U, 0x80U, 0x01U, 0x6AU, 0x41U, 0x20U, 0x41U, 0x01U, 0x10U, 0x08U, + 0x1AU, 0x0BU, 0x20U, 0x00U, 0x41U, 0xB0U, 0x09U, 0x6AU, 0x41U, 0x0CU, 0x72U, + 0x21U, 0x04U, 0x20U, 0x00U, 0x29U, 0x03U, 0x8CU, 0x01U, 0x20U, 0x00U, 0x29U, + 0x03U, 0xBCU, 0x09U, 0x51U, 0x04U, 0x40U, 0x02U, 0x40U, 0x20U, 0x00U, 0x28U, + 0x02U, 0x9CU, 0x01U, 0x20U, 0x00U, 0x28U, 0x02U, 0xCCU, 0x09U, 0x47U, 0x20U, + 0x00U, 0x29U, 0x03U, 0x94U, 0x01U, 0x20U, 0x00U, 0x29U, 0x03U, 0xC4U, 0x09U, + 0x52U, 0x72U, 0x0DU, 0x00U, 0x41U, 0xC9U, 0x18U, 0x41U, 0xCDU, 0x00U, 0x42U, + 0xB9U, 0x04U, 0x10U, 0x05U, 0x1AU, 0x0BU, 0x0BU, 0x41U, 0x00U, 0x41U, 0x00U, + 0x20U, 0x04U, 0x41U, 0x14U, 0x10U, 0x09U, 0x22U, 0x0DU, 0x42U, 0x3FU, 0x88U, + 0xA7U, 0x41U, 0x01U, 0x73U, 0x21U, 0x01U, 0x20U, 0x0DU, 0x42U, 0x00U, 0x59U, + 0x04U, 0x40U, 0x41U, 0x96U, 0x19U, 0x41U, 0x30U, 0x41U, 0x00U, 0x41U, 0x00U, + 0x41U, 0x00U, 0x10U, 0x08U, 0x1AU, 0x0BU, 0x20U, 0x01U, 0x20U, 0x0BU, 0x42U, + 0x14U, 0x52U, 0x22U, 0x03U, 0x41U, 0x02U, 0x74U, 0x20U, 0x07U, 0x41U, 0x01U, + 0x74U, 0x72U, 0x72U, 0x22U, 0x02U, 0xADU, 0x21U, 0x0EU, 0x20U, 0x02U, 0x41U, + 0x03U, 0x6BU, 0x22U, 0x05U, 0x41U, 0x04U, 0x4DU, 0x04U, 0x40U, 0x02U, 0x40U, + 0x02U, 0x40U, 0x20U, 0x05U, 0x41U, 0x01U, 0x6BU, 0x0EU, 0x03U, 0x01U, 0x01U, + 0x01U, 0x00U, 0x0BU, 0x41U, 0xB4U, 0x0AU, 0x41U, 0x1AU, 0x42U, 0xC5U, 0x04U, + 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x0BU, 0x41U, 0xC6U, 0x19U, 0x41U, 0x02U, 0x20U, + 0x0EU, 0x10U, 0x03U, 0x1AU, 0x41U, 0xC9U, 0x19U, 0x41U, 0x02U, 0x20U, 0x03U, + 0xADU, 0x10U, 0x03U, 0x1AU, 0x41U, 0xCBU, 0x19U, 0x41U, 0x02U, 0x20U, 0x0FU, + 0x10U, 0x03U, 0x1AU, 0x41U, 0xCDU, 0x19U, 0x41U, 0x02U, 0x20U, 0x01U, 0xADU, + 0x10U, 0x03U, 0x1AU, 0x02U, 0x40U, 0x20U, 0x02U, 0x41U, 0x01U, 0x6BU, 0x22U, + 0x01U, 0x41U, 0x03U, 0x4DU, 0x04U, 0x40U, 0x02U, 0x40U, 0x02U, 0x40U, 0x20U, + 0x01U, 0x41U, 0x02U, 0x6BU, 0x0EU, 0x02U, 0x03U, 0x00U, 0x01U, 0x0BU, 0x20U, + 0x0CU, 0x42U, 0x01U, 0x7CU, 0x21U, 0x0CU, 0x0CU, 0x02U, 0x0BU, 0x20U, 0x0CU, + 0x42U, 0x01U, 0x7DU, 0x21U, 0x0CU, 0x0BU, 0x0BU, 0x41U, 0xCFU, 0x19U, 0x41U, + 0x10U, 0x20U, 0x0BU, 0x42U, 0x14U, 0x51U, 0xADU, 0x10U, 0x03U, 0x1AU, 0x41U, + 0xB5U, 0x13U, 0x41U, 0x0FU, 0x20U, 0x0FU, 0x10U, 0x03U, 0x1AU, 0x41U, 0xCEU, + 0x0AU, 0x41U, 0x0CU, 0x20U, 0x0CU, 0x10U, 0x03U, 0x1AU, 0x20U, 0x0CU, 0x42U, + 0x01U, 0x57U, 0x04U, 0x40U, 0x41U, 0xB4U, 0x0AU, 0x41U, 0x1AU, 0x42U, 0xE7U, + 0x04U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x20U, 0x00U, 0x20U, 0x0CU, 0x3CU, 0x00U, + 0x20U, 0x20U, 0x00U, 0x41U, 0x20U, 0x6AU, 0x41U, 0x01U, 0x41U, 0xEFU, 0x09U, + 0x41U, 0x02U, 0x10U, 0x0CU, 0x42U, 0x01U, 0x52U, 0x04U, 0x40U, 0x41U, 0xB4U, + 0x0AU, 0x41U, 0x1AU, 0x42U, 0xEAU, 0x04U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x20U, + 0x0DU, 0x42U, 0x00U, 0x59U, 0x04U, 0x40U, 0x02U, 0x40U, 0x20U, 0x00U, 0x20U, + 0x0DU, 0x3CU, 0x00U, 0x20U, 0x41U, 0x00U, 0x41U, 0x00U, 0x20U, 0x00U, 0x41U, + 0x20U, 0x6AU, 0x41U, 0x01U, 0x10U, 0x0CU, 0x50U, 0x45U, 0x04U, 0x40U, 0x41U, + 0xB4U, 0x0AU, 0x41U, 0x1AU, 0x42U, 0xF4U, 0x04U, 0x10U, 0x0BU, 0x1AU, 0x0BU, + 0x41U, 0x00U, 0x41U, 0x00U, 0x20U, 0x04U, 0x41U, 0x14U, 0x10U, 0x0CU, 0x50U, + 0x0DU, 0x00U, 0x41U, 0xB4U, 0x0AU, 0x41U, 0x1AU, 0x42U, 0xF7U, 0x04U, 0x10U, + 0x0BU, 0x1AU, 0x0BU, 0x0BU, 0x20U, 0x0BU, 0x42U, 0x14U, 0x51U, 0x04U, 0x40U, + 0x02U, 0x40U, 0x20U, 0x00U, 0x41U, 0xD6U, 0x00U, 0x3AU, 0x00U, 0x80U, 0x01U, + 0x20U, 0x00U, 0x41U, 0x38U, 0x6AU, 0x21U, 0x06U, 0x20U, 0x00U, 0x41U, 0x30U, + 0x6AU, 0x21U, 0x09U, 0x41U, 0x01U, 0x21U, 0x03U, 0x03U, 0x40U, 0x41U, 0x80U, + 0x85U, 0x80U, 0x80U, 0x78U, 0x41U, 0x03U, 0x10U, 0x00U, 0x1AU, 0x20U, 0x03U, + 0x41U, 0x03U, 0x46U, 0x45U, 0x04U, 0x40U, 0x41U, 0x00U, 0x21U, 0x01U, 0x03U, + 0x40U, 0x41U, 0x82U, 0x85U, 0x80U, 0x80U, 0x78U, 0x41U, 0xC3U, 0x00U, 0x10U, + 0x00U, 0x1AU, 0x02U, 0x40U, 0x20U, 0x01U, 0x41U, 0x20U, 0x46U, 0x0DU, 0x00U, + 0x41U, 0xD2U, 0x00U, 0x21U, 0x02U, 0x20U, 0x00U, 0x41U, 0xD2U, 0x00U, 0x41U, + 0xC8U, 0x00U, 0x41U, 0xD3U, 0x00U, 0x20U, 0x01U, 0x41U, 0x0CU, 0x49U, 0x22U, + 0x0AU, 0x1BU, 0x20U, 0x01U, 0x41U, 0x02U, 0x49U, 0x1BU, 0x22U, 0x05U, 0x3AU, + 0x00U, 0x81U, 0x01U, 0x02U, 0x40U, 0x20U, 0x01U, 0x41U, 0x01U, 0x4BU, 0x04U, + 0x7FU, 0x41U, 0x7EU, 0x41U, 0x74U, 0x20U, 0x0AU, 0x1BU, 0x20U, 0x01U, 0x6AU, + 0x05U, 0x20U, 0x01U, 0x41U, 0x01U, 0x47U, 0x0DU, 0x01U, 0x41U, 0xC4U, 0x00U, + 0x0BU, 0x21U, 0x02U, 0x0BU, 0x20U, 0x00U, 0x20U, 0x03U, 0x3AU, 0x00U, 0x83U, + 0x01U, 0x20U, 0x00U, 0x20U, 0x02U, 0x3AU, 0x00U, 0x82U, 0x01U, 0x20U, 0x06U, + 0x42U, 0x00U, 0x37U, 0x03U, 0x00U, 0x20U, 0x09U, 0x42U, 0x00U, 0x37U, 0x03U, + 0x00U, 0x20U, 0x00U, 0x42U, 0x00U, 0x37U, 0x03U, 0x28U, 0x20U, 0x00U, 0x42U, + 0x00U, 0x37U, 0x03U, 0x20U, 0x20U, 0x00U, 0x41U, 0x20U, 0x6AU, 0x41U, 0x20U, + 0x41U, 0x20U, 0x41U, 0x14U, 0x41U, 0x08U, 0x20U, 0x05U, 0x41U, 0xD3U, 0x00U, + 0x46U, 0x1BU, 0x20U, 0x05U, 0x41U, 0xC8U, 0x00U, 0x46U, 0x1BU, 0x22U, 0x02U, + 0x6BU, 0x41U, 0xFCU, 0x01U, 0x71U, 0x6AU, 0x20U, 0x02U, 0x20U, 0x00U, 0x41U, + 0x80U, 0x01U, 0x6AU, 0x41U, 0x20U, 0x10U, 0x09U, 0x20U, 0x02U, 0xADU, 0x51U, + 0x04U, 0x40U, 0x20U, 0x00U, 0x41U, 0xC3U, 0x00U, 0x3AU, 0x00U, 0x20U, 0x20U, + 0x00U, 0x41U, 0x00U, 0x3AU, 0x00U, 0x50U, 0x20U, 0x00U, 0x20U, 0x03U, 0x3AU, + 0x00U, 0x23U, 0x20U, 0x00U, 0x20U, 0x00U, 0x2FU, 0x00U, 0x81U, 0x01U, 0x3BU, + 0x00U, 0x21U, 0x20U, 0x00U, 0x41U, 0xD0U, 0x00U, 0x6AU, 0x41U, 0x01U, 0x20U, + 0x00U, 0x41U, 0x20U, 0x6AU, 0x41U, 0x20U, 0x10U, 0x09U, 0x42U, 0x01U, 0x51U, + 0x04U, 0x40U, 0x20U, 0x00U, 0x2DU, 0x00U, 0x50U, 0x22U, 0x02U, 0x41U, 0x01U, + 0x4BU, 0x04U, 0x40U, 0x20U, 0x00U, 0x20U, 0x02U, 0x41U, 0x01U, 0x6BU, 0x3AU, + 0x00U, 0x50U, 0x20U, 0x00U, 0x41U, 0xD0U, 0x00U, 0x6AU, 0x41U, 0x01U, 0x20U, + 0x00U, 0x41U, 0x20U, 0x6AU, 0x41U, 0x20U, 0x10U, 0x0CU, 0x42U, 0x01U, 0x52U, + 0x04U, 0x40U, 0x41U, 0xB4U, 0x0AU, 0x41U, 0x1AU, 0x42U, 0xA8U, 0x05U, 0x10U, + 0x0BU, 0x1AU, 0x0BU, 0x41U, 0xFDU, 0x19U, 0x41U, 0x18U, 0x20U, 0x00U, 0x31U, + 0x00U, 0x50U, 0x10U, 0x03U, 0x1AU, 0x05U, 0x41U, 0x00U, 0x41U, 0x00U, 0x20U, + 0x00U, 0x41U, 0x20U, 0x6AU, 0x41U, 0x20U, 0x10U, 0x0CU, 0x50U, 0x45U, 0x04U, + 0x40U, 0x41U, 0xB4U, 0x0AU, 0x41U, 0x1AU, 0x42U, 0xA2U, 0x05U, 0x10U, 0x0BU, + 0x1AU, 0x0BU, 0x41U, 0xE0U, 0x19U, 0x41U, 0x1DU, 0x20U, 0x00U, 0x31U, 0x00U, + 0x50U, 0x10U, 0x03U, 0x1AU, 0x0BU, 0x0BU, 0x41U, 0x00U, 0x41U, 0x00U, 0x20U, + 0x00U, 0x41U, 0x80U, 0x01U, 0x6AU, 0x41U, 0x20U, 0x10U, 0x0CU, 0x50U, 0x45U, + 0x04U, 0x40U, 0x41U, 0xB4U, 0x0AU, 0x41U, 0x1AU, 0x42U, 0xAEU, 0x05U, 0x10U, + 0x0BU, 0x1AU, 0x0BU, 0x41U, 0x95U, 0x1AU, 0x41U, 0x13U, 0x20U, 0x00U, 0x41U, + 0x20U, 0x6AU, 0x41U, 0x20U, 0x41U, 0x01U, 0x10U, 0x08U, 0x1AU, 0x0BU, 0x20U, + 0x01U, 0x41U, 0x01U, 0x6AU, 0x21U, 0x01U, 0x0CU, 0x01U, 0x0BU, 0x0BU, 0x20U, + 0x03U, 0x41U, 0x01U, 0x6AU, 0x21U, 0x03U, 0x0CU, 0x01U, 0x0BU, 0x0BU, 0x41U, + 0x00U, 0x41U, 0x00U, 0x20U, 0x00U, 0x41U, 0xEDU, 0x09U, 0x6AU, 0x41U, 0x01U, + 0x10U, 0x0CU, 0x50U, 0x45U, 0x04U, 0x40U, 0x41U, 0xB4U, 0x0AU, 0x41U, 0x1AU, + 0x42U, 0xB6U, 0x05U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x41U, 0x00U, 0x41U, 0x00U, + 0x20U, 0x08U, 0x41U, 0x14U, 0x10U, 0x0CU, 0x50U, 0x0DU, 0x00U, 0x41U, 0xB4U, + 0x0AU, 0x41U, 0x1AU, 0x42U, 0xB9U, 0x05U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x0BU, + 0x20U, 0x07U, 0x45U, 0x04U, 0x40U, 0x02U, 0x40U, 0x20U, 0x04U, 0x41U, 0x14U, + 0x20U, 0x00U, 0x41U, 0xEDU, 0x09U, 0x6AU, 0x41U, 0x01U, 0x10U, 0x0CU, 0x42U, + 0x14U, 0x52U, 0x04U, 0x40U, 0x41U, 0xB4U, 0x0AU, 0x41U, 0x1AU, 0x42U, 0xC0U, + 0x05U, 0x10U, 0x0BU, 0x1AU, 0x0BU, 0x20U, 0x00U, 0x41U, 0xEDU, 0x09U, 0x6AU, + 0x41U, 0x01U, 0x20U, 0x04U, 0x41U, 0x14U, 0x10U, 0x0CU, 0x42U, 0x01U, 0x51U, + 0x0DU, 0x00U, 0x41U, 0xB4U, 0x0AU, 0x41U, 0x1AU, 0x42U, 0xC3U, 0x05U, 0x10U, + 0x0BU, 0x1AU, 0x0BU, 0x0BU, 0x41U, 0xA8U, 0x1AU, 0x41U, 0x22U, 0x42U, 0xC6U, + 0x05U, 0x10U, 0x05U, 0x1AU, 0x0BU, 0x41U, 0xCAU, 0x1AU, 0x41U, 0x22U, 0x42U, + 0xCAU, 0x05U, 0x10U, 0x0BU, 0x1AU, 0x20U, 0x00U, 0x41U, 0xB0U, 0x0AU, 0x6AU, + 0x24U, 0x00U, 0x20U, 0x0CU, 0x0BU, 0x0BU, 0xF9U, 0x12U, 0x02U, 0x00U, 0x41U, + 0x80U, 0x08U, 0x0BU, 0x14U, 0xB5U, 0xF7U, 0x62U, 0x79U, 0x8AU, 0x53U, 0xD5U, + 0x43U, 0xA0U, 0x14U, 0xCAU, 0xF8U, 0xB2U, 0x97U, 0xCFU, 0xF8U, 0xF2U, 0xF9U, + 0x37U, 0xE8U, 0x00U, 0x41U, 0x94U, 0x08U, 0x0BU, 0xD7U, 0x12U, 0x44U, 0x00U, + 0x44U, 0x42U, 0x47U, 0x4CU, 0x4EU, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x50U, 0x61U, 0x73U, 0x73U, 0x69U, 0x6EU, 0x67U, 0x20U, 0x6EU, 0x6FU, 0x6EU, 0x2DU, 0x49U, 0x6EU, 0x76U, 0x6FU, 0x6BU, 0x65U, 0x20U, 0x74U, 0x78U, 0x6EU, 0x2EU, 0x20U, 0x48U, 0x6FU, 0x6FU, 0x6BU, 0x4FU, 0x6EU, 0x20U, 0x73U, 0x68U, 0x6FU, 0x75U, 0x6CU, 0x64U, 0x20U, 0x62U, 0x65U, 0x20U, 0x63U, 0x68U, 0x61U, 0x6EU, 0x67U, 0x65U, 0x64U, 0x20U, 0x74U, 0x6FU, 0x20U, 0x61U, 0x76U, 0x6FU, 0x69U, 0x64U, 0x20U, 0x74U, - 0x68U, 0x69U, 0x73U, 0x2EU, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, - 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x49U, 0x6EU, 0x74U, 0x65U, 0x72U, - 0x6EU, 0x61U, 0x6CU, 0x20U, 0x6CU, 0x6FU, 0x67U, 0x69U, 0x63U, 0x20U, 0x65U, - 0x72U, 0x72U, 0x6FU, 0x72U, 0x2EU, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, - 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x56U, 0x61U, 0x6CU, 0x69U, - 0x64U, 0x20U, 0x54U, 0x4FU, 0x50U, 0x49U, 0x43U, 0x20U, 0x6DU, 0x75U, 0x73U, - 0x74U, 0x20U, 0x62U, 0x65U, 0x20U, 0x73U, 0x70U, 0x65U, 0x63U, 0x69U, 0x66U, - 0x69U, 0x65U, 0x64U, 0x20U, 0x61U, 0x73U, 0x20U, 0x6FU, 0x74U, 0x78U, 0x6EU, - 0x20U, 0x70U, 0x61U, 0x72U, 0x61U, 0x6DU, 0x65U, 0x74U, 0x65U, 0x72U, 0x2EU, + 0x68U, 0x69U, 0x73U, 0x2EU, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x61U, + 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x50U, 0x61U, 0x73U, 0x73U, 0x69U, 0x6EU, + 0x67U, 0x20U, 0x6FU, 0x75U, 0x74U, 0x67U, 0x6FU, 0x69U, 0x6EU, 0x67U, 0x20U, + 0x74U, 0x78U, 0x6EU, 0x2EU, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, + 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x53U, 0x74U, 0x61U, 0x72U, 0x74U, + 0x69U, 0x6EU, 0x67U, 0x20U, 0x67U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, + 0x6EU, 0x63U, 0x65U, 0x20U, 0x6CU, 0x6FU, 0x67U, 0x69U, 0x63U, 0x20U, 0x6FU, + 0x6EU, 0x20U, 0x4CU, 0x31U, 0x20U, 0x74U, 0x61U, 0x62U, 0x6CU, 0x65U, 0x2EU, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, - 0x3AU, 0x20U, 0x41U, 0x63U, 0x74U, 0x69U, 0x6FU, 0x6EU, 0x69U, 0x6EU, 0x67U, - 0x20U, 0x73U, 0x65U, 0x61U, 0x74U, 0x20U, 0x63U, 0x68U, 0x61U, 0x6EU, 0x67U, - 0x65U, 0x2CU, 0x20U, 0x62U, 0x75U, 0x74U, 0x20U, 0x73U, 0x65U, 0x61U, 0x74U, - 0x20U, 0x61U, 0x6CU, 0x72U, 0x65U, 0x61U, 0x64U, 0x79U, 0x20U, 0x63U, 0x6FU, - 0x6EU, 0x74U, 0x61U, 0x69U, 0x6EU, 0x73U, 0x20U, 0x74U, 0x68U, 0x65U, 0x20U, - 0x6EU, 0x65U, 0x77U, 0x20U, 0x6DU, 0x65U, 0x6DU, 0x62U, 0x65U, 0x72U, 0x2EU, - 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, - 0x20U, 0x50U, 0x61U, 0x73U, 0x73U, 0x69U, 0x6EU, 0x67U, 0x20U, 0x6FU, 0x75U, - 0x74U, 0x67U, 0x6FU, 0x69U, 0x6EU, 0x67U, 0x20U, 0x74U, 0x78U, 0x6EU, 0x2EU, - 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, - 0x3AU, 0x20U, 0x56U, 0x6FU, 0x74U, 0x65U, 0x20U, 0x72U, 0x65U, 0x63U, 0x6FU, - 0x72U, 0x64U, 0x2EU, 0x20U, 0x4EU, 0x6FU, 0x74U, 0x20U, 0x79U, 0x65U, 0x74U, - 0x20U, 0x65U, 0x6EU, 0x6FU, 0x75U, 0x67U, 0x68U, 0x20U, 0x76U, 0x6FU, 0x74U, - 0x65U, 0x73U, 0x20U, 0x74U, 0x6FU, 0x20U, 0x61U, 0x63U, 0x74U, 0x69U, 0x6FU, - 0x6EU, 0x2EU, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x61U, 0x6EU, 0x63U, - 0x65U, 0x3AU, 0x20U, 0x48U, 0x6FU, 0x6FU, 0x6BU, 0x20U, 0x48U, 0x61U, 0x73U, - 0x68U, 0x20U, 0x64U, 0x6FU, 0x65U, 0x73U, 0x6EU, 0x27U, 0x74U, 0x20U, 0x65U, - 0x78U, 0x69U, 0x73U, 0x74U, 0x20U, 0x6FU, 0x6EU, 0x20U, 0x6CU, 0x65U, 0x64U, - 0x67U, 0x65U, 0x72U, 0x20U, 0x77U, 0x68U, 0x69U, 0x6CU, 0x65U, 0x20U, 0x61U, - 0x63U, 0x74U, 0x69U, 0x6FU, 0x6EU, 0x69U, 0x6EU, 0x67U, 0x20U, 0x68U, 0x6FU, - 0x6FU, 0x6BU, 0x2EU, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x61U, 0x6EU, - 0x63U, 0x65U, 0x3AU, 0x20U, 0x54U, 0x61U, 0x72U, 0x67U, 0x65U, 0x74U, 0x20U, - 0x68U, 0x6FU, 0x6FU, 0x6BU, 0x20U, 0x69U, 0x73U, 0x20U, 0x61U, 0x6CU, 0x72U, - 0x65U, 0x61U, 0x64U, 0x79U, 0x20U, 0x74U, 0x68U, 0x65U, 0x20U, 0x73U, 0x61U, - 0x6DU, 0x65U, 0x20U, 0x61U, 0x73U, 0x20U, 0x61U, 0x63U, 0x74U, 0x69U, 0x6FU, - 0x6EU, 0x65U, 0x64U, 0x20U, 0x68U, 0x6FU, 0x6FU, 0x6BU, 0x2EU, 0x00U, 0x47U, - 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, - 0x45U, 0x6DU, 0x69U, 0x74U, 0x20U, 0x66U, 0x61U, 0x69U, 0x6CU, 0x65U, 0x64U, - 0x20U, 0x64U, 0x75U, 0x72U, 0x69U, 0x6EU, 0x67U, 0x20U, 0x68U, 0x6FU, 0x6FU, - 0x6BU, 0x20U, 0x61U, 0x63U, 0x74U, 0x69U, 0x6FU, 0x6EU, 0x69U, 0x6EU, 0x67U, - 0x2EU, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, - 0x65U, 0x3AU, 0x20U, 0x53U, 0x75U, 0x63U, 0x63U, 0x65U, 0x73U, 0x73U, 0x66U, - 0x75U, 0x6CU, 0x6CU, 0x79U, 0x20U, 0x65U, 0x6DU, 0x69U, 0x74U, 0x74U, 0x65U, - 0x64U, 0x20U, 0x4CU, 0x31U, 0x20U, 0x76U, 0x6FU, 0x74U, 0x65U, 0x2EU, 0x00U, - 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, - 0x20U, 0x4DU, 0x69U, 0x73U, 0x73U, 0x69U, 0x6EU, 0x67U, 0x20U, 0x6FU, 0x72U, - 0x20U, 0x69U, 0x6EU, 0x63U, 0x6FU, 0x72U, 0x72U, 0x65U, 0x63U, 0x74U, 0x20U, - 0x73U, 0x69U, 0x7AU, 0x65U, 0x20U, 0x6FU, 0x66U, 0x20U, 0x56U, 0x4FU, 0x54U, - 0x45U, 0x20U, 0x64U, 0x61U, 0x74U, 0x61U, 0x20U, 0x66U, 0x6FU, 0x72U, 0x20U, - 0x54U, 0x4FU, 0x50U, 0x49U, 0x43U, 0x20U, 0x74U, 0x79U, 0x70U, 0x65U, 0x2EU, - 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, - 0x3AU, 0x20U, 0x59U, 0x6FU, 0x75U, 0x20U, 0x61U, 0x72U, 0x65U, 0x20U, 0x6EU, - 0x6FU, 0x74U, 0x20U, 0x63U, 0x75U, 0x72U, 0x72U, 0x65U, 0x6EU, 0x74U, 0x6CU, - 0x79U, 0x20U, 0x61U, 0x20U, 0x67U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, - 0x6EU, 0x63U, 0x65U, 0x20U, 0x6DU, 0x65U, 0x6DU, 0x62U, 0x65U, 0x72U, 0x20U, - 0x61U, 0x74U, 0x20U, 0x74U, 0x68U, 0x69U, 0x73U, 0x20U, 0x74U, 0x61U, 0x62U, - 0x6CU, 0x65U, 0x2EU, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, - 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x53U, 0x74U, 0x61U, 0x72U, 0x74U, 0x69U, - 0x6EU, 0x67U, 0x20U, 0x67U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, 0x6EU, - 0x63U, 0x65U, 0x20U, 0x6CU, 0x6FU, 0x67U, 0x69U, 0x63U, 0x20U, 0x6FU, 0x6EU, - 0x20U, 0x4CU, 0x32U, 0x20U, 0x74U, 0x61U, 0x62U, 0x6CU, 0x65U, 0x2EU, 0x00U, - 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, - 0x20U, 0x53U, 0x74U, 0x61U, 0x72U, 0x74U, 0x69U, 0x6EU, 0x67U, 0x20U, 0x67U, - 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, 0x20U, 0x6CU, - 0x6FU, 0x67U, 0x69U, 0x63U, 0x20U, 0x6FU, 0x6EU, 0x20U, 0x4CU, 0x31U, 0x20U, - 0x74U, 0x61U, 0x62U, 0x6CU, 0x65U, 0x2EU, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, - 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x41U, 0x63U, 0x74U, - 0x69U, 0x6FU, 0x6EU, 0x20U, 0x6DU, 0x65U, 0x6DU, 0x62U, 0x65U, 0x72U, 0x20U, - 0x63U, 0x68U, 0x61U, 0x6EU, 0x67U, 0x65U, 0x2EU, 0x00U, 0x47U, 0x6FU, 0x76U, - 0x65U, 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x48U, 0x6FU, - 0x6FU, 0x6BU, 0x20U, 0x61U, 0x63U, 0x74U, 0x69U, 0x6FU, 0x6EU, 0x65U, 0x64U, - 0x2EU, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x3AU, 0x20U, 0x41U, - 0x73U, 0x73U, 0x65U, 0x72U, 0x74U, 0x69U, 0x6FU, 0x6EU, 0x20U, 0x66U, 0x61U, - 0x69U, 0x6CU, 0x65U, 0x64U, 0x2EU, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, - 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x4CU, 0x31U, 0x20U, 0x76U, - 0x6FU, 0x74U, 0x65U, 0x20U, 0x65U, 0x6DU, 0x69U, 0x73U, 0x73U, 0x69U, 0x6FU, - 0x6EU, 0x20U, 0x66U, 0x61U, 0x69U, 0x6CU, 0x65U, 0x64U, 0x2EU, 0x00U, 0x47U, - 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, - 0x59U, 0x6FU, 0x75U, 0x72U, 0x20U, 0x76U, 0x6FU, 0x74U, 0x65U, 0x20U, 0x69U, - 0x73U, 0x20U, 0x61U, 0x6CU, 0x72U, 0x65U, 0x61U, 0x64U, 0x79U, 0x20U, 0x63U, - 0x61U, 0x73U, 0x74U, 0x20U, 0x74U, 0x68U, 0x69U, 0x73U, 0x20U, 0x77U, 0x61U, - 0x79U, 0x20U, 0x66U, 0x6FU, 0x72U, 0x20U, 0x74U, 0x68U, 0x69U, 0x73U, 0x20U, - 0x74U, 0x6FU, 0x70U, 0x69U, 0x63U, 0x2EU, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, - 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x56U, 0x61U, 0x6CU, - 0x69U, 0x64U, 0x20U, 0x73U, 0x65U, 0x61U, 0x74U, 0x20U, 0x74U, 0x6FU, 0x70U, - 0x69U, 0x63U, 0x73U, 0x20U, 0x61U, 0x72U, 0x65U, 0x20U, 0x30U, 0x20U, 0x74U, - 0x68U, 0x72U, 0x6FU, 0x75U, 0x67U, 0x68U, 0x20U, 0x31U, 0x39U, 0x2EU, 0x00U, - 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, - 0x20U, 0x56U, 0x61U, 0x6CU, 0x69U, 0x64U, 0x20U, 0x68U, 0x6FU, 0x6FU, 0x6BU, - 0x20U, 0x74U, 0x6FU, 0x70U, 0x69U, 0x63U, 0x73U, 0x20U, 0x61U, 0x72U, 0x65U, - 0x20U, 0x30U, 0x20U, 0x74U, 0x68U, 0x72U, 0x6FU, 0x75U, 0x67U, 0x68U, 0x20U, - 0x39U, 0x2EU, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, 0x6EU, - 0x63U, 0x65U, 0x3AU, 0x20U, 0x49U, 0x6EU, 0x69U, 0x74U, 0x69U, 0x61U, 0x6CU, - 0x20U, 0x52U, 0x65U, 0x77U, 0x61U, 0x72U, 0x64U, 0x20U, 0x44U, 0x65U, 0x6CU, - 0x61U, 0x79U, 0x20U, 0x6DU, 0x75U, 0x73U, 0x74U, 0x20U, 0x62U, 0x65U, 0x20U, - 0x3EU, 0x20U, 0x30U, 0x2EU, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, - 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x49U, 0x6EU, 0x69U, 0x74U, 0x69U, - 0x61U, 0x6CU, 0x20U, 0x4DU, 0x65U, 0x6DU, 0x62U, 0x65U, 0x72U, 0x20U, 0x43U, - 0x6FU, 0x75U, 0x6EU, 0x74U, 0x20U, 0x6DU, 0x75U, 0x73U, 0x74U, 0x20U, 0x62U, - 0x65U, 0x20U, 0x3EU, 0x20U, 0x30U, 0x2EU, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, - 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x4EU, 0x6FU, 0x74U, - 0x20U, 0x79U, 0x65U, 0x74U, 0x20U, 0x65U, 0x6EU, 0x6FU, 0x75U, 0x67U, 0x68U, - 0x20U, 0x76U, 0x6FU, 0x74U, 0x65U, 0x73U, 0x20U, 0x74U, 0x6FU, 0x20U, 0x61U, - 0x63U, 0x74U, 0x69U, 0x6FU, 0x6EU, 0x20U, 0x4CU, 0x31U, 0x20U, 0x76U, 0x6FU, - 0x74U, 0x65U, 0x2EU, 0x2EU, 0x2EU, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, - 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x56U, 0x61U, 0x6CU, 0x69U, - 0x64U, 0x20U, 0x72U, 0x65U, 0x77U, 0x61U, 0x72U, 0x64U, 0x20U, 0x74U, 0x6FU, - 0x70U, 0x69U, 0x63U, 0x73U, 0x20U, 0x61U, 0x72U, 0x65U, 0x20U, 0x52U, 0x20U, - 0x28U, 0x72U, 0x61U, 0x74U, 0x65U, 0x29U, 0x20U, 0x61U, 0x6EU, 0x64U, 0x20U, - 0x44U, 0x20U, 0x28U, 0x64U, 0x65U, 0x6CU, 0x61U, 0x79U, 0x29U, 0x2EU, 0x00U, - 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, - 0x20U, 0x49U, 0x6EU, 0x69U, 0x74U, 0x69U, 0x61U, 0x6CU, 0x20U, 0x52U, 0x65U, - 0x77U, 0x61U, 0x72U, 0x64U, 0x20U, 0x52U, 0x61U, 0x74U, 0x65U, 0x20U, 0x50U, - 0x61U, 0x72U, 0x61U, 0x6DU, 0x65U, 0x74U, 0x65U, 0x72U, 0x20U, 0x6DU, 0x69U, - 0x73U, 0x73U, 0x69U, 0x6EU, 0x67U, 0x20U, 0x28U, 0x49U, 0x52U, 0x52U, 0x29U, - 0x2EU, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, + 0x3AU, 0x20U, 0x53U, 0x74U, 0x61U, 0x72U, 0x74U, 0x69U, 0x6EU, 0x67U, 0x20U, + 0x67U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, 0x20U, + 0x6CU, 0x6FU, 0x67U, 0x69U, 0x63U, 0x20U, 0x6FU, 0x6EU, 0x20U, 0x4CU, 0x32U, + 0x20U, 0x74U, 0x61U, 0x62U, 0x6CU, 0x65U, 0x2EU, 0x00U, 0x4DU, 0x43U, 0x00U, + 0x49U, 0x4DU, 0x43U, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, + 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x49U, 0x6EU, 0x69U, 0x74U, 0x69U, 0x61U, + 0x6CU, 0x20U, 0x4DU, 0x65U, 0x6DU, 0x62U, 0x65U, 0x72U, 0x20U, 0x43U, 0x6FU, + 0x75U, 0x6EU, 0x74U, 0x20U, 0x50U, 0x61U, 0x72U, 0x61U, 0x6DU, 0x65U, 0x74U, + 0x65U, 0x72U, 0x20U, 0x6DU, 0x69U, 0x73U, 0x73U, 0x69U, 0x6EU, 0x67U, 0x20U, + 0x28U, 0x49U, 0x4DU, 0x43U, 0x29U, 0x2EU, 0x00U, 0x69U, 0x6DU, 0x63U, 0x00U, + 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x3AU, 0x20U, 0x41U, 0x73U, 0x73U, + 0x65U, 0x72U, 0x74U, 0x69U, 0x6FU, 0x6EU, 0x20U, 0x66U, 0x61U, 0x69U, 0x6CU, + 0x65U, 0x64U, 0x2EU, 0x00U, 0x6DU, 0x65U, 0x6DU, 0x62U, 0x65U, 0x72U, 0x5FU, + 0x63U, 0x6FU, 0x75U, 0x6EU, 0x74U, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, + 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x49U, 0x6EU, 0x69U, 0x74U, + 0x69U, 0x61U, 0x6CU, 0x20U, 0x4DU, 0x65U, 0x6DU, 0x62U, 0x65U, 0x72U, 0x20U, + 0x43U, 0x6FU, 0x75U, 0x6EU, 0x74U, 0x20U, 0x6DU, 0x75U, 0x73U, 0x74U, 0x20U, + 0x62U, 0x65U, 0x20U, 0x3EU, 0x20U, 0x30U, 0x2EU, 0x00U, 0x47U, 0x6FU, 0x76U, + 0x65U, 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x49U, 0x6EU, + 0x69U, 0x74U, 0x69U, 0x61U, 0x6CU, 0x20U, 0x4DU, 0x65U, 0x6DU, 0x62U, 0x65U, + 0x72U, 0x20U, 0x43U, 0x6FU, 0x75U, 0x6EU, 0x74U, 0x20U, 0x6DU, 0x75U, 0x73U, + 0x74U, 0x20U, 0x62U, 0x65U, 0x20U, 0x3CU, 0x3DU, 0x20U, 0x53U, 0x65U, 0x61U, + 0x74U, 0x20U, 0x43U, 0x6FU, 0x75U, 0x6EU, 0x74U, 0x20U, 0x28U, 0x32U, 0x30U, + 0x29U, 0x2EU, 0x00U, 0x49U, 0x52U, 0x52U, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, + 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x49U, 0x6EU, 0x69U, + 0x74U, 0x69U, 0x61U, 0x6CU, 0x20U, 0x52U, 0x65U, 0x77U, 0x61U, 0x72U, 0x64U, + 0x20U, 0x52U, 0x61U, 0x74U, 0x65U, 0x20U, 0x50U, 0x61U, 0x72U, 0x61U, 0x6DU, + 0x65U, 0x74U, 0x65U, 0x72U, 0x20U, 0x6DU, 0x69U, 0x73U, 0x73U, 0x69U, 0x6EU, + 0x67U, 0x20U, 0x28U, 0x49U, 0x52U, 0x52U, 0x29U, 0x2EU, 0x00U, 0x49U, 0x52U, + 0x44U, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x49U, 0x6EU, 0x69U, 0x74U, 0x69U, 0x61U, 0x6CU, 0x20U, 0x52U, 0x65U, 0x77U, 0x61U, 0x72U, 0x64U, 0x20U, 0x44U, 0x65U, 0x6CU, 0x61U, 0x79U, 0x20U, 0x50U, 0x61U, 0x72U, 0x61U, 0x6DU, 0x65U, 0x74U, 0x65U, 0x72U, 0x20U, 0x6DU, 0x69U, 0x73U, 0x73U, 0x20U, 0x28U, 0x49U, 0x52U, 0x44U, 0x29U, 0x2EU, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x49U, 0x6EU, 0x69U, 0x74U, 0x69U, 0x61U, 0x6CU, 0x20U, - 0x4DU, 0x65U, 0x6DU, 0x62U, 0x65U, 0x72U, 0x20U, 0x43U, 0x6FU, 0x75U, 0x6EU, - 0x74U, 0x20U, 0x50U, 0x61U, 0x72U, 0x61U, 0x6DU, 0x65U, 0x74U, 0x65U, 0x72U, - 0x20U, 0x6DU, 0x69U, 0x73U, 0x73U, 0x69U, 0x6EU, 0x67U, 0x20U, 0x28U, 0x49U, - 0x4DU, 0x43U, 0x29U, 0x2EU, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, - 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x49U, 0x6EU, 0x69U, 0x74U, 0x69U, - 0x61U, 0x6CU, 0x20U, 0x4DU, 0x65U, 0x6DU, 0x62U, 0x65U, 0x72U, 0x20U, 0x43U, - 0x6FU, 0x75U, 0x6EU, 0x74U, 0x20U, 0x6DU, 0x75U, 0x73U, 0x74U, 0x20U, 0x62U, - 0x65U, 0x20U, 0x3CU, 0x3DU, 0x20U, 0x53U, 0x65U, 0x61U, 0x74U, 0x20U, 0x43U, - 0x6FU, 0x75U, 0x6EU, 0x74U, 0x20U, 0x28U, 0x32U, 0x30U, 0x29U, 0x2EU, 0x00U, - 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, - 0x20U, 0x4CU, 0x61U, 0x79U, 0x65U, 0x72U, 0x20U, 0x70U, 0x61U, 0x72U, 0x61U, - 0x6DU, 0x65U, 0x74U, 0x65U, 0x72U, 0x20U, 0x6DU, 0x75U, 0x73U, 0x74U, 0x20U, - 0x62U, 0x65U, 0x20U, 0x27U, 0x31U, 0x27U, 0x20U, 0x6FU, 0x72U, 0x20U, 0x27U, - 0x32U, 0x27U, 0x2EU, 0x00U, 0x22U, 0x41U, 0x63U, 0x74U, 0x69U, 0x6FU, 0x6EU, - 0x69U, 0x6EU, 0x67U, 0x20U, 0x76U, 0x6FU, 0x74U, 0x65U, 0x73U, 0x22U, 0x00U, - 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, - 0x20U, 0x52U, 0x65U, 0x77U, 0x61U, 0x72U, 0x64U, 0x20U, 0x64U, 0x65U, 0x6CU, - 0x61U, 0x79U, 0x20U, 0x63U, 0x68U, 0x61U, 0x6EU, 0x67U, 0x65U, 0x20U, 0x61U, - 0x63U, 0x74U, 0x69U, 0x6FU, 0x6EU, 0x65U, 0x64U, 0x21U, 0x00U, 0x47U, 0x6FU, - 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x52U, - 0x65U, 0x77U, 0x61U, 0x72U, 0x64U, 0x20U, 0x72U, 0x61U, 0x74U, 0x65U, 0x20U, - 0x63U, 0x68U, 0x61U, 0x6EU, 0x67U, 0x65U, 0x20U, 0x61U, 0x63U, 0x74U, 0x69U, - 0x6FU, 0x6EU, 0x65U, 0x64U, 0x21U, 0x00U, 0x41U, 0xB0U, 0x1AU, 0x0BU, 0x14U, - 0xB5U, 0xF7U, 0x62U, 0x79U, 0x8AU, 0x53U, 0xD5U, 0x43U, 0xA0U, 0x14U, 0xCAU, - 0xF8U, 0xB2U, 0x97U, 0xCFU, 0xF8U, 0xF2U, 0xF9U, 0x37U, 0xE8U}; + 0x52U, 0x65U, 0x77U, 0x61U, 0x72U, 0x64U, 0x20U, 0x44U, 0x65U, 0x6CU, 0x61U, + 0x79U, 0x20U, 0x6DU, 0x75U, 0x73U, 0x74U, 0x20U, 0x62U, 0x65U, 0x20U, 0x3EU, + 0x20U, 0x30U, 0x2EU, 0x00U, 0x52U, 0x52U, 0x00U, 0x52U, 0x44U, 0x00U, 0x47U, + 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, + 0x4FU, 0x6EU, 0x65U, 0x20U, 0x6FU, 0x72U, 0x20U, 0x6DU, 0x6FU, 0x72U, 0x65U, + 0x20U, 0x69U, 0x6EU, 0x69U, 0x74U, 0x69U, 0x61U, 0x6CU, 0x20U, 0x6DU, 0x65U, + 0x6DU, 0x62U, 0x65U, 0x72U, 0x20U, 0x61U, 0x63U, 0x63U, 0x6FU, 0x75U, 0x6EU, + 0x74U, 0x20U, 0x49U, 0x44U, 0x27U, 0x73U, 0x20U, 0x69U, 0x73U, 0x20U, 0x6DU, + 0x69U, 0x73U, 0x73U, 0x69U, 0x6EU, 0x67U, 0x00U, 0x4DU, 0x65U, 0x6DU, 0x62U, + 0x65U, 0x72U, 0x3AU, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, + 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x53U, 0x65U, 0x74U, 0x75U, 0x70U, 0x20U, + 0x63U, 0x6FU, 0x6DU, 0x70U, 0x6CU, 0x65U, 0x74U, 0x65U, 0x64U, 0x20U, 0x73U, + 0x75U, 0x63U, 0x63U, 0x65U, 0x73U, 0x73U, 0x66U, 0x75U, 0x6CU, 0x6CU, 0x79U, + 0x2EU, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, + 0x65U, 0x3AU, 0x20U, 0x59U, 0x6FU, 0x75U, 0x20U, 0x61U, 0x72U, 0x65U, 0x20U, + 0x6EU, 0x6FU, 0x74U, 0x20U, 0x63U, 0x75U, 0x72U, 0x72U, 0x65U, 0x6EU, 0x74U, + 0x6CU, 0x79U, 0x20U, 0x61U, 0x20U, 0x67U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, + 0x61U, 0x6EU, 0x63U, 0x65U, 0x20U, 0x6DU, 0x65U, 0x6DU, 0x62U, 0x65U, 0x72U, + 0x20U, 0x61U, 0x74U, 0x20U, 0x74U, 0x68U, 0x69U, 0x73U, 0x20U, 0x74U, 0x61U, + 0x62U, 0x6CU, 0x65U, 0x2EU, 0x00U, 0x54U, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, + 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x56U, 0x61U, 0x6CU, + 0x69U, 0x64U, 0x20U, 0x54U, 0x4FU, 0x50U, 0x49U, 0x43U, 0x20U, 0x6DU, 0x75U, + 0x73U, 0x74U, 0x20U, 0x62U, 0x65U, 0x20U, 0x73U, 0x70U, 0x65U, 0x63U, 0x69U, + 0x66U, 0x69U, 0x65U, 0x64U, 0x20U, 0x61U, 0x73U, 0x20U, 0x6FU, 0x74U, 0x78U, + 0x6EU, 0x20U, 0x70U, 0x61U, 0x72U, 0x61U, 0x6DU, 0x65U, 0x74U, 0x65U, 0x72U, + 0x2EU, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, + 0x65U, 0x3AU, 0x20U, 0x56U, 0x61U, 0x6CU, 0x69U, 0x64U, 0x20U, 0x73U, 0x65U, + 0x61U, 0x74U, 0x20U, 0x74U, 0x6FU, 0x70U, 0x69U, 0x63U, 0x73U, 0x20U, 0x61U, + 0x72U, 0x65U, 0x20U, 0x30U, 0x20U, 0x74U, 0x68U, 0x72U, 0x6FU, 0x75U, 0x67U, + 0x68U, 0x20U, 0x31U, 0x39U, 0x2EU, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, + 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x56U, 0x61U, 0x6CU, 0x69U, + 0x64U, 0x20U, 0x68U, 0x6FU, 0x6FU, 0x6BU, 0x20U, 0x74U, 0x6FU, 0x70U, 0x69U, + 0x63U, 0x73U, 0x20U, 0x61U, 0x72U, 0x65U, 0x20U, 0x30U, 0x20U, 0x74U, 0x68U, + 0x72U, 0x6FU, 0x75U, 0x67U, 0x68U, 0x20U, 0x39U, 0x2EU, 0x00U, 0x47U, 0x6FU, + 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x56U, + 0x61U, 0x6CU, 0x69U, 0x64U, 0x20U, 0x72U, 0x65U, 0x77U, 0x61U, 0x72U, 0x64U, + 0x20U, 0x74U, 0x6FU, 0x70U, 0x69U, 0x63U, 0x73U, 0x20U, 0x61U, 0x72U, 0x65U, + 0x20U, 0x52U, 0x20U, 0x28U, 0x72U, 0x61U, 0x74U, 0x65U, 0x29U, 0x20U, 0x61U, + 0x6EU, 0x64U, 0x20U, 0x44U, 0x20U, 0x28U, 0x64U, 0x65U, 0x6CU, 0x61U, 0x79U, + 0x29U, 0x2EU, 0x00U, 0x4CU, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, + 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x4DU, 0x69U, 0x73U, 0x73U, 0x69U, + 0x6EU, 0x67U, 0x20U, 0x4CU, 0x20U, 0x70U, 0x61U, 0x72U, 0x61U, 0x6DU, 0x65U, + 0x74U, 0x65U, 0x72U, 0x2EU, 0x20U, 0x57U, 0x68U, 0x69U, 0x63U, 0x68U, 0x20U, + 0x6CU, 0x61U, 0x79U, 0x65U, 0x72U, 0x20U, 0x61U, 0x72U, 0x65U, 0x20U, 0x79U, + 0x6FU, 0x75U, 0x20U, 0x76U, 0x6FU, 0x74U, 0x69U, 0x6EU, 0x67U, 0x20U, 0x66U, + 0x6FU, 0x72U, 0x3FU, 0x00U, 0x6CU, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, + 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x4CU, 0x61U, 0x79U, 0x65U, + 0x72U, 0x20U, 0x70U, 0x61U, 0x72U, 0x61U, 0x6DU, 0x65U, 0x74U, 0x65U, 0x72U, + 0x20U, 0x6DU, 0x75U, 0x73U, 0x74U, 0x20U, 0x62U, 0x65U, 0x20U, 0x27U, 0x31U, + 0x27U, 0x20U, 0x6FU, 0x72U, 0x20U, 0x27U, 0x32U, 0x27U, 0x2EU, 0x00U, 0x47U, + 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, + 0x4CU, 0x32U, 0x73U, 0x20U, 0x63U, 0x61U, 0x6EU, 0x6EU, 0x6FU, 0x74U, 0x20U, + 0x76U, 0x6FU, 0x74U, 0x65U, 0x20U, 0x6FU, 0x6EU, 0x20U, 0x52U, 0x52U, 0x2FU, + 0x52U, 0x44U, 0x20U, 0x61U, 0x74U, 0x20U, 0x4CU, 0x32U, 0x2CU, 0x20U, 0x64U, + 0x69U, 0x64U, 0x20U, 0x79U, 0x6FU, 0x75U, 0x20U, 0x6DU, 0x65U, 0x61U, 0x6EU, + 0x20U, 0x74U, 0x6FU, 0x20U, 0x73U, 0x65U, 0x74U, 0x20U, 0x4CU, 0x3DU, 0x31U, + 0x3FU, 0x00U, 0x56U, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, + 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x4DU, 0x69U, 0x73U, 0x73U, 0x69U, 0x6EU, + 0x67U, 0x20U, 0x6FU, 0x72U, 0x20U, 0x69U, 0x6EU, 0x63U, 0x6FU, 0x72U, 0x72U, + 0x65U, 0x63U, 0x74U, 0x20U, 0x73U, 0x69U, 0x7AU, 0x65U, 0x20U, 0x6FU, 0x66U, + 0x20U, 0x56U, 0x4FU, 0x54U, 0x45U, 0x20U, 0x64U, 0x61U, 0x74U, 0x61U, 0x20U, + 0x66U, 0x6FU, 0x72U, 0x20U, 0x54U, 0x4FU, 0x50U, 0x49U, 0x43U, 0x20U, 0x74U, + 0x79U, 0x70U, 0x65U, 0x2EU, 0x00U, 0x74U, 0x6FU, 0x70U, 0x69U, 0x63U, 0x5FU, + 0x64U, 0x61U, 0x74U, 0x61U, 0x5FU, 0x72U, 0x61U, 0x77U, 0x3AU, 0x00U, 0x74U, + 0x6FU, 0x70U, 0x69U, 0x63U, 0x5FU, 0x70U, 0x61U, 0x64U, 0x64U, 0x69U, 0x6EU, + 0x67U, 0x3AU, 0x00U, 0x74U, 0x6FU, 0x70U, 0x69U, 0x63U, 0x5FU, 0x73U, 0x69U, + 0x7AU, 0x65U, 0x3AU, 0x00U, 0x74U, 0x6FU, 0x70U, 0x69U, 0x63U, 0x5FU, 0x64U, + 0x61U, 0x74U, 0x61U, 0x3AU, 0x00U, 0x70U, 0x72U, 0x65U, 0x76U, 0x69U, 0x6FU, + 0x75U, 0x73U, 0x5FU, 0x74U, 0x6FU, 0x70U, 0x69U, 0x63U, 0x5FU, 0x64U, 0x61U, + 0x74U, 0x61U, 0x00U, 0x74U, 0x6FU, 0x70U, 0x69U, 0x63U, 0x5FU, 0x64U, 0x61U, + 0x74U, 0x61U, 0x00U, 0x70U, 0x72U, 0x65U, 0x76U, 0x69U, 0x6FU, 0x75U, 0x73U, + 0x5FU, 0x74U, 0x6FU, 0x70U, 0x69U, 0x63U, 0x5FU, 0x73U, 0x69U, 0x7AU, 0x65U, + 0x00U, 0x74U, 0x6FU, 0x70U, 0x69U, 0x63U, 0x5FU, 0x73U, 0x69U, 0x7AU, 0x65U, + 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, + 0x3AU, 0x20U, 0x59U, 0x6FU, 0x75U, 0x72U, 0x20U, 0x76U, 0x6FU, 0x74U, 0x65U, + 0x20U, 0x69U, 0x73U, 0x20U, 0x61U, 0x6CU, 0x72U, 0x65U, 0x61U, 0x64U, 0x79U, + 0x20U, 0x63U, 0x61U, 0x73U, 0x74U, 0x20U, 0x74U, 0x68U, 0x69U, 0x73U, 0x20U, + 0x77U, 0x61U, 0x79U, 0x20U, 0x66U, 0x6FU, 0x72U, 0x20U, 0x74U, 0x68U, 0x69U, + 0x73U, 0x20U, 0x74U, 0x6FU, 0x70U, 0x69U, 0x63U, 0x2EU, 0x00U, 0x74U, 0x6FU, + 0x70U, 0x69U, 0x63U, 0x5FU, 0x64U, 0x61U, 0x74U, 0x61U, 0x5FU, 0x7AU, 0x65U, + 0x72U, 0x6FU, 0x00U, 0x76U, 0x6FU, 0x74U, 0x65U, 0x73U, 0x00U, 0x74U, 0x6FU, + 0x70U, 0x69U, 0x63U, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, + 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x56U, 0x6FU, 0x74U, 0x65U, 0x20U, 0x72U, + 0x65U, 0x63U, 0x6FU, 0x72U, 0x64U, 0x2EU, 0x20U, 0x4EU, 0x6FU, 0x74U, 0x20U, + 0x79U, 0x65U, 0x74U, 0x20U, 0x65U, 0x6EU, 0x6FU, 0x75U, 0x67U, 0x68U, 0x20U, + 0x76U, 0x6FU, 0x74U, 0x65U, 0x73U, 0x20U, 0x74U, 0x6FU, 0x20U, 0x61U, 0x63U, + 0x74U, 0x69U, 0x6FU, 0x6EU, 0x2EU, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, + 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x4EU, 0x6FU, 0x74U, 0x20U, + 0x79U, 0x65U, 0x74U, 0x20U, 0x65U, 0x6EU, 0x6FU, 0x75U, 0x67U, 0x68U, 0x20U, + 0x76U, 0x6FU, 0x74U, 0x65U, 0x73U, 0x20U, 0x74U, 0x6FU, 0x20U, 0x61U, 0x63U, + 0x74U, 0x69U, 0x6FU, 0x6EU, 0x20U, 0x4CU, 0x31U, 0x20U, 0x76U, 0x6FU, 0x74U, + 0x65U, 0x2EU, 0x2EU, 0x2EU, 0x00U, 0x22U, 0x41U, 0x63U, 0x74U, 0x69U, 0x6FU, + 0x6EU, 0x69U, 0x6EU, 0x67U, 0x20U, 0x76U, 0x6FU, 0x74U, 0x65U, 0x73U, 0x22U, + 0x00U, 0x41U, 0x63U, 0x74U, 0x69U, 0x6FU, 0x6EU, 0x69U, 0x6EU, 0x67U, 0x20U, + 0x76U, 0x6FU, 0x74U, 0x65U, 0x73U, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, + 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x45U, 0x6DU, 0x69U, 0x74U, + 0x74U, 0x69U, 0x6EU, 0x67U, 0x20U, 0x69U, 0x6EU, 0x76U, 0x6FU, 0x6BU, 0x65U, + 0x20U, 0x74U, 0x6FU, 0x20U, 0x4CU, 0x31U, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, + 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x45U, 0x6DU, 0x69U, + 0x74U, 0x20U, 0x72U, 0x65U, 0x73U, 0x75U, 0x6CU, 0x74U, 0x00U, 0x47U, 0x6FU, + 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x53U, + 0x75U, 0x63U, 0x63U, 0x65U, 0x73U, 0x73U, 0x66U, 0x75U, 0x6CU, 0x6CU, 0x79U, + 0x20U, 0x65U, 0x6DU, 0x69U, 0x74U, 0x74U, 0x65U, 0x64U, 0x20U, 0x4CU, 0x31U, + 0x20U, 0x76U, 0x6FU, 0x74U, 0x65U, 0x2EU, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, + 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x4CU, 0x31U, 0x20U, + 0x76U, 0x6FU, 0x74U, 0x65U, 0x20U, 0x65U, 0x6DU, 0x69U, 0x73U, 0x73U, 0x69U, + 0x6FU, 0x6EU, 0x20U, 0x66U, 0x61U, 0x69U, 0x6CU, 0x65U, 0x64U, 0x2EU, 0x00U, + 0x72U, 0x65U, 0x73U, 0x75U, 0x6CU, 0x74U, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, + 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x52U, 0x65U, 0x77U, + 0x61U, 0x72U, 0x64U, 0x20U, 0x72U, 0x61U, 0x74U, 0x65U, 0x20U, 0x63U, 0x68U, + 0x61U, 0x6EU, 0x67U, 0x65U, 0x20U, 0x61U, 0x63U, 0x74U, 0x69U, 0x6FU, 0x6EU, + 0x65U, 0x64U, 0x21U, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, + 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x52U, 0x65U, 0x77U, 0x61U, 0x72U, 0x64U, + 0x20U, 0x64U, 0x65U, 0x6CU, 0x61U, 0x79U, 0x20U, 0x63U, 0x68U, 0x61U, 0x6EU, + 0x67U, 0x65U, 0x20U, 0x61U, 0x63U, 0x74U, 0x69U, 0x6FU, 0x6EU, 0x65U, 0x64U, + 0x21U, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x61U, 0x6EU, 0x63U, 0x65U, + 0x3AU, 0x20U, 0x54U, 0x61U, 0x72U, 0x67U, 0x65U, 0x74U, 0x20U, 0x68U, 0x6FU, + 0x6FU, 0x6BU, 0x20U, 0x69U, 0x73U, 0x20U, 0x61U, 0x6CU, 0x72U, 0x65U, 0x61U, + 0x64U, 0x79U, 0x20U, 0x74U, 0x68U, 0x65U, 0x20U, 0x73U, 0x61U, 0x6DU, 0x65U, + 0x20U, 0x61U, 0x73U, 0x20U, 0x61U, 0x63U, 0x74U, 0x69U, 0x6FU, 0x6EU, 0x65U, + 0x64U, 0x20U, 0x68U, 0x6FU, 0x6FU, 0x6BU, 0x2EU, 0x00U, 0x47U, 0x6FU, 0x76U, + 0x65U, 0x72U, 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x48U, 0x6FU, 0x6FU, + 0x6BU, 0x20U, 0x48U, 0x61U, 0x73U, 0x68U, 0x20U, 0x64U, 0x6FU, 0x65U, 0x73U, + 0x6EU, 0x27U, 0x74U, 0x20U, 0x65U, 0x78U, 0x69U, 0x73U, 0x74U, 0x20U, 0x6FU, + 0x6EU, 0x20U, 0x6CU, 0x65U, 0x64U, 0x67U, 0x65U, 0x72U, 0x20U, 0x77U, 0x68U, + 0x69U, 0x6CU, 0x65U, 0x20U, 0x61U, 0x63U, 0x74U, 0x69U, 0x6FU, 0x6EU, 0x69U, + 0x6EU, 0x67U, 0x20U, 0x68U, 0x6FU, 0x6FU, 0x6BU, 0x2EU, 0x00U, 0x45U, 0x6DU, + 0x69U, 0x74U, 0x74U, 0x65U, 0x64U, 0x54U, 0x78U, 0x6EU, 0x00U, 0x65U, 0x6DU, + 0x69U, 0x74U, 0x5FU, 0x72U, 0x65U, 0x73U, 0x75U, 0x6CU, 0x74U, 0x00U, 0x47U, + 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, + 0x45U, 0x6DU, 0x69U, 0x74U, 0x20U, 0x66U, 0x61U, 0x69U, 0x6CU, 0x65U, 0x64U, + 0x20U, 0x64U, 0x75U, 0x72U, 0x69U, 0x6EU, 0x67U, 0x20U, 0x68U, 0x6FU, 0x6FU, + 0x6BU, 0x20U, 0x61U, 0x63U, 0x74U, 0x69U, 0x6FU, 0x6EU, 0x69U, 0x6EU, 0x67U, + 0x2EU, 0x00U, 0x45U, 0x6DU, 0x69U, 0x74U, 0x74U, 0x65U, 0x64U, 0x54U, 0x78U, + 0x6EU, 0x48U, 0x61U, 0x73U, 0x68U, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, + 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x48U, 0x6FU, 0x6FU, 0x6BU, + 0x20U, 0x61U, 0x63U, 0x74U, 0x69U, 0x6FU, 0x6EU, 0x65U, 0x64U, 0x2EU, 0x00U, + 0x50U, 0x72U, 0x65U, 0x76U, 0x69U, 0x6FU, 0x75U, 0x73U, 0x20U, 0x70U, 0x72U, + 0x65U, 0x73U, 0x65U, 0x6EU, 0x74U, 0x3DU, 0x3DU, 0x3AU, 0x00U, 0x47U, 0x6FU, + 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x41U, + 0x63U, 0x74U, 0x69U, 0x6FU, 0x6EU, 0x69U, 0x6EU, 0x67U, 0x20U, 0x73U, 0x65U, + 0x61U, 0x74U, 0x20U, 0x63U, 0x68U, 0x61U, 0x6EU, 0x67U, 0x65U, 0x2CU, 0x20U, + 0x62U, 0x75U, 0x74U, 0x20U, 0x73U, 0x65U, 0x61U, 0x74U, 0x20U, 0x61U, 0x6CU, + 0x72U, 0x65U, 0x61U, 0x64U, 0x79U, 0x20U, 0x63U, 0x6FU, 0x6EU, 0x74U, 0x61U, + 0x69U, 0x6EU, 0x73U, 0x20U, 0x74U, 0x68U, 0x65U, 0x20U, 0x6EU, 0x65U, 0x77U, + 0x20U, 0x6DU, 0x65U, 0x6DU, 0x62U, 0x65U, 0x72U, 0x2EU, 0x00U, 0x47U, 0x6FU, + 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, 0x3AU, 0x20U, 0x4DU, + 0x6FU, 0x76U, 0x69U, 0x6EU, 0x67U, 0x20U, 0x65U, 0x78U, 0x69U, 0x73U, 0x74U, + 0x69U, 0x6EU, 0x67U, 0x20U, 0x6DU, 0x65U, 0x6DU, 0x62U, 0x65U, 0x72U, 0x20U, + 0x74U, 0x6FU, 0x20U, 0x6EU, 0x65U, 0x77U, 0x20U, 0x73U, 0x65U, 0x61U, 0x74U, + 0x2EU, 0x00U, 0x6FU, 0x70U, 0x00U, 0x45U, 0x00U, 0x5AU, 0x00U, 0x4DU, 0x00U, + 0x70U, 0x72U, 0x65U, 0x76U, 0x69U, 0x6FU, 0x75U, 0x73U, 0x5FU, 0x70U, 0x72U, + 0x65U, 0x73U, 0x65U, 0x6EU, 0x74U, 0x00U, 0x44U, 0x65U, 0x63U, 0x72U, 0x65U, + 0x6DU, 0x65U, 0x6EU, 0x74U, 0x20U, 0x76U, 0x6FU, 0x74U, 0x65U, 0x20U, 0x63U, + 0x6FU, 0x75U, 0x6EU, 0x74U, 0x20U, 0x64U, 0x65U, 0x6CU, 0x65U, 0x74U, 0x65U, + 0x64U, 0x00U, 0x44U, 0x65U, 0x63U, 0x72U, 0x65U, 0x6DU, 0x65U, 0x6EU, 0x74U, + 0x20U, 0x76U, 0x6FU, 0x74U, 0x65U, 0x20U, 0x63U, 0x6FU, 0x75U, 0x6EU, 0x74U, + 0x20U, 0x74U, 0x6FU, 0x00U, 0x56U, 0x6FU, 0x74U, 0x65U, 0x20U, 0x65U, 0x6EU, + 0x74U, 0x72U, 0x79U, 0x20U, 0x64U, 0x65U, 0x6CU, 0x65U, 0x74U, 0x65U, 0x64U, + 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, 0x65U, + 0x3AU, 0x20U, 0x41U, 0x63U, 0x74U, 0x69U, 0x6FU, 0x6EU, 0x20U, 0x6DU, 0x65U, + 0x6DU, 0x62U, 0x65U, 0x72U, 0x20U, 0x63U, 0x68U, 0x61U, 0x6EU, 0x67U, 0x65U, + 0x2EU, 0x00U, 0x47U, 0x6FU, 0x76U, 0x65U, 0x72U, 0x6EU, 0x61U, 0x6EU, 0x63U, + 0x65U, 0x3AU, 0x20U, 0x49U, 0x6EU, 0x74U, 0x65U, 0x72U, 0x6EU, 0x61U, 0x6CU, + 0x20U, 0x6CU, 0x6FU, 0x67U, 0x69U, 0x63U, 0x20U, 0x65U, 0x72U, 0x72U, 0x6FU, + 0x72U, 0x2EU}; static const std::vector RewardHook = { 0x00U, 0x61U, 0x73U, 0x6DU, 0x01U, 0x00U, 0x00U, 0x00U, 0x01U, 0x61U, 0x0EU, diff --git a/include/xrpl/protocol/Feature.h b/include/xrpl/protocol/Feature.h index d5dbd3969..0e3a04cd5 100644 --- a/include/xrpl/protocol/Feature.h +++ b/include/xrpl/protocol/Feature.h @@ -80,7 +80,7 @@ namespace detail { // Feature.cpp. Because it's only used to reserve storage, and determine how // large to make the FeatureBitset, it MAY be larger. It MUST NOT be less than // the actual number of amendments. A LogicError on startup will verify this. -static constexpr std::size_t numFeatures = 115; +static constexpr std::size_t numFeatures = 117; /** Amendments that this server supports and the default voting behavior. Whether they are enabled depends on the Rules defined in the validated diff --git a/include/xrpl/protocol/TxFlags.h b/include/xrpl/protocol/TxFlags.h index 8d9d29f16..83f8e79c2 100644 --- a/include/xrpl/protocol/TxFlags.h +++ b/include/xrpl/protocol/TxFlags.h @@ -132,7 +132,7 @@ constexpr std::uint32_t tfTrustSetMask = tfClearFreeze | tfSetDeepFreeze | tfClearDeepFreeze); // EnableAmendment flags: -enum EnableAmendmentFlags : std::uint32_t { +enum EnableAmendmentFlags : uint32_t { tfGotMajority = 0x00010000, tfLostMajority = 0x00020000, tfTestSuite = 0x80000000, diff --git a/include/xrpl/protocol/detail/features.macro b/include/xrpl/protocol/detail/features.macro index affdca560..ad2e30e68 100644 --- a/include/xrpl/protocol/detail/features.macro +++ b/include/xrpl/protocol/detail/features.macro @@ -31,6 +31,8 @@ // If you add an amendment here, then do not forget to increment `numFeatures` // in include/xrpl/protocol/Feature.h. +XRPL_FIX (IOULockedBalanceInvariant, Supported::yes, VoteBehavior::DefaultNo) +XRPL_FIX (ImportIssuer, Supported::yes, VoteBehavior::DefaultYes) XRPL_FEATURE(HookAPISerializedType240, Supported::yes, VoteBehavior::DefaultNo) XRPL_FEATURE(PermissionedDomains, Supported::no, VoteBehavior::DefaultNo) XRPL_FEATURE(DynamicNFT, Supported::no, VoteBehavior::DefaultNo) diff --git a/include/xrpl/protocol/detail/sfields.macro b/include/xrpl/protocol/detail/sfields.macro index 6fcab8759..e5bbcd9f3 100644 --- a/include/xrpl/protocol/detail/sfields.macro +++ b/include/xrpl/protocol/detail/sfields.macro @@ -372,7 +372,7 @@ UNTYPED_SFIELD(sfMajority, OBJECT, 18) UNTYPED_SFIELD(sfDisabledValidator, OBJECT, 19) UNTYPED_SFIELD(sfEmittedTxn, OBJECT, 20) UNTYPED_SFIELD(sfHookExecution, OBJECT, 21) -UNTYPED_SFIELD(sfHookDefinition, OBJECT, 22) + // 22 unused UNTYPED_SFIELD(sfHookParameter, OBJECT, 23) UNTYPED_SFIELD(sfHookGrant, OBJECT, 24) UNTYPED_SFIELD(sfVoteEntry, OBJECT, 25) diff --git a/src/libxrpl/protocol/Indexes.cpp b/src/libxrpl/protocol/Indexes.cpp index 3ee0984f4..d962b6317 100644 --- a/src/libxrpl/protocol/Indexes.cpp +++ b/src/libxrpl/protocol/Indexes.cpp @@ -31,6 +31,8 @@ namespace ripple { +#define LEDGER_NAMESPACE2(value1, value2) (uint16_t(value1) << 8) | value2 + /** Type-specific prefix for calculating ledger indices. The identifier for a given object within the ledger is calculated based @@ -82,14 +84,14 @@ enum class LedgerNameSpace : std::uint16_t { CRON = 'L', CONSENSUS_ENTROPY = 'X', AMM = 'A', - BRIDGE = 'H', + BRIDGE = LEDGER_NAMESPACE2(0x01, 'H'), XCHAIN_CLAIM_ID = 'Q', XCHAIN_CREATE_ACCOUNT_CLAIM_ID = 'K', - DID = 'I', - ORACLE = 'R', + DID = LEDGER_NAMESPACE2(0x01, 'I'), + ORACLE = LEDGER_NAMESPACE2(0x01, 'R'), MPTOKEN_ISSUANCE = '~', MPTOKEN = 't', - CREDENTIAL = 'D', + CREDENTIAL = LEDGER_NAMESPACE2(0x01, 'D'), PERMISSIONED_DOMAIN = 'm', // No longer used or supported. Left here to reserve the space diff --git a/src/libxrpl/protocol/InnerObjectFormats.cpp b/src/libxrpl/protocol/InnerObjectFormats.cpp index 8cc9a2a1d..bec47d07d 100644 --- a/src/libxrpl/protocol/InnerObjectFormats.cpp +++ b/src/libxrpl/protocol/InnerObjectFormats.cpp @@ -88,19 +88,6 @@ InnerObjectFormats::InnerObjectFormats() {sfEmittedTxnID, soeREQUIRED}, {sfEmitNonce, soeOPTIONAL}}); - add(sfHookDefinition.jsonName, - sfHookDefinition.getCode(), - {{sfCreateCode, soeREQUIRED}, - {sfHookNamespace, soeREQUIRED}, - {sfHookParameters, soeREQUIRED}, - {sfHookOn, soeOPTIONAL}, - {sfHookOnIncoming, soeOPTIONAL}, - {sfHookOnOutgoing, soeOPTIONAL}, - {sfHookCanEmit, soeOPTIONAL}, - {sfHookApiVersion, soeREQUIRED}, - {sfFlags, soeREQUIRED}, - {sfFee, soeREQUIRED}}); - add(sfHook.jsonName, sfHook.getCode(), {{sfHookHash, soeOPTIONAL}, diff --git a/src/magic/magic_enum.h b/src/magic/magic_enum.h deleted file mode 100644 index 7adf87715..000000000 --- a/src/magic/magic_enum.h +++ /dev/null @@ -1,1474 +0,0 @@ -// __ __ _ ______ _____ -// | \/ | (_) | ____| / ____|_ _ -// | \ / | __ _ __ _ _ ___ | |__ _ __ _ _ _ __ ___ | | _| |_ _| |_ -// | |\/| |/ _` |/ _` | |/ __| | __| | '_ \| | | | '_ ` _ \ | | |_ _|_ _| -// | | | | (_| | (_| | | (__ | |____| | | | |_| | | | | | | | |____|_| |_| -// |_| |_|\__,_|\__, |_|\___| |______|_| |_|\__,_|_| |_| |_| \_____| -// __/ | https://github.com/Neargye/magic_enum -// |___/ version 0.9.5 -// -// Licensed under the MIT License . -// SPDX-License-Identifier: MIT -// Copyright (c) 2019 - 2024 Daniil Goncharov . -// -// 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. - -#ifndef NEARGYE_MAGIC_ENUM_HPP -#define NEARGYE_MAGIC_ENUM_HPP - -#define MAGIC_ENUM_VERSION_MAJOR 0 -#define MAGIC_ENUM_VERSION_MINOR 9 -#define MAGIC_ENUM_VERSION_PATCH 5 - -#include -#include -#include -#include -#include -#include -#include - -#if defined(MAGIC_ENUM_CONFIG_FILE) -# include MAGIC_ENUM_CONFIG_FILE -#endif - -#if !defined(MAGIC_ENUM_USING_ALIAS_OPTIONAL) -# include -#endif -#if !defined(MAGIC_ENUM_USING_ALIAS_STRING) -# include -#endif -#if !defined(MAGIC_ENUM_USING_ALIAS_STRING_VIEW) -# include -#endif - -#if defined(MAGIC_ENUM_NO_ASSERT) -# define MAGIC_ENUM_ASSERT(...) static_cast(0) -#elif !defined(MAGIC_ENUM_ASSERT) -# include -# define MAGIC_ENUM_ASSERT(...) assert((__VA_ARGS__)) -#endif - -#if defined(__clang__) -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wunknown-warning-option" -# pragma clang diagnostic ignored "-Wenum-constexpr-conversion" -# pragma clang diagnostic ignored "-Wuseless-cast" // suppresses 'static_cast('\0')' for char_type = char (common on Linux). -#elif defined(__GNUC__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wmaybe-uninitialized" // May be used uninitialized 'return {};'. -# pragma GCC diagnostic ignored "-Wuseless-cast" // suppresses 'static_cast('\0')' for char_type = char (common on Linux). -#elif defined(_MSC_VER) -# pragma warning(push) -# pragma warning(disable : 26495) // Variable 'static_str::chars_' is uninitialized. -# pragma warning(disable : 28020) // Arithmetic overflow: Using operator '-' on a 4 byte value and then casting the result to a 8 byte value. -# pragma warning(disable : 26451) // The expression '0<=_Param_(1)&&_Param_(1)<=1-1' is not true at this call. -# pragma warning(disable : 4514) // Unreferenced inline function has been removed. -#endif - -// Checks magic_enum compiler compatibility. -#if defined(__clang__) && __clang_major__ >= 5 || defined(__GNUC__) && __GNUC__ >= 9 || defined(_MSC_VER) && _MSC_VER >= 1910 || defined(__RESHARPER__) -# undef MAGIC_ENUM_SUPPORTED -# define MAGIC_ENUM_SUPPORTED 1 -#endif - -// Checks magic_enum compiler aliases compatibility. -#if defined(__clang__) && __clang_major__ >= 5 || defined(__GNUC__) && __GNUC__ >= 9 || defined(_MSC_VER) && _MSC_VER >= 1920 -# undef MAGIC_ENUM_SUPPORTED_ALIASES -# define MAGIC_ENUM_SUPPORTED_ALIASES 1 -#endif - -// Enum value must be greater or equals than MAGIC_ENUM_RANGE_MIN. By default MAGIC_ENUM_RANGE_MIN = -128. -// If need another min range for all enum types by default, redefine the macro MAGIC_ENUM_RANGE_MIN. -#if !defined(MAGIC_ENUM_RANGE_MIN) -# define MAGIC_ENUM_RANGE_MIN -128 -#endif - -// Enum value must be less or equals than MAGIC_ENUM_RANGE_MAX. By default MAGIC_ENUM_RANGE_MAX = 128. -// If need another max range for all enum types by default, redefine the macro MAGIC_ENUM_RANGE_MAX. -#if !defined(MAGIC_ENUM_RANGE_MAX) -# define MAGIC_ENUM_RANGE_MAX 127 -#endif - -// Improve ReSharper C++ intellisense performance with builtins, avoiding unnecessary template instantiations. -#if defined(__RESHARPER__) -# undef MAGIC_ENUM_GET_ENUM_NAME_BUILTIN -# undef MAGIC_ENUM_GET_TYPE_NAME_BUILTIN -# if __RESHARPER__ >= 20230100 -# define MAGIC_ENUM_GET_ENUM_NAME_BUILTIN(V) __rscpp_enumerator_name(V) -# define MAGIC_ENUM_GET_TYPE_NAME_BUILTIN(T) __rscpp_type_name() -# else -# define MAGIC_ENUM_GET_ENUM_NAME_BUILTIN(V) nullptr -# define MAGIC_ENUM_GET_TYPE_NAME_BUILTIN(T) nullptr -# endif -#endif - -namespace magic_enum { - -// If need another optional type, define the macro MAGIC_ENUM_USING_ALIAS_OPTIONAL. -#if defined(MAGIC_ENUM_USING_ALIAS_OPTIONAL) -MAGIC_ENUM_USING_ALIAS_OPTIONAL -#else -using std::optional; -#endif - -// If need another string_view type, define the macro MAGIC_ENUM_USING_ALIAS_STRING_VIEW. -#if defined(MAGIC_ENUM_USING_ALIAS_STRING_VIEW) -MAGIC_ENUM_USING_ALIAS_STRING_VIEW -#else -using std::string_view; -#endif - -// If need another string type, define the macro MAGIC_ENUM_USING_ALIAS_STRING. -#if defined(MAGIC_ENUM_USING_ALIAS_STRING) -MAGIC_ENUM_USING_ALIAS_STRING -#else -using std::string; -#endif - -using char_type = string_view::value_type; -static_assert(std::is_same_v, "magic_enum::customize requires same string_view::value_type and string::value_type"); -static_assert([] { - if constexpr (std::is_same_v) { - constexpr const char c[] = "abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789|"; - constexpr const wchar_t wc[] = L"abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789|"; - static_assert(std::size(c) == std::size(wc), "magic_enum::customize identifier characters are multichars in wchar_t."); - - for (std::size_t i = 0; i < std::size(c); ++i) { - if (c[i] != wc[i]) { - return false; - } - } - } - return true; -} (), "magic_enum::customize wchar_t is not compatible with ASCII."); - -namespace customize { - -// Enum value must be in range [MAGIC_ENUM_RANGE_MIN, MAGIC_ENUM_RANGE_MAX]. By default MAGIC_ENUM_RANGE_MIN = -128, MAGIC_ENUM_RANGE_MAX = 128. -// If need another range for all enum types by default, redefine the macro MAGIC_ENUM_RANGE_MIN and MAGIC_ENUM_RANGE_MAX. -// If need another range for specific enum type, add specialization enum_range for necessary enum type. -template -struct enum_range { - static constexpr int min = MAGIC_ENUM_RANGE_MIN; - static constexpr int max = MAGIC_ENUM_RANGE_MAX; -}; - -static_assert(MAGIC_ENUM_RANGE_MAX > MAGIC_ENUM_RANGE_MIN, "MAGIC_ENUM_RANGE_MAX must be greater than MAGIC_ENUM_RANGE_MIN."); - -namespace detail { - -enum class customize_tag { - default_tag, - invalid_tag, - custom_tag -}; - -} // namespace magic_enum::customize::detail - -class customize_t : public std::pair { - public: - constexpr customize_t(string_view srt) : std::pair{detail::customize_tag::custom_tag, srt} {} - constexpr customize_t(const char_type* srt) : customize_t{string_view{srt}} {} - constexpr customize_t(detail::customize_tag tag) : std::pair{tag, string_view{}} { - MAGIC_ENUM_ASSERT(tag != detail::customize_tag::custom_tag); - } -}; - -// Default customize. -inline constexpr auto default_tag = customize_t{detail::customize_tag::default_tag}; -// Invalid customize. -inline constexpr auto invalid_tag = customize_t{detail::customize_tag::invalid_tag}; - -// If need custom names for enum, add specialization enum_name for necessary enum type. -template -constexpr customize_t enum_name(E) noexcept { - return default_tag; -} - -// If need custom type name for enum, add specialization enum_type_name for necessary enum type. -template -constexpr customize_t enum_type_name() noexcept { - return default_tag; -} - -} // namespace magic_enum::customize - -namespace detail { - -template -struct supported -#if defined(MAGIC_ENUM_SUPPORTED) && MAGIC_ENUM_SUPPORTED || defined(MAGIC_ENUM_NO_CHECK_SUPPORT) - : std::true_type {}; -#else - : std::false_type {}; -#endif - -template , std::enable_if_t, int> = 0> -using enum_constant = std::integral_constant; - -template -inline constexpr bool always_false_v = false; - -template -struct has_is_flags : std::false_type {}; - -template -struct has_is_flags::is_flags)>> : std::bool_constant::is_flags)>>> {}; - -template -struct range_min : std::integral_constant {}; - -template -struct range_min::min)>> : std::integral_constant::min), customize::enum_range::min> {}; - -template -struct range_max : std::integral_constant {}; - -template -struct range_max::max)>> : std::integral_constant::max), customize::enum_range::max> {}; - -struct str_view { - const char* str_ = nullptr; - std::size_t size_ = 0; -}; - -template -class static_str { - public: - constexpr explicit static_str(str_view str) noexcept : static_str{str.str_, std::make_integer_sequence{}} { - MAGIC_ENUM_ASSERT(str.size_ == N); - } - - constexpr explicit static_str(string_view str) noexcept : static_str{str.data(), std::make_integer_sequence{}} { - MAGIC_ENUM_ASSERT(str.size() == N); - } - - constexpr const char_type* data() const noexcept { return chars_; } - - constexpr std::uint16_t size() const noexcept { return N; } - - constexpr operator string_view() const noexcept { return {data(), size()}; } - - private: - template - constexpr static_str(const char* str, std::integer_sequence) noexcept : chars_{static_cast(str[I])..., static_cast('\0')} {} - - template - constexpr static_str(string_view str, std::integer_sequence) noexcept : chars_{str[I]..., static_cast('\0')} {} - - char_type chars_[static_cast(N) + 1]; -}; - -template <> -class static_str<0> { - public: - constexpr explicit static_str() = default; - - constexpr explicit static_str(str_view) noexcept {} - - constexpr explicit static_str(string_view) noexcept {} - - constexpr const char_type* data() const noexcept { return nullptr; } - - constexpr std::uint16_t size() const noexcept { return 0; } - - constexpr operator string_view() const noexcept { return {}; } -}; - -template > -class case_insensitive { - static constexpr char_type to_lower(char_type c) noexcept { - return (c >= static_cast('A') && c <= static_cast('Z')) ? static_cast(c + (static_cast('a') - static_cast('A'))) : c; - } - - public: - template - constexpr auto operator()(L lhs, R rhs) const noexcept -> std::enable_if_t, char_type> && std::is_same_v, char_type>, bool> { - return Op{}(to_lower(lhs), to_lower(rhs)); - } -}; - -constexpr std::size_t find(string_view str, char_type c) noexcept { -#if defined(__clang__) && __clang_major__ < 9 && defined(__GLIBCXX__) || defined(_MSC_VER) && _MSC_VER < 1920 && !defined(__clang__) -// https://stackoverflow.com/questions/56484834/constexpr-stdstring-viewfind-last-of-doesnt-work-on-clang-8-with-libstdc -// https://developercommunity.visualstudio.com/content/problem/360432/vs20178-regression-c-failed-in-test.html - constexpr bool workaround = true; -#else - constexpr bool workaround = false; -#endif - - if constexpr (workaround) { - for (std::size_t i = 0; i < str.size(); ++i) { - if (str[i] == c) { - return i; - } - } - - return string_view::npos; - } else { - return str.find(c); - } -} - -template -constexpr bool is_default_predicate() noexcept { - return std::is_same_v, std::equal_to> || - std::is_same_v, std::equal_to<>>; -} - -template -constexpr bool is_nothrow_invocable() { - return is_default_predicate() || - std::is_nothrow_invocable_r_v; -} - -template -constexpr bool cmp_equal(string_view lhs, string_view rhs, [[maybe_unused]] BinaryPredicate&& p) noexcept(is_nothrow_invocable()) { -#if defined(_MSC_VER) && _MSC_VER < 1920 && !defined(__clang__) - // https://developercommunity.visualstudio.com/content/problem/360432/vs20178-regression-c-failed-in-test.html - // https://developercommunity.visualstudio.com/content/problem/232218/c-constexpr-string-view.html - constexpr bool workaround = true; -#else - constexpr bool workaround = false; -#endif - - if constexpr (!is_default_predicate() || workaround) { - if (lhs.size() != rhs.size()) { - return false; - } - - const auto size = lhs.size(); - for (std::size_t i = 0; i < size; ++i) { - if (!p(lhs[i], rhs[i])) { - return false; - } - } - - return true; - } else { - return lhs == rhs; - } -} - -template -constexpr bool cmp_less(L lhs, R rhs) noexcept { - static_assert(std::is_integral_v && std::is_integral_v, "magic_enum::detail::cmp_less requires integral type."); - - if constexpr (std::is_signed_v == std::is_signed_v) { - // If same signedness (both signed or both unsigned). - return lhs < rhs; - } else if constexpr (std::is_same_v) { // bool special case - return static_cast(lhs) < rhs; - } else if constexpr (std::is_same_v) { // bool special case - return lhs < static_cast(rhs); - } else if constexpr (std::is_signed_v) { - // If 'right' is negative, then result is 'false', otherwise cast & compare. - return rhs > 0 && lhs < static_cast>(rhs); - } else { - // If 'left' is negative, then result is 'true', otherwise cast & compare. - return lhs < 0 || static_cast>(lhs) < rhs; - } -} - -template -constexpr I log2(I value) noexcept { - static_assert(std::is_integral_v, "magic_enum::detail::log2 requires integral type."); - - if constexpr (std::is_same_v) { // bool special case - return MAGIC_ENUM_ASSERT(false), value; - } else { - auto ret = I{0}; - for (; value > I{1}; value >>= I{1}, ++ret) {} - - return ret; - } -} - -#if defined(__cpp_lib_array_constexpr) && __cpp_lib_array_constexpr >= 201603L -# define MAGIC_ENUM_ARRAY_CONSTEXPR 1 -#else -template -constexpr std::array, N> to_array(T (&a)[N], std::index_sequence) noexcept { - return {{a[I]...}}; -} -#endif - -template -inline constexpr bool is_enum_v = std::is_enum_v && std::is_same_v>; - -template -constexpr auto n() noexcept { - static_assert(is_enum_v, "magic_enum::detail::n requires enum type."); - - if constexpr (supported::value) { -#if defined(MAGIC_ENUM_GET_TYPE_NAME_BUILTIN) - constexpr auto name_ptr = MAGIC_ENUM_GET_TYPE_NAME_BUILTIN(E); - constexpr auto name = name_ptr ? str_view{name_ptr, std::char_traits::length(name_ptr)} : str_view{}; -#elif defined(__clang__) - str_view name; - if constexpr (sizeof(__PRETTY_FUNCTION__) == sizeof(__FUNCTION__)) { - static_assert(always_false_v, "magic_enum::detail::n requires __PRETTY_FUNCTION__."); - return str_view{}; - } else { - name.size_ = sizeof(__PRETTY_FUNCTION__) - 36; - name.str_ = __PRETTY_FUNCTION__ + 34; - } -#elif defined(__GNUC__) - auto name = str_view{__PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__) - 1}; - if constexpr (sizeof(__PRETTY_FUNCTION__) == sizeof(__FUNCTION__)) { - static_assert(always_false_v, "magic_enum::detail::n requires __PRETTY_FUNCTION__."); - return str_view{}; - } else if (name.str_[name.size_ - 1] == ']') { - name.size_ -= 50; - name.str_ += 49; - } else { - name.size_ -= 40; - name.str_ += 37; - } -#elif defined(_MSC_VER) - // CLI/C++ workaround (see https://github.com/Neargye/magic_enum/issues/284). - str_view name; - name.str_ = __FUNCSIG__; - name.str_ += 40; - name.size_ += sizeof(__FUNCSIG__) - 57; -#else - auto name = str_view{}; -#endif - std::size_t p = 0; - for (std::size_t i = name.size_; i > 0; --i) { - if (name.str_[i] == ':') { - p = i + 1; - break; - } - } - if (p > 0) { - name.size_ -= p; - name.str_ += p; - } - return name; - } else { - return str_view{}; // Unsupported compiler or Invalid customize. - } -} - -template -constexpr auto type_name() noexcept { - [[maybe_unused]] constexpr auto custom = customize::enum_type_name(); - static_assert(std::is_same_v, customize::customize_t>, "magic_enum::customize requires customize_t type."); - if constexpr (custom.first == customize::detail::customize_tag::custom_tag) { - constexpr auto name = custom.second; - static_assert(!name.empty(), "magic_enum::customize requires not empty string."); - return static_str{name}; - } else if constexpr (custom.first == customize::detail::customize_tag::invalid_tag) { - return static_str<0>{}; - } else if constexpr (custom.first == customize::detail::customize_tag::default_tag) { - constexpr auto name = n(); - return static_str{name}; - } else { - static_assert(always_false_v, "magic_enum::customize invalid."); - } -} - -template -inline constexpr auto type_name_v = type_name(); - -template -constexpr auto n() noexcept { - static_assert(is_enum_v, "magic_enum::detail::n requires enum type."); - - if constexpr (supported::value) { -#if defined(MAGIC_ENUM_GET_ENUM_NAME_BUILTIN) - constexpr auto name_ptr = MAGIC_ENUM_GET_ENUM_NAME_BUILTIN(V); - auto name = name_ptr ? str_view{name_ptr, std::char_traits::length(name_ptr)} : str_view{}; -#elif defined(__clang__) - str_view name; - if constexpr (sizeof(__PRETTY_FUNCTION__) == sizeof(__FUNCTION__)) { - static_assert(always_false_v, "magic_enum::detail::n requires __PRETTY_FUNCTION__."); - return str_view{}; - } else { - name.size_ = sizeof(__PRETTY_FUNCTION__) - 36; - name.str_ = __PRETTY_FUNCTION__ + 34; - } - if (name.size_ > 22 && name.str_[0] == '(' && name.str_[1] == 'a' && name.str_[10] == ' ' && name.str_[22] == ':') { - name.size_ -= 23; - name.str_ += 23; - } - if (name.str_[0] == '(' || name.str_[0] == '-' || (name.str_[0] >= '0' && name.str_[0] <= '9')) { - name = str_view{}; - } -#elif defined(__GNUC__) - auto name = str_view{__PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__) - 1}; - if constexpr (sizeof(__PRETTY_FUNCTION__) == sizeof(__FUNCTION__)) { - static_assert(always_false_v, "magic_enum::detail::n requires __PRETTY_FUNCTION__."); - return str_view{}; - } else if (name.str_[name.size_ - 1] == ']') { - name.size_ -= 55; - name.str_ += 54; - } else { - name.size_ -= 40; - name.str_ += 37; - } - if (name.str_[0] == '(') { - name = str_view{}; - } -#elif defined(_MSC_VER) - str_view name; - if ((__FUNCSIG__[5] == '_' && __FUNCSIG__[35] != '(') || (__FUNCSIG__[5] == 'c' && __FUNCSIG__[41] != '(')) { - // CLI/C++ workaround (see https://github.com/Neargye/magic_enum/issues/284). - name.str_ = __FUNCSIG__; - name.str_ += 35; - name.size_ = sizeof(__FUNCSIG__) - 52; - } -#else - auto name = str_view{}; -#endif - std::size_t p = 0; - for (std::size_t i = name.size_; i > 0; --i) { - if (name.str_[i] == ':') { - p = i + 1; - break; - } - } - if (p > 0) { - name.size_ -= p; - name.str_ += p; - } - return name; - } else { - return str_view{}; // Unsupported compiler or Invalid customize. - } -} - -#if defined(_MSC_VER) && !defined(__clang__) && _MSC_VER < 1920 -# define MAGIC_ENUM_VS_2017_WORKAROUND 1 -#endif - -#if defined(MAGIC_ENUM_VS_2017_WORKAROUND) -template -constexpr auto n() noexcept { - static_assert(is_enum_v, "magic_enum::detail::n requires enum type."); - -# if defined(MAGIC_ENUM_GET_ENUM_NAME_BUILTIN) - constexpr auto name_ptr = MAGIC_ENUM_GET_ENUM_NAME_BUILTIN(V); - auto name = name_ptr ? str_view{name_ptr, std::char_traits::length(name_ptr)} : str_view{}; -# else - // CLI/C++ workaround (see https://github.com/Neargye/magic_enum/issues/284). - str_view name; - name.str_ = __FUNCSIG__; - name.size_ = sizeof(__FUNCSIG__) - 17; - std::size_t p = 0; - for (std::size_t i = name.size_; i > 0; --i) { - if (name.str_[i] == ',' || name.str_[i] == ':') { - p = i + 1; - break; - } - } - if (p > 0) { - name.size_ -= p; - name.str_ += p; - } - if (name.str_[0] == '(' || name.str_[0] == '-' || (name.str_[0] >= '0' && name.str_[0] <= '9')) { - name = str_view{}; - } - return name; -# endif -} -#endif - -template -constexpr auto enum_name() noexcept { - [[maybe_unused]] constexpr auto custom = customize::enum_name(V); - static_assert(std::is_same_v, customize::customize_t>, "magic_enum::customize requires customize_t type."); - if constexpr (custom.first == customize::detail::customize_tag::custom_tag) { - constexpr auto name = custom.second; - static_assert(!name.empty(), "magic_enum::customize requires not empty string."); - return static_str{name}; - } else if constexpr (custom.first == customize::detail::customize_tag::invalid_tag) { - return static_str<0>{}; - } else if constexpr (custom.first == customize::detail::customize_tag::default_tag) { -#if defined(MAGIC_ENUM_VS_2017_WORKAROUND) - constexpr auto name = n(); -#else - constexpr auto name = n(); -#endif - return static_str{name}; - } else { - static_assert(always_false_v, "magic_enum::customize invalid."); - } -} - -template -inline constexpr auto enum_name_v = enum_name(); - -template -constexpr bool is_valid() noexcept { -#if defined(__clang__) && __clang_major__ >= 16 - // https://reviews.llvm.org/D130058, https://reviews.llvm.org/D131307 - constexpr E v = __builtin_bit_cast(E, V); -#else - constexpr E v = static_cast(V); -#endif - [[maybe_unused]] constexpr auto custom = customize::enum_name(v); - static_assert(std::is_same_v, customize::customize_t>, "magic_enum::customize requires customize_t type."); - if constexpr (custom.first == customize::detail::customize_tag::custom_tag) { - constexpr auto name = custom.second; - static_assert(!name.empty(), "magic_enum::customize requires not empty string."); - return name.size() != 0; - } else if constexpr (custom.first == customize::detail::customize_tag::default_tag) { -#if defined(MAGIC_ENUM_VS_2017_WORKAROUND) - return n().size_ != 0; -#else - return n().size_ != 0; -#endif - } else { - return false; - } -} - -enum class enum_subtype { - common, - flags -}; - -template > -constexpr U ualue(std::size_t i) noexcept { - if constexpr (std::is_same_v) { // bool special case - static_assert(O == 0, "magic_enum::detail::ualue requires valid offset."); - - return static_cast(i); - } else if constexpr (S == enum_subtype::flags) { - return static_cast(U{1} << static_cast(static_cast(i) + O)); - } else { - return static_cast(static_cast(i) + O); - } -} - -template > -constexpr E value(std::size_t i) noexcept { - return static_cast(ualue(i)); -} - -template > -constexpr int reflected_min() noexcept { - if constexpr (S == enum_subtype::flags) { - return 0; - } else { - constexpr auto lhs = range_min::value; - constexpr auto rhs = (std::numeric_limits::min)(); - - if constexpr (cmp_less(rhs, lhs)) { - return lhs; - } else { - return rhs; - } - } -} - -template > -constexpr int reflected_max() noexcept { - if constexpr (S == enum_subtype::flags) { - return std::numeric_limits::digits - 1; - } else { - constexpr auto lhs = range_max::value; - constexpr auto rhs = (std::numeric_limits::max)(); - - if constexpr (cmp_less(lhs, rhs)) { - return lhs; - } else { - return rhs; - } - } -} - -#define MAGIC_ENUM_FOR_EACH_256(T) \ - T( 0)T( 1)T( 2)T( 3)T( 4)T( 5)T( 6)T( 7)T( 8)T( 9)T( 10)T( 11)T( 12)T( 13)T( 14)T( 15)T( 16)T( 17)T( 18)T( 19)T( 20)T( 21)T( 22)T( 23)T( 24)T( 25)T( 26)T( 27)T( 28)T( 29)T( 30)T( 31) \ - T( 32)T( 33)T( 34)T( 35)T( 36)T( 37)T( 38)T( 39)T( 40)T( 41)T( 42)T( 43)T( 44)T( 45)T( 46)T( 47)T( 48)T( 49)T( 50)T( 51)T( 52)T( 53)T( 54)T( 55)T( 56)T( 57)T( 58)T( 59)T( 60)T( 61)T( 62)T( 63) \ - T( 64)T( 65)T( 66)T( 67)T( 68)T( 69)T( 70)T( 71)T( 72)T( 73)T( 74)T( 75)T( 76)T( 77)T( 78)T( 79)T( 80)T( 81)T( 82)T( 83)T( 84)T( 85)T( 86)T( 87)T( 88)T( 89)T( 90)T( 91)T( 92)T( 93)T( 94)T( 95) \ - T( 96)T( 97)T( 98)T( 99)T(100)T(101)T(102)T(103)T(104)T(105)T(106)T(107)T(108)T(109)T(110)T(111)T(112)T(113)T(114)T(115)T(116)T(117)T(118)T(119)T(120)T(121)T(122)T(123)T(124)T(125)T(126)T(127) \ - T(128)T(129)T(130)T(131)T(132)T(133)T(134)T(135)T(136)T(137)T(138)T(139)T(140)T(141)T(142)T(143)T(144)T(145)T(146)T(147)T(148)T(149)T(150)T(151)T(152)T(153)T(154)T(155)T(156)T(157)T(158)T(159) \ - T(160)T(161)T(162)T(163)T(164)T(165)T(166)T(167)T(168)T(169)T(170)T(171)T(172)T(173)T(174)T(175)T(176)T(177)T(178)T(179)T(180)T(181)T(182)T(183)T(184)T(185)T(186)T(187)T(188)T(189)T(190)T(191) \ - T(192)T(193)T(194)T(195)T(196)T(197)T(198)T(199)T(200)T(201)T(202)T(203)T(204)T(205)T(206)T(207)T(208)T(209)T(210)T(211)T(212)T(213)T(214)T(215)T(216)T(217)T(218)T(219)T(220)T(221)T(222)T(223) \ - T(224)T(225)T(226)T(227)T(228)T(229)T(230)T(231)T(232)T(233)T(234)T(235)T(236)T(237)T(238)T(239)T(240)T(241)T(242)T(243)T(244)T(245)T(246)T(247)T(248)T(249)T(250)T(251)T(252)T(253)T(254)T(255) - -template -constexpr void valid_count(bool* valid, std::size_t& count) noexcept { -#define MAGIC_ENUM_V(O) \ - if constexpr ((I + O) < Size) { \ - if constexpr (is_valid(I + O)>()) { \ - valid[I + O] = true; \ - ++count; \ - } \ - } - - MAGIC_ENUM_FOR_EACH_256(MAGIC_ENUM_V) - - if constexpr ((I + 256) < Size) { - valid_count(valid, count); - } -#undef MAGIC_ENUM_V -} - -template -struct valid_count_t { - std::size_t count = 0; - bool valid[N] = {}; -}; - -template -constexpr auto valid_count() noexcept { - valid_count_t vc; - valid_count(vc.valid, vc.count); - return vc; -} - -template -constexpr auto values() noexcept { - constexpr auto vc = valid_count(); - - if constexpr (vc.count > 0) { -#if defined(MAGIC_ENUM_ARRAY_CONSTEXPR) - std::array values = {}; -#else - E values[vc.count] = {}; -#endif - for (std::size_t i = 0, v = 0; v < vc.count; ++i) { - if (vc.valid[i]) { - values[v++] = value(i); - } - } -#if defined(MAGIC_ENUM_ARRAY_CONSTEXPR) - return values; -#else - return to_array(values, std::make_index_sequence{}); -#endif - } else { - return std::array{}; - } -} - -template > -constexpr auto values() noexcept { - constexpr auto min = reflected_min(); - constexpr auto max = reflected_max(); - constexpr auto range_size = max - min + 1; - static_assert(range_size > 0, "magic_enum::enum_range requires valid size."); - - return values(); -} - -template > -constexpr enum_subtype subtype(std::true_type) noexcept { - if constexpr (std::is_same_v) { // bool special case - return enum_subtype::common; - } else if constexpr (has_is_flags::value) { - return customize::enum_range::is_flags ? enum_subtype::flags : enum_subtype::common; - } else { -#if defined(MAGIC_ENUM_AUTO_IS_FLAGS) - constexpr auto flags_values = values(); - constexpr auto default_values = values(); - if (flags_values.size() == 0 || default_values.size() > flags_values.size()) { - return enum_subtype::common; - } - for (std::size_t i = 0; i < default_values.size(); ++i) { - const auto v = static_cast(default_values[i]); - if (v != 0 && (v & (v - 1)) != 0) { - return enum_subtype::common; - } - } - return enum_subtype::flags; -#else - return enum_subtype::common; -#endif - } -} - -template -constexpr enum_subtype subtype(std::false_type) noexcept { - // For non-enum type return default common subtype. - return enum_subtype::common; -} - -template > -inline constexpr auto subtype_v = subtype(std::is_enum{}); - -template -inline constexpr auto values_v = values(); - -template > -using values_t = decltype((values_v)); - -template -inline constexpr auto count_v = values_v.size(); - -template > -inline constexpr auto min_v = (count_v > 0) ? static_cast(values_v.front()) : U{0}; - -template > -inline constexpr auto max_v = (count_v > 0) ? static_cast(values_v.back()) : U{0}; - -template -constexpr auto names(std::index_sequence) noexcept { - constexpr auto names = std::array{{enum_name_v[I]>...}}; - return names; -} - -template -inline constexpr auto names_v = names(std::make_index_sequence>{}); - -template > -using names_t = decltype((names_v)); - -template -constexpr auto entries(std::index_sequence) noexcept { - constexpr auto entries = std::array, sizeof...(I)>{{{values_v[I], enum_name_v[I]>}...}}; - return entries; -} - -template -inline constexpr auto entries_v = entries(std::make_index_sequence>{}); - -template > -using entries_t = decltype((entries_v)); - -template > -constexpr bool is_sparse() noexcept { - if constexpr (count_v == 0) { - return false; - } else if constexpr (std::is_same_v) { // bool special case - return false; - } else { - constexpr auto max = (S == enum_subtype::flags) ? log2(max_v) : max_v; - constexpr auto min = (S == enum_subtype::flags) ? log2(min_v) : min_v; - constexpr auto range_size = max - min + 1; - - return range_size != count_v; - } -} - -template > -inline constexpr bool is_sparse_v = is_sparse(); - -template -struct is_reflected -#if defined(MAGIC_ENUM_NO_CHECK_REFLECTED_ENUM) - : std::true_type {}; -#else - : std::bool_constant && (count_v != 0)> {}; -#endif - -template -inline constexpr bool is_reflected_v = is_reflected, S>{}; - -template -struct enable_if_enum {}; - -template -struct enable_if_enum { - using type = R; - static_assert(supported::value, "magic_enum unsupported compiler (https://github.com/Neargye/magic_enum#compiler-compatibility)."); -}; - -template , typename D = std::decay_t> -using enable_if_t = typename enable_if_enum && std::is_invocable_r_v, R>::type; - -template >, int> = 0> -using enum_concept = T; - -template > -struct is_scoped_enum : std::false_type {}; - -template -struct is_scoped_enum : std::bool_constant>> {}; - -template > -struct is_unscoped_enum : std::false_type {}; - -template -struct is_unscoped_enum : std::bool_constant>> {}; - -template >> -struct underlying_type {}; - -template -struct underlying_type : std::underlying_type> {}; - -#if defined(MAGIC_ENUM_ENABLE_HASH) || defined(MAGIC_ENUM_ENABLE_HASH_SWITCH) - -template -struct constexpr_hash_t; - -template -struct constexpr_hash_t>> { - constexpr auto operator()(Value value) const noexcept { - using U = typename underlying_type::type; - if constexpr (std::is_same_v) { // bool special case - return static_cast(value); - } else { - return static_cast(value); - } - } - using secondary_hash = constexpr_hash_t; -}; - -template -struct constexpr_hash_t>> { - static constexpr std::uint32_t crc_table[256] { - 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L, - 0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L, - 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, - 0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L, - 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, - 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, - 0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 0xb8bda50fL, - 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, - 0x76dc4190L, 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L, - 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, - 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, - 0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L, - 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, - 0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L, - 0x5005713cL, 0x270241aaL, 0xbe0b1010L, 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, - 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, - 0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, 0x73dc1683L, - 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, - 0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, 0x196c3671L, 0x6e6b06e7L, - 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, - 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, - 0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 0x4669be79L, - 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, - 0xc5ba3bbeL, 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL, - 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, - 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, - 0x86d3d2d4L, 0xf1d4e242L, 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 0x18b74777L, - 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, - 0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL, - 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, - 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL, - 0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL - }; - constexpr std::uint32_t operator()(string_view value) const noexcept { - auto crc = static_cast(0xffffffffL); - for (const auto c : value) { - crc = (crc >> 8) ^ crc_table[(crc ^ static_cast(c)) & 0xff]; - } - return crc ^ 0xffffffffL; - } - - struct secondary_hash { - constexpr std::uint32_t operator()(string_view value) const noexcept { - auto acc = static_cast(2166136261ULL); - for (const auto c : value) { - acc = ((acc ^ static_cast(c)) * static_cast(16777619ULL)) & (std::numeric_limits::max)(); - } - return static_cast(acc); - } - }; -}; - -template -inline constexpr Hash hash_v{}; - -template -constexpr auto calculate_cases(std::size_t Page) noexcept { - constexpr std::array values = *GlobValues; - constexpr std::size_t size = values.size(); - - using switch_t = std::invoke_result_t; - static_assert(std::is_integral_v && !std::is_same_v); - const std::size_t values_to = (std::min)(static_cast(256), size - Page); - - std::array result{}; - auto fill = result.begin(); - { - auto first = values.begin() + static_cast(Page); - auto last = values.begin() + static_cast(Page + values_to); - while (first != last) { - *fill++ = hash_v(*first++); - } - } - - // dead cases, try to avoid case collisions - for (switch_t last_value = result[values_to - 1]; fill != result.end() && last_value != (std::numeric_limits::max)(); *fill++ = ++last_value) { - } - - { - auto it = result.begin(); - auto last_value = (std::numeric_limits::min)(); - for (; fill != result.end(); *fill++ = last_value++) { - while (last_value == *it) { - ++last_value, ++it; - } - } - } - - return result; -} - -template -constexpr R invoke_r(F&& f, Args&&... args) noexcept(std::is_nothrow_invocable_r_v) { - if constexpr (std::is_void_v) { - std::forward(f)(std::forward(args)...); - } else { - return static_cast(std::forward(f)(std::forward(args)...)); - } -} - -enum class case_call_t { - index, - value -}; - -template -inline constexpr auto default_result_type_lambda = []() noexcept(std::is_nothrow_default_constructible_v) { return T{}; }; - -template <> -inline constexpr auto default_result_type_lambda = []() noexcept {}; - -template -constexpr bool has_duplicate() noexcept { - using value_t = std::decay_t; - using hash_value_t = std::invoke_result_t; - std::arraysize()> hashes{}; - std::size_t size = 0; - for (auto elem : *Arr) { - hashes[size] = hash_v(elem); - for (auto i = size++; i > 0; --i) { - if (hashes[i] < hashes[i - 1]) { - auto tmp = hashes[i]; - hashes[i] = hashes[i - 1]; - hashes[i - 1] = tmp; - } else if (hashes[i] == hashes[i - 1]) { - return false; - } else { - break; - } - } - } - return true; -} - -#define MAGIC_ENUM_CASE(val) \ - case cases[val]: \ - if constexpr ((val) + Page < size) { \ - if (!pred(values[val + Page], searched)) { \ - break; \ - } \ - if constexpr (CallValue == case_call_t::index) { \ - if constexpr (std::is_invocable_r_v>) { \ - return detail::invoke_r(std::forward(lambda), std::integral_constant{}); \ - } else if constexpr (std::is_invocable_v>) { \ - MAGIC_ENUM_ASSERT(false && "magic_enum::detail::constexpr_switch wrong result type."); \ - } \ - } else if constexpr (CallValue == case_call_t::value) { \ - if constexpr (std::is_invocable_r_v>) { \ - return detail::invoke_r(std::forward(lambda), enum_constant{}); \ - } else if constexpr (std::is_invocable_r_v>) { \ - MAGIC_ENUM_ASSERT(false && "magic_enum::detail::constexpr_switch wrong result type."); \ - } \ - } \ - break; \ - } else [[fallthrough]]; - -template ::value_type>, - typename BinaryPredicate = std::equal_to<>, - typename Lambda, - typename ResultGetterType> -constexpr decltype(auto) constexpr_switch( - Lambda&& lambda, - typename std::decay_t::value_type searched, - ResultGetterType&& def, - BinaryPredicate&& pred = {}) { - using result_t = std::invoke_result_t; - using hash_t = std::conditional_t(), Hash, typename Hash::secondary_hash>; - static_assert(has_duplicate(), "magic_enum::detail::constexpr_switch duplicated hash found, please report it: https://github.com/Neargye/magic_enum/issues."); - constexpr std::array values = *GlobValues; - constexpr std::size_t size = values.size(); - constexpr std::array cases = calculate_cases(Page); - - switch (hash_v(searched)) { - MAGIC_ENUM_FOR_EACH_256(MAGIC_ENUM_CASE) - default: - if constexpr (size > 256 + Page) { - return constexpr_switch(std::forward(lambda), searched, std::forward(def)); - } - break; - } - return def(); -} - -#undef MAGIC_ENUM_CASE - -#endif - -} // namespace magic_enum::detail - -// Checks is magic_enum supported compiler. -inline constexpr bool is_magic_enum_supported = detail::supported::value; - -template -using Enum = detail::enum_concept; - -// Checks whether T is an Unscoped enumeration type. -// Provides the member constant value which is equal to true, if T is an [Unscoped enumeration](https://en.cppreference.com/w/cpp/language/enum#Unscoped_enumeration) type. Otherwise, value is equal to false. -template -struct is_unscoped_enum : detail::is_unscoped_enum {}; - -template -inline constexpr bool is_unscoped_enum_v = is_unscoped_enum::value; - -// Checks whether T is an Scoped enumeration type. -// Provides the member constant value which is equal to true, if T is an [Scoped enumeration](https://en.cppreference.com/w/cpp/language/enum#Scoped_enumerations) type. Otherwise, value is equal to false. -template -struct is_scoped_enum : detail::is_scoped_enum {}; - -template -inline constexpr bool is_scoped_enum_v = is_scoped_enum::value; - -// If T is a complete enumeration type, provides a member typedef type that names the underlying type of T. -// Otherwise, if T is not an enumeration type, there is no member type. Otherwise (T is an incomplete enumeration type), the program is ill-formed. -template -struct underlying_type : detail::underlying_type {}; - -template -using underlying_type_t = typename underlying_type::type; - -template -using enum_constant = detail::enum_constant; - -// Returns type name of enum. -template -[[nodiscard]] constexpr auto enum_type_name() noexcept -> detail::enable_if_t { - constexpr string_view name = detail::type_name_v>; - static_assert(!name.empty(), "magic_enum::enum_type_name enum type does not have a name."); - - return name; -} - -// Returns number of enum values. -template > -[[nodiscard]] constexpr auto enum_count() noexcept -> detail::enable_if_t { - return detail::count_v, S>; -} - -// Returns enum value at specified index. -// No bounds checking is performed: the behavior is undefined if index >= number of enum values. -template > -[[nodiscard]] constexpr auto enum_value(std::size_t index) noexcept -> detail::enable_if_t> { - using D = std::decay_t; - static_assert(detail::is_reflected_v, "magic_enum requires enum implementation and valid max and min."); - - if constexpr (detail::is_sparse_v) { - return MAGIC_ENUM_ASSERT(index < detail::count_v), detail::values_v[index]; - } else { - constexpr auto min = (S == detail::enum_subtype::flags) ? detail::log2(detail::min_v) : detail::min_v; - - return MAGIC_ENUM_ASSERT(index < detail::count_v), detail::value(index); - } -} - -// Returns enum value at specified index. -template > -[[nodiscard]] constexpr auto enum_value() noexcept -> detail::enable_if_t> { - using D = std::decay_t; - static_assert(detail::is_reflected_v, "magic_enum requires enum implementation and valid max and min."); - static_assert(I < detail::count_v, "magic_enum::enum_value out of range."); - - return enum_value(I); -} - -// Returns std::array with enum values, sorted by enum value. -template > -[[nodiscard]] constexpr auto enum_values() noexcept -> detail::enable_if_t> { - using D = std::decay_t; - static_assert(detail::is_reflected_v, "magic_enum requires enum implementation and valid max and min."); - - return detail::values_v; -} - -// Returns integer value from enum value. -template -[[nodiscard]] constexpr auto enum_integer(E value) noexcept -> detail::enable_if_t> { - return static_cast>(value); -} - -// Returns underlying value from enum value. -template -[[nodiscard]] constexpr auto enum_underlying(E value) noexcept -> detail::enable_if_t> { - return static_cast>(value); -} - -// Obtains index in enum values from enum value. -// Returns optional with index. -template > -[[nodiscard]] constexpr auto enum_index(E value) noexcept -> detail::enable_if_t> { - using D = std::decay_t; - using U = underlying_type_t; - static_assert(detail::is_reflected_v, "magic_enum requires enum implementation and valid max and min."); - - if constexpr (detail::is_sparse_v || (S == detail::enum_subtype::flags)) { -#if defined(MAGIC_ENUM_ENABLE_HASH) - return detail::constexpr_switch<&detail::values_v, detail::case_call_t::index>( - [](std::size_t i) { return optional{i}; }, - value, - detail::default_result_type_lambda>); -#else - for (std::size_t i = 0; i < detail::count_v; ++i) { - if (enum_value(i) == value) { - return i; - } - } - return {}; // Invalid value or out of range. -#endif - } else { - const auto v = static_cast(value); - if (v >= detail::min_v && v <= detail::max_v) { - return static_cast(v - detail::min_v); - } - return {}; // Invalid value or out of range. - } -} - -// Obtains index in enum values from enum value. -// Returns optional with index. -template -[[nodiscard]] constexpr auto enum_index(E value) noexcept -> detail::enable_if_t> { - using D = std::decay_t; - static_assert(detail::is_reflected_v, "magic_enum requires enum implementation and valid max and min."); - - return enum_index(value); -} - -// Obtains index in enum values from static storage enum variable. -template >> -[[nodiscard]] constexpr auto enum_index() noexcept -> detail::enable_if_t {\ - using D = std::decay_t; - static_assert(detail::is_reflected_v, "magic_enum requires enum implementation and valid max and min."); - constexpr auto index = enum_index(V); - static_assert(index, "magic_enum::enum_index enum value does not have a index."); - - return *index; -} - -// Returns name from static storage enum variable. -// This version is much lighter on the compile times and is not restricted to the enum_range limitation. -template -[[nodiscard]] constexpr auto enum_name() noexcept -> detail::enable_if_t { - constexpr string_view name = detail::enum_name_v, V>; - static_assert(!name.empty(), "magic_enum::enum_name enum value does not have a name."); - - return name; -} - -// Returns name from enum value. -// If enum value does not have name or value out of range, returns empty string. -template > -[[nodiscard]] constexpr auto enum_name(E value) noexcept -> detail::enable_if_t { - using D = std::decay_t; - static_assert(detail::is_reflected_v, "magic_enum requires enum implementation and valid max and min."); - - if (const auto i = enum_index(value)) { - return detail::names_v[*i]; - } - return {}; -} - -// Returns name from enum value. -// If enum value does not have name or value out of range, returns empty string. -template -[[nodiscard]] constexpr auto enum_name(E value) -> detail::enable_if_t { - using D = std::decay_t; - static_assert(detail::is_reflected_v, "magic_enum requires enum implementation and valid max and min."); - - return enum_name(value); -} - -// Returns std::array with names, sorted by enum value. -template > -[[nodiscard]] constexpr auto enum_names() noexcept -> detail::enable_if_t> { - using D = std::decay_t; - static_assert(detail::is_reflected_v, "magic_enum requires enum implementation and valid max and min."); - - return detail::names_v; -} - -// Returns std::array with pairs (value, name), sorted by enum value. -template > -[[nodiscard]] constexpr auto enum_entries() noexcept -> detail::enable_if_t> { - using D = std::decay_t; - static_assert(detail::is_reflected_v, "magic_enum requires enum implementation and valid max and min."); - - return detail::entries_v; -} - -// Allows you to write magic_enum::enum_cast("bar", magic_enum::case_insensitive); -inline constexpr auto case_insensitive = detail::case_insensitive<>{}; - -// Obtains enum value from integer value. -// Returns optional with enum value. -template > -[[nodiscard]] constexpr auto enum_cast(underlying_type_t value) noexcept -> detail::enable_if_t>> { - using D = std::decay_t; - static_assert(detail::is_reflected_v, "magic_enum requires enum implementation and valid max and min."); - - if constexpr (detail::is_sparse_v || (S == detail::enum_subtype::flags)) { -#if defined(MAGIC_ENUM_ENABLE_HASH) - return detail::constexpr_switch<&detail::values_v, detail::case_call_t::value>( - [](D v) { return optional{v}; }, - static_cast(value), - detail::default_result_type_lambda>); -#else - for (std::size_t i = 0; i < detail::count_v; ++i) { - if (value == static_cast>(enum_value(i))) { - return static_cast(value); - } - } - return {}; // Invalid value or out of range. -#endif - } else { - if (value >= detail::min_v && value <= detail::max_v) { - return static_cast(value); - } - return {}; // Invalid value or out of range. - } -} - -// Obtains enum value from name. -// Returns optional with enum value. -template , typename BinaryPredicate = std::equal_to<>> -[[nodiscard]] constexpr auto enum_cast(string_view value, [[maybe_unused]] BinaryPredicate p = {}) noexcept(detail::is_nothrow_invocable()) -> detail::enable_if_t>, BinaryPredicate> { - using D = std::decay_t; - static_assert(detail::is_reflected_v, "magic_enum requires enum implementation and valid max and min."); - -#if defined(MAGIC_ENUM_ENABLE_HASH) - if constexpr (detail::is_default_predicate()) { - return detail::constexpr_switch<&detail::names_v, detail::case_call_t::index>( - [](std::size_t i) { return optional{detail::values_v[i]}; }, - value, - detail::default_result_type_lambda>, - [&p](string_view lhs, string_view rhs) { return detail::cmp_equal(lhs, rhs, p); }); - } -#endif - for (std::size_t i = 0; i < detail::count_v; ++i) { - if (detail::cmp_equal(value, detail::names_v[i], p)) { - return enum_value(i); - } - } - return {}; // Invalid value or out of range. -} - -// Checks whether enum contains value with such value. -template > -[[nodiscard]] constexpr auto enum_contains(E value) noexcept -> detail::enable_if_t { - using D = std::decay_t; - using U = underlying_type_t; - - return static_cast(enum_cast(static_cast(value))); -} - -// Checks whether enum contains value with such value. -template -[[nodiscard]] constexpr auto enum_contains(E value) noexcept -> detail::enable_if_t { - using D = std::decay_t; - using U = underlying_type_t; - - return static_cast(enum_cast(static_cast(value))); -} - -// Checks whether enum contains value with such integer value. -template > -[[nodiscard]] constexpr auto enum_contains(underlying_type_t value) noexcept -> detail::enable_if_t { - using D = std::decay_t; - - return static_cast(enum_cast(value)); -} - -// Checks whether enum contains enumerator with such name. -template , typename BinaryPredicate = std::equal_to<>> -[[nodiscard]] constexpr auto enum_contains(string_view value, BinaryPredicate p = {}) noexcept(detail::is_nothrow_invocable()) -> detail::enable_if_t { - using D = std::decay_t; - - return static_cast(enum_cast(value, std::move(p))); -} - -template -inline constexpr auto as_flags = AsFlags ? detail::enum_subtype::flags : detail::enum_subtype::common; - -template -inline constexpr auto as_common = AsFlags ? detail::enum_subtype::common : detail::enum_subtype::flags; - -namespace bitwise_operators { - -template = 0> -constexpr E operator~(E rhs) noexcept { - return static_cast(~static_cast>(rhs)); -} - -template = 0> -constexpr E operator|(E lhs, E rhs) noexcept { - return static_cast(static_cast>(lhs) | static_cast>(rhs)); -} - -template = 0> -constexpr E operator&(E lhs, E rhs) noexcept { - return static_cast(static_cast>(lhs) & static_cast>(rhs)); -} - -template = 0> -constexpr E operator^(E lhs, E rhs) noexcept { - return static_cast(static_cast>(lhs) ^ static_cast>(rhs)); -} - -template = 0> -constexpr E& operator|=(E& lhs, E rhs) noexcept { - return lhs = (lhs | rhs); -} - -template = 0> -constexpr E& operator&=(E& lhs, E rhs) noexcept { - return lhs = (lhs & rhs); -} - -template = 0> -constexpr E& operator^=(E& lhs, E rhs) noexcept { - return lhs = (lhs ^ rhs); -} - -} // namespace magic_enum::bitwise_operators - -} // namespace magic_enum - -#if defined(__clang__) -# pragma clang diagnostic pop -#elif defined(__GNUC__) -# pragma GCC diagnostic pop -#elif defined(_MSC_VER) -# pragma warning(pop) -#endif - -#undef MAGIC_ENUM_GET_ENUM_NAME_BUILTIN -#undef MAGIC_ENUM_GET_TYPE_NAME_BUILTIN -#undef MAGIC_ENUM_VS_2017_WORKAROUND -#undef MAGIC_ENUM_ARRAY_CONSTEXPR -#undef MAGIC_ENUM_FOR_EACH_256 - -#endif // NEARGYE_MAGIC_ENUM_HPP diff --git a/src/test/app/ClaimReward_test.cpp b/src/test/app/ClaimReward_test.cpp index b23b29fc7..d33e68aa2 100644 --- a/src/test/app/ClaimReward_test.cpp +++ b/src/test/app/ClaimReward_test.cpp @@ -18,6 +18,7 @@ //============================================================================== #include +#include #include #include #include @@ -300,6 +301,28 @@ struct ClaimReward_test : public beast::unit_test::suite env(tx, reward::issuer(issuer), ter(tecNO_ISSUER)); env.close(); } + + // tecNO_PERMISSION + // issuer is an AMM account + { + test::jtx::Env env{*this, network::makeNetworkConfig(21337)}; + + auto const alice = Account("alice"); + auto const issuer = Account("issuer"); + auto const USD = issuer["USD"]; + + env.fund(XRP(1000), alice, issuer); + env.close(); + + AMM amm(env, issuer, XRP(100), USD(100)); + + BEAST_EXPECT(amm.ammExists()); + + env(reward::claim(alice), + reward::issuer(amm.ammAccount()), + ter(tecNO_PERMISSION)); + env.close(); + } } void diff --git a/src/test/app/Import_test.cpp b/src/test/app/Import_test.cpp index 1a65de486..96dbddfe5 100644 --- a/src/test/app/Import_test.cpp +++ b/src/test/app/Import_test.cpp @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -2635,6 +2636,77 @@ class Import_test : public beast::unit_test::suite ter(temDISABLED)); } + // tecNO_ISSUER, tecNO_PERMISSION + // issuer not found, issuer is an AMM account + { + auto const alice = Account("alice"); + auto const bob = Account("bob"); + auto const issuer = Account("issuer"); + auto const USD = issuer["USD"]; + + for (bool const withFixImportIssuer : {true, false}) + { + auto const amend = + withFixImportIssuer ? features : features - fixImportIssuer; + test::jtx::Env env{ + *this, network::makeNetworkVLConfig(21337, keys), amend}; + env.fund(XRP(1000), alice, issuer); + env.close(); + + // burn 10'000 xrp + auto const master = Account("masterpassphrase"); + env(noop(master), fee(10'000'000'000), ter(tesSUCCESS)); + env.close(); + + env(import::import( + alice, import::loadXpop(ImportTCAccountSet::w_seed)), + import::issuer(bob), + fee(100'000'000), + withFixImportIssuer ? ter(tecNO_ISSUER) : ter(tesSUCCESS)); + env.close(); + } + for (bool const withFixImportIssuer : {true, false}) + { + auto const amend = + withFixImportIssuer ? features : features - fixImportIssuer; + test::jtx::Env env{ + *this, network::makeNetworkVLConfig(21337, keys), amend}; + env.fund(XRP(1000), alice, issuer); + env.close(); + + // burn 10'000 xrp + auto const master = Account("masterpassphrase"); + env(noop(master), fee(10'000'000'000), ter(tesSUCCESS)); + env.close(); + + AMM amm(env, issuer, XRP(100), USD(100)); + BEAST_EXPECT(amm.ammExists()); + + env(import::import( + alice, import::loadXpop(ImportTCAccountSet::w_seed)), + import::issuer(amm.ammAccount()), + fee(100'000'000), + withFixImportIssuer ? ter(tecNO_PERMISSION) + : ter(tesSUCCESS)); + env.close(); + } + + // env.enableFeature(fixImportIssuer); + // env.close(); + + // env(import::import( + // carol, import::loadXpop(ImportTCAccountSet::w_seed)), + // import::issuer(bob), + // ter(tecNO_ISSUER)); + // env.close(); + // env(import::import( + // dave, import::loadXpop(ImportTCAccountSet::w_seed)), + // import::issuer(amm.ammAccount()), + // // fee(100'000'000), + // ter(tecNO_PERMISSION)); + // env.close(); + } + // tefINTERNAL // during preclaim could not parse xpop, bailing. { diff --git a/src/test/app/Invoke_test.cpp b/src/test/app/Invoke_test.cpp index 3c322532c..703237fe5 100644 --- a/src/test/app/Invoke_test.cpp +++ b/src/test/app/Invoke_test.cpp @@ -18,6 +18,7 @@ //============================================================================== #include +#include #include namespace ripple { @@ -168,6 +169,27 @@ class Invoke_test : public beast::unit_test::suite fee(feeDrops), ter(tecNO_TARGET)); } + + // tecNO_PERMISSION + // issuer is an AMM account + { + test::jtx::Env env{*this, network::makeNetworkConfig(21337)}; + + auto const alice = Account("alice"); + auto const issuer = Account("issuer"); + auto const USD = issuer["USD"]; + env.fund(XRP(1000), alice, issuer); + env.close(); + + AMM amm(env, issuer, XRP(100), USD(100)); + + BEAST_EXPECT(amm.ammExists()); + + env(invoke::invoke(alice), + invoke::dest(amm.ammAccount()), + ter(tecNO_PERMISSION)); + env.close(); + } } void diff --git a/src/test/app/Path_test.cpp b/src/test/app/Path_test.cpp index 1db15388f..ae7018947 100644 --- a/src/test/app/Path_test.cpp +++ b/src/test/app/Path_test.cpp @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include #include #include @@ -573,6 +575,164 @@ public: BEAST_EXPECT(equal(sa, Account("alice")["USD"](5))); } + Json::Value + six_path_append_request_result() + { + using namespace jtx; + Env env = pathTestEnv(); + + Account A1{"A1"}; + Account A2{"A2"}; + Account G1{"G1"}; + Account G2{"G2"}; + Account M1{"M1"}; + Account M2{"M2"}; + Account M3{"M3"}; + Account M4{"M4"}; + Account M5{"M5"}; + Account M6{"M6"}; + Account MM{"MM"}; + + env.fund(XRP(1000), A1, A2, G1, G2, M1, M2, M3, M4, M5, M6, MM); + env.close(); + + env.trust(G1["HKD"](2000), A1); + env.trust(G2["HKD"](2000), A2); + + env.trust(G1["HKD"](100000), M1, M2, M3, M4, M5, M6, MM); + env.trust(G2["HKD"](100000), M1, M2, M3, M4, M5, M6, MM); + env.close(); + + env(pay(G1, A1, G1["HKD"](1000))); + + env(pay(G1, M1, G1["HKD"](10))); + env(pay(G1, M2, G1["HKD"](10))); + env(pay(G1, M3, G1["HKD"](10))); + env(pay(G1, M4, G1["HKD"](10))); + env(pay(G1, M5, G1["HKD"](10))); + env(pay(G1, M6, G1["HKD"](10))); + env(pay(G1, MM, G1["HKD"](1000))); + + env(pay(G2, M1, G2["HKD"](10))); + env(pay(G2, M2, G2["HKD"](10))); + env(pay(G2, M3, G2["HKD"](10))); + env(pay(G2, M4, G2["HKD"](10))); + env(pay(G2, M5, G2["HKD"](10))); + env(pay(G2, M6, G2["HKD"](10))); + env(pay(G2, MM, G2["HKD"](1000))); + env.close(); + + env(offer(MM, G1["HKD"](1000), G2["HKD"](100))); + env.close(); + + return find_paths_request( + env, A1, A2, A2["HKD"](60), std::nullopt, G1["HKD"].currency); + } + + void + pathfind_paths_computed_never_exceeds_six() + { + testcase("pathfind paths_computed never exceeds six"); + + auto const result = six_path_append_request_result(); + BEAST_EXPECT(result.isMember(jss::alternatives)); + if (!result.isMember(jss::alternatives)) + return; + + BEAST_EXPECT(result[jss::alternatives].isArray()); + if (!result[jss::alternatives].isArray()) + return; + + bool sawPathsComputed = false; + for (auto const& alt : result[jss::alternatives]) + { + if (!alt.isMember(jss::paths_computed)) + continue; + sawPathsComputed = true; + BEAST_EXPECT(alt[jss::paths_computed].isArray()); + if (alt[jss::paths_computed].isArray()) + BEAST_EXPECT(alt[jss::paths_computed].size() <= 6); + } + BEAST_EXPECT(sawPathsComputed); + } + + void + pathfind_can_return_six_paths_with_append() + { + testcase("pathfind can return six paths with append"); + using namespace jtx; + Env env = pathTestEnv(); + + Account A1{"A1"}; + Account A2{"A2"}; + Account G1{"G1"}; + Account G2{"G2"}; + Account M1{"M1"}; + Account M2{"M2"}; + Account M3{"M3"}; + Account M4{"M4"}; + Account M5{"M5"}; + Account M6{"M6"}; + Account MM{"MM"}; + + env.fund(XRP(1000), A1, A2, G1, G2, M1, M2, M3, M4, M5, M6, MM); + env.close(); + + env.trust(G1["HKD"](2000), A1); + env.trust(G2["HKD"](2000), A2); + + env.trust(G1["HKD"](100000), M1, M2, M3, M4, M5, M6, MM); + env.trust(G2["HKD"](100000), M1, M2, M3, M4, M5, M6, MM); + env.close(); + + env(pay(G1, A1, G1["HKD"](1000))); + + env(pay(G1, M1, G1["HKD"](10))); + env(pay(G1, M2, G1["HKD"](10))); + env(pay(G1, M3, G1["HKD"](10))); + env(pay(G1, M4, G1["HKD"](10))); + env(pay(G1, M5, G1["HKD"](10))); + env(pay(G1, M6, G1["HKD"](10))); + env(pay(G1, MM, G1["HKD"](1000))); + + env(pay(G2, M1, G2["HKD"](10))); + env(pay(G2, M2, G2["HKD"](10))); + env(pay(G2, M3, G2["HKD"](10))); + env(pay(G2, M4, G2["HKD"](10))); + env(pay(G2, M5, G2["HKD"](10))); + env(pay(G2, M6, G2["HKD"](10))); + env(pay(G2, MM, G2["HKD"](1000))); + env.close(); + + env(offer(MM, G1["HKD"](1000), G2["HKD"](100))); + env.close(); + + auto cache = std::make_shared( + env.current(), env.app().journal("RippleLineCache")); + Pathfinder pf( + cache, + A1.id(), + A2.id(), + G1["HKD"].currency, + std::nullopt, + A2["HKD"](60), + std::nullopt, + env.app()); + + BEAST_EXPECT(pf.findPaths(7)); + pf.computePathRanks(5); + + STPath fullLiquidityPath; + auto bestPaths = + pf.getBestPaths(5, fullLiquidityPath, STPathSet{}, A1.id()); + BEAST_EXPECT(bestPaths.size() == 5); + BEAST_EXPECT(!fullLiquidityPath.empty()); + + if (!fullLiquidityPath.empty()) + bestPaths.push_back(fullLiquidityPath); + BEAST_EXPECT(bestPaths.size() == 6); + } + void issues_path_negative_issue() { @@ -1381,6 +1541,8 @@ public: path_find_04(); path_find_05(); path_find_06(); + pathfind_paths_computed_never_exceeds_six(); + pathfind_can_return_six_paths_with_append(); } }; diff --git a/src/test/app/Remit_test.cpp b/src/test/app/Remit_test.cpp index b8b298a83..3825aeb82 100644 --- a/src/test/app/Remit_test.cpp +++ b/src/test/app/Remit_test.cpp @@ -18,6 +18,7 @@ //============================================================================== #include +#include #include #include #include @@ -410,6 +411,21 @@ struct Remit_test : public beast::unit_test::suite env.close(); } + // tecNO_PERMISSION - inform account is an AMM + { + Env env{*this, features}; + env.fund(XRP(1000), gw, alice, bob); + env.close(); + + AMM amm(env, gw, XRP(100), USD(100)); + BEAST_EXPECT(amm.ammExists()); + + auto tx = remit::remit(alice, bob); + tx[sfInform.jsonName] = to_string(amm.ammAccount()); + env(tx, alice, ter(tecNO_PERMISSION)); + env.close(); + } + // tecNO_PERMISSION - lsfDisallowIncomingRemit // DA: see testAllowIncoming @@ -2875,6 +2891,39 @@ struct Remit_test : public beast::unit_test::suite } } + void + testDestAMM(FeatureBitset features) + { + testcase("remit to AMM Account"); + using namespace test::jtx; + using namespace std::literals; + + auto const alice = Account("alice"); + auto const gw = Account("gw"); + auto const USD = gw["USD"]; + + Env env{*this, features}; + env.fund(XRP(10'000'000), alice, gw); + env.close(); + + env.trust(USD(100'000), alice); + env.close(); + env(pay(gw, alice, USD(100'000))); + env.close(); + + AMM ammAlice(env, alice, XRP(10'000), USD(10'000)); + + env(remit::remit(alice, ammAlice.ammAccount()), + remit::amts({USD(10'000)}), + ter(tecNO_PERMISSION)); + env(remit::remit(alice, ammAlice.ammAccount()), + remit::amts({XRP(10'000)}), + ter(tecNO_PERMISSION)); + env(remit::remit(gw, ammAlice.ammAccount()), + remit::amts({gw["EUR"](10'000)}), + ter(tecNO_PERMISSION)); + } + void testWithFeats(FeatureBitset features) { @@ -2896,6 +2945,7 @@ struct Remit_test : public beast::unit_test::suite testRippling(features); testURIToken(features); testOptionals(features); + testDestAMM(features); } public: diff --git a/src/test/app/SetHookTSH_test.cpp b/src/test/app/SetHookTSH_test.cpp index 223a200b8..4f0dd9490 100644 --- a/src/test/app/SetHookTSH_test.cpp +++ b/src/test/app/SetHookTSH_test.cpp @@ -21,10 +21,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include @@ -1702,13 +1704,15 @@ private: } void - testClawbackTSH(FeatureBitset features) + testClawbackTSH(FeatureBitset _features) { testcase("clawback tsh"); using namespace test::jtx; using namespace std::literals; + auto const features = _features | featureMPTokensV1; + // otxn: IOU issuer // tsh issuer // w/s: strong @@ -1825,6 +1829,30 @@ private: } } + void + testCredentialCreateTSH(FeatureBitset features) + { + testcase("credential create tsh"); + + BEAST_EXPECT(!features[featureCredentials]); + } + + void + testCredentialAcceptTSH(FeatureBitset features) + { + testcase("credential accept tsh"); + + BEAST_EXPECT(!features[featureCredentials]); + } + + void + testCredentialDeleteTSH(FeatureBitset features) + { + testcase("credential delete tsh"); + + BEAST_EXPECT(!features[featureCredentials]); + } + // DepositPreauth // | otxn | tsh | preauth | // | A | A | S | @@ -1905,6 +1933,31 @@ private: } } + void + testDIDSetTSH(FeatureBitset features) + { + testcase("did set tsh"); + + BEAST_EXPECT(!features[featureDID]); + } + + void + testDIDDeleteTSH(FeatureBitset features) + { + testcase("did delete tsh"); + + BEAST_EXPECT(!features[featureDID]); + } + + void + testEmitFailureTSH(FeatureBitset features) + { + testcase("emit failure tsh"); + + // pseudo transaction + pass(); + } + // Escrow // | otxn | tsh | cancel | cancel(id) | create | finish | finish(id) // | A | A | S | S | S | S | S @@ -3097,6 +3150,15 @@ private: } } + void + testEnableAmendmentTSH(FeatureBitset features) + { + testcase("enable amendment tsh"); + + // pseudo transaction + pass(); + } + // GenesisMint // | otxn | tsh | mint | // | A | A | S | @@ -3467,6 +3529,1223 @@ private: } } + // from FixNFTokenPageLinks_test.cpp + // A helper function that generates 96 nfts packed into three pages + // of 32 each. Returns a sorted vector of the NFTokenIDs packed into + // the pages. + std::vector + genPackedTokens(test::jtx::Env& env, test::jtx::Account const& owner) + { + using namespace test::jtx; + + std::vector nfts; + nfts.reserve(96); + + // We want to create fully packed NFT pages. This is a little + // tricky since the system currently in place is inclined to + // assign consecutive tokens to only 16 entries per page. + // + // By manipulating the internal form of the taxon we can force + // creation of NFT pages that are completely full. This lambda + // tells us the taxon value we should pass in in order for the + // internal representation to match the passed in value. + auto internalTaxon = [this, &env]( + Account const& acct, + std::uint32_t taxon) -> std::uint32_t { + std::uint32_t tokenSeq = [this, &env, &acct]() { + auto const le = env.le(acct); + if (BEAST_EXPECT(le)) + return le->at(~sfMintedNFTokens).value_or(0u); + return 0u; + }(); + + // If fixNFTokenRemint amendment is on, we must + // add FirstNFTokenSequence. + if (env.current()->rules().enabled(fixNFTokenRemint)) + tokenSeq += env.le(acct) + ->at(~sfFirstNFTokenSequence) + .value_or(env.seq(acct)); + + return toUInt32(nft::cipheredTaxon(tokenSeq, nft::toTaxon(taxon))); + }; + + for (std::uint32_t i = 0; i < 96; ++i) + { + // In order to fill the pages we use the taxon to break them + // into groups of 16 entries. By having the internal + // representation of the taxon go... + // 0, 3, 2, 5, 4, 7... + // in sets of 16 NFTs we can get each page to be fully + // populated. + std::uint32_t const intTaxon = (i / 16) + (i & 0b10000 ? 2 : 0); + uint32_t const extTaxon = internalTaxon(owner, intTaxon); + nfts.push_back( + token::getNextID(env, owner, extTaxon, tfTransferable)); + env(token::mint(owner, extTaxon), txflags(tfTransferable)); + env.close(); + } + + // Sort the NFTs so they are listed in storage order, not + // creation order. + std::sort(nfts.begin(), nfts.end()); + + // Verify that the owner does indeed have exactly three pages + // of NFTs with 32 entries in each page. + { + Json::Value params; + params[jss::account] = owner.human(); + auto resp = env.rpc("json", "account_objects", to_string(params)); + + Json::Value const& acctObjs = + resp[jss::result][jss::account_objects]; + + int pageCount = 0; + for (Json::UInt i = 0; i < acctObjs.size(); ++i) + { + if (BEAST_EXPECT( + acctObjs[i].isMember(sfNFTokens.jsonName) && + acctObjs[i][sfNFTokens.jsonName].isArray())) + { + BEAST_EXPECT(acctObjs[i][sfNFTokens.jsonName].size() == 32); + ++pageCount; + } + } + // If this check fails then the internal NFT directory logic + // has changed. + BEAST_EXPECT(pageCount == 3); + } + return nfts; + }; + + void + testLedgerStateFixTSH(FeatureBitset features) + { + testcase("ledger state fix tsh"); + + using namespace test::jtx; + using namespace std::literals; + + // otxn: account + // tsh account + // w/s: strong + + // otxn: account + // tsh owner + // w/s: weak + for (auto const& [testStrong, testOtxnAccount] : + std::vector>{ + {true, true}, {false, true}, {true, false}, {false, false}}) + { + test::jtx::Env env{ + *this, + network::makeNetworkConfig(21337, "10", "1000000", "200000"), + features - fixNFTokenPageLinks}; + + Account const alice("alice"); + Account const bob("bob"); + Account const carol("carol"); + Account const daria("daria"); + + Account const& hook = testOtxnAccount ? daria : alice; + + env.fund(XRP(1000), alice, bob, carol, daria); + + //********************************************************************** + // Step 1A: Create damaged NFToken directories: + // o One where there is only one page, but without the final + // index. + //********************************************************************** + + // alice generates three packed pages. + std::vector aliceNFTs = genPackedTokens(env, alice); + + // alice burns all the tokens in the first and last pages. + for (int i = 0; i < 32; ++i) + { + env(token::burn(alice, {aliceNFTs[i]})); + env.close(); + } + aliceNFTs.erase(aliceNFTs.begin(), aliceNFTs.begin() + 32); + for (int i = 0; i < 32; ++i) + { + env(token::burn(alice, {aliceNFTs.back()})); + aliceNFTs.pop_back(); + env.close(); + } + + //********************************************************************** + // Step 1B: Create damaged NFToken directories: + // o One with multiple pages and a missing final page. + //********************************************************************** + + // bob generates three packed pages. + std::vector bobNFTs = genPackedTokens(env, bob); + + // bob burns all the tokens in the very last page. + for (int i = 0; i < 32; ++i) + { + env(token::burn(bob, {bobNFTs.back()})); + bobNFTs.pop_back(); + env.close(); + } + + //********************************************************************** + // Step 1C: Create damaged NFToken directories: + // o One with links missing in the middle of the chain. + //********************************************************************** + + // carol generates three packed pages. + std::vector carolNFTs = genPackedTokens(env, carol); + + // carol sells all of the tokens in the very last page to daria. + std::vector dariaNFTs; + dariaNFTs.reserve(32); + for (int i = 0; i < 32; ++i) + { + uint256 const offerIndex = + keylet::nftoffer(carol, env.seq(carol)).key; + env(token::createOffer(carol, carolNFTs.back(), XRP(0)), + txflags(tfSellNFToken)); + env.close(); + + env(token::acceptSellOffer(daria, offerIndex)); + env.close(); + + dariaNFTs.push_back(carolNFTs.back()); + carolNFTs.pop_back(); + } + + // At this point carol's NFT directory has the same problem that + // bob's has: the last page is missing. Now we make things more + // complicated by putting the last page back. carol buys their NFTs + // back from daria. + for (uint256 const& nft : dariaNFTs) + { + uint256 const offerIndex = + keylet::nftoffer(carol, env.seq(carol)).key; + env(token::createOffer(carol, nft, drops(1)), + token::owner(daria)); + env.close(); + + env(token::acceptBuyOffer(daria, offerIndex)); + env.close(); + + carolNFTs.push_back(nft); + } + + //********************************************************************** + // Step 2: Enable the fixNFTokenPageLinks amendment. + //********************************************************************** + env.enableFeature(fixNFTokenPageLinks); + env.close(); + + //********************************************************************** + // Step 3A: Repair the one-page directory (alice's) + //********************************************************************** + + // The server "remembers" daria's failed nftPageLinks transaction + // signature. So we need to advance daria's sequence number before + // daria can submit a similar transaction. + env(noop(daria)); + + // set tsh collect + if (!testStrong) + addWeakTSH(env, hook); + + // set tsh hook + setTSHHook(env, hook, testStrong); + + // daria fixes the links in alice's NFToken directory. + env(ledgerStateFix::nftPageLinks(daria, alice), fee(XRP(100))); + env.close(); + + // verify tsh hook triggered + auto const expected = + testOtxnAccount ? tshSTRONG : (testStrong ? tshNONE : tshWEAK); + testTSHStrongWeak(env, expected, __LINE__); + } + } + + void + testMPTokenIssuanceCreateTSH(FeatureBitset features) + { + testcase("mp token issuance create tsh"); + + BEAST_EXPECT(!features[featureMPTokensV1]); + } + + void + testMPTokenIssuanceDestroyTSH(FeatureBitset features) + { + testcase("mp token issuance destroy tsh"); + + BEAST_EXPECT(!features[featureMPTokensV1]); + } + + void + testMPTokenIssuanceSetTSH(FeatureBitset features) + { + testcase("mp token issuance set tsh"); + + BEAST_EXPECT(!features[featureMPTokensV1]); + } + + void + testMPTokenAuthorizeTSH(FeatureBitset features) + { + testcase("mp token authorize tsh"); + + BEAST_EXPECT(!features[featureMPTokensV1]); + } + + void + testNFTokenMintTSH(FeatureBitset features) + { + testcase("nftoken mint tsh"); + + using namespace test::jtx; + using namespace std::literals; + + // otxn: account + // tsh account + // w/s: strong + for (bool const testStrong : {true, false}) + { + test::jtx::Env env{ + *this, + network::makeNetworkConfig(21337, "10", "1000000", "200000"), + features}; + + auto const account = Account("alice"); + env.fund(XRP(1000), account); + env.close(); + + // set tsh collect + if (!testStrong) + addWeakTSH(env, account); + + // set tsh hook + setTSHHook(env, account, testStrong); + + // mint nft + env(token::mint(account), fee(XRP(1))); + env.close(); + + // verify tsh hook triggered + testTSHStrongWeak(env, tshSTRONG, __LINE__); + } + + // otxn: account + // tsh issuer + // w/s: strong + for (bool const testStrong : {true, false}) + { + test::jtx::Env env{ + *this, + network::makeNetworkConfig(21337, "10", "1000000", "200000"), + features}; + + auto const account = Account("alice"); + auto const issuer = Account("bob"); + env.fund(XRP(1000), account, issuer); + env.close(); + + // set NFTokenMinter + env(token::setMinter(issuer, account)); + env.close(); + + // set tsh collect + if (!testStrong) + addWeakTSH(env, issuer); + + // set tsh hook + setTSHHook(env, issuer, testStrong); + + // mint nft + env(token::mint(account), token::issuer(issuer), fee(XRP(1))); + env.close(); + + // verify tsh hook triggered + testTSHStrongWeak(env, tshSTRONG, __LINE__); + } + + // + // after NFTokenMintOffer amendment + // + BEAST_EXPECT(!features[featureNFTokenMintOffer]); + } + + void + testNFTokenBurnTSH(FeatureBitset features) + { + testcase("nftoken burn tsh"); + + using namespace test::jtx; + using namespace std::literals; + + auto const mintFlags = tfTransferable | tfBurnable; + + // otxn: account + // tsh account + // w/s: strong + for (bool const testStrong : {true, false}) + { + test::jtx::Env env{ + *this, + network::makeNetworkConfig(21337, "10", "1000000", "200000"), + features}; + + auto const account = Account("alice"); + env.fund(XRP(1000), account); + env.close(); + + auto const nftid = token::getNextID(env, account, 0, mintFlags); + env(token::mint(account), txflags(mintFlags)); + env.close(); + + // set tsh collect + if (!testStrong) + addWeakTSH(env, account); + + // set tsh hook + setTSHHook(env, account, testStrong); + + // burn nft + env(token::burn(account, nftid), fee(XRP(1))); + env.close(); + + // verify tsh hook triggered + testTSHStrongWeak(env, tshSTRONG, __LINE__); + } + + // otxn: account + // tsh owner + // w/s: weak + for (bool const testStrong : {true, false}) + { + test::jtx::Env env{ + *this, + network::makeNetworkConfig(21337, "10", "1000000", "200000"), + features}; + + auto const issuer = Account("alice"); + auto const owner = Account("bob"); + env.fund(XRP(1000), issuer, owner); + env.close(); + + auto const nftid = token::getNextID(env, issuer, 0, mintFlags); + env(token::mint(issuer), txflags(mintFlags)); + env.close(); + + auto const offerIndex = + keylet::nftoffer(issuer, env.seq(issuer)).key; + env(token::createOffer(issuer, nftid, XRP(1)), + txflags(tfSellNFToken), + fee(XRP(1))); + env.close(); + env(token::acceptSellOffer(owner, offerIndex), fee(XRP(1))); + env.close(); + + // set tsh collect + if (!testStrong) + addWeakTSH(env, owner); + + // set tsh hook + setTSHHook(env, owner, testStrong); + + // burn nft + env(token::burn(issuer, nftid), token::owner(owner), fee(XRP(1))); + env.close(); + + // verify tsh hook triggered + auto const expected = + testStrong || !features[featureIOUIssuerWeakTSH] ? tshNONE + : tshWEAK; + testTSHStrongWeak(env, expected, __LINE__); + } + + // otxn: account + // tsh issuer + // nft flag: not tfStrongTSH + // w/s: weak + for (bool const testStrong : {true, false}) + { + test::jtx::Env env{ + *this, + network::makeNetworkConfig(21337, "10", "1000000", "200000"), + features}; + + auto const issuer = Account("alice"); + auto const owner = Account("bob"); + env.fund(XRP(1000), issuer, owner); + env.close(); + + auto const nftid = token::getNextID(env, issuer, 0, mintFlags); + env(token::mint(issuer), txflags(mintFlags)); + env.close(); + + auto const offerIndex = + keylet::nftoffer(issuer, env.seq(issuer)).key; + env(token::createOffer(issuer, nftid, XRP(1)), + txflags(tfSellNFToken), + fee(XRP(1))); + env.close(); + env(token::acceptSellOffer(owner, offerIndex), fee(XRP(1))); + env.close(); + + // set tsh collect + if (!testStrong) + addWeakTSH(env, issuer); + + // set tsh hook + setTSHHook(env, issuer, testStrong); + + // burn nft + env(token::burn(owner, nftid), fee(XRP(1))); + env.close(); + + // verify tsh hook triggered + auto const expected = + testStrong || !features[featureIOUIssuerWeakTSH] ? tshNONE + : tshWEAK; + testTSHStrongWeak(env, expected, __LINE__); + } + + // otxn: account + // tsh issuer + // nft flag: tfStrongTSH + // w/s: strong + for (bool const testStrong : {true, false}) + { + test::jtx::Env env{ + *this, + network::makeNetworkConfig(21337, "10", "1000000", "200000"), + features}; + + auto const issuer = Account("alice"); + auto const owner = Account("bob"); + env.fund(XRP(1000), issuer, owner); + env.close(); + + auto const nftid = + token::getNextID(env, issuer, 0, mintFlags | tfStrongTSH); + env(token::mint(issuer), txflags(mintFlags | tfStrongTSH)); + env.close(); + + auto const offerIndex = + keylet::nftoffer(issuer, env.seq(issuer)).key; + env(token::createOffer(issuer, nftid, XRP(1)), + txflags(tfSellNFToken), + fee(XRP(1))); + env.close(); + env(token::acceptSellOffer(owner, offerIndex), fee(XRP(1))); + env.close(); + + // set tsh collect + if (!testStrong) + addWeakTSH(env, issuer); + + // set tsh hook + setTSHHook(env, issuer, testStrong); + + // burn nft + env(token::burn(owner, nftid), fee(XRP(1))); + env.close(); + + // verify tsh hook triggered + testTSHStrongWeak(env, tshSTRONG, __LINE__); + } + } + + void + testNFTokenCreateOfferTSH(FeatureBitset features) + { + testcase("nftoken create offer tsh"); + + using namespace test::jtx; + using namespace std::literals; + + auto const mintFlags = tfTransferable; + + // otxn: account + // tsh account + // w/s: strong + for (bool const testStrong : {true, false}) + { + test::jtx::Env env{ + *this, + network::makeNetworkConfig(21337, "10", "1000000", "200000"), + features}; + + auto const account = Account("alice"); + auto const owner = Account("bob"); + env.fund(XRP(1000), account, owner); + env.close(); + + auto const nftid = token::getNextID(env, account, 0, mintFlags); + env(token::mint(account), txflags(mintFlags)); + env.close(); + + // set tsh collect + if (!testStrong) + addWeakTSH(env, account); + + // set tsh hook + setTSHHook(env, account, testStrong); + + // create offer + env(token::createOffer(account, nftid, XRP(1)), + txflags(tfSellNFToken), + fee(XRP(1))); + env.close(); + + // verify tsh hook triggered + testTSHStrongWeak(env, tshSTRONG, __LINE__); + } + + // otxn: account + // tsh owner + // w/s: weak + for (bool const testStrong : {true, false}) + { + test::jtx::Env env{ + *this, + network::makeNetworkConfig(21337, "10", "1000000", "200000"), + features}; + + auto const account = Account("alice"); + auto const owner = Account("bob"); + auto const issuer = Account("carol"); + env.fund(XRP(1000), account, owner, issuer); + env.close(); + + auto const nftid = token::getNextID(env, issuer, 0, mintFlags); + env(token::mint(issuer), txflags(mintFlags)); + env.close(); + + auto const offerIndex = + keylet::nftoffer(issuer, env.seq(issuer)).key; + env(token::createOffer(issuer, nftid, XRP(1)), + txflags(tfSellNFToken)); + env.close(); + env(token::acceptSellOffer(owner, offerIndex), fee(XRP(1))); + env.close(); + + // set tsh collect + if (!testStrong) + addWeakTSH(env, owner); + + // set tsh hook + setTSHHook(env, owner, testStrong); + + // create buy offer to owner + env(token::createOffer(account, nftid, XRP(1)), + token::owner(owner), + fee(XRP(1))); + env.close(); + + // verify tsh hook triggered + auto const expected = testStrong ? tshNONE : tshWEAK; + testTSHStrongWeak(env, expected, __LINE__); + } + + // otxn: account + // nft flag: not tfStrongTSH + // tsh issuer + // w/s: weak + for (bool const testStrong : {true, false}) + { + test::jtx::Env env{ + *this, + network::makeNetworkConfig(21337, "10", "1000000", "200000"), + features}; + + auto const account = Account("alice"); + auto const owner = Account("bob"); + auto const issuer = Account("carol"); + env.fund(XRP(1000), account, owner, issuer); + env.close(); + + auto const nftid = token::getNextID(env, issuer, 0, mintFlags); + env(token::mint(issuer), txflags(mintFlags)); + env.close(); + + auto const offerIndex = + keylet::nftoffer(issuer, env.seq(issuer)).key; + env(token::createOffer(issuer, nftid, XRP(1)), + txflags(tfSellNFToken)); + env.close(); + env(token::acceptSellOffer(owner, offerIndex), fee(XRP(1))); + env.close(); + + // set tsh collect + if (!testStrong) + addWeakTSH(env, issuer); + + // set tsh hook + setTSHHook(env, issuer, testStrong); + + // create buy offer to owner + env(token::createOffer(account, nftid, XRP(1)), + token::owner(owner), + fee(XRP(1))); + env.close(); + + // verify tsh hook triggered + auto const expected = testStrong ? tshNONE : tshWEAK; + testTSHStrongWeak(env, expected, __LINE__); + } + // otxn: account + // nft flag: tfStrongTSH + // tsh issuer + // w/s: string + for (bool const testStrong : {true, false}) + { + test::jtx::Env env{ + *this, + network::makeNetworkConfig(21337, "10", "1000000", "200000"), + features}; + + auto const account = Account("alice"); + auto const owner = Account("bob"); + auto const issuer = Account("carol"); + env.fund(XRP(1000), account, owner, issuer); + env.close(); + + auto const nftid = + token::getNextID(env, issuer, 0, mintFlags | tfStrongTSH); + env(token::mint(issuer), txflags(mintFlags | tfStrongTSH)); + env.close(); + + auto const offerIndex = + keylet::nftoffer(issuer, env.seq(issuer)).key; + env(token::createOffer(issuer, nftid, XRP(1)), + txflags(tfSellNFToken)); + env.close(); + env(token::acceptSellOffer(owner, offerIndex), fee(XRP(1))); + env.close(); + + // set tsh collect + if (!testStrong) + addWeakTSH(env, issuer); + + // set tsh hook + setTSHHook(env, issuer, testStrong); + + // create buy offer to owner + env(token::createOffer(account, nftid, XRP(1)), + token::owner(owner), + fee(XRP(1))); + env.close(); + + // verify tsh hook triggered + testTSHStrongWeak(env, tshSTRONG, __LINE__); + } + + // otxn: account + // tsh destination + // w/s: none + for (bool const testStrong : {true, false}) + { + test::jtx::Env env{ + *this, + network::makeNetworkConfig(21337, "10", "1000000", "200000"), + features}; + + auto const issuer = Account("alice"); + auto const destination = Account("bob"); + env.fund(XRP(1000), destination, issuer); + env.close(); + + auto const nftid = token::getNextID(env, issuer, 0, mintFlags); + env(token::mint(issuer), txflags(mintFlags)); + env.close(); + + // set tsh collect + if (!testStrong) + addWeakTSH(env, destination); + + // set tsh hook + setTSHHook(env, destination, testStrong); + + env(token::createOffer(issuer, nftid, XRP(1)), + token::destination(destination), + txflags(tfSellNFToken)); + env.close(); + + // verify tsh hook triggered + testTSHStrongWeak(env, tshNONE, __LINE__); + } + + // otxn: account + // tsh amount issuer + // w/s: none + for (bool const testStrong : {true, false}) + { + test::jtx::Env env{ + *this, + network::makeNetworkConfig(21337, "10", "1000000", "200000"), + features}; + + auto const issuer = Account("alice"); + auto const gw = Account("gw"); + auto const USD = gw["USD"]; + env.fund(XRP(1000), issuer, gw); + env.close(); + + env.trust(USD(10000), issuer); + env.close(); + env(pay(gw, issuer, USD(10000))); + env.close(); + + auto const nftid = token::getNextID(env, issuer, 0, mintFlags); + env(token::mint(issuer), txflags(mintFlags)); + env.close(); + + // set tsh collect + if (!testStrong) + addWeakTSH(env, gw); + + // set tsh hook + setTSHHook(env, gw, testStrong); + + env(token::createOffer(issuer, nftid, USD(1)), + txflags(tfSellNFToken)); + env.close(); + + // verify tsh hook triggered + testTSHStrongWeak(env, tshNONE, __LINE__); + } + } + + void + testNFTokenCancelOfferTSH(FeatureBitset features) + { + testcase("nftoken cancel offer tsh"); + + using namespace test::jtx; + using namespace std::literals; + + auto const mintFlags = tfTransferable; + + // otxn: account + // tsh account + // w/s: strong + for (bool const testStrong : {true, false}) + { + test::jtx::Env env{ + *this, + network::makeNetworkConfig(21337, "10", "1000000", "200000"), + features}; + + auto const account = Account("alice"); + auto const gw = Account("gw"); + env.fund(XRP(1000), account, gw); + env.close(); + + auto const nftid = token::getNextID(env, account, 0, mintFlags); + env(token::mint(account), txflags(mintFlags)); + env.close(); + + auto const offerIndex = + keylet::nftoffer(account, env.seq(account)).key; + env(token::createOffer(account, nftid, XRP(1)), + txflags(tfSellNFToken)); + env.close(); + + // set tsh collect + if (!testStrong) + addWeakTSH(env, account); + + // set tsh hook + setTSHHook(env, account, testStrong); + + // cancel offer + env(token::cancelOffer(account, {offerIndex}), fee(XRP(1))); + env.close(); + + // verify tsh hook triggered + testTSHStrongWeak(env, tshSTRONG, __LINE__); + } + + // otxn: issuer + // tsh owner + // w/s: weak + for (bool const testStrong : {true, false}) + { + test::jtx::Env env{ + *this, + network::makeNetworkConfig(21337, "10", "1000000", "200000"), + features}; + + auto const issuer = Account("alice"); + auto const owner = Account("bob"); + auto const buyer = Account("carol"); + env.fund(XRP(1000), issuer, owner, buyer); + env.close(); + + auto const nftid = token::getNextID(env, issuer, 0, mintFlags); + env(token::mint(issuer), txflags(mintFlags)); + env.close(); + + auto const offerIndex = + keylet::nftoffer(issuer, env.seq(issuer)).key; + env(token::createOffer(issuer, nftid, XRP(1)), + token::destination(owner), + txflags(tfSellNFToken)); + env.close(); + env(token::acceptSellOffer(owner, offerIndex), fee(XRP(1))); + env.close(); + auto const offerIndex2 = + keylet::nftoffer(owner, env.seq(owner)).key; + env(token::createOffer(owner, nftid, XRP(1)), + token::destination(buyer), + txflags(tfSellNFToken)); + env.close(); + + // set tsh collect + if (!testStrong) + addWeakTSH(env, owner); + + // set tsh hook + setTSHHook(env, owner, testStrong); + + // cancel offer + env(token::cancelOffer(buyer, {offerIndex2}), fee(XRP(1))); + env.close(); + + // verify tsh hook triggered + auto const expected = + testStrong || !features[featureIOUIssuerWeakTSH] ? tshNONE + : tshWEAK; + testTSHStrongWeak(env, expected, __LINE__); + } + + // otxn: owner + // tsh destination + // w/s: weak + for (bool const testStrong : {true, false}) + { + test::jtx::Env env{ + *this, + network::makeNetworkConfig(21337, "10", "1000000", "200000"), + features}; + + auto const issuer = Account("alice"); + auto const owner = Account("bob"); + auto const buyer = Account("carol"); + env.fund(XRP(1000), issuer, owner, buyer); + env.close(); + + auto const nftid = token::getNextID(env, issuer, 0, mintFlags); + env(token::mint(issuer), txflags(mintFlags)); + env.close(); + + auto const offerIndex = + keylet::nftoffer(issuer, env.seq(issuer)).key; + env(token::createOffer(issuer, nftid, XRP(1)), + token::destination(owner), + txflags(tfSellNFToken)); + env.close(); + env(token::acceptSellOffer(owner, offerIndex), fee(XRP(1))); + env.close(); + auto const offerIndex2 = + keylet::nftoffer(owner, env.seq(owner)).key; + env(token::createOffer(owner, nftid, XRP(1)), + token::destination(buyer), + txflags(tfSellNFToken)); + env.close(); + + // set tsh collect + if (!testStrong) + addWeakTSH(env, buyer); + + // set tsh hook + setTSHHook(env, buyer, testStrong); + + // cancel offer + env(token::cancelOffer(owner, {offerIndex2}), fee(XRP(1))); + env.close(); + + // verify tsh hook triggered + auto const expected = + testStrong || !features[featureIOUIssuerWeakTSH] ? tshNONE + : tshWEAK; + testTSHStrongWeak(env, expected, __LINE__); + } + + // otxn: account + // tsh nft issuer + // w/s: weak (Regardless of tfStrongTSH) + for (auto const& [testStrong, strongIssuerTSH] : + std::vector>{ + {true, true}, {true, false}, {false, true}, {false, false}}) + { + test::jtx::Env env{ + *this, + network::makeNetworkConfig(21337, "10", "1000000", "200000"), + features}; + + auto const issuer = Account("alice"); + auto const owner = Account("bob"); + env.fund(XRP(1000), issuer, owner); + env.close(); + + auto const nftid = token::getNextID( + env, + issuer, + 0, + mintFlags | (strongIssuerTSH ? tfStrongTSH : 0)); + env(token::mint(issuer), + txflags(mintFlags | (strongIssuerTSH ? tfStrongTSH : 0))); + env.close(); + + auto const offerIndex = + keylet::nftoffer(issuer, env.seq(issuer)).key; + env(token::createOffer(issuer, nftid, XRP(1)), + token::destination(owner), + txflags(tfSellNFToken)); + env.close(); + env(token::acceptSellOffer(owner, offerIndex), fee(XRP(1))); + env.close(); + auto const offerIndex2 = + keylet::nftoffer(owner, env.seq(owner)).key; + env(token::createOffer(owner, nftid, XRP(1)), + txflags(tfSellNFToken)); + env.close(); + + // set tsh collect + if (!testStrong) + addWeakTSH(env, issuer); + + // set tsh hook + setTSHHook(env, issuer, testStrong); + + // cancel offer + env(token::cancelOffer(owner, {offerIndex2}), fee(XRP(1))); + env.close(); + + // verify tsh hook triggered + auto const expected = + testStrong || !features[featureIOUIssuerWeakTSH] ? tshNONE + : tshWEAK; + testTSHStrongWeak(env, expected, __LINE__); + } + } + + void + testNFTokenAcceptOfferTSH(FeatureBitset features) + { + testcase("nftoken accept offer tsh"); + + using namespace test::jtx; + using namespace std::literals; + + auto const mintFlags = tfTransferable; + + // tsh: account(strong), issuer(weak/strong), owner(strong), + // destination(strong) + + // otxn: account + // tsh account + // w/s: strong + for (bool const testStrong : {true, false}) + { + test::jtx::Env env{ + *this, + network::makeNetworkConfig(21337, "10", "1000000", "200000"), + features}; + + auto const account = Account("alice"); + auto const issuer = Account("bob"); + env.fund(XRP(1000), account, issuer); + env.close(); + + auto const nftid = token::getNextID(env, issuer, 0, mintFlags); + env(token::mint(issuer), txflags(mintFlags)); + env.close(); + + auto const offerIndex = + keylet::nftoffer(issuer, env.seq(issuer)).key; + env(token::createOffer(issuer, nftid, XRP(1)), + txflags(tfSellNFToken)); + env.close(); + + // set tsh collect + if (!testStrong) + addWeakTSH(env, account); + + // set tsh hook + setTSHHook(env, account, testStrong); + + // accept offer + env(token::acceptSellOffer(account, offerIndex), fee(XRP(1))); + env.close(); + + // verify tsh hook triggered + testTSHStrongWeak(env, tshSTRONG, __LINE__); + } + + // otxn: owner + // nft flag: not tfStrongTSH + // tsh issuer + // w/s: weak + for (bool const testStrong : {true, false}) + { + test::jtx::Env env{ + *this, + network::makeNetworkConfig(21337, "10", "1000000", "200000"), + features}; + + auto const issuer = Account("alice"); + auto const owner = Account("bob"); + auto const buyer = Account("carol"); + env.fund(XRP(1000), issuer, owner, buyer); + env.close(); + + auto const nftid = token::getNextID(env, issuer, 0, mintFlags); + env(token::mint(issuer), txflags(mintFlags)); + env.close(); + + auto const offerIndex = + keylet::nftoffer(issuer, env.seq(issuer)).key; + env(token::createOffer(issuer, nftid, XRP(1)), + txflags(tfSellNFToken)); + env.close(); + + env(token::acceptSellOffer(owner, offerIndex), fee(XRP(1))); + env.close(); + auto const offerIndex2 = + keylet::nftoffer(buyer, env.seq(buyer)).key; + env(token::createOffer(buyer, nftid, XRP(1)), token::owner(owner)); + env.close(); + + // set tsh collect + if (!testStrong) + addWeakTSH(env, issuer); + + // set tsh hook + setTSHHook(env, issuer, testStrong); + + // accept offer + env(token::acceptBuyOffer(owner, offerIndex2), fee(XRP(1))); + env.close(); + + // verify tsh hook triggered + auto const expected = + testStrong || !features[featureIOUIssuerWeakTSH] ? tshNONE + : tshWEAK; + testTSHStrongWeak(env, expected, __LINE__); + } + + // otxn: owner + // nft flag: tfStrongTSH + // tsh issuer + // w/s: weak + for (bool const testStrong : {true, false}) + { + test::jtx::Env env{ + *this, + network::makeNetworkConfig(21337, "10", "1000000", "200000"), + features}; + + auto const issuer = Account("alice"); + auto const owner = Account("bob"); + auto const buyer = Account("carol"); + env.fund(XRP(1000), issuer, owner, buyer); + env.close(); + + auto const nftid = + token::getNextID(env, issuer, 0, mintFlags | tfStrongTSH); + env(token::mint(issuer), txflags(mintFlags | tfStrongTSH)); + env.close(); + + auto const offerIndex = + keylet::nftoffer(issuer, env.seq(issuer)).key; + env(token::createOffer(issuer, nftid, XRP(1)), + txflags(tfSellNFToken)); + env.close(); + + env(token::acceptSellOffer(owner, offerIndex), fee(XRP(1))); + env.close(); + auto const offerIndex2 = + keylet::nftoffer(buyer, env.seq(buyer)).key; + env(token::createOffer(buyer, nftid, XRP(1)), token::owner(owner)); + env.close(); + + // set tsh collect + if (!testStrong) + addWeakTSH(env, issuer); + + // set tsh hook + setTSHHook(env, issuer, testStrong); + + // accept offer + env(token::acceptBuyOffer(owner, offerIndex2), fee(XRP(1))); + env.close(); + + // verify tsh hook triggered + testTSHStrongWeak(env, tshSTRONG, __LINE__); + } + + // otxn: account + // tsh owner + // w/s: strong + for (bool const testStrong : {true, false}) + { + test::jtx::Env env{ + *this, + network::makeNetworkConfig(21337, "10", "1000000", "200000"), + features}; + auto const account = Account("alice"); + auto const destination = Account("bob"); + env.fund(XRP(1000), account, destination); + env.close(); + + auto const nftid = token::getNextID(env, account, 0, mintFlags); + env(token::mint(account), txflags(mintFlags)); + env.close(); + + auto const offerIndex = + keylet::nftoffer(account, env.seq(account)).key; + env(token::createOffer(account, nftid, XRP(1)), + txflags(tfSellNFToken)); + env.close(); + + // set tsh collect + if (!testStrong) + addWeakTSH(env, account); + + // set tsh hook + setTSHHook(env, account, testStrong); + + // accept offer + env(token::acceptSellOffer(destination, offerIndex), fee(XRP(1))); + env.close(); + + // verify tsh hook triggered + testTSHStrongWeak(env, tshSTRONG, __LINE__); + } + + // otxn: account + // tsh destination + // w/s: strong + { + // If sfDestination holds an Offer, it meets the sfOwner criteria. + // If it doesn't hold an Offer, it falls under the Otxn Account. + // Because of this, we might not be able to run TSH tests regarding + // sfDestination. + } + } + + void + testNFTokenModifyTSH(FeatureBitset features) + { + testcase("nftoken modify tsh"); + + BEAST_EXPECT(!features[featureDynamicNFT]); + } + // Offer // | otxn | tsh | cancel | create | // | A | A | S | S | @@ -3656,6 +4935,99 @@ private: } } + void + testOracleSetTSH(FeatureBitset features) + { + testcase("oracle set tsh"); + + using namespace test::jtx; + using namespace std::literals; + using namespace oracle; + + // otxn: account + // tsh account + // w/s: strong + for (bool const testStrong : {true, false}) + { + test::jtx::Env env{ + *this, + network::makeNetworkConfig(21337, "10", "1000000", "200000"), + features}; + + auto const account = Account("alice"); + env.fund(XRP(1000), account); + env.close(); + + // set tsh collect + if (!testStrong) + addWeakTSH(env, account); + + // set tsh hook + setTSHHook(env, account, testStrong); + + // set oracle + env.close(std::chrono::seconds(300)); + Oracle oracle( + env, + {.owner = account, + .series = {{"XRP", "USD", 740, 1}}, + .fee = 10000}); + + // verify tsh hook triggered + testTSHStrongWeak(env, tshSTRONG, __LINE__); + } + } + + void + testOracleDeleteTSH(FeatureBitset features) + { + testcase("oracle delete tsh"); + + using namespace test::jtx; + using namespace std::literals; + using namespace oracle; + + // otxn: account + // tsh account + // w/s: strong + for (bool const testStrong : {true, false}) + { + test::jtx::Env env{ + *this, + network::makeNetworkConfig(21337, "10", "1000000", "200000"), + features}; + + auto const account = Account("alice"); + env.fund(XRP(1000), account); + env.close(); + + // set oracle + env.close(std::chrono::seconds(300)); + Oracle oracle( + env, + { + .owner = account, + .series = {{"XRP", "USD", 740, 1}}, + }); + + // set tsh collect + if (!testStrong) + addWeakTSH(env, account); + + // set tsh hook + setTSHHook(env, account, testStrong); + + // delete oracle + oracle.remove(oracle::RemoveArg{ + .documentID = oracle.documentID(), + .fee = 10000, + }); + + // verify tsh hook triggered + testTSHStrongWeak(env, tshSTRONG, __LINE__); + } + } + // Payment // | otxn | tsh | payment | // | A | A | S | @@ -4374,6 +5746,41 @@ private: } } + void + testPermissionedDomainSetTSH(FeatureBitset features) + { + testcase("permissioned domain set tsh"); + + BEAST_EXPECT(!features[featurePermissionedDomains]); + } + + void + testPermissionedDomainDeleteTSH(FeatureBitset features) + { + testcase("permissioned domain delete tsh"); + + BEAST_EXPECT(!features[featurePermissionedDomains]); + } + + void + testExportTSH(FeatureBitset features) + { + testcase("export tsh"); + + // ttEXPORT is a wrapper/consensus-driven path, not a hook-dispatched + // user transaction for triggered strong/weak hook execution. + pass(); + } + + void + testSetFeeTSH(FeatureBitset features) + { + testcase("set fee tsh"); + + // pseudo transaction + pass(); + } + // SetHook // | otxn | tsh | set | // | A | A | S | @@ -4492,6 +5899,88 @@ private: } } + void + testSetRemarksTSH(FeatureBitset features) + { + testcase("set remarks tsh"); + + using namespace test::jtx; + using namespace std::literals; + + // otxn: account + // tsh account + // w/s: strong + for (bool const testStrong : {true, false}) + { + test::jtx::Env env{ + *this, + network::makeNetworkConfig(21337, "10", "1000000", "200000"), + features}; + + auto const account = Account("alice"); + env.fund(XRP(1000), account); + env.close(); + + // set tsh collect + if (!testStrong) + addWeakTSH(env, account); + + // set tsh hook + setTSHHook(env, account, testStrong); + + // set remarks + env(remarks::setRemarks( + account, + keylet::account(account.id()).key, + {{"CAFE", "DEADBEEF", 0}}), + fee(XRP(1)), + ter(tesSUCCESS)); + env.close(); + + // verify tsh hook triggered + testTSHStrongWeak(env, tshSTRONG, __LINE__); + } + + // otxn: account + // tsh: object issuer + // w/s:none + for (bool const testStrong : {true, false}) + { + test::jtx::Env env{ + *this, + network::makeNetworkConfig(21337, "10", "1000000", "200000"), + features}; + + auto const account = Account("alice"); + auto const issuer = Account("issuer"); + env.fund(XRP(1000), account, issuer); + env.close(); + + std::string const uri("https://example.com"); + env(remit::remit(issuer, account), remit::uri(uri), fee(XRP(1))); + env.close(); + + // set tsh collect + if (!testStrong) + addWeakTSH(env, account); + + // set tsh hook + setTSHHook(env, account, testStrong); + + // set remarks + env(remarks::setRemarks( + issuer, + keylet::uritoken(issuer, Blob(uri.begin(), uri.end())).key, + {{"CAFE", "DEADBEEF", 0}}), + fee(XRP(1)), + ter(tesSUCCESS)); + env.close(); + + // verify tsh hook triggered + testTSHStrongWeak(env, tshNONE, __LINE__); + } + } + // SignerListSet // | otxn | tsh | sls | // | A | A | S | @@ -4705,6 +6194,33 @@ private: } } + void + testUNLModifyTSH(FeatureBitset features) + { + testcase("unl modify tsh"); + + // pseudo transaction + pass(); + } + + void + testUNLReportTSH(FeatureBitset features) + { + testcase("unl report tsh"); + + // pseudo transaction + pass(); + } + + void + testConsensusEntropyTSH(FeatureBitset features) + { + testcase("consensus entropy tsh"); + + // pseudo transaction + pass(); + } + // | otxn | tfBurnable | tsh | mint | burn | buy | sell | cancel // | O | false | O | N/A | S | N/A | S | S // | O | false | I | N/A | N | N/A | W | N/A @@ -6119,6 +7635,70 @@ private: } } + void + testXChainCreateClaimIDTSH(FeatureBitset features) + { + testcase("xchain create claim id tsh"); + + BEAST_EXPECT(!features[featureXChainBridge]); + } + + void + testXChainCommitTSH(FeatureBitset features) + { + testcase("xchain commit tsh"); + + BEAST_EXPECT(!features[featureXChainBridge]); + } + + void + testXChainClaimTSH(FeatureBitset features) + { + testcase("xchain claim tsh"); + + BEAST_EXPECT(!features[featureXChainBridge]); + } + + void + testXChainAccountCreateCommitTSH(FeatureBitset features) + { + testcase("xchain account create commit tsh"); + + BEAST_EXPECT(!features[featureXChainBridge]); + } + + void + testXChainAddClaimAttestationTSH(FeatureBitset features) + { + testcase("xchain add claim attestation tsh"); + + BEAST_EXPECT(!features[featureXChainBridge]); + } + + void + testXChainAddAccountCreateAttestationTSH(FeatureBitset features) + { + testcase("xchain add account create attestation tsh"); + + BEAST_EXPECT(!features[featureXChainBridge]); + } + + void + testXChainModifyBridgeTSH(FeatureBitset features) + { + testcase("xchain modify bridge tsh"); + + BEAST_EXPECT(!features[featureXChainBridge]); + } + + void + testXChainCreateBridgeTSH(FeatureBitset features) + { + testcase("xchain create bridge tsh"); + + BEAST_EXPECT(!features[featureXChainBridge]); + } + void testEmittedTxnReliability(FeatureBitset features) { @@ -6883,48 +8463,15 @@ private: void testTSH(FeatureBitset features) { - testAccountSetTSH(features); - testAccountDeleteTSH(features); - testAMMBidTSH(features); - testAMMCreateTSH(features); - testAMMDeleteTSH(features); - testAMMClawbackTSH(features); - testAMMDepositTSH(features); - testAMMVoteTSH(features); - testAMMWithdrawTSH(features); - testCheckCancelTSH(features); - testCheckCashTSH(features); - testCheckCreateTSH(features); - testClaimRewardTSH(features); - testClawbackTSH(features); - testDepositPreauthTSH(features); - testEscrowCancelTSH(features); - testEscrowIDCancelTSH(features); - testEscrowCreateTSH(features); - testEscrowFinishTSH(features); - testEscrowIDFinishTSH(features); - testGenesisMintTSH(features); - testImportTSH(features); - testInvokeTSH(features); - testOfferCancelTSH(features); - testOfferCreateTSH(features); - testPaymentTSH(features); - testPaymentChannelClaimTSH(features); - testPaymentChannelCreateTSH(features); - testPaymentChannelFundTSH(features); - testSetHookTSH(features); - testSetRegularKeyTSH(features); - testSignerListSetTSH(features); - testTicketCreateTSH(features); - testTrustSetTSH(features); - testURITokenMintTSH(features); - testURITokenBurnTSH(features); - testURITokenBuyTSH(features); - testURITokenCancelSellOfferTSH(features); - testURITokenCreateSellOfferTSH(features); - testRemitTSH(features); - testCronSetTSH(features); - testCronTSH(features); +#pragma push_macro("TRANSACTION") +#undef TRANSACTION + +#define TRANSACTION(tag, value, name, fields) test##name##TSH(features); + +#include + +#undef TRANSACTION +#pragma pop_macro("TRANSACTION") } void @@ -6940,8 +8487,7 @@ public: run(std::uint32_t instance, bool last = false) { using namespace test::jtx; - static FeatureBitset const all{ - supported_amendments() | featureMPTokensV1}; + static FeatureBitset const all{supported_amendments()}; static std::array const feats{ all, diff --git a/src/test/app/XahauGenesis_test.cpp b/src/test/app/XahauGenesis_test.cpp index 9c73977f0..b3b5e7e95 100644 --- a/src/test/app/XahauGenesis_test.cpp +++ b/src/test/app/XahauGenesis_test.cpp @@ -140,8 +140,7 @@ struct XahauGenesis_test : public beast::unit_test::suite bool skipTests = false, bool const testFlag = false, bool const badNetID = false, - uint32_t const expectedOwnerCount = - 10 /** testFlag ? 10 : 14 (default) */) + uint32_t const expectedOwnerCount = 14 /** case for testFlag=false */) { using namespace jtx; @@ -250,9 +249,7 @@ struct XahauGenesis_test : public beast::unit_test::suite genesisAccRoot->getFieldAmount(sfBalance) == XahauGenesis::GenesisAmount); BEAST_EXPECT( - genesisAccRoot->getFieldU32(sfOwnerCount) == !testFlag - ? expectedOwnerCount - : 14); + genesisAccRoot->getFieldU32(sfOwnerCount) == expectedOwnerCount); // ensure the definitions are correctly set { @@ -595,7 +592,8 @@ struct XahauGenesis_test : public beast::unit_test::suite false, true, {}, - 3 /* IRR,IRD,IMC */ + members.size() + tables.size()); + 2 /*Hook objects *2 */ + 3 /* IRR,IRD,IMC HookStates */ + + members.size()); env.close(); env.close(); @@ -2327,7 +2325,7 @@ struct XahauGenesis_test : public beast::unit_test::suite { BEAST_EXPECT( root->getFieldU32(sfOwnerCount) == - mc * 2 + 2 + paramsCount); + (mc * 2 + 2 + paramsCount)); BEAST_EXPECT(root->getFieldU32(sfFlags) & lsfDisableMaster); BEAST_EXPECT(root->getAccountID(sfRegularKey) == noAccount()); } diff --git a/src/test/jtx/impl/import.cpp b/src/test/jtx/impl/import.cpp index 7ba068923..e90159bc4 100644 --- a/src/test/jtx/impl/import.cpp +++ b/src/test/jtx/impl/import.cpp @@ -44,7 +44,7 @@ import(jtx::Account const& account, Json::Value const& xpop) void issuer::operator()(Env& env, JTx& jt) const { - jt.jv[sfIssuer.jsonName] = issuer_.human(); + jt.jv[sfIssuer.jsonName] = to_string(issuer_); } Json::Value diff --git a/src/test/jtx/impl/invoke.cpp b/src/test/jtx/impl/invoke.cpp index 6b3665a94..b94562975 100644 --- a/src/test/jtx/impl/invoke.cpp +++ b/src/test/jtx/impl/invoke.cpp @@ -66,7 +66,7 @@ blob::operator()(Env& env, JTx& jt) const void dest::operator()(Env& env, JTx& jt) const { - jt.jv[sfDestination.jsonName] = dest_.human(); + jt.jv[sfDestination.jsonName] = to_string(dest_); } } // namespace invoke diff --git a/src/test/jtx/impl/reward.cpp b/src/test/jtx/impl/reward.cpp index 49714200c..5b48a0e64 100644 --- a/src/test/jtx/impl/reward.cpp +++ b/src/test/jtx/impl/reward.cpp @@ -29,18 +29,24 @@ namespace reward { // Claim a reward. Json::Value claim(jtx::Account const& account) +{ + return claim(account.id()); +} + +Json::Value +claim(AccountID const& account) { using namespace jtx; Json::Value jv; jv[jss::TransactionType] = jss::ClaimReward; - jv[jss::Account] = account.human(); + jv[jss::Account] = to_string(account); return jv; } void issuer::operator()(Env& env, JTx& jt) const { - jt.jv[sfIssuer.jsonName] = issuer_.human(); + jt.jv[sfIssuer.jsonName] = to_string(issuer_); } } // namespace reward diff --git a/src/test/jtx/impl/unl.cpp b/src/test/jtx/impl/unl.cpp index bd82a76f6..fc664f9ff 100644 --- a/src/test/jtx/impl/unl.cpp +++ b/src/test/jtx/impl/unl.cpp @@ -63,7 +63,7 @@ countTx(std::shared_ptr const& txSet) auto tx = std::make_shared(SerialIter{sit.getSlice(sit.getVLDataLength())}); - if (tx->getFieldU16(sfTransactionType) == ttUNL_MODIFY) + if (tx->getTxnType() == ttUNL_MODIFY) counter++; } */ diff --git a/src/test/jtx/import.h b/src/test/jtx/import.h index e554b8d17..ddf17f30d 100644 --- a/src/test/jtx/import.h +++ b/src/test/jtx/import.h @@ -37,10 +37,10 @@ import(jtx::Account const& account, Json::Value const& xpop); class issuer { private: - jtx::Account issuer_; + AccountID issuer_; public: - explicit issuer(jtx::Account const& issuer) : issuer_(issuer) + explicit issuer(AccountID const& issuer) : issuer_(issuer) { } diff --git a/src/test/jtx/invoke.h b/src/test/jtx/invoke.h index 2875eccc2..40c5182c2 100644 --- a/src/test/jtx/invoke.h +++ b/src/test/jtx/invoke.h @@ -58,10 +58,10 @@ public: class dest { private: - jtx::Account dest_; + AccountID dest_; public: - explicit dest(jtx::Account const& dest) : dest_(dest) + explicit dest(AccountID const& dest) : dest_(dest) { } diff --git a/src/test/jtx/reward.h b/src/test/jtx/reward.h index 78a49841b..bb0e0c74b 100644 --- a/src/test/jtx/reward.h +++ b/src/test/jtx/reward.h @@ -34,17 +34,24 @@ namespace reward { Json::Value claim(jtx::Account const& account); +Json::Value +claim(AccountID const& account); + /** Sets the optional Issuer on a JTx. */ class issuer { private: - jtx::Account issuer_; + AccountID issuer_; public: explicit issuer(jtx::Account const& issuer) : issuer_(issuer) { } + explicit issuer(AccountID const& issuer) : issuer_(issuer) + { + } + void operator()(Env&, JTx& jtx) const; }; diff --git a/src/test/ledger/Invariants_test.cpp b/src/test/ledger/Invariants_test.cpp index 7c28c1c55..54bd6c93e 100644 --- a/src/test/ledger/Invariants_test.cpp +++ b/src/test/ledger/Invariants_test.cpp @@ -28,7 +28,6 @@ #include #include -#include namespace ripple { @@ -137,7 +136,9 @@ class Invariants_test : public beast::unit_test::suite if (sink.messages().str().find(m) == std::string::npos) { // uncomment if you want to log the invariant failure - // message log << " --> " << m << std::endl; + // message + // log << sink.messages().str() << std::endl; + // log << " --> " << m << std::endl; fail(); } } @@ -1233,6 +1234,42 @@ class Invariants_test : public beast::unit_test::suite {tecINVARIANT_FAILED, tecINVARIANT_FAILED}); } + void + testLockedBalance() + { + using namespace test::jtx; + + testcase << "ValidLockedBalance"; + + doInvariantCheck( + {{"Invariant failed: IOU locked balance is greater than balance"}}, + [&](Account const& A1, Account const& A2, ApplyContext& ac) { + IOU const USD{A2["USD"]}; + auto const sle = + std::make_shared(keylet::line(A1, A2, USD.currency)); + sle->setFieldAmount(sfHighLimit, A1["USD"](100)); + sle->setFieldAmount(sfLowLimit, A2["USD"](100)); + sle->setFieldAmount(sfBalance, USD(100)); + sle->setFieldAmount(sfLockedBalance, USD(101)); + ac.view().insert(sle); + return true; + }); + + doInvariantCheck( + {{"Invariant failed: IOU locked balance is greater than balance"}}, + [&](Account const& A1, Account const& A2, ApplyContext& ac) { + IOU const USD{A2["USD"]}; + auto const sle = + std::make_shared(keylet::line(A1, A2, USD.currency)); + sle->setFieldAmount(sfHighLimit, A1["USD"](100)); + sle->setFieldAmount(sfLowLimit, A2["USD"](100)); + sle->setFieldAmount(sfBalance, USD(-100)); + sle->setFieldAmount(sfLockedBalance, USD(-101)); + ac.view().insert(sle); + return true; + }); + } + public: void run() override @@ -1251,6 +1288,7 @@ public: testValidNewAccountRoot(); testNFTokenPageInvariants(); testPermissionedDomainInvariants(); + testLockedBalance(); } }; diff --git a/src/test/protocol/Hooks_test.cpp b/src/test/protocol/Hooks_test.cpp index fb61d10a7..78c1b0d28 100644 --- a/src/test/protocol/Hooks_test.cpp +++ b/src/test/protocol/Hooks_test.cpp @@ -69,7 +69,6 @@ class Hooks_test : public beast::unit_test::suite sfHookAccount, sfEmittedTxn, sfHook, - sfHookDefinition, sfHookParameter, sfHookGrant, sfEmitDetails, diff --git a/src/xrpld/app/hook/detail/HookAPI.cpp b/src/xrpld/app/hook/detail/HookAPI.cpp index c3199f1d6..e3e05a235 100644 --- a/src/xrpld/app/hook/detail/HookAPI.cpp +++ b/src/xrpld/app/hook/detail/HookAPI.cpp @@ -2843,7 +2843,7 @@ HookAPI::meta_slot(uint32_t slot_into) const Expected, HookReturnCode> HookAPI::xpop_slot(uint32_t slot_into_tx, uint32_t slot_into_meta) const { - if (hookCtx.applyCtx.tx.getFieldU16(sfTransactionType) != ttIMPORT) + if (hookCtx.applyCtx.tx.getTxnType() != ttIMPORT) return Unexpected(PREREQUISITE_NOT_MET); if (slot_into_tx > hook_api::max_slots || diff --git a/src/xrpld/app/hook/detail/applyHook.cpp b/src/xrpld/app/hook/detail/applyHook.cpp index e7d00ec24..d6deb77f7 100644 --- a/src/xrpld/app/hook/detail/applyHook.cpp +++ b/src/xrpld/app/hook/detail/applyHook.cpp @@ -42,7 +42,7 @@ getTransactionalStakeHolders(STTx const& tx, ReadView const& rv) if (!otxnAcc) return {}; - uint16_t tt = tx.getFieldU16(sfTransactionType); + TxType const& tt = tx.getTxnType(); std::map> tshEntries; @@ -302,18 +302,14 @@ getTransactionalStakeHolders(STTx const& tx, ReadView const& rv) bool issuerCanRollback = nft::getFlags(nid) & tfStrongTSH; ADD_TSH(issuer, issuerCanRollback); - if (bo) + for (auto const& offer : {bo, so}) { - ADD_TSH(bo->getAccountID(sfOwner), tshSTRONG); - if (bo->isFieldPresent(sfDestination)) - ADD_TSH(bo->getAccountID(sfDestination), tshSTRONG); - } - - if (so) - { - ADD_TSH(so->getAccountID(sfOwner), tshSTRONG); - if (so->isFieldPresent(sfDestination)) - ADD_TSH(so->getAccountID(sfDestination), tshSTRONG); + if (offer) + { + ADD_TSH(offer->getAccountID(sfOwner), tshSTRONG); + if (offer->isFieldPresent(sfDestination)) + ADD_TSH(offer->getAccountID(sfDestination), tshSTRONG); + } } break; @@ -552,7 +548,8 @@ getTransactionalStakeHolders(STTx const& tx, ReadView const& rv) break; } case ttLEDGER_STATE_FIX: { - // TODO: Implement if needed + if (tx.isFieldPresent(sfOwner)) + ADD_TSH(tx.getAccountID(sfOwner), tshWEAK); break; } case ttMPTOKEN_ISSUANCE_CREATE: @@ -2745,26 +2742,23 @@ DEFINE_HOOK_FUNCTION( return serialize_keylet(kl, memory, write_ptr, write_len); } + // These keylet types are not yet implemented. Their + // corresponding amendments are not yet supported on the + // network. Each case needs a full implementation (see + // above cases for reference) before its amendment can be + // enabled. + // featureXChainBridge case keylet_code::BRIDGE: case keylet_code::XCHAIN_OWNED_CLAIM_ID: - case keylet_code::XCHAIN_OWNED_CREATE_ACCOUNT_CLAIM_ID: { - if (!applyCtx.view().rules().enabled(featureXChainBridge)) - return INVALID_ARGUMENT; - } + case keylet_code::XCHAIN_OWNED_CREATE_ACCOUNT_CLAIM_ID: + // featureMPTokensV1 case keylet_code::MPTOKEN_ISSUANCE: - case keylet_code::MPTOKEN: { - if (!applyCtx.view().rules().enabled(featureMPTokensV1)) - return INVALID_ARGUMENT; - } - case keylet_code::CREDENTIAL: { - if (!applyCtx.view().rules().enabled(featureCredentials)) - return INVALID_ARGUMENT; - } - case keylet_code::PERMISSIONED_DOMAIN: { - if (!applyCtx.view().rules().enabled( - featurePermissionedDomains)) - return INVALID_ARGUMENT; - } + case keylet_code::MPTOKEN: + // featureCredentials + case keylet_code::CREDENTIAL: + // featurePermissionedDomains + case keylet_code::PERMISSIONED_DOMAIN: + return INVALID_ARGUMENT; } } catch (std::exception& e) diff --git a/src/xrpld/app/paths/PathRequest.h b/src/xrpld/app/paths/PathRequest.h index 21f10d066..dc32c6a4d 100644 --- a/src/xrpld/app/paths/PathRequest.h +++ b/src/xrpld/app/paths/PathRequest.h @@ -170,7 +170,7 @@ private: std::chrono::steady_clock::time_point quick_reply_; std::chrono::steady_clock::time_point full_reply_; - static unsigned int const max_paths_ = 4; + static unsigned int const max_paths_ = 5; }; } // namespace ripple diff --git a/src/xrpld/app/paths/Pathfinder.cpp b/src/xrpld/app/paths/Pathfinder.cpp index 3732ee34e..aa9f8e3d9 100644 --- a/src/xrpld/app/paths/Pathfinder.cpp +++ b/src/xrpld/app/paths/Pathfinder.cpp @@ -1324,11 +1324,13 @@ Pathfinder::initPathTable() fillPaths( pt_nonXRP_to_XRP, - {{1, "sxd"}, // gateway buys XRP - {2, "saxd"}, // source -> gateway -> book(XRP) -> dest + {{1, "sxd"}, // gateway buys XRP + {2, "saxd"}, // source -> gateway -> book(XRP) -> dest + {5, "sabxd"}, // source -> gateway -> book -> book(XRP) -> dest {6, "saaxd"}, {7, "sbxd"}, - {8, "sabxd"}, + {8, + "sabbxd"}, // source -> gateway -> book -> book -> book(XRP) -> dest {9, "sabaxd"}}); // non-XRP to non-XRP (same currency) diff --git a/src/xrpld/app/tx/detail/ClaimReward.cpp b/src/xrpld/app/tx/detail/ClaimReward.cpp index e1b812e15..6f99c4884 100644 --- a/src/xrpld/app/tx/detail/ClaimReward.cpp +++ b/src/xrpld/app/tx/detail/ClaimReward.cpp @@ -82,8 +82,15 @@ ClaimReward::preclaim(PreclaimContext const& ctx) if ((issuer && isOptOut) || (!issuer && !isOptOut)) return temMALFORMED; - if (issuer && !ctx.view.exists(keylet::account(*issuer))) - return tecNO_ISSUER; + if (issuer) + { + auto const sleIssuer = ctx.view.read(keylet::account(*issuer)); + if (!sleIssuer) + return tecNO_ISSUER; + + if (sleIssuer->isFieldPresent(sfAMMID)) + return tecNO_PERMISSION; + } return tesSUCCESS; } diff --git a/src/xrpld/app/tx/detail/Import.cpp b/src/xrpld/app/tx/detail/Import.cpp index eccf3f06c..c48550e0f 100644 --- a/src/xrpld/app/tx/detail/Import.cpp +++ b/src/xrpld/app/tx/detail/Import.cpp @@ -932,6 +932,17 @@ Import::preclaim(PreclaimContext const& ctx) if (!ctx.tx.isFieldPresent(sfBlob)) return tefINTERNAL; + if (ctx.tx.isFieldPresent(sfIssuer) && + ctx.view.rules().enabled(fixImportIssuer)) + { + auto const sleIssuer = ctx.view.read(keylet::account(ctx.tx[sfIssuer])); + if (!sleIssuer) + return tecNO_ISSUER; + + if (sleIssuer->isFieldPresent(sfAMMID)) + return tecNO_PERMISSION; + } + // parse blob as json auto const xpop = syntaxCheckXPOP(ctx.tx.getFieldVL(sfBlob), ctx.j); @@ -1223,7 +1234,7 @@ Import::doRegularKey(std::shared_ptr& sle, STTx const& stpTrans) JLOG(ctx_.journal.trace()) << "Import: doRegularKey acc: " << id; - if (stpTrans.getFieldU16(sfTransactionType) != ttREGULAR_KEY_SET) + if (stpTrans.getTxnType() != ttREGULAR_KEY_SET) { JLOG(ctx_.journal.warn()) << "Import: doRegularKey called on non-regular key transaction."; diff --git a/src/xrpld/app/tx/detail/InvariantCheck.cpp b/src/xrpld/app/tx/detail/InvariantCheck.cpp index 6292e1eb6..e20718490 100644 --- a/src/xrpld/app/tx/detail/InvariantCheck.cpp +++ b/src/xrpld/app/tx/detail/InvariantCheck.cpp @@ -22,7 +22,6 @@ #include #include -#include #include #include #include @@ -402,7 +401,7 @@ NoZeroEscrow::finalize( if (bad_ && rv.rules().enabled(featurePaychanAndEscrowForTokens) && txn.isFieldPresent(sfTransactionType)) { - uint16_t const tt = txn.getFieldU16(sfTransactionType); + TxType const& tt = txn.getTxnType(); if (tt == ttESCROW_CANCEL || tt == ttESCROW_FINISH) return true; @@ -1984,4 +1983,44 @@ ValidAMM::finalize( return true; } +void +ValidLockedBalance::visitEntry( + bool, + std::shared_ptr const& before, + std::shared_ptr const& after) +{ + if (after && after->getType() == ltRIPPLE_STATE && + after->isFieldPresent(sfLockedBalance)) + { + iouIOULockedBalanceAfter_ = (*after)[sfLockedBalance]; + iouIOUBalanceAfter_ = (*after)[sfBalance]; + } +} + +bool +ValidLockedBalance::finalize( + STTx const& tx, + TER const result, + XRPAmount const, + ReadView const& view, + beast::Journal const& j) +{ + if (!view.rules().enabled(fixIOULockedBalanceInvariant)) + return true; + + if (iouIOULockedBalanceAfter_) + { + if ((!iouIOULockedBalanceAfter_->negative() && + *iouIOULockedBalanceAfter_ > *iouIOUBalanceAfter_) || + (iouIOULockedBalanceAfter_->negative() && + *iouIOULockedBalanceAfter_ < *iouIOUBalanceAfter_)) + { + JLOG(j.fatal()) << "Invariant failed: IOU locked balance is " + "greater than balance"; + return false; + } + } + + return true; +} } // namespace ripple diff --git a/src/xrpld/app/tx/detail/InvariantCheck.h b/src/xrpld/app/tx/detail/InvariantCheck.h index e854fd649..41445b137 100644 --- a/src/xrpld/app/tx/detail/InvariantCheck.h +++ b/src/xrpld/app/tx/detail/InvariantCheck.h @@ -680,6 +680,30 @@ private: beast::Journal const&) const; }; +class ValidLockedBalance +{ + std::optional iouIOULockedBalanceAfter_; + std::optional iouIOUBalanceAfter_; + +public: + ValidLockedBalance() + { + } + void + visitEntry( + bool, + std::shared_ptr const&, + std::shared_ptr const&); + + bool + finalize( + STTx const&, + TER const, + XRPAmount const, + ReadView const&, + beast::Journal const&); +}; + // additional invariant checks can be declared above and then added to this // tuple using InvariantChecks = std::tuple< @@ -700,7 +724,8 @@ using InvariantChecks = std::tuple< ValidClawback, ValidMPTIssuance, ValidPermissionedDomain, - ValidAMM>; + ValidAMM, + ValidLockedBalance>; /** * @brief get a tuple of all invariant checks diff --git a/src/xrpld/app/tx/detail/Invoke.cpp b/src/xrpld/app/tx/detail/Invoke.cpp index 869b7272c..baae9a554 100644 --- a/src/xrpld/app/tx/detail/Invoke.cpp +++ b/src/xrpld/app/tx/detail/Invoke.cpp @@ -64,8 +64,13 @@ Invoke::preclaim(PreclaimContext const& ctx) if (ctx.tx.isFieldPresent(sfDestination)) { - if (!ctx.view.exists(keylet::account(ctx.tx[sfDestination]))) + auto const sleDest = + ctx.view.read(keylet::account(ctx.tx[sfDestination])); + if (!sleDest) return tecNO_TARGET; + + if (sleDest->isFieldPresent(sfAMMID)) + return tecNO_PERMISSION; } return tesSUCCESS; diff --git a/src/xrpld/app/tx/detail/Payment.cpp b/src/xrpld/app/tx/detail/Payment.cpp index 6090cf6f7..316a309b9 100644 --- a/src/xrpld/app/tx/detail/Payment.cpp +++ b/src/xrpld/app/tx/detail/Payment.cpp @@ -573,7 +573,7 @@ Payment::doApply() return tecUNFUNDED_PAYMENT; } - // AMMs can never receive an XRP payment. + // AMMs can never receive an XAH payment. // Must use AMMDeposit transaction instead. if (sleDst->isFieldPresent(sfAMMID)) return tecNO_PERMISSION; diff --git a/src/xrpld/app/tx/detail/Remit.cpp b/src/xrpld/app/tx/detail/Remit.cpp index 5528d10d9..36a4a7ad2 100644 --- a/src/xrpld/app/tx/detail/Remit.cpp +++ b/src/xrpld/app/tx/detail/Remit.cpp @@ -256,11 +256,18 @@ Remit::doApply() if (ctx_.tx.isFieldPresent(sfInform)) { auto const informAcc = ctx_.tx.getAccountID(sfInform); - if (!sb.exists(keylet::account(informAcc))) + auto const sleInformAcc = sb.read(keylet::account(informAcc)); + if (!sleInformAcc) { JLOG(j.warn()) << "Remit: sfInform account does not exist."; return tecNO_TARGET; } + + if (sleInformAcc->isFieldPresent(sfAMMID)) + { + JLOG(j.warn()) << "Remit: sfInform account is an AMM."; + return tecNO_PERMISSION; + } } XRPAmount const accountReserve{sb.fees().accountReserve(0)}; @@ -288,6 +295,11 @@ Remit::doApply() (flags & lsfDisallowIncomingRemit)) return tecNO_PERMISSION; + // AMMs can never receive an XAH payment. + // Must use AMMDeposit transaction instead. + if (sleDstAcc && sleDstAcc->isFieldPresent(sfAMMID)) + return tecNO_PERMISSION; + // Check if the destination account requires deposit authorization. bool const depositAuth{sb.rules().enabled(featureDepositAuth)}; if (depositAuth && sleDstAcc && (flags & lsfDepositAuth)) diff --git a/src/xrpld/app/tx/detail/SetHook.cpp b/src/xrpld/app/tx/detail/SetHook.cpp index d1ba99905..e02ce6dbe 100644 --- a/src/xrpld/app/tx/detail/SetHook.cpp +++ b/src/xrpld/app/tx/detail/SetHook.cpp @@ -425,7 +425,7 @@ SetHook::validateHookSetEntry(SetHookCtx& ctx, STObject const& hookSetObj) JLOG(ctx.j.trace()) << "HookSet(" << hook::log::NAMESPACE_MISSING << ")[" << HS_ACC() - << "]: Malformed transaction: SetHook sfHookDefinition " + << "]: Malformed transaction: SetHook ltHookDefinition " "must contain sfHookNamespace."; return false; } @@ -2005,7 +2005,7 @@ SetHook::setHook() // sfHookHash, sfHookNamespace, sfHookOn, sfHookOnOutgoing, // sfHookOnIncoming, sfHookCanEmit sfHookApiVersion, sfFlags: free - // sfHookDefinition is not reserved because it is an unowned object, + // ltHookDefinition is not reserved because it is an unowned object, // rather the uploader is billed via fee according to the following: // sfCreateCode: 5000 drops per byte // sfHookParameters: 5000 drops per byte diff --git a/src/xrpld/app/tx/detail/Transactor.cpp b/src/xrpld/app/tx/detail/Transactor.cpp index 96ab76000..0541f3afb 100644 --- a/src/xrpld/app/tx/detail/Transactor.cpp +++ b/src/xrpld/app/tx/detail/Transactor.cpp @@ -308,7 +308,7 @@ Transactor::calculateBaseFee(ReadView const& view, STTx const& tx) // * The additional cost of each multisignature on the transaction. XRPAmount baseFee = view.fees().base; - if (tx.getFieldU16(sfTransactionType) == ttIMPORT) + if (tx.getTxnType() == ttIMPORT) { XRPAmount const importFee = baseFee * 10; if (importFee > baseFee) @@ -325,7 +325,7 @@ Transactor::calculateBaseFee(ReadView const& view, STTx const& tx) if (view.rules().enabled(featureHooks)) { // if this is a "cleanup" txn we regard it as already paid up - if (tx.getFieldU16(sfTransactionType) == ttEMIT_FAILURE) + if (tx.getTxnType() == ttEMIT_FAILURE) return XRPAmount{0}; // if the txn is an emitted txn then we add the callback fee @@ -1536,10 +1536,7 @@ Transactor::doHookCallback( true, true, false, - safe_cast(ctx_.tx.getFieldU16(sfTransactionType)) == - ttEMIT_FAILURE - ? 1UL - : 0UL, + ctx_.tx.getTxnType() == ttEMIT_FAILURE ? 1UL : 0UL, hook_no - 1, provisionalMeta); diff --git a/src/xrpld/app/tx/detail/URIToken.cpp b/src/xrpld/app/tx/detail/URIToken.cpp index 452fe8429..01cbbc635 100644 --- a/src/xrpld/app/tx/detail/URIToken.cpp +++ b/src/xrpld/app/tx/detail/URIToken.cpp @@ -180,7 +180,7 @@ URIToken::preclaim(PreclaimContext const& ctx) } AccountID const acc = ctx.tx.getAccountID(sfAccount); - uint16_t tt = ctx.tx.getFieldU16(sfTransactionType); + TxType const& tt = ctx.tx.getTxnType(); auto const sle = ctx.view.read(keylet::account(ctx.tx.getAccountID(sfAccount))); @@ -349,7 +349,7 @@ URIToken::doApply() if (!sle) return tefINTERNAL; - uint16_t tt = ctx_.tx.getFieldU16(sfTransactionType); + TxType const& tt = ctx_.tx.getTxnType(); if (tt == ttURITOKEN_MINT || tt == ttURITOKEN_BUY) { diff --git a/src/xrpld/rpc/BookChanges.h b/src/xrpld/rpc/BookChanges.h index c87fa0ccf..9e7e0804f 100644 --- a/src/xrpld/rpc/BookChanges.h +++ b/src/xrpld/rpc/BookChanges.h @@ -65,7 +65,7 @@ computeBookChanges(std::shared_ptr const& lpAccepted) continue; std::optional offerCancel; - uint16_t tt = tx.first->getFieldU16(sfTransactionType); + TxType const& tt = tx.first->getTxnType(); switch (tt) { case ttOFFER_CANCEL: diff --git a/src/xrpld/rpc/handlers/ServerDefinitions.cpp b/src/xrpld/rpc/handlers/ServerDefinitions.cpp index 798b7e047..2d3ce7372 100644 --- a/src/xrpld/rpc/handlers/ServerDefinitions.cpp +++ b/src/xrpld/rpc/handlers/ServerDefinitions.cpp @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #define MAGIC_ENUM(x, _min, _max) \