From 27fe5c66042e819a18efbd48e4dbf0c1575a2521 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sun, 15 Feb 2026 16:46:32 +0300 Subject: [PATCH 001/175] rsx: Fix input-side vs output-side remapping flags - Sign bit and biased renorm apply on input, Gamma on output --- rpcs3/Emu/RSX/RSXThread.cpp | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 0d9955b4d4..b7c1d2ca77 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -2332,19 +2332,47 @@ namespace rsx u32 unsigned_remap = 0; u32 gamma = 0; + auto remap_channel_bits = [](const rsx::texture_channel_remap_t& remap, u32 bits) -> u32 + { + if (!bits || remap.encoded == RSX_TEXTURE_REMAP_IDENTITY) [[ likely ]] + { + return bits; + } + + u32 result = 0; + for (u8 channel = 0; channel < 4; ++channel) + { + switch (remap.control_map[channel]) + { + case CELL_GCM_TEXTURE_REMAP_REMAP: + if (bits & (1u << remap.channel_map[channel])) + { + result |= (1u << channel); + } + break; + default: + break; + } + } + return result; + }; + + const auto texture_remap = tex.decoded_remap(); if (format_features & RSX_FORMAT_FEATURE_SIGNED_COMPONENTS) { - argb8_signed = tex.argb_signed(); + // Tests show this is applied pre-readout. It's just a property of the incoming bytes and is therefore subject to remap. + argb8_signed = remap_channel_bits(texture_remap, tex.argb_signed()); } if (format_features & RSX_FORMAT_FEATURE_GAMMA_CORRECTION) { + // Tests show this is applied post-readout. It's a property of the final value stored in the register and is not remapped. It overwrites even constant channels (REMAP_ZERO | REMAP_ONE) gamma = tex.gamma() & ~(argb8_signed); } if (format_features & RSX_FORMAT_FEATURE_BIASED_NORMALIZATION) { - // The renormalization flag applies to all channels + // The renormalization flag applies to all channels. It is weaker than the other flags. unsigned_remap = (tex.unsigned_remap() == CELL_GCM_TEXTURE_UNSIGNED_REMAP_NORMAL) ? 0u : 0xF; unsigned_remap &= ~(argb8_signed | gamma); } From 8a1b3237497c02e055c3b18ba3be4245e1a0e4d5 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sun, 15 Feb 2026 17:34:00 +0300 Subject: [PATCH 002/175] rsx/fp: Rework FP prepass analyzer to capture more information about bx2 expansion --- rpcs3/Emu/RSX/Program/ProgramStateCache.cpp | 84 ++++++++++----------- rpcs3/Emu/RSX/Program/ProgramStateCache.h | 1 + rpcs3/Emu/RSX/Program/RSXFragmentProgram.h | 8 ++ 3 files changed, 48 insertions(+), 45 deletions(-) diff --git a/rpcs3/Emu/RSX/Program/ProgramStateCache.cpp b/rpcs3/Emu/RSX/Program/ProgramStateCache.cpp index 45b2da4af6..15546afd7e 100644 --- a/rpcs3/Emu/RSX/Program/ProgramStateCache.cpp +++ b/rpcs3/Emu/RSX/Program/ProgramStateCache.cpp @@ -1,5 +1,6 @@ #include "stdafx.h" #include "ProgramStateCache.h" +#include "FragmentProgramDecompiler.h" #include "Emu/system_config.h" #include "Emu/RSX/Core/RSXDriverState.h" #include "util/sysinfo.hpp" @@ -637,58 +638,51 @@ fragment_program_utils::fragment_program_metadata fragment_program_utils::analys while (true) { const auto inst = v128::loadu(instBuffer, index); + const auto d0 = OPDEST::from_be32(inst._u32[0]); + const auto opcode = static_cast(d0.opcode); - // Check for opcode high bit which indicates a branch instructions (opcode 0x40...0x45) - if (inst._u32[2] & (1 << 23)) + switch (opcode) { + case RSX_FP_OPCODE_TEX: + case RSX_FP_OPCODE_TEXBEM: + case RSX_FP_OPCODE_TXP: + case RSX_FP_OPCODE_TXPBEM: + case RSX_FP_OPCODE_TXD: + case RSX_FP_OPCODE_TXB: + case RSX_FP_OPCODE_TXL: + result.referenced_textures_mask |= (1 << d0.tex_num); + result.has_tex_bx2_conv |= !!d0.exp_tex; + break; + case RSX_FP_OPCODE_PK4: + case RSX_FP_OPCODE_UP4: + case RSX_FP_OPCODE_PK2: + case RSX_FP_OPCODE_UP2: + case RSX_FP_OPCODE_PKB: + case RSX_FP_OPCODE_UPB: + case RSX_FP_OPCODE_PK16: + case RSX_FP_OPCODE_UP16: + case RSX_FP_OPCODE_PKG: + case RSX_FP_OPCODE_UPG: + result.has_pack_instructions = true; + break; + case RSX_FP_OPCODE_BRK: + case RSX_FP_OPCODE_CAL: + case RSX_FP_OPCODE_IFE: + case RSX_FP_OPCODE_LOOP: + case RSX_FP_OPCODE_REP: + case RSX_FP_OPCODE_RET: // NOTE: Jump instructions are not yet proved to work outside of loops and if/else blocks // Otherwise we would need to follow the execution chain result.has_branch_instructions = true; + break; } - else - { - const u32 opcode = (inst._u32[0] >> 16) & 0x3F; - if (opcode) - { - switch (opcode) - { - case RSX_FP_OPCODE_TEX: - case RSX_FP_OPCODE_TEXBEM: - case RSX_FP_OPCODE_TXP: - case RSX_FP_OPCODE_TXPBEM: - case RSX_FP_OPCODE_TXD: - case RSX_FP_OPCODE_TXB: - case RSX_FP_OPCODE_TXL: - { - //Bits 17-20 of word 1, swapped within u16 sections - //Bits 16-23 are swapped into the upper 8 bits (24-31) - const u32 tex_num = (inst._u32[0] >> 25) & 15; - result.referenced_textures_mask |= (1 << tex_num); - break; - } - case RSX_FP_OPCODE_PK4: - case RSX_FP_OPCODE_UP4: - case RSX_FP_OPCODE_PK2: - case RSX_FP_OPCODE_UP2: - case RSX_FP_OPCODE_PKB: - case RSX_FP_OPCODE_UPB: - case RSX_FP_OPCODE_PK16: - case RSX_FP_OPCODE_UP16: - case RSX_FP_OPCODE_PKG: - case RSX_FP_OPCODE_UPG: - { - result.has_pack_instructions = true; - break; - } - } - } - if (is_any_src_constant(inst)) - { - //Instruction references constant, skip one slot occupied by data - index++; - result.program_constants_buffer_length += 16; - } + if (rsx::assembler::FP::get_operand_count(opcode) > 0 && + is_any_src_constant(inst)) + { + // Instruction references constant, skip one slot occupied by data + index++; + result.program_constants_buffer_length += 16; } index++; diff --git a/rpcs3/Emu/RSX/Program/ProgramStateCache.h b/rpcs3/Emu/RSX/Program/ProgramStateCache.h index efd5dd326a..ce5be4a425 100644 --- a/rpcs3/Emu/RSX/Program/ProgramStateCache.h +++ b/rpcs3/Emu/RSX/Program/ProgramStateCache.h @@ -59,6 +59,7 @@ namespace program_hash_util bool has_pack_instructions; bool has_branch_instructions; + bool has_tex_bx2_conv; bool is_nop_shader; // Does this affect Z-pass testing??? }; diff --git a/rpcs3/Emu/RSX/Program/RSXFragmentProgram.h b/rpcs3/Emu/RSX/Program/RSXFragmentProgram.h index d93ec760e6..7bb8517b85 100644 --- a/rpcs3/Emu/RSX/Program/RSXFragmentProgram.h +++ b/rpcs3/Emu/RSX/Program/RSXFragmentProgram.h @@ -54,6 +54,14 @@ union OPDEST u32 : 9; u32 write_mask : 4; }; + + static OPDEST from_be32(u32 be_word) + { + const u32 _hex = + ((be_word & 0x00FF00FF) << 8) | + ((be_word & 0xFF00FF00) >> 8); + return OPDEST{ .HEX = _hex }; + } }; union SRC0 From b30a44c1367635af0675f61504e1ca45263655c6 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sun, 15 Feb 2026 18:15:42 +0300 Subject: [PATCH 003/175] rsx: Make BX2 flag respect constant overrides --- .../RSXProg/RSXFragmentTextureOps.glsl | 2 +- rpcs3/Emu/RSX/RSXThread.cpp | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXProg/RSXFragmentTextureOps.glsl b/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXProg/RSXFragmentTextureOps.glsl index a59e8ae3a1..43dcf9e6eb 100644 --- a/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXProg/RSXFragmentTextureOps.glsl +++ b/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXProg/RSXFragmentTextureOps.glsl @@ -34,7 +34,7 @@ R"( #define _enable_texture_expand(index) \ do { \ if (_test_bit(TEX_PARAM(index).flags, FORMAT_FEATURE_BIASED_RENORMALIZATION_BIT)) { \ - _texture_flag_override = SIGN_EXPAND_MASK; \ + _texture_flag_override = SIGN_EXPAND_MASK & (_get_bits(TEX_PARAM(index).remap, 16, 4) << EXPAND_A_BIT); \ _texture_flag_erase = GAMMA_CTRL_MASK; \ _texture_bx2_active = true; \ } \ diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index b7c1d2ca77..5b4b732c4d 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -2366,15 +2366,19 @@ namespace rsx if (format_features & RSX_FORMAT_FEATURE_GAMMA_CORRECTION) { - // Tests show this is applied post-readout. It's a property of the final value stored in the register and is not remapped. It overwrites even constant channels (REMAP_ZERO | REMAP_ONE) + // Tests show this is applied post-readout. It's a property of the final value stored in the register and is not remapped. + // NOTE: GAMMA correction has no algorithmic effect on constants (0 and 1) so we need not mask it out for correctness. gamma = tex.gamma() & ~(argb8_signed); } if (format_features & RSX_FORMAT_FEATURE_BIASED_NORMALIZATION) { // The renormalization flag applies to all channels. It is weaker than the other flags. - unsigned_remap = (tex.unsigned_remap() == CELL_GCM_TEXTURE_UNSIGNED_REMAP_NORMAL) ? 0u : 0xF; - unsigned_remap &= ~(argb8_signed | gamma); + // This applies on input and is subject to remap overrides + if (tex.unsigned_remap() == CELL_GCM_TEXTURE_UNSIGNED_REMAP_BIASED) + { + unsigned_remap = remap_channel_bits(texture_remap, 0xF) & ~(argb8_signed | gamma); + } } u32 argb8_convert = gamma; @@ -2390,6 +2394,13 @@ namespace rsx texture_control |= argb8_convert; texture_control |= format_features << texture_control_bits::FORMAT_FEATURES_OFFSET; + + if (current_fp_metadata.has_tex_bx2_conv) + { + const u32 remap_hi = remap_channel_bits(texture_remap, 0xFu); + current_fragment_program.texture_params[i].remap &= ~(0xFu << 16u); + current_fragment_program.texture_params[i].remap |= (remap_hi << 16u); + } } current_fragment_program.texture_params[i].control = texture_control; From 0faa8945bc20956ce5ddc3b00aa0cd5ad33110bb Mon Sep 17 00:00:00 2001 From: kd-11 Date: Wed, 18 Feb 2026 02:25:13 +0300 Subject: [PATCH 004/175] rsx/vk: Fix bug with custom border color sampler storage - If an app used multiple border colors, only the first one was being applied. --- rpcs3/Emu/RSX/VK/VKDraw.cpp | 2 +- rpcs3/Emu/RSX/VK/vkutils/sampler.cpp | 14 +++----------- rpcs3/Emu/RSX/VK/vkutils/sampler.h | 18 +++++++++++++++++- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/rpcs3/Emu/RSX/VK/VKDraw.cpp b/rpcs3/Emu/RSX/VK/VKDraw.cpp index 59f9bfb40a..491078cc93 100644 --- a/rpcs3/Emu/RSX/VK/VKDraw.cpp +++ b/rpcs3/Emu/RSX/VK/VKDraw.cpp @@ -275,7 +275,7 @@ void VKGSRender::load_texture_env() auto get_border_color = [&](const rsx::Texture auto& tex) { - return m_device->get_custom_border_color_support().require_border_color_remap + return m_device->get_custom_border_color_support().require_border_color_remap ? tex.remapped_border_color() : rsx::decode_border_color(tex.border_color()); }; diff --git a/rpcs3/Emu/RSX/VK/vkutils/sampler.cpp b/rpcs3/Emu/RSX/VK/vkutils/sampler.cpp index 073fc514d0..53066e2f4a 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/sampler.cpp +++ b/rpcs3/Emu/RSX/VK/vkutils/sampler.cpp @@ -182,16 +182,8 @@ namespace vk return found == m_generic_sampler_pool.end() ? nullptr : found->second.get(); } - const auto block = m_custom_color_sampler_pool.equal_range(key.base_key); - for (auto it = block.first; it != block.second; ++it) - { - if (it->second->key.border_color_key == key.border_color_key) - { - return it->second.get(); - } - } - - return nullptr; + const auto found = m_custom_color_sampler_pool.find(key); + return found == m_custom_color_sampler_pool.end() ? nullptr : found->second.get(); } cached_sampler_object_t* sampler_pool_t::emplace(const sampler_pool_key_t& key, std::unique_ptr& object) @@ -204,7 +196,7 @@ namespace vk return iterator->second.get(); } - const auto [iterator, _unused] = m_custom_color_sampler_pool.emplace(key.base_key, std::move(object)); + const auto [iterator, _unused] = m_custom_color_sampler_pool.emplace(key, std::move(object)); return iterator->second.get(); } diff --git a/rpcs3/Emu/RSX/VK/vkutils/sampler.h b/rpcs3/Emu/RSX/VK/vkutils/sampler.h index f1d81d542f..232f1073d7 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/sampler.h +++ b/rpcs3/Emu/RSX/VK/vkutils/sampler.h @@ -64,6 +64,22 @@ namespace vk { u64 base_key; u64 border_color_key; + + bool operator == (const sampler_pool_key_t& that) const + { + return this->base_key == that.base_key && + this->border_color_key == that.border_color_key; + } + }; + + struct sampler_pool_key_hash + { + size_t operator()(const vk::sampler_pool_key_t& k) const noexcept + { + usz result = k.base_key; + result ^= k.border_color_key + 0x9e3779b97f4a7c15ULL + (result << 6) + (result >> 2); + return result; + } }; struct cached_sampler_object_t : public vk::sampler, public rsx::ref_counted @@ -75,7 +91,7 @@ namespace vk class sampler_pool_t { std::unordered_map> m_generic_sampler_pool; - std::unordered_map> m_custom_color_sampler_pool; + std::unordered_map, sampler_pool_key_hash> m_custom_color_sampler_pool; public: From dc63f2fc1f75316987f4e4b898f0792db91d8f65 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Wed, 18 Feb 2026 03:07:50 +0300 Subject: [PATCH 005/175] rsx: Correct border-color register value for shader texel remapping - PS3 border color does not correctly support signed channels and instead treats them as simple compression - We instead perform the reverse conversion before sending it to our shader pipeline --- rpcs3/Emu/RSX/RSXTexture.cpp | 73 +++++++++++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) diff --git a/rpcs3/Emu/RSX/RSXTexture.cpp b/rpcs3/Emu/RSX/RSXTexture.cpp index 52f8183545..e770923696 100644 --- a/rpcs3/Emu/RSX/RSXTexture.cpp +++ b/rpcs3/Emu/RSX/RSXTexture.cpp @@ -4,6 +4,15 @@ #include "rsx_utils.h" #include "Emu/system_config.h" +#include "util/simd.hpp" + +#if defined(ARCH_ARM64) +#if !defined(_MSC_VER) +#pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif +#undef FORCE_INLINE +#include "Emu/CPU/sse2neon.h" +#endif namespace rsx { @@ -291,7 +300,69 @@ namespace rsx u32 fragment_texture::border_color() const { - return registers[NV4097_SET_TEXTURE_BORDER_COLOR + (m_index * 8)]; + const u32 raw = registers[NV4097_SET_TEXTURE_BORDER_COLOR + (m_index * 8)]; + const u32 sext = argb_signed(); + + if (!sext) [[ likely ]] + { + return raw; + } + + // Border color is broken on PS3. The SNORM behavior is completely broken and behaves like BIASED renormalization instead. + // To solve the mismatch, we need to first do a bit expansion on the value then store it as sign extended. The second part is a natural part of numbers on a binary system, so we only need to do the former. + static constexpr u32 expand4_lut[16] = + { + 0x00000000u, // 0000 + 0xFF000000u, // 0001 + 0x00FF0000u, // 0010 + 0xFFFF0000u, // 0011 + 0x0000FF00u, // 0100 + 0xFF00FF00u, // 0101 + 0x00FFFF00u, // 0110 + 0xFFFFFF00u, // 0111 + 0x000000FFu, // 1000 + 0xFF0000FFu, // 1001 + 0x00FF00FFu, // 1010 + 0xFFFF00FFu, // 1011 + 0x0000FFFFu, // 1100 + 0xFF00FFFFu, // 1101 + 0x00FFFFFFu, // 1110 + 0xFFFFFFFFu // 1111 + }; + + // Bit pattern expand and reverse BE -> LE using LUT + const u32 mask = expand4_lut[sext]; + + // Now we perform the compensation operation + // BIAS operation = (V - 128 / 127) + + // Load + const __m128i _0 = _mm_setzero_si128(); + const __m128i _128 = _mm_set1_epi32(128); + const __m128i _127 = _mm_set1_epi32(127); + const __m128i _255 = _mm_set1_epi32(255); + + const auto be_raw = be_t(raw); + __m128i v = _mm_cvtsi32_si128(static_cast(be_raw)); + v = _mm_unpacklo_epi8(v, _0); + v = _mm_unpacklo_epi16(v, _0); // [ 0, 64, 255, 128 ] + + // Conversion: x = (y - 128) + v = _mm_sub_epi32(v, _128); // [ -128, -64, 127, 0 ] + + // Convert to signed encoding (reverse sext) + v = _mm_slli_epi32(v, 24); + v = _mm_srli_epi32(v, 24); + + // Pack down + v = _mm_packs_epi32(v, _0); + v = _mm_packus_epi16(v, _0); + + // Read + const u32 conv = _mm_cvtsi128_si32(v); + + // Merge + return (conv & mask) | (raw & ~mask); } color4f fragment_texture::remapped_border_color() const From 2064bd87e37da1d0946f7c5b62f2d38003abff8e Mon Sep 17 00:00:00 2001 From: kd-11 Date: Wed, 18 Feb 2026 03:26:51 +0300 Subject: [PATCH 006/175] rsx: Fix GCC build --- rpcs3/Emu/RSX/RSXTexture.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/rpcs3/Emu/RSX/RSXTexture.cpp b/rpcs3/Emu/RSX/RSXTexture.cpp index e770923696..b3f9dc1962 100644 --- a/rpcs3/Emu/RSX/RSXTexture.cpp +++ b/rpcs3/Emu/RSX/RSXTexture.cpp @@ -6,6 +6,11 @@ #include "Emu/system_config.h" #include "util/simd.hpp" +#if !defined(_MSC_VER) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wold-style-cast" +#endif + #if defined(ARCH_ARM64) #if !defined(_MSC_VER) #pragma GCC diagnostic ignored "-Wstrict-aliasing" From 53dcf2ba00b0f1395d6e782841fdd6a8558e121a Mon Sep 17 00:00:00 2001 From: RipleyTom Date: Thu, 19 Feb 2026 22:18:34 +0100 Subject: [PATCH 007/175] rpcn_client: Misc fixes Fix missing freeaddrinfo Fix wrong return value in a rpcn_client::connect() path Fix missing 0 presence validation in vec_stream::get_string() --- rpcs3/Emu/NP/rpcn_client.cpp | 6 ++++-- rpcs3/Emu/NP/rpcn_client.h | 8 ++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/rpcs3/Emu/NP/rpcn_client.cpp b/rpcs3/Emu/NP/rpcn_client.cpp index d7bb274c66..38a4ad95ca 100644 --- a/rpcs3/Emu/NP/rpcn_client.cpp +++ b/rpcs3/Emu/NP/rpcn_client.cpp @@ -896,7 +896,7 @@ namespace rpcn return error_and_disconnect("Failed to send all the bytes"); } - res = 0; + continue; } n_sent += res; } @@ -1055,6 +1055,8 @@ namespace rpcn found = found->ai_next; } + freeaddrinfo(addr_info); + if (!found_ipv4) { rpcn_log.error("connect: Failed to find IPv4 for %s", host); @@ -1156,7 +1158,7 @@ namespace rpcn if (!connected || terminate) { state = rpcn_state::failure_other; - return true; + return false; } if (received_version != RPCN_PROTOCOL_VERSION) diff --git a/rpcs3/Emu/NP/rpcn_client.h b/rpcs3/Emu/NP/rpcn_client.h index 56ba17d04d..377cd9c898 100644 --- a/rpcs3/Emu/NP/rpcn_client.h +++ b/rpcs3/Emu/NP/rpcn_client.h @@ -79,6 +79,14 @@ public: res.push_back(vec[i]); i++; } + + // Make sure we hit terminating 0 + if (i >= vec.size()) + { + error = true; + return {}; + } + i++; if (!empty && res.empty()) From b7b0e06a5404306b37299f204e11082684c3729e Mon Sep 17 00:00:00 2001 From: RipleyTom Date: Thu, 19 Feb 2026 23:44:10 +0100 Subject: [PATCH 008/175] sys_net/lv2_socket_native: Various fixes Fix is_socket_connected(always returned false) Implement SYS_NET_IP_TTLCHK and SYS_NET_IP_MAXTTL Fix lv2_socket_native::sendmsg, it was only sending the first iovec Fix sys_net_bnet_sendto addrlen check Fix assert in lv2_socket_native::recvfrom() --- rpcs3/Emu/Cell/lv2/sys_net.cpp | 2 +- rpcs3/Emu/Cell/lv2/sys_net.h | 2 +- .../Cell/lv2/sys_net/lv2_socket_native.cpp | 50 ++++++++++--------- .../Emu/Cell/lv2/sys_net/lv2_socket_native.h | 4 ++ 4 files changed, 33 insertions(+), 25 deletions(-) diff --git a/rpcs3/Emu/Cell/lv2/sys_net.cpp b/rpcs3/Emu/Cell/lv2/sys_net.cpp index 827a4c98f2..27731e44ca 100644 --- a/rpcs3/Emu/Cell/lv2/sys_net.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_net.cpp @@ -992,7 +992,7 @@ error_code sys_net_bnet_sendto(ppu_thread& ppu, s32 s, vm::cptr buf, u32 l fmt::throw_exception("sys_net_bnet_sendto(s=%d): unknown flags (0x%x)", flags); } - if (addr && addrlen < 8) + if (addr && addrlen < sizeof(sys_net_sockaddr)) { sys_net.error("sys_net_bnet_sendto(s=%d): bad addrlen (%u)", s, addrlen); return -SYS_NET_EINVAL; diff --git a/rpcs3/Emu/Cell/lv2/sys_net.h b/rpcs3/Emu/Cell/lv2/sys_net.h index b1f9ef7268..68e7041df0 100644 --- a/rpcs3/Emu/Cell/lv2/sys_net.h +++ b/rpcs3/Emu/Cell/lv2/sys_net.h @@ -107,7 +107,7 @@ enum lv2_ip_option : s32 SYS_NET_IP_MULTICAST_LOOP = 11, SYS_NET_IP_ADD_MEMBERSHIP = 12, SYS_NET_IP_DROP_MEMBERSHIP = 13, - SYS_NET_IP_TTLCHK = 23, + SYS_NET_IP_TTLCHK = 23, // This is probably the equivalent of IP_MINTTL on FreeBSD SYS_NET_IP_MAXTTL = 24, SYS_NET_IP_DONTFRAG = 26 }; diff --git a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_native.cpp b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_native.cpp index d420f23cc8..2eb47d7b55 100644 --- a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_native.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_native.cpp @@ -551,12 +551,14 @@ std::tuple lv2_socket_native::getsockopt(s32 } case SYS_NET_IP_TTLCHK: { - sys_net.error("sys_net_bnet_getsockopt(IPPROTO_IP, SYS_NET_IP_TTLCHK): stubbed option"); + out_val._int = min_ttl; + out_len = sizeof(s32); return {CELL_OK, out_val, out_len}; } case SYS_NET_IP_MAXTTL: { - sys_net.error("sys_net_bnet_getsockopt(IPPROTO_IP, SYS_NET_IP_MAXTTL): stubbed option"); + out_val._int = max_ttl; + out_len = sizeof(s32); return {CELL_OK, out_val, out_len}; } case SYS_NET_IP_DONTFRAG: @@ -834,13 +836,13 @@ s32 lv2_socket_native::setsockopt(s32 level, s32 optname, const std::vector& } case SYS_NET_IP_TTLCHK: { - sys_net.error("sys_net_bnet_setsockopt(s=%d, IPPROTO_IP): Stubbed option (0x%x) (SYS_NET_IP_TTLCHK)", lv2_id, optname); - break; + min_ttl = native_int; + return {}; } case SYS_NET_IP_MAXTTL: { - sys_net.error("sys_net_bnet_setsockopt(s=%d, IPPROTO_IP): Stubbed option (0x%x) (SYS_NET_IP_MAXTTL)", lv2_id, optname); - break; + max_ttl = native_int; + return {}; } case SYS_NET_IP_DONTFRAG: { @@ -910,7 +912,7 @@ std::optional, sys_net_sockaddr>> lv2_socket_nat { auto& nph = g_fxo->get>(); const auto packet = dnshook.get_dns_packet(lv2_id); - ensure(packet.size() < len); + ensure(packet.size() <= len); memcpy(res_buf.data(), packet.data(), packet.size()); native_addr.ss_family = AF_INET; (reinterpret_cast<::sockaddr_in*>(&native_addr))->sin_port = std::bit_cast>(53); // htons(53) @@ -1069,18 +1071,20 @@ std::optional lv2_socket_native::sendmsg(s32 flags, const sys_net_msghdr& m return {-SYS_NET_ECONNRESET}; } + std::vector buf_copy; for (int i = 0; i < msg.msg_iovlen; i++) { auto iov_base = msg.msg_iov[i].iov_base; const u32 len = msg.msg_iov[i].iov_len; - const std::vector buf_copy(vm::_ptr(iov_base.addr()), vm::_ptr(iov_base.addr()) + len); + const auto* src = vm::_ptr(iov_base.addr()); + buf_copy.insert(buf_copy.end(), src, src + len); + } - native_result = ::send(native_socket, reinterpret_cast(buf_copy.data()), ::narrow(buf_copy.size()), native_flags); + native_result = ::send(native_socket, reinterpret_cast(buf_copy.data()), ::narrow(buf_copy.size()), native_flags); - if (native_result >= 0) - { - return {native_result}; - } + if (native_result >= 0) + { + return {native_result}; } result = get_last_error(!so_nbio && (flags & SYS_NET_MSG_DONTWAIT) == 0); @@ -1232,16 +1236,16 @@ bool lv2_socket_native::is_socket_connected() return false; } - fd_set readfds, writefds; - struct timeval timeout{0, 0}; // Zero timeout + pollfd pfd{}; + pfd.fd = native_socket; + pfd.events = POLLIN | POLLOUT; - FD_ZERO(&readfds); - FD_ZERO(&writefds); - FD_SET(native_socket, &readfds); - FD_SET(native_socket, &writefds); - - // Use select to check for readability and writability - const int result = ::select(1, &readfds, &writefds, NULL, &timeout); + // Use poll to check for readability and writability +#ifdef _WIN32 + const int result = WSAPoll(&pfd, 1, 0); +#else + const int result = ::poll(&pfd, 1, 0); +#endif if (result < 0) { @@ -1250,5 +1254,5 @@ bool lv2_socket_native::is_socket_connected() } // Socket is connected if it's readable or writable - return FD_ISSET(native_socket, &readfds) || FD_ISSET(native_socket, &writefds); + return (pfd.revents & (POLLIN | POLLOUT)) != 0; } diff --git a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_native.h b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_native.h index cf07dfcb76..84f4218cbd 100644 --- a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_native.h +++ b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_native.h @@ -70,6 +70,10 @@ private: s32 so_reuseaddr = 0; s32 so_reuseport = 0; #endif + // Those values come from FreeBSD + s32 min_ttl = 1; + s32 max_ttl = 64; + u16 bound_port = 0; bool feign_tcp_conn_failure = false; // Savestate load related }; From aaf84a844542cf0697c19cb0d8579eff705b10c5 Mon Sep 17 00:00:00 2001 From: RipleyTom Date: Fri, 20 Feb 2026 00:53:12 +0100 Subject: [PATCH 009/175] sys_net/P2P: Various fixes Fix RTT adjustment Fix possible dead pointer interaction in lv2_socket_native::recvfrom() Fix iterator invalidation in nt_p2p_port::recv_data() --- rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2ps.cpp | 5 ++--- rpcs3/Emu/Cell/lv2/sys_net/nt_p2p_port.cpp | 10 ++++++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2ps.cpp b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2ps.cpp index c0790a2e33..771402809e 100644 --- a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2ps.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2ps.cpp @@ -112,7 +112,6 @@ public: // reply is late, increases rtt auto& msg = it->second; - const auto addr = msg.dst_addr.sin_addr.s_addr; rtt_info rtt = rtts[msg.sock_id]; // Only increases rtt once per loop(in case a big number of packets are sent at once) if (!rtt_increased.count(msg.sock_id)) @@ -120,7 +119,7 @@ public: rtt.num_retries += 1; // Increases current rtt by 10% rtt.rtt_time += (rtt.rtt_time / 10); - rtts[addr] = rtt; + rtts[msg.sock_id] = rtt; rtt_increased.emplace(msg.sock_id); } @@ -625,7 +624,7 @@ std::tuple, sys_net_sockaddr> lv2_socket_p2ps: sys_net_sockaddr ps3_addr{}; auto* paddr = reinterpret_cast(&ps3_addr); - lv2_socket_p2ps* sock_client = reinterpret_cast(idm::check_unlocked(p2ps_client)); + auto sock_client = static_cast>(idm::get_unlocked(p2ps_client)); { std::lock_guard lock(sock_client->mutex); paddr->sin_family = SYS_NET_AF_INET; diff --git a/rpcs3/Emu/Cell/lv2/sys_net/nt_p2p_port.cpp b/rpcs3/Emu/Cell/lv2/sys_net/nt_p2p_port.cpp index 61039c7856..67be0df63b 100644 --- a/rpcs3/Emu/Cell/lv2/sys_net/nt_p2p_port.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_net/nt_p2p_port.cpp @@ -249,8 +249,9 @@ bool nt_p2p_port::recv_data() auto& bound_sockets = ::at32(bound_p2p_vports, dst_vport); - for (const auto sock_id : bound_sockets) + for (auto it = bound_sockets.begin(); it != bound_sockets.end();) { + s32 sock_id = *it; const auto sock = idm::check(sock_id, [&](lv2_socket& sock) { ensure(sock.get_type() == SYS_NET_SOCK_DGRAM_P2P); @@ -262,12 +263,17 @@ bool nt_p2p_port::recv_data() if (!sock) { sys_net.error("Socket %d found in bound_p2p_vports didn't exist!", sock_id); - bound_sockets.erase(sock_id); + it = bound_sockets.erase(it); if (bound_sockets.empty()) { bound_p2p_vports.erase(dst_vport); + break; } } + else + { + it++; + } } return true; From ff992a67c8e1c1eb83c39ab619c1eab564e80c36 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Thu, 19 Feb 2026 23:58:34 +0100 Subject: [PATCH 010/175] win/fs: check file handle with GetFileInformationByHandle when creating fs::file On empty mounted drives CreateFileW may return a valid handle even if the drive is not usable. We have to check the file handle early. Otherwise other functions may fail later as a result. --- Utilities/File.cpp | 24 +++++++++++++++++------- Utilities/File.h | 14 +++++++------- rpcs3/Loader/ISO.h | 16 ++++++++-------- 3 files changed, 32 insertions(+), 22 deletions(-) diff --git a/Utilities/File.cpp b/Utilities/File.cpp index 30e6414675..d2adb22c61 100644 --- a/Utilities/File.cpp +++ b/Utilities/File.cpp @@ -398,12 +398,11 @@ namespace fs class windows_file final : public file_base { HANDLE m_handle; - atomic_t m_pos; + atomic_t m_pos {0}; public: windows_file(HANDLE handle) : m_handle(handle) - , m_pos(0) { } @@ -417,10 +416,10 @@ namespace fs stat_t get_stat() override { - FILE_BASIC_INFO basic_info; + FILE_BASIC_INFO basic_info {}; ensure(GetFileInformationByHandleEx(m_handle, FileBasicInfo, &basic_info, sizeof(FILE_BASIC_INFO))); // "file::stat" - stat_t info; + stat_t info {}; info.is_directory = (basic_info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; info.is_writable = (basic_info.FileAttributes & FILE_ATTRIBUTE_READONLY) == 0; info.size = this->size(); @@ -441,7 +440,7 @@ namespace fs bool trunc(u64 length) override { - FILE_END_OF_FILE_INFO _eof; + FILE_END_OF_FILE_INFO _eof {}; _eof.EndOfFile.QuadPart = length; if (!SetFileInformationByHandle(m_handle, FileEndOfFileInfo, &_eof, sizeof(_eof))) @@ -563,6 +562,7 @@ namespace fs u64 size() override { + // NOTE: this can fail if we access a mounted empty drive (e.g. after unmounting an iso). LARGE_INTEGER size; ensure(GetFileSizeEx(m_handle, &size)); // "file::size" @@ -579,7 +579,7 @@ namespace fs file_id id{"windows_file"}; id.data.resize(sizeof(FILE_ID_INFO)); - FILE_ID_INFO info; + FILE_ID_INFO info {}; if (!GetFileInformationByHandleEx(m_handle, FileIdInfo, &info, sizeof(info))) { @@ -625,7 +625,7 @@ namespace fs struct ::stat file_info; ensure(::fstat(m_fd, &file_info) == 0); // "file::stat" - stat_t info; + stat_t info {}; info.is_directory = S_ISDIR(file_info.st_mode); info.is_writable = file_info.st_mode & 0200; // HACK: approximation info.size = file_info.st_size; @@ -1656,6 +1656,16 @@ fs::file::file(const std::string& path, bs_t mode) return; } + // Check if the handle is actually valid. + // This can fail on empty mounted drives (e.g. with ERROR_NOT_READY or ERROR_INVALID_FUNCTION). + BY_HANDLE_FILE_INFORMATION info; + if (!GetFileInformationByHandle(handle, &info)) + { + CloseHandle(handle); + g_tls_error = to_error(GetLastError()); + return; + } + m_file = std::make_unique(handle); #else int flags = O_CLOEXEC; // Ensures all files are closed on execl for auto updater diff --git a/Utilities/File.h b/Utilities/File.h index 7e6356da7b..dd2db42a46 100644 --- a/Utilities/File.h +++ b/Utilities/File.h @@ -66,13 +66,13 @@ namespace fs // File attributes (TODO) struct stat_t { - bool is_directory; - bool is_symlink; - bool is_writable; - u64 size; - s64 atime; - s64 mtime; - s64 ctime; + bool is_directory = false; + bool is_symlink = false; + bool is_writable = false; + u64 size = 0; + s64 atime = 0; + s64 mtime = 0; + s64 ctime = 0; using enable_bitcopy = std::true_type; diff --git a/rpcs3/Loader/ISO.h b/rpcs3/Loader/ISO.h index 3af4732aad..588e4b8491 100644 --- a/rpcs3/Loader/ISO.h +++ b/rpcs3/Loader/ISO.h @@ -13,16 +13,16 @@ void unload_iso(); struct iso_extent_info { - u64 start; - u64 size; + u64 start = 0; + u64 size = 0; }; struct iso_fs_metadata { std::string name; - s64 time; - bool is_directory; - bool has_multiple_extents; + s64 time = 0; + bool is_directory = false; + bool has_multiple_extents = false; std::vector extents; u64 size() const; @@ -30,7 +30,7 @@ struct iso_fs_metadata struct iso_fs_node { - iso_fs_metadata metadata; + iso_fs_metadata metadata {}; std::vector> children; }; @@ -38,7 +38,7 @@ class iso_file : public fs::file_base { private: fs::file m_file; - iso_fs_metadata m_meta; + iso_fs_metadata m_meta {}; u64 m_pos = 0; std::pair get_extent_pos(u64 pos) const; @@ -80,7 +80,7 @@ class iso_archive { private: std::string m_path; - iso_fs_node m_root; + iso_fs_node m_root {}; fs::file m_file; public: From a29758de6e14cf148e2a2af89c7a74fea8979411 Mon Sep 17 00:00:00 2001 From: RipleyTom Date: Fri, 20 Feb 2026 14:48:03 +0100 Subject: [PATCH 011/175] signaling_handler: bugfix and cleanup --- rpcs3/Emu/NP/np_cache.cpp | 4 ++-- rpcs3/Emu/NP/np_handler.cpp | 4 ++-- rpcs3/Emu/NP/np_helpers.cpp | 7 +++++++ rpcs3/Emu/NP/np_helpers.h | 1 + rpcs3/Emu/NP/np_notifications.cpp | 2 +- rpcs3/Emu/NP/rpcn_client.cpp | 2 +- rpcs3/Emu/NP/signaling_handler.cpp | 12 ++++++------ 7 files changed, 20 insertions(+), 12 deletions(-) diff --git a/rpcs3/Emu/NP/np_cache.cpp b/rpcs3/Emu/NP/np_cache.cpp index 04223da545..4731e0cede 100644 --- a/rpcs3/Emu/NP/np_cache.cpp +++ b/rpcs3/Emu/NP/np_cache.cpp @@ -377,7 +377,7 @@ namespace np if (!rooms.contains(room_id)) { - np_cache.error("np_cache::get_memberid cache miss room_id: room_id(%d)/npid(%s)", room_id, static_cast(npid.handle.data)); + np_cache.error("np_cache::get_memberid cache miss room_id: room_id(%d)/npid(%s)", room_id, np::npid_to_string(npid)); return std::nullopt; } @@ -389,7 +389,7 @@ namespace np return id; } - np_cache.error("np_cache::get_memberid cache miss member_id: room_id(%d)/npid(%s)", room_id, static_cast(npid.handle.data)); + np_cache.error("np_cache::get_memberid cache miss member_id: room_id(%d)/npid(%s)", room_id, np::npid_to_string(npid)); return std::nullopt; } diff --git a/rpcs3/Emu/NP/np_handler.cpp b/rpcs3/Emu/NP/np_handler.cpp index c4db3350c0..3041f24424 100644 --- a/rpcs3/Emu/NP/np_handler.cpp +++ b/rpcs3/Emu/NP/np_handler.cpp @@ -1361,7 +1361,7 @@ namespace np player_history& np_handler::get_player_and_set_timestamp(const SceNpId& npid, u64 timestamp) { - std::string npid_str = std::string(npid.handle.data); + std::string npid_str = np::npid_to_string(npid); if (!players_history.contains(npid_str)) { @@ -1641,7 +1641,7 @@ namespace np return SCE_NP_BASIC_ERROR_NOT_CONNECTED; } - auto friend_infos = rpcn->get_friend_presence_by_npid(std::string(npid.handle.data)); + auto friend_infos = rpcn->get_friend_presence_by_npid(np::npid_to_string(npid)); if (!friend_infos) { return SCE_NP_BASIC_ERROR_INVALID_ARGUMENT; diff --git a/rpcs3/Emu/NP/np_helpers.cpp b/rpcs3/Emu/NP/np_helpers.cpp index 79f61ca627..39c59afdb0 100644 --- a/rpcs3/Emu/NP/np_helpers.cpp +++ b/rpcs3/Emu/NP/np_helpers.cpp @@ -89,6 +89,13 @@ namespace np // npid->reserved[0] = 1; } + std::string npid_to_string(const SceNpId& npid) + { + char npid_str[17]{}; + std::memcpy(npid_str, npid.handle.data, 16); + return std::string(npid_str); + } + void string_to_online_name(std::string_view str, SceNpOnlineName& online_name) { memset(&online_name, 0, sizeof(online_name)); diff --git a/rpcs3/Emu/NP/np_helpers.h b/rpcs3/Emu/NP/np_helpers.h index c33b4ca001..a51499ca64 100644 --- a/rpcs3/Emu/NP/np_helpers.h +++ b/rpcs3/Emu/NP/np_helpers.h @@ -13,6 +13,7 @@ namespace np std::optional string_to_communication_id(std::string_view str); void string_to_npid(std::string_view str, SceNpId& npid); + std::string npid_to_string(const SceNpId& npid); void string_to_online_name(std::string_view str, SceNpOnlineName& online_name); void string_to_avatar_url(std::string_view str, SceNpAvatarUrl& avatar_url); void strings_to_userinfo(std::string_view npid, std::string_view online_name, std::string_view avatar_url, SceNpUserInfo& user_info); diff --git a/rpcs3/Emu/NP/np_notifications.cpp b/rpcs3/Emu/NP/np_notifications.cpp index d5756a8351..92072d2b5a 100644 --- a/rpcs3/Emu/NP/np_notifications.cpp +++ b/rpcs3/Emu/NP/np_notifications.cpp @@ -54,7 +54,7 @@ namespace np const u16 member_id = notif_data->roomMemberDataInternal->memberId; const SceNpId& npid = notif_data->roomMemberDataInternal->userInfo.npId; - rpcn_log.notice("Join notification told to connect to member(%d=%s) of room(%d): %s:%d", member_id, reinterpret_cast(npid.handle.data), room_id, ip_to_string(addr_p2p), port_p2p); + rpcn_log.notice("Join notification told to connect to member(%d=%s) of room(%d): %s:%d", member_id, np::npid_to_string(npid), room_id, ip_to_string(addr_p2p), port_p2p); // Attempt Signaling auto& sigh = g_fxo->get>(); diff --git a/rpcs3/Emu/NP/rpcn_client.cpp b/rpcs3/Emu/NP/rpcn_client.cpp index 38a4ad95ca..071afa2b3f 100644 --- a/rpcs3/Emu/NP/rpcn_client.cpp +++ b/rpcs3/Emu/NP/rpcn_client.cpp @@ -2318,7 +2318,7 @@ namespace rpcn { np2_structs::GetScoreGameDataRequest pb_req; pb_req.set_boardid(board_id); - pb_req.set_npid(reinterpret_cast(npid.handle.data)); + pb_req.set_npid(np::npid_to_string(npid)); pb_req.set_pcid(pc_id); std::string serialized; diff --git a/rpcs3/Emu/NP/signaling_handler.cpp b/rpcs3/Emu/NP/signaling_handler.cpp index 2e4ac5df56..e6d79f1fca 100644 --- a/rpcs3/Emu/NP/signaling_handler.cpp +++ b/rpcs3/Emu/NP/signaling_handler.cpp @@ -426,9 +426,10 @@ void signaling_handler::operator()() if (sig.sig_info->time_last_msg_recvd < now - 60s && cmd != signal_info) { // We had no connection to opponent for 60 seconds, consider the connection dead + auto retire_info = sig.sig_info; sign_log.notice("Timeout disconnection"); - update_si_status(sig.sig_info, SCE_NP_SIGNALING_CONN_STATUS_INACTIVE, SCE_NP_SIGNALING_ERROR_TIMEOUT); - retire_packet(sig.sig_info, signal_ping); // Retire ping packet if necessary + update_si_status(retire_info, SCE_NP_SIGNALING_CONN_STATUS_INACTIVE, SCE_NP_SIGNALING_ERROR_TIMEOUT); + retire_packet(retire_info, signal_ping); // Retire ping packet if necessary break; // qpackets has been emptied of all packets for this user so we're requeuing } @@ -784,7 +785,7 @@ void signaling_handler::send_information_packets(u32 addr, u16 port, const SceNp u32 signaling_handler::get_always_conn_id(const SceNpId& npid) { - std::string npid_str(reinterpret_cast(npid.handle.data)); + std::string npid_str = np::npid_to_string(npid); if (npid_to_conn_id.contains(npid_str)) return ::at32(npid_to_conn_id, npid_str); @@ -810,9 +811,8 @@ u32 signaling_handler::init_sig1(const SceNpId& npid) sig_peers[conn_id]->conn_status = SCE_NP_SIGNALING_CONN_STATUS_PENDING; // Request peer infos from RPCN - std::string npid_str(reinterpret_cast(npid.handle.data)); auto& nph = g_fxo->get>(); - nph.req_sign_infos(npid_str, conn_id); + nph.req_sign_infos(np::npid_to_string(npid), conn_id); } return conn_id; @@ -839,7 +839,7 @@ std::optional signaling_handler::get_conn_id_from_npid(const SceNpId& npid) { std::lock_guard lock(data_mutex); - std::string npid_str(reinterpret_cast(npid.handle.data)); + std::string npid_str = np::npid_to_string(npid); if (npid_to_conn_id.contains(npid_str)) return ::at32(npid_to_conn_id, npid_str); From a6b5c7e79f57c666b0f1e0f9f4fe3e8e3b886a00 Mon Sep 17 00:00:00 2001 From: RipleyTom Date: Fri, 20 Feb 2026 15:45:15 +0100 Subject: [PATCH 012/175] Generalize np::npid_to_string() use --- rpcs3/Emu/Cell/Modules/sceNp.cpp | 8 ++++---- rpcs3/Emu/NP/clans_client.cpp | 18 +++++++++--------- rpcs3/Emu/NP/np_handler.cpp | 2 +- rpcs3/Emu/NP/np_notifications.cpp | 6 +++--- rpcs3/Emu/NP/np_requests.cpp | 2 +- rpcs3/Emu/NP/np_structs_extra.cpp | 13 +++++++------ rpcs3/Emu/NP/pb_helpers.cpp | 2 +- rpcs3/Emu/NP/rpcn_client.cpp | 12 ++++++------ rpcs3/Emu/NP/signaling_handler.cpp | 8 ++------ 9 files changed, 34 insertions(+), 37 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/sceNp.cpp b/rpcs3/Emu/Cell/Modules/sceNp.cpp index 2a2075f0ca..3eee01cf9a 100644 --- a/rpcs3/Emu/Cell/Modules/sceNp.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNp.cpp @@ -1199,7 +1199,7 @@ error_code _sceNpBasicSendMessage(vm::cptr to, vm::cptr data, u32 .msgFeatures = {}, .data = std::vector(static_cast(data.get_ptr()), static_cast(data.get_ptr()) + size)}; std::set npids; - npids.insert(std::string(to->handle.data)); + npids.insert(np::npid_to_string(*to)); nph.send_message(msg_data, npids); @@ -1228,7 +1228,7 @@ error_code sceNpBasicSendMessageGui(ppu_thread& ppu, vm::cptrmsgId, msg->mainType, msg->subType, msg->msgFeatures, msg->count, msg->npids); for (u32 i = 0; i < msg->count && msg->npids; i++) { - sceNp.trace("sceNpBasicSendMessageGui: NpId[%d] = %s", i, static_cast(&msg->npids[i].handle.data[0])); + sceNp.trace("sceNpBasicSendMessageGui: NpId[%d] = %s", i, np::npid_to_string(msg->npids[i])); } sceNp.notice("sceNpBasicSendMessageGui: subject: %s", msg->subject); sceNp.notice("sceNpBasicSendMessageGui: body: %s", msg->body); @@ -1398,7 +1398,7 @@ error_code sceNpBasicSendMessageGui(ppu_thread& ppu, vm::cptrcount; i++) { - npids.insert(std::string(msg->npids[i].handle.data)); + npids.insert(np::npid_to_string(msg->npids[i])); } } @@ -7144,7 +7144,7 @@ error_code sceNpUtilCanonicalizeNpIdForPsp(vm::ptr npId) error_code sceNpUtilCmpNpId(vm::ptr id1, vm::ptr id2) { - sceNp.trace("sceNpUtilCmpNpId(id1=*0x%x(%s), id2=*0x%x(%s))", id1, id1 ? id1->handle.data : "", id2, id2 ? id2->handle.data : ""); + sceNp.trace("sceNpUtilCmpNpId(id1=*0x%x(%s), id2=*0x%x(%s))", id1, id1 ? np::npid_to_string(*id1) : std::string(), id2, id2 ? np::npid_to_string(*id2) : std::string()); if (!id1 || !id2) { diff --git a/rpcs3/Emu/NP/clans_client.cpp b/rpcs3/Emu/NP/clans_client.cpp index da3f506c91..e2d9fa9de0 100644 --- a/rpcs3/Emu/NP/clans_client.cpp +++ b/rpcs3/Emu/NP/clans_client.cpp @@ -464,7 +464,7 @@ namespace clan clan.append_child("ticket").text().set(ticket.c_str()); clan.append_child("id").text().set(clan_id); - const std::string jid_str = fmt::format(JID_FORMAT, np_id.handle.data); + const std::string jid_str = fmt::format(JID_FORMAT, np::npid_to_string(np_id)); clan.append_child("jid").text().set(jid_str.c_str()); pugi::xml_document response = pugi::xml_document(); @@ -656,7 +656,7 @@ namespace clan clan.append_child("ticket").text().set(ticket.c_str()); clan.append_child("id").text().set(clan_id); - const std::string jid_str = fmt::format(JID_FORMAT, np_id.handle.data); + const std::string jid_str = fmt::format(JID_FORMAT, np::npid_to_string(np_id)); clan.append_child("jid").text().set(jid_str.c_str()); pugi::xml_document response = pugi::xml_document(); @@ -674,7 +674,7 @@ namespace clan clan.append_child("ticket").text().set(ticket.c_str()); clan.append_child("id").text().set(clan_id); - const std::string jid_str = fmt::format(JID_FORMAT, np_id.handle.data); + const std::string jid_str = fmt::format(JID_FORMAT, np::npid_to_string(np_id)); clan.append_child("jid").text().set(jid_str.c_str()); pugi::xml_document response = pugi::xml_document(); @@ -832,7 +832,7 @@ namespace clan clan.append_child("ticket").text().set(ticket.c_str()); clan.append_child("id").text().set(clan_id); - const std::string jid_str = fmt::format(JID_FORMAT, np_id.handle.data); + const std::string jid_str = fmt::format(JID_FORMAT, np::npid_to_string(np_id)); clan.append_child("jid").text().set(jid_str.c_str()); pugi::xml_document response = pugi::xml_document(); @@ -850,7 +850,7 @@ namespace clan clan.append_child("ticket").text().set(ticket.c_str()); clan.append_child("id").text().set(clan_id); - const std::string jid_str = fmt::format(JID_FORMAT, np_id.handle.data); + const std::string jid_str = fmt::format(JID_FORMAT, np::npid_to_string(np_id)); clan.append_child("jid").text().set(jid_str.c_str()); pugi::xml_document response = pugi::xml_document(); @@ -868,7 +868,7 @@ namespace clan clan.append_child("ticket").text().set(ticket.c_str()); clan.append_child("id").text().set(clan_id); - const std::string jid_str = fmt::format(JID_FORMAT, np_id.handle.data); + const std::string jid_str = fmt::format(JID_FORMAT, np::npid_to_string(np_id)); clan.append_child("jid").text().set(jid_str.c_str()); pugi::xml_document response = pugi::xml_document(); @@ -902,7 +902,7 @@ namespace clan clan.append_child("id").text().set(clan_id); pugi::xml_node role = clan.append_child("onlinename"); - role.text().set(nph.get_npid().handle.data); + role.text().set(np::npid_to_string(nph.get_npid()).c_str()); pugi::xml_node description = clan.append_child("description"); description.text().set(info.description); @@ -990,7 +990,7 @@ namespace clan clan.append_child("ticket").text().set(ticket.c_str()); clan.append_child("id").text().set(clan_id); - const std::string jid_str = fmt::format(JID_FORMAT, np_id.handle.data); + const std::string jid_str = fmt::format(JID_FORMAT, np::npid_to_string(np_id)); clan.append_child("jid").text().set(jid_str.c_str()); pugi::xml_document response = pugi::xml_document(); @@ -1008,7 +1008,7 @@ namespace clan clan.append_child("ticket").text().set(ticket.c_str()); clan.append_child("id").text().set(clan_id); - const std::string jid_str = fmt::format(JID_FORMAT, np_id.handle.data); + const std::string jid_str = fmt::format(JID_FORMAT, np::npid_to_string(np_id)); clan.append_child("jid").text().set(jid_str.c_str()); pugi::xml_node role_node = clan.append_child("role"); diff --git a/rpcs3/Emu/NP/np_handler.cpp b/rpcs3/Emu/NP/np_handler.cpp index 3041f24424..1fc9342329 100644 --- a/rpcs3/Emu/NP/np_handler.cpp +++ b/rpcs3/Emu/NP/np_handler.cpp @@ -1024,7 +1024,7 @@ namespace np } } - nph_log.notice("basic_event: event:%d, from:%s(%s), size:%d", *event, static_cast(from->userId.handle.data), static_cast(from->name.data), *size); + nph_log.notice("basic_event: event:%d, from:%s(%s), size:%d", *event, np::npid_to_string(from->userId), static_cast(from->name.data), *size); return CELL_OK; } diff --git a/rpcs3/Emu/NP/np_notifications.cpp b/rpcs3/Emu/NP/np_notifications.cpp index 92072d2b5a..6d6d511ee0 100644 --- a/rpcs3/Emu/NP/np_notifications.cpp +++ b/rpcs3/Emu/NP/np_notifications.cpp @@ -41,7 +41,7 @@ namespace np return; } - rpcn_log.notice("Received notification that user %s(%d) joined the room(%d)", notif_data->roomMemberDataInternal->userInfo.npId.handle.data, notif_data->roomMemberDataInternal->memberId, room_id); + rpcn_log.notice("Received notification that user %s(%d) joined the room(%d)", np::npid_to_string(notif_data->roomMemberDataInternal->userInfo.npId), notif_data->roomMemberDataInternal->memberId, room_id); extra_nps::print_SceNpMatching2RoomMemberDataInternal(notif_data->roomMemberDataInternal.get_ptr()); // We initiate signaling if necessary @@ -98,7 +98,7 @@ namespace np return; } - rpcn_log.notice("Received notification that user %s(%d) left the room(%d)", notif_data->roomMemberDataInternal->userInfo.npId.handle.data, notif_data->roomMemberDataInternal->memberId, room_id); + rpcn_log.notice("Received notification that user %s(%d) left the room(%d)", np::npid_to_string(notif_data->roomMemberDataInternal->userInfo.npId), notif_data->roomMemberDataInternal->memberId, room_id); extra_nps::print_SceNpMatching2RoomMemberDataInternal(notif_data->roomMemberDataInternal.get_ptr()); if (room_event_cb) @@ -204,7 +204,7 @@ namespace np return; } - rpcn_log.notice("Received notification that user's %s(%d) room (%d) data was updated", notif_data->newRoomMemberDataInternal->userInfo.npId.handle.data, notif_data->newRoomMemberDataInternal->memberId, room_id); + rpcn_log.notice("Received notification that user's %s(%d) room (%d) data was updated", np::npid_to_string(notif_data->newRoomMemberDataInternal->userInfo.npId), notif_data->newRoomMemberDataInternal->memberId, room_id); extra_nps::print_SceNpMatching2RoomMemberDataInternal(notif_data->newRoomMemberDataInternal.get_ptr()); if (room_event_cb) diff --git a/rpcs3/Emu/NP/np_requests.cpp b/rpcs3/Emu/NP/np_requests.cpp index 3f21f24cd3..ed7023cc89 100644 --- a/rpcs3/Emu/NP/np_requests.cpp +++ b/rpcs3/Emu/NP/np_requests.cpp @@ -310,7 +310,7 @@ namespace np if (npid_res != CELL_OK) continue; - rpcn_log.notice("JoinRoomResult told to connect to member(%d=%s) of room(%d): %s:%d", member_id, reinterpret_cast(npid_p2p->handle.data), room_id, ip_to_string(addr_p2p), port_p2p); + rpcn_log.notice("JoinRoomResult told to connect to member(%d=%s) of room(%d): %s:%d", member_id, np::npid_to_string(*npid_p2p), room_id, ip_to_string(addr_p2p), port_p2p); // Attempt Signaling auto& sigh = g_fxo->get>(); diff --git a/rpcs3/Emu/NP/np_structs_extra.cpp b/rpcs3/Emu/NP/np_structs_extra.cpp index 58770c450f..6774b20bc4 100644 --- a/rpcs3/Emu/NP/np_structs_extra.cpp +++ b/rpcs3/Emu/NP/np_structs_extra.cpp @@ -2,6 +2,7 @@ #include "stdafx.h" #include #include "np_structs_extra.h" +#include "np_helpers.h" LOG_CHANNEL(sceNp); LOG_CHANNEL(sceNp2); @@ -13,7 +14,7 @@ namespace extra_nps void print_SceNpUserInfo2(const SceNpUserInfo2* user) { sceNp2.warning("SceNpUserInfo2:"); - sceNp2.warning("npid: %s", static_cast(user->npId.handle.data)); + sceNp2.warning("npid: %s", np::npid_to_string(user->npId)); sceNp2.warning("onlineName: *0x%x(%s)", user->onlineName, user->onlineName ? static_cast(user->onlineName->data) : ""); sceNp2.warning("avatarUrl: *0x%x(%s)", user->avatarUrl, user->avatarUrl ? static_cast(user->avatarUrl->data) : ""); } @@ -208,7 +209,7 @@ namespace extra_nps { sceNp2.warning("SceNpMatching2RoomMemberDataInternal:"); sceNp2.warning("next: *0x%x", member->next); - sceNp2.warning("npId: %s", member->userInfo.npId.handle.data); + sceNp2.warning("npId: %s", np::npid_to_string(member->userInfo.npId)); sceNp2.warning("onlineName: %s", member->userInfo.onlineName ? member->userInfo.onlineName->data : ""); sceNp2.warning("avatarUrl: %s", member->userInfo.avatarUrl ? member->userInfo.avatarUrl->data : ""); sceNp2.warning("joinDate: %lld", member->joinDate.tick); @@ -460,7 +461,7 @@ namespace extra_nps void print_SceNpScoreRankData(const SceNpScoreRankData* data) { sceNp.warning("sceNpScoreRankData:"); - sceNp.warning("npId: %s", static_cast(data->npId.handle.data)); + sceNp.warning("npId: %s", np::npid_to_string(data->npId)); sceNp.warning("onlineName: %s", static_cast(data->onlineName.data)); sceNp.warning("pcId: %d", data->pcId); sceNp.warning("serialRank: %d", data->serialRank); @@ -474,7 +475,7 @@ namespace extra_nps void print_SceNpScoreRankData_deprecated(const SceNpScoreRankData_deprecated* data) { sceNp.warning("sceNpScoreRankData_deprecated:"); - sceNp.warning("npId: %s", static_cast(data->npId.handle.data)); + sceNp.warning("npId: %s", np::npid_to_string(data->npId)); sceNp.warning("onlineName: %s", static_cast(data->onlineName.data)); sceNp.warning("serialRank: %d", data->serialRank); sceNp.warning("rank: %d", data->rank); @@ -542,7 +543,7 @@ namespace extra_nps void print_SceNpUserInfo(const SceNpUserInfo* data) { - sceNp.warning("userId: %s", data->userId.handle.data); + sceNp.warning("userId: %s", np::npid_to_string(data->userId)); sceNp.warning("name: %s", data->name.data); sceNp.warning("icon: %s", data->icon.data); } @@ -576,7 +577,7 @@ namespace extra_nps if (data->kick_actor) { - sceNp.warning("kick_actor: %s", data->kick_actor->handle.data); + sceNp.warning("kick_actor: %s", np::npid_to_string(*data->kick_actor)); } sceNp.warning("opt: 0x%x", data->kick_actor); diff --git a/rpcs3/Emu/NP/pb_helpers.cpp b/rpcs3/Emu/NP/pb_helpers.cpp index 41b0ca4579..83170426ff 100644 --- a/rpcs3/Emu/NP/pb_helpers.cpp +++ b/rpcs3/Emu/NP/pb_helpers.cpp @@ -263,7 +263,7 @@ namespace np for (u32 i = 0; i < room_info->memberList.membersNum; i++) { SceNpMatching2RoomMemberDataInternal* sce_member = &room_info->memberList.members[i]; - if (strcmp(sce_member->userInfo.npId.handle.data, npid.handle.data) == 0) + if (strncmp(sce_member->userInfo.npId.handle.data, npid.handle.data, 16) == 0) { room_info->memberList.me = room_info->memberList.members + i; edata.add_relocation(room_info->memberList.me); diff --git a/rpcs3/Emu/NP/rpcn_client.cpp b/rpcs3/Emu/NP/rpcn_client.cpp index 071afa2b3f..86a688705e 100644 --- a/rpcs3/Emu/NP/rpcn_client.cpp +++ b/rpcs3/Emu/NP/rpcn_client.cpp @@ -1756,7 +1756,7 @@ namespace rpcn { continue; } - pb_req.add_alloweduser(req->allowedUser[i].handle.data); + pb_req.add_alloweduser(np::npid_to_string(req->allowedUser[i])); } } @@ -1768,7 +1768,7 @@ namespace rpcn { continue; } - pb_req.add_blockeduser(req->blockedUser[i].handle.data); + pb_req.add_blockeduser(np::npid_to_string(req->blockedUser[i])); } } @@ -2267,7 +2267,7 @@ namespace rpcn for (usz i = 0; i < npids.size(); i++) { auto* npid_entry = pb_req.add_npids(); - npid_entry->set_npid(static_cast(npids[i].first.handle.data)); + npid_entry->set_npid(np::npid_to_string(npids[i].first)); npid_entry->set_pcid(npids[i].second); } @@ -2414,7 +2414,7 @@ namespace rpcn if (option->isLastChangedAuthorId) { - pb_req.set_islastchangedauthorid(option->isLastChangedAuthorId->handle.data); + pb_req.set_islastchangedauthorid(np::npid_to_string(*option->isLastChangedAuthorId)); } } @@ -2443,7 +2443,7 @@ namespace rpcn if (option->isLastChangedAuthorId) { - pb_req.set_islastchangedauthorid(option->isLastChangedAuthorId->handle.data); + pb_req.set_islastchangedauthorid(np::npid_to_string(*option->isLastChangedAuthorId)); } if (option->compareValue) @@ -2499,7 +2499,7 @@ namespace rpcn if (option->isLastChangedAuthorId) { - pb_req.set_islastchangedauthorid(option->isLastChangedAuthorId->handle.data); + pb_req.set_islastchangedauthorid(np::npid_to_string(*option->isLastChangedAuthorId)); } } diff --git a/rpcs3/Emu/NP/signaling_handler.cpp b/rpcs3/Emu/NP/signaling_handler.cpp index e6d79f1fca..97a2673e0f 100644 --- a/rpcs3/Emu/NP/signaling_handler.cpp +++ b/rpcs3/Emu/NP/signaling_handler.cpp @@ -256,9 +256,7 @@ void signaling_handler::process_incoming_messages() addr.s_addr = op_addr; char ip_str[16]; inet_ntop(AF_INET, &addr, ip_str, sizeof(ip_str)); - std::string_view npid(sp->npid.handle.data); - - sign_log.trace("SP %s from %s:%d(npid: %s)", sp->command, ip_str, op_port, npid); + sign_log.trace("SP %s from %s:%d(npid: %s)", sp->command, ip_str, op_port, np::npid_to_string(sp->npid)); } bool reply = false, schedule_repeat = false; @@ -675,9 +673,7 @@ std::shared_ptr signaling_handler::get_signaling_ptr(const signa { u32 conn_id; - char npid_buf[17]{}; - memcpy(npid_buf, sp->npid.handle.data, 16); - std::string npid(npid_buf); + std::string npid = np::npid_to_string(sp->npid); if (!npid_to_conn_id.contains(npid)) return nullptr; From 48667d68b2165e295e0c9a8e2d97ff94afad6cd8 Mon Sep 17 00:00:00 2001 From: Ani Date: Fri, 20 Feb 2026 12:33:54 +0100 Subject: [PATCH 013/175] rpcs3: Target c++23 --- CMakeLists.txt | 8 ++++---- rpcs3/CMakeLists.txt | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 65e415bdb7..738d9bbf17 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,12 +13,12 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_POSITION_INDEPENDENT_CODE ON) if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 11) - message(FATAL_ERROR "RPCS3 requires at least gcc-11.") + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 13) + message(FATAL_ERROR "RPCS3 requires at least gcc-13.") endif() elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") - if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 12.0) - message(FATAL_ERROR "RPCS3 requires at least clang-12.0.") + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.0) + message(FATAL_ERROR "RPCS3 requires at least clang-19.0.") endif() endif() diff --git a/rpcs3/CMakeLists.txt b/rpcs3/CMakeLists.txt index e32597f792..41597127b8 100644 --- a/rpcs3/CMakeLists.txt +++ b/rpcs3/CMakeLists.txt @@ -8,7 +8,7 @@ include(${CMAKE_CURRENT_SOURCE_DIR}/git-version.cmake) include(ConfigureCompiler) include(CheckFunctionExists) -set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD 23) if(UNIX AND NOT APPLE AND NOT ANDROID) add_compile_definitions(DATADIR="${CMAKE_INSTALL_FULL_DATADIR}/rpcs3") From 6de8861b4eeb32c1adea3180c45c2f4aa9ed1a1e Mon Sep 17 00:00:00 2001 From: Ani Date: Fri, 20 Feb 2026 13:21:31 +0100 Subject: [PATCH 014/175] rpcs3: Target c++23 (msvc) --- buildfiles/msvc/common_default.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildfiles/msvc/common_default.props b/buildfiles/msvc/common_default.props index 04f6502839..bfddbb5465 100644 --- a/buildfiles/msvc/common_default.props +++ b/buildfiles/msvc/common_default.props @@ -13,7 +13,7 @@ stdcpplatest - stdcpp20 + stdcpp23 _SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING=1;_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions) false -d2FH4- %(AdditionalOptions) From fec2be87f615e1ca912f05aaacebc6bfe7075e64 Mon Sep 17 00:00:00 2001 From: Ani Date: Fri, 20 Feb 2026 13:40:00 +0100 Subject: [PATCH 015/175] types.hpp: #include Co-Authored-By: RipleyTom --- rpcs3/util/types.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/rpcs3/util/types.hpp b/rpcs3/util/types.hpp index 4a2ef5baea..a1a07bac69 100644 --- a/rpcs3/util/types.hpp +++ b/rpcs3/util/types.hpp @@ -13,6 +13,7 @@ #include #include #include +#include #if defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__) || defined(__amd64__) #define ARCH_X64 1 From c7d7f2d03b7a613b28117e8eca618541db8d8b6b Mon Sep 17 00:00:00 2001 From: Ani Date: Fri, 20 Feb 2026 14:15:39 +0100 Subject: [PATCH 016/175] Thread: Move include to .h Co-Authored-By: RipleyTom --- Utilities/Thread.cpp | 1 - Utilities/Thread.h | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index 810b8fd7c5..08dce12315 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -8,7 +8,6 @@ #include "Emu/RSX/RSXThread.h" #include "Thread.h" #include "Utilities/JIT.h" -#include #include #ifdef ARCH_ARM64 diff --git a/Utilities/Thread.h b/Utilities/Thread.h index 02e5db56ff..7cd9a7c7ea 100644 --- a/Utilities/Thread.h +++ b/Utilities/Thread.h @@ -4,6 +4,7 @@ #include "util/atomic.hpp" #include "util/shared_ptr.hpp" +#include #include // Hardware core layout From e075170cc485b803a9d91f67728cd6349a9b10da Mon Sep 17 00:00:00 2001 From: Ani Date: Fri, 20 Feb 2026 14:17:41 +0100 Subject: [PATCH 017/175] JITASM: include on APPLE Co-Authored-By: RipleyTom --- Utilities/JITASM.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Utilities/JITASM.cpp b/Utilities/JITASM.cpp index acb5f40b04..90c09bb0bf 100644 --- a/Utilities/JITASM.cpp +++ b/Utilities/JITASM.cpp @@ -14,6 +14,10 @@ #define CAN_OVERCOMMIT #endif +#if defined(__APPLE__) +#include +#endif + LOG_CHANNEL(jit_log, "JIT"); void jit_announce(uptr func, usz size, std::string_view name) From bfea622999c9207c3a2d1561fecc61c4f92622d0 Mon Sep 17 00:00:00 2001 From: Ani Date: Fri, 20 Feb 2026 14:50:35 +0100 Subject: [PATCH 018/175] sys_time: include on NOT WIN32 --- rpcs3/Emu/Cell/lv2/sys_time.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/rpcs3/Emu/Cell/lv2/sys_time.cpp b/rpcs3/Emu/Cell/lv2/sys_time.cpp index 539bb9dedf..a71a11ba31 100644 --- a/rpcs3/Emu/Cell/lv2/sys_time.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_time.cpp @@ -118,6 +118,7 @@ static int clock_gettime(int clk_id, struct timespec* tp) #ifndef _WIN32 +#include #include static struct timespec start_time = []() From 89efca9f63c14d631bb07025ff83158ebad6a7be Mon Sep 17 00:00:00 2001 From: Ani Date: Fri, 20 Feb 2026 15:26:22 +0100 Subject: [PATCH 019/175] system_utils: include --- rpcs3/Emu/system_utils.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/rpcs3/Emu/system_utils.hpp b/rpcs3/Emu/system_utils.hpp index d8f4f59d8a..fd8717f4f9 100644 --- a/rpcs3/Emu/system_utils.hpp +++ b/rpcs3/Emu/system_utils.hpp @@ -3,6 +3,7 @@ #include "util/types.hpp" #include #include +#include enum class game_content_type { From 6bfb33279f6989f3ff9ea2dc40ef45d6aeb57ef8 Mon Sep 17 00:00:00 2001 From: Ani Date: Fri, 20 Feb 2026 16:11:11 +0100 Subject: [PATCH 020/175] test_fmt: include --- rpcs3/tests/test_fmt.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/rpcs3/tests/test_fmt.cpp b/rpcs3/tests/test_fmt.cpp index 95c31d17c6..069051bd1a 100644 --- a/rpcs3/tests/test_fmt.cpp +++ b/rpcs3/tests/test_fmt.cpp @@ -1,3 +1,4 @@ +#include #include #include "Utilities/StrUtil.h" From 3585881a6c6d8a5fad78ec1949be89a7a20b9be3 Mon Sep 17 00:00:00 2001 From: oltolm Date: Sun, 22 Feb 2026 01:59:55 +0100 Subject: [PATCH 021/175] cellSaveData: fix "Your comparator is not a valid strict-weak ordering" --- rpcs3/Emu/Cell/Modules/cellSaveData.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/cellSaveData.cpp b/rpcs3/Emu/Cell/Modules/cellSaveData.cpp index a4d160fdcb..7878e86642 100644 --- a/rpcs3/Emu/Cell/Modules/cellSaveData.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSaveData.cpp @@ -876,39 +876,42 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v // Sort the entries { - const u32 order = setList->sortOrder; const u32 type = setList->sortType; - std::sort(save_entries.begin(), save_entries.end(), [order, type](const SaveDataEntry& entry1, const SaveDataEntry& entry2) -> bool + auto comp = [type](const SaveDataEntry& entry1, const SaveDataEntry& entry2) -> bool { const bool mtime_lower = entry1.mtime < entry2.mtime; const bool mtime_equal = entry1.mtime == entry2.mtime; const bool subtitle_lower = entry1.subtitle < entry2.subtitle; const bool subtitle_equal = entry1.subtitle == entry2.subtitle; - const bool revert_order = order == CELL_SAVEDATA_SORTORDER_DESCENT; if (type == CELL_SAVEDATA_SORTTYPE_MODIFIEDTIME) { if (mtime_equal) { - return subtitle_lower != revert_order; + return subtitle_lower; } - return mtime_lower != revert_order; + return mtime_lower; } else if (type == CELL_SAVEDATA_SORTTYPE_SUBTITLE) { if (subtitle_equal) { - return mtime_lower != revert_order; + return mtime_lower; } - return subtitle_lower != revert_order; + return subtitle_lower; } ensure(false); return true; - }); + }; + + if (setList->sortOrder == CELL_SAVEDATA_SORTORDER_ASCENT) + std::sort(save_entries.begin(), save_entries.end(), comp); + else + std::sort(save_entries.rbegin(), save_entries.rend(), comp); } // Fill the listGet->dirList array From e22c83f4cec4b3f70815ffc780ffa22b6d91818c Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sat, 21 Feb 2026 14:03:04 +0300 Subject: [PATCH 022/175] rsx: Improve comments/documentation around border color SEXT convert --- rpcs3/Emu/RSX/RSXTexture.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/rpcs3/Emu/RSX/RSXTexture.cpp b/rpcs3/Emu/RSX/RSXTexture.cpp index b3f9dc1962..e6483b51d7 100644 --- a/rpcs3/Emu/RSX/RSXTexture.cpp +++ b/rpcs3/Emu/RSX/RSXTexture.cpp @@ -315,6 +315,7 @@ namespace rsx // Border color is broken on PS3. The SNORM behavior is completely broken and behaves like BIASED renormalization instead. // To solve the mismatch, we need to first do a bit expansion on the value then store it as sign extended. The second part is a natural part of numbers on a binary system, so we only need to do the former. + // Note that the input color is in BE order (BGRA) so we reverse the mask to match. static constexpr u32 expand4_lut[16] = { 0x00000000u, // 0000 @@ -335,7 +336,7 @@ namespace rsx 0xFFFFFFFFu // 1111 }; - // Bit pattern expand and reverse BE -> LE using LUT + // Bit pattern expand const u32 mask = expand4_lut[sext]; // Now we perform the compensation operation @@ -344,16 +345,14 @@ namespace rsx // Load const __m128i _0 = _mm_setzero_si128(); const __m128i _128 = _mm_set1_epi32(128); - const __m128i _127 = _mm_set1_epi32(127); - const __m128i _255 = _mm_set1_epi32(255); - const auto be_raw = be_t(raw); - __m128i v = _mm_cvtsi32_si128(static_cast(be_raw)); + // Explode the bytes. + __m128i v = _mm_cvtsi32_si128(raw); v = _mm_unpacklo_epi8(v, _0); - v = _mm_unpacklo_epi16(v, _0); // [ 0, 64, 255, 128 ] + v = _mm_unpacklo_epi16(v, _0); // Conversion: x = (y - 128) - v = _mm_sub_epi32(v, _128); // [ -128, -64, 127, 0 ] + v = _mm_sub_epi32(v, _128); // Convert to signed encoding (reverse sext) v = _mm_slli_epi32(v, 24); From 2b7bb9ef0ac7f7559822b6dd30a6cf2cb7eb065a Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sat, 21 Feb 2026 16:49:01 +0300 Subject: [PATCH 023/175] rsx: Add format_ex utility --- rpcs3/Emu/RSX/Common/TextureUtils.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/rpcs3/Emu/RSX/Common/TextureUtils.h b/rpcs3/Emu/RSX/Common/TextureUtils.h index 65f4ef5c6f..c32152fecd 100644 --- a/rpcs3/Emu/RSX/Common/TextureUtils.h +++ b/rpcs3/Emu/RSX/Common/TextureUtils.h @@ -137,6 +137,22 @@ namespace rsx using enum format_features; + struct texture_format_ex + { + texture_format_ex() = default; + texture_format_ex(u32 bits) + : format_bits(bits) + {} + + bool valid() const { return format_bits != 0; } + u32 format() const { return format_bits & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN); } + + //private: + u32 format_bits = 0; + u32 features = 0; + u32 texel_remap_control = 0; + }; + // Sampled image descriptor class sampled_image_descriptor_base { @@ -179,6 +195,7 @@ namespace rsx u64 surface_cache_tag = 0; texcoord_xform_t texcoord_xform; + texture_format_ex format_ex; }; struct typeless_xfer From 2d7b72a769b4085b893bfa3430fe7ac66c7f8f2b Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sat, 21 Feb 2026 17:44:06 +0300 Subject: [PATCH 024/175] rsx: Implement format_ex decoding for FS inputs --- rpcs3/Emu/RSX/RSXTexture.cpp | 61 ++++++++++++++++++++++++++++++++++++ rpcs3/Emu/RSX/RSXTexture.h | 3 ++ rpcs3/Emu/RSX/color_utils.h | 28 +++++++++++++++++ 3 files changed, 92 insertions(+) diff --git a/rpcs3/Emu/RSX/RSXTexture.cpp b/rpcs3/Emu/RSX/RSXTexture.cpp index e6483b51d7..6f8eec0e3b 100644 --- a/rpcs3/Emu/RSX/RSXTexture.cpp +++ b/rpcs3/Emu/RSX/RSXTexture.cpp @@ -2,6 +2,8 @@ #include "RSXTexture.h" #include "rsx_utils.h" +#include "Common/TextureUtils.h" +#include "Program/GLSLCommon.h" #include "Emu/system_config.h" #include "util/simd.hpp" @@ -63,6 +65,65 @@ namespace rsx return ((registers[NV4097_SET_TEXTURE_FORMAT + (m_index * 8)] >> 8) & 0xff); } + texture_format_ex fragment_texture::format_ex() const + { + const auto format_bits = format(); + const auto base_format = format_bits & ~(CELL_GCM_TEXTURE_UN | CELL_GCM_TEXTURE_LN); + const auto format_features = rsx::get_format_features(base_format); + if (format_features == 0) + { + return { format_bits }; + } + + // NOTE: The unsigned_remap=bias flag being set flags the texture as being compressed normal (2n-1 / BX2) (UE3) + // NOTE: The ARGB8_signed flag means to reinterpret the raw bytes as signed. This is different than unsigned_remap=bias which does range decompression. + // This is a separate method of setting the format to signed mode without doing so per-channel + // Precedence = SNORM > GAMMA > UNSIGNED_REMAP/BX2 + // Games using mixed flags: (See Resistance 3 for GAMMA/BX2 relationship, UE3 for BX2 effect) + u32 argb_signed_ = 0; + u32 unsigned_remap_ = 0; + u32 gamma_ = 0; + + if (format_features & RSX_FORMAT_FEATURE_SIGNED_COMPONENTS) + { + // Tests show this is applied pre-readout. It's just a property of the incoming bytes and is therefore subject to remap. + argb_signed_ = decoded_remap().shuffle_mask_bits(argb_signed()); + } + + if (format_features & RSX_FORMAT_FEATURE_GAMMA_CORRECTION) + { + // Tests show this is applied post-readout. It's a property of the final value stored in the register and is not remapped. + // NOTE: GAMMA correction has no algorithmic effect on constants (0 and 1) so we need not mask it out for correctness. + gamma_ = gamma() & ~(argb_signed_); + } + + if (format_features & RSX_FORMAT_FEATURE_BIASED_NORMALIZATION) + { + // The renormalization flag applies to all channels. It is weaker than the other flags. + // This applies on input and is subject to remap overrides + if (unsigned_remap() == CELL_GCM_TEXTURE_UNSIGNED_REMAP_BIASED) + { + unsigned_remap_ = decoded_remap().shuffle_mask_bits(0xFu) & ~(argb_signed_ | gamma_); + } + } + + u32 format_convert = gamma_; + + // The options are mutually exclusive + ensure((argb_signed_ & gamma_) == 0); + ensure((argb_signed_ & unsigned_remap_) == 0); + ensure((gamma_ & unsigned_remap_) == 0); + + // NOTE: Hardware tests show that remapping bypasses the channel swizzles completely + format_convert |= (argb_signed_ << texture_control_bits::SEXT_OFFSET); + format_convert |= (unsigned_remap_ << texture_control_bits::EXPAND_OFFSET); + + texture_format_ex result { format_bits }; + result.features = format_features; + result.texel_remap_control = format_convert; + return result; + } + bool fragment_texture::is_compressed_format() const { int texture_format = format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN); diff --git a/rpcs3/Emu/RSX/RSXTexture.h b/rpcs3/Emu/RSX/RSXTexture.h index 5517a39e3f..3b0ccdebce 100644 --- a/rpcs3/Emu/RSX/RSXTexture.h +++ b/rpcs3/Emu/RSX/RSXTexture.h @@ -4,6 +4,8 @@ namespace rsx { + struct texture_format_ex; + class fragment_texture { protected: @@ -33,6 +35,7 @@ namespace rsx // cubemap as a separate dimension. rsx::texture_dimension_extended get_extended_texture_dimension() const; u8 format() const; + texture_format_ex format_ex() const; bool is_compressed_format() const; u16 mipmap() const; diff --git a/rpcs3/Emu/RSX/color_utils.h b/rpcs3/Emu/RSX/color_utils.h index fd3156bd3e..40335c07e3 100644 --- a/rpcs3/Emu/RSX/color_utils.h +++ b/rpcs3/Emu/RSX/color_utils.h @@ -39,6 +39,34 @@ namespace rsx return remapped; } + + /** + * Remap color channel bits based on a remap vector. The output is a normalized selector of each color channel with spread. + * The input bits are an action selector. e.g a mask of channels that need to be interpreted as SNORM or BX2 + * The output is a final mask on which post-sampling channels the operation applies to. + * Examples: + * - If we have remap as [ 1 R R R ] and mask of R (0010) then we get 1110. Remapper spreads 'R' action to all channels where it should apply. + */ + u32 shuffle_mask_bits(u32 bits) const + { + if (!bits || encoded == RSX_TEXTURE_REMAP_IDENTITY) [[likely]] + { + return bits; + } + + u32 result = 0; + for (u8 channel = 0; channel < 4; ++channel) + { + if (control_map[channel] != CELL_GCM_TEXTURE_REMAP_REMAP || // Channel not read from input + (bits & (1u << channel_map[channel])) == 0) // Input channel is not enabled in the mask + { + continue; + } + result |= (1u << channel); + } + return result; + } + template requires std::is_integral_v || std::is_floating_point_v std::array remap(const std::array& components) const From f5cf818bcc02ce940e38cfd772ca1681f5b66054 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sat, 21 Feb 2026 17:47:46 +0300 Subject: [PATCH 025/175] rsx: Disable interpolation for SNORM emulated textures --- rpcs3/Emu/RSX/GL/GLDraw.cpp | 16 ++++++-- rpcs3/Emu/RSX/RSXThread.cpp | 77 ++----------------------------------- rpcs3/Emu/RSX/VK/VKDraw.cpp | 8 +++- 3 files changed, 22 insertions(+), 79 deletions(-) diff --git a/rpcs3/Emu/RSX/GL/GLDraw.cpp b/rpcs3/Emu/RSX/GL/GLDraw.cpp index e8ea4bc714..475507ee78 100644 --- a/rpcs3/Emu/RSX/GL/GLDraw.cpp +++ b/rpcs3/Emu/RSX/GL/GLDraw.cpp @@ -2,6 +2,7 @@ #include "GLGSRender.h" #include "../rsx_methods.h" #include "../Common/BufferUtils.h" +#include "../Program/GLSLCommon.h" #include "Emu/RSX/NV47/HW/context_accessors.define.h" @@ -315,6 +316,8 @@ void GLGSRender::load_texture_env() if (sampler_state->validate()) { + sampler_state->format_ex = tex.format_ex(); + if (m_textures_dirty[i]) { m_fs_sampler_states[i].apply(tex, fs_sampler_state[i].get()); @@ -324,12 +327,17 @@ void GLGSRender::load_texture_env() m_graphics_state |= rsx::fragment_program_state_dirty; } - if (const auto texture_format = tex.format() & ~(CELL_GCM_TEXTURE_UN | CELL_GCM_TEXTURE_LN); - sampler_state->format_class != rsx::classify_format(texture_format) && - (texture_format == CELL_GCM_TEXTURE_A8R8G8B8 || texture_format == CELL_GCM_TEXTURE_D8R8G8B8)) + const auto texture_format = sampler_state->format_ex.format(); + // Depth format redirected to BGRA8 resample stage. Do not filter to avoid bits leaking. + // If accurate graphics are desired, force a bitcast to COLOR as a workaround. + const bool is_depth_reconstructed = sampler_state->format_class != rsx::classify_format(texture_format) && + (texture_format == CELL_GCM_TEXTURE_A8R8G8B8 || texture_format == CELL_GCM_TEXTURE_D8R8G8B8); + // SNORM conversion required in shader. Do not interpolate to avoid introducing discontinuities due to how negative numbers work + const bool is_snorm = (sampler_state->format_ex.texel_remap_control & rsx::texture_control_bits::SEXT_MASK) != 0; + + if (is_depth_reconstructed || is_snorm) { // Depth format redirected to BGRA8 resample stage. Do not filter to avoid bits leaking. - // If accurate graphics are desired, force a bitcast to COLOR as a workaround. m_fs_sampler_states[i].set_parameteri(GL_TEXTURE_MIN_FILTER, GL_NEAREST); m_fs_sampler_states[i].set_parameteri(GL_TEXTURE_MAG_FILTER, GL_NEAREST); } diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 5b4b732c4d..5bfc60ee2a 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -2321,83 +2321,14 @@ namespace rsx } } - if (const auto format_features = rsx::get_format_features(format); format_features != 0) + if (const auto& format_ex = sampler_descriptors[i]->format_ex; format_ex.features != 0) { - // NOTE: The unsigned_remap=bias flag being set flags the texture as being compressed normal (2n-1 / BX2) (UE3) - // NOTE: The ARGB8_signed flag means to reinterpret the raw bytes as signed. This is different than unsigned_remap=bias which does range decompression. - // This is a separate method of setting the format to signed mode without doing so per-channel - // Precedence = SNORM > GAMMA > UNSIGNED_REMAP/BX2 - // Games using mixed flags: (See Resistance 3 for GAMMA/BX2 relationship, UE3 for BX2 effect) - u32 argb8_signed = 0; - u32 unsigned_remap = 0; - u32 gamma = 0; - - auto remap_channel_bits = [](const rsx::texture_channel_remap_t& remap, u32 bits) -> u32 - { - if (!bits || remap.encoded == RSX_TEXTURE_REMAP_IDENTITY) [[ likely ]] - { - return bits; - } - - u32 result = 0; - for (u8 channel = 0; channel < 4; ++channel) - { - switch (remap.control_map[channel]) - { - case CELL_GCM_TEXTURE_REMAP_REMAP: - if (bits & (1u << remap.channel_map[channel])) - { - result |= (1u << channel); - } - break; - default: - break; - } - } - return result; - }; - - const auto texture_remap = tex.decoded_remap(); - if (format_features & RSX_FORMAT_FEATURE_SIGNED_COMPONENTS) - { - // Tests show this is applied pre-readout. It's just a property of the incoming bytes and is therefore subject to remap. - argb8_signed = remap_channel_bits(texture_remap, tex.argb_signed()); - } - - if (format_features & RSX_FORMAT_FEATURE_GAMMA_CORRECTION) - { - // Tests show this is applied post-readout. It's a property of the final value stored in the register and is not remapped. - // NOTE: GAMMA correction has no algorithmic effect on constants (0 and 1) so we need not mask it out for correctness. - gamma = tex.gamma() & ~(argb8_signed); - } - - if (format_features & RSX_FORMAT_FEATURE_BIASED_NORMALIZATION) - { - // The renormalization flag applies to all channels. It is weaker than the other flags. - // This applies on input and is subject to remap overrides - if (tex.unsigned_remap() == CELL_GCM_TEXTURE_UNSIGNED_REMAP_BIASED) - { - unsigned_remap = remap_channel_bits(texture_remap, 0xF) & ~(argb8_signed | gamma); - } - } - - u32 argb8_convert = gamma; - - // The options are mutually exclusive - ensure((argb8_signed & gamma) == 0); - ensure((argb8_signed & unsigned_remap) == 0); - ensure((gamma & unsigned_remap) == 0); - - // NOTE: Hardware tests show that remapping bypasses the channel swizzles completely - argb8_convert |= (argb8_signed << texture_control_bits::SEXT_OFFSET); - argb8_convert |= (unsigned_remap << texture_control_bits::EXPAND_OFFSET); - texture_control |= argb8_convert; - - texture_control |= format_features << texture_control_bits::FORMAT_FEATURES_OFFSET; + texture_control |= format_ex.texel_remap_control; + texture_control |= format_ex.features << texture_control_bits::FORMAT_FEATURES_OFFSET; if (current_fp_metadata.has_tex_bx2_conv) { - const u32 remap_hi = remap_channel_bits(texture_remap, 0xFu); + const u32 remap_hi = tex.decoded_remap().shuffle_mask_bits(0xFu); current_fragment_program.texture_params[i].remap &= ~(0xFu << 16u); current_fragment_program.texture_params[i].remap |= (remap_hi << 16u); } diff --git a/rpcs3/Emu/RSX/VK/VKDraw.cpp b/rpcs3/Emu/RSX/VK/VKDraw.cpp index 491078cc93..7a9d6aae6e 100644 --- a/rpcs3/Emu/RSX/VK/VKDraw.cpp +++ b/rpcs3/Emu/RSX/VK/VKDraw.cpp @@ -1,5 +1,6 @@ #include "stdafx.h" #include "../Common/BufferUtils.h" +#include "../Program/GLSLCommon.h" #include "../rsx_methods.h" #include "VKAsyncScheduler.h" @@ -307,6 +308,8 @@ void VKGSRender::load_texture_env() if (sampler_state->validate()) { + sampler_state->format_ex = tex.format_ex(); + if (sampler_state->is_cyclic_reference) { check_for_cyclic_refs |= true; @@ -324,7 +327,7 @@ void VKGSRender::load_texture_env() f32 min_lod = 0.f, max_lod = 0.f; f32 lod_bias = 0.f; - const u32 texture_format = tex.format() & ~(CELL_GCM_TEXTURE_UN | CELL_GCM_TEXTURE_LN); + const u32 texture_format = sampler_state->format_ex.format(); VkBool32 compare_enabled = VK_FALSE; VkCompareOp depth_compare_mode = VK_COMPARE_OP_NEVER; @@ -350,7 +353,8 @@ void VKGSRender::load_texture_env() if (sampler_state->format_class == RSX_FORMAT_CLASS_COLOR) [[likely]] { // Most PS3-like formats can be linearly filtered without problem - can_sample_linear = true; + // Exclude textures that require SNORM conversion however + can_sample_linear = (sampler_state->format_ex.texel_remap_control & rsx::texture_control_bits::SEXT_MASK) == 0; } else if (sampler_state->format_class != rsx::classify_format(texture_format) && (texture_format == CELL_GCM_TEXTURE_A8R8G8B8 || texture_format == CELL_GCM_TEXTURE_D8R8G8B8)) From 3b494202059f7ff94f27b44414d8b173496b31fd Mon Sep 17 00:00:00 2001 From: oltolm Date: Sun, 22 Feb 2026 12:26:27 +0100 Subject: [PATCH 026/175] cellVdec: replace std::aligned_union_t with a union --- rpcs3/Emu/Cell/Modules/cellVdec.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/rpcs3/Emu/Cell/Modules/cellVdec.cpp b/rpcs3/Emu/Cell/Modules/cellVdec.cpp index 5cf5e64a51..3205afd786 100644 --- a/rpcs3/Emu/Cell/Modules/cellVdec.cpp +++ b/rpcs3/Emu/Cell/Modules/cellVdec.cpp @@ -1462,7 +1462,12 @@ error_code cellVdecGetPicItem(ppu_thread& ppu, u32 handle, vm::pptr picInfo; + union + { + CellVdecAvcInfo avcInfo; + CellVdecDivxInfo divxInfo; + CellVdecMpeg2Info mpeg2Info; + } picInfo; }; AVFrame* frame{}; From 260c98618614c070067c6b0b1a82f2e8199d7d4a Mon Sep 17 00:00:00 2001 From: silviolet Date: Wed, 11 Feb 2026 13:27:40 -0500 Subject: [PATCH 027/175] Implemented sorted emit_data for YAML nodes - emit_data now Recursively sorts each node in a YAML node and outputs them as per the function description, originally a TODO - The default config is still unsorted so when you click save or apply the sorted file will appear --- rpcs3/rpcs3qt/emu_settings.cpp | 37 ++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/rpcs3/rpcs3qt/emu_settings.cpp b/rpcs3/rpcs3qt/emu_settings.cpp index 20bb58ba93..ccb2308509 100644 --- a/rpcs3/rpcs3qt/emu_settings.cpp +++ b/rpcs3/rpcs3qt/emu_settings.cpp @@ -25,8 +25,41 @@ namespace { static NEVER_INLINE void emit_data(YAML::Emitter& out, const YAML::Node& node) { - // TODO - out << node; + if (!node || node.IsNull()) + { + // I chose to output a null when nothing is present so that recursive YAML Value calls can be matched to a null value instead of nothing + out << YAML::Null; + return; + } + if (node.IsMap()) + { + std::vector keys; + keys.reserve(node.size()); + // generate vector of strings to be sorted using the as function from YAML documentation + for (const auto& pair : node) + { + keys.push_back(pair.first.as()); + } + std::sort(keys.begin(), keys.end()); + // recursively generate sorted maps + // alternative implementations could have stops at specified recursion levels or maybe just the first two levels would be sorted + out << YAML::BeginMap; + for (const std::string& key : keys) + { + out << YAML::Key << key; + out << YAML::Value; + emit_data(out, node[key]); + } + out << YAML::EndMap; + } + // alternatively: an else statement could be used however I wanted to follow a similar format to the += operator so the YAML Undefined class can be ignored + else if (node.IsScalar() || node.IsSequence()) + { + out << node; + } + // this exists to preserve the same functionality as before where Undefined nodes would still be output, can be removed or consolidated with the else if branch + else + out << node; } // Incrementally load YAML From 064c006339f9e5b46e43c4dfa8d0c8e1e18eeece Mon Sep 17 00:00:00 2001 From: RipleyTom Date: Wed, 25 Feb 2026 00:58:09 +0100 Subject: [PATCH 028/175] Various sys_ fixes --- rpcs3/Emu/Cell/lv2/sys_cond.cpp | 1 + rpcs3/Emu/Cell/lv2/sys_event.cpp | 7 ++++--- rpcs3/Emu/Cell/lv2/sys_event.h | 1 - rpcs3/Emu/Cell/lv2/sys_lwcond.cpp | 2 ++ rpcs3/Emu/Cell/lv2/sys_mutex.cpp | 2 +- rpcs3/Emu/Cell/lv2/sys_spu.cpp | 2 +- 6 files changed, 9 insertions(+), 6 deletions(-) diff --git a/rpcs3/Emu/Cell/lv2/sys_cond.cpp b/rpcs3/Emu/Cell/lv2/sys_cond.cpp index 401ed3bd66..f66146ae01 100644 --- a/rpcs3/Emu/Cell/lv2/sys_cond.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_cond.cpp @@ -59,6 +59,7 @@ CellError lv2_cond::on_id_create() if (!mutex) { _mutex = static_cast>(ensure(idm::get_unlocked(mtx_id))); + mutex = static_cast(_mutex.get()); } // Defer function diff --git a/rpcs3/Emu/Cell/lv2/sys_event.cpp b/rpcs3/Emu/Cell/lv2/sys_event.cpp index 8b3de14bf7..d50ae87f9d 100644 --- a/rpcs3/Emu/Cell/lv2/sys_event.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_event.cpp @@ -621,7 +621,7 @@ error_code sys_event_port_create(cpu_thread& cpu, vm::ptr eport_id, s32 por sys_event.warning("sys_event_port_create(eport_id=*0x%x, port_type=%d, name=0x%llx)", eport_id, port_type, name); - if (port_type != SYS_EVENT_PORT_LOCAL && port_type != 3) + if (port_type != SYS_EVENT_PORT_LOCAL && port_type != SYS_EVENT_PORT_IPC) { sys_event.error("sys_event_port_create(): unknown port type (%d)", port_type); return CELL_EINVAL; @@ -675,8 +675,9 @@ error_code sys_event_port_connect_local(cpu_thread& cpu, u32 eport_id, u32 equeu std::lock_guard lock(id_manager::g_mutex); const auto port = idm::check_unlocked(eport_id); + auto queue = idm::get_unlocked(equeue_id); - if (!port || !idm::check_unlocked(equeue_id)) + if (!port || !queue) { return CELL_ESRCH; } @@ -691,7 +692,7 @@ error_code sys_event_port_connect_local(cpu_thread& cpu, u32 eport_id, u32 equeu return CELL_EISCONN; } - port->queue = idm::get_unlocked(equeue_id); + port->queue = std::move(queue); return CELL_OK; } diff --git a/rpcs3/Emu/Cell/lv2/sys_event.h b/rpcs3/Emu/Cell/lv2/sys_event.h index 6c43798a30..8364361e6c 100644 --- a/rpcs3/Emu/Cell/lv2/sys_event.h +++ b/rpcs3/Emu/Cell/lv2/sys_event.h @@ -7,7 +7,6 @@ #include class cpu_thread; -class spu_thrread; // Event Queue Type enum : u32 diff --git a/rpcs3/Emu/Cell/lv2/sys_lwcond.cpp b/rpcs3/Emu/Cell/lv2/sys_lwcond.cpp index 43bfb308ba..ebe4dfc07c 100644 --- a/rpcs3/Emu/Cell/lv2/sys_lwcond.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_lwcond.cpp @@ -487,6 +487,8 @@ error_code _sys_lwcond_queue_wait(ppu_thread& ppu, u32 lwcond_id, u32 lwmutex_id { ensure(cond.unqueue(cond.sq, &ppu)); ppu.state += cpu_flag::again; + cond.lwmutex_waiters--; + mutex->lwcond_waiters--; return; } diff --git a/rpcs3/Emu/Cell/lv2/sys_mutex.cpp b/rpcs3/Emu/Cell/lv2/sys_mutex.cpp index e6c96ffd64..9f436ae4d3 100644 --- a/rpcs3/Emu/Cell/lv2/sys_mutex.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_mutex.cpp @@ -85,7 +85,7 @@ error_code sys_mutex_create(ppu_thread& ppu, vm::ptr mutex_id, vm::ptr(_attr.pshared, _attr.ipc_key, _attr.flags, [&]() + if (auto error = lv2_obj::create(_attr.pshared, ipc_key, _attr.flags, [&]() { return make_shared( _attr.protocol, diff --git a/rpcs3/Emu/Cell/lv2/sys_spu.cpp b/rpcs3/Emu/Cell/lv2/sys_spu.cpp index 3665efcd0a..ff4294a24f 100644 --- a/rpcs3/Emu/Cell/lv2/sys_spu.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_spu.cpp @@ -437,7 +437,7 @@ struct spu_limits_t raw_spu_count += spu_thread::g_raw_spu_ctr; // physical_spus_count >= spu_limit returns EBUSY, not EINVAL! - if (spu_limit + raw_limit > 6 || raw_spu_count > raw_limit || physical_spus_count >= spu_limit || physical_spus_count > spu_limit || controllable_spu_count > spu_limit) + if (spu_limit + raw_limit > 6 || raw_spu_count > raw_limit || physical_spus_count >= spu_limit || controllable_spu_count > spu_limit) { return false; } From bc93fdf9f40f8cef00edb1d506cf0266f4aa27c2 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Wed, 25 Feb 2026 07:10:06 +0100 Subject: [PATCH 029/175] input: Add some logging to mouse_gyro_handler --- rpcs3/Input/mouse_gyro_handler.cpp | 50 ++++++++++++++++-------------- rpcs3/Input/mouse_gyro_handler.h | 27 ++++++++-------- 2 files changed, 39 insertions(+), 38 deletions(-) diff --git a/rpcs3/Input/mouse_gyro_handler.cpp b/rpcs3/Input/mouse_gyro_handler.cpp index 6f1c7cd637..e1b241f9cd 100644 --- a/rpcs3/Input/mouse_gyro_handler.cpp +++ b/rpcs3/Input/mouse_gyro_handler.cpp @@ -1,3 +1,4 @@ +#include "stdafx.h" #include "mouse_gyro_handler.h" #include @@ -7,53 +8,57 @@ #include +LOG_CHANNEL(gui_log, "GUI"); + void mouse_gyro_handler::clear() { - active = false; - reset = false; - gyro_x = DEFAULT_MOTION_X; - gyro_y = DEFAULT_MOTION_Y; - gyro_z = DEFAULT_MOTION_Z; + m_active = false; + m_reset = false; + m_gyro_x = DEFAULT_MOTION_X; + m_gyro_y = DEFAULT_MOTION_Y; + m_gyro_z = DEFAULT_MOTION_Z; } bool mouse_gyro_handler::toggle_enabled() { - enabled = !enabled; + m_enabled = !m_enabled; clear(); - return enabled; + return m_enabled; } void mouse_gyro_handler::set_gyro_active() { - active = true; + gui_log.notice("Mouse-based gyro activated"); + m_active = true; } void mouse_gyro_handler::set_gyro_reset() { - active = false; - reset = true; + gui_log.notice("Mouse-based gyro deactivated"); + m_active = false; + m_reset = true; } void mouse_gyro_handler::set_gyro_xz(s32 off_x, s32 off_y) { - if (!active) + if (!m_active) return; - gyro_x = static_cast(std::clamp(off_x, 0, DEFAULT_MOTION_X * 2 - 1)); - gyro_z = static_cast(std::clamp(off_y, 0, DEFAULT_MOTION_Z * 2 - 1)); + m_gyro_x = static_cast(std::clamp(off_x, 0, DEFAULT_MOTION_X * 2 - 1)); + m_gyro_z = static_cast(std::clamp(off_y, 0, DEFAULT_MOTION_Z * 2 - 1)); } void mouse_gyro_handler::set_gyro_y(s32 steps) { - if (!active) + if (!m_active) return; - gyro_y = static_cast(std::clamp(gyro_y + steps, 0, DEFAULT_MOTION_Y * 2 - 1)); + m_gyro_y = static_cast(std::clamp(m_gyro_y + steps, 0, DEFAULT_MOTION_Y * 2 - 1)); } void mouse_gyro_handler::handle_event(QEvent* ev, const QWindow& win) { - if (!enabled) + if (!m_enabled) return; // Mouse-based motion input. @@ -119,15 +124,12 @@ void mouse_gyro_handler::handle_event(QEvent* ev, const QWindow& win) void mouse_gyro_handler::apply_gyro(const std::shared_ptr& pad) { - if (!enabled) - return; - - if (!pad || !pad->is_connected()) + if (!m_enabled || !pad || !pad->is_connected()) return; // Inject mouse-based motion sensor values into pad sensors for gyro emulation. // The Qt frontend maps cursor offset and wheel input to absolute motion values while RMB is held. - if (reset) + if (m_reset) { // RMB released → reset motion pad->m_sensors[0].m_value = DEFAULT_MOTION_X; @@ -139,8 +141,8 @@ void mouse_gyro_handler::apply_gyro(const std::shared_ptr& pad) { // RMB held → accumulate motion // Axes have been chosen as tested in Sly 4 minigames. Top-down view motion uses X/Z axes. - pad->m_sensors[0].m_value = gyro_x; // Mouse X → Motion X - pad->m_sensors[1].m_value = gyro_y; // Mouse Wheel → Motion Y - pad->m_sensors[2].m_value = gyro_z; // Mouse Y → Motion Z + pad->m_sensors[0].m_value = m_gyro_x; // Mouse X → Motion X + pad->m_sensors[1].m_value = m_gyro_y; // Mouse Wheel → Motion Y + pad->m_sensors[2].m_value = m_gyro_z; // Mouse Y → Motion Z } } diff --git a/rpcs3/Input/mouse_gyro_handler.h b/rpcs3/Input/mouse_gyro_handler.h index 97a745d919..9c53f574e4 100644 --- a/rpcs3/Input/mouse_gyro_handler.h +++ b/rpcs3/Input/mouse_gyro_handler.h @@ -10,24 +10,23 @@ class QWindow; // Mouse-based motion sensor emulation state. class mouse_gyro_handler { -private: - atomic_t enabled = false; // Whether mouse-based gyro emulation mode has been enabled by using the associated hotkey - - atomic_t active = false; // Whether right mouse button is currently held (gyro active) - atomic_t reset = false; // One-shot reset request on right mouse button release - atomic_t gyro_x = DEFAULT_MOTION_X; // Accumulated from mouse X position relative to center - atomic_t gyro_y = DEFAULT_MOTION_Y; // Accumulated from mouse wheel delta - atomic_t gyro_z = DEFAULT_MOTION_Z; // Accumulated from mouse Y position relative to center - - void set_gyro_active(); - void set_gyro_reset(); - void set_gyro_xz(s32 off_x, s32 off_y); - void set_gyro_y(s32 steps); - public: void clear(); bool toggle_enabled(); void handle_event(QEvent* ev, const QWindow& win); void apply_gyro(const std::shared_ptr& pad); + +private: + atomic_t m_enabled = false; // Whether mouse-based gyro emulation mode has been enabled by using the associated hotkey + atomic_t m_active = false; // Whether right mouse button is currently held (gyro active) + atomic_t m_reset = false; // One-shot reset request on right mouse button release + atomic_t m_gyro_x = DEFAULT_MOTION_X; // Accumulated from mouse X position relative to center + atomic_t m_gyro_y = DEFAULT_MOTION_Y; // Accumulated from mouse wheel delta + atomic_t m_gyro_z = DEFAULT_MOTION_Z; // Accumulated from mouse Y position relative to center + + void set_gyro_active(); + void set_gyro_reset(); + void set_gyro_xz(s32 off_x, s32 off_y); + void set_gyro_y(s32 steps); }; From f6429a1ae84a3968f57a21f3ac13d679d61313c2 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Wed, 25 Feb 2026 07:40:08 +0100 Subject: [PATCH 030/175] overlays: add fullscreen toggle to home menu --- .../HomeMenu/overlay_home_menu_main_menu.cpp | 15 ++++++++++++++- rpcs3/Emu/localized_string_id.h | 1 + rpcs3/rpcs3qt/gs_frame.cpp | 9 +++++++++ rpcs3/rpcs3qt/localized_emu.h | 1 + 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/rpcs3/Emu/RSX/Overlays/HomeMenu/overlay_home_menu_main_menu.cpp b/rpcs3/Emu/RSX/Overlays/HomeMenu/overlay_home_menu_main_menu.cpp index 7a6a5a6b47..368ac4dd39 100644 --- a/rpcs3/Emu/RSX/Overlays/HomeMenu/overlay_home_menu_main_menu.cpp +++ b/rpcs3/Emu/RSX/Overlays/HomeMenu/overlay_home_menu_main_menu.cpp @@ -12,6 +12,8 @@ extern atomic_t g_user_asked_for_recording; +atomic_t g_user_asked_for_fullscreen = false; + namespace rsx { namespace overlays @@ -80,7 +82,7 @@ namespace rsx if (btn != pad_button::cross) return page_navigation::stay; rsx_log.notice("User selected trophies in home menu"); - Emu.CallFromMainThread([trop_name = std::move(trop_name)]() + Emu.CallFromMainThread([trop_name]() { if (auto manager = g_fxo->try_get()) { @@ -110,6 +112,17 @@ namespace rsx return page_navigation::exit; }); + std::unique_ptr fullscreen = std::make_unique(get_localized_string(localized_string_id::HOME_MENU_TOGGLE_FULLSCREEN)); + add_item(fullscreen, [](pad_button btn) -> page_navigation + { + if (btn != pad_button::cross) + return page_navigation::stay; + + rsx_log.notice("User selected toggle fullscreen in home menu"); + g_user_asked_for_fullscreen = true; + return page_navigation::stay; // No need to exit + }); + add_page(std::make_shared(x, y, width, height, use_separators, this)); std::unique_ptr restart = std::make_unique(get_localized_string(localized_string_id::HOME_MENU_RESTART)); diff --git a/rpcs3/Emu/localized_string_id.h b/rpcs3/Emu/localized_string_id.h index 399b45c437..9ab9f57a9b 100644 --- a/rpcs3/Emu/localized_string_id.h +++ b/rpcs3/Emu/localized_string_id.h @@ -277,6 +277,7 @@ enum class localized_string_id HOME_MENU_RELOAD_SECOND_SAVESTATE, HOME_MENU_RELOAD_THIRD_SAVESTATE, HOME_MENU_RELOAD_FOURTH_SAVESTATE, + HOME_MENU_TOGGLE_FULLSCREEN, HOME_MENU_RECORDING, HOME_MENU_TROPHIES, HOME_MENU_TROPHY_LIST_TITLE, diff --git a/rpcs3/rpcs3qt/gs_frame.cpp b/rpcs3/rpcs3qt/gs_frame.cpp index 6557168cce..74ecf7fccd 100644 --- a/rpcs3/rpcs3qt/gs_frame.cpp +++ b/rpcs3/rpcs3qt/gs_frame.cpp @@ -51,6 +51,7 @@ LOG_CHANNEL(screenshot_log, "SCREENSHOT"); LOG_CHANNEL(mark_log, "MARK"); LOG_CHANNEL(gui_log, "GUI"); +extern atomic_t g_user_asked_for_fullscreen; extern atomic_t g_user_asked_for_recording; extern atomic_t g_user_asked_for_screenshot; extern atomic_t g_user_asked_for_frame_capture; @@ -840,6 +841,14 @@ void gs_frame::flip(draw_context_t, bool /*skip_frame*/) toggle_recording(); }); } + + if (g_user_asked_for_fullscreen.exchange(false)) + { + Emu.CallFromMainThread([this]() + { + toggle_fullscreen(); + }); + } } bool gs_frame::can_consume_frame() const diff --git a/rpcs3/rpcs3qt/localized_emu.h b/rpcs3/rpcs3qt/localized_emu.h index 7d4453a1bd..d05d3e52ee 100644 --- a/rpcs3/rpcs3qt/localized_emu.h +++ b/rpcs3/rpcs3qt/localized_emu.h @@ -298,6 +298,7 @@ private: case localized_string_id::HOME_MENU_RELOAD_SECOND_SAVESTATE: return tr("Reload Second-To-Last Emulation State"); case localized_string_id::HOME_MENU_RELOAD_THIRD_SAVESTATE: return tr("Reload Third-To-Last Emulation State"); case localized_string_id::HOME_MENU_RELOAD_FOURTH_SAVESTATE: return tr("Reload Fourth-To-Last Emulation State"); + case localized_string_id::HOME_MENU_TOGGLE_FULLSCREEN: return tr("Toggle Fullscreen"); case localized_string_id::HOME_MENU_RECORDING: return tr("Start/Stop Recording"); case localized_string_id::HOME_MENU_TROPHIES: return tr("Trophies"); case localized_string_id::HOME_MENU_TROPHY_LIST_TITLE: return tr("Trophy Progress: %0").arg(std::forward(args)...); From 8a0eae0ccdc53a0185e65b25c6472f201fbeb7f7 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Wed, 25 Feb 2026 07:50:26 +0100 Subject: [PATCH 031/175] overlays: allow to go to begin/end of list without auto repeat --- .../RSX/Overlays/HomeMenu/overlay_home_menu_page.cpp | 12 ++++++++++++ rpcs3/Emu/RSX/Overlays/overlay_list_view.cpp | 7 ++++++- rpcs3/Emu/RSX/Overlays/overlay_list_view.hpp | 3 ++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/rpcs3/Emu/RSX/Overlays/HomeMenu/overlay_home_menu_page.cpp b/rpcs3/Emu/RSX/Overlays/HomeMenu/overlay_home_menu_page.cpp index 81c1ebecba..edfb932d26 100644 --- a/rpcs3/Emu/RSX/Overlays/HomeMenu/overlay_home_menu_page.cpp +++ b/rpcs3/Emu/RSX/Overlays/HomeMenu/overlay_home_menu_page.cpp @@ -215,12 +215,24 @@ namespace rsx case pad_button::dpad_up: case pad_button::ls_up: { + if (!is_auto_repeat && get_selected_index() <= 0) + { + select_entry(get_elements_count() - 1); + break; + } + select_previous(); break; } case pad_button::dpad_down: case pad_button::ls_down: { + if (!is_auto_repeat && get_selected_index() >= (get_elements_count() - 1)) + { + select_entry(0); + break; + } + select_next(); break; } diff --git a/rpcs3/Emu/RSX/Overlays/overlay_list_view.cpp b/rpcs3/Emu/RSX/Overlays/overlay_list_view.cpp index 093902dbe3..1b6f4e8fc6 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_list_view.cpp +++ b/rpcs3/Emu/RSX/Overlays/overlay_list_view.cpp @@ -189,7 +189,12 @@ namespace rsx update_selection(); } - int list_view::get_selected_index() const + u16 list_view::get_elements_count() const + { + return m_elements_count; + } + + s32 list_view::get_selected_index() const { return m_selected_entry; } diff --git a/rpcs3/Emu/RSX/Overlays/overlay_list_view.hpp b/rpcs3/Emu/RSX/Overlays/overlay_list_view.hpp index c2378c5319..8f191dd404 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_list_view.hpp +++ b/rpcs3/Emu/RSX/Overlays/overlay_list_view.hpp @@ -34,7 +34,8 @@ namespace rsx void add_entry(std::unique_ptr& entry); - int get_selected_index() const; + u16 get_elements_count() const; + s32 get_selected_index() const; bool get_cancel_only() const; const overlay_element* get_selected_entry() const; From 9ede04c4b9f867d3568b7cf193fb8d4af71f54f9 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Wed, 25 Feb 2026 08:02:17 +0100 Subject: [PATCH 032/175] Invalidate some global variables in gs_frame dtor --- rpcs3/rpcs3qt/gs_frame.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rpcs3/rpcs3qt/gs_frame.cpp b/rpcs3/rpcs3qt/gs_frame.cpp index 74ecf7fccd..ef6fa7cb46 100644 --- a/rpcs3/rpcs3qt/gs_frame.cpp +++ b/rpcs3/rpcs3qt/gs_frame.cpp @@ -151,6 +151,9 @@ gs_frame::gs_frame(QScreen* screen, const QRect& geometry, const QIcon& appIcon, gs_frame::~gs_frame() { g_user_asked_for_screenshot = false; + g_user_asked_for_recording = false; + g_user_asked_for_frame_capture = false; + g_user_asked_for_fullscreen = false; pad::g_home_menu_requested = false; // Save active screen to gui settings From 7c8b915ba1eae5097825b40964e8b7290945d72c Mon Sep 17 00:00:00 2001 From: Megamouse Date: Wed, 25 Feb 2026 09:01:08 +0100 Subject: [PATCH 033/175] tiny style fixes --- rpcs3/Emu/title.h | 2 +- rpcs3/rpcs3qt/gs_frame.cpp | 6 +++--- rpcs3/rpcs3qt/gs_frame.h | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/rpcs3/Emu/title.h b/rpcs3/Emu/title.h index 7084231f32..783ad7abb4 100644 --- a/rpcs3/Emu/title.h +++ b/rpcs3/Emu/title.h @@ -11,7 +11,7 @@ namespace rpcs3 std::string title_id; std::string renderer; std::string vulkan_adapter; - double fps = .0; + double fps = 0.0; }; std::string get_formatted_title(const title_format_data& title_data); diff --git a/rpcs3/rpcs3qt/gs_frame.cpp b/rpcs3/rpcs3qt/gs_frame.cpp index ef6fa7cb46..67a750316e 100644 --- a/rpcs3/rpcs3qt/gs_frame.cpp +++ b/rpcs3/rpcs3qt/gs_frame.cpp @@ -205,12 +205,12 @@ void gs_frame::update_shortcuts() } } -void gs_frame::paintEvent(QPaintEvent *event) +void gs_frame::paintEvent(QPaintEvent* event) { Q_UNUSED(event) } -void gs_frame::showEvent(QShowEvent *event) +void gs_frame::showEvent(QShowEvent* event) { // We have to calculate new window positions, since the frame is only known once the window was created. // We will try to find the originally requested dimensions if possible by moving the frame. @@ -805,7 +805,7 @@ f64 gs_frame::client_display_rate() return rate; } -void gs_frame::flip(draw_context_t, bool /*skip_frame*/) +void gs_frame::flip(draw_context_t /*context*/, bool /*skip_frame*/) { static Timer fps_t; diff --git a/rpcs3/rpcs3qt/gs_frame.h b/rpcs3/rpcs3qt/gs_frame.h index a00773240e..5e63a2d9c1 100644 --- a/rpcs3/rpcs3qt/gs_frame.h +++ b/rpcs3/rpcs3qt/gs_frame.h @@ -85,8 +85,8 @@ public: protected: video_renderer m_renderer; - void paintEvent(QPaintEvent *event) override; - void showEvent(QShowEvent *event) override; + void paintEvent(QPaintEvent* event) override; + void showEvent(QShowEvent* event) override; void close() override; void reset() override; From 9e7268ed6de007a4ea09b31d162f7c52b9af47fb Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sun, 22 Feb 2026 17:02:15 +0300 Subject: [PATCH 034/175] gl: Despaghettify texture handling --- rpcs3/Emu/RSX/GL/GLDraw.cpp | 149 +++++++++++++++++++++--------------- 1 file changed, 87 insertions(+), 62 deletions(-) diff --git a/rpcs3/Emu/RSX/GL/GLDraw.cpp b/rpcs3/Emu/RSX/GL/GLDraw.cpp index 475507ee78..b167ab24c2 100644 --- a/rpcs3/Emu/RSX/GL/GLDraw.cpp +++ b/rpcs3/Emu/RSX/GL/GLDraw.cpp @@ -299,95 +299,114 @@ void GLGSRender::load_texture_env() for (u32 textures_ref = current_fp_metadata.referenced_textures_mask, i = 0; textures_ref; textures_ref >>= 1, ++i) { if (!(textures_ref & 1)) + { continue; + } if (!fs_sampler_state[i]) + { fs_sampler_state[i] = std::make_unique(); + } auto sampler_state = static_cast(fs_sampler_state[i].get()); const auto& tex = rsx::method_registers.fragment_textures[i]; const auto previous_format_class = sampler_state->format_class; - if (m_samplers_dirty || m_textures_dirty[i] || m_gl_texture_cache.test_if_descriptor_expired(cmd, m_rtts, sampler_state, tex)) + if (!m_samplers_dirty && + !m_textures_dirty[i] && + !m_gl_texture_cache.test_if_descriptor_expired(cmd, m_rtts, sampler_state, tex)) { - if (tex.enabled()) - { - *sampler_state = m_gl_texture_cache.upload_texture(cmd, tex, m_rtts); + continue; + } - if (sampler_state->validate()) - { - sampler_state->format_ex = tex.format_ex(); + const bool is_sampler_dirty = m_textures_dirty[i]; + m_textures_dirty[i] = false; - if (m_textures_dirty[i]) - { - m_fs_sampler_states[i].apply(tex, fs_sampler_state[i].get()); - } - else if (sampler_state->format_class != previous_format_class) - { - m_graphics_state |= rsx::fragment_program_state_dirty; - } + if (!tex.enabled()) + { + *sampler_state = {}; + continue; + } - const auto texture_format = sampler_state->format_ex.format(); - // Depth format redirected to BGRA8 resample stage. Do not filter to avoid bits leaking. - // If accurate graphics are desired, force a bitcast to COLOR as a workaround. - const bool is_depth_reconstructed = sampler_state->format_class != rsx::classify_format(texture_format) && - (texture_format == CELL_GCM_TEXTURE_A8R8G8B8 || texture_format == CELL_GCM_TEXTURE_D8R8G8B8); - // SNORM conversion required in shader. Do not interpolate to avoid introducing discontinuities due to how negative numbers work - const bool is_snorm = (sampler_state->format_ex.texel_remap_control & rsx::texture_control_bits::SEXT_MASK) != 0; + *sampler_state = m_gl_texture_cache.upload_texture(cmd, tex, m_rtts); + if (!sampler_state->validate()) + { + continue; + } - if (is_depth_reconstructed || is_snorm) - { - // Depth format redirected to BGRA8 resample stage. Do not filter to avoid bits leaking. - m_fs_sampler_states[i].set_parameteri(GL_TEXTURE_MIN_FILTER, GL_NEAREST); - m_fs_sampler_states[i].set_parameteri(GL_TEXTURE_MAG_FILTER, GL_NEAREST); - } - } - } - else - { - *sampler_state = {}; - } + sampler_state->format_ex = tex.format_ex(); - m_textures_dirty[i] = false; + if (is_sampler_dirty) + { + m_fs_sampler_states[i].apply(tex, fs_sampler_state[i].get()); + } + else if (sampler_state->format_class != previous_format_class) + { + m_graphics_state |= rsx::fragment_program_state_dirty; + } + + const auto texture_format = sampler_state->format_ex.format(); + // Depth format redirected to BGRA8 resample stage. Do not filter to avoid bits leaking. + // If accurate graphics are desired, force a bitcast to COLOR as a workaround. + const bool is_depth_reconstructed = sampler_state->format_class != rsx::classify_format(texture_format) && + (texture_format == CELL_GCM_TEXTURE_A8R8G8B8 || texture_format == CELL_GCM_TEXTURE_D8R8G8B8); + // SNORM conversion required in shader. Do not interpolate to avoid introducing discontinuities due to how negative numbers work + const bool is_snorm = (sampler_state->format_ex.texel_remap_control & rsx::texture_control_bits::SEXT_MASK) != 0; + + if (is_depth_reconstructed || is_snorm) + { + // Depth format redirected to BGRA8 resample stage. Do not filter to avoid bits leaking. + m_fs_sampler_states[i].set_parameteri(GL_TEXTURE_MIN_FILTER, GL_NEAREST); + m_fs_sampler_states[i].set_parameteri(GL_TEXTURE_MAG_FILTER, GL_NEAREST); } } for (u32 textures_ref = current_vp_metadata.referenced_textures_mask, i = 0; textures_ref; textures_ref >>= 1, ++i) { if (!(textures_ref & 1)) + { continue; + } if (!vs_sampler_state[i]) + { vs_sampler_state[i] = std::make_unique(); + } auto sampler_state = static_cast(vs_sampler_state[i].get()); const auto& tex = rsx::method_registers.vertex_textures[i]; const auto previous_format_class = sampler_state->format_class; - if (m_samplers_dirty || m_vertex_textures_dirty[i] || m_gl_texture_cache.test_if_descriptor_expired(cmd, m_rtts, sampler_state, tex)) + if (!m_samplers_dirty && + !m_vertex_textures_dirty[i] && + !m_gl_texture_cache.test_if_descriptor_expired(cmd, m_rtts, sampler_state, tex)) { - if (rsx::method_registers.vertex_textures[i].enabled()) - { - *sampler_state = m_gl_texture_cache.upload_texture(cmd, rsx::method_registers.vertex_textures[i], m_rtts); + continue; + } - if (sampler_state->validate()) - { - if (m_vertex_textures_dirty[i]) - { - m_vs_sampler_states[i].apply(tex, vs_sampler_state[i].get()); - } - else if (sampler_state->format_class != previous_format_class) - { - m_graphics_state |= rsx::vertex_program_state_dirty; - } - } - } - else - { - *sampler_state = {}; - } + const bool is_sampler_dirty = m_vertex_textures_dirty[i]; + m_vertex_textures_dirty[i] = false; - m_vertex_textures_dirty[i] = false; + if (!tex.enabled()) + { + *sampler_state = {}; + continue; + } + + *sampler_state = m_gl_texture_cache.upload_texture(cmd, rsx::method_registers.vertex_textures[i], m_rtts); + + if (!sampler_state->validate()) + { + continue; + } + + if (m_vertex_textures_dirty[i]) + { + m_vs_sampler_states[i].apply(tex, vs_sampler_state[i].get()); + } + else if (sampler_state->format_class != previous_format_class) + { + m_graphics_state |= rsx::vertex_program_state_dirty; } } @@ -402,7 +421,9 @@ void GLGSRender::bind_texture_env() for (u32 textures_ref = current_fp_metadata.referenced_textures_mask, i = 0; textures_ref; textures_ref >>= 1, ++i) { if (!(textures_ref & 1)) + { continue; + } gl::texture_view* view = nullptr; auto sampler_state = static_cast(fs_sampler_state[i].get()); @@ -442,22 +463,26 @@ void GLGSRender::bind_texture_env() for (u32 textures_ref = current_vp_metadata.referenced_textures_mask, i = 0; textures_ref; textures_ref >>= 1, ++i) { if (!(textures_ref & 1)) + { continue; + } auto sampler_state = static_cast(vs_sampler_state[i].get()); + gl::texture_view* view = nullptr; if (rsx::method_registers.vertex_textures[i].enabled() && sampler_state->validate()) { - if (sampler_state->image_handle) [[likely]] + if (view = sampler_state->image_handle; !view) { - sampler_state->image_handle->bind(cmd, GL_VERTEX_TEXTURES_START + i); - } - else - { - m_gl_texture_cache.create_temporary_subresource(cmd, sampler_state->external_subresource_desc)->bind(cmd, GL_VERTEX_TEXTURES_START + i); + view = m_gl_texture_cache.create_temporary_subresource(cmd, sampler_state->external_subresource_desc); } } + + if (view) [[likely]] + { + view->bind(cmd, GL_VERTEX_TEXTURES_START + i); + } else { cmd->bind_texture(GL_VERTEX_TEXTURES_START + i, GL_TEXTURE_2D, GL_NONE); From b9bdbfa55b3380ae0b35e360a5d1895d910e43f6 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sun, 22 Feb 2026 17:25:25 +0300 Subject: [PATCH 035/175] vk: De-sphaggetify texture handling --- rpcs3/Emu/RSX/VK/VKDraw.cpp | 419 +++++++++++++++++++----------------- 1 file changed, 220 insertions(+), 199 deletions(-) diff --git a/rpcs3/Emu/RSX/VK/VKDraw.cpp b/rpcs3/Emu/RSX/VK/VKDraw.cpp index 7a9d6aae6e..27a07faf43 100644 --- a/rpcs3/Emu/RSX/VK/VKDraw.cpp +++ b/rpcs3/Emu/RSX/VK/VKDraw.cpp @@ -263,7 +263,7 @@ void VKGSRender::load_texture_env() { // Load textures bool check_for_cyclic_refs = false; - auto check_surface_cache_sampler = [&](auto descriptor, const auto& tex) + auto check_surface_cache_sampler_valid = [&](auto descriptor, const auto& tex) { if (!m_texture_cache.test_if_descriptor_expired(*m_current_command_buffer, m_rtts, descriptor, tex)) { @@ -286,242 +286,259 @@ void VKGSRender::load_texture_env() for (u32 textures_ref = current_fp_metadata.referenced_textures_mask, i = 0; textures_ref; textures_ref >>= 1, ++i) { if (!(textures_ref & 1)) + { continue; + } if (!fs_sampler_state[i]) + { fs_sampler_state[i] = std::make_unique(); + } auto sampler_state = static_cast(fs_sampler_state[i].get()); const auto& tex = rsx::method_registers.fragment_textures[i]; const auto previous_format_class = fs_sampler_state[i]->format_class; - if (m_samplers_dirty || m_textures_dirty[i] || !check_surface_cache_sampler(sampler_state, tex)) + if (!m_samplers_dirty && + !m_textures_dirty[i] && + check_surface_cache_sampler_valid(sampler_state, tex)) { - if (tex.enabled()) + continue; + } + + const bool is_sampler_dirty = m_textures_dirty[i]; + m_textures_dirty[i] = false; + + if (!tex.enabled()) + { + *sampler_state = {}; + continue; + } + + *sampler_state = m_texture_cache.upload_texture(*m_current_command_buffer, tex, m_rtts); + if (!sampler_state->validate()) + { + continue; + } + + sampler_state->format_ex = tex.format_ex(); + + if (sampler_state->is_cyclic_reference) + { + check_for_cyclic_refs |= true; + } + + if (!is_sampler_dirty && sampler_state->format_class != previous_format_class) + { + // Host details changed but RSX is not aware + m_graphics_state |= rsx::fragment_program_state_dirty; + } + + if (!is_sampler_dirty && fs_sampler_handles[i]) + { + // Nothing to change, use cached sampler + continue; + } + + VkFilter mag_filter; + vk::minification_filter min_filter; + f32 min_lod = 0.f, max_lod = 0.f; + f32 lod_bias = 0.f; + + const u32 texture_format = sampler_state->format_ex.format(); + VkBool32 compare_enabled = VK_FALSE; + VkCompareOp depth_compare_mode = VK_COMPARE_OP_NEVER; + + if (texture_format >= CELL_GCM_TEXTURE_DEPTH24_D8 && texture_format <= CELL_GCM_TEXTURE_DEPTH16_FLOAT) + { + compare_enabled = VK_TRUE; + depth_compare_mode = vk::get_compare_func(tex.zfunc(), true); + } + + const f32 af_level = vk::max_aniso(tex.max_aniso()); + const auto wrap_s = vk::vk_wrap_mode(tex.wrap_s()); + const auto wrap_t = vk::vk_wrap_mode(tex.wrap_t()); + const auto wrap_r = vk::vk_wrap_mode(tex.wrap_r()); + + // NOTE: In vulkan, the border color can bypass the sample swizzle stage. + // Check the device properties to determine whether to pre-swizzle the colors or not. + const auto border_color = rsx::is_border_clamped_texture(tex) + ? vk::border_color_t(get_border_color(tex)) + : vk::border_color_t(VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK); + + // Check if non-point filtering can even be used on this format + bool can_sample_linear; + if (sampler_state->format_class == RSX_FORMAT_CLASS_COLOR) [[likely]] + { + // Most PS3-like formats can be linearly filtered without problem + // Exclude textures that require SNORM conversion however + can_sample_linear = (sampler_state->format_ex.texel_remap_control & rsx::texture_control_bits::SEXT_MASK) == 0; + } + else if (sampler_state->format_class != rsx::classify_format(texture_format) && + (texture_format == CELL_GCM_TEXTURE_A8R8G8B8 || texture_format == CELL_GCM_TEXTURE_D8R8G8B8)) + { + // Depth format redirected to BGRA8 resample stage. Do not filter to avoid bits leaking + can_sample_linear = false; + } + else + { + // Not all GPUs support linear filtering of depth formats + const auto vk_format = sampler_state->image_handle ? sampler_state->image_handle->image()->format() : + vk::get_compatible_sampler_format(m_device->get_formats_support(), sampler_state->external_subresource_desc.gcm_format); + + can_sample_linear = m_device->get_format_properties(vk_format).optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT; + } + + const auto mipmap_count = tex.get_exact_mipmap_count(); + min_filter = vk::get_min_filter(tex.min_filter()); + + if (can_sample_linear) + { + mag_filter = vk::get_mag_filter(tex.mag_filter()); + } + else + { + mag_filter = VK_FILTER_NEAREST; + min_filter.filter = VK_FILTER_NEAREST; + } + + if (min_filter.sample_mipmaps && mipmap_count > 1) + { + f32 actual_mipmaps; + if (sampler_state->upload_context == rsx::texture_upload_context::shader_read) { - *sampler_state = m_texture_cache.upload_texture(*m_current_command_buffer, tex, m_rtts); + actual_mipmaps = static_cast(mipmap_count); + } + else if (sampler_state->external_subresource_desc.op == rsx::deferred_request_command::mipmap_gather) + { + // Clamp min and max lod + actual_mipmaps = static_cast(sampler_state->external_subresource_desc.sections_to_copy.size()); } else { - *sampler_state = {}; + actual_mipmaps = 1.f; } - if (sampler_state->validate()) + if (actual_mipmaps > 1.f) { - sampler_state->format_ex = tex.format_ex(); + min_lod = tex.min_lod(); + max_lod = tex.max_lod(); + lod_bias = tex.bias(); - if (sampler_state->is_cyclic_reference) + min_lod = std::min(min_lod, actual_mipmaps - 1.f); + max_lod = std::min(max_lod, actual_mipmaps - 1.f); + + if (min_filter.mipmap_mode == VK_SAMPLER_MIPMAP_MODE_NEAREST) { - check_for_cyclic_refs |= true; - } - - if (!m_textures_dirty[i] && sampler_state->format_class != previous_format_class) - { - // Host details changed but RSX is not aware - m_graphics_state |= rsx::fragment_program_state_dirty; - } - - bool replace = !fs_sampler_handles[i]; - VkFilter mag_filter; - vk::minification_filter min_filter; - f32 min_lod = 0.f, max_lod = 0.f; - f32 lod_bias = 0.f; - - const u32 texture_format = sampler_state->format_ex.format(); - VkBool32 compare_enabled = VK_FALSE; - VkCompareOp depth_compare_mode = VK_COMPARE_OP_NEVER; - - if (texture_format >= CELL_GCM_TEXTURE_DEPTH24_D8 && texture_format <= CELL_GCM_TEXTURE_DEPTH16_FLOAT) - { - compare_enabled = VK_TRUE; - depth_compare_mode = vk::get_compare_func(tex.zfunc(), true); - } - - const f32 af_level = vk::max_aniso(tex.max_aniso()); - const auto wrap_s = vk::vk_wrap_mode(tex.wrap_s()); - const auto wrap_t = vk::vk_wrap_mode(tex.wrap_t()); - const auto wrap_r = vk::vk_wrap_mode(tex.wrap_r()); - - // NOTE: In vulkan, the border color can bypass the sample swizzle stage. - // Check the device properties to determine whether to pre-swizzle the colors or not. - const auto border_color = rsx::is_border_clamped_texture(tex) - ? vk::border_color_t(get_border_color(tex)) - : vk::border_color_t(VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK); - - // Check if non-point filtering can even be used on this format - bool can_sample_linear; - if (sampler_state->format_class == RSX_FORMAT_CLASS_COLOR) [[likely]] - { - // Most PS3-like formats can be linearly filtered without problem - // Exclude textures that require SNORM conversion however - can_sample_linear = (sampler_state->format_ex.texel_remap_control & rsx::texture_control_bits::SEXT_MASK) == 0; - } - else if (sampler_state->format_class != rsx::classify_format(texture_format) && - (texture_format == CELL_GCM_TEXTURE_A8R8G8B8 || texture_format == CELL_GCM_TEXTURE_D8R8G8B8)) - { - // Depth format redirected to BGRA8 resample stage. Do not filter to avoid bits leaking - can_sample_linear = false; - } - else - { - // Not all GPUs support linear filtering of depth formats - const auto vk_format = sampler_state->image_handle ? sampler_state->image_handle->image()->format() : - vk::get_compatible_sampler_format(m_device->get_formats_support(), sampler_state->external_subresource_desc.gcm_format); - - can_sample_linear = m_device->get_format_properties(vk_format).optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT; - } - - const auto mipmap_count = tex.get_exact_mipmap_count(); - min_filter = vk::get_min_filter(tex.min_filter()); - - if (can_sample_linear) - { - mag_filter = vk::get_mag_filter(tex.mag_filter()); - } - else - { - mag_filter = VK_FILTER_NEAREST; - min_filter.filter = VK_FILTER_NEAREST; - } - - if (min_filter.sample_mipmaps && mipmap_count > 1) - { - f32 actual_mipmaps; - if (sampler_state->upload_context == rsx::texture_upload_context::shader_read) - { - actual_mipmaps = static_cast(mipmap_count); - } - else if (sampler_state->external_subresource_desc.op == rsx::deferred_request_command::mipmap_gather) - { - // Clamp min and max lod - actual_mipmaps = static_cast(sampler_state->external_subresource_desc.sections_to_copy.size()); - } - else - { - actual_mipmaps = 1.f; - } - - if (actual_mipmaps > 1.f) - { - min_lod = tex.min_lod(); - max_lod = tex.max_lod(); - lod_bias = tex.bias(); - - min_lod = std::min(min_lod, actual_mipmaps - 1.f); - max_lod = std::min(max_lod, actual_mipmaps - 1.f); - - if (min_filter.mipmap_mode == VK_SAMPLER_MIPMAP_MODE_NEAREST) - { - // Round to nearest 0.5 to work around some broken games - // Unlike openGL, sampler parameters cannot be dynamically changed on vulkan, leading to many permutations - lod_bias = std::floor(lod_bias * 2.f + 0.5f) * 0.5f; - } - } - else - { - min_lod = max_lod = lod_bias = 0.f; - min_filter.mipmap_mode = VK_SAMPLER_MIPMAP_MODE_NEAREST; - } - } - - if (fs_sampler_handles[i] && m_textures_dirty[i]) - { - if (!fs_sampler_handles[i]->matches(wrap_s, wrap_t, wrap_r, false, lod_bias, af_level, min_lod, max_lod, - min_filter.filter, mag_filter, min_filter.mipmap_mode, border_color, compare_enabled, depth_compare_mode)) - { - replace = true; - } - } - - if (replace) - { - fs_sampler_handles[i] = vk::get_resource_manager()->get_sampler( - *m_device, - fs_sampler_handles[i], - wrap_s, wrap_t, wrap_r, - false, - lod_bias, af_level, min_lod, max_lod, - min_filter.filter, mag_filter, min_filter.mipmap_mode, - border_color, compare_enabled, depth_compare_mode); + // Round to nearest 0.5 to work around some broken games + // Unlike openGL, sampler parameters cannot be dynamically changed on vulkan, leading to many permutations + lod_bias = std::floor(lod_bias * 2.f + 0.5f) * 0.5f; } } - - m_textures_dirty[i] = false; + else + { + min_lod = max_lod = lod_bias = 0.f; + min_filter.mipmap_mode = VK_SAMPLER_MIPMAP_MODE_NEAREST; + } } + + if (fs_sampler_handles[i] && + fs_sampler_handles[i]->matches(wrap_s, wrap_t, wrap_r, false, lod_bias, af_level, min_lod, max_lod, + min_filter.filter, mag_filter, min_filter.mipmap_mode, border_color, compare_enabled, depth_compare_mode)) + { + continue; + } + + fs_sampler_handles[i] = vk::get_resource_manager()->get_sampler( + *m_device, + fs_sampler_handles[i], + wrap_s, wrap_t, wrap_r, + false, + lod_bias, af_level, min_lod, max_lod, + min_filter.filter, mag_filter, min_filter.mipmap_mode, + border_color, compare_enabled, depth_compare_mode); } for (u32 textures_ref = current_vp_metadata.referenced_textures_mask, i = 0; textures_ref; textures_ref >>= 1, ++i) { if (!(textures_ref & 1)) + { continue; + } if (!vs_sampler_state[i]) + { vs_sampler_state[i] = std::make_unique(); + } auto sampler_state = static_cast(vs_sampler_state[i].get()); const auto& tex = rsx::method_registers.vertex_textures[i]; const auto previous_format_class = sampler_state->format_class; - if (m_samplers_dirty || m_vertex_textures_dirty[i] || !check_surface_cache_sampler(sampler_state, tex)) + if (!m_samplers_dirty && + !m_vertex_textures_dirty[i] && + check_surface_cache_sampler_valid(sampler_state, tex)) { - if (rsx::method_registers.vertex_textures[i].enabled()) - { - *sampler_state = m_texture_cache.upload_texture(*m_current_command_buffer, tex, m_rtts); - } - else - { - *sampler_state = {}; - } - - if (sampler_state->validate()) - { - if (sampler_state->is_cyclic_reference || sampler_state->external_subresource_desc.do_not_cache) - { - check_for_cyclic_refs |= true; - } - - if (!m_vertex_textures_dirty[i] && sampler_state->format_class != previous_format_class) - { - // Host details changed but RSX is not aware - m_graphics_state |= rsx::vertex_program_state_dirty; - } - - bool replace = !vs_sampler_handles[i]; - const VkBool32 unnormalized_coords = !!(tex.format() & CELL_GCM_TEXTURE_UN); - const auto min_lod = tex.min_lod(); - const auto max_lod = tex.max_lod(); - const auto wrap_s = vk::vk_wrap_mode(tex.wrap_s()); - const auto wrap_t = vk::vk_wrap_mode(tex.wrap_t()); - - // NOTE: In vulkan, the border color can bypass the sample swizzle stage. - // Check the device properties to determine whether to pre-swizzle the colors or not. - const auto border_color = is_border_clamped_texture(tex) - ? vk::border_color_t(get_border_color(tex)) - : vk::border_color_t(VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK); - - if (vs_sampler_handles[i]) - { - if (!vs_sampler_handles[i]->matches(wrap_s, wrap_t, VK_SAMPLER_ADDRESS_MODE_REPEAT, - unnormalized_coords, 0.f, 1.f, min_lod, max_lod, VK_FILTER_NEAREST, VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST, border_color)) - { - replace = true; - } - } - - if (replace) - { - vs_sampler_handles[i] = vk::get_resource_manager()->get_sampler( - *m_device, - vs_sampler_handles[i], - wrap_s, wrap_t, VK_SAMPLER_ADDRESS_MODE_REPEAT, - unnormalized_coords, - 0.f, 1.f, min_lod, max_lod, - VK_FILTER_NEAREST, VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST, border_color); - } - } - - m_vertex_textures_dirty[i] = false; + continue; } + + const bool is_sampler_dirty = m_vertex_textures_dirty[i]; + m_vertex_textures_dirty[i] = false; + + if (!rsx::method_registers.vertex_textures[i].enabled()) + { + *sampler_state = {}; + continue; + } + + *sampler_state = m_texture_cache.upload_texture(*m_current_command_buffer, tex, m_rtts); + if (!sampler_state->validate()) + { + continue; + } + + if (sampler_state->is_cyclic_reference || sampler_state->external_subresource_desc.do_not_cache) + { + check_for_cyclic_refs |= true; + } + + if (!is_sampler_dirty && sampler_state->format_class != previous_format_class) + { + // Host details changed but RSX is not aware + m_graphics_state |= rsx::vertex_program_state_dirty; + } + + if (!is_sampler_dirty && vs_sampler_handles[i]) + { + continue; + } + + const VkBool32 unnormalized_coords = !!(tex.format() & CELL_GCM_TEXTURE_UN); + const auto min_lod = tex.min_lod(); + const auto max_lod = tex.max_lod(); + const auto wrap_s = vk::vk_wrap_mode(tex.wrap_s()); + const auto wrap_t = vk::vk_wrap_mode(tex.wrap_t()); + + // NOTE: In vulkan, the border color can bypass the sample swizzle stage. + // Check the device properties to determine whether to pre-swizzle the colors or not. + const auto border_color = is_border_clamped_texture(tex) + ? vk::border_color_t(get_border_color(tex)) + : vk::border_color_t(VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK); + + if (vs_sampler_handles[i] && + vs_sampler_handles[i]->matches(wrap_s, wrap_t, VK_SAMPLER_ADDRESS_MODE_REPEAT, + unnormalized_coords, 0.f, 1.f, min_lod, max_lod, VK_FILTER_NEAREST, VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST, border_color)) + { + continue; + } + + vs_sampler_handles[i] = vk::get_resource_manager()->get_sampler( + *m_device, + vs_sampler_handles[i], + wrap_s, wrap_t, VK_SAMPLER_ADDRESS_MODE_REPEAT, + unnormalized_coords, + 0.f, 1.f, min_lod, max_lod, + VK_FILTER_NEAREST, VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST, border_color); } m_samplers_dirty.store(false); @@ -557,7 +574,9 @@ bool VKGSRender::bind_texture_env() for (u32 textures_ref = current_fp_metadata.referenced_textures_mask, i = 0; textures_ref; textures_ref >>= 1, ++i) { if (!(textures_ref & 1)) + { continue; + } vk::image_view* view = nullptr; auto sampler_state = static_cast(fs_sampler_state[i].get()); @@ -627,7 +646,9 @@ bool VKGSRender::bind_texture_env() for (u32 textures_ref = current_vp_metadata.referenced_textures_mask, i = 0; textures_ref; textures_ref >>= 1, ++i) { if (!(textures_ref & 1)) + { continue; + } if (!rsx::method_registers.vertex_textures[i].enabled()) { From f2a17e489806daf46bd943a43383fed9cfa870dc Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sun, 22 Feb 2026 18:13:23 +0300 Subject: [PATCH 036/175] rsx: Add format override functionality to format_ex --- rpcs3/Emu/RSX/Common/TextureUtils.h | 3 ++ rpcs3/Emu/RSX/Program/GLSLCommon.h | 42 +------------------------- rpcs3/Emu/RSX/color_utils.h | 46 +++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 41 deletions(-) diff --git a/rpcs3/Emu/RSX/Common/TextureUtils.h b/rpcs3/Emu/RSX/Common/TextureUtils.h index c32152fecd..551052f0ad 100644 --- a/rpcs3/Emu/RSX/Common/TextureUtils.h +++ b/rpcs3/Emu/RSX/Common/TextureUtils.h @@ -147,6 +147,9 @@ namespace rsx bool valid() const { return format_bits != 0; } u32 format() const { return format_bits & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN); } + bool hw_SNORM_possible() const { return (texel_remap_control & SEXT_MASK) == SEXT_MASK; } + bool hw_SRGB_possible() const { return (texel_remap_control & GAMMA_CTRL_MASK) == GAMMA_RGB_MASK; } + //private: u32 format_bits = 0; u32 features = 0; diff --git a/rpcs3/Emu/RSX/Program/GLSLCommon.h b/rpcs3/Emu/RSX/Program/GLSLCommon.h index ae22464f12..81b5043fc9 100644 --- a/rpcs3/Emu/RSX/Program/GLSLCommon.h +++ b/rpcs3/Emu/RSX/Program/GLSLCommon.h @@ -4,52 +4,12 @@ #include "GLSLTypes.h" #include "ShaderParam.h" +#include "../color_utils.h" struct RSXFragmentProgram; namespace rsx { - // TODO: Move this somewhere else once more compilers are supported other than glsl - enum texture_control_bits - { - GAMMA_A = 0, - GAMMA_R, - GAMMA_G, - GAMMA_B, - ALPHAKILL, - RENORMALIZE, - EXPAND_A, - EXPAND_R, - EXPAND_G, - EXPAND_B, - SEXT_A, - SEXT_R, - SEXT_G, - SEXT_B, - DEPTH_FLOAT, - DEPTH_COMPARE_OP, - DEPTH_COMPARE_1, - DEPTH_COMPARE_2, - FILTERED_MAG, - FILTERED_MIN, - UNNORMALIZED_COORDS, - CLAMP_TEXCOORDS_BIT, - WRAP_S, - WRAP_T, - WRAP_R, - FF_SIGNED_BIT, - FF_BIASED_RENORM_BIT, - FF_GAMMA_BIT, - FF_16BIT_CHANNELS_BIT, - - GAMMA_CTRL_MASK = (1 << GAMMA_R) | (1 << GAMMA_G) | (1 << GAMMA_B) | (1 << GAMMA_A), - EXPAND_MASK = (1 << EXPAND_R) | (1 << EXPAND_G) | (1 << EXPAND_B) | (1 << EXPAND_A), - EXPAND_OFFSET = EXPAND_A, - SEXT_MASK = (1 << SEXT_R) | (1 << SEXT_G) | (1 << SEXT_B) | (1 << SEXT_A), - SEXT_OFFSET = SEXT_A, - FORMAT_FEATURES_OFFSET = FF_SIGNED_BIT, - }; - enum ROP_control_bits : u32 { // Commands. These trigger explicit action. diff --git a/rpcs3/Emu/RSX/color_utils.h b/rpcs3/Emu/RSX/color_utils.h index 40335c07e3..25aa6eb7e9 100644 --- a/rpcs3/Emu/RSX/color_utils.h +++ b/rpcs3/Emu/RSX/color_utils.h @@ -7,6 +7,52 @@ namespace rsx { + enum texture_control_bits : u32 + { + GAMMA_A = 0, + GAMMA_R, + GAMMA_G, + GAMMA_B, + ALPHAKILL, + RENORMALIZE, + EXPAND_A, + EXPAND_R, + EXPAND_G, + EXPAND_B, + SEXT_A, + SEXT_R, + SEXT_G, + SEXT_B, + DEPTH_FLOAT, + DEPTH_COMPARE_OP, + DEPTH_COMPARE_1, + DEPTH_COMPARE_2, + FILTERED_MAG, + FILTERED_MIN, + UNNORMALIZED_COORDS, + CLAMP_TEXCOORDS_BIT, + WRAP_S, + WRAP_T, + WRAP_R, + FF_SIGNED_BIT, + FF_BIASED_RENORM_BIT, + FF_GAMMA_BIT, + FF_16BIT_CHANNELS_BIT, + + // Meta + GAMMA_CTRL_MASK = (1 << GAMMA_R) | (1 << GAMMA_G) | (1 << GAMMA_B) | (1 << GAMMA_A), + GAMMA_RGB_MASK = (1 << GAMMA_R) | (1 << GAMMA_G) | (1 << GAMMA_B), + GAMMA_OFFSET = GAMMA_A, + + EXPAND_MASK = (1 << EXPAND_R) | (1 << EXPAND_G) | (1 << EXPAND_B) | (1 << EXPAND_A), + EXPAND_OFFSET = EXPAND_A, + + SEXT_MASK = (1 << SEXT_R) | (1 << SEXT_G) | (1 << SEXT_B) | (1 << SEXT_A), + SEXT_OFFSET = SEXT_A, + + FORMAT_FEATURES_OFFSET = FF_SIGNED_BIT, + }; + struct texture_channel_remap_t { u32 encoded = 0xDEAD; From 4c20bdcc9fafe9d579a0d33184b9a041eb1d1dda Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sun, 22 Feb 2026 18:14:06 +0300 Subject: [PATCH 037/175] vk: Add support for derived image views --- rpcs3/Emu/RSX/VK/VKFramebuffer.cpp | 2 +- rpcs3/Emu/RSX/VK/VKRenderTargets.cpp | 6 ++--- rpcs3/Emu/RSX/VK/VKRenderTargets.h | 2 +- rpcs3/Emu/RSX/VK/vkutils/image.cpp | 35 ++++++++++++++++++++++++---- rpcs3/Emu/RSX/VK/vkutils/image.h | 19 ++++++++++++++- 5 files changed, 54 insertions(+), 10 deletions(-) diff --git a/rpcs3/Emu/RSX/VK/VKFramebuffer.cpp b/rpcs3/Emu/RSX/VK/VKFramebuffer.cpp index d1fc5a4764..eb5f11ce03 100644 --- a/rpcs3/Emu/RSX/VK/VKFramebuffer.cpp +++ b/rpcs3/Emu/RSX/VK/VKFramebuffer.cpp @@ -45,7 +45,7 @@ namespace vk for (const auto& e : image_list) { const VkImageSubresourceRange subres = { e->aspect(), 0, 1, 0, 1 }; - image_views.push_back(std::make_unique(dev, e, VK_IMAGE_VIEW_TYPE_2D, vk::default_component_map, subres)); + image_views.push_back(std::make_unique(dev, e, e->format(), VK_IMAGE_VIEW_TYPE_2D, vk::default_component_map, subres)); } auto value = std::make_unique(dev, renderpass, width, height, std::move(image_views)); diff --git a/rpcs3/Emu/RSX/VK/VKRenderTargets.cpp b/rpcs3/Emu/RSX/VK/VKRenderTargets.cpp index 9d66baa9d2..0bd7852c2d 100644 --- a/rpcs3/Emu/RSX/VK/VKRenderTargets.cpp +++ b/rpcs3/Emu/RSX/VK/VKRenderTargets.cpp @@ -911,15 +911,15 @@ namespace vk m_cyclic_ref_tracker.reset(); } - image_view* render_target::get_view(const rsx::texture_channel_remap_t& remap, VkImageAspectFlags mask) + image_view* render_target::get_view(VkFormat format, const rsx::texture_channel_remap_t& remap, VkImageAspectFlags mask) { if (remap.encoded == VK_REMAP_VIEW_MULTISAMPLED) { // Special remap flag, intercept here - return vk::viewable_image::get_view(remap.with_encoding(VK_REMAP_IDENTITY), mask); + return vk::viewable_image::get_view(format, remap.with_encoding(VK_REMAP_IDENTITY), mask); } - return vk::viewable_image::get_view(remap, mask); + return vk::viewable_image::get_view(format, remap, mask); } void render_target::memory_barrier(vk::command_buffer& cmd, rsx::surface_access access) diff --git a/rpcs3/Emu/RSX/VK/VKRenderTargets.h b/rpcs3/Emu/RSX/VK/VKRenderTargets.h index 3c3ef0acbd..287c9c2c52 100644 --- a/rpcs3/Emu/RSX/VK/VKRenderTargets.h +++ b/rpcs3/Emu/RSX/VK/VKRenderTargets.h @@ -110,7 +110,7 @@ namespace vk bool matches_dimensions(u16 _width, u16 _height) const; void reset_surface_counters(); - image_view* get_view(const rsx::texture_channel_remap_t& remap, + image_view* get_view(VkFormat format, const rsx::texture_channel_remap_t& remap, VkImageAspectFlags mask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT) override; // Memory management diff --git a/rpcs3/Emu/RSX/VK/vkutils/image.cpp b/rpcs3/Emu/RSX/VK/vkutils/image.cpp index 5e4c8ce022..ce431945ed 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/image.cpp +++ b/rpcs3/Emu/RSX/VK/vkutils/image.cpp @@ -333,10 +333,10 @@ namespace vk create_impl(); } - image_view::image_view(VkDevice dev, vk::image* resource, VkImageViewType view_type, const VkComponentMapping& mapping, const VkImageSubresourceRange& range) + image_view::image_view(VkDevice dev, vk::image* resource, VkFormat format, VkImageViewType view_type, const VkComponentMapping& mapping, const VkImageSubresourceRange& range) : m_device(dev), m_resource(resource) { - info.format = resource->info.format; + info.format = format == VK_FORMAT_UNDEFINED ? resource->format() : format; info.image = resource->value; info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; info.components = mapping; @@ -379,6 +379,33 @@ namespace vk vkDestroyImageView(m_device, value, nullptr); } + image_view* image_view::as(VkFormat format) + { + if (this->format() == format) + { + return this; + } + + auto self = this->m_root_view + ? this->m_root_view + : this; + + if (auto found = self->m_subviews.find(format); + found != self->m_subviews.end()) + { + return found->second.get(); + } + + // Create a derived + auto view = std::make_unique(m_device, info.image, info.viewType, format, info.components, info.subresourceRange); + view->m_resource = self->m_resource; + view->m_root_view = self; + + auto ret = view.get(); + self->m_subviews.emplace(format, std::move(view)); + return ret; + } + u32 image_view::encoded_component_map() const { #if (VK_DISABLE_COMPONENT_SWIZZLE) @@ -436,7 +463,7 @@ namespace vk return result; } - image_view* viewable_image::get_view(const rsx::texture_channel_remap_t& remap, VkImageAspectFlags mask) + image_view* viewable_image::get_view(VkFormat format, const rsx::texture_channel_remap_t& remap, VkImageAspectFlags mask) { u32 remap_encoding = remap.encoded; if (remap_encoding == VK_REMAP_IDENTITY) @@ -479,7 +506,7 @@ namespace vk const VkImageSubresourceRange range = { aspect() & mask, 0, info.mipLevels, 0, info.arrayLayers }; ensure(range.aspectMask); - auto view = std::make_unique(*g_render_device, this, VK_IMAGE_VIEW_TYPE_MAX_ENUM, real_mapping, range); + auto view = std::make_unique(*g_render_device, this, format, VK_IMAGE_VIEW_TYPE_MAX_ENUM, real_mapping, range); auto result = view.get(); views.emplace(storage_key, std::move(view)); return result; diff --git a/rpcs3/Emu/RSX/VK/vkutils/image.h b/rpcs3/Emu/RSX/VK/vkutils/image.h index fbe7abb5fd..e494f9e40d 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/image.h +++ b/rpcs3/Emu/RSX/VK/vkutils/image.h @@ -112,21 +112,29 @@ namespace vk image_view(VkDevice dev, VkImageViewCreateInfo create_info); image_view(VkDevice dev, vk::image* resource, + VkFormat format = VK_FORMAT_UNDEFINED, VkImageViewType view_type = VK_IMAGE_VIEW_TYPE_MAX_ENUM, const VkComponentMapping& mapping = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }, const VkImageSubresourceRange& range = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }); ~image_view(); + vk::image_view* as(VkFormat new_format); + u32 encoded_component_map() const; vk::image* image() const; image_view(const image_view&) = delete; image_view(image_view&&) = delete; + VkFormat format() const { return info.format; } + private: + std::unordered_map> m_subviews; + VkDevice m_device; vk::image* m_resource = nullptr; + vk::image_view* m_root_view = nullptr; void create_impl(); void set_debug_name(std::string_view name); @@ -141,9 +149,18 @@ namespace vk public: using image::image; - virtual image_view* get_view(const rsx::texture_channel_remap_t& remap, + virtual image_view* get_view( + VkFormat format, + const rsx::texture_channel_remap_t& remap, VkImageAspectFlags mask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT); + image_view* get_view( + const rsx::texture_channel_remap_t& remap, + VkImageAspectFlags mask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT) + { + return get_view(info.format, remap, mask); + } + void set_native_component_layout(VkComponentMapping new_layout); }; } From 3f174b2a97f672ffc3d097a185d81253298e44fe Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sun, 22 Feb 2026 18:14:27 +0300 Subject: [PATCH 038/175] vk: Implement SNORM and SRGB format overrides --- rpcs3/Emu/RSX/VK/VKDraw.cpp | 46 +++++++++++++++++++----- rpcs3/Emu/RSX/VK/VKFormats.cpp | 66 +++++++++++++++++++++++++++++++++- rpcs3/Emu/RSX/VK/VKFormats.h | 1 + 3 files changed, 104 insertions(+), 9 deletions(-) diff --git a/rpcs3/Emu/RSX/VK/VKDraw.cpp b/rpcs3/Emu/RSX/VK/VKDraw.cpp index 27a07faf43..6bec02ab7c 100644 --- a/rpcs3/Emu/RSX/VK/VKDraw.cpp +++ b/rpcs3/Emu/RSX/VK/VKDraw.cpp @@ -321,23 +321,53 @@ void VKGSRender::load_texture_env() continue; } - sampler_state->format_ex = tex.format_ex(); - if (sampler_state->is_cyclic_reference) { check_for_cyclic_refs |= true; } - if (!is_sampler_dirty && sampler_state->format_class != previous_format_class) + if (!is_sampler_dirty) { - // Host details changed but RSX is not aware - m_graphics_state |= rsx::fragment_program_state_dirty; + if (sampler_state->format_class != previous_format_class) + { + // Host details changed but RSX is not aware + m_graphics_state |= rsx::fragment_program_state_dirty; + } + + if (fs_sampler_handles[i]) + { + // Nothing to change, use cached sampler + continue; + } } - if (!is_sampler_dirty && fs_sampler_handles[i]) + sampler_state->format_ex = tex.format_ex(); + + if (sampler_state->format_ex.texel_remap_control && + sampler_state->image_handle && + sampler_state->upload_context == rsx::texture_upload_context::shader_read) [[ unlikely ]] { - // Nothing to change, use cached sampler - continue; + // Check if we need to override the view format + const auto vk_format = sampler_state->image_handle->format(); + VkFormat format_override = vk_format;; + rsx::flags32_t flags_to_erase = 0u; + + if (sampler_state->format_ex.hw_SNORM_possible()) + { + format_override = vk::get_compatible_snorm_format(vk_format); + flags_to_erase = rsx::texture_control_bits::SEXT_MASK; + } + else if (sampler_state->format_ex.hw_SRGB_possible()) + { + format_override = vk::get_compatible_srgb_format(vk_format); + flags_to_erase = rsx::texture_control_bits::GAMMA_CTRL_MASK; + } + + if (format_override != VK_FORMAT_UNDEFINED && format_override != vk_format) + { + sampler_state->image_handle = sampler_state->image_handle->as(format_override); + sampler_state->format_ex.texel_remap_control &= (~flags_to_erase); + } } VkFilter mag_filter; diff --git a/rpcs3/Emu/RSX/VK/VKFormats.cpp b/rpcs3/Emu/RSX/VK/VKFormats.cpp index f766a70e79..ed824de77d 100644 --- a/rpcs3/Emu/RSX/VK/VKFormats.cpp +++ b/rpcs3/Emu/RSX/VK/VKFormats.cpp @@ -244,16 +244,80 @@ namespace vk { switch (rgb_format) { + // 8-bit + case VK_FORMAT_R8_UNORM: + return VK_FORMAT_R8_SRGB; + case VK_FORMAT_R8G8_UNORM: + return VK_FORMAT_R8G8_SRGB; + case VK_FORMAT_R8G8B8A8_UNORM: + return VK_FORMAT_R8G8B8A8_SRGB; case VK_FORMAT_B8G8R8A8_UNORM: return VK_FORMAT_B8G8R8A8_SRGB; + // 16-bit + case VK_FORMAT_R16_UNORM: + case VK_FORMAT_R16G16_UNORM: + return VK_FORMAT_UNDEFINED; // No match + case VK_FORMAT_A1R5G5B5_UNORM_PACK16: + case VK_FORMAT_R4G4B4A4_UNORM_PACK16: + case VK_FORMAT_R5G6B5_UNORM_PACK16: + case VK_FORMAT_R5G5B5A1_UNORM_PACK16: + return VK_FORMAT_UNDEFINED; // No match + // DXT case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: return VK_FORMAT_BC1_RGBA_SRGB_BLOCK; case VK_FORMAT_BC2_UNORM_BLOCK: return VK_FORMAT_BC2_SRGB_BLOCK; case VK_FORMAT_BC3_UNORM_BLOCK: return VK_FORMAT_BC3_SRGB_BLOCK; + // Depth + case VK_FORMAT_D16_UNORM: + case VK_FORMAT_D32_SFLOAT: + case VK_FORMAT_D32_SFLOAT_S8_UINT: + case VK_FORMAT_D24_UNORM_S8_UINT: + return VK_FORMAT_UNDEFINED; // Unsupported default: - return rgb_format; + rsx_log.error("[SRGB_FMT] Unexpected VkFormat 0x%x", static_cast(rgb_format)); + return VK_FORMAT_UNDEFINED; + } + } + + VkFormat get_compatible_snorm_format(VkFormat rgb_format) + { + switch (rgb_format) + { + // 8-bit + case VK_FORMAT_R8_UNORM: + return VK_FORMAT_R8_SNORM; + case VK_FORMAT_R8G8_UNORM: + return VK_FORMAT_R8G8_SNORM; + case VK_FORMAT_R8G8B8A8_UNORM: + return VK_FORMAT_R8G8B8A8_SNORM; + case VK_FORMAT_B8G8R8A8_UNORM: + return VK_FORMAT_B8G8R8A8_SNORM; + // 16-bit + case VK_FORMAT_R16_UNORM: + return VK_FORMAT_R16_SNORM; + case VK_FORMAT_R16G16_UNORM: + return VK_FORMAT_R16G16_SNORM; + case VK_FORMAT_A1R5G5B5_UNORM_PACK16: + case VK_FORMAT_R4G4B4A4_UNORM_PACK16: + case VK_FORMAT_R5G6B5_UNORM_PACK16: + case VK_FORMAT_R5G5B5A1_UNORM_PACK16: + return VK_FORMAT_UNDEFINED; // No match + // DXT + case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: + case VK_FORMAT_BC2_UNORM_BLOCK: + case VK_FORMAT_BC3_UNORM_BLOCK: + return VK_FORMAT_UNDEFINED; // No match + // Depth + case VK_FORMAT_D16_UNORM: + case VK_FORMAT_D32_SFLOAT: + case VK_FORMAT_D32_SFLOAT_S8_UINT: + case VK_FORMAT_D24_UNORM_S8_UINT: + return VK_FORMAT_UNDEFINED; // Unsupported + default: + rsx_log.error("[SEXT_FMT] Unexpected VkFormat 0x%x", static_cast(rgb_format)); + return VK_FORMAT_UNDEFINED; } } diff --git a/rpcs3/Emu/RSX/VK/VKFormats.h b/rpcs3/Emu/RSX/VK/VKFormats.h index 85b52ca56b..fae25f92b7 100644 --- a/rpcs3/Emu/RSX/VK/VKFormats.h +++ b/rpcs3/Emu/RSX/VK/VKFormats.h @@ -19,6 +19,7 @@ namespace vk VkFormat get_compatible_depth_surface_format(const gpu_formats_support& support, rsx::surface_depth_format2 format); VkFormat get_compatible_sampler_format(const gpu_formats_support& support, u32 format); VkFormat get_compatible_srgb_format(VkFormat rgb_format); + VkFormat get_compatible_snorm_format(VkFormat rgb_format); u8 get_format_texel_width(VkFormat format); std::pair get_format_element_size(VkFormat format); std::pair get_format_convert_flags(VkFormat format); From 07abde4e8d413a05e444f42f6853aee66c2fda9a Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sun, 22 Feb 2026 20:05:33 +0300 Subject: [PATCH 039/175] vk: Allow cached view to have mutable format --- rpcs3/Emu/RSX/VK/vkutils/image.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpcs3/Emu/RSX/VK/vkutils/image.cpp b/rpcs3/Emu/RSX/VK/vkutils/image.cpp index ce431945ed..c6f71e73f0 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/image.cpp +++ b/rpcs3/Emu/RSX/VK/vkutils/image.cpp @@ -482,7 +482,7 @@ namespace vk if (found != views.end()) { ensure(found->second->info.subresourceRange.aspectMask & mask); - return found->second.get(); + return found->second->as(format); } VkComponentMapping real_mapping; From 0f1735d0df96e662c3e36df5d785e890c9caade1 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sun, 22 Feb 2026 20:26:26 +0300 Subject: [PATCH 040/175] gl: Add support for subviews --- rpcs3/Emu/RSX/GL/glutils/image.cpp | 28 ++++++++++++++++++++++++++++ rpcs3/Emu/RSX/GL/glutils/image.h | 7 ++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/rpcs3/Emu/RSX/GL/glutils/image.cpp b/rpcs3/Emu/RSX/GL/glutils/image.cpp index bb6439cc05..7dbd7fc254 100644 --- a/rpcs3/Emu/RSX/GL/glutils/image.cpp +++ b/rpcs3/Emu/RSX/GL/glutils/image.cpp @@ -318,6 +318,34 @@ namespace gl } } + texture_view* texture_view::as(GLenum format) + { + if (format == this->m_view_format) + { + return this; + } + + auto self = m_root_view ? m_root_view : this; + if (auto found = self->m_subviews.find(format); + found != self->m_subviews.end()) + { + return found->second.get(); + } + + GLenum swizzle_argb[4] = + { + component_swizzle[3], + component_swizzle[0], + component_swizzle[1], + component_swizzle[2], + }; + + auto view = std::make_unique(m_image_data, m_target, format, swizzle_argb, m_aspect_flags); + auto ret = view.get(); + self->m_subviews.emplace(format, std::move(view)); + return ret; + } + void texture_view::bind(gl::command_context& cmd, GLuint layer) const { cmd->bind_texture(layer, m_target, m_id); diff --git a/rpcs3/Emu/RSX/GL/glutils/image.h b/rpcs3/Emu/RSX/GL/glutils/image.h index 6617caa54c..4112d833c7 100644 --- a/rpcs3/Emu/RSX/GL/glutils/image.h +++ b/rpcs3/Emu/RSX/GL/glutils/image.h @@ -353,7 +353,10 @@ namespace gl GLenum m_aspect_flags = 0; texture* m_image_data = nullptr; - GLenum component_swizzle[4] {}; + GLenum component_swizzle[4]{}; + + std::unordered_map> m_subviews; + texture_view* m_root_view = nullptr; texture_view() = default; @@ -395,6 +398,8 @@ namespace gl virtual ~texture_view(); + texture_view* as(GLenum format); + GLuint id() const { return m_id; From e29cd4cc9311ec8c7f4eafe962f4ebef75ed7eba Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sun, 22 Feb 2026 20:57:16 +0300 Subject: [PATCH 041/175] gl: Implement SNORM and SRGB format overrides --- rpcs3/Emu/RSX/GL/GLDraw.cpp | 47 +++++++++++++++++++++++++++++----- rpcs3/Emu/RSX/GL/GLTexture.cpp | 38 +++++++++++++++++++++++++++ rpcs3/Emu/RSX/GL/GLTexture.h | 2 ++ 3 files changed, 81 insertions(+), 6 deletions(-) diff --git a/rpcs3/Emu/RSX/GL/GLDraw.cpp b/rpcs3/Emu/RSX/GL/GLDraw.cpp index b167ab24c2..c564adfa20 100644 --- a/rpcs3/Emu/RSX/GL/GLDraw.cpp +++ b/rpcs3/Emu/RSX/GL/GLDraw.cpp @@ -334,17 +334,52 @@ void GLGSRender::load_texture_env() continue; } + if (!is_sampler_dirty) + { + if (sampler_state->format_class != previous_format_class) + { + // Host details changed but RSX is not aware + m_graphics_state |= rsx::fragment_program_state_dirty; + } + + if (m_fs_sampler_states[i]) + { + // Nothing to change, use cached sampler + continue; + } + } + sampler_state->format_ex = tex.format_ex(); - if (is_sampler_dirty) + if (sampler_state->format_ex.texel_remap_control && + sampler_state->image_handle && + sampler_state->upload_context == rsx::texture_upload_context::shader_read) [[ unlikely ]] { - m_fs_sampler_states[i].apply(tex, fs_sampler_state[i].get()); - } - else if (sampler_state->format_class != previous_format_class) - { - m_graphics_state |= rsx::fragment_program_state_dirty; + // Check if we need to override the view format + const auto gl_format = sampler_state->image_handle->view_format(); + GLenum format_override = gl_format; + rsx::flags32_t flags_to_erase = 0u; + + if (sampler_state->format_ex.hw_SNORM_possible()) + { + format_override = gl::get_compatible_snorm_format(gl_format); + flags_to_erase = rsx::texture_control_bits::SEXT_MASK; + } + else if (sampler_state->format_ex.hw_SRGB_possible()) + { + format_override = gl::get_compatible_srgb_format(gl_format); + flags_to_erase = rsx::texture_control_bits::GAMMA_CTRL_MASK; + } + + if (format_override != GL_NONE && format_override != gl_format) + { + sampler_state->image_handle = sampler_state->image_handle->as(format_override); + sampler_state->format_ex.texel_remap_control &= (~flags_to_erase); + } } + m_fs_sampler_states[i].apply(tex, fs_sampler_state[i].get()); + const auto texture_format = sampler_state->format_ex.format(); // Depth format redirected to BGRA8 resample stage. Do not filter to avoid bits leaking. // If accurate graphics are desired, force a bitcast to COLOR as a workaround. diff --git a/rpcs3/Emu/RSX/GL/GLTexture.cpp b/rpcs3/Emu/RSX/GL/GLTexture.cpp index 9a439177f4..181e5058c8 100644 --- a/rpcs3/Emu/RSX/GL/GLTexture.cpp +++ b/rpcs3/Emu/RSX/GL/GLTexture.cpp @@ -266,6 +266,44 @@ namespace gl fmt::throw_exception("Unknown format 0x%x", texture_format); } + GLenum get_compatible_snorm_format(GLenum base_format) + { + switch (base_format) + { + case GL_R8: + return GL_R8_SNORM; + case GL_RG8: + return GL_RG8_SNORM; + case GL_RGBA8: + return GL_RGBA8_SNORM; + case GL_R16: + return GL_R16_SNORM; + case GL_RG16: + return GL_RG16_SNORM; + case GL_RGBA16: + return GL_RGBA16_SNORM; + default: + return GL_NONE; + } + } + + GLenum get_compatible_srgb_format(GLenum base_format) + { + switch (base_format) + { + case GL_RGBA8: + return GL_SRGB8_ALPHA8_EXT; + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT; + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT; + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT; + default: + return GL_NONE; + } + } + cs_shuffle_base* get_trivial_transform_job(const pixel_buffer_layout& pack_info) { if (!pack_info.swap_bytes) diff --git a/rpcs3/Emu/RSX/GL/GLTexture.h b/rpcs3/Emu/RSX/GL/GLTexture.h index dc6d90098a..10c26dc536 100644 --- a/rpcs3/Emu/RSX/GL/GLTexture.h +++ b/rpcs3/Emu/RSX/GL/GLTexture.h @@ -62,6 +62,8 @@ namespace gl std::tuple get_format_type(u32 texture_format); pixel_buffer_layout get_format_type(texture::internal_format format); std::array get_swizzle_remap(u32 texture_format); + GLenum get_compatible_snorm_format(GLenum base_format); + GLenum get_compatible_srgb_format(GLenum base_format); viewable_image* create_texture(u32 gcm_format, u16 width, u16 height, u16 depth, u16 mipmaps, rsx::texture_dimension_extended type); From 794abe20252eb111aea34a79042777e1dfa5b13a Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sun, 22 Feb 2026 21:14:15 +0300 Subject: [PATCH 042/175] vk: Clean up image_view interfaces --- rpcs3/Emu/RSX/VK/VKRenderTargets.cpp | 6 +++--- rpcs3/Emu/RSX/VK/VKRenderTargets.h | 2 +- rpcs3/Emu/RSX/VK/vkutils/image.cpp | 6 +++--- rpcs3/Emu/RSX/VK/vkutils/image.h | 8 -------- 4 files changed, 7 insertions(+), 15 deletions(-) diff --git a/rpcs3/Emu/RSX/VK/VKRenderTargets.cpp b/rpcs3/Emu/RSX/VK/VKRenderTargets.cpp index 0bd7852c2d..9d66baa9d2 100644 --- a/rpcs3/Emu/RSX/VK/VKRenderTargets.cpp +++ b/rpcs3/Emu/RSX/VK/VKRenderTargets.cpp @@ -911,15 +911,15 @@ namespace vk m_cyclic_ref_tracker.reset(); } - image_view* render_target::get_view(VkFormat format, const rsx::texture_channel_remap_t& remap, VkImageAspectFlags mask) + image_view* render_target::get_view(const rsx::texture_channel_remap_t& remap, VkImageAspectFlags mask) { if (remap.encoded == VK_REMAP_VIEW_MULTISAMPLED) { // Special remap flag, intercept here - return vk::viewable_image::get_view(format, remap.with_encoding(VK_REMAP_IDENTITY), mask); + return vk::viewable_image::get_view(remap.with_encoding(VK_REMAP_IDENTITY), mask); } - return vk::viewable_image::get_view(format, remap, mask); + return vk::viewable_image::get_view(remap, mask); } void render_target::memory_barrier(vk::command_buffer& cmd, rsx::surface_access access) diff --git a/rpcs3/Emu/RSX/VK/VKRenderTargets.h b/rpcs3/Emu/RSX/VK/VKRenderTargets.h index 287c9c2c52..3c3ef0acbd 100644 --- a/rpcs3/Emu/RSX/VK/VKRenderTargets.h +++ b/rpcs3/Emu/RSX/VK/VKRenderTargets.h @@ -110,7 +110,7 @@ namespace vk bool matches_dimensions(u16 _width, u16 _height) const; void reset_surface_counters(); - image_view* get_view(VkFormat format, const rsx::texture_channel_remap_t& remap, + image_view* get_view(const rsx::texture_channel_remap_t& remap, VkImageAspectFlags mask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT) override; // Memory management diff --git a/rpcs3/Emu/RSX/VK/vkutils/image.cpp b/rpcs3/Emu/RSX/VK/vkutils/image.cpp index c6f71e73f0..c6238ac6e8 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/image.cpp +++ b/rpcs3/Emu/RSX/VK/vkutils/image.cpp @@ -463,7 +463,7 @@ namespace vk return result; } - image_view* viewable_image::get_view(VkFormat format, const rsx::texture_channel_remap_t& remap, VkImageAspectFlags mask) + image_view* viewable_image::get_view(const rsx::texture_channel_remap_t& remap, VkImageAspectFlags mask) { u32 remap_encoding = remap.encoded; if (remap_encoding == VK_REMAP_IDENTITY) @@ -482,7 +482,7 @@ namespace vk if (found != views.end()) { ensure(found->second->info.subresourceRange.aspectMask & mask); - return found->second->as(format); + return found->second.get(); } VkComponentMapping real_mapping; @@ -506,7 +506,7 @@ namespace vk const VkImageSubresourceRange range = { aspect() & mask, 0, info.mipLevels, 0, info.arrayLayers }; ensure(range.aspectMask); - auto view = std::make_unique(*g_render_device, this, format, VK_IMAGE_VIEW_TYPE_MAX_ENUM, real_mapping, range); + auto view = std::make_unique(*g_render_device, this, format(), VK_IMAGE_VIEW_TYPE_MAX_ENUM, real_mapping, range); auto result = view.get(); views.emplace(storage_key, std::move(view)); return result; diff --git a/rpcs3/Emu/RSX/VK/vkutils/image.h b/rpcs3/Emu/RSX/VK/vkutils/image.h index e494f9e40d..abf708559d 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/image.h +++ b/rpcs3/Emu/RSX/VK/vkutils/image.h @@ -150,17 +150,9 @@ namespace vk using image::image; virtual image_view* get_view( - VkFormat format, const rsx::texture_channel_remap_t& remap, VkImageAspectFlags mask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT); - image_view* get_view( - const rsx::texture_channel_remap_t& remap, - VkImageAspectFlags mask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT) - { - return get_view(info.format, remap, mask); - } - void set_native_component_layout(VkComponentMapping new_layout); }; } From f27315c821cbdf5762ca355bd4c8db76cbe1a2dd Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sun, 22 Feb 2026 21:36:54 +0300 Subject: [PATCH 043/175] vk: Support explicit mutable format list - Actually important for performance reasons --- rpcs3/Emu/RSX/VK/vkutils/ex.h | 16 ++++++++++++++++ rpcs3/Emu/RSX/VK/vkutils/image.cpp | 14 ++++++++++++-- rpcs3/Emu/RSX/VK/vkutils/image.h | 5 +++-- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/rpcs3/Emu/RSX/VK/vkutils/ex.h b/rpcs3/Emu/RSX/VK/vkutils/ex.h index 361ae1d32d..1a80ffbbf5 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/ex.h +++ b/rpcs3/Emu/RSX/VK/vkutils/ex.h @@ -39,6 +39,22 @@ namespace vk VkDescriptorBufferInfoEx() = default; VkDescriptorBufferInfoEx(const vk::buffer& buffer, u64 offset, u64 range); }; + + struct VkFormatEx + { + VkFormat baseFormat = VK_FORMAT_UNDEFINED; + VkFormat* pViewFormats = nullptr; + u32 viewFormatCount = 0u; + + VkFormatEx() = default; + + VkFormatEx(VkFormat format) + : baseFormat(format) + {} + + operator VkFormat() const { return baseFormat; } + bool is_mutable() const { return viewFormatCount != 0; } + }; } // Re-export diff --git a/rpcs3/Emu/RSX/VK/vkutils/image.cpp b/rpcs3/Emu/RSX/VK/vkutils/image.cpp index c6238ac6e8..b58a95c29b 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/image.cpp +++ b/rpcs3/Emu/RSX/VK/vkutils/image.cpp @@ -47,7 +47,7 @@ namespace vk const memory_type_info& memory_type, u32 access_flags, VkImageType image_type, - VkFormat format, + const VkFormatEx& format, u32 width, u32 height, u32 depth, u32 mipmaps, u32 layers, VkSampleCountFlagBits samples, @@ -59,7 +59,6 @@ namespace vk rsx::format_class format_class) : m_device(dev) { - info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; info.imageType = image_type; info.format = format; info.extent = { width, height, depth }; @@ -84,6 +83,16 @@ namespace vk info.pQueueFamilyIndices = concurrency_queue_families.data(); } + VkImageFormatListCreateInfo format_list = { .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO }; + if (format.is_mutable()) + { + info.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT; + + format_list.pViewFormats = format.pViewFormats; + format_list.viewFormatCount = format.viewFormatCount; + info.pNext = &format_list; + } + create_impl(dev, access_flags, memory_type, allocation_pool); m_storage_aspect = get_aspect_flags(format); @@ -100,6 +109,7 @@ namespace vk } m_format_class = format_class; + info.pNext = nullptr; } // TODO: Ctor that uses a provided memory heap diff --git a/rpcs3/Emu/RSX/VK/vkutils/image.h b/rpcs3/Emu/RSX/VK/vkutils/image.h index abf708559d..a301db6a6d 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/image.h +++ b/rpcs3/Emu/RSX/VK/vkutils/image.h @@ -5,6 +5,7 @@ #include "commands.h" #include "device.h" +#include "ex.h" #include "memory.h" #include "unique_resource.h" @@ -46,14 +47,14 @@ namespace vk VkComponentMapping native_component_map = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; VkImageLayout current_layout = VK_IMAGE_LAYOUT_UNDEFINED; u32 current_queue_family = VK_QUEUE_FAMILY_IGNORED; - VkImageCreateInfo info = {}; + VkImageCreateInfo info = { .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO }; std::shared_ptr memory; image(const vk::render_device& dev, const memory_type_info& memory_type, u32 access_flags, VkImageType image_type, - VkFormat format, + const VkFormatEx& format, u32 width, u32 height, u32 depth, u32 mipmaps, u32 layers, VkSampleCountFlagBits samples, From 34380b1ee7446b7b270f240d59ddfd6614e3294d Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sun, 22 Feb 2026 22:01:31 +0300 Subject: [PATCH 044/175] vk: Make use of mutable formats for dynamic views --- rpcs3/Emu/RSX/VK/VKFormats.cpp | 33 ------------------------- rpcs3/Emu/RSX/VK/VKTextureCache.cpp | 37 ++++++++++++++++++++++++++++- rpcs3/Emu/RSX/VK/VKTextureCache.h | 3 ++- 3 files changed, 38 insertions(+), 35 deletions(-) diff --git a/rpcs3/Emu/RSX/VK/VKFormats.cpp b/rpcs3/Emu/RSX/VK/VKFormats.cpp index ed824de77d..0110460a51 100644 --- a/rpcs3/Emu/RSX/VK/VKFormats.cpp +++ b/rpcs3/Emu/RSX/VK/VKFormats.cpp @@ -253,15 +253,6 @@ namespace vk return VK_FORMAT_R8G8B8A8_SRGB; case VK_FORMAT_B8G8R8A8_UNORM: return VK_FORMAT_B8G8R8A8_SRGB; - // 16-bit - case VK_FORMAT_R16_UNORM: - case VK_FORMAT_R16G16_UNORM: - return VK_FORMAT_UNDEFINED; // No match - case VK_FORMAT_A1R5G5B5_UNORM_PACK16: - case VK_FORMAT_R4G4B4A4_UNORM_PACK16: - case VK_FORMAT_R5G6B5_UNORM_PACK16: - case VK_FORMAT_R5G5B5A1_UNORM_PACK16: - return VK_FORMAT_UNDEFINED; // No match // DXT case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: return VK_FORMAT_BC1_RGBA_SRGB_BLOCK; @@ -269,14 +260,7 @@ namespace vk return VK_FORMAT_BC2_SRGB_BLOCK; case VK_FORMAT_BC3_UNORM_BLOCK: return VK_FORMAT_BC3_SRGB_BLOCK; - // Depth - case VK_FORMAT_D16_UNORM: - case VK_FORMAT_D32_SFLOAT: - case VK_FORMAT_D32_SFLOAT_S8_UINT: - case VK_FORMAT_D24_UNORM_S8_UINT: - return VK_FORMAT_UNDEFINED; // Unsupported default: - rsx_log.error("[SRGB_FMT] Unexpected VkFormat 0x%x", static_cast(rgb_format)); return VK_FORMAT_UNDEFINED; } } @@ -299,24 +283,7 @@ namespace vk return VK_FORMAT_R16_SNORM; case VK_FORMAT_R16G16_UNORM: return VK_FORMAT_R16G16_SNORM; - case VK_FORMAT_A1R5G5B5_UNORM_PACK16: - case VK_FORMAT_R4G4B4A4_UNORM_PACK16: - case VK_FORMAT_R5G6B5_UNORM_PACK16: - case VK_FORMAT_R5G5B5A1_UNORM_PACK16: - return VK_FORMAT_UNDEFINED; // No match - // DXT - case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: - case VK_FORMAT_BC2_UNORM_BLOCK: - case VK_FORMAT_BC3_UNORM_BLOCK: - return VK_FORMAT_UNDEFINED; // No match - // Depth - case VK_FORMAT_D16_UNORM: - case VK_FORMAT_D32_SFLOAT: - case VK_FORMAT_D32_SFLOAT_S8_UINT: - case VK_FORMAT_D24_UNORM_S8_UINT: - return VK_FORMAT_UNDEFINED; // Unsupported default: - rsx_log.error("[SEXT_FMT] Unexpected VkFormat 0x%x", static_cast(rgb_format)); return VK_FORMAT_UNDEFINED; } } diff --git a/rpcs3/Emu/RSX/VK/VKTextureCache.cpp b/rpcs3/Emu/RSX/VK/VKTextureCache.cpp index d1b0e536ef..2427cd8da3 100644 --- a/rpcs3/Emu/RSX/VK/VKTextureCache.cpp +++ b/rpcs3/Emu/RSX/VK/VKTextureCache.cpp @@ -1025,6 +1025,29 @@ namespace vk const VkFormat vk_format = get_compatible_sampler_format(m_formats_support, gcm_format); VkImageCreateFlags create_flags = is_cubemap ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0; VkSharingMode sharing_mode = (flags & texture_create_flags::shareable) ? VK_SHARING_MODE_CONCURRENT : VK_SHARING_MODE_EXCLUSIVE; + rsx::simple_array mutable_format_list; + + if (flags & texture_create_flags::mutable_format) + { + const VkFormat snorm_fmt = get_compatible_snorm_format(vk_format); + const VkFormat srgb_fmt = get_compatible_srgb_format(vk_format); + + if (snorm_fmt != VK_FORMAT_UNDEFINED) + { + mutable_format_list.push_back(snorm_fmt); + } + + if (srgb_fmt != VK_FORMAT_UNDEFINED) + { + mutable_format_list.push_back(srgb_fmt); + } + + if (!mutable_format_list.empty()) + { + create_flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT; + mutable_format_list.push_back(vk_format); + } + } if (auto found = find_cached_image(vk_format, width, height, depth, mipmaps, image_type, create_flags, usage_flags, sharing_mode)) { @@ -1037,9 +1060,16 @@ namespace vk create_flags |= VK_IMAGE_CREATE_SHAREABLE_RPCS3; } + VkFormatEx create_format = vk_format; + if (!mutable_format_list.empty()) + { + create_format.pViewFormats = mutable_format_list.data(); + create_format.viewFormatCount = mutable_format_list.size(); + } + image = new vk::viewable_image(*m_device, m_memory_types.device_local, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, - image_type, vk_format, + image_type, create_format, width, height, depth, mipmaps, layer, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_TILING_OPTIMAL, usage_flags, create_flags, VMM_ALLOCATION_POOL_TEXTURE_CACHE, rsx::classify_format(gcm_format)); @@ -1123,6 +1153,11 @@ namespace vk const bool upload_async = rsx::get_current_renderer()->get_backend_config().supports_asynchronous_compute; rsx::flags32_t create_flags = 0; + if (context == rsx::texture_upload_context::shader_read) + { + create_flags |= texture_create_flags::mutable_format; + } + if (upload_async && ensure(g_fxo->try_get())->is_host_mode()) { create_flags |= texture_create_flags::do_not_reuse; diff --git a/rpcs3/Emu/RSX/VK/VKTextureCache.h b/rpcs3/Emu/RSX/VK/VKTextureCache.h index 786eb51270..85687c8c69 100644 --- a/rpcs3/Emu/RSX/VK/VKTextureCache.h +++ b/rpcs3/Emu/RSX/VK/VKTextureCache.h @@ -418,7 +418,8 @@ namespace vk { initialize_image_contents = 1, do_not_reuse = 2, - shareable = 4 + shareable = 4, + mutable_format = 8 }; void on_section_destroyed(cached_texture_section& tex) override; From bf5056145e68d0c7789fc152365f34fef121439e Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sun, 22 Feb 2026 22:30:46 +0300 Subject: [PATCH 045/175] rsx: Track BX2 reads per-TIU to allow enabling/disabling hw remapping --- rpcs3/Emu/RSX/Program/ProgramStateCache.cpp | 2 +- rpcs3/Emu/RSX/Program/ProgramStateCache.h | 2 +- rpcs3/Emu/RSX/RSXThread.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/rpcs3/Emu/RSX/Program/ProgramStateCache.cpp b/rpcs3/Emu/RSX/Program/ProgramStateCache.cpp index 15546afd7e..4420e51555 100644 --- a/rpcs3/Emu/RSX/Program/ProgramStateCache.cpp +++ b/rpcs3/Emu/RSX/Program/ProgramStateCache.cpp @@ -651,7 +651,7 @@ fragment_program_utils::fragment_program_metadata fragment_program_utils::analys case RSX_FP_OPCODE_TXB: case RSX_FP_OPCODE_TXL: result.referenced_textures_mask |= (1 << d0.tex_num); - result.has_tex_bx2_conv |= !!d0.exp_tex; + result.bx2_texture_reads_mask |= ((d0.exp_tex ? 1u : 0u) << d0.tex_num); break; case RSX_FP_OPCODE_PK4: case RSX_FP_OPCODE_UP4: diff --git a/rpcs3/Emu/RSX/Program/ProgramStateCache.h b/rpcs3/Emu/RSX/Program/ProgramStateCache.h index ce5be4a425..76e168d20a 100644 --- a/rpcs3/Emu/RSX/Program/ProgramStateCache.h +++ b/rpcs3/Emu/RSX/Program/ProgramStateCache.h @@ -56,10 +56,10 @@ namespace program_hash_util u32 program_ucode_length; u32 program_constants_buffer_length; u16 referenced_textures_mask; + u16 bx2_texture_reads_mask; bool has_pack_instructions; bool has_branch_instructions; - bool has_tex_bx2_conv; bool is_nop_shader; // Does this affect Z-pass testing??? }; diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 5bfc60ee2a..65958e189f 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -2326,7 +2326,7 @@ namespace rsx texture_control |= format_ex.texel_remap_control; texture_control |= format_ex.features << texture_control_bits::FORMAT_FEATURES_OFFSET; - if (current_fp_metadata.has_tex_bx2_conv) + if (current_fp_metadata.bx2_texture_reads_mask) { const u32 remap_hi = tex.decoded_remap().shuffle_mask_bits(0xFu); current_fragment_program.texture_params[i].remap &= ~(0xFu << 16u); From 0fb8091a31d500df8e3cb6ff6e09a2efc85d49be Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sun, 22 Feb 2026 22:31:18 +0300 Subject: [PATCH 046/175] rsx: Disable HW remapper if BX2 is active or the user requests not to use it --- rpcs3/Emu/RSX/GL/GLDraw.cpp | 4 +++- rpcs3/Emu/RSX/VK/VKDraw.cpp | 4 +++- rpcs3/Emu/RSX/VK/VKTextureCache.cpp | 3 ++- rpcs3/Emu/system_config.h | 1 + 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/rpcs3/Emu/RSX/GL/GLDraw.cpp b/rpcs3/Emu/RSX/GL/GLDraw.cpp index c564adfa20..e7d1338868 100644 --- a/rpcs3/Emu/RSX/GL/GLDraw.cpp +++ b/rpcs3/Emu/RSX/GL/GLDraw.cpp @@ -353,7 +353,9 @@ void GLGSRender::load_texture_env() if (sampler_state->format_ex.texel_remap_control && sampler_state->image_handle && - sampler_state->upload_context == rsx::texture_upload_context::shader_read) [[ unlikely ]] + sampler_state->upload_context == rsx::texture_upload_context::shader_read && + (current_fp_metadata.bx2_texture_reads_mask & (1u << i)) == 0 && + g_cfg.video.use_hardware_texel_remapping) [[ unlikely ]] { // Check if we need to override the view format const auto gl_format = sampler_state->image_handle->view_format(); diff --git a/rpcs3/Emu/RSX/VK/VKDraw.cpp b/rpcs3/Emu/RSX/VK/VKDraw.cpp index 6bec02ab7c..8f14d7e8c7 100644 --- a/rpcs3/Emu/RSX/VK/VKDraw.cpp +++ b/rpcs3/Emu/RSX/VK/VKDraw.cpp @@ -345,7 +345,9 @@ void VKGSRender::load_texture_env() if (sampler_state->format_ex.texel_remap_control && sampler_state->image_handle && - sampler_state->upload_context == rsx::texture_upload_context::shader_read) [[ unlikely ]] + sampler_state->upload_context == rsx::texture_upload_context::shader_read && + (current_fp_metadata.bx2_texture_reads_mask & (1u << i)) == 0 && + g_cfg.video.use_hardware_texel_remapping) [[ unlikely ]] { // Check if we need to override the view format const auto vk_format = sampler_state->image_handle->format(); diff --git a/rpcs3/Emu/RSX/VK/VKTextureCache.cpp b/rpcs3/Emu/RSX/VK/VKTextureCache.cpp index 2427cd8da3..0c3df5cd9c 100644 --- a/rpcs3/Emu/RSX/VK/VKTextureCache.cpp +++ b/rpcs3/Emu/RSX/VK/VKTextureCache.cpp @@ -1153,7 +1153,8 @@ namespace vk const bool upload_async = rsx::get_current_renderer()->get_backend_config().supports_asynchronous_compute; rsx::flags32_t create_flags = 0; - if (context == rsx::texture_upload_context::shader_read) + if (context == rsx::texture_upload_context::shader_read && + g_cfg.video.use_hardware_texel_remapping) { create_flags |= texture_create_flags::mutable_format; } diff --git a/rpcs3/Emu/system_config.h b/rpcs3/Emu/system_config.h index aaa889ce1f..c9e763b5af 100644 --- a/rpcs3/Emu/system_config.h +++ b/rpcs3/Emu/system_config.h @@ -176,6 +176,7 @@ struct cfg_root : cfg::node cfg::_bool disable_async_host_memory_manager{ this, "Disable Asynchronous Memory Manager", false, true }; cfg::_enum output_scaling{ this, "Output Scaling Mode", output_scaling_mode::bilinear, true }; cfg::_bool record_with_overlays{ this, "Record With Overlays", true, true }; + cfg::_bool use_hardware_texel_remapping{ this, "Use Hardware Texel Remapping", true, false }; struct node_vk : cfg::node { From cee868560a8a8cb50da8c851c8e64be9e6078014 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sun, 22 Feb 2026 22:56:42 +0300 Subject: [PATCH 047/175] rsx: Add configuration toggle to debug tab --- rpcs3/Emu/RSX/GL/GLDraw.cpp | 2 +- rpcs3/Emu/RSX/VK/VKDraw.cpp | 2 +- rpcs3/Emu/RSX/VK/VKTextureCache.cpp | 2 +- rpcs3/Emu/system_config.h | 2 +- rpcs3/rpcs3qt/emu_settings_type.h | 2 ++ rpcs3/rpcs3qt/settings_dialog.cpp | 3 +++ rpcs3/rpcs3qt/settings_dialog.ui | 7 +++++++ rpcs3/rpcs3qt/tooltips.h | 1 + 8 files changed, 17 insertions(+), 4 deletions(-) diff --git a/rpcs3/Emu/RSX/GL/GLDraw.cpp b/rpcs3/Emu/RSX/GL/GLDraw.cpp index e7d1338868..bdf5a53d01 100644 --- a/rpcs3/Emu/RSX/GL/GLDraw.cpp +++ b/rpcs3/Emu/RSX/GL/GLDraw.cpp @@ -355,7 +355,7 @@ void GLGSRender::load_texture_env() sampler_state->image_handle && sampler_state->upload_context == rsx::texture_upload_context::shader_read && (current_fp_metadata.bx2_texture_reads_mask & (1u << i)) == 0 && - g_cfg.video.use_hardware_texel_remapping) [[ unlikely ]] + !g_cfg.video.disable_hardware_texel_remapping) [[ unlikely ]] { // Check if we need to override the view format const auto gl_format = sampler_state->image_handle->view_format(); diff --git a/rpcs3/Emu/RSX/VK/VKDraw.cpp b/rpcs3/Emu/RSX/VK/VKDraw.cpp index 8f14d7e8c7..344bde8b64 100644 --- a/rpcs3/Emu/RSX/VK/VKDraw.cpp +++ b/rpcs3/Emu/RSX/VK/VKDraw.cpp @@ -347,7 +347,7 @@ void VKGSRender::load_texture_env() sampler_state->image_handle && sampler_state->upload_context == rsx::texture_upload_context::shader_read && (current_fp_metadata.bx2_texture_reads_mask & (1u << i)) == 0 && - g_cfg.video.use_hardware_texel_remapping) [[ unlikely ]] + !g_cfg.video.disable_hardware_texel_remapping) [[ unlikely ]] { // Check if we need to override the view format const auto vk_format = sampler_state->image_handle->format(); diff --git a/rpcs3/Emu/RSX/VK/VKTextureCache.cpp b/rpcs3/Emu/RSX/VK/VKTextureCache.cpp index 0c3df5cd9c..c9d9599b9e 100644 --- a/rpcs3/Emu/RSX/VK/VKTextureCache.cpp +++ b/rpcs3/Emu/RSX/VK/VKTextureCache.cpp @@ -1154,7 +1154,7 @@ namespace vk rsx::flags32_t create_flags = 0; if (context == rsx::texture_upload_context::shader_read && - g_cfg.video.use_hardware_texel_remapping) + !g_cfg.video.disable_hardware_texel_remapping) { create_flags |= texture_create_flags::mutable_format; } diff --git a/rpcs3/Emu/system_config.h b/rpcs3/Emu/system_config.h index c9e763b5af..8ccf91db0e 100644 --- a/rpcs3/Emu/system_config.h +++ b/rpcs3/Emu/system_config.h @@ -176,7 +176,7 @@ struct cfg_root : cfg::node cfg::_bool disable_async_host_memory_manager{ this, "Disable Asynchronous Memory Manager", false, true }; cfg::_enum output_scaling{ this, "Output Scaling Mode", output_scaling_mode::bilinear, true }; cfg::_bool record_with_overlays{ this, "Record With Overlays", true, true }; - cfg::_bool use_hardware_texel_remapping{ this, "Use Hardware Texel Remapping", true, false }; + cfg::_bool disable_hardware_texel_remapping{ this, "Disable Hardware ColorSpace Remapping", false, true }; struct node_vk : cfg::node { diff --git a/rpcs3/rpcs3qt/emu_settings_type.h b/rpcs3/rpcs3qt/emu_settings_type.h index cc8ab57b96..6a5b6841b1 100644 --- a/rpcs3/rpcs3qt/emu_settings_type.h +++ b/rpcs3/rpcs3qt/emu_settings_type.h @@ -108,6 +108,7 @@ enum class emu_settings_type DisableAsyncHostMM, UseReBAR, RecordWithOverlays, + DisableHWTexelRemapping, // Performance Overlay PerfOverlayEnabled, @@ -312,6 +313,7 @@ inline static const std::map settings_location { emu_settings_type::ForceHwMSAAResolve, { "Video", "Force Hardware MSAA Resolve"}}, { emu_settings_type::DisableAsyncHostMM, { "Video", "Disable Asynchronous Memory Manager"}}, { emu_settings_type::RecordWithOverlays, { "Video", "Record With Overlays"}}, + { emu_settings_type::DisableHWTexelRemapping, { "Video", "Disable Hardware ColorSpace Remapping"}}, // Vulkan { emu_settings_type::VulkanAsyncTextureUploads, { "Video", "Vulkan", "Asynchronous Texture Streaming 2"}}, diff --git a/rpcs3/rpcs3qt/settings_dialog.cpp b/rpcs3/rpcs3qt/settings_dialog.cpp index 81e85546e9..0c0fb63efd 100644 --- a/rpcs3/rpcs3qt/settings_dialog.cpp +++ b/rpcs3/rpcs3qt/settings_dialog.cpp @@ -1555,6 +1555,9 @@ settings_dialog::settings_dialog(std::shared_ptr gui_settings, std m_emu_settings->EnhanceCheckBox(ui->enableSpuEventsBusyLoop, emu_settings_type::EnabledSPUEventsBusyLoop); SubscribeTooltip(ui->enableSpuEventsBusyLoop, tooltips.settings.enable_spu_events_busy_loop); + m_emu_settings->EnhanceCheckBox(ui->disableHardwareTexelRemapping, emu_settings_type::DisableHWTexelRemapping); + SubscribeTooltip(ui->disableHardwareTexelRemapping, tooltips.settings.disable_hw_texel_remapping); + // Comboboxes m_emu_settings->EnhanceComboBox(ui->maxSPURSThreads, emu_settings_type::MaxSPURSThreads, true); diff --git a/rpcs3/rpcs3qt/settings_dialog.ui b/rpcs3/rpcs3qt/settings_dialog.ui index 6a27f45be3..e394407e11 100644 --- a/rpcs3/rpcs3qt/settings_dialog.ui +++ b/rpcs3/rpcs3qt/settings_dialog.ui @@ -4316,6 +4316,13 @@ + + + + Disable Hardware ColorSpace Remapping + + + diff --git a/rpcs3/rpcs3qt/tooltips.h b/rpcs3/rpcs3qt/tooltips.h index abdc60f3dd..e9c8ad436b 100644 --- a/rpcs3/rpcs3qt/tooltips.h +++ b/rpcs3/rpcs3qt/tooltips.h @@ -127,6 +127,7 @@ public: const QString accurate_ppu_128_loop = tr("When enabled, PPU atomic operations will operate on entire cache line data, as opposed to a single 64bit block of memory when disabled.\nNumerical values control whether or not to enable the accurate version based on the atomic operation's length."); const QString enable_performance_report = tr("Measure certain events and print a chart after the emulator is stopped. Don't enable if not asked to."); const QString num_ppu_threads = tr("Affects maximum amount of PPU threads running concurrently, the value of 1 has very low compatibility with games.\n2 is the default, if unsure do not modify this setting."); + const QString disable_hw_texel_remapping = tr("Disables use of hardware-native color-space remapping formats such as _sRGB and _SNORM suffixes.\nDisabling this option increases accuracy compared to PS3 but can also introduce some noise due to how the software emulation works."); // emulator From 585305f434e48afab4c2ac3fbf7314fa537ec7fb Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sun, 22 Feb 2026 23:27:06 +0300 Subject: [PATCH 048/175] rsx: Improve hardware texel remapping support - Fixes issues observed when the remap is requested on a hardcoded channel - In that scenario, fall back to software --- rpcs3/Emu/RSX/Common/TextureUtils.cpp | 36 +++++++++++++++++++++++++++ rpcs3/Emu/RSX/Common/TextureUtils.h | 10 ++++++-- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/rpcs3/Emu/RSX/Common/TextureUtils.cpp b/rpcs3/Emu/RSX/Common/TextureUtils.cpp index 7fe0431baf..4c92f18aaa 100644 --- a/rpcs3/Emu/RSX/Common/TextureUtils.cpp +++ b/rpcs3/Emu/RSX/Common/TextureUtils.cpp @@ -847,6 +847,16 @@ namespace rsx } } + bool texture_format_ex::hw_SNORM_possible() const + { + return (texel_remap_control & SEXT_MASK) == (get_host_format_snorm_mask(format()) << SEXT_OFFSET); + } + + bool texture_format_ex::hw_SRGB_possible() const + { + return (texel_remap_control & GAMMA_CTRL_MASK) == GAMMA_RGB_MASK; + } + std::vector get_subresources_layout(const rsx::fragment_texture& texture) { return get_subresources_layout_impl(texture); @@ -1255,6 +1265,32 @@ namespace rsx fmt::throw_exception("Unknown format 0x%x", texture_format); } + /** + * Returns a channel mask in ARGB that can be SNORM-converted + * Some formats have a hardcoded constant in one lane which we cannot SNORM-interpret in hardware. + */ + u32 get_host_format_snorm_mask(u32 format) + { + switch (format) + { + case CELL_GCM_TEXTURE_B8: + case CELL_GCM_TEXTURE_R5G6B5: + case CELL_GCM_TEXTURE_R6G5B5: + case CELL_GCM_TEXTURE_D1R5G5B5: + case CELL_GCM_TEXTURE_D8R8G8B8: + case CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: + case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: + // Hardcoded alpha formats + return 0b1110; + + case CELL_GCM_TEXTURE_X16: + // This one is a mess. X and Z are hardcoded. Not supported. + // Fall through instead of throw + default: + return 0b1111; + } + } + /** * A texture is stored as an array of blocks, where a block is a pixel for standard texture * but is a structure containing several pixels for compressed format diff --git a/rpcs3/Emu/RSX/Common/TextureUtils.h b/rpcs3/Emu/RSX/Common/TextureUtils.h index 551052f0ad..f8d899a6ca 100644 --- a/rpcs3/Emu/RSX/Common/TextureUtils.h +++ b/rpcs3/Emu/RSX/Common/TextureUtils.h @@ -147,8 +147,8 @@ namespace rsx bool valid() const { return format_bits != 0; } u32 format() const { return format_bits & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN); } - bool hw_SNORM_possible() const { return (texel_remap_control & SEXT_MASK) == SEXT_MASK; } - bool hw_SRGB_possible() const { return (texel_remap_control & GAMMA_CTRL_MASK) == GAMMA_RGB_MASK; } + bool hw_SNORM_possible() const; + bool hw_SRGB_possible() const; //private: u32 format_bits = 0; @@ -296,6 +296,12 @@ namespace rsx */ rsx::flags32_t get_format_features(u32 texture_format); + /** + * Returns a channel mask in ARGB that can be SNORM-converted + * Some formats have a hardcoded constant in one lane which we cannot SNORM-interpret in hardware. + */ + u32 get_host_format_snorm_mask(u32 format); + /** * Returns number of texel rows encoded in one pitch-length line of bytes */ From 759ef0f5b0b1c8e4cfe01a5f4d7ee5b8b7818203 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Mon, 23 Feb 2026 00:23:23 +0300 Subject: [PATCH 049/175] rsx: Add border color correction for hardware SNORM formats --- Utilities/geometry.h | 8 ++++++ rpcs3/Emu/RSX/GL/glutils/sampler.cpp | 25 +++++++++++++++++-- rpcs3/Emu/RSX/RSXTexture.cpp | 18 ++++++++------ rpcs3/Emu/RSX/RSXTexture.h | 8 +++--- rpcs3/Emu/RSX/VK/VKDraw.cpp | 37 ++++++++++++++++++++++------ 5 files changed, 75 insertions(+), 21 deletions(-) diff --git a/Utilities/geometry.h b/Utilities/geometry.h index faace6c77e..3ffbc04dd3 100644 --- a/Utilities/geometry.h +++ b/Utilities/geometry.h @@ -821,6 +821,14 @@ struct color4_base a *= rhs; } + void operator += (const color4_base& rhs) + { + r += rhs.r; + g += rhs.g; + b += rhs.b; + a += rhs.a; + } + constexpr color4_base operator * (const color4_base& rhs) const { return { r * rhs.r, g * rhs.g, b * rhs.b, a * rhs.a }; diff --git a/rpcs3/Emu/RSX/GL/glutils/sampler.cpp b/rpcs3/Emu/RSX/GL/glutils/sampler.cpp index 580caf0dc2..0d37dc3524 100644 --- a/rpcs3/Emu/RSX/GL/glutils/sampler.cpp +++ b/rpcs3/Emu/RSX/GL/glutils/sampler.cpp @@ -82,11 +82,32 @@ namespace gl { // NOTE: In OpenGL, the border texels are processed by the pipeline and will be swizzled by the texture view. // Therefore, we pass the raw value here, and the texture view will handle the rest for us. - const auto encoded_color = tex.border_color(); + const bool sext_conv_required = (sampled_image->format_ex.texel_remap_control & rsx::SEXT_MASK) != 0; + const auto encoded_color = tex.border_color(sext_conv_required); if (get_parameteri(GL_TEXTURE_BORDER_COLOR) != encoded_color) { m_propertiesi[GL_TEXTURE_BORDER_COLOR] = encoded_color; - const auto border_color = rsx::decode_border_color(encoded_color); + auto border_color = rsx::decode_border_color(encoded_color); + + if (const auto snorm_mask = tex.argb_signed(); + !sext_conv_required && tex.argb_signed()) [[ unlikely ]] + { + // Hardware SNORM is active + ensure(sampled_image->format_ex.hw_SNORM_possible()); + + // Convert the border color in host space (2N - 1) + // HW does the conversion in integer space as (x - 128) / 127 which introduces a biasing error. + const float bias_v = 128.f / 255.f; + const float scale_v = 255.f / 127.f; + + color4f scale{ 1.f }, bias{ 0.f }; + if (snorm_mask & 1) { scale.a = scale_v; bias.a = -bias_v; } + if (snorm_mask & 2) { scale.r = scale_v; bias.r = -bias_v; } + if (snorm_mask & 4) { scale.g = scale_v; bias.g = -bias_v; } + if (snorm_mask & 8) { scale.b = scale_v; bias.b = -bias_v; } + border_color = (border_color + bias) * scale; + } + glSamplerParameterfv(sampler_handle, GL_TEXTURE_BORDER_COLOR, border_color.rgba); } } diff --git a/rpcs3/Emu/RSX/RSXTexture.cpp b/rpcs3/Emu/RSX/RSXTexture.cpp index 6f8eec0e3b..071a1c8a78 100644 --- a/rpcs3/Emu/RSX/RSXTexture.cpp +++ b/rpcs3/Emu/RSX/RSXTexture.cpp @@ -364,11 +364,15 @@ namespace rsx return dimension() != rsx::texture_dimension::dimension1d ? ((registers[NV4097_SET_TEXTURE_IMAGE_RECT + (m_index * 8)]) & 0xffff) : 1; } - u32 fragment_texture::border_color() const + u32 fragment_texture::border_color(bool apply_colorspace_remapping) const { const u32 raw = registers[NV4097_SET_TEXTURE_BORDER_COLOR + (m_index * 8)]; - const u32 sext = argb_signed(); + if (!apply_colorspace_remapping) [[ likely ]] + { + return raw; + } + const u32 sext = argb_signed(); if (!sext) [[ likely ]] { return raw; @@ -430,9 +434,9 @@ namespace rsx return (conv & mask) | (raw & ~mask); } - color4f fragment_texture::remapped_border_color() const + color4f fragment_texture::remapped_border_color(bool apply_colorspace_remapping) const { - color4f base_color = rsx::decode_border_color(border_color()); + color4f base_color = rsx::decode_border_color(border_color(apply_colorspace_remapping)); if (remap() == RSX_TEXTURE_REMAP_IDENTITY) { return base_color; @@ -571,14 +575,14 @@ namespace rsx return dimension() != rsx::texture_dimension::dimension1d ? ((registers[NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT + (m_index * 8)]) & 0xffff) : 1; } - u32 vertex_texture::border_color() const + u32 vertex_texture::border_color(bool) const { return registers[NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR + (m_index * 8)]; } - color4f vertex_texture::remapped_border_color() const + color4f vertex_texture::remapped_border_color(bool) const { - return rsx::decode_border_color(border_color()); + return rsx::decode_border_color(border_color(false)); } u16 vertex_texture::depth() const diff --git a/rpcs3/Emu/RSX/RSXTexture.h b/rpcs3/Emu/RSX/RSXTexture.h index 3b0ccdebce..3acb532c0f 100644 --- a/rpcs3/Emu/RSX/RSXTexture.h +++ b/rpcs3/Emu/RSX/RSXTexture.h @@ -80,8 +80,8 @@ namespace rsx u16 height() const; // Border Color - u32 border_color() const; - color4f remapped_border_color() const; + u32 border_color(bool apply_colorspace_remapping = false) const; + color4f remapped_border_color(bool apply_colorspace_remapping = false) const; u16 depth() const; u32 pitch() const; @@ -136,8 +136,8 @@ namespace rsx u16 height() const; // Border Color - u32 border_color() const; - color4f remapped_border_color() const; + u32 border_color(bool = false) const; + color4f remapped_border_color(bool = false) const; u16 depth() const; u32 pitch() const; diff --git a/rpcs3/Emu/RSX/VK/VKDraw.cpp b/rpcs3/Emu/RSX/VK/VKDraw.cpp index 344bde8b64..e13cc9aa94 100644 --- a/rpcs3/Emu/RSX/VK/VKDraw.cpp +++ b/rpcs3/Emu/RSX/VK/VKDraw.cpp @@ -274,11 +274,11 @@ void VKGSRender::load_texture_env() return false; }; - auto get_border_color = [&](const rsx::Texture auto& tex) + auto get_border_color = [&](const rsx::Texture auto& tex, bool remap_colorspace) { return m_device->get_custom_border_color_support().require_border_color_remap - ? tex.remapped_border_color() - : rsx::decode_border_color(tex.border_color()); + ? tex.remapped_border_color(remap_colorspace) + : rsx::decode_border_color(tex.border_color(remap_colorspace)); }; std::lock_guard lock(m_sampler_mutex); @@ -394,9 +394,30 @@ void VKGSRender::load_texture_env() // NOTE: In vulkan, the border color can bypass the sample swizzle stage. // Check the device properties to determine whether to pre-swizzle the colors or not. - const auto border_color = rsx::is_border_clamped_texture(tex) - ? vk::border_color_t(get_border_color(tex)) - : vk::border_color_t(VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK); + const bool sext_conv_required = (sampler_state->format_ex.texel_remap_control & rsx::texture_control_bits::SEXT_MASK) != 0; + vk::border_color_t border_color(VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK); + + if (rsx::is_border_clamped_texture(tex)) + { + auto color_value = get_border_color(tex, sext_conv_required); + if (const auto snorm_mask = tex.argb_signed(); + !sext_conv_required && snorm_mask) + { + // Convert the border color in host space (2N - 1) + // HW does the conversion in integer space as (x - 128) / 127 which introduces a biasing error. + const float bias_v = 128.f / 255.f; + const float scale_v = 255.f / 127.f; + + color4f scale{ 1.f }, bias{ 0.f }; + if (snorm_mask & 1) { scale.a = scale_v; bias.a = -bias_v; } + if (snorm_mask & 2) { scale.r = scale_v; bias.r = -bias_v; } + if (snorm_mask & 4) { scale.g = scale_v; bias.g = -bias_v; } + if (snorm_mask & 8) { scale.b = scale_v; bias.b = -bias_v; } + color_value = (color_value + bias) * scale; + } + + border_color = color_value; + } // Check if non-point filtering can even be used on this format bool can_sample_linear; @@ -404,7 +425,7 @@ void VKGSRender::load_texture_env() { // Most PS3-like formats can be linearly filtered without problem // Exclude textures that require SNORM conversion however - can_sample_linear = (sampler_state->format_ex.texel_remap_control & rsx::texture_control_bits::SEXT_MASK) == 0; + can_sample_linear = !sext_conv_required; } else if (sampler_state->format_class != rsx::classify_format(texture_format) && (texture_format == CELL_GCM_TEXTURE_A8R8G8B8 || texture_format == CELL_GCM_TEXTURE_D8R8G8B8)) @@ -554,7 +575,7 @@ void VKGSRender::load_texture_env() // NOTE: In vulkan, the border color can bypass the sample swizzle stage. // Check the device properties to determine whether to pre-swizzle the colors or not. const auto border_color = is_border_clamped_texture(tex) - ? vk::border_color_t(get_border_color(tex)) + ? vk::border_color_t(get_border_color(tex, false)) : vk::border_color_t(VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK); if (vs_sampler_handles[i] && From cb7c3488ab02ed0264a7dfd2643f35e8ed86c5dc Mon Sep 17 00:00:00 2001 From: kd-11 Date: Mon, 23 Feb 2026 00:50:47 +0300 Subject: [PATCH 050/175] rsx: Do not emit format conversion code in shaders if the feature is unused - The sampling logic has become increasingly complex yet it is needed very rarely --- rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp | 1 + rpcs3/Emu/RSX/Program/GLSLCommon.cpp | 5 ++++ .../RSXProg/RSXFragmentTextureOps.glsl | 29 ++++++++++++++++++- rpcs3/Emu/RSX/Program/GLSLTypes.h | 1 + rpcs3/Emu/RSX/RSXThread.cpp | 8 +++++ rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp | 1 + rpcs3/Emu/RSX/gcm_enums.h | 2 ++ 7 files changed, 46 insertions(+), 1 deletion(-) diff --git a/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp b/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp index f8cc046569..5271390af9 100644 --- a/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp +++ b/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp @@ -237,6 +237,7 @@ void GLFragmentDecompilerThread::insertGlobalFunctions(std::stringstream &OS) m_shader_props.require_tex3D_ops = properties.has_tex3D; m_shader_props.require_shadowProj_ops = properties.shadow_sampler_mask != 0 && properties.has_texShadowProj; m_shader_props.require_alpha_kill = !!(m_prog.ctrl & RSX_SHADER_CONTROL_TEXTURE_ALPHA_KILL); + m_shader_props.require_color_format_convert = !!(m_prog.ctrl & RSX_SHADER_CONTROL_TEXTURE_FORMAT_CONVERT); glsl::insert_glsl_legacy_function(OS, m_shader_props); } diff --git a/rpcs3/Emu/RSX/Program/GLSLCommon.cpp b/rpcs3/Emu/RSX/Program/GLSLCommon.cpp index ebf73e935a..800a9979ff 100644 --- a/rpcs3/Emu/RSX/Program/GLSLCommon.cpp +++ b/rpcs3/Emu/RSX/Program/GLSLCommon.cpp @@ -408,6 +408,11 @@ namespace glsl enabled_options.push_back("_ENABLE_TEXTURE_ALPHA_KILL"); } + if (props.require_color_format_convert) + { + enabled_options.push_back("_ENABLE_FORMAT_CONVERSION"); + } + program_common::define_glsl_switches(OS, enabled_options); enabled_options.clear(); diff --git a/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXProg/RSXFragmentTextureOps.glsl b/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXProg/RSXFragmentTextureOps.glsl index 43dcf9e6eb..0ca9118057 100644 --- a/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXProg/RSXFragmentTextureOps.glsl +++ b/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXProg/RSXFragmentTextureOps.glsl @@ -46,8 +46,10 @@ R"( _texture_bx2_active = false; \ } while (false) #define TEX_FLAGS(index) ((TEX_PARAM(index).flags & ~(_texture_flag_erase)) | _texture_flag_override) -#else +#elif defined(_ENABLE_TEXTURE_ALPHA_KILL) || defined(_ENABLE_FORMAT_CONVERSION) #define TEX_FLAGS(index) (TEX_PARAM(index).flags) +#else + #define TEX_FLAGS(index) 0 #endif #define TEX_NAME(index) tex##index @@ -193,6 +195,8 @@ vec4 _texcoord_xform_shadow(const in vec4 coord4, const in sampler_info params) #endif // _EMULATE_SHADOW +#ifdef _ENABLE_FORMAT_CONVERSION + vec4 _sext_unorm8x4(const in vec4 x) { // TODO: Handle clamped sign-extension @@ -285,4 +289,27 @@ vec4 _process_texel(in vec4 rgba, const in uint control_bits) return rgba; } +#elif defined(_ENABLE_TEXTURE_ALPHA_KILL) + +vec4 _process_texel(in vec4 rgba, const in uint control_bits) +{ + if (_test_bit(control_bits, ALPHAKILL)) + { + // Alphakill + if (rgba.a < 0.000001) + { + _kill(); + return rgba; + } + } + + return rgba; +} + +#else + +#define _process_texel(rgba, control) rgba + +#endif // _ENABLE_FORMAT_CONVERSION + )" diff --git a/rpcs3/Emu/RSX/Program/GLSLTypes.h b/rpcs3/Emu/RSX/Program/GLSLTypes.h index 8f7cb6fa03..685d87fafd 100644 --- a/rpcs3/Emu/RSX/Program/GLSLTypes.h +++ b/rpcs3/Emu/RSX/Program/GLSLTypes.h @@ -60,5 +60,6 @@ namespace glsl bool require_tex3D_ops : 1; // Include 3D texture stuff (including cubemap) bool require_shadowProj_ops : 1; // Include shadow2DProj projection textures (1D is unsupported anyway) bool require_alpha_kill : 1; // Include alpha kill checking code + bool require_color_format_convert : 1; // Include colorspace conversion code }; }; diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 65958e189f..a8aa7cdf60 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -2315,6 +2315,7 @@ namespace rsx case CELL_GCM_TEXTURE_R5G6B5: case CELL_GCM_TEXTURE_R6G5B5: texture_control |= (1 << texture_control_bits::RENORMALIZE); + current_fragment_program.ctrl |= RSX_SHADER_CONTROL_TEXTURE_FORMAT_CONVERT; break; default: break; @@ -2326,8 +2327,15 @@ namespace rsx texture_control |= format_ex.texel_remap_control; texture_control |= format_ex.features << texture_control_bits::FORMAT_FEATURES_OFFSET; + if (format_ex.texel_remap_control) + { + current_fragment_program.ctrl |= RSX_SHADER_CONTROL_TEXTURE_FORMAT_CONVERT; + } + if (current_fp_metadata.bx2_texture_reads_mask) { + current_fragment_program.ctrl |= RSX_SHADER_CONTROL_TEXTURE_FORMAT_CONVERT; + const u32 remap_hi = tex.decoded_remap().shuffle_mask_bits(0xFu); current_fragment_program.texture_params[i].remap &= ~(0xFu << 16u); current_fragment_program.texture_params[i].remap |= (remap_hi << 16u); diff --git a/rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp b/rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp index af2e60ec93..02709d9b5c 100644 --- a/rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp +++ b/rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp @@ -336,6 +336,7 @@ void VKFragmentDecompilerThread::insertGlobalFunctions(std::stringstream &OS) m_shader_props.require_tex3D_ops = properties.has_tex3D; m_shader_props.require_shadowProj_ops = properties.shadow_sampler_mask != 0 && properties.has_texShadowProj; m_shader_props.require_alpha_kill = !!(m_prog.ctrl & RSX_SHADER_CONTROL_TEXTURE_ALPHA_KILL); + m_shader_props.require_color_format_convert = !!(m_prog.ctrl & RSX_SHADER_CONTROL_TEXTURE_FORMAT_CONVERT); // Declare global constants if (m_shader_props.require_fog_read) diff --git a/rpcs3/Emu/RSX/gcm_enums.h b/rpcs3/Emu/RSX/gcm_enums.h index 6662df1653..542151e340 100644 --- a/rpcs3/Emu/RSX/gcm_enums.h +++ b/rpcs3/Emu/RSX/gcm_enums.h @@ -468,6 +468,8 @@ namespace gcm RSX_SHADER_CONTROL_DISABLE_EARLY_Z = 0x2000000, // Do not allow early-Z optimizations on this shader + RSX_SHADER_CONTROL_TEXTURE_FORMAT_CONVERT = 0x4000000, // Allow format conversions (BX2, SNORM, SRGB, RENORM) + // Meta RSX_SHADER_CONTROL_META_USES_DISCARD = (RSX_SHADER_CONTROL_USES_KIL | RSX_SHADER_CONTROL_TEXTURE_ALPHA_KILL | RSX_SHADER_CONTROL_ALPHA_TEST | RSX_SHADER_CONTROL_POLYGON_STIPPLE | RSX_SHADER_CONTROL_ALPHA_TO_COVERAGE) }; From 34f0e865ac6d2baa31ffc5c379d1fd743c282fc3 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Mon, 23 Feb 2026 01:42:49 +0300 Subject: [PATCH 051/175] rsx: Get rid of some guessing when handling special hardware formats --- rpcs3/Emu/RSX/Common/TextureUtils.h | 10 ++++++++++ rpcs3/Emu/RSX/GL/GLDraw.cpp | 4 ++++ rpcs3/Emu/RSX/GL/glutils/sampler.cpp | 14 ++++++++------ rpcs3/Emu/RSX/VK/VKDraw.cpp | 8 ++++++-- 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/rpcs3/Emu/RSX/Common/TextureUtils.h b/rpcs3/Emu/RSX/Common/TextureUtils.h index f8d899a6ca..1cc9c21248 100644 --- a/rpcs3/Emu/RSX/Common/TextureUtils.h +++ b/rpcs3/Emu/RSX/Common/TextureUtils.h @@ -135,6 +135,12 @@ namespace rsx RSX_FORMAT_FEATURE_16BIT_CHANNELS = (1 << 3), // Complements RSX_FORMAT_FEATURE_SIGNED_COMPONENTS }; + enum host_format_features : u8 + { + RSX_HOST_FORMAT_FEATURE_SNORM = (1 << 0), + RSX_HOST_FORMAT_FEATURE_SRGB = (1 << 1), + }; + using enum format_features; struct texture_format_ex @@ -150,10 +156,14 @@ namespace rsx bool hw_SNORM_possible() const; bool hw_SRGB_possible() const; + bool host_snorm_format_active() const { return host_features & RSX_HOST_FORMAT_FEATURE_SNORM; } + bool host_srgb_format_active() const { return host_features & RSX_HOST_FORMAT_FEATURE_SRGB; } + //private: u32 format_bits = 0; u32 features = 0; u32 texel_remap_control = 0; + u32 host_features = 0; }; // Sampled image descriptor diff --git a/rpcs3/Emu/RSX/GL/GLDraw.cpp b/rpcs3/Emu/RSX/GL/GLDraw.cpp index bdf5a53d01..10e5f6da31 100644 --- a/rpcs3/Emu/RSX/GL/GLDraw.cpp +++ b/rpcs3/Emu/RSX/GL/GLDraw.cpp @@ -361,22 +361,26 @@ void GLGSRender::load_texture_env() const auto gl_format = sampler_state->image_handle->view_format(); GLenum format_override = gl_format; rsx::flags32_t flags_to_erase = 0u; + rsx::flags32_t host_flags_to_set = 0u; if (sampler_state->format_ex.hw_SNORM_possible()) { format_override = gl::get_compatible_snorm_format(gl_format); flags_to_erase = rsx::texture_control_bits::SEXT_MASK; + host_flags_to_set = rsx::RSX_HOST_FORMAT_FEATURE_SNORM; } else if (sampler_state->format_ex.hw_SRGB_possible()) { format_override = gl::get_compatible_srgb_format(gl_format); flags_to_erase = rsx::texture_control_bits::GAMMA_CTRL_MASK; + host_flags_to_set = rsx::RSX_HOST_FORMAT_FEATURE_SRGB; } if (format_override != GL_NONE && format_override != gl_format) { sampler_state->image_handle = sampler_state->image_handle->as(format_override); sampler_state->format_ex.texel_remap_control &= (~flags_to_erase); + sampler_state->format_ex.host_features |= host_flags_to_set; } } diff --git a/rpcs3/Emu/RSX/GL/glutils/sampler.cpp b/rpcs3/Emu/RSX/GL/glutils/sampler.cpp index 0d37dc3524..387228983c 100644 --- a/rpcs3/Emu/RSX/GL/glutils/sampler.cpp +++ b/rpcs3/Emu/RSX/GL/glutils/sampler.cpp @@ -84,23 +84,25 @@ namespace gl // Therefore, we pass the raw value here, and the texture view will handle the rest for us. const bool sext_conv_required = (sampled_image->format_ex.texel_remap_control & rsx::SEXT_MASK) != 0; const auto encoded_color = tex.border_color(sext_conv_required); - if (get_parameteri(GL_TEXTURE_BORDER_COLOR) != encoded_color) + const auto host_features = sampled_image->format_ex.host_features; + + if (get_parameteri(GL_TEXTURE_BORDER_COLOR) != encoded_color || + get_parameteri(GL_TEXTURE_BORDER_VALUES_NV) != host_features) { m_propertiesi[GL_TEXTURE_BORDER_COLOR] = encoded_color; - auto border_color = rsx::decode_border_color(encoded_color); + m_propertiesi[GL_TEXTURE_BORDER_VALUES_NV] = host_features; - if (const auto snorm_mask = tex.argb_signed(); - !sext_conv_required && tex.argb_signed()) [[ unlikely ]] + auto border_color = rsx::decode_border_color(encoded_color); + if (sampled_image->format_ex.host_snorm_format_active()) [[ unlikely ]] { // Hardware SNORM is active - ensure(sampled_image->format_ex.hw_SNORM_possible()); - // Convert the border color in host space (2N - 1) // HW does the conversion in integer space as (x - 128) / 127 which introduces a biasing error. const float bias_v = 128.f / 255.f; const float scale_v = 255.f / 127.f; color4f scale{ 1.f }, bias{ 0.f }; + const auto snorm_mask = tex.argb_signed(); if (snorm_mask & 1) { scale.a = scale_v; bias.a = -bias_v; } if (snorm_mask & 2) { scale.r = scale_v; bias.r = -bias_v; } if (snorm_mask & 4) { scale.g = scale_v; bias.g = -bias_v; } diff --git a/rpcs3/Emu/RSX/VK/VKDraw.cpp b/rpcs3/Emu/RSX/VK/VKDraw.cpp index e13cc9aa94..2e62edd331 100644 --- a/rpcs3/Emu/RSX/VK/VKDraw.cpp +++ b/rpcs3/Emu/RSX/VK/VKDraw.cpp @@ -353,22 +353,26 @@ void VKGSRender::load_texture_env() const auto vk_format = sampler_state->image_handle->format(); VkFormat format_override = vk_format;; rsx::flags32_t flags_to_erase = 0u; + rsx::flags32_t host_flags_to_set = 0u; if (sampler_state->format_ex.hw_SNORM_possible()) { format_override = vk::get_compatible_snorm_format(vk_format); flags_to_erase = rsx::texture_control_bits::SEXT_MASK; + host_flags_to_set = rsx::RSX_HOST_FORMAT_FEATURE_SNORM; } else if (sampler_state->format_ex.hw_SRGB_possible()) { format_override = vk::get_compatible_srgb_format(vk_format); flags_to_erase = rsx::texture_control_bits::GAMMA_CTRL_MASK; + host_flags_to_set = rsx::RSX_HOST_FORMAT_FEATURE_SRGB; } if (format_override != VK_FORMAT_UNDEFINED && format_override != vk_format) { sampler_state->image_handle = sampler_state->image_handle->as(format_override); sampler_state->format_ex.texel_remap_control &= (~flags_to_erase); + sampler_state->format_ex.host_features |= host_flags_to_set; } } @@ -400,8 +404,7 @@ void VKGSRender::load_texture_env() if (rsx::is_border_clamped_texture(tex)) { auto color_value = get_border_color(tex, sext_conv_required); - if (const auto snorm_mask = tex.argb_signed(); - !sext_conv_required && snorm_mask) + if (sampler_state->format_ex.host_snorm_format_active()) { // Convert the border color in host space (2N - 1) // HW does the conversion in integer space as (x - 128) / 127 which introduces a biasing error. @@ -409,6 +412,7 @@ void VKGSRender::load_texture_env() const float scale_v = 255.f / 127.f; color4f scale{ 1.f }, bias{ 0.f }; + const auto snorm_mask = tex.argb_signed(); if (snorm_mask & 1) { scale.a = scale_v; bias.a = -bias_v; } if (snorm_mask & 2) { scale.r = scale_v; bias.r = -bias_v; } if (snorm_mask & 4) { scale.g = scale_v; bias.g = -bias_v; } From 4fa3aaf2b5867cf68d48fa4a0407f65ce0f43e20 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Tue, 24 Feb 2026 01:25:29 +0300 Subject: [PATCH 052/175] rsx: Fix flickering when initializing texture units --- rpcs3/Emu/RSX/Common/TextureUtils.h | 9 +++++++++ rpcs3/Emu/RSX/GL/GLDraw.cpp | 2 +- rpcs3/Emu/RSX/VK/VKDraw.cpp | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/rpcs3/Emu/RSX/Common/TextureUtils.h b/rpcs3/Emu/RSX/Common/TextureUtils.h index 1cc9c21248..eb64410418 100644 --- a/rpcs3/Emu/RSX/Common/TextureUtils.h +++ b/rpcs3/Emu/RSX/Common/TextureUtils.h @@ -159,6 +159,15 @@ namespace rsx bool host_snorm_format_active() const { return host_features & RSX_HOST_FORMAT_FEATURE_SNORM; } bool host_srgb_format_active() const { return host_features & RSX_HOST_FORMAT_FEATURE_SRGB; } + operator bool() const { return valid(); } + + bool operator == (const texture_format_ex& that) const + { + return this->format_bits == that.format_bits && + this->features == that.features && + this->host_features == that.host_features; + } + //private: u32 format_bits = 0; u32 features = 0; diff --git a/rpcs3/Emu/RSX/GL/GLDraw.cpp b/rpcs3/Emu/RSX/GL/GLDraw.cpp index 10e5f6da31..940534cdea 100644 --- a/rpcs3/Emu/RSX/GL/GLDraw.cpp +++ b/rpcs3/Emu/RSX/GL/GLDraw.cpp @@ -342,7 +342,7 @@ void GLGSRender::load_texture_env() m_graphics_state |= rsx::fragment_program_state_dirty; } - if (m_fs_sampler_states[i]) + if (sampler_state->format_ex) { // Nothing to change, use cached sampler continue; diff --git a/rpcs3/Emu/RSX/VK/VKDraw.cpp b/rpcs3/Emu/RSX/VK/VKDraw.cpp index 2e62edd331..c0cb429593 100644 --- a/rpcs3/Emu/RSX/VK/VKDraw.cpp +++ b/rpcs3/Emu/RSX/VK/VKDraw.cpp @@ -334,7 +334,7 @@ void VKGSRender::load_texture_env() m_graphics_state |= rsx::fragment_program_state_dirty; } - if (fs_sampler_handles[i]) + if (sampler_state->format_ex) { // Nothing to change, use cached sampler continue; From 94cd6a6f9e3e92d8e40334824e579f909b9f1bd4 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Tue, 24 Feb 2026 01:35:33 +0300 Subject: [PATCH 053/175] gl/vk: Clean up vertex texture handling - Clean up code after refactors --- rpcs3/Emu/RSX/GL/GLDraw.cpp | 2 +- rpcs3/Emu/RSX/VK/VKDraw.cpp | 17 ++++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/rpcs3/Emu/RSX/GL/GLDraw.cpp b/rpcs3/Emu/RSX/GL/GLDraw.cpp index 940534cdea..3de2585523 100644 --- a/rpcs3/Emu/RSX/GL/GLDraw.cpp +++ b/rpcs3/Emu/RSX/GL/GLDraw.cpp @@ -441,7 +441,7 @@ void GLGSRender::load_texture_env() continue; } - if (m_vertex_textures_dirty[i]) + if (is_sampler_dirty) { m_vs_sampler_states[i].apply(tex, vs_sampler_state[i].get()); } diff --git a/rpcs3/Emu/RSX/VK/VKDraw.cpp b/rpcs3/Emu/RSX/VK/VKDraw.cpp index c0cb429593..634131b13b 100644 --- a/rpcs3/Emu/RSX/VK/VKDraw.cpp +++ b/rpcs3/Emu/RSX/VK/VKDraw.cpp @@ -559,15 +559,18 @@ void VKGSRender::load_texture_env() check_for_cyclic_refs |= true; } - if (!is_sampler_dirty && sampler_state->format_class != previous_format_class) + if (!is_sampler_dirty) { - // Host details changed but RSX is not aware - m_graphics_state |= rsx::vertex_program_state_dirty; - } + if (sampler_state->format_class != previous_format_class) + { + // Host details changed but RSX is not aware + m_graphics_state |= rsx::vertex_program_state_dirty; + } - if (!is_sampler_dirty && vs_sampler_handles[i]) - { - continue; + if (vs_sampler_handles[i]) + { + continue; + } } const VkBool32 unnormalized_coords = !!(tex.format() & CELL_GCM_TEXTURE_UN); From 99c9c16187dbaf4bd49acc797d41bdb0b0dd9cdb Mon Sep 17 00:00:00 2001 From: kd-11 Date: Tue, 24 Feb 2026 02:34:30 +0300 Subject: [PATCH 054/175] rsx: Disallow sRGB hardware format promotion unless no remap is required --- rpcs3/Emu/RSX/Common/TextureUtils.cpp | 3 ++- rpcs3/Emu/RSX/Common/TextureUtils.h | 4 +++- rpcs3/Emu/RSX/RSXTexture.cpp | 1 + 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/rpcs3/Emu/RSX/Common/TextureUtils.cpp b/rpcs3/Emu/RSX/Common/TextureUtils.cpp index 4c92f18aaa..937508035b 100644 --- a/rpcs3/Emu/RSX/Common/TextureUtils.cpp +++ b/rpcs3/Emu/RSX/Common/TextureUtils.cpp @@ -854,7 +854,8 @@ namespace rsx bool texture_format_ex::hw_SRGB_possible() const { - return (texel_remap_control & GAMMA_CTRL_MASK) == GAMMA_RGB_MASK; + return encoded_remap == RSX_TEXTURE_REMAP_IDENTITY && + (texel_remap_control & GAMMA_CTRL_MASK) == GAMMA_RGB_MASK; } std::vector get_subresources_layout(const rsx::fragment_texture& texture) diff --git a/rpcs3/Emu/RSX/Common/TextureUtils.h b/rpcs3/Emu/RSX/Common/TextureUtils.h index eb64410418..31f43432dc 100644 --- a/rpcs3/Emu/RSX/Common/TextureUtils.h +++ b/rpcs3/Emu/RSX/Common/TextureUtils.h @@ -165,12 +165,14 @@ namespace rsx { return this->format_bits == that.format_bits && this->features == that.features && - this->host_features == that.host_features; + this->host_features == that.host_features && + this->encoded_remap == that.encoded_remap; } //private: u32 format_bits = 0; u32 features = 0; + u32 encoded_remap = 0; u32 texel_remap_control = 0; u32 host_features = 0; }; diff --git a/rpcs3/Emu/RSX/RSXTexture.cpp b/rpcs3/Emu/RSX/RSXTexture.cpp index 071a1c8a78..0d18cf0cd3 100644 --- a/rpcs3/Emu/RSX/RSXTexture.cpp +++ b/rpcs3/Emu/RSX/RSXTexture.cpp @@ -121,6 +121,7 @@ namespace rsx texture_format_ex result { format_bits }; result.features = format_features; result.texel_remap_control = format_convert; + result.encoded_remap = remap(); return result; } From daa53c8642f3ab4240b188df59f03130208172a7 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Tue, 24 Feb 2026 21:20:33 +0300 Subject: [PATCH 055/175] vk: Fix cubemap detection logic --- rpcs3/Emu/RSX/VK/vkutils/image.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rpcs3/Emu/RSX/VK/vkutils/image.cpp b/rpcs3/Emu/RSX/VK/vkutils/image.cpp index b58a95c29b..9197c5a936 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/image.cpp +++ b/rpcs3/Emu/RSX/VK/vkutils/image.cpp @@ -23,7 +23,7 @@ namespace vk break; case VK_IMAGE_TYPE_2D: longest_dim = std::max(info.extent.width, info.extent.height); - dim_limit = (info.flags == VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) ? gpu_limits.maxImageDimensionCube : gpu_limits.maxImageDimension2D; + dim_limit = (info.flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) ? gpu_limits.maxImageDimensionCube : gpu_limits.maxImageDimension2D; break; case VK_IMAGE_TYPE_3D: longest_dim = std::max({ info.extent.width, info.extent.height, info.extent.depth }); @@ -360,7 +360,7 @@ namespace vk info.viewType = VK_IMAGE_VIEW_TYPE_1D; break; case VK_IMAGE_TYPE_2D: - if (resource->info.flags == VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) + if (resource->info.flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) info.viewType = VK_IMAGE_VIEW_TYPE_CUBE; else if (resource->info.arrayLayers == 1) info.viewType = VK_IMAGE_VIEW_TYPE_2D; From 41e036473a898c46147f868dba5534666b9bd36f Mon Sep 17 00:00:00 2001 From: kd-11 Date: Wed, 25 Feb 2026 02:34:20 +0300 Subject: [PATCH 056/175] rsx: Fix broken shaders when depth format conversion is enabled with no format conversion code active --- rpcs3/Emu/RSX/Program/GLSLCommon.cpp | 5 +++++ .../Program/GLSLSnippets/RSXProg/RSXFragmentTextureOps.glsl | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/rpcs3/Emu/RSX/Program/GLSLCommon.cpp b/rpcs3/Emu/RSX/Program/GLSLCommon.cpp index 800a9979ff..28cbaa61f0 100644 --- a/rpcs3/Emu/RSX/Program/GLSLCommon.cpp +++ b/rpcs3/Emu/RSX/Program/GLSLCommon.cpp @@ -413,6 +413,11 @@ namespace glsl enabled_options.push_back("_ENABLE_FORMAT_CONVERSION"); } + if (props.require_depth_conversion) + { + enabled_options.push_back("_ENABLE_DEPTH_FORMAT_RECONSTRUCTION"); + } + program_common::define_glsl_switches(OS, enabled_options); enabled_options.clear(); diff --git a/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXProg/RSXFragmentTextureOps.glsl b/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXProg/RSXFragmentTextureOps.glsl index 0ca9118057..aaf4dc434a 100644 --- a/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXProg/RSXFragmentTextureOps.glsl +++ b/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXProg/RSXFragmentTextureOps.glsl @@ -46,7 +46,7 @@ R"( _texture_bx2_active = false; \ } while (false) #define TEX_FLAGS(index) ((TEX_PARAM(index).flags & ~(_texture_flag_erase)) | _texture_flag_override) -#elif defined(_ENABLE_TEXTURE_ALPHA_KILL) || defined(_ENABLE_FORMAT_CONVERSION) +#elif defined(_ENABLE_TEXTURE_ALPHA_KILL) || defined(_ENABLE_FORMAT_CONVERSION) || defined(_ENABLE_DEPTH_FORMAT_RECONSTRUCTION) #define TEX_FLAGS(index) (TEX_PARAM(index).flags) #else #define TEX_FLAGS(index) 0 From 8396cc2300d7e07ab02b1095c26bc5448737af82 Mon Sep 17 00:00:00 2001 From: Ani Date: Sat, 14 Feb 2026 14:05:36 +0100 Subject: [PATCH 057/175] openal: Update to 1.25.1 --- 3rdparty/OpenAL/openal-soft | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rdparty/OpenAL/openal-soft b/3rdparty/OpenAL/openal-soft index 75c0059630..c41d64c6a3 160000 --- a/3rdparty/OpenAL/openal-soft +++ b/3rdparty/OpenAL/openal-soft @@ -1 +1 @@ -Subproject commit 75c00596307bf05ba7bbc8c7022836bf52f17477 +Subproject commit c41d64c6a35f6174bf4a27010aeac52a8d3bb2c6 From 60db25980f3220bcb47f902cf051dba467913d82 Mon Sep 17 00:00:00 2001 From: Ani Date: Thu, 26 Feb 2026 00:02:52 +0100 Subject: [PATCH 058/175] ci: Update docker to 1.9 --- .github/workflows/rpcs3.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/rpcs3.yml b/.github/workflows/rpcs3.yml index 0132095f41..740e844d04 100644 --- a/.github/workflows/rpcs3.yml +++ b/.github/workflows/rpcs3.yml @@ -30,23 +30,23 @@ jobs: matrix: include: - os: ubuntu-24.04 - docker_img: "rpcs3/rpcs3-ci-jammy:1.8" + docker_img: "rpcs3/rpcs3-ci-jammy:1.9" build_sh: "/rpcs3/.ci/build-linux.sh" compiler: clang UPLOAD_COMMIT_HASH: d812f1254a1157c80fd402f94446310560f54e5f UPLOAD_REPO_FULL_NAME: "rpcs3/rpcs3-binaries-linux" - os: ubuntu-24.04 - docker_img: "rpcs3/rpcs3-ci-jammy:1.8" + docker_img: "rpcs3/rpcs3-ci-jammy:1.9" build_sh: "/rpcs3/.ci/build-linux.sh" compiler: gcc - os: ubuntu-24.04-arm - docker_img: "rpcs3/rpcs3-ci-jammy-aarch64:1.8" + docker_img: "rpcs3/rpcs3-ci-jammy-aarch64:1.9" build_sh: "/rpcs3/.ci/build-linux-aarch64.sh" compiler: clang UPLOAD_COMMIT_HASH: a1d35836e8d45bfc6f63c26f0a3e5d46ef622fe1 UPLOAD_REPO_FULL_NAME: "rpcs3/rpcs3-binaries-linux-arm64" - os: ubuntu-24.04-arm - docker_img: "rpcs3/rpcs3-ci-jammy-aarch64:1.8" + docker_img: "rpcs3/rpcs3-ci-jammy-aarch64:1.9" build_sh: "/rpcs3/.ci/build-linux-aarch64.sh" compiler: gcc name: RPCS3 Linux ${{ matrix.os }} ${{ matrix.compiler }} From b30a20c2dc368f76e81ee484d2322a2c35848656 Mon Sep 17 00:00:00 2001 From: RipleyTom Date: Thu, 26 Feb 2026 21:22:15 +0100 Subject: [PATCH 059/175] More sys_ fixes --- rpcs3/Emu/Cell/lv2/sys_event.cpp | 3 +- rpcs3/Emu/Cell/lv2/sys_event_flag.cpp | 52 +++++++++++---------------- rpcs3/Emu/Cell/lv2/sys_mutex.h | 6 +++- rpcs3/Emu/Cell/lv2/sys_rwlock.cpp | 2 ++ rpcs3/Emu/Cell/lv2/sys_semaphore.cpp | 4 +-- 5 files changed, 30 insertions(+), 37 deletions(-) diff --git a/rpcs3/Emu/Cell/lv2/sys_event.cpp b/rpcs3/Emu/Cell/lv2/sys_event.cpp index d50ae87f9d..2d8417cbfc 100644 --- a/rpcs3/Emu/Cell/lv2/sys_event.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_event.cpp @@ -170,8 +170,7 @@ CellError lv2_event_queue::send(lv2_event event, bool* notified_thread, lv2_even { if (auto cpu = get_current_cpu_thread()) { - cpu->state += cpu_flag::again; - cpu->state += cpu_flag::exit; + cpu->state += cpu_flag::again + cpu_flag::exit; } sys_event.warning("Ignored event!"); diff --git a/rpcs3/Emu/Cell/lv2/sys_event_flag.cpp b/rpcs3/Emu/Cell/lv2/sys_event_flag.cpp index c28efaf711..89a6c42ac5 100644 --- a/rpcs3/Emu/Cell/lv2/sys_event_flag.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_event_flag.cpp @@ -19,6 +19,22 @@ lv2_event_flag::lv2_event_flag(utils::serial& ar) ar(pattern); } +// Always set result +struct sys_event_store_result +{ + vm::ptr ptr; + u64 val = 0; + + ~sys_event_store_result() noexcept + { + if (ptr) + { + cpu_thread::get_current()->check_state(); + *ptr = val; + } + } +}; + std::function lv2_event_flag::load(utils::serial& ar) { return load_func(make_shared(stx::exact_t(ar))); @@ -120,21 +136,7 @@ error_code sys_event_flag_wait(ppu_thread& ppu, u32 id, u64 bitptn, u32 mode, vm ppu.gpr[5] = mode; ppu.gpr[6] = 0; - // Always set result - struct store_result - { - vm::ptr ptr; - u64 val = 0; - - ~store_result() noexcept - { - if (ptr) - { - cpu_thread::get_current()->check_state(); - *ptr = val; - } - } - } store{result}; + sys_event_store_result store{result}; if (!lv2_event_flag::check_mode(mode)) { @@ -273,21 +275,7 @@ error_code sys_event_flag_trywait(ppu_thread& ppu, u32 id, u64 bitptn, u32 mode, sys_event_flag.trace("sys_event_flag_trywait(id=0x%x, bitptn=0x%llx, mode=0x%x, result=*0x%x)", id, bitptn, mode, result); - // Always set result - struct store_result - { - vm::ptr ptr; - u64 val = 0; - - ~store_result() noexcept - { - if (ptr) - { - cpu_thread::get_current()->check_state(); - *ptr = val; - } - } - } store{result}; + sys_event_store_result store{result}; if (!lv2_event_flag::check_mode(mode)) { @@ -556,8 +544,6 @@ error_code sys_event_flag_get(ppu_thread& ppu, u32 id, vm::ptr flags) return +flag.pattern; }); - ppu.check_state(); - if (!flag) { if (flags) *flags = 0; @@ -569,6 +555,8 @@ error_code sys_event_flag_get(ppu_thread& ppu, u32 id, vm::ptr flags) return CELL_EFAULT; } + ppu.check_state(); + *flags = flag.ret; return CELL_OK; } diff --git a/rpcs3/Emu/Cell/lv2/sys_mutex.h b/rpcs3/Emu/Cell/lv2/sys_mutex.h index f82f913399..c4fe04ce2a 100644 --- a/rpcs3/Emu/Cell/lv2/sys_mutex.h +++ b/rpcs3/Emu/Cell/lv2/sys_mutex.h @@ -173,7 +173,11 @@ struct lv2_mutex final : lv2_obj if (sq == data.sq) { - atomic_storage::release(control.raw().owner, res->id); + if (cpu_flag::again - res->state) + { + atomic_storage::release(control.raw().owner, res->id); + } + return false; } diff --git a/rpcs3/Emu/Cell/lv2/sys_rwlock.cpp b/rpcs3/Emu/Cell/lv2/sys_rwlock.cpp index c2abd40284..e60d4895cc 100644 --- a/rpcs3/Emu/Cell/lv2/sys_rwlock.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_rwlock.cpp @@ -441,6 +441,8 @@ error_code sys_rwlock_wlock(ppu_thread& ppu, u32 rw_lock_id, u64 timeout) continue; } + ppu.state += cpu_flag::wait; + std::lock_guard lock(rwlock->mutex); if (!rwlock->unqueue(rwlock->wq, &ppu)) diff --git a/rpcs3/Emu/Cell/lv2/sys_semaphore.cpp b/rpcs3/Emu/Cell/lv2/sys_semaphore.cpp index 7440cf2def..b6ca578977 100644 --- a/rpcs3/Emu/Cell/lv2/sys_semaphore.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_semaphore.cpp @@ -72,7 +72,7 @@ error_code sys_semaphore_create(ppu_thread& ppu, vm::ptr sem_id, vm::ptr(ppu.test_stopped()); + ppu.check_state(); *sem_id = idm::last_id(); return CELL_OK; @@ -358,7 +358,7 @@ error_code sys_semaphore_get_value(ppu_thread& ppu, u32 sem_id, vm::ptr cou return CELL_EFAULT; } - static_cast(ppu.test_stopped()); + ppu.check_state(); *count = sema.ret; return CELL_OK; From 3b6afc1d9acb62d00c580a07d7884212a05251eb Mon Sep 17 00:00:00 2001 From: RipleyTom Date: Fri, 27 Feb 2026 08:02:46 +0100 Subject: [PATCH 060/175] Final sys_ fixes --- rpcs3/Emu/Cell/lv2/sys_config.cpp | 34 ++++++++----- rpcs3/Emu/Cell/lv2/sys_config.h | 7 ++- rpcs3/Emu/Cell/lv2/sys_dbg.cpp | 2 +- rpcs3/Emu/Cell/lv2/sys_event.cpp | 20 ++++---- rpcs3/Emu/Cell/lv2/sys_fs.cpp | 18 ++----- rpcs3/Emu/Cell/lv2/sys_mmapper.cpp | 17 +++++-- rpcs3/Emu/Cell/lv2/sys_net.cpp | 48 +++++++++---------- rpcs3/Emu/Cell/lv2/sys_net/lv2_socket.h | 2 +- .../Cell/lv2/sys_net/lv2_socket_native.cpp | 6 +-- .../Emu/Cell/lv2/sys_net/lv2_socket_native.h | 2 +- rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2p.cpp | 4 +- rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2p.h | 2 +- .../Emu/Cell/lv2/sys_net/lv2_socket_p2ps.cpp | 9 +--- rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2ps.h | 2 +- rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_raw.cpp | 3 +- rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_raw.h | 2 +- rpcs3/Emu/Cell/lv2/sys_ppu_thread.cpp | 1 + rpcs3/Emu/Cell/lv2/sys_prx.cpp | 2 +- rpcs3/Emu/Cell/lv2/sys_rsxaudio.cpp | 16 +++---- rpcs3/Emu/Cell/lv2/sys_ss.cpp | 3 +- rpcs3/Emu/Cell/lv2/sys_uart.cpp | 6 ++- rpcs3/Emu/Cell/lv2/sys_usbd.cpp | 16 ++++--- rpcs3/Emu/Cell/lv2/sys_vm.cpp | 2 +- 23 files changed, 110 insertions(+), 114 deletions(-) diff --git a/rpcs3/Emu/Cell/lv2/sys_config.cpp b/rpcs3/Emu/Cell/lv2/sys_config.cpp index 0179a6b7f2..54cb2d6ce8 100644 --- a/rpcs3/Emu/Cell/lv2/sys_config.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_config.cpp @@ -174,20 +174,28 @@ bool lv2_config_service_listener::check_service(const lv2_config_service& servic return true; } -bool lv2_config_service_listener::notify(const shared_ptr& event) -{ - service_events.emplace_back(event); - return event->notify(); -} - bool lv2_config_service_listener::notify(const shared_ptr& service) { - if (!check_service(*service)) - return false; + { + std::lock_guard lock(mutex_service_events); - // Create service event and notify queue! - const auto event = lv2_config_service_event::create(handle, service, *this); - return notify(event); + if (!check_service(*service)) + return false; + + // Create service event and notify queue! + const auto event = lv2_config_service_event::create(handle, service, *this); + service_events.emplace_back(event); + + if (!event->notify()) + { + // If we fail to deliver the event to the queue just clean the event up or it'll hold the listener alive forever + g_fxo->get().remove_service_event(event->id); + service_events.pop_back(); + return false; + } + } + + return true; } void lv2_config_service_listener::notify_all() @@ -267,7 +275,7 @@ void lv2_config_service_event::write(sys_config_service_event_t *dst) const { const auto registered = service->is_registered(); - dst->service_listener_handle = listener.get_id(); + dst->service_listener_handle = listener_id; dst->registered = registered; dst->service_id = service->id; dst->user_id = service->user_id; @@ -346,7 +354,7 @@ error_code sys_config_get_service_event(u32 config_hdl, u32 event_id, vm::ptrget().find_event(event_id); - if (!event) + if (!event || event->handle != cfg) { return CELL_ESRCH; } diff --git a/rpcs3/Emu/Cell/lv2/sys_config.h b/rpcs3/Emu/Cell/lv2/sys_config.h index 0804671141..aaf4c6f5d0 100644 --- a/rpcs3/Emu/Cell/lv2/sys_config.h +++ b/rpcs3/Emu/Cell/lv2/sys_config.h @@ -296,11 +296,10 @@ private: // The service listener owns the service events - service events will not be freed as long as their corresponding listener exists // This has been confirmed to be the case in realhw + shared_mutex mutex_service_events; std::vector> service_events; shared_ptr handle; - bool notify(const shared_ptr& event); - public: const sys_config_service_id service_id; const u64 min_verbosity; @@ -370,14 +369,14 @@ public: // This has been confirmed to be the case in realhw const shared_ptr handle; const shared_ptr service; - const lv2_config_service_listener& listener; + const u32 listener_id; // Constructors (should not be used directly) lv2_config_service_event(shared_ptr _handle, shared_ptr _service, const lv2_config_service_listener& _listener) noexcept : id(get_next_id()) , handle(std::move(_handle)) , service(std::move(_service)) - , listener(_listener) + , listener_id(_listener.get_id()) { } diff --git a/rpcs3/Emu/Cell/lv2/sys_dbg.cpp b/rpcs3/Emu/Cell/lv2/sys_dbg.cpp index 27fa51b148..eb04cff61b 100644 --- a/rpcs3/Emu/Cell/lv2/sys_dbg.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_dbg.cpp @@ -105,7 +105,7 @@ error_code sys_dbg_write_process_memory(s32 pid, u32 address, u32 size, vm::cptr i += op_size; } - if (!is_exec || i >= end) + if ((!is_exec || i >= end) && exec_update_size > 0) { // Commit executable data update // The read memory is also super ptr so memmove can work correctly on all implementations diff --git a/rpcs3/Emu/Cell/lv2/sys_event.cpp b/rpcs3/Emu/Cell/lv2/sys_event.cpp index 2d8417cbfc..c5fa15cf55 100644 --- a/rpcs3/Emu/Cell/lv2/sys_event.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_event.cpp @@ -308,6 +308,15 @@ error_code sys_event_queue_destroy(ppu_thread& ppu, u32 equeue_id, s32 mode) return CELL_EBUSY; } + for (auto cpu = head; cpu; cpu = cpu->get_next_cpu()) + { + if (cpu->state & cpu_flag::again) + { + ppu.state += cpu_flag::again; + return CELL_EAGAIN; + } + } + if (!queue.events.empty()) { // Copy events for logging, does not empty @@ -320,17 +329,6 @@ error_code sys_event_queue_destroy(ppu_thread& ppu, u32 equeue_id, s32 mode) { qlock.unlock(); } - else - { - for (auto cpu = head; cpu; cpu = cpu->get_next_cpu()) - { - if (cpu->state & cpu_flag::again) - { - ppu.state += cpu_flag::again; - return CELL_EAGAIN; - } - } - } return {}; }); diff --git a/rpcs3/Emu/Cell/lv2/sys_fs.cpp b/rpcs3/Emu/Cell/lv2/sys_fs.cpp index 961d0d6ad3..312754af8a 100644 --- a/rpcs3/Emu/Cell/lv2/sys_fs.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_fs.cpp @@ -382,7 +382,7 @@ lv2_fs_object::lv2_fs_object(utils::serial& ar, bool) u64 lv2_file::op_read(const fs::file& file, vm::ptr buf, u64 size, u64 opt_pos) { - if (u64 region = buf.addr() >> 28, region_end = (buf.addr() & 0xfff'ffff) + (size & 0xfff'ffff); region == region_end && ((region >> 28) == 0 || region >= 0xC)) + if (u64 region = buf.addr() >> 28, region_end = (buf.addr() + size) >> 28; region == region_end && region == 0) { // Optimize reads from safe memory return (opt_pos == umax ? file.read(buf.get_ptr(), size) : file.read_at(opt_pos, buf.get_ptr(), size)); @@ -1391,7 +1391,8 @@ error_code sys_fs_opendir(ppu_thread& ppu, vm::cptr path, vm::ptr fd) // Add additional entries for split file candidates (while ends with .66600) while (mp.mp != &g_mp_sys_dev_hdd1 && data.back().name.ends_with(".66600")) { - data.emplace_back(data.back()).name.resize(data.back().name.size() - 6); + fs::dir_entry copy = data.back(); + data.emplace_back(copy).name.resize(copy.name.size() - 6); } } @@ -2147,6 +2148,7 @@ error_code sys_fs_fcntl(ppu_thread& ppu, u32 fd, u32 op, vm::ptr _arg, u32 sys_fs.notice("sys_fs_fcntl(0xc0000006): %s", vpath); // Check only mountpoint + vpath = vpath.substr(0, vpath.find_first_of('\0')); vpath = vpath.substr(0, vpath.find_first_of("/", 1)); // Some mountpoints seem to be handled specially @@ -2635,8 +2637,6 @@ error_code sys_fs_lseek(ppu_thread& ppu, u32 fd, s64 offset, s32 whence, vm::ptr error_code sys_fs_fdatasync(ppu_thread& ppu, u32 fd) { - lv2_obj::sleep(ppu); - sys_fs.trace("sys_fs_fdadasync(fd=%d)", fd); const auto file = idm::get_unlocked(fd); @@ -2661,8 +2661,6 @@ error_code sys_fs_fdatasync(ppu_thread& ppu, u32 fd) error_code sys_fs_fsync(ppu_thread& ppu, u32 fd) { - lv2_obj::sleep(ppu); - sys_fs.trace("sys_fs_fsync(fd=%d)", fd); const auto file = idm::get_unlocked(fd); @@ -2903,14 +2901,6 @@ error_code sys_fs_chmod(ppu_thread&, vm::cptr path, s32 mode) { // Try to locate split files - for (u32 i = 66601; i <= 66699; i++) - { - if (mp != &g_mp_sys_dev_hdd1 && !fs::get_stat(fmt::format("%s.%u", local_path, i), info) && !info.is_directory) - { - break; - } - } - if (fs::get_stat(local_path + ".66600", info) && !info.is_directory) { break; diff --git a/rpcs3/Emu/Cell/lv2/sys_mmapper.cpp b/rpcs3/Emu/Cell/lv2/sys_mmapper.cpp index d7b66adfd8..0723564a5e 100644 --- a/rpcs3/Emu/Cell/lv2/sys_mmapper.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_mmapper.cpp @@ -333,7 +333,7 @@ error_code sys_mmapper_allocate_shared_memory_ext(ppu_thread& ppu, u64 ipc_key, } } - if (flags & ~SYS_MEMORY_PAGE_SIZE_MASK) + if (flags & ~SYS_MEMORY_GRANULARITY_MASK) { return CELL_EINVAL; } @@ -401,6 +401,11 @@ error_code sys_mmapper_allocate_shared_memory_from_container_ext(ppu_thread& ppu sys_mmapper.todo("sys_mmapper_allocate_shared_memory_from_container_ext(ipc_key=0x%x, size=0x%x, flags=0x%x, cid=0x%x, entries=*0x%x, entry_count=0x%x, mem_id=*0x%x)", ipc_key, size, flags, cid, entries, entry_count, mem_id); + if (size == 0) + { + return CELL_EALIGN; + } + switch (flags & SYS_MEMORY_PAGE_SIZE_MASK) { case SYS_MEMORY_PAGE_SIZE_1M: @@ -546,8 +551,7 @@ error_code sys_mmapper_free_address(ppu_thread& ppu, u32 addr) // If a memory block is freed, remove it from page notification table. auto& pf_entries = g_fxo->get(); - std::lock_guard lock(pf_entries.mutex); - + std::unique_lock lock(pf_entries.mutex); auto ind_to_remove = pf_entries.entries.begin(); for (; ind_to_remove != pf_entries.entries.end(); ++ind_to_remove) { @@ -558,7 +562,11 @@ error_code sys_mmapper_free_address(ppu_thread& ppu, u32 addr) } if (ind_to_remove != pf_entries.entries.end()) { + u32 port_id = ind_to_remove->port_id; pf_entries.entries.erase(ind_to_remove); + lock.unlock(); + sys_event_port_disconnect(ppu, port_id); + sys_event_port_destroy(ppu, port_id); } return CELL_OK; @@ -826,7 +834,6 @@ error_code sys_mmapper_enable_page_fault_notification(ppu_thread& ppu, u32 start vm::var port_id(0); error_code res = sys_event_port_create(ppu, port_id, SYS_EVENT_PORT_LOCAL, SYS_MEMORY_PAGE_FAULT_EVENT_KEY); - sys_event_port_connect_local(ppu, *port_id, event_queue_id); if (res + 0u == CELL_EAGAIN) { @@ -834,6 +841,8 @@ error_code sys_mmapper_enable_page_fault_notification(ppu_thread& ppu, u32 start return CELL_EAGAIN; } + sys_event_port_connect_local(ppu, *port_id, event_queue_id); + auto& pf_entries = g_fxo->get(); std::unique_lock lock(pf_entries.mutex); diff --git a/rpcs3/Emu/Cell/lv2/sys_net.cpp b/rpcs3/Emu/Cell/lv2/sys_net.cpp index 27731e44ca..a860d43b12 100644 --- a/rpcs3/Emu/Cell/lv2/sys_net.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_net.cpp @@ -563,37 +563,34 @@ error_code sys_net_bnet_connect(ppu_thread& ppu, s32 s, vm::ptr(-SYS_NET_EINTR)) + if (state & cpu_flag::signal) { - return -SYS_NET_EINTR; + break; } - if (result) - { - if (result < 0) - { - return sys_net_error{result}; - } + ppu.state.wait(state); + } - return not_an_error(result); + if (ppu.gpr[3] == static_cast(-SYS_NET_EINTR)) + { + return -SYS_NET_EINTR; + } + + if (result) + { + if (result < 0) + { + return sys_net_error{result}; } + + return not_an_error(result); } return CELL_OK; @@ -1295,7 +1292,7 @@ error_code sys_net_bnet_poll(ppu_thread& ppu, vm::ptr fds, s32 n if (auto sock = idm::check_unlocked(fds_buf[i].fd)) { - signaled += sock->poll(fds_buf[i], _fds[i]); + sock->poll(fds_buf[i], _fds[i]); #ifdef _WIN32 connecting[i] = sock->is_connecting(); #endif @@ -1303,7 +1300,6 @@ error_code sys_net_bnet_poll(ppu_thread& ppu, vm::ptr fds, s32 n else { fds_buf[i].revents |= SYS_NET_POLLNVAL; - signaled++; } } @@ -1536,9 +1532,9 @@ error_code sys_net_bnet_select(ppu_thread& ppu, s32 nfds, vm::ptr select(bs_t selected, pollfd& native_pfd) = 0; error_code abort_socket(s32 flags); diff --git a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_native.cpp b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_native.cpp index 2eb47d7b55..b422db814b 100644 --- a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_native.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_native.cpp @@ -1147,14 +1147,14 @@ s32 lv2_socket_native::shutdown(s32 how) return -get_last_error(false); } -s32 lv2_socket_native::poll(sys_net_pollfd& sn_pfd, pollfd& native_pfd) +void lv2_socket_native::poll(sys_net_pollfd& sn_pfd, pollfd& native_pfd) { // Check for fake packet for dns interceptions auto& dnshook = g_fxo->get(); if (sn_pfd.events & SYS_NET_POLLIN && dnshook.is_dns(sn_pfd.fd) && dnshook.is_dns_queue(sn_pfd.fd)) { sn_pfd.revents |= SYS_NET_POLLIN; - return 1; + return; } if (sn_pfd.events & ~(SYS_NET_POLLIN | SYS_NET_POLLOUT | SYS_NET_POLLERR)) { @@ -1171,8 +1171,6 @@ s32 lv2_socket_native::poll(sys_net_pollfd& sn_pfd, pollfd& native_pfd) { native_pfd.events |= POLLOUT; } - - return 0; } std::tuple lv2_socket_native::select(bs_t selected, pollfd& native_pfd) diff --git a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_native.h b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_native.h index 84f4218cbd..af9e6a57b7 100644 --- a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_native.h +++ b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_native.h @@ -50,7 +50,7 @@ public: std::optional sendto(s32 flags, const std::vector& buf, std::optional opt_sn_addr, bool is_lock = true) override; std::optional sendmsg(s32 flags, const sys_net_msghdr& msg, bool is_lock = true) override; - s32 poll(sys_net_pollfd& sn_pfd, pollfd& native_pfd) override; + void poll(sys_net_pollfd& sn_pfd, pollfd& native_pfd) override; std::tuple select(bs_t selected, pollfd& native_pfd) override; bool is_socket_connected(); diff --git a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2p.cpp b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2p.cpp index 67cefe3e3e..903752085b 100644 --- a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2p.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2p.cpp @@ -364,7 +364,7 @@ s32 lv2_socket_p2p::shutdown([[maybe_unused]] s32 how) return CELL_OK; } -s32 lv2_socket_p2p::poll(sys_net_pollfd& sn_pfd, [[maybe_unused]] pollfd& native_pfd) +void lv2_socket_p2p::poll(sys_net_pollfd& sn_pfd, [[maybe_unused]] pollfd& native_pfd) { std::lock_guard lock(mutex); ensure(vport); @@ -381,8 +381,6 @@ s32 lv2_socket_p2p::poll(sys_net_pollfd& sn_pfd, [[maybe_unused]] pollfd& native { sn_pfd.revents |= SYS_NET_POLLOUT; } - - return sn_pfd.revents ? 1 : 0; } std::tuple lv2_socket_p2p::select(bs_t selected, [[maybe_unused]] pollfd& native_pfd) diff --git a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2p.h b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2p.h index b8fadb3d53..ec6c1d8b31 100644 --- a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2p.h +++ b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2p.h @@ -30,7 +30,7 @@ public: void close() override; s32 shutdown(s32 how) override; - s32 poll(sys_net_pollfd& sn_pfd, pollfd& native_pfd) override; + void poll(sys_net_pollfd& sn_pfd, pollfd& native_pfd) override; std::tuple select(bs_t selected, pollfd& native_pfd) override; void handle_new_data(sys_net_sockaddr_in_p2p p2p_addr, std::vector p2p_data); diff --git a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2ps.cpp b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2ps.cpp index 771402809e..cb59557458 100644 --- a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2ps.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2ps.cpp @@ -985,7 +985,7 @@ s32 lv2_socket_p2ps::shutdown([[maybe_unused]] s32 how) return CELL_OK; } -s32 lv2_socket_p2ps::poll(sys_net_pollfd& sn_pfd, [[maybe_unused]] pollfd& native_pfd) +void lv2_socket_p2ps::poll(sys_net_pollfd& sn_pfd, [[maybe_unused]] pollfd& native_pfd) { std::lock_guard lock(mutex); sys_net.trace("[P2PS] poll checking for 0x%X", sn_pfd.events); @@ -1002,14 +1002,7 @@ s32 lv2_socket_p2ps::poll(sys_net_pollfd& sn_pfd, [[maybe_unused]] pollfd& nativ { sn_pfd.revents |= SYS_NET_POLLOUT; } - - if (sn_pfd.revents) - { - return 1; - } } - - return 0; } std::tuple lv2_socket_p2ps::select(bs_t selected, [[maybe_unused]] pollfd& native_pfd) diff --git a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2ps.h b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2ps.h index 8158138936..ac23528d57 100644 --- a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2ps.h +++ b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2ps.h @@ -89,7 +89,7 @@ public: void close() override; s32 shutdown(s32 how) override; - s32 poll(sys_net_pollfd& sn_pfd, pollfd& native_pfd) override; + void poll(sys_net_pollfd& sn_pfd, pollfd& native_pfd) override; std::tuple select(bs_t selected, pollfd& native_pfd) override; private: diff --git a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_raw.cpp b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_raw.cpp index 6e74bd512f..39ae39e5b5 100644 --- a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_raw.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_raw.cpp @@ -134,10 +134,9 @@ s32 lv2_socket_raw::shutdown([[maybe_unused]] s32 how) return {}; } -s32 lv2_socket_raw::poll([[maybe_unused]] sys_net_pollfd& sn_pfd, [[maybe_unused]] pollfd& native_pfd) +void lv2_socket_raw::poll([[maybe_unused]] sys_net_pollfd& sn_pfd, [[maybe_unused]] pollfd& native_pfd) { LOG_ONCE(raw_poll, "lv2_socket_raw::poll"); - return {}; } std::tuple lv2_socket_raw::select([[maybe_unused]] bs_t selected, [[maybe_unused]] pollfd& native_pfd) diff --git a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_raw.h b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_raw.h index 01b7255884..a03339354f 100644 --- a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_raw.h +++ b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_raw.h @@ -32,6 +32,6 @@ public: void close() override; s32 shutdown(s32 how) override; - s32 poll(sys_net_pollfd& sn_pfd, pollfd& native_pfd) override; + void poll(sys_net_pollfd& sn_pfd, pollfd& native_pfd) override; std::tuple select(bs_t selected, pollfd& native_pfd) override; }; diff --git a/rpcs3/Emu/Cell/lv2/sys_ppu_thread.cpp b/rpcs3/Emu/Cell/lv2/sys_ppu_thread.cpp index e2463ca101..f26b650346 100644 --- a/rpcs3/Emu/Cell/lv2/sys_ppu_thread.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_ppu_thread.cpp @@ -305,6 +305,7 @@ error_code sys_ppu_thread_detach(ppu_thread& ppu, u32 thread_id) { // Join and notify thread (it is detached from IDM now so it must be done explicitly now) *ptr = thread_state::finished; + return CELL_OK; } return result; diff --git a/rpcs3/Emu/Cell/lv2/sys_prx.cpp b/rpcs3/Emu/Cell/lv2/sys_prx.cpp index 046d19c48e..f20b6be6cb 100644 --- a/rpcs3/Emu/Cell/lv2/sys_prx.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_prx.cpp @@ -899,7 +899,7 @@ error_code _sys_prx_register_library(ppu_thread& ppu, vm::ptr library) { for (u32 lib_addr = prx.exports_start, index = 0; lib_addr < prx.exports_end; index++, lib_addr += vm::read8(lib_addr) ? vm::read8(lib_addr) : sizeof_lib) { - if (std::memcpy(vm::base(lib_addr), mem_copy.data(), sizeof_lib) == 0) + if (std::memcmp(vm::base(lib_addr), mem_copy.data(), sizeof_lib) == 0) { atomic_storage::release(prx.m_external_loaded_flags[index], true); return true; diff --git a/rpcs3/Emu/Cell/lv2/sys_rsxaudio.cpp b/rpcs3/Emu/Cell/lv2/sys_rsxaudio.cpp index 2ba15b1146..29a1fa3501 100644 --- a/rpcs3/Emu/Cell/lv2/sys_rsxaudio.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_rsxaudio.cpp @@ -46,14 +46,14 @@ namespace rsxaudio_ringbuf_reader static void set_timestamp(rsxaudio_shmem::ringbuf_t& ring_buf, u64 timestamp) { const s32 entry_idx_raw = (ring_buf.read_idx + ring_buf.rw_max_idx - (ring_buf.rw_max_idx > 2) - 1) % ring_buf.rw_max_idx; - const s32 entry_idx = std::clamp(entry_idx_raw, 0, SYS_RSXAUDIO_RINGBUF_SZ); + const s32 entry_idx = std::clamp(entry_idx_raw, 0, SYS_RSXAUDIO_RINGBUF_SZ - 1); ring_buf.entries[entry_idx].timestamp = convert_to_timebased_time(timestamp); } static std::tuple update_status(rsxaudio_shmem::ringbuf_t& ring_buf) { - const s32 read_idx = std::clamp(ring_buf.read_idx, 0, SYS_RSXAUDIO_RINGBUF_SZ); + const s32 read_idx = std::clamp(ring_buf.read_idx, 0, SYS_RSXAUDIO_RINGBUF_SZ - 1); if ((ring_buf.entries[read_idx].valid & 1) == 0U) { @@ -61,7 +61,7 @@ namespace rsxaudio_ringbuf_reader } const s32 entry_idx_raw = (ring_buf.read_idx + ring_buf.rw_max_idx - (ring_buf.rw_max_idx > 2)) % ring_buf.rw_max_idx; - const s32 entry_idx = std::clamp(entry_idx_raw, 0, SYS_RSXAUDIO_RINGBUF_SZ); + const s32 entry_idx = std::clamp(entry_idx_raw, 0, SYS_RSXAUDIO_RINGBUF_SZ - 1); ring_buf.entries[read_idx].valid = 0; ring_buf.queue_notify_idx = (ring_buf.queue_notify_idx + 1) % ring_buf.queue_notify_step; @@ -72,7 +72,7 @@ namespace rsxaudio_ringbuf_reader static std::pair get_addr(const rsxaudio_shmem::ringbuf_t& ring_buf) { - const s32 read_idx = std::clamp(ring_buf.read_idx, 0, SYS_RSXAUDIO_RINGBUF_SZ); + const s32 read_idx = std::clamp(ring_buf.read_idx, 0, SYS_RSXAUDIO_RINGBUF_SZ - 1); if (ring_buf.entries[read_idx].valid & 1) { @@ -1392,9 +1392,9 @@ void rsxaudio_backend_thread::operator()() return; } - static rsxaudio_state ra_state{}; - static emu_audio_cfg emu_cfg{}; - static bool backend_failed = false; + rsxaudio_state ra_state{}; + emu_audio_cfg emu_cfg{}; + bool backend_failed = false; for (;;) { @@ -2018,7 +2018,7 @@ void rsxaudio_periodic_tmr::cancel_timer_unlocked() { const u64 flag = 1; const auto wr_res = write(cancel_event, &flag, sizeof(flag)); - ensure(wr_res == sizeof(flag) || wr_res == -EAGAIN); + ensure(wr_res == sizeof(flag) || errno == EAGAIN); } #elif defined(BSD) || defined(__APPLE__) handle[TIMER_ID].flags = (handle[TIMER_ID].flags & ~EV_ENABLE) | EV_DISABLE; diff --git a/rpcs3/Emu/Cell/lv2/sys_ss.cpp b/rpcs3/Emu/Cell/lv2/sys_ss.cpp index 2c4b1282fd..725adbcfc3 100644 --- a/rpcs3/Emu/Cell/lv2/sys_ss.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_ss.cpp @@ -24,7 +24,7 @@ struct lv2_update_manager // For example, 4.90 should be converted to 0x4900000000000 std::erase(version_str, '.'); - if (std::from_chars(version_str.data(), version_str.data() + version_str.size(), system_sw_version, 16).ec != std::errc{}) + if (std::from_chars(version_str.data(), version_str.data() + version_str.size(), system_sw_version, 16).ec == std::errc{}) system_sw_version <<= 40; else system_sw_version = 0; @@ -79,6 +79,7 @@ struct lv2_update_manager if (malloc_set.count(addr)) { + malloc_set.erase(addr); return vm::dealloc(addr, vm::main); } diff --git a/rpcs3/Emu/Cell/lv2/sys_uart.cpp b/rpcs3/Emu/Cell/lv2/sys_uart.cpp index 67e91b97a0..0049b60ffe 100644 --- a/rpcs3/Emu/Cell/lv2/sys_uart.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_uart.cpp @@ -1531,9 +1531,11 @@ private: } }(); + if (sce_idx == umax) + return PS3AV_STATUS_INVALID_VIDEO_PARAM; + const video_sce_param &sce_param = sce_param_arr[sce_idx]; - if (sce_idx == umax || - video_head_cfg.video_head > PS3AV_HEAD_B_ANALOG || + if (video_head_cfg.video_head > PS3AV_HEAD_B_ANALOG || video_head_cfg.video_order > 1 || video_head_cfg.video_format > 16 || video_head_cfg.video_out_format > 16 || diff --git a/rpcs3/Emu/Cell/lv2/sys_usbd.cpp b/rpcs3/Emu/Cell/lv2/sys_usbd.cpp index e1c3caf9d7..dca61f3be8 100644 --- a/rpcs3/Emu/Cell/lv2/sys_usbd.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_usbd.cpp @@ -1173,11 +1173,15 @@ error_code sys_usbd_get_device_list(ppu_thread& ppu, u32 handle, vm::ptr - u32 i_tocopy = std::min(max_devices, ::size32(usbh.handled_devices)); + const u32 i_tocopy = std::min(max_devices, ::size32(usbh.handled_devices)); + u32 index = 0; - for (u32 index = 0; index < i_tocopy; index++) + for (const auto& [_, device] : usbh.handled_devices) { - device_list[index] = usbh.handled_devices[index].first; + if (index == i_tocopy) + break; + + device_list[index++] = device.first; } return not_an_error(i_tocopy); @@ -1409,7 +1413,7 @@ error_code sys_usbd_receive_event(ppu_thread& ppu, u32 handle, vm::ptr arg1 if (is_stopped(state)) { - std::lock_guard lock(usbh.mutex); + std::lock_guard lock(usbh.mutex_sq); for (auto cpu = +usbh.sq; cpu; cpu = cpu->next_cpu) { @@ -1587,7 +1591,7 @@ error_code sys_usbd_get_transfer_status(ppu_thread& ppu, u32 handle, u32 id_tran std::lock_guard lock(usbh.mutex); - if (!usbh.is_init) + if (!usbh.is_init || id_transfer >= MAX_SYS_USBD_TRANSFERS) return CELL_EINVAL; const auto status = usbh.get_transfer_status(id_transfer); @@ -1607,7 +1611,7 @@ error_code sys_usbd_get_isochronous_transfer_status(ppu_thread& ppu, u32 handle, std::lock_guard lock(usbh.mutex); - if (!usbh.is_init) + if (!usbh.is_init || id_transfer >= MAX_SYS_USBD_TRANSFERS) return CELL_EINVAL; const auto status = usbh.get_isochronous_transfer_status(id_transfer); diff --git a/rpcs3/Emu/Cell/lv2/sys_vm.cpp b/rpcs3/Emu/Cell/lv2/sys_vm.cpp index 2a224d2339..49337cf223 100644 --- a/rpcs3/Emu/Cell/lv2/sys_vm.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_vm.cpp @@ -97,7 +97,7 @@ error_code sys_vm_memory_map(ppu_thread& ppu, u64 vsize, u64 psize, u32 cid, u64 // Look for unmapped space if (const auto area = vm::find_map(0x10000000, 0x10000000, 2 | (flag & SYS_MEMORY_PAGE_SIZE_MASK))) { - sys_vm.warning("sys_vm_memory_map(): Found VM 0x%x area (vsize=0x%x)", addr, vsize); + sys_vm.warning("sys_vm_memory_map(): Found VM 0x%x area (vsize=0x%x)", area->addr, vsize); // Alloc all memory (shall not fail) ensure(area->alloc(static_cast(vsize))); From cc1b4c8fd106774ee7f15b17b244c6f758442d39 Mon Sep 17 00:00:00 2001 From: Elad <18193363+elad335@users.noreply.github.com> Date: Fri, 30 Jan 2026 10:22:36 +0200 Subject: [PATCH 061/175] Fix strcpy_trunc type validation --- Utilities/StrUtil.h | 8 ++++---- rpcs3/Emu/Cell/Modules/sceNp.h | 28 ++++++++++++++-------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Utilities/StrUtil.h b/Utilities/StrUtil.h index d274cc074d..66c351d60f 100644 --- a/Utilities/StrUtil.h +++ b/Utilities/StrUtil.h @@ -13,13 +13,13 @@ std::string wchar_to_utf8(std::wstring_view src); std::string utf16_to_utf8(std::u16string_view src); std::u16string utf8_to_utf16(std::string_view src); -// Copy null-terminated string from a std::string or a char array to a char array with truncation -template +// Copy null-terminated string from a std::basic_string or a char array to a char array with truncation +template requires requires (D& d, T& t) { std::declval() = &d[0]; } inline void strcpy_trunc(D&& dst, const T& src) { const usz count = std::size(src) >= std::size(dst) ? std::max(std::size(dst), 1) - 1 : std::size(src); - std::memcpy(std::data(dst), std::data(src), count); - std::memset(std::data(dst) + count, 0, std::size(dst) - count); + std::copy_n(std::data(src), count, std::data(dst)); + std::fill_n(std::data(dst) + count, std::size(dst) - count, std::remove_cvref_t{}); } // Convert string to signed integer diff --git a/rpcs3/Emu/Cell/Modules/sceNp.h b/rpcs3/Emu/Cell/Modules/sceNp.h index 88dd2d816b..1bc0a345db 100644 --- a/rpcs3/Emu/Cell/Modules/sceNp.h +++ b/rpcs3/Emu/Cell/Modules/sceNp.h @@ -1397,9 +1397,9 @@ struct SceNpBasicMessageDetails // Presence details of an user struct SceNpBasicPresenceDetails { - s8 title[SCE_NP_BASIC_PRESENCE_TITLE_SIZE_MAX]; - s8 status[SCE_NP_BASIC_PRESENCE_STATUS_SIZE_MAX]; - s8 comment[SCE_NP_BASIC_PRESENCE_COMMENT_SIZE_MAX]; + char title[SCE_NP_BASIC_PRESENCE_TITLE_SIZE_MAX]; + char status[SCE_NP_BASIC_PRESENCE_STATUS_SIZE_MAX]; + char comment[SCE_NP_BASIC_PRESENCE_COMMENT_SIZE_MAX]; u8 data[SCE_NP_BASIC_MAX_PRESENCE_SIZE]; be_t size; be_t state; @@ -1410,9 +1410,9 @@ struct SceNpBasicPresenceDetails2 { be_t struct_size; be_t state; - s8 title[SCE_NP_BASIC_PRESENCE_TITLE_SIZE_MAX]; - s8 status[SCE_NP_BASIC_PRESENCE_EXTENDED_STATUS_SIZE_MAX]; - s8 comment[SCE_NP_BASIC_PRESENCE_COMMENT_SIZE_MAX]; + char title[SCE_NP_BASIC_PRESENCE_TITLE_SIZE_MAX]; + char status[SCE_NP_BASIC_PRESENCE_EXTENDED_STATUS_SIZE_MAX]; + char comment[SCE_NP_BASIC_PRESENCE_COMMENT_SIZE_MAX]; u8 data[SCE_NP_BASIC_MAX_PRESENCE_SIZE]; be_t size; }; @@ -1420,9 +1420,9 @@ struct SceNpBasicPresenceDetails2 // Country/region code struct SceNpCountryCode { - s8 data[2]; - s8 term; - s8 padding[1]; + char data[2]; + char term; + char padding[1]; }; // Date information @@ -1451,8 +1451,8 @@ struct SceNpScoreGameInfo // Ranking comment structure struct SceNpScoreComment { - s8 data[SCE_NP_SCORE_COMMENT_MAXLEN]; - s8 term[1]; + char data[SCE_NP_SCORE_COMMENT_MAXLEN]; + char term[1]; }; // Ranking information structure @@ -1524,15 +1524,15 @@ struct SceNpScoreNpIdPcId // Basic clan information to be used in raking struct SceNpScoreClanBasicInfo { - s8 clanName[SCE_NP_CLANS_CLAN_NAME_MAX_LENGTH + 1]; - s8 clanTag[SCE_NP_CLANS_CLAN_TAG_MAX_LENGTH + 1]; + char clanName[SCE_NP_CLANS_CLAN_NAME_MAX_LENGTH + 1]; + char clanTag[SCE_NP_CLANS_CLAN_TAG_MAX_LENGTH + 1]; u8 reserved[10]; }; // Clan member information handled in ranking struct SceNpScoreClansMemberDescription { - s8 description[SCE_NP_CLANS_CLAN_DESCRIPTION_MAX_LENGTH + 1]; + char description[SCE_NP_CLANS_CLAN_DESCRIPTION_MAX_LENGTH + 1]; }; // Clan ranking information From bbd91dad925e0a0bba6aed9092b3ecce47b03918 Mon Sep 17 00:00:00 2001 From: Elad <18193363+elad335@users.noreply.github.com> Date: Wed, 10 Dec 2025 09:48:18 +0200 Subject: [PATCH 062/175] SPU DisAsm: Disable unlikely float representations --- rpcs3/Emu/Cell/PPUDisAsm.cpp | 2 +- rpcs3/Emu/Cell/SPUDisAsm.h | 24 +++++++++++++++++++++--- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/rpcs3/Emu/Cell/PPUDisAsm.cpp b/rpcs3/Emu/Cell/PPUDisAsm.cpp index 484688ee12..ebfdffb5bc 100644 --- a/rpcs3/Emu/Cell/PPUDisAsm.cpp +++ b/rpcs3/Emu/Cell/PPUDisAsm.cpp @@ -330,7 +330,7 @@ void comment_constant(std::string& last_opcode, u64 value, bool print_float = fa // Comment constant formation fmt::append(last_opcode, " #0x%xh", value); - if (print_float && ((value >> 31) <= 1u || (value >> 31) == 0x1'ffff'ffffu)) + if (print_float && ((value >> 31) <= 1u || (value >> 31) == 0x1'ffff'ffffu) && (value > 0x3fffff && (value << 32 >> 32) < 0xffc00000)) { const f32 float_val = std::bit_cast(static_cast(value)); diff --git a/rpcs3/Emu/Cell/SPUDisAsm.h b/rpcs3/Emu/Cell/SPUDisAsm.h index 0d5862025b..5b1f097393 100644 --- a/rpcs3/Emu/Cell/SPUDisAsm.h +++ b/rpcs3/Emu/Cell/SPUDisAsm.h @@ -903,8 +903,14 @@ public: if (auto [is_const, value] = try_get_const_equal_value_array(+op.ra); is_const) { + if (value % 0x200 != 0) + { + // si10 is overwritten - likely an analysis mistake + return; + } + // Comment constant formation - comment_constant(last_opcode, value | static_cast(op.si10)); + comment_constant(last_opcode, value | static_cast(op.si10), false); } } void ORHI(spu_opcode_t op) @@ -941,8 +947,14 @@ public: if (auto [is_const, value] = try_get_const_equal_value_array(op.ra); is_const) { + if (value % 0x200 != 0) + { + // si10 is overwritten - likely an analysis mistake + return; + } + // Comment constant formation - comment_constant(last_opcode, value + static_cast(op.si10)); + comment_constant(last_opcode, value + static_cast(op.si10), false); } } void AHI(spu_opcode_t op) @@ -963,8 +975,14 @@ public: if (auto [is_const, value] = try_get_const_equal_value_array(op.ra); is_const) { + if (value % 0x200 != 0) + { + // si10 is overwritten - likely an analysis mistake + return; + } + // Comment constant formation - comment_constant(last_opcode, value ^ static_cast(op.si10)); + comment_constant(last_opcode, value ^ static_cast(op.si10), false); } } void XORHI(spu_opcode_t op) From f39d82f9906a1ce3b86d06c6fcb29d46eeaa9f99 Mon Sep 17 00:00:00 2001 From: Elad <18193363+elad335@users.noreply.github.com> Date: Sun, 8 Feb 2026 14:53:45 +0200 Subject: [PATCH 063/175] SPU: Fix spu_itype::zregmod --- rpcs3/Emu/Cell/SPUAnalyser.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/rpcs3/Emu/Cell/SPUAnalyser.h b/rpcs3/Emu/Cell/SPUAnalyser.h index 103c655a9e..123a629bed 100644 --- a/rpcs3/Emu/Cell/SPUAnalyser.h +++ b/rpcs3/Emu/Cell/SPUAnalyser.h @@ -51,22 +51,22 @@ struct spu_itype RDCH, RCHCNT, - BR, // branch_tag first + BR, // branch_tag first, zregmod_tag (2) first BRA, BRNZ, BRZ, BRHNZ, BRHZ, - BRSL, - BRASL, IRET, BI, BISLED, - BISL, BIZ, BINZ, BIHZ, - BIHNZ, // branch_tag last + BIHNZ, // zregmod_tag (2) last + BRSL, + BRASL, + BISL, // branch_tag last ILH, // constant_tag_first ILHU, @@ -245,7 +245,7 @@ struct spu_itype // Test for branch instruction friend constexpr bool operator &(type value, branch_tag) { - return value >= BR && value <= BIHNZ; + return value >= BR && value <= BISL; } // Test for floating point instruction @@ -299,7 +299,7 @@ struct spu_itype // Test for non register-modifying instruction friend constexpr bool operator &(type value, zregmod_tag) { - return value >= HEQ && value <= STQR; + return (value >= HEQ && value <= STQR) || (value >= BR && value <= BIHNZ); } }; From 16b05c930f71cc04af467206961efad5be1d1815 Mon Sep 17 00:00:00 2001 From: Elad <18193363+elad335@users.noreply.github.com> Date: Mon, 9 Feb 2026 21:50:38 +0200 Subject: [PATCH 064/175] Misc: Force define LLVM for IntelliSense --- rpcs3/stdafx.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rpcs3/stdafx.h b/rpcs3/stdafx.h index b1e768dc52..e2f04ca1b1 100644 --- a/rpcs3/stdafx.h +++ b/rpcs3/stdafx.h @@ -22,3 +22,7 @@ #include // IWYU pragma: export #include // IWYU pragma: export #include // IWYU pragma: export + +#if defined(__INTELLISENSE__) && !defined(LLVM_AVAILABLE) +#define LLVM_AVAILABLE +#endif From 188151fa995048d5e63fb5f4b8356c17d249e563 Mon Sep 17 00:00:00 2001 From: Elad <18193363+elad335@users.noreply.github.com> Date: Wed, 18 Feb 2026 15:13:42 +0200 Subject: [PATCH 065/175] SPU/misc: Remove outdated Instruction statistics --- rpcs3/Emu/Cell/SPUCommonRecompiler.cpp | 102 ------------------------- rpcs3/Emu/Cell/SPULLVMRecompiler.cpp | 18 ++--- 2 files changed, 6 insertions(+), 114 deletions(-) diff --git a/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp b/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp index 4d04b13666..a930bdc548 100644 --- a/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp +++ b/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp @@ -1176,108 +1176,6 @@ void spu_cache::initialize(bool build_existing_cache) if ((g_cfg.core.spu_decoder == spu_decoder_type::asmjit || g_cfg.core.spu_decoder == spu_decoder_type::llvm) && !func_list.empty()) { spu_log.success("SPU Runtime: Built %u functions.", func_list.size()); - - if (g_cfg.core.spu_debug) - { - std::string dump; - dump.reserve(10'000'000); - - std::map, spu_program*, span_less> sorted; - - for (auto&& f : func_list) - { - // Interpret as a byte string - std::span data = {reinterpret_cast(f.data.data()), f.data.size() * sizeof(u32)}; - - sorted[data] = &f; - } - - std::unordered_set depth_n; - - u32 n_max = 0; - - for (auto&& [bytes, f] : sorted) - { - { - sha1_context ctx; - u8 output[20]; - - sha1_starts(&ctx); - sha1_update(&ctx, bytes.data(), bytes.size()); - sha1_finish(&ctx, output); - fmt::append(dump, "\n\t[%s] ", fmt::base57(output)); - } - - u32 depth_m = 0; - - for (auto&& [data, f2] : sorted) - { - u32 depth = 0; - - if (f2 == f) - { - continue; - } - - for (u32 i = 0; i < bytes.size(); i++) - { - if (i < data.size() && data[i] == bytes[i]) - { - depth++; - } - else - { - break; - } - } - - depth_n.emplace(depth); - depth_m = std::max(depth, depth_m); - } - - fmt::append(dump, "c=%06d,d=%06d ", depth_n.size(), depth_m); - - bool sk = false; - - for (u32 i = 0; i < std::min(bytes.size(), std::max(256, depth_m)); i++) - { - if (depth_m == i) - { - dump += '|'; - sk = true; - } - - fmt::append(dump, "%02x", bytes[i]); - - if (i % 4 == 3) - { - if (sk) - { - sk = false; - } - else - { - dump += ' '; - } - - dump += ' '; - } - } - - fmt::append(dump, "\n\t%49s", ""); - - for (u32 i = 0; i < std::min(f->data.size(), std::max(64, utils::aligned_div(depth_m, 4))); i++) - { - fmt::append(dump, "%-10s", g_spu_iname.decode(std::bit_cast>(f->data[i]))); - } - - n_max = std::max(n_max, ::size32(depth_n)); - - depth_n.clear(); - } - - spu_log.notice("SPU Cache Dump (max_c=%d): %s", n_max, dump); - } } // Initialize global cache instance diff --git a/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp b/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp index eb44289320..2e14b09517 100644 --- a/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp +++ b/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp @@ -2802,12 +2802,9 @@ public: std::string& llvm_log = function_log; raw_string_ostream out(llvm_log); - if (g_cfg.core.spu_debug) - { - fmt::append(llvm_log, "LLVM IR at 0x%x:\n", func.entry_point); - out << *_module; // print IR - out << "\n\n"; - } + fmt::append(llvm_log, "LLVM IR at 0x%x:\n", func.entry_point); + out << *_module; // print IR + out << "\n\n"; if (verifyModule(*_module, &out)) { @@ -3274,12 +3271,9 @@ public: std::string llvm_log; raw_string_ostream out(llvm_log); - if (g_cfg.core.spu_debug) - { - fmt::append(llvm_log, "LLVM IR (interpreter):\n"); - out << *_module; // print IR - out << "\n\n"; - } + fmt::append(llvm_log, "LLVM IR (interpreter):\n"); + out << *_module; // print IR + out << "\n\n"; if (verifyModule(*_module, &out)) { From 35ccd63dbc1cbefd7ee5a299340ed148ab9dd829 Mon Sep 17 00:00:00 2001 From: Elad <18193363+elad335@users.noreply.github.com> Date: Fri, 20 Feb 2026 17:57:33 +0200 Subject: [PATCH 066/175] Win32/File.cpp: Fix fs::file constraints to avoid crashes --- Utilities/File.cpp | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/Utilities/File.cpp b/Utilities/File.cpp index d2adb22c61..490605c792 100644 --- a/Utilities/File.cpp +++ b/Utilities/File.cpp @@ -117,6 +117,7 @@ static fs::error to_error(DWORD e) case ERROR_NEGATIVE_SEEK: return fs::error::inval; case ERROR_DIRECTORY: return fs::error::inval; case ERROR_INVALID_NAME: return fs::error::inval; + case ERROR_INVALID_FUNCTION: return fs::error::inval; case ERROR_SHARING_VIOLATION: return fs::error::acces; case ERROR_DIR_NOT_EMPTY: return fs::error::notempty; case ERROR_NOT_READY: return fs::error::noent; @@ -584,7 +585,7 @@ namespace fs if (!GetFileInformationByHandleEx(m_handle, FileIdInfo, &info, sizeof(info))) { // Try GetFileInformationByHandle as a fallback - BY_HANDLE_FILE_INFORMATION info2; + BY_HANDLE_FILE_INFORMATION info2{}; ensure(GetFileInformationByHandle(m_handle, &info2)); info = {}; @@ -1658,11 +1659,40 @@ fs::file::file(const std::string& path, bs_t mode) // Check if the handle is actually valid. // This can fail on empty mounted drives (e.g. with ERROR_NOT_READY or ERROR_INVALID_FUNCTION). - BY_HANDLE_FILE_INFORMATION info; + BY_HANDLE_FILE_INFORMATION info{}; if (!GetFileInformationByHandle(handle, &info)) { + const DWORD last_error = GetLastError(); CloseHandle(handle); - g_tls_error = to_error(GetLastError()); + + if (last_error == ERROR_INVALID_FUNCTION) + { + g_tls_error = fs::error::isdir; + return; + } + + g_tls_error = to_error(last_error); + return; + } + + if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + CloseHandle(handle); + g_tls_error = fs::error::isdir; + return; + } + + if (info.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) + { + CloseHandle(handle); + g_tls_error = fs::error::acces; + return; + } + + if ((mode & fs::write) && (info.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) + { + CloseHandle(handle); + g_tls_error = fs::error::readonly; return; } @@ -2605,7 +2635,7 @@ bool fs::pending_file::commit(bool overwrite) while (file_handle != INVALID_HANDLE_VALUE) { // Get file ID (used to check for hardlinks) - BY_HANDLE_FILE_INFORMATION file_info; + BY_HANDLE_FILE_INFORMATION file_info{}; if (!GetFileInformationByHandle(file_handle, &file_info) || file_info.nNumberOfLinks == 1) { From 1ec3de9e8f0903843c253e80bec64529edc2e7d7 Mon Sep 17 00:00:00 2001 From: Elad <18193363+elad335@users.noreply.github.com> Date: Sat, 21 Feb 2026 19:32:48 +0200 Subject: [PATCH 067/175] SPU Analyzer: Fix analysis of instructions without regmod --- rpcs3/Emu/Cell/SPUCommonRecompiler.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp b/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp index a930bdc548..b4a7945ff3 100644 --- a/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp +++ b/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp @@ -3603,6 +3603,11 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s default: { + if (type & spu_itype::zregmod) + { + break; + } + // Unconst const u32 op_rt = type & spu_itype::_quadrop ? +op.rt4 : +op.rt; m_regmod[pos / 4] = op_rt; From 45c6e938a5eee47f6e276b33463020866005d67d Mon Sep 17 00:00:00 2001 From: Elad <18193363+elad335@users.noreply.github.com> Date: Thu, 26 Feb 2026 15:50:37 +0200 Subject: [PATCH 068/175] SPU LLVM: Expand SPU Profiling to blocks --- rpcs3/Emu/CPU/CPUThread.cpp | 6 +----- rpcs3/Emu/Cell/SPUCommonRecompiler.cpp | 4 +++- rpcs3/Emu/Cell/SPULLVMRecompiler.cpp | 8 ++++++++ rpcs3/Emu/Cell/SPUThread.cpp | 2 +- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/rpcs3/Emu/CPU/CPUThread.cpp b/rpcs3/Emu/CPU/CPUThread.cpp index afec56f7e1..e37e6ed0da 100644 --- a/rpcs3/Emu/CPU/CPUThread.cpp +++ b/rpcs3/Emu/CPU/CPUThread.cpp @@ -206,11 +206,7 @@ struct cpu_prof // Print only 7 hash characters out of 11 (which covers roughly 48 bits) if (type_id == 2) { - fmt::append(results, "\n\t[%s", fmt::base57(be_t{name})); - results.resize(results.size() - 4); - - // Print chunk address from lowest 16 bits - fmt::append(results, "...chunk-0x%05x]: %.4f%% (%u)", (name & 0xffff) * 4, _frac * 100., count); + fmt::append(results, "\n\t[%s]: %.4f%% (%u)", spu_block_hash{name}, _frac * 100., count); } else { diff --git a/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp b/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp index b4a7945ff3..1b6003036b 100644 --- a/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp +++ b/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp @@ -7391,6 +7391,7 @@ void spu_recompiler_base::dump(const spu_program& result, std::string& out) SPUDisAsm dis_asm(cpu_disasm_mode::dump, reinterpret_cast(result.data.data()), result.lower_bound); std::string hash; + be_t hash_start{}; if (!result.data.empty()) { @@ -7401,6 +7402,7 @@ void spu_recompiler_base::dump(const spu_program& result, std::string& out) sha1_update(&ctx, reinterpret_cast(result.data.data()), result.data.size() * 4); sha1_finish(&ctx, output); fmt::append(hash, "%s", fmt::base57(output)); + std::memcpy(&hash_start, output, sizeof(hash_start)); } else { @@ -7413,7 +7415,7 @@ void spu_recompiler_base::dump(const spu_program& result, std::string& out) { if (m_block_info[bb.first / 4]) { - fmt::append(out, "A: [0x%05x] %s\n", bb.first, m_entry_info[bb.first / 4] ? (m_ret_info[bb.first / 4] ? "Chunk" : "Entry") : "Block"); + fmt::append(out, "A: [0x%05x] %s [%s]\n", bb.first, m_entry_info[bb.first / 4] ? (m_ret_info[bb.first / 4] ? "Chunk" : "Entry") : "Block", spu_block_hash{(hash_start & -65536) + bb.first / 4}); fmt::append(out, "\t F: 0x%05x\n", bb.second.func); diff --git a/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp b/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp index 2e14b09517..d42acd3560 100644 --- a/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp +++ b/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp @@ -2160,6 +2160,14 @@ public: } } + if (bb.preds.size() >= 2) + { + if (g_cfg.core.spu_prof || g_cfg.core.spu_debug) + { + m_ir->CreateStore(m_ir->getInt64((m_hash_start & -65536) | (baddr >> 2)), spu_ptr(&spu_thread::block_hash)); + } + } + // State check at the beginning of the chunk if (need_check || (bi == 0 && g_cfg.core.spu_block_size != spu_block_size_type::safe)) { diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index 7b70dcdbd2..b9a77d7696 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -164,7 +164,7 @@ void fmt_class_string::format(std::string& out, u64 arg) out.resize(out.size() - 4); // Print chunk address from lowest 16 bits - fmt::append(out, "...chunk-0x%05x", (arg & 0xffff) * 4); + fmt::append(out, "-0x%05x", (arg & 0xffff) * 4); } enum class spu_block_hash_short : u64{}; From 0f3275ec8241af5838690a1c6d9f4da8eddcb35b Mon Sep 17 00:00:00 2001 From: Elad <18193363+elad335@users.noreply.github.com> Date: Sat, 28 Feb 2026 09:14:34 +0200 Subject: [PATCH 069/175] sys_fs: Fixup op_read --- rpcs3/Emu/Cell/lv2/sys_fs.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/rpcs3/Emu/Cell/lv2/sys_fs.cpp b/rpcs3/Emu/Cell/lv2/sys_fs.cpp index 312754af8a..172dbc60b5 100644 --- a/rpcs3/Emu/Cell/lv2/sys_fs.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_fs.cpp @@ -382,10 +382,12 @@ lv2_fs_object::lv2_fs_object(utils::serial& ar, bool) u64 lv2_file::op_read(const fs::file& file, vm::ptr buf, u64 size, u64 opt_pos) { - if (u64 region = buf.addr() >> 28, region_end = (buf.addr() + size) >> 28; region == region_end && region == 0) + if (u64 region = buf.addr() >> 28, region_end = (buf.addr() + size) >> 28; + size < u32{umax} && region == region_end && (region == 0 || region == 0xD) && vm::check_addr(buf.addr(), vm::page_writable, static_cast(size))) { // Optimize reads from safe memory - return (opt_pos == umax ? file.read(buf.get_ptr(), size) : file.read_at(opt_pos, buf.get_ptr(), size)); + const auto buf_ptr = vm::get_super_ptr(buf.addr()); + return (opt_pos == umax ? file.read(buf_ptr, size) : file.read_at(opt_pos, buf_ptr, size)); } // Copy data from intermediate buffer (avoid passing vm pointer to a native API) @@ -412,6 +414,14 @@ u64 lv2_file::op_read(const fs::file& file, vm::ptr buf, u64 size, u64 opt u64 lv2_file::op_write(const fs::file& file, vm::cptr buf, u64 size) { + if (u64 region = buf.addr() >> 28, region_end = (buf.addr() + size) >> 28; + size < u32{umax} && region == region_end && (region == 0 || region == 0xD) && vm::check_addr(buf.addr(), vm::page_readable, static_cast(size))) + { + // Optimize writes from safe memory + const auto buf_ptr = vm::get_super_ptr(buf.addr()); + return file.write(buf_ptr, size); + } + // Copy data to intermediate buffer (avoid passing vm pointer to a native API) std::vector local_buf(std::min(size, 65536)); From a9d4e1399a621bf5ed1087daf2a5d707a00153fb Mon Sep 17 00:00:00 2001 From: Megamouse Date: Wed, 25 Feb 2026 21:01:03 +0100 Subject: [PATCH 070/175] Update zlib to 1.3.2 --- 3rdparty/zlib/zlib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rdparty/zlib/zlib b/3rdparty/zlib/zlib index 51b7f2abda..da607da739 160000 --- a/3rdparty/zlib/zlib +++ b/3rdparty/zlib/zlib @@ -1 +1 @@ -Subproject commit 51b7f2abdade71cd9bb0e7a373ef2610ec6f9daf +Subproject commit da607da739fa6047df13e66a2af6b8bec7c2a498 From 8cee5a33d0709ea2642b7353c026f421f4d5c3cf Mon Sep 17 00:00:00 2001 From: Megamouse Date: Wed, 25 Feb 2026 21:12:46 +0100 Subject: [PATCH 071/175] Fix some warnings --- rpcs3/Emu/NP/pb_helpers.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/rpcs3/Emu/NP/pb_helpers.cpp b/rpcs3/Emu/NP/pb_helpers.cpp index 83170426ff..3debd0ba20 100644 --- a/rpcs3/Emu/NP/pb_helpers.cpp +++ b/rpcs3/Emu/NP/pb_helpers.cpp @@ -532,8 +532,8 @@ namespace np if (!mi.msg().empty()) { - sce_mi->msgLen = ::narrow(mi.msg().size()); - auto* ptr_msg_data = static_cast(edata.allocate(mi.msg().size(), sce_mi->msg)); + sce_mi->msgLen = ::size32(mi.msg()); + auto* ptr_msg_data = static_cast(edata.allocate(::size32(mi.msg()), sce_mi->msg)); memcpy(ptr_msg_data, mi.msg().data(), mi.msg().size()); } } @@ -575,8 +575,8 @@ namespace np if (!resp.opt().empty()) { - room_status->opt_len = ::narrow(resp.opt().size()); - u8* opt_data = static_cast(edata.allocate(resp.opt().size(), room_status->opt)); + room_status->opt_len = ::size32(resp.opt()); + u8* opt_data = static_cast(edata.allocate(::size32(resp.opt()), room_status->opt)); memcpy(opt_data, resp.opt().data(), resp.opt().size()); } @@ -604,8 +604,8 @@ namespace np cur_attr->id = attr.attr_id(); if (!attr.data().empty()) { - cur_attr->value.data.size = ::narrow(attr.data().size()); - u8* data_ptr = static_cast(edata.allocate(attr.data().size(), cur_attr->value.data.ptr)); + cur_attr->value.data.size = ::size32(attr.data()); + u8* data_ptr = static_cast(edata.allocate(::size32(attr.data()), cur_attr->value.data.ptr)); memcpy(data_ptr, attr.data().data(), attr.data().size()); } else From b8f4aaa6fb6e5d1296ce982cb8bb1f5897ba0294 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Wed, 25 Feb 2026 21:14:08 +0100 Subject: [PATCH 072/175] Update SDL to 3.4.2 --- 3rdparty/libsdl-org/SDL | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rdparty/libsdl-org/SDL b/3rdparty/libsdl-org/SDL index a962f40bbb..683181b47c 160000 --- a/3rdparty/libsdl-org/SDL +++ b/3rdparty/libsdl-org/SDL @@ -1 +1 @@ -Subproject commit a962f40bbba175e9716557a25d5d7965f134a3d3 +Subproject commit 683181b47cfabd293e3ea409f838915b8297a4fd From 3624dac22b592439990c0e9560ed7ea4cc9d8b04 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Sat, 10 Jan 2026 18:56:18 +0100 Subject: [PATCH 073/175] clans: remove unused struct --- rpcs3/Emu/NP/clans_client.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/rpcs3/Emu/NP/clans_client.cpp b/rpcs3/Emu/NP/clans_client.cpp index e2d9fa9de0..c529d5ea38 100644 --- a/rpcs3/Emu/NP/clans_client.cpp +++ b/rpcs3/Emu/NP/clans_client.cpp @@ -128,12 +128,6 @@ void fmt_class_string::format(std::string& out, u64 arg namespace clan { - struct curl_memory - { - char* response; - size_t size; - }; - size_t clans_client::curl_write_callback(void* data, size_t size, size_t nmemb, void* clientp) { const size_t realsize = size * nmemb; From 37a125ddbdf1bb13e784ceec8dc7301df412847c Mon Sep 17 00:00:00 2001 From: Megamouse Date: Sat, 10 Jan 2026 18:56:35 +0100 Subject: [PATCH 074/175] clans: const correctness --- rpcs3/Emu/NP/np_handler.cpp | 6 +++--- rpcs3/Emu/NP/np_handler.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/rpcs3/Emu/NP/np_handler.cpp b/rpcs3/Emu/NP/np_handler.cpp index 1fc9342329..f0cdc55ee2 100644 --- a/rpcs3/Emu/NP/np_handler.cpp +++ b/rpcs3/Emu/NP/np_handler.cpp @@ -254,7 +254,7 @@ namespace np // Trim null characters const auto& vec = node.data.data_vec; - auto it = std::find(vec.begin(), vec.end(), 0); + const auto it = std::find(vec.begin(), vec.end(), 0); return std::string(vec.begin(), it); } @@ -1375,12 +1375,12 @@ namespace np return history; } - u32 np_handler::get_clan_ticket_ready() + u32 np_handler::get_clan_ticket_ready() const { return clan_ticket_ready.load(); } - ticket np_handler::get_clan_ticket() + ticket np_handler::get_clan_ticket() const { clan_ticket_ready.wait(0, atomic_wait_timeout{60'000'000'000}); // 60 seconds diff --git a/rpcs3/Emu/NP/np_handler.h b/rpcs3/Emu/NP/np_handler.h index 9c02007a9c..62b69a73ac 100644 --- a/rpcs3/Emu/NP/np_handler.h +++ b/rpcs3/Emu/NP/np_handler.h @@ -257,8 +257,8 @@ namespace np // Misc stuff void req_ticket(u32 version, const SceNpId* npid, const char* service_id, const u8* cookie, u32 cookie_size, const char* entitlement_id, u32 consumed_count); const ticket& get_ticket() const; - u32 get_clan_ticket_ready(); - ticket get_clan_ticket(); + u32 get_clan_ticket_ready() const; + ticket get_clan_ticket() const; void add_player_to_history(const SceNpId* npid, const char* description); u32 add_players_to_history(const SceNpId* npids, const char* description, u32 count); u32 get_players_history_count(u32 options); From df5b624e451e16e43016f267d7deeab415d66593 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Sat, 10 Jan 2026 18:56:49 +0100 Subject: [PATCH 075/175] clans: use std::move for ticket --- rpcs3/Emu/Cell/lv2/sys_fs.cpp | 2 +- rpcs3/Emu/NP/np_requests.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/rpcs3/Emu/Cell/lv2/sys_fs.cpp b/rpcs3/Emu/Cell/lv2/sys_fs.cpp index 172dbc60b5..ffd31227a8 100644 --- a/rpcs3/Emu/Cell/lv2/sys_fs.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_fs.cpp @@ -900,7 +900,7 @@ lv2_file::open_raw_result_t lv2_file::open_raw(const std::string& local_path, s3 switch (auto error = fs::g_tls_error) { case fs::error::noent: return {CELL_ENOENT}; - default: sys_fs.error("lv2_file::open(): unknown error %s", error); + default: sys_fs.error("lv2_file::open(): unknown error %s", error); break; } return {CELL_EIO}; diff --git a/rpcs3/Emu/NP/np_requests.cpp b/rpcs3/Emu/NP/np_requests.cpp index ed7023cc89..cd18892277 100644 --- a/rpcs3/Emu/NP/np_requests.cpp +++ b/rpcs3/Emu/NP/np_requests.cpp @@ -920,19 +920,19 @@ namespace np ensure(!reply.is_error(), "Malformed reply to RequestTicket command"); auto incoming_ticket = ticket(std::move(ticket_raw)); - + // Clans: check if ticket belongs to the clan service. // If so, hijack the ticket and cache it for future use. if (incoming_ticket.get_service_id() == CLANS_SERVICE_ID) { - clan_ticket = incoming_ticket; + clan_ticket = std::move(incoming_ticket); clan_ticket_ready.store(1); clan_ticket_ready.notify_all(); - + return; } - current_ticket = incoming_ticket; + current_ticket = std::move(incoming_ticket); auto ticket_size = static_cast(current_ticket.size()); if (manager_cb) From 198c2e9eb835dbe95c674ad8c98138fb080f1ff4 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Sat, 28 Feb 2026 12:36:43 +0100 Subject: [PATCH 076/175] Qt: attempt to download up to 3 times on return_code -255 --- rpcs3/rpcs3qt/downloader.cpp | 37 ++++++++++++++++++++++++-- rpcs3/rpcs3qt/downloader.h | 3 ++- rpcs3/rpcs3qt/game_compatibility.cpp | 15 ++++------- rpcs3/rpcs3qt/patch_manager_dialog.cpp | 4 +-- rpcs3/rpcs3qt/update_manager.cpp | 4 +-- rpcs3/rpcs3qt/update_manager.h | 16 +++++------ 6 files changed, 54 insertions(+), 25 deletions(-) diff --git a/rpcs3/rpcs3qt/downloader.cpp b/rpcs3/rpcs3qt/downloader.cpp index ae97dc8f77..39078c880d 100644 --- a/rpcs3/rpcs3qt/downloader.cpp +++ b/rpcs3/rpcs3qt/downloader.cpp @@ -1,5 +1,6 @@ #include #include +#include #include "downloader.h" #include "curl_handle.h" @@ -7,6 +8,8 @@ #include "util/logs.hpp" +#include + LOG_CHANNEL(network_log, "NET"); usz curl_write_cb_compat(char* ptr, usz /*size*/, usz nmemb, void* userdata) @@ -31,7 +34,7 @@ downloader::~downloader() } } -void downloader::start(const std::string& url, bool follow_location, bool show_progress_dialog, const QString& progress_dialog_title, bool keep_progress_dialog_open, int expected_size) +void downloader::start(const std::string& url, bool follow_location, bool show_progress_dialog, const QString& progress_dialog_title, bool keep_progress_dialog_open, int expected_size, bool check_return_code, bool again) { network_log.notice("Starting download from URL: %s", url); @@ -49,6 +52,21 @@ void downloader::start(const std::string& url, bool follow_location, bool show_p m_curl_buf.clear(); m_curl_abort = false; + if (again) + { + m_download_attempts++; + + if (m_progress_dialog && m_download_attempts > 1) + { + handle_buffer_update(0, 100); + m_progress_dialog->setLabelText(tr("Please wait... Trying again")); + } + } + else + { + m_download_attempts = 1; + } + CURLcode err = curl_easy_setopt(m_curl->get_curl(), CURLOPT_URL, url.c_str()); if (err != CURLE_OK) network_log.error("curl_easy_setopt(CURLOPT_URL, %s) error: %s", url, curl_easy_strerror(err)); @@ -77,7 +95,7 @@ void downloader::start(const std::string& url, bool follow_location, bool show_p } }); - connect(m_thread, &QThread::finished, this, [this]() + connect(m_thread, &QThread::finished, this, [=, this]() { if (m_curl_abort) { @@ -93,6 +111,21 @@ void downloader::start(const std::string& url, bool follow_location, bool show_p if (m_curl_success) { network_log.notice("Download finished"); + + if (check_return_code && m_download_attempts < 3) + { + const QJsonObject json_data = QJsonDocument::fromJson(m_curl_buf).object(); + const int return_code = json_data["return_code"].toInt(-255); + + if (return_code == -255) + { + network_log.error("Error during download. Trying to download again (attempts=%d, return_code=%d)", m_download_attempts, return_code); + std::this_thread::sleep_for(500ms); // Wait for a little while + start(url, follow_location, show_progress_dialog, progress_dialog_title, keep_progress_dialog_open, expected_size, check_return_code, true); + return; + } + } + Q_EMIT signal_download_finished(m_curl_buf); } }); diff --git a/rpcs3/rpcs3qt/downloader.h b/rpcs3/rpcs3qt/downloader.h index 5a2a44fabe..be0cd0e568 100644 --- a/rpcs3/rpcs3qt/downloader.h +++ b/rpcs3/rpcs3qt/downloader.h @@ -21,7 +21,7 @@ public: explicit downloader(QWidget* parent = nullptr); ~downloader(); - void start(const std::string& url, bool follow_location, bool show_progress_dialog, const QString& progress_dialog_title = "", bool keep_progress_dialog_open = false, int expected_size = -1); + void start(const std::string& url, bool follow_location, bool show_progress_dialog, const QString& progress_dialog_title = "", bool keep_progress_dialog_open = false, int expected_size = -1, bool check_return_code = true, bool again = false); usz update_buffer(char* data, usz size); void update_progress_dialog(const QString& title) const; @@ -46,6 +46,7 @@ private: atomic_t m_curl_abort = false; atomic_t m_curl_success = false; double m_actual_download_size = -1.0; + u32 m_download_attempts = 0; progress_dialog* m_progress_dialog = nullptr; atomic_t m_keep_progress_dialog_open = false; diff --git a/rpcs3/rpcs3qt/game_compatibility.cpp b/rpcs3/rpcs3qt/game_compatibility.cpp index 2845659716..b9cb32a7c1 100644 --- a/rpcs3/rpcs3qt/game_compatibility.cpp +++ b/rpcs3/rpcs3qt/game_compatibility.cpp @@ -69,7 +69,7 @@ void game_compatibility::handle_download_canceled() bool game_compatibility::ReadJSON(const QJsonObject& json_data, bool after_download) { - const int return_code = json_data["return_code"].toInt(); + const int return_code = json_data["return_code"].toInt(-255); if (return_code < 0) { @@ -78,15 +78,10 @@ bool game_compatibility::ReadJSON(const QJsonObject& json_data, bool after_downl std::string error_message; switch (return_code) { - case -1: - error_message = "Server Error - Internal Error"; - break; - case -2: - error_message = "Server Error - Maintenance Mode"; - break; - default: - error_message = "Server Error - Unknown Error"; - break; + case -1: error_message = "Server Error - Internal Error"; break; + case -2: error_message = "Server Error - Maintenance Mode"; break; + case -255: error_message = "Server Error - Return code not found"; break; + default: error_message = "Server Error - Unknown Error"; break; } compat_log.error("%s: return code %d", error_message, return_code); Q_EMIT DownloadError(QString::fromStdString(error_message) + " " + QString::number(return_code)); diff --git a/rpcs3/rpcs3qt/patch_manager_dialog.cpp b/rpcs3/rpcs3qt/patch_manager_dialog.cpp index 227a4a3a47..a41d8ed7b5 100644 --- a/rpcs3/rpcs3qt/patch_manager_dialog.cpp +++ b/rpcs3/rpcs3qt/patch_manager_dialog.cpp @@ -1184,9 +1184,9 @@ bool patch_manager_dialog::handle_json(const QByteArray& data) } if (return_code != -1) - patch_log.error("Patch download error: %s return code: %d", error_message, return_code); + patch_log.error("Patch download error: %s, return code: %d", error_message, return_code); else - patch_log.warning("Patch download error: %s return code: %d", error_message, return_code); + patch_log.warning("Patch download error: %s, return code: %d", error_message, return_code); return false; } diff --git a/rpcs3/rpcs3qt/update_manager.cpp b/rpcs3/rpcs3qt/update_manager.cpp index 6929e08318..ec4d7ce44f 100644 --- a/rpcs3/rpcs3qt/update_manager.cpp +++ b/rpcs3/rpcs3qt/update_manager.cpp @@ -135,9 +135,9 @@ bool update_manager::handle_json(bool automatic, bool check_only, bool auto_acce } if (return_code != -1) - update_log.error("Update error: %s return code: %d", error_message, return_code); + update_log.error("Update error: %s, return code: %d", error_message, return_code); else - update_log.warning("Update error: %s return code: %d", error_message, return_code); + update_log.warning("Update error: %s, return code: %d", error_message, return_code); // If a user clicks "Check for Updates" with a custom build ask him if he's sure he wants to update to latest version if (!automatic && return_code == -1) diff --git a/rpcs3/rpcs3qt/update_manager.h b/rpcs3/rpcs3qt/update_manager.h index 8e7d9e8eb0..98ef5cf3f1 100644 --- a/rpcs3/rpcs3qt/update_manager.h +++ b/rpcs3/rpcs3qt/update_manager.h @@ -13,6 +13,14 @@ class update_manager final : public QObject { Q_OBJECT +public: + update_manager(QObject* parent, std::shared_ptr gui_settings); + void check_for_updates(bool automatic, bool check_only, bool auto_accept, QWidget* parent = nullptr); + void update(bool auto_accept); + +Q_SIGNALS: + void signal_update_available(bool update_available); + private: downloader* m_downloader = nullptr; QWidget* m_parent = nullptr; @@ -45,12 +53,4 @@ private: bool handle_json(bool automatic, bool check_only, bool auto_accept, const QByteArray& data); bool handle_rpcs3(const QByteArray& data, bool auto_accept); - -public: - update_manager(QObject* parent, std::shared_ptr gui_settings); - void check_for_updates(bool automatic, bool check_only, bool auto_accept, QWidget* parent = nullptr); - void update(bool auto_accept); - -Q_SIGNALS: - void signal_update_available(bool update_available); }; From 5ca19eabd548d517b8834e2aa3e08ab90e8d9ebf Mon Sep 17 00:00:00 2001 From: RipleyTom Date: Sat, 28 Feb 2026 18:55:31 +0100 Subject: [PATCH 077/175] NP code review sceNpTrophy fixes - sceNpTrophyGetTrophyUnlockState: signed 1 was potentially shifted by 31(UB) - sceNpTrophyUnlockTrophy: used a reader_lock and was missing check for read only context cellGame fixes - cellHddGameCheck: missing log parameters - cellGameDataCheckCreate2: missing log parameter - cellGameThemeInstall: condition inverted checking for extension + added tolower just in case - cellGameThemeInstallFromBuffer: OOB access, buf is always filled from the start and then used as a parameter to the CB sceNp fixes - sceNpManagerGetTicket: Made accurate from RE - sceNpDrmGetTimelimit: Fix msec calculation sceNp2 fixes -sceNpMatching2ContextStartAsync: avoid capturing ctx -sceNpMatching2ContextStop: Minor error value swap rpcn_client fixes -add_friend: missing log parameter -handle_friend_notification: misc validation issue np_handler fixes -ticket: Missing move in move constructor -ticket::parse: Misc validation fix -get_player_history_entry: potential UB fix np_requests fixes -Wrong CB event_type set for get_room_member_data_external_list! -reply_tus_get_data was not copying status data! -Order of error check in reply_get_room_member_data_external_list was wrong -Improved logging np_requests_gui: -Added missing guards for gui_notifications upnp_handler fixes -Highest density of bugs per line of code in the west, let's pretend I never wrote this signaling_handler fixes -Swapped to multimap to avoid collisions on timestamps Misc fixes --- Utilities/bin_patch.cpp | 2 +- rpcs3/Emu/Cell/Modules/cellGame.cpp | 12 ++--- rpcs3/Emu/Cell/Modules/sceNp.cpp | 15 +++--- rpcs3/Emu/Cell/Modules/sceNp2.cpp | 4 +- rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp | 8 ++-- rpcs3/Emu/NP/np_handler.cpp | 15 +++--- rpcs3/Emu/NP/np_helpers.cpp | 4 +- rpcs3/Emu/NP/np_helpers.h | 2 +- rpcs3/Emu/NP/np_notifications.cpp | 3 ++ rpcs3/Emu/NP/np_requests.cpp | 64 ++++++++++++++------------ rpcs3/Emu/NP/np_requests_gui.cpp | 27 ++++++++--- rpcs3/Emu/NP/rpcn_client.cpp | 4 +- rpcs3/Emu/NP/signaling_handler.cpp | 1 + rpcs3/Emu/NP/signaling_handler.h | 2 +- rpcs3/Emu/NP/upnp_handler.cpp | 35 +++++++------- rpcs3/Emu/NP/upnp_handler.h | 2 +- 16 files changed, 111 insertions(+), 89 deletions(-) diff --git a/Utilities/bin_patch.cpp b/Utilities/bin_patch.cpp index 9449d808c0..fd94b830e0 100644 --- a/Utilities/bin_patch.cpp +++ b/Utilities/bin_patch.cpp @@ -329,7 +329,7 @@ bool patch_engine::load(patch_map& patches_map, const std::string& path, std::st is_valid = false; continue; } - else if (serial.size() != 9 || !std::all_of(serial.begin(), serial.end(), [](char c) { return std::isalnum(c); })) + else if (serial.size() != 9 || !std::all_of(serial.begin(), serial.end(), [](char c) { return std::isalnum(static_cast(c)); })) { append_log_message(log_messages, fmt::format("Error: Serial '%s' invalid (patch: %s, key: %s, location: %s, file: %s)", serial, description, main_key, get_yaml_node_location(serial_node), path), &patch_log.error); is_valid = false; diff --git a/rpcs3/Emu/Cell/Modules/cellGame.cpp b/rpcs3/Emu/Cell/Modules/cellGame.cpp index 371aa2a7b3..51e5ed6a33 100644 --- a/rpcs3/Emu/Cell/Modules/cellGame.cpp +++ b/rpcs3/Emu/Cell/Modules/cellGame.cpp @@ -492,8 +492,8 @@ error_code cellHddGameCheck(ppu_thread& ppu, u32 version, vm::cptr dirName strcpy_trunc(get->getParam.titleLang[i], psf::get_string(psf, fmt::format("TITLE_%02d", i))); } - cellGame.warning("cellHddGameCheck(): Data exists:\nATTRIBUTE: 0x%x, RESOLUTION: 0x%x, RESOLUTION: 0x%x, SOUND_FORMAT: 0x%x, dataVersion: %s" - , get->getParam.attribute, get->getParam.resolution, get->getParam.soundFormat, get->getParam.soundFormat, std::span(reinterpret_cast(get->getParam.dataVersion), 6)); + cellGame.warning("cellHddGameCheck(): Data exists:\nATTRIBUTE: 0x%x, RESOLUTION: 0x%x, SOUND_FORMAT: 0x%x, dataVersion: %s" + , get->getParam.attribute, get->getParam.resolution, get->getParam.soundFormat, std::span(reinterpret_cast(get->getParam.dataVersion), 6)); } // TODO ? @@ -580,7 +580,7 @@ error_code cellHddGameCheck(ppu_thread& ppu, u32 version, vm::cptr dirName break; default: - cellGame.error("cellHddGameCheck(): callback returned unknown error (code=0x%x). Error message: %s", result->invalidMsg); + cellGame.error("cellHddGameCheck(): callback returned unknown error (code=0x%x). Error message: %s", result->result, result->invalidMsg); error_msg = get_localized_string(localized_string_id::CELL_HDD_GAME_CHECK_INVALID, "%s", result->invalidMsg); break; } @@ -1199,7 +1199,7 @@ error_code cellGameDataCheckCreate2(ppu_thread& ppu, u32 version, vm::cptr break; default: - cellGame.error("cellGameDataCheckCreate2(): callback returned unknown error (code=0x%x). Error message: %s", cbResult->invalidMsg); + cellGame.error("cellGameDataCheckCreate2(): callback returned unknown error (code=0x%x). Error message: %s", cbResult->result, cbResult->invalidMsg); error_msg = get_localized_string(localized_string_id::CELL_GAMEDATA_CHECK_INVALID, "%s", cbResult->invalidMsg); break; } @@ -1747,7 +1747,7 @@ error_code cellGameThemeInstall(vm::cptr usrdirPath, vm::cptr fileNa { u32 magic{}; - if (src_path.ends_with(".p3t") || !theme.read(magic) || magic != "P3TF"_u32) + if (!fmt::to_lower(src_path).ends_with(".p3t") || !theme.read(magic) || magic != "P3TF"_u32) { return CELL_GAME_ERROR_INVALID_THEME_FILE; } @@ -1819,7 +1819,7 @@ error_code cellGameThemeInstallFromBuffer(ppu_thread& ppu, u32 fileSize, u32 buf const u32 read_size = std::min(bufSize, fileSize - file_offset); cellGame.notice("cellGameThemeInstallFromBuffer: writing %d bytes at pos %d", read_size, file_offset); - if (theme.write(reinterpret_cast(buf.get_ptr()) + file_offset, read_size) != read_size) + if (theme.write(reinterpret_cast(buf.get_ptr()), read_size) != read_size) { cellGame.error("cellGameThemeInstallFromBuffer: failed to write to destination file '%s' (error=%s)", dst_path, fs::g_tls_error); diff --git a/rpcs3/Emu/Cell/Modules/sceNp.cpp b/rpcs3/Emu/Cell/Modules/sceNp.cpp index 3eee01cf9a..e82491eac1 100644 --- a/rpcs3/Emu/Cell/Modules/sceNp.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNp.cpp @@ -871,7 +871,7 @@ error_code sceNpDrmGetTimelimit(vm::cptr path, vm::ptr time_remain) } // Convert time to milliseconds - s64 msec = *sec * 1000ll + *nsec / 1000ll; + s64 msec = *sec * 1000ll + *nsec / 1'000'000ll; // Return the remaining time in microseconds if (npd.activate_time != 0 && msec < npd.activate_time) @@ -4242,19 +4242,16 @@ error_code sceNpManagerGetTicket(vm::ptr buffer, vm::ptr bufferSize) } const auto& ticket = nph.get_ticket(); - *bufferSize = static_cast(ticket.size()); if (!buffer) { + *bufferSize = static_cast(ticket.size()); return CELL_OK; } - if (*bufferSize < ticket.size()) - { - return SCE_NP_ERROR_INVALID_ARGUMENT; - } - - memcpy(buffer.get_ptr(), ticket.data(), ticket.size()); + const u32 size_read = std::min(::size32(ticket), static_cast(*bufferSize)); + std::memcpy(buffer.get_ptr(), ticket.data(), size_read); + *bufferSize = size_read; return CELL_OK; } @@ -5676,7 +5673,7 @@ error_code scenp_score_record_score(s32 transId, SceNpScoreBoardId boardId, SceN else { data = &gameInfo->nativeData[0]; - data_size = 64; + data_size = sizeof(gameInfo->nativeData); } nph.record_score(trans_ctx, boardId, score, scoreComment, data, data_size, tmpRank, async); diff --git a/rpcs3/Emu/Cell/Modules/sceNp2.cpp b/rpcs3/Emu/Cell/Modules/sceNp2.cpp index c9816b60f5..7809676078 100644 --- a/rpcs3/Emu/Cell/Modules/sceNp2.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNp2.cpp @@ -1135,7 +1135,7 @@ error_code sceNpMatching2ContextStartAsync(SceNpMatching2ContextId ctxId, u32 ti { sysutil_register_cb([=, context_callback = ctx->context_callback, context_callback_param = ctx->context_callback_param](ppu_thread& cb_ppu) -> s32 { - context_callback(cb_ppu, ctxId, SCE_NP_MATCHING2_CONTEXT_EVENT_Start, SCE_NP_MATCHING2_EVENT_CAUSE_CONTEXT_ACTION, 0, ctx->context_callback_param); + context_callback(cb_ppu, ctxId, SCE_NP_MATCHING2_CONTEXT_EVENT_Start, SCE_NP_MATCHING2_EVENT_CAUSE_CONTEXT_ACTION, 0, context_callback_param); return 0; }); } @@ -1760,7 +1760,7 @@ error_code sceNpMatching2ContextStop(SceNpMatching2ContextId ctxId) const auto ctx = get_match2_context(ctxId); if (!ctx) - return SCE_NP_MATCHING2_ERROR_INVALID_CONTEXT_ID; + return SCE_NP_MATCHING2_ERROR_CONTEXT_NOT_FOUND; if (!ctx->started.compare_and_swap_test(1, 0)) return SCE_NP_MATCHING2_ERROR_CONTEXT_NOT_STARTED; diff --git a/rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp b/rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp index 803d174549..866db860ec 100644 --- a/rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp @@ -1026,14 +1026,14 @@ error_code sceNpTrophyUnlockTrophy(ppu_thread& ppu, u32 context, u32 handle, s32 auto& trophy_manager = g_fxo->get(); - reader_lock lock(trophy_manager.mtx); + std::scoped_lock lock(trophy_manager.mtx); if (!trophy_manager.is_initialized) { return SCE_NP_TROPHY_ERROR_NOT_INITIALIZED; } - const auto [ctxt, error] = trophy_manager.get_context_ex(context, handle); + const auto [ctxt, error] = trophy_manager.get_context_ex(context, handle, true); if (error) { @@ -1184,9 +1184,9 @@ error_code sceNpTrophyGetTrophyUnlockState(u32 context, u32 handle, vm::ptrGetTrophyUnlockState(id)) - flags->flag_bits[id / 32] |= 1 << (id % 32); + flags->flag_bits[id / 32] |= 1u << (id % 32); else - flags->flag_bits[id / 32] &= ~(1 << (id % 32)); + flags->flag_bits[id / 32] &= ~(1u << (id % 32)); } return CELL_OK; diff --git a/rpcs3/Emu/NP/np_handler.cpp b/rpcs3/Emu/NP/np_handler.cpp index f0cdc55ee2..f1fda0752c 100644 --- a/rpcs3/Emu/NP/np_handler.cpp +++ b/rpcs3/Emu/NP/np_handler.cpp @@ -111,7 +111,7 @@ namespace np } ticket::ticket(std::vector&& raw_data) - : raw_data(raw_data) + : raw_data(std::move(raw_data)) { parse(); } @@ -387,7 +387,7 @@ namespace np return; } - if (nodes[0].id != 0x3000 && nodes[1].id != 0x3002) + if (nodes[0].id != 0x3000 || nodes[1].id != 0x3002) { ticket_log.error("The 2 blobs ids are incorrect"); return; @@ -1467,14 +1467,13 @@ namespace np if (all_history) { + if (index >= players_history.size()) + return false; + auto it = players_history.begin(); std::advance(it, index); - - if (it != players_history.end()) - { - string_to_npid(it->first, *npid); - return true; - } + string_to_npid(it->first, *npid); + return true; } else { diff --git a/rpcs3/Emu/NP/np_helpers.cpp b/rpcs3/Emu/NP/np_helpers.cpp index 39c59afdb0..9d651693d9 100644 --- a/rpcs3/Emu/NP/np_helpers.cpp +++ b/rpcs3/Emu/NP/np_helpers.cpp @@ -20,7 +20,7 @@ namespace np return std::string(ip_str); } - std::string ether_to_string(std::array& ether) + std::string ether_to_string(const std::array& ether) { return fmt::format("%02X:%02X:%02X:%02X:%02X:%02X", ether[0], ether[1], ether[2], ether[3], ether[4], ether[5]); } @@ -110,7 +110,7 @@ namespace np bool is_valid_npid(const SceNpId& npid) { - if (!std::all_of(npid.handle.data, npid.handle.data + 16, [](char c) { return std::isalnum(c) || c == '-' || c == '_' || c == 0; } ) + if (!std::all_of(npid.handle.data, npid.handle.data + 16, [](char c) { return std::isalnum(static_cast(c)) || c == '-' || c == '_' || c == 0; } ) || npid.handle.data[16] != 0 || !std::all_of(npid.handle.dummy, npid.handle.dummy + 3, [](char val) { return val == 0; }) ) { diff --git a/rpcs3/Emu/NP/np_helpers.h b/rpcs3/Emu/NP/np_helpers.h index a51499ca64..d9e2a9d076 100644 --- a/rpcs3/Emu/NP/np_helpers.h +++ b/rpcs3/Emu/NP/np_helpers.h @@ -7,7 +7,7 @@ namespace np { std::string ip_to_string(u32 addr); - std::string ether_to_string(std::array& ether); + std::string ether_to_string(const std::array& ether); bool validate_communication_id(const SceNpCommunicationId& com_id); std::string communication_id_to_string(const SceNpCommunicationId& communicationId); std::optional string_to_communication_id(std::string_view str); diff --git a/rpcs3/Emu/NP/np_notifications.cpp b/rpcs3/Emu/NP/np_notifications.cpp index 6d6d511ee0..9b64882f0f 100644 --- a/rpcs3/Emu/NP/np_notifications.cpp +++ b/rpcs3/Emu/NP/np_notifications.cpp @@ -381,7 +381,10 @@ namespace np auto ctx = get_matching_context(ctx_id); if (!ctx) + { + np_memory.free(edata.addr()); return; + } gui_cache.add_room(room_info->room_status.id); diff --git a/rpcs3/Emu/NP/np_requests.cpp b/rpcs3/Emu/NP/np_requests.cpp index cd18892277..d9dd6dc337 100644 --- a/rpcs3/Emu/NP/np_requests.cpp +++ b/rpcs3/Emu/NP/np_requests.cpp @@ -191,7 +191,7 @@ namespace np case rpcn::ErrorType::RoomGroupMaxSlotMismatch: error_code = SCE_NP_MATCHING2_SERVER_ERROR_MAX_OVER_SLOT_GROUP; break; case rpcn::ErrorType::RoomPasswordMissing: error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_PASSWORD; break; case rpcn::ErrorType::RoomGroupNoJoinLabel: error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_JOIN_GROUP_LABEL; break; - default: fmt::throw_exception("Unexpected error in reply to CreateRoom: %d", static_cast(error)); + default: fmt::throw_exception("Unexpected error in reply to CreateRoom: %s", error); } if (error_code != CELL_OK) @@ -262,7 +262,7 @@ namespace np case rpcn::ErrorType::RoomPasswordMismatch: error_code = SCE_NP_MATCHING2_SERVER_ERROR_PASSWORD_MISMATCH; break; case rpcn::ErrorType::RoomGroupFull: error_code = SCE_NP_MATCHING2_SERVER_ERROR_GROUP_FULL; break; case rpcn::ErrorType::RoomGroupJoinLabelNotFound: error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_GROUP; break; - default: fmt::throw_exception("Unexpected error in reply to JoinRoom: %d", static_cast(error)); + default: fmt::throw_exception("Unexpected error in reply to JoinRoom: %s", error); } if (error_code != 0) @@ -348,7 +348,7 @@ namespace np case rpcn::ErrorType::NoError: break; case rpcn::ErrorType::NotFound: error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_ROOM; break; // Unsure if this should return another error(missing user in room has no appropriate error code) case rpcn::ErrorType::RoomMissing: error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_ROOM; break; - default: fmt::throw_exception("Unexpected error in reply to LeaveRoom: %d", static_cast(error)); + default: fmt::throw_exception("Unexpected error in reply to LeaveRoom: %s", error); } if (error_code != CELL_OK) @@ -447,7 +447,7 @@ namespace np u32 np_handler::get_room_member_data_external_list(SceNpMatching2ContextId ctx_id, vm::cptr optParam, const SceNpMatching2GetRoomMemberDataExternalListRequest* req) { - const u32 req_id = generate_callback_info(ctx_id, optParam, SCE_NP_MATCHING2_REQUEST_EVENT_GetRoomDataExternalList, true); + const u32 req_id = generate_callback_info(ctx_id, optParam, SCE_NP_MATCHING2_REQUEST_EVENT_GetRoomMemberDataExternalList, true); if (!get_rpcn()->get_room_member_data_external_list(req_id, get_match2_context(ctx_id)->communicationId, req->roomId)) { @@ -465,13 +465,18 @@ namespace np if (!cb_info_opt) return; - ensure(error == rpcn::ErrorType::NoError, "Unexpected error in GetRoomMemberDataExternalList reply"); - - if (error == rpcn::ErrorType::RoomMissing) + switch (error) + { + case rpcn::ErrorType::NoError: + break; + case rpcn::ErrorType::RoomMissing: { cb_info_opt->queue_callback(req_id, 0, SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_ROOM, 0); return; } + default: + fmt::throw_exception("Unexpected error in GetRoomMemberDataExternalList reply: %s", error); + } const auto resp = reply.get_protobuf(); ensure(!reply.is_error(), "Malformed reply to GetRoomMemberDataExternalList command"); @@ -518,7 +523,7 @@ namespace np case rpcn::ErrorType::NoError: break; case rpcn::ErrorType::RoomMissing: error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_ROOM; break; case rpcn::ErrorType::Unauthorized: error_code = SCE_NP_MATCHING2_SERVER_ERROR_FORBIDDEN; break; - default: fmt::throw_exception("Unexpected error in reply to SetRoomDataExternal: %d", static_cast(error)); + default: fmt::throw_exception("Unexpected error in reply to SetRoomDataExternal: %s", error); } cb_info_opt->queue_callback(req_id, 0, error_code, 0); @@ -550,7 +555,7 @@ namespace np { case rpcn::ErrorType::NoError: break; case rpcn::ErrorType::RoomMissing: error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_ROOM; break; - default: fmt::throw_exception("Unexpected error in reply to GetRoomDataInternal: %d", static_cast(error)); + default: fmt::throw_exception("Unexpected error in reply to GetRoomDataInternal: %s", error); } if (error_code != CELL_OK) @@ -606,7 +611,7 @@ namespace np { case rpcn::ErrorType::NoError: break; case rpcn::ErrorType::RoomMissing: error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_ROOM; break; - default: fmt::throw_exception("Unexpected error in reply to GetRoomDataInternal: %d", static_cast(error)); + default: fmt::throw_exception("Unexpected error in reply to SetRoomDataInternal: %s", error); } cb_info_opt->queue_callback(req_id, 0, error_code, 0); @@ -640,7 +645,7 @@ namespace np case rpcn::ErrorType::NoError: break; case rpcn::ErrorType::RoomMissing: error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_ROOM; break; case rpcn::ErrorType::NotFound: error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_USER; break; - default: fmt::throw_exception("Unexpected error in reply to GetRoomMemberDataInternal: %d", static_cast(error)); + default: fmt::throw_exception("Unexpected error in reply to GetRoomMemberDataInternal: %s", error); } if (error_code != CELL_OK) @@ -694,7 +699,7 @@ namespace np case rpcn::ErrorType::RoomMissing: error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_ROOM; break; case rpcn::ErrorType::NotFound: error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_USER; break; case rpcn::ErrorType::Unauthorized: error_code = SCE_NP_MATCHING2_SERVER_ERROR_FORBIDDEN; break; - default: fmt::throw_exception("Unexpected error in reply to SetRoomMemberDataInternal: %d", static_cast(error)); + default: fmt::throw_exception("Unexpected error in reply to SetRoomMemberDataInternal: %s", error); } cb_info_opt->queue_callback(req_id, 0, error_code, 0); @@ -723,7 +728,7 @@ namespace np switch (error) { case rpcn::ErrorType::NoError: break; - default: fmt::throw_exception("Unexpected error in reply to SetUserInfo: %d", static_cast(error)); + default: fmt::throw_exception("Unexpected error in reply to SetUserInfo: %s", error); } cb_info_opt->queue_callback(req_id, 0, 0, 0); @@ -755,7 +760,7 @@ namespace np { case rpcn::ErrorType::NoError: break; case rpcn::ErrorType::RoomMissing: error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_ROOM; break; - default: fmt::throw_exception("Unexpected error in reply to PingRoomOwner: %d", static_cast(error)); + default: fmt::throw_exception("Unexpected error in reply to PingRoomOwner: %s", error); } if (error_code != CELL_OK) @@ -803,7 +808,7 @@ namespace np case rpcn::ErrorType::NoError: break; case rpcn::ErrorType::RoomMissing: error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_ROOM; break; case rpcn::ErrorType::Unauthorized: error_code = SCE_NP_MATCHING2_SERVER_ERROR_FORBIDDEN; break; - default: fmt::throw_exception("Unexpected error in reply to SendRoomMessage: %d", static_cast(error)); + default: fmt::throw_exception("Unexpected error in reply to SendRoomMessage: %s", error); } cb_info_opt->queue_callback(req_id, 0, error_code, 0); @@ -841,7 +846,7 @@ namespace np rpcn_log.error("Signaling information was requested for a user that doesn't exist or is not online"); return; } - default: fmt::throw_exception("Unexpected error in reply to RequestSignalingInfos: %d", static_cast(error)); + default: fmt::throw_exception("Unexpected error in reply to RequestSignalingInfos: %s", error); } const auto resp = reply.get_protobuf(); @@ -861,9 +866,7 @@ namespace np const u32 req_id = generate_callback_info(ctx_id, optParam, SCE_NP_MATCHING2_REQUEST_EVENT_GetLobbyInfoList, false); auto cb_info_opt = take_pending_request(req_id); - - if (!cb_info_opt) - return true; + ensure (cb_info_opt); const u32 event_key = get_event_key(); @@ -1017,7 +1020,7 @@ namespace np { case rpcn::ErrorType::NoError: break; case rpcn::ErrorType::NotFound: error_code = SCE_NP_COMMUNITY_SERVER_ERROR_RANKING_BOARD_MASTER_NOT_FOUND; break; - default: fmt::throw_exception("Unexpected error in reply to GetBoardInfos: %d", static_cast(error)); + default: fmt::throw_exception("Unexpected error in reply to GetBoardInfos: %s", error); } if (error_code != CELL_OK) @@ -1091,7 +1094,7 @@ namespace np score_trans->wake_cond.notify_one(); return; } - default: fmt::throw_exception("Unexpected error in reply_record_score: %d", static_cast(error)); + default: fmt::throw_exception("Unexpected error in reply_record_score: %s", error); } auto tmp_rank = reply.get(); @@ -1154,7 +1157,7 @@ namespace np case rpcn::ErrorType::NotFound: trans->set_result_and_wake(SCE_NP_COMMUNITY_SERVER_ERROR_RANKING_STORE_NOT_FOUND); break; case rpcn::ErrorType::ScoreInvalid: trans->set_result_and_wake(SCE_NP_COMMUNITY_SERVER_ERROR_INVALID_SCORE); break; case rpcn::ErrorType::ScoreHasData: trans->set_result_and_wake(SCE_NP_COMMUNITY_SERVER_ERROR_GAME_DATA_ALREADY_EXISTS); break; - default: fmt::throw_exception("Unexpected error in reply to RecordScoreData: %d", static_cast(error)); + default: fmt::throw_exception("Unexpected error in reply to RecordScoreData: %s", error); } } @@ -1207,7 +1210,7 @@ namespace np { case rpcn::ErrorType::NoError: break; case rpcn::ErrorType::NotFound: score_trans->set_result_and_wake(SCE_NP_COMMUNITY_SERVER_ERROR_RANKING_GAME_DATA_MASTER_NOT_FOUND); return; - default: fmt::throw_exception("Unexpected error in reply to GetScoreData: %d", static_cast(error)); + default: fmt::throw_exception("Unexpected error in reply to GetScoreData: %s", error); } auto* tdata = std::get_if(&score_trans->tdata); @@ -1287,7 +1290,7 @@ namespace np switch (error) { case rpcn::ErrorType::NoError: break; - default: fmt::throw_exception("Unexpected error in GetScoreResponse: %d", static_cast(error)); + default: fmt::throw_exception("Unexpected error in GetScoreResponse: %s", error); } const auto resp = reply.get_protobuf(); @@ -1476,7 +1479,7 @@ namespace np case rpcn::ErrorType::NotFound: trans->set_result_and_wake(SCE_NP_COMMUNITY_SERVER_ERROR_USER_NOT_ASSIGNED); break; case rpcn::ErrorType::Unauthorized: trans->set_result_and_wake(SCE_NP_COMMUNITY_SERVER_ERROR_FORBIDDEN); break; case rpcn::ErrorType::CondFail: trans->set_result_and_wake(SCE_NP_COMMUNITY_SERVER_ERROR_CONDITIONS_NOT_SATISFIED); break; - default: fmt::throw_exception("Unexpected error in handle_tus_no_data: %d", static_cast(error)); + default: fmt::throw_exception("Unexpected error in handle_tus_no_data: %s", error); } } @@ -1499,7 +1502,7 @@ namespace np case rpcn::ErrorType::NotFound: return tus_trans->set_result_and_wake(SCE_NP_COMMUNITY_SERVER_ERROR_USER_NOT_ASSIGNED); case rpcn::ErrorType::Unauthorized: return tus_trans->set_result_and_wake(SCE_NP_COMMUNITY_SERVER_ERROR_FORBIDDEN); case rpcn::ErrorType::CondFail: return tus_trans->set_result_and_wake(SCE_NP_COMMUNITY_SERVER_ERROR_CONDITIONS_NOT_SATISFIED); - default: fmt::throw_exception("Unexpected error in handle_TusVarResponse: %d", static_cast(error)); + default: fmt::throw_exception("Unexpected error in handle_TusVarResponse: %s", error); } const auto resp = reply.get_protobuf(); @@ -1555,7 +1558,7 @@ namespace np case rpcn::ErrorType::NotFound: return tus_trans->set_result_and_wake(SCE_NP_COMMUNITY_SERVER_ERROR_USER_NOT_ASSIGNED); case rpcn::ErrorType::Unauthorized: return tus_trans->set_result_and_wake(SCE_NP_COMMUNITY_SERVER_ERROR_FORBIDDEN); case rpcn::ErrorType::CondFail: return tus_trans->set_result_and_wake(SCE_NP_COMMUNITY_SERVER_ERROR_CONDITIONS_NOT_SATISFIED); - default: fmt::throw_exception("Unexpected error in handle_TusVariable: %d", static_cast(error)); + default: fmt::throw_exception("Unexpected error in handle_TusVariable: %s", error); } auto pb_var = reply.get_protobuf(); @@ -1603,7 +1606,7 @@ namespace np case rpcn::ErrorType::NotFound: return tus_trans->set_result_and_wake(SCE_NP_COMMUNITY_SERVER_ERROR_USER_NOT_ASSIGNED); case rpcn::ErrorType::Unauthorized: return tus_trans->set_result_and_wake(SCE_NP_COMMUNITY_SERVER_ERROR_FORBIDDEN); case rpcn::ErrorType::CondFail: return tus_trans->set_result_and_wake(SCE_NP_COMMUNITY_SERVER_ERROR_CONDITIONS_NOT_SATISFIED); - default: fmt::throw_exception("Unexpected error in handle_TusDataStatusResponse: %d", static_cast(error)); + default: fmt::throw_exception("Unexpected error in handle_TusDataStatusResponse: %s", error); } const auto resp = reply.get_protobuf(); @@ -1803,7 +1806,7 @@ namespace np if (!tdata) { trans_ctx->tdata = tdata_tus_get_data{.recvSize = recvSize, .dataStatus = dataStatus, .data = data}; - const u32 req_id = get_req_id(REQUEST_ID_HIGH::SCORE); + const u32 req_id = get_req_id(REQUEST_ID_HIGH::TUS); get_rpcn()->tus_get_data(req_id, trans_ctx->communicationId, targetNpId, slotId, vuser); transaction_async_handler(std::move(lock), trans_ctx, req_id, async); return; @@ -1844,7 +1847,7 @@ namespace np case rpcn::ErrorType::NotFound: return tus_trans->set_result_and_wake(SCE_NP_COMMUNITY_SERVER_ERROR_USER_NOT_ASSIGNED); case rpcn::ErrorType::Unauthorized: return tus_trans->set_result_and_wake(SCE_NP_COMMUNITY_SERVER_ERROR_FORBIDDEN); case rpcn::ErrorType::CondFail: return tus_trans->set_result_and_wake(SCE_NP_COMMUNITY_SERVER_ERROR_CONDITIONS_NOT_SATISFIED); - default: fmt::throw_exception("Unexpected error in reply to TusGetData: %d", static_cast(error)); + default: fmt::throw_exception("Unexpected error in reply to TusGetData: %s", error); } auto pb_data = reply.get_protobuf(); @@ -1870,6 +1873,7 @@ namespace np data_status->data = tdata->data; data_status->dataSize = ::narrow(pb_data->data().size()); data_status->info.infoSize = ::narrow(pb_status.info().size()); + memcpy(data_status->info.data, pb_data->status().info().data(), std::min(pb_data->status().info().size(), sizeof(data_status->info.data))); const u32 to_copy = std::min(data_status->dataSize, tdata->recvSize); memcpy(data, pb_data->data().data(), to_copy); diff --git a/rpcs3/Emu/NP/np_requests_gui.cpp b/rpcs3/Emu/NP/np_requests_gui.cpp index be6026afa6..5e38a57e77 100644 --- a/rpcs3/Emu/NP/np_requests_gui.cpp +++ b/rpcs3/Emu/NP/np_requests_gui.cpp @@ -303,7 +303,11 @@ namespace np gui_cache.del_room(room_status->id); - gui_notifications.list.emplace(std::make_pair(gui_notifications.current_gui_ctx_id, req_id), gui_notification{.event = SCE_NP_MATCHING_EVENT_LEAVE_ROOM_DONE, .edata = std::move(edata)}); + { + std::lock_guard lock(gui_notifications.mutex); + gui_notifications.list.emplace(std::make_pair(gui_notifications.current_gui_ctx_id, req_id), gui_notification{.event = SCE_NP_MATCHING_EVENT_LEAVE_ROOM_DONE, .edata = std::move(edata)}); + } + ctx->queue_callback(req_id, SCE_NP_MATCHING_EVENT_LEAVE_ROOM_DONE, 0); } @@ -453,7 +457,11 @@ namespace np extra_nps::print_SceNpMatchingRoom(room_info); - gui_notifications.list.emplace(std::make_pair(gui_notifications.current_gui_ctx_id, req_id), gui_notification{.event = SCE_NP_MATCHING_EVENT_GET_ROOM_SEARCH_FLAG_DONE, .edata = std::move(edata)}); + { + std::lock_guard lock(gui_notifications.mutex); + gui_notifications.list.emplace(std::make_pair(gui_notifications.current_gui_ctx_id, req_id), gui_notification{.event = SCE_NP_MATCHING_EVENT_GET_ROOM_SEARCH_FLAG_DONE, .edata = std::move(edata)}); + } + ctx->queue_callback(req_id, SCE_NP_MATCHING_EVENT_GET_ROOM_SEARCH_FLAG_DONE, 0); } @@ -548,7 +556,11 @@ namespace np extra_nps::print_SceNpMatchingRoom(room_info); - gui_notifications.list.emplace(std::make_pair(gui_notifications.current_gui_ctx_id, req_id), gui_notification{.event = SCE_NP_MATCHING_EVENT_GET_ROOM_INFO_DONE, .edata = std::move(edata)}); + { + std::lock_guard lock(gui_notifications.mutex); + gui_notifications.list.emplace(std::make_pair(gui_notifications.current_gui_ctx_id, req_id), gui_notification{.event = SCE_NP_MATCHING_EVENT_GET_ROOM_INFO_DONE, .edata = std::move(edata)}); + } + ctx->queue_callback(req_id, SCE_NP_MATCHING_EVENT_GET_ROOM_INFO_DONE, 0); } @@ -581,9 +593,13 @@ namespace np SceNpRoomId room_id{}; ensure(!resp->id().empty() && resp->id().size() == sizeof(SceNpRoomId::opt)); + ctx->wakey = 0; std::memcpy(room_id.opt, resp->id().data(), sizeof(SceNpRoomId::opt)); - const auto [_, inserted] = pending_quickmatching.insert_or_assign(room_id, ctx->ctx_id); - ensure(inserted); + { + std::lock_guard lock(this->mutex_quickmatching); + const auto [_, inserted] = pending_quickmatching.insert_or_assign(room_id, ctx->ctx_id); + ensure(inserted); + } // Now that the reply has been received, we start the wait for the notification ctx->thread = std::make_unique>>("NP GUI Timeout Worker", [ctx, req_id, this](SceNpRoomId room_id) @@ -615,7 +631,6 @@ namespace np } }); - ctx->wakey = 0; auto& thread = *ctx->thread; thread(room_id); } diff --git a/rpcs3/Emu/NP/rpcn_client.cpp b/rpcs3/Emu/NP/rpcn_client.cpp index 86a688705e..56cfabd855 100644 --- a/rpcs3/Emu/NP/rpcn_client.cpp +++ b/rpcs3/Emu/NP/rpcn_client.cpp @@ -1489,7 +1489,7 @@ namespace rpcn if (error == ErrorType::NoError) rpcn_log.success("add_friend(\"%s\") succeeded", friend_username); else - rpcn_log.error("add_friend(\"%s\") failed with error: %s", error); + rpcn_log.error("add_friend(\"%s\") failed with error: %s", friend_username, error); return error; } @@ -3085,7 +3085,7 @@ namespace rpcn } case NotificationType::FriendPresenceChanged: { - const std::string username = vdata.get_string(true); + const std::string username = vdata.get_string(false); SceNpCommunicationId pr_com_id = vdata.get_com_id(); std::string pr_title = fmt::truncate(vdata.get_string(true), SCE_NP_BASIC_PRESENCE_TITLE_SIZE_MAX - 1); std::string pr_status = fmt::truncate(vdata.get_string(true), SCE_NP_BASIC_PRESENCE_EXTENDED_STATUS_SIZE_MAX - 1); diff --git a/rpcs3/Emu/NP/signaling_handler.cpp b/rpcs3/Emu/NP/signaling_handler.cpp index 97a2673e0f..85c9321e28 100644 --- a/rpcs3/Emu/NP/signaling_handler.cpp +++ b/rpcs3/Emu/NP/signaling_handler.cpp @@ -774,6 +774,7 @@ void signaling_handler::send_information_packets(u32 addr, u16 port, const SceNp auto& sent_packet = sig_packet; sent_packet.command = signal_info; + retire_packet(si, signal_info); send_signaling_packet(sent_packet, addr, port); queue_signaling_packet(sent_packet, si, steady_clock::now() + REPEAT_INFO_DELAY); wake_up(); diff --git a/rpcs3/Emu/NP/signaling_handler.h b/rpcs3/Emu/NP/signaling_handler.h index b4ec8229b8..a3eb027fe1 100644 --- a/rpcs3/Emu/NP/signaling_handler.h +++ b/rpcs3/Emu/NP/signaling_handler.h @@ -133,7 +133,7 @@ private: signaling_packet sig_packet{}; - std::map qpackets; // (wakeup time, packet) + std::multimap qpackets; // (wakeup time, packet) u32 cur_conn_id = 1; std::unordered_map npid_to_conn_id; // (npid, conn_id) diff --git a/rpcs3/Emu/NP/upnp_handler.cpp b/rpcs3/Emu/NP/upnp_handler.cpp index dca00de986..c19e30d441 100644 --- a/rpcs3/Emu/NP/upnp_handler.cpp +++ b/rpcs3/Emu/NP/upnp_handler.cpp @@ -89,12 +89,10 @@ void upnp_handler::upnp_enable() if (desc_xml) { - IGDdatas igd_data{}; - UPNPUrls igd_urls{}; - parserootdesc(desc_xml, desc_xml_size, &igd_data); + parserootdesc(desc_xml, desc_xml_size, &m_igd_data); free(desc_xml); desc_xml = nullptr; - GetUPNPUrls(&igd_urls, &igd_data, dev->descURL, 1); + GetUPNPUrls(&m_igd_urls, &m_igd_data, dev->descURL, 1); upnp_log.notice("Found UPnP device type:%s at %s", dev->st, dev->descURL); @@ -116,24 +114,28 @@ void upnp_handler::upnp_enable() freeUPNPDevlist(devlist); } -void upnp_handler::add_port_redir(std::string_view addr, u16 internal_port, std::string_view protocol) +void upnp_handler::add_port_redir(const std::string& addr, u16 internal_port, std::string_view protocol) { if (!m_active) return; std::lock_guard lock(m_mutex); - u16 external_port = internal_port; - std::string internal_port_str = fmt::format("%d", internal_port); + if (m_bindings[std::string(protocol)].contains(internal_port)) + return; + + const std::string internal_port_str = fmt::format("%d", internal_port); + const std::string protocol_str(protocol); + const u32 max_port = std::min(static_cast(internal_port) + 100, 0xFFFFu); int res = 0; - for (u16 external_port = internal_port; external_port < internal_port + 100; external_port++) + for (u32 external_port = internal_port; external_port <= max_port; external_port++) { std::string external_port_str = fmt::format("%d", external_port); - res = UPNP_AddPortMapping(m_igd_urls.controlURL, m_igd_data.first.servicetype, external_port_str.c_str(), internal_port_str.c_str(), addr.data(), "RPCS3", protocol.data(), nullptr, nullptr); + res = UPNP_AddPortMapping(m_igd_urls.controlURL, m_igd_data.first.servicetype, external_port_str.c_str(), internal_port_str.c_str(), addr.c_str(), "RPCS3", protocol_str.c_str(), nullptr, nullptr); if (res == UPNPCOMMAND_SUCCESS) { - m_bindings[std::string(protocol)][internal_port] = external_port; + m_bindings[protocol_str][static_cast(internal_port)] = external_port; upnp_log.notice("Successfully bound %s:%d(%s) to IGD:%d", addr, internal_port, protocol, external_port); return; } @@ -146,7 +148,7 @@ void upnp_handler::add_port_redir(std::string_view addr, u16 internal_port, std: // } } - upnp_log.error("Failed to bind %s:%d(%s) to IGD:(%d=>%d): %d", addr, internal_port, protocol, internal_port, external_port, res); + upnp_log.error("Failed to bind %s:%d(%s) to IGD:(%d=>%d): %d", addr, internal_port, protocol, internal_port, internal_port, res); } void upnp_handler::remove_port_redir(u16 internal_port, std::string_view protocol) @@ -156,27 +158,28 @@ void upnp_handler::remove_port_redir(u16 internal_port, std::string_view protoco std::lock_guard lock(m_mutex); - const std::string str_protocol(protocol); + const std::string protocol_str(protocol); - if (!m_bindings.contains(str_protocol) || !::at32(m_bindings, str_protocol).contains(internal_port)) + if (!m_bindings.contains(protocol_str) || !::at32(m_bindings, protocol_str).contains(internal_port)) { upnp_log.error("tried to unbind port mapping %d to IGD(%s) but it isn't bound", internal_port, protocol); return; } - const u16 external_port = ::at32(::at32(m_bindings, str_protocol), internal_port); + const u16 external_port = ::at32(::at32(m_bindings, protocol_str), internal_port); remove_port_redir_external(external_port, protocol); - ensure(::at32(m_bindings, str_protocol).erase(internal_port)); + ensure(::at32(m_bindings, protocol_str).erase(internal_port)); upnp_log.notice("Successfully deleted port mapping %d to IGD:%d(%s)", internal_port, external_port, protocol); } void upnp_handler::remove_port_redir_external(u16 external_port, std::string_view protocol, bool verbose) { const std::string str_ext_port = fmt::format("%d", external_port); + const std::string protocol_str(protocol); - if (int res = UPNP_DeletePortMapping(m_igd_urls.controlURL, m_igd_data.first.servicetype, str_ext_port.c_str(), protocol.data(), nullptr); res != 0 && verbose) + if (int res = UPNP_DeletePortMapping(m_igd_urls.controlURL, m_igd_data.first.servicetype, str_ext_port.c_str(), protocol_str.c_str(), nullptr); res != 0 && verbose) upnp_log.error("Failed to delete port mapping IGD:%s(%s): %d", str_ext_port, protocol, res); } diff --git a/rpcs3/Emu/NP/upnp_handler.h b/rpcs3/Emu/NP/upnp_handler.h index 40892f7443..1486702cbb 100644 --- a/rpcs3/Emu/NP/upnp_handler.h +++ b/rpcs3/Emu/NP/upnp_handler.h @@ -13,7 +13,7 @@ public: ~upnp_handler(); void upnp_enable(); - void add_port_redir(std::string_view addr, u16 internal_port, std::string_view protocol); + void add_port_redir(const std::string& addr, u16 internal_port, std::string_view protocol); void remove_port_redir(u16 internal_port, std::string_view protocol); bool is_active() const; From 00a1c7278a90d85e5b2e1eb551b9ff80d858b21c Mon Sep 17 00:00:00 2001 From: Ani Date: Sun, 22 Feb 2026 16:30:34 +0100 Subject: [PATCH 078/175] config/ux: Disable double-click to fullscreen by default The state of mouse/keyboard on rpcs3 has matured enough to the point where using mouse on rpcs3 to play games is normal. Other games do not fullscreen on double-click, our default should match the expected application behaviour. --- rpcs3/rpcs3qt/gui_settings.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpcs3/rpcs3qt/gui_settings.h b/rpcs3/rpcs3qt/gui_settings.h index a3b6fb4286..21a46259c2 100644 --- a/rpcs3/rpcs3qt/gui_settings.h +++ b/rpcs3/rpcs3qt/gui_settings.h @@ -256,7 +256,7 @@ namespace gui const gui_save m_discordState = gui_save(meta, "discordState", ""); const gui_save m_check_upd_start = gui_save(meta, "checkUpdateStart", update_on); - const gui_save gs_disableMouse = gui_save(gs_frame, "disableMouse", false); + const gui_save gs_disableMouse = gui_save(gs_frame, "disableMouse", true); const gui_save gs_disableKbHotkeys = gui_save(gs_frame, "disableKbHotkeys", false); const gui_save gs_showMouseFs = gui_save(gs_frame, "showMouseInFullscreen", false); const gui_save gs_lockMouseFs = gui_save(gs_frame, "lockMouseInFullscreen", true); From 928856567670d123b88b458f450bae0051deecb7 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Sun, 1 Mar 2026 22:06:01 +0100 Subject: [PATCH 079/175] Qt: properly handle cancel of pkg install dialog --- rpcs3/rpcs3qt/main_window.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/rpcs3/rpcs3qt/main_window.cpp b/rpcs3/rpcs3qt/main_window.cpp index 56e125ab11..687358d625 100644 --- a/rpcs3/rpcs3qt/main_window.cpp +++ b/rpcs3/rpcs3qt/main_window.cpp @@ -938,13 +938,20 @@ bool main_window::HandlePackageInstallation(QStringList file_paths, bool from_bo bool precompile_caches = false; bool create_desktop_shortcuts = false; bool create_app_shortcut = false; + bool canceled = false; game_compatibility* compat = m_game_list_frame ? m_game_list_frame->GetGameCompatibility() : nullptr; // Let the user choose the packages to install and select the order in which they shall be installed. pkg_install_dialog dlg(file_paths, compat, this); - connect(&dlg, &QDialog::accepted, this, [&]() + connect(&dlg, &QDialog::finished, this, [&](int result) { + if (result != QDialog::Accepted) + { + canceled = true; + return; + } + packages = dlg.get_paths_to_install(); precompile_caches = dlg.precompile_caches(); create_desktop_shortcuts = dlg.create_desktop_shortcuts(); @@ -952,6 +959,11 @@ bool main_window::HandlePackageInstallation(QStringList file_paths, bool from_bo }); dlg.exec(); + if (canceled) + { + return false; + } + if (!from_boot) { if (!m_gui_settings->GetBootConfirmation(this)) From 595e42c4f3bfa11b8585ea029e1aa9d2c9c68fd1 Mon Sep 17 00:00:00 2001 From: AniLeo Date: Sun, 1 Mar 2026 12:33:42 +0100 Subject: [PATCH 080/175] rpcs3_version: Bump to 0.0.40 --- rpcs3/rpcs3_version.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpcs3/rpcs3_version.cpp b/rpcs3/rpcs3_version.cpp index 19d107e582..6eb904222f 100644 --- a/rpcs3/rpcs3_version.cpp +++ b/rpcs3/rpcs3_version.cpp @@ -26,7 +26,7 @@ namespace rpcs3 const utils::version& get_version() { - static constexpr utils::version version{ 0, 0, 39, utils::version_type::alpha, 1, RPCS3_GIT_VERSION }; + static constexpr utils::version version{ 0, 0, 40, utils::version_type::alpha, 1, RPCS3_GIT_VERSION }; return version; } From e66f1fa3066f99d816fb950aad77d6fc57d0f1c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20D=C3=ADaz=20=C3=81lvarez?= Date: Tue, 3 Mar 2026 21:41:51 +0100 Subject: [PATCH 081/175] Solves render problems due to vertex data being modified before reuse * Stores first 64bit of the vertex data to compare on retrieval as a fingerprint of if the underlying vertex data has been changed --- rpcs3/Emu/RSX/rsx_cache.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/rpcs3/Emu/RSX/rsx_cache.h b/rpcs3/Emu/RSX/rsx_cache.h index b219745f6a..c73e3c2d11 100644 --- a/rpcs3/Emu/RSX/rsx_cache.h +++ b/rpcs3/Emu/RSX/rsx_cache.h @@ -7,6 +7,7 @@ #include "Common/unordered_map.hpp" #include "Emu/System.h" #include "Emu/cache_utils.hpp" +#include "Emu/Memory/vm.h" #include "Emu/RSX/Program/RSXVertexProgram.h" #include "Emu/RSX/Program/RSXFragmentProgram.h" #include "Overlays/Shaders/shader_loading_dialog.h" @@ -478,6 +479,7 @@ namespace rsx uptr local_address; u32 offset_in_heap; u32 data_length; + u64 fingerprint; }; // A weak vertex cache with no data checks or memory range locks @@ -502,11 +504,19 @@ namespace rsx { const auto key = hash(local_addr, data_length); const auto found = vertex_ranges.find(key); + if (found == vertex_ranges.end()) { return nullptr; } + // Check if data in local_address changed vs what was stored in the vertex_cache + if (auto sudo_ptr = vm::get_super_ptr(local_addr); + data_length >= 8 && found->second.fingerprint != *utils::bless(sudo_ptr)) + { + vertex_ranges.erase(key); + return nullptr; + } return std::addressof(found->second); } @@ -516,7 +526,15 @@ namespace rsx v.data_length = data_length; v.local_address = local_addr; v.offset_in_heap = offset_in_heap; + v.fingerprint = 0; + if (data_length >= 8) + { + // Uses get_super_ptr to access vm memory safely + // and bless to avoid endian conversion and circumvent compiler strict aliasing rules. + auto sudo_ptr = vm::get_super_ptr(local_addr); + v.fingerprint = *utils::bless(sudo_ptr); + } const auto key = hash(local_addr, data_length); vertex_ranges[key] = v; } From 11a9011510e8b6c256a86f057764c929afd99a5b Mon Sep 17 00:00:00 2001 From: kd-11 Date: Wed, 4 Mar 2026 02:54:42 +0300 Subject: [PATCH 082/175] rsx: Fix memory misalignment for temporary storage - We create the temp storage with alignment of U but then do a type cast to u128 later. This obviously causes problems. --- rpcs3/Emu/RSX/Common/TextureUtils.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpcs3/Emu/RSX/Common/TextureUtils.cpp b/rpcs3/Emu/RSX/Common/TextureUtils.cpp index 937508035b..8cf3466bb9 100644 --- a/rpcs3/Emu/RSX/Common/TextureUtils.cpp +++ b/rpcs3/Emu/RSX/Common/TextureUtils.cpp @@ -244,7 +244,7 @@ struct copy_unmodified_block_swizzled } const u32 size_in_block = padded_width * padded_height * depth * 2; - rsx::simple_array tmp(size_in_block * words_per_block); + rsx::simple_array tmp(size_in_block * words_per_block); if (words_per_block == 1) [[likely]] { From 86b2773c2854ede00ff376d1ee82898c74eb8b71 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Wed, 4 Mar 2026 02:56:12 +0300 Subject: [PATCH 083/175] rsx: Clean up after vertex cache changes --- rpcs3/Emu/RSX/rsx_cache.h | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/rpcs3/Emu/RSX/rsx_cache.h b/rpcs3/Emu/RSX/rsx_cache.h index c73e3c2d11..625311fc11 100644 --- a/rpcs3/Emu/RSX/rsx_cache.h +++ b/rpcs3/Emu/RSX/rsx_cache.h @@ -517,6 +517,7 @@ namespace rsx vertex_ranges.erase(key); return nullptr; } + return std::addressof(found->second); } @@ -526,15 +527,12 @@ namespace rsx v.data_length = data_length; v.local_address = local_addr; v.offset_in_heap = offset_in_heap; - v.fingerprint = 0; - if (data_length >= 8) + if (auto sudo_ptr = vm::get_super_ptr(local_addr); data_length >= 8) { - // Uses get_super_ptr to access vm memory safely - // and bless to avoid endian conversion and circumvent compiler strict aliasing rules. - auto sudo_ptr = vm::get_super_ptr(local_addr); v.fingerprint = *utils::bless(sudo_ptr); } + const auto key = hash(local_addr, data_length); vertex_ranges[key] = v; } From 3750fb2c1f1ff5ccd4996ef42cdf8b16119666c3 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Wed, 4 Mar 2026 08:37:26 +0100 Subject: [PATCH 084/175] cellGem: Fix deadlock when cellGemUpdateStart is called before cellCamera delivers images --- rpcs3/Emu/Cell/Modules/cellGem.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/cellGem.cpp b/rpcs3/Emu/Cell/Modules/cellGem.cpp index 3c7b299af7..1a1e8a7d04 100644 --- a/rpcs3/Emu/Cell/Modules/cellGem.cpp +++ b/rpcs3/Emu/Cell/Modules/cellGem.cpp @@ -1616,6 +1616,7 @@ public: } m_tracker.set_image_data(m_camera_info.buffer.get_ptr(), m_camera_info.bytesize, m_camera_info.width, m_camera_info.height, m_camera_info.format); + m_framenumber++; // using framenumber instead of timestamp since the timestamp could be identical return true; } @@ -1648,6 +1649,7 @@ public: } auto& gem = g_fxo->get(); + u64 last_framenumber = 0; while (thread_ctrl::state() != thread_state::aborting) { @@ -1663,6 +1665,13 @@ public: } } + if (std::exchange(last_framenumber, m_framenumber.load()) == last_framenumber) + { + cellGem.warning("Tracker woke up without new frame. Skipping processing (framenumber=%d)", last_framenumber); + tracker_done(); + continue; + } + m_busy.release(true); // Update PS Move LED colors @@ -1754,6 +1763,7 @@ public: private: atomic_t m_wake_up_tracker = 0; atomic_t m_tracker_done = 0; + atomic_t m_framenumber = 0; atomic_t m_busy = false; ps_move_tracker m_tracker{}; CellCameraInfoEx m_camera_info{}; @@ -3876,13 +3886,15 @@ error_code cellGemUpdateStart(vm::cptr camera_frame, u64 timestamp) gem.camera_frame = camera_frame.addr(); - if (!tracker.set_image(gem.camera_frame)) + const bool image_set = tracker.set_image(gem.camera_frame); + + tracker.wake_up_tracker(); + + if (!image_set) { return not_an_error(CELL_GEM_NO_VIDEO); } - tracker.wake_up_tracker(); - return CELL_OK; } From d46ddcee5d8db68d7f856c5e7015bffc651b419f Mon Sep 17 00:00:00 2001 From: RipleyTom Date: Wed, 4 Mar 2026 01:29:10 +0100 Subject: [PATCH 085/175] Fix mac build --- .ci/build-mac.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/build-mac.sh b/.ci/build-mac.sh index 2f43e05e74..300f69cb06 100755 --- a/.ci/build-mac.sh +++ b/.ci/build-mac.sh @@ -17,7 +17,7 @@ brew install -f --overwrite --quiet ccache "llvm@$LLVM_COMPILER_VER" brew link -f --overwrite --quiet "llvm@$LLVM_COMPILER_VER" if [ "$AARCH64" -eq 1 ]; then brew install -f --overwrite --quiet googletest opencv@4 sdl3 vulkan-headers vulkan-loader molten-vk - brew unlink --quiet ffmpeg fmt qtbase qtsvg qtdeclarative protobuf + brew unlink --quiet ffmpeg fmt qtbase qtsvg qtdeclarative else arch -x86_64 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" arch -x86_64 /usr/local/bin/brew install -f --overwrite --quiet python@3.14 opencv@4 "llvm@$LLVM_COMPILER_VER" sdl3 vulkan-headers vulkan-loader molten-vk From 5605cf21413be189ca8e2ab866c3ad537b5e79ca Mon Sep 17 00:00:00 2001 From: Megamouse Date: Thu, 5 Mar 2026 15:32:14 +0100 Subject: [PATCH 086/175] Qt: Do not check return code of rpcs3 download --- rpcs3/rpcs3qt/downloader.cpp | 4 ++-- rpcs3/rpcs3qt/downloader.h | 2 +- rpcs3/rpcs3qt/game_compatibility.cpp | 14 +++++++------- rpcs3/rpcs3qt/game_compatibility.h | 2 +- rpcs3/rpcs3qt/patch_manager_dialog.cpp | 2 +- rpcs3/rpcs3qt/update_manager.cpp | 4 ++-- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/rpcs3/rpcs3qt/downloader.cpp b/rpcs3/rpcs3qt/downloader.cpp index 39078c880d..65f481bff8 100644 --- a/rpcs3/rpcs3qt/downloader.cpp +++ b/rpcs3/rpcs3qt/downloader.cpp @@ -34,7 +34,7 @@ downloader::~downloader() } } -void downloader::start(const std::string& url, bool follow_location, bool show_progress_dialog, const QString& progress_dialog_title, bool keep_progress_dialog_open, int expected_size, bool check_return_code, bool again) +void downloader::start(const std::string& url, bool follow_location, bool show_progress_dialog, bool check_return_code, const QString& progress_dialog_title, bool keep_progress_dialog_open, int expected_size, bool again) { network_log.notice("Starting download from URL: %s", url); @@ -121,7 +121,7 @@ void downloader::start(const std::string& url, bool follow_location, bool show_p { network_log.error("Error during download. Trying to download again (attempts=%d, return_code=%d)", m_download_attempts, return_code); std::this_thread::sleep_for(500ms); // Wait for a little while - start(url, follow_location, show_progress_dialog, progress_dialog_title, keep_progress_dialog_open, expected_size, check_return_code, true); + start(url, follow_location, show_progress_dialog, check_return_code, progress_dialog_title, keep_progress_dialog_open, expected_size, true); return; } } diff --git a/rpcs3/rpcs3qt/downloader.h b/rpcs3/rpcs3qt/downloader.h index be0cd0e568..35c2d5533e 100644 --- a/rpcs3/rpcs3qt/downloader.h +++ b/rpcs3/rpcs3qt/downloader.h @@ -21,7 +21,7 @@ public: explicit downloader(QWidget* parent = nullptr); ~downloader(); - void start(const std::string& url, bool follow_location, bool show_progress_dialog, const QString& progress_dialog_title = "", bool keep_progress_dialog_open = false, int expected_size = -1, bool check_return_code = true, bool again = false); + void start(const std::string& url, bool follow_location, bool show_progress_dialog, bool check_return_code, const QString& progress_dialog_title = "", bool keep_progress_dialog_open = false, int expected_size = -1, bool again = false); usz update_buffer(char* data, usz size); void update_progress_dialog(const QString& title) const; diff --git a/rpcs3/rpcs3qt/game_compatibility.cpp b/rpcs3/rpcs3qt/game_compatibility.cpp index b9cb32a7c1..a7a4a4bc34 100644 --- a/rpcs3/rpcs3qt/game_compatibility.cpp +++ b/rpcs3/rpcs3qt/game_compatibility.cpp @@ -36,7 +36,7 @@ void game_compatibility::handle_download_finished(const QByteArray& content) compat_log.notice("Database download finished"); // Create new map from database and write database to file if database was valid - if (ReadJSON(QJsonDocument::fromJson(content).object(), true)) + if (handle_json(content, true)) { // Write database to file QFile file(m_filepath); @@ -67,8 +67,9 @@ void game_compatibility::handle_download_canceled() Q_EMIT DownloadCanceled(); } -bool game_compatibility::ReadJSON(const QJsonObject& json_data, bool after_download) +bool game_compatibility::handle_json(const QByteArray& data, bool after_download) { + const QJsonObject json_data = QJsonDocument::fromJson(data).object(); const int return_code = json_data["return_code"].toInt(-255); if (return_code < 0) @@ -101,7 +102,7 @@ bool game_compatibility::ReadJSON(const QJsonObject& json_data, bool after_downl m_compat_database.clear(); - QJsonObject json_results = json_data["results"].toObject(); + const QJsonObject json_results = json_data["results"].toObject(); // Retrieve status data for every valid entry for (const auto& key : json_results.keys()) @@ -112,7 +113,7 @@ bool game_compatibility::ReadJSON(const QJsonObject& json_data, bool after_downl continue; } - QJsonObject json_result = json_results[key].toObject(); + const QJsonObject json_result = json_results[key].toObject(); // Retrieve compatibility information from json compat::status status = ::at32(Status_Data, json_result.value("status").toString("NoResult")); @@ -210,15 +211,14 @@ void game_compatibility::RequestCompatibility(bool online) compat_log.notice("Finished reading database from file: %s", m_filepath); // Create new map from database - ReadJSON(QJsonDocument::fromJson(content).object(), online); - + handle_json(content, online); return; } const std::string url = "https://rpcs3.net/compatibility?api=v1&export"; compat_log.notice("Beginning compatibility database download from: %s", url); - m_downloader->start(url, true, true, tr("Downloading Database")); + m_downloader->start(url, true, true, true, tr("Downloading Database")); // We want to retrieve a new database, therefore refresh gamelist and indicate that Q_EMIT DownloadStarted(); diff --git a/rpcs3/rpcs3qt/game_compatibility.h b/rpcs3/rpcs3qt/game_compatibility.h index 664bafea34..8dc1ce5aa5 100644 --- a/rpcs3/rpcs3qt/game_compatibility.h +++ b/rpcs3/rpcs3qt/game_compatibility.h @@ -138,7 +138,7 @@ private: std::map m_compat_database; /** Creates new map from the database */ - bool ReadJSON(const QJsonObject& json_data, bool after_download); + bool handle_json(const QByteArray& data, bool after_download); public: /** Handles reads, writes and downloads for the compatibility database */ diff --git a/rpcs3/rpcs3qt/patch_manager_dialog.cpp b/rpcs3/rpcs3qt/patch_manager_dialog.cpp index a41d8ed7b5..2e9d980d20 100644 --- a/rpcs3/rpcs3qt/patch_manager_dialog.cpp +++ b/rpcs3/rpcs3qt/patch_manager_dialog.cpp @@ -1163,7 +1163,7 @@ void patch_manager_dialog::download_update(bool automatic, bool auto_accept) } } - m_downloader->start(url, true, !m_download_automatic, tr("Downloading latest patches")); + m_downloader->start(url, true, !m_download_automatic, true, tr("Downloading latest patches")); } bool patch_manager_dialog::handle_json(const QByteArray& data) diff --git a/rpcs3/rpcs3qt/update_manager.cpp b/rpcs3/rpcs3qt/update_manager.cpp index ec4d7ce44f..d32a1810b9 100644 --- a/rpcs3/rpcs3qt/update_manager.cpp +++ b/rpcs3/rpcs3qt/update_manager.cpp @@ -110,7 +110,7 @@ void update_manager::check_for_updates(bool automatic, bool check_only, bool aut const std::string url = fmt::format("https://update.rpcs3.net/?api=v3&c=%s&os_type=%s&os_arch=%s&os_version=%i.%i.%i", rpcs3::get_commit_and_hash().second, os.type, os.arch, os.version_major, os.version_minor, os.version_patch); - m_downloader->start(url, true, !automatic, tr("Checking For Updates"), true); + m_downloader->start(url, true, !automatic, true, tr("Checking For Updates"), true); } bool update_manager::handle_json(bool automatic, bool check_only, bool auto_accept, const QByteArray& data) @@ -440,7 +440,7 @@ void update_manager::update(bool auto_accept) }); update_log.notice("Downloading update..."); - m_downloader->start(m_request_url, true, true, tr("Downloading Update"), true, m_expected_size); + m_downloader->start(m_request_url, true, true, false, tr("Downloading Update"), true, m_expected_size); } bool update_manager::handle_rpcs3(const QByteArray& data, bool auto_accept) From ae6172d86bc79a63af0533c870e13d6702ad2343 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Sun, 1 Mar 2026 11:39:52 +0100 Subject: [PATCH 087/175] Remove unused function --- rpcs3/Emu/Io/LogitechG27.cpp | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/rpcs3/Emu/Io/LogitechG27.cpp b/rpcs3/Emu/Io/LogitechG27.cpp index 1f02c92d59..7ae996c864 100644 --- a/rpcs3/Emu/Io/LogitechG27.cpp +++ b/rpcs3/Emu/Io/LogitechG27.cpp @@ -945,17 +945,6 @@ static u8 sdl_to_logitech_g27_pedal(std::map>& j return unsigned_avg * 0xFF / 0xFFFF; } -static inline void set_bit(u8* buf, int bit_num, bool set) -{ - const int byte_num = bit_num / 8; - bit_num %= 8; - const u8 mask = 1 << bit_num; - if (set) - buf[byte_num] = buf[byte_num] | mask; - else - buf[byte_num] = buf[byte_num] & (~mask); -} - void usb_device_logitech_g27::transfer_dfex(u32 buf_size, u8* buf, UsbTransfer* transfer) { DFEX_data data{}; From ec00a06cafceb5849633f4c5f501e975d0f4cc24 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Sun, 1 Mar 2026 11:41:22 +0100 Subject: [PATCH 088/175] Fix warning suppression in windows clang --- Utilities/StrFmt.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Utilities/StrFmt.cpp b/Utilities/StrFmt.cpp index 4431769f3a..d68ef51cb5 100644 --- a/Utilities/StrFmt.cpp +++ b/Utilities/StrFmt.cpp @@ -16,12 +16,12 @@ #include #endif -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable : 4996) -#elif defined(__clang__) +#ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" +#elif defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable : 4996) #else #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" From f2c8b157ef048f57570861d305d2fa8ead03fc92 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Sun, 1 Mar 2026 11:41:56 +0100 Subject: [PATCH 089/175] ISO: pass mode to file --- rpcs3/Loader/ISO.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpcs3/Loader/ISO.cpp b/rpcs3/Loader/ISO.cpp index e46a1a6b82..af2d18ff7d 100644 --- a/rpcs3/Loader/ISO.cpp +++ b/rpcs3/Loader/ISO.cpp @@ -569,7 +569,7 @@ std::unique_ptr iso_device::open(const std::string& path, bs_t(fs::file(iso_path), *node); + return std::make_unique(fs::file(iso_path, mode), *node); } std::unique_ptr iso_device::open_dir(const std::string& path) From 2a292d1e2e4541162a1b85efa28500f6de2c9b98 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Sun, 1 Mar 2026 11:42:29 +0100 Subject: [PATCH 090/175] rsx: fix unused parameter warning --- rpcs3/Emu/RSX/NV47/HW/nv4097.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpcs3/Emu/RSX/NV47/HW/nv4097.cpp b/rpcs3/Emu/RSX/NV47/HW/nv4097.cpp index 17ee040f8c..43c8a5d9f4 100644 --- a/rpcs3/Emu/RSX/NV47/HW/nv4097.cpp +++ b/rpcs3/Emu/RSX/NV47/HW/nv4097.cpp @@ -306,7 +306,7 @@ namespace rsx REGS(ctx)->decode(reg, REGS(ctx)->latch); } - void set_aa_control(context* ctx, u32 reg, u32 arg) + void set_aa_control(context* ctx, u32 /*reg*/, u32 arg) { const auto latch = REGS(ctx)->latch; if (arg == latch) From c57d6110c4c503e8145c9d18e38042d275cd6995 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Sun, 1 Mar 2026 11:42:51 +0100 Subject: [PATCH 091/175] rsx: add missing default to switch --- rpcs3/Emu/RSX/Program/ProgramStateCache.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rpcs3/Emu/RSX/Program/ProgramStateCache.cpp b/rpcs3/Emu/RSX/Program/ProgramStateCache.cpp index 4420e51555..528b5c6316 100644 --- a/rpcs3/Emu/RSX/Program/ProgramStateCache.cpp +++ b/rpcs3/Emu/RSX/Program/ProgramStateCache.cpp @@ -675,6 +675,8 @@ fragment_program_utils::fragment_program_metadata fragment_program_utils::analys // Otherwise we would need to follow the execution chain result.has_branch_instructions = true; break; + default: + break; } if (rsx::assembler::FP::get_operand_count(opcode) > 0 && From 2f9f79eea2673aaafb5ff91e4d294777906d629b Mon Sep 17 00:00:00 2001 From: RipleyTom Date: Fri, 6 Mar 2026 08:06:29 +0100 Subject: [PATCH 092/175] PPU Fixes -CallFunction empty function/jump elision was never gone through as cond was always false -MSelf duplicate offset detection never triggered because set was reset each loop -Rel executable memory size calculation used wrong section type --- rpcs3/Emu/Cell/PPUModule.cpp | 6 +++--- rpcs3/Emu/Cell/PPUThread.cpp | 4 ++-- rpcs3/Emu/Cell/PPUTranslator.cpp | 5 ++--- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/rpcs3/Emu/Cell/PPUModule.cpp b/rpcs3/Emu/Cell/PPUModule.cpp index b298539519..e95a1542d8 100644 --- a/rpcs3/Emu/Cell/PPUModule.cpp +++ b/rpcs3/Emu/Cell/PPUModule.cpp @@ -1004,7 +1004,7 @@ static import_result_t ppu_load_imports(const ppu_module& _module, std: // Check address // TODO: The address of use should be extracted from analyser instead - if (fstub && fstub >= _module.segs[0].addr && fstub <= _module.segs[0].addr + _module.segs[0].size) + if (fstub && fstub >= _module.segs[0].addr && fstub < _module.segs[0].addr + _module.segs[0].size) { nid_to_use_addr.emplace(fnid, fstub); } @@ -1895,7 +1895,7 @@ shared_ptr ppu_load_prx(const ppu_prx_object& elf, bool virtual_load, c } else { - ppu_loader.error("Library %s: PRX library info not found"); + ppu_loader.error("Library: PRX library info not found"); } prx->start.set(prx->specials[0xbc9a0086]); @@ -3192,7 +3192,7 @@ bool ppu_load_rel_exec(const ppu_rel_object& elf) for (const auto& s : elf.shdrs) { - if (s.sh_type != sec_type::sht_progbits) + if (s.sh_type == sec_type::sht_progbits) { memsize = utils::align(memsize + vm::cast(s.sh_size), 128); } diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index a9bef5e640..4d690b344d 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -3867,12 +3867,12 @@ extern void ppu_precompile(std::vector& dir_queue, std::vector offs; + for (u32 j = 0; j < hdr.count; j++) { mself_record rec{}; - std::set offs; - if (mself.read(rec) && rec.get_pos(mself.size())) { if (rec.size <= 0x20) diff --git a/rpcs3/Emu/Cell/PPUTranslator.cpp b/rpcs3/Emu/Cell/PPUTranslator.cpp index 70d34aa775..1c9f6e2b9d 100644 --- a/rpcs3/Emu/Cell/PPUTranslator.cpp +++ b/rpcs3/Emu/Cell/PPUTranslator.cpp @@ -550,11 +550,10 @@ void PPUTranslator::CallFunction(u64 target, Value* indirect) else if (_target >= caddr && _target <= cend) { u32 target_last = static_cast(_target); - std::unordered_set passed_targets{target_last}; // Try to follow unconditional branches as long as there is no infinite loop - while (target_last != _target) + while (true) { const ppu_opcode_t op{*ensure(m_info.get_ptr(target_last))}; const ppu_itype::type itype = g_ppu_itype.decode(op.opcode); @@ -1304,7 +1303,7 @@ void PPUTranslator::VMADDFP(ppu_opcode_t op) if (!m_use_fma && data == v128{}) { set_vr(op.vd, vec_handle_result(a * c + fsplat(0.f))); - ppu_log.notice("LLVM: VMADDFP with -0 addend at [0x%08x]", m_addr + (m_reloc ? m_reloc->addr : 0)); + ppu_log.notice("LLVM: VMADDFP with +0 addend at [0x%08x]", m_addr + (m_reloc ? m_reloc->addr : 0)); return; } } From cf5eb22591f9443eb97c0537eeaf588801afd3f6 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Thu, 5 Mar 2026 02:33:25 +0300 Subject: [PATCH 093/175] glutils: Extend buffer_object interface --- rpcs3/Emu/RSX/GL/glutils/buffer_object.cpp | 5 +++++ rpcs3/Emu/RSX/GL/glutils/buffer_object.h | 7 ++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/rpcs3/Emu/RSX/GL/glutils/buffer_object.cpp b/rpcs3/Emu/RSX/GL/glutils/buffer_object.cpp index 5c1f0d0447..f3849718d0 100644 --- a/rpcs3/Emu/RSX/GL/glutils/buffer_object.cpp +++ b/rpcs3/Emu/RSX/GL/glutils/buffer_object.cpp @@ -131,6 +131,11 @@ namespace gl DSA_CALL2(NamedBufferSubData, m_id, offset, length, data); } + void buffer::fill(GLsizeiptr offset, GLsizeiptr length, GLuint pattern) + { + DSA_CALL2(ClearNamedBufferSubData, m_id, GL_R32UI, offset, length, GL_RED, GL_UNSIGNED_INT, &pattern); + } + GLubyte* buffer::map(GLsizeiptr offset, GLsizeiptr length, access access_) { ensure(m_memory_type == memory_type::host_visible); diff --git a/rpcs3/Emu/RSX/GL/glutils/buffer_object.h b/rpcs3/Emu/RSX/GL/glutils/buffer_object.h index dccb2a314e..28730bdd0d 100644 --- a/rpcs3/Emu/RSX/GL/glutils/buffer_object.h +++ b/rpcs3/Emu/RSX/GL/glutils/buffer_object.h @@ -15,7 +15,9 @@ namespace gl element_array = GL_ELEMENT_ARRAY_BUFFER, uniform = GL_UNIFORM_BUFFER, texture = GL_TEXTURE_BUFFER, - ssbo = GL_SHADER_STORAGE_BUFFER + ssbo = GL_SHADER_STORAGE_BUFFER, + copy_src = GL_COPY_READ_BUFFER, + copy_dst = GL_COPY_WRITE_BUFFER }; enum class access @@ -65,6 +67,8 @@ namespace gl case target::uniform: pname = GL_UNIFORM_BUFFER_BINDING; break; case target::texture: pname = GL_TEXTURE_BUFFER_BINDING; break; case target::ssbo: pname = GL_SHADER_STORAGE_BUFFER_BINDING; break; + case target::copy_src: pname = GL_COPY_READ_BUFFER_BINDING; break; + case target::copy_dst: pname = GL_COPY_WRITE_BUFFER_BINDING; break; default: fmt::throw_exception("Invalid binding state target (0x%x)", static_cast(target_)); } @@ -113,6 +117,7 @@ namespace gl void data(GLsizeiptr size, const void* data_ = nullptr, GLenum usage = GL_STREAM_DRAW); void sub_data(GLsizeiptr offset, GLsizeiptr length, const GLvoid* data); + void fill(GLsizeiptr offset, GLsizeiptr length, GLuint pattern); GLubyte* map(GLsizeiptr offset, GLsizeiptr length, access access_); void unmap(); From a1af15b907a27bc12c6459801cf3d3514f39fb42 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Thu, 5 Mar 2026 02:33:47 +0300 Subject: [PATCH 094/175] gl/dma: Fix range calculation when creating DMA blocks --- rpcs3/Emu/RSX/GL/GLDMA.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rpcs3/Emu/RSX/GL/GLDMA.cpp b/rpcs3/Emu/RSX/GL/GLDMA.cpp index 3c12009f67..5e60525a5c 100644 --- a/rpcs3/Emu/RSX/GL/GLDMA.cpp +++ b/rpcs3/Emu/RSX/GL/GLDMA.cpp @@ -22,7 +22,7 @@ namespace gl void* userptr = vm::get_super_ptr(base_address); m_data = std::make_unique(); - m_data->create(buffer::target::array, block_size, userptr, buffer::memory_type::userptr, 0); + m_data->create(buffer::target::copy_dst, block_size, userptr, buffer::memory_type::userptr, 0); m_base_address = base_address; // Some drivers may reject userptr input for whatever reason. Check that the state is still valid. @@ -77,7 +77,7 @@ namespace gl { const auto start_block_address = start & s_dma_block_mask; const auto end_block_address = (start + length + s_dma_block_size - 1) & s_dma_block_mask; - return utils::address_range32::start_end(start_block_address, end_block_address); + return utils::address_range32::start_length(start_block_address, end_block_address - start_block_address); } const dma_block& get_block(u32 start, u32 length) From d75e8b24f7f4726656c77467110273588d99fa4e Mon Sep 17 00:00:00 2001 From: kd-11 Date: Thu, 5 Mar 2026 02:34:04 +0300 Subject: [PATCH 095/175] [FIXUP] API extend --- rpcs3/Emu/RSX/GL/GLProcTable.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rpcs3/Emu/RSX/GL/GLProcTable.h b/rpcs3/Emu/RSX/GL/GLProcTable.h index 8f42995a9d..5278014b5c 100644 --- a/rpcs3/Emu/RSX/GL/GLProcTable.h +++ b/rpcs3/Emu/RSX/GL/GLProcTable.h @@ -218,6 +218,9 @@ OPENGL_PROC(PFNGLNAMEDBUFFERDATAEXTPROC, NamedBufferDataEXT); OPENGL_PROC(PFNGLNAMEDBUFFERSUBDATAPROC, NamedBufferSubData); OPENGL_PROC(PFNGLNAMEDBUFFERSUBDATAEXTPROC, NamedBufferSubDataEXT); +OPENGL_PROC(PFNGLCLEARNAMEDBUFFERSUBDATAPROC, ClearNamedBufferSubData); +OPENGL_PROC(PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC, ClearNamedBufferSubDataEXT); + // ARB_shader_image_load_store OPENGL_PROC(PFNGLBINDIMAGETEXTUREPROC, BindImageTexture); From 92f63ccc0b09aa90cf5d16a5b73a62a9568988bc Mon Sep 17 00:00:00 2001 From: kd-11 Date: Fri, 6 Mar 2026 02:19:25 +0300 Subject: [PATCH 096/175] rsx/cfg: Silence GCC noise --- .../Program/Assembler/Passes/FP/RegisterAnnotationPass.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rpcs3/Emu/RSX/Program/Assembler/Passes/FP/RegisterAnnotationPass.cpp b/rpcs3/Emu/RSX/Program/Assembler/Passes/FP/RegisterAnnotationPass.cpp index 622deefe7c..5e45ec6133 100644 --- a/rpcs3/Emu/RSX/Program/Assembler/Passes/FP/RegisterAnnotationPass.cpp +++ b/rpcs3/Emu/RSX/Program/Assembler/Passes/FP/RegisterAnnotationPass.cpp @@ -31,14 +31,14 @@ namespace rsx::assembler::FP switch (dst.prec) { case RSX_FP_PRECISION_REAL: - case RSX_FP_PRECISION_UNKNOWN: + // case RSX_FP_PRECISION_UNKNOWN: // Unreachable break; case RSX_FP_PRECISION_HALF: if (!src0.fp16) return false; break; case RSX_FP_PRECISION_FIXED12: case RSX_FP_PRECISION_FIXED9: - case RSX_FP_PRECISION_SATURATE: + // case RSX_FP_PRECISION_SATURATE: // Unreachable return false; } From 414df8432e56e8b015a4b447242f8127e62197b7 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Fri, 6 Mar 2026 03:25:58 +0300 Subject: [PATCH 097/175] gl: Respect internal offsets when performing DMA transfer operations --- rpcs3/Emu/RSX/GL/GLTextureCache.h | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/rpcs3/Emu/RSX/GL/GLTextureCache.h b/rpcs3/Emu/RSX/GL/GLTextureCache.h index ae3b8e37e9..2c16bc8ba5 100644 --- a/rpcs3/Emu/RSX/GL/GLTextureCache.h +++ b/rpcs3/Emu/RSX/GL/GLTextureCache.h @@ -48,7 +48,7 @@ namespace gl void init_buffer(const gl::texture* src) { - const u32 vram_size = src->pitch() * src->height(); + const u32 vram_size = std::max(src->pitch() * src->height(), get_section_size()); const u32 buffer_size = utils::align(vram_size, 4096); if (pbo) @@ -148,7 +148,7 @@ namespace gl } } - void dma_transfer(gl::command_context& cmd, gl::texture* src, const areai& /*src_area*/, const utils::address_range32& /*valid_range*/, u32 pitch) + void dma_transfer(gl::command_context& cmd, gl::texture* src, const areai& src_area, const utils::address_range32& valid_range, u32 pitch) { init_buffer(src); glGetError(); @@ -165,6 +165,20 @@ namespace gl real_pitch = src->pitch(); rsx_pitch = pitch; + const coord3u src_rgn = + { + { static_cast(src_area.x1), static_cast(src_area.y1), 0 }, + { static_cast(src_area.width()), static_cast(src_area.height()), 1 } + }; + + u32 pbo_offset = 0; + if (valid_range.valid()) + { + const u32 section_base = get_section_base(); + pbo_offset = valid_range.start - section_base; + ensure(valid_range.start >= section_base && pbo_offset <= pbo.size()); + } + bool use_driver_pixel_transform = true; if (get_driver_caps().ARB_compute_shader_supported) [[likely]] { @@ -193,14 +207,14 @@ namespace gl mem_info.image_size_in_bytes *= 2; } - void* out_offset = copy_image_to_buffer(cmd, pack_info, src, &scratch_mem, 0, 0, { {}, src->size3D() }, &mem_info); + void* out_offset = copy_image_to_buffer(cmd, pack_info, src, &scratch_mem, 0, 0, src_rgn, &mem_info); glBindBuffer(GL_SHADER_STORAGE_BUFFER, GL_NONE); glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); real_pitch = pack_info.size * src->width(); const u64 data_length = pack_info.size * mem_info.image_size_in_texels; - scratch_mem.copy_to(&pbo, reinterpret_cast(out_offset), 0, data_length); + scratch_mem.copy_to(&pbo, reinterpret_cast(out_offset), pbo_offset, data_length); } else { @@ -225,7 +239,7 @@ namespace gl pack_settings.alignment(1); pack_settings.swap_bytes(pack_unpack_swap_bytes); - src->copy_to(nullptr, format, type, pack_settings); + src->copy_to(reinterpret_cast(pbo_offset), format, type, 0, src_rgn, pack_settings); } if (auto error = glGetError()) From 1c5e30e83f4a9840a712cc70fc69c4a4c2123002 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Fri, 6 Mar 2026 12:21:28 +0100 Subject: [PATCH 098/175] input/qt: fix default squircle value in text and remove duplicate comments --- rpcs3/Emu/Io/PadHandler.cpp | 16 ---------------- rpcs3/Emu/Io/PadHandler.h | 8 ++++---- rpcs3/rpcs3qt/tooltips.h | 2 +- 3 files changed, 5 insertions(+), 21 deletions(-) diff --git a/rpcs3/Emu/Io/PadHandler.cpp b/rpcs3/Emu/Io/PadHandler.cpp index 9110687a9c..a2ae41349e 100644 --- a/rpcs3/Emu/Io/PadHandler.cpp +++ b/rpcs3/Emu/Io/PadHandler.cpp @@ -24,13 +24,11 @@ std::set PadHandlerBase::narrow_set(const std::set& src) return dst; } -// Get new multiplied value based on the multiplier s32 PadHandlerBase::MultipliedInput(s32 raw_value, s32 multiplier) { return (multiplier * raw_value) / 100; } -// Get new scaled value between 0 and range based on its minimum and maximum f32 PadHandlerBase::ScaledInput(f32 raw_value, f32 minimum, f32 maximum, f32 deadzone, f32 range) { if (deadzone > 0 && deadzone > minimum) @@ -46,7 +44,6 @@ f32 PadHandlerBase::ScaledInput(f32 raw_value, f32 minimum, f32 maximum, f32 dea return range * val; } -// Get new scaled value between -range and range based on its minimum and maximum f32 PadHandlerBase::ScaledAxisInput(f32 raw_value, f32 minimum, f32 maximum, f32 deadzone, f32 range) { // convert [min, max] to [0, 1] @@ -79,7 +76,6 @@ f32 PadHandlerBase::ScaledAxisInput(f32 raw_value, f32 minimum, f32 maximum, f32 return (2.0f * range * val) - range; } -// Get normalized trigger value based on the range defined by a threshold u16 PadHandlerBase::NormalizeTriggerInput(u16 value, u32 threshold) const { if (value <= threshold || threshold >= trigger_max) @@ -90,8 +86,6 @@ u16 PadHandlerBase::NormalizeTriggerInput(u16 value, u32 threshold) const return static_cast(ScaledInput(static_cast(value), static_cast(trigger_min), static_cast(trigger_max), static_cast(threshold))); } -// normalizes a directed input, meaning it will correspond to a single "button" and not an axis with two directions -// the input values must lie in 0+ u16 PadHandlerBase::NormalizeDirectedInput(s32 raw_value, s32 threshold, s32 maximum) const { if (threshold >= maximum || maximum <= 0 || raw_value < 0) @@ -114,9 +108,6 @@ u16 PadHandlerBase::NormalizeStickInput(u16 raw_value, s32 threshold, s32 multip return static_cast(ScaledInput(static_cast(scaled_value), 0.0f, static_cast(thumb_max), static_cast(threshold))); } -// This function normalizes stick deadzone based on the DS3's deadzone, which is ~13% (default of anti deadzone) -// X and Y is expected to be in (-255) to 255 range, deadzone should be in terms of thumb stick range -// return is new x and y values in 0-255 range std::tuple PadHandlerBase::NormalizeStickDeadzone(s32 inX, s32 inY, u32 deadzone, u32 anti_deadzone) const { f32 X = inX / 255.0f; @@ -150,28 +141,21 @@ std::tuple PadHandlerBase::NormalizeStickDeadzone(s32 inX, s32 inY, u3 return std::tuple(ConvertAxis(X), ConvertAxis(Y)); } -// get clamped value between 0 and 255 u16 PadHandlerBase::Clamp0To255(f32 input) { return static_cast(std::clamp(input, 0.0f, 255.0f)); } -// get clamped value between 0 and 1023 u16 PadHandlerBase::Clamp0To1023(f32 input) { return static_cast(std::clamp(input, 0.0f, 1023.0f)); } -// input has to be [-1,1]. result will be [0,255] u16 PadHandlerBase::ConvertAxis(f32 value) { return static_cast((value + 1.0) * (255.0 / 2.0)); } -// The DS3, (and i think xbox controllers) give a 'square-ish' type response, so that the corners will give (almost)max x/y instead of the ~30x30 from a perfect circle -// using a simple scale/sensitivity increase would *work* although it eats a chunk of our usable range in exchange -// this might be the best for now, in practice it seems to push the corners to max of 20x20, with a squircle_factor of ~4000 -// This function assumes inX and inY is already in 0-255 void PadHandlerBase::ConvertToSquirclePoint(u16& inX, u16& inY, u32 squircle_factor) { if (!squircle_factor) diff --git a/rpcs3/Emu/Io/PadHandler.h b/rpcs3/Emu/Io/PadHandler.h index 98cca72a7d..a273beb3de 100644 --- a/rpcs3/Emu/Io/PadHandler.h +++ b/rpcs3/Emu/Io/PadHandler.h @@ -274,7 +274,7 @@ protected: // the input values must lie in 0+ u16 NormalizeDirectedInput(s32 raw_value, s32 threshold, s32 maximum) const; - // This function normalizes stick deadzone based on the DS3's deadzone, which is ~13% + // This function normalizes stick deadzone based on the DS3's deadzone, which is ~13% (default of anti deadzone) // X and Y is expected to be in (-255) to 255 range, deadzone should be in terms of thumb stick range // return is new x and y values in 0-255 range std::tuple NormalizeStickDeadzone(s32 inX, s32 inY, u32 deadzone, u32 anti_deadzone) const; @@ -284,10 +284,10 @@ public: // Get new multiplied value based on the multiplier static s32 MultipliedInput(s32 raw_value, s32 multiplier); - // Get new scaled value between 0 and 255 based on its minimum and maximum + // Get new scaled value between 0 and range based on its minimum and maximum static f32 ScaledInput(f32 raw_value, f32 minimum, f32 maximum, f32 deadzone, f32 range = 255.0f); - // Get new scaled value between -255 and 255 based on its minimum and maximum + // Get new scaled value between -range and range based on its minimum and maximum static f32 ScaledAxisInput(f32 raw_value, f32 minimum, f32 maximum, f32 deadzone, f32 range = 255.0f); // get clamped value between 0 and 255 @@ -301,7 +301,7 @@ public: // The DS3, (and i think xbox controllers) give a 'square-ish' type response, so that the corners will give (almost)max x/y instead of the ~30x30 from a perfect circle // using a simple scale/sensitivity increase would *work* although it eats a chunk of our usable range in exchange - // this might be the best for now, in practice it seems to push the corners to max of 20x20, with a squircle_factor of 8000 + // this might be the best for now, in practice it seems to push the corners to max of 20x20, with a squircle_factor of ~4000 // This function assumes inX and inY is already in 0-255 static void ConvertToSquirclePoint(u16& inX, u16& inY, u32 squircle_factor); diff --git a/rpcs3/rpcs3qt/tooltips.h b/rpcs3/rpcs3qt/tooltips.h index e9c8ad436b..4f983dc18a 100644 --- a/rpcs3/rpcs3qt/tooltips.h +++ b/rpcs3/rpcs3qt/tooltips.h @@ -302,7 +302,7 @@ public: const QString analog_limiter = tr("Applies the stick multipliers while this special button is pressed.
Enable \"Toggle\" if you want to toggle the analog limiter on button press instead.
If no button has been assigned, the stick multipliers are always applied."); const QString pressure_intensity = tr("Controls the intensity of pressure sensitive buttons while this special button is pressed.
Enable \"Toggle\" if you want to toggle the intensity on button press instead.
Use the percentage to change how hard you want to press a button."); const QString pressure_deadzone = tr("Controls the deadzone of pressure sensitive buttons. It determines how far the button has to be pressed until it is recognized by the game. The resulting range will be projected onto the full button sensitivity range."); - const QString squircle_factor = tr("The actual DualShock 3's stick range is not circular but formed like a rounded square (or squircle) which represents the maximum range of the emulated sticks. You can use the squircle values to modify the stick input if your sticks can't reach the corners of that range. A value of 0 does not apply any so called squircling. A value of 8000 is usually recommended."); + const QString squircle_factor = tr("The actual DualShock 3's stick range is not circular but formed like a rounded square (or squircle) which represents the maximum range of the emulated sticks. You can use the squircle values to modify the stick input if your sticks can't reach the corners of that range. A value of 0 does not apply any so called squircling. A value of 4000 is usually recommended."); const QString stick_multiplier = tr("The stick multipliers can be used to change the sensitivity of your stick movements.
The default setting is 1 and represents normal input."); const QString stick_deadzones = tr("A stick's deadzone determines how far the stick has to be moved until it is fully recognized by the game. The resulting range will be projected onto the full input range in order to give you a smooth experience. Movement inside the deadzone is simulated using the anti-deadzone slider (default is 13%), so don't worry if there is still movement shown in the emulated stick preview."); const QString vibration = tr("The PS3 activates two motors (large and small) to handle controller vibrations.
You can enable, disable or even switch these signals for the currently selected pad here.
The game sends values from 0-255 to activate the motors.
Any value smaller or equal the threshold will be set to 0. This is 63 by default for pad handlers other than DualShock3 in order to emulate the DualShock3's behavior."); From d97851376d0adb736dff4715e158b4c2355432b8 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Fri, 6 Mar 2026 09:06:53 +0100 Subject: [PATCH 099/175] Add stacktrace in case of exception --- Utilities/Thread.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index 08dce12315..6395c32505 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -14,6 +14,11 @@ #include "Emu/CPU/Backends/AArch64/AArch64Signal.h" #endif +#ifdef __cpp_lib_stacktrace +#include "rpcs3_version.h" +#include +#endif + #ifdef _WIN32 #include #include @@ -2800,6 +2805,16 @@ void thread_base::exec() [[noreturn]] void thread_ctrl::emergency_exit(std::string_view reason) { + // Print stacktrace +#ifdef __cpp_lib_stacktrace + if (rpcs3::is_local_build()) + { + std::ostringstream oss; + oss << std::stacktrace::current(); + sys_log.notice("StackTrace\n\n%s\n", oss.str()); + } +#endif + if (const std::string info = dump_useful_thread_info(); !info.empty()) { sys_log.notice("\n%s", info); From 4fd2409b8be1e85c9c25e631012b53abc5a859dc Mon Sep 17 00:00:00 2001 From: Megamouse Date: Tue, 3 Mar 2026 20:41:36 +0100 Subject: [PATCH 100/175] Update FAudio to 26.03 --- 3rdparty/FAudio | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rdparty/FAudio b/3rdparty/FAudio index e67d761ead..dc034fc671 160000 --- a/3rdparty/FAudio +++ b/3rdparty/FAudio @@ -1 +1 @@ -Subproject commit e67d761ead486de3e69fa11705456bf94df734ca +Subproject commit dc034fc671b07bbd14e8410d5dd6be6da38fdf6d From 69384d7bb4018dd0886fee25afe791bb99fbcbfd Mon Sep 17 00:00:00 2001 From: Megamouse Date: Mon, 5 Jan 2026 12:58:23 +0100 Subject: [PATCH 101/175] Update codebase to SDL 3.4.0 --- rpcs3/Emu/Io/LogitechG27.h | 5 +---- rpcs3/Input/sdl_camera_handler.cpp | 9 --------- rpcs3/Input/sdl_instance.cpp | 4 ++-- 3 files changed, 3 insertions(+), 15 deletions(-) diff --git a/rpcs3/Emu/Io/LogitechG27.h b/rpcs3/Emu/Io/LogitechG27.h index 4ec0d35c0b..dc68db68b9 100644 --- a/rpcs3/Emu/Io/LogitechG27.h +++ b/rpcs3/Emu/Io/LogitechG27.h @@ -38,10 +38,7 @@ struct logitech_g27_ffb_slot logitech_g27_ffb_state state = logitech_g27_ffb_state::inactive; u64 last_update = 0; SDL_HapticEffect last_effect {}; - - // TODO switch to SDL_HapticEffectID when it becomes available in a future SDL release - // Match the return of SDL_CreateHapticEffect for now - int effect_id = -1; + SDL_HapticEffectID effect_id = -1; }; struct sdl_mapping diff --git a/rpcs3/Input/sdl_camera_handler.cpp b/rpcs3/Input/sdl_camera_handler.cpp index 4faf4eaf75..8f6aa965de 100644 --- a/rpcs3/Input/sdl_camera_handler.cpp +++ b/rpcs3/Input/sdl_camera_handler.cpp @@ -10,15 +10,6 @@ LOG_CHANNEL(camera_log, "Camera"); -#if !(SDL_VERSION_ATLEAST(3, 4, 0)) -namespace SDL_CameraPermissionState -{ - constexpr int SDL_CAMERA_PERMISSION_STATE_DENIED = -1; - constexpr int SDL_CAMERA_PERMISSION_STATE_PENDING = 0; - constexpr int SDL_CAMERA_PERMISSION_STATE_APPROVED = 1; -} -#endif - template <> void fmt_class_string::format(std::string& out, u64 arg) { diff --git a/rpcs3/Input/sdl_instance.cpp b/rpcs3/Input/sdl_instance.cpp index d3296f44ba..a1b1410b53 100644 --- a/rpcs3/Input/sdl_instance.cpp +++ b/rpcs3/Input/sdl_instance.cpp @@ -102,8 +102,8 @@ bool sdl_instance::initialize_impl() set_hint(SDL_HINT_JOYSTICK_HIDAPI_PS3, "1"); #endif - // Disable LG4FF driver on windows (only needed for SDL 3.4.0) -#if _WIN32 && SDL_VERSION_ATLEAST(3, 4, 0) + // Disable LG4FF driver on windows +#if _WIN32 set_hint(SDL_HINT_JOYSTICK_HIDAPI_LG4FF, "0"); #endif From 0d80e300a07bb46d1b35e0b4211865c7b641859f Mon Sep 17 00:00:00 2001 From: Megamouse Date: Wed, 4 Mar 2026 19:31:50 +0100 Subject: [PATCH 102/175] Qt: add log level settings --- 3rdparty/yaml-cpp/yaml-cpp | 2 +- Utilities/Config.cpp | 2 +- .../Emu/CPU/Backends/AArch64/AArch64Common.h | 6 +- rpcs3/rpcs3.vcxproj | 2 + rpcs3/rpcs3.vcxproj.filters | 6 + rpcs3/rpcs3qt/CMakeLists.txt | 1 + rpcs3/rpcs3qt/emu_settings.cpp | 44 +++-- rpcs3/rpcs3qt/emu_settings.h | 9 + rpcs3/rpcs3qt/emu_settings_type.h | 6 + rpcs3/rpcs3qt/log_level_dialog.cpp | 155 ++++++++++++++++++ rpcs3/rpcs3qt/log_level_dialog.h | 19 +++ rpcs3/rpcs3qt/settings_dialog.cpp | 12 +- rpcs3/rpcs3qt/settings_dialog.ui | 26 ++- rpcs3/rpcs3qt/tooltips.h | 1 + rpcs3/util/logs.cpp | 11 +- rpcs3/util/logs.hpp | 8 +- 16 files changed, 279 insertions(+), 31 deletions(-) create mode 100644 rpcs3/rpcs3qt/log_level_dialog.cpp create mode 100644 rpcs3/rpcs3qt/log_level_dialog.h diff --git a/3rdparty/yaml-cpp/yaml-cpp b/3rdparty/yaml-cpp/yaml-cpp index 05c44fcd18..51a5d623e3 160000 --- a/3rdparty/yaml-cpp/yaml-cpp +++ b/3rdparty/yaml-cpp/yaml-cpp @@ -1 +1 @@ -Subproject commit 05c44fcd18074836e21e1eda9fc02b3a4a1529b5 +Subproject commit 51a5d623e3fde1f58829a56ba910f1cb33596222 diff --git a/Utilities/Config.cpp b/Utilities/Config.cpp index cee928def7..381ee01079 100644 --- a/Utilities/Config.cpp +++ b/Utilities/Config.cpp @@ -416,7 +416,7 @@ void cfg::encode(YAML::Emitter& out, const cfg::_base& rhs) out << YAML::BeginMap; for (const auto& np : static_cast(rhs).get_map()) { - if (np.second == logs::level::notice) continue; + if (np.second == logs::level::_default) continue; out << YAML::Key << np.first; out << YAML::Value << fmt::format("%s", np.second); } diff --git a/rpcs3/Emu/CPU/Backends/AArch64/AArch64Common.h b/rpcs3/Emu/CPU/Backends/AArch64/AArch64Common.h index dff06dfb81..2ce4fa68b3 100644 --- a/rpcs3/Emu/CPU/Backends/AArch64/AArch64Common.h +++ b/rpcs3/Emu/CPU/Backends/AArch64/AArch64Common.h @@ -20,19 +20,19 @@ namespace aarch64 sp }; - static const char* gpr_names[] = + [[maybe_unused]] static const char* gpr_names[] = { "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26", "x27", "x28", "x29", "x30" }; - static const char* spr_names[] = + [[maybe_unused]] static const char* spr_names[] = { "xzr", "pc", "sp" }; - static const char* spr_asm_names[] = + [[maybe_unused]] static const char* spr_asm_names[] = { "xzr", ".", "sp" }; diff --git a/rpcs3/rpcs3.vcxproj b/rpcs3/rpcs3.vcxproj index 9749f60fcd..cd5d7c8bc4 100644 --- a/rpcs3/rpcs3.vcxproj +++ b/rpcs3/rpcs3.vcxproj @@ -826,6 +826,7 @@ + @@ -1578,6 +1579,7 @@ "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DWIN32_LEAN_AND_MEAN -DHAVE_VULKAN -DWITH_DISCORD_RPC -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DNDEBUG -DQT_CONCURRENT_LIB -DQT_MULTIMEDIA_LIB -DQT_MULTIMEDIAWIDGETS_LIB -DQT_SVG_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\SoundTouch\soundtouch\include" "-I.\..\3rdparty\cubeb\extra" "-I.\..\3rdparty\cubeb\cubeb\include" "-I.\..\3rdparty\protobuf\protobuf\src" "-I.\..\3rdparty\wolfssl\wolfssl" "-I.\..\3rdparty\curl\curl\include" "-I.\..\3rdparty\libusb\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtCore" "-I.\release" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtMultimedia" "-I$(QTDIR)\include\QtMultimediaWidgets" "-I$(QTDIR)\include\QtSvg" + diff --git a/rpcs3/rpcs3.vcxproj.filters b/rpcs3/rpcs3.vcxproj.filters index a011ddf62e..6c7841b4fc 100644 --- a/rpcs3/rpcs3.vcxproj.filters +++ b/rpcs3/rpcs3.vcxproj.filters @@ -1275,6 +1275,9 @@ Io + + Gui\settings + @@ -1517,6 +1520,9 @@ Io + + Gui\settings + diff --git a/rpcs3/rpcs3qt/CMakeLists.txt b/rpcs3/rpcs3qt/CMakeLists.txt index b59d6f7a11..6fe8d9db13 100644 --- a/rpcs3/rpcs3qt/CMakeLists.txt +++ b/rpcs3/rpcs3qt/CMakeLists.txt @@ -53,6 +53,7 @@ add_library(rpcs3_ui STATIC localized.cpp localized_emu.cpp log_frame.cpp + log_level_dialog.cpp log_viewer.cpp main_window.cpp memory_string_searcher.cpp diff --git a/rpcs3/rpcs3qt/emu_settings.cpp b/rpcs3/rpcs3qt/emu_settings.cpp index ccb2308509..c686394c10 100644 --- a/rpcs3/rpcs3qt/emu_settings.cpp +++ b/rpcs3/rpcs3qt/emu_settings.cpp @@ -31,18 +31,20 @@ namespace out << YAML::Null; return; } + if (node.IsMap()) { std::vector keys; keys.reserve(node.size()); + // generate vector of strings to be sorted using the as function from YAML documentation for (const auto& pair : node) { - keys.push_back(pair.first.as()); + keys.push_back(pair.first.Scalar()); } std::sort(keys.begin(), keys.end()); + // recursively generate sorted maps - // alternative implementations could have stops at specified recursion levels or maybe just the first two levels would be sorted out << YAML::BeginMap; for (const std::string& key : keys) { @@ -51,15 +53,10 @@ namespace emit_data(out, node[key]); } out << YAML::EndMap; + return; } - // alternatively: an else statement could be used however I wanted to follow a similar format to the += operator so the YAML Undefined class can be ignored - else if (node.IsScalar() || node.IsSequence()) - { - out << node; - } - // this exists to preserve the same functionality as before where Undefined nodes would still be output, can be removed or consolidated with the else if branch - else - out << node; + + out << node; } // Incrementally load YAML @@ -910,11 +907,38 @@ std::string emu_settings::GetSetting(emu_settings_type type) const return ""; } +std::map emu_settings::GetMapSettingDefault(emu_settings_type type) const +{ + if (const auto node = cfg_adapter::get_node(m_default_settings, ::at32(settings_location, type)); node && node.IsMap()) + { + return node.as>(); + } + + cfg_log.fatal("GetMapSettingDefault(type=%d) could not retrieve the requested node", static_cast(type)); + return {}; +} + +std::map emu_settings::GetMapSetting(emu_settings_type type) const +{ + if (const auto node = cfg_adapter::get_node(m_current_settings, ::at32(settings_location, type)); node && node.IsMap()) + { + return node.as>(); + } + + cfg_log.fatal("GetMapSetting(type=%d) could not retrieve the requested node", static_cast(type)); + return {}; +} + void emu_settings::SetSetting(emu_settings_type type, const std::string& val) const { cfg_adapter::get_node(m_current_settings, ::at32(settings_location, type)) = val; } +void emu_settings::SetMapSetting(emu_settings_type type, const std::map& val) const +{ + cfg_adapter::get_node(m_current_settings, ::at32(settings_location, type)) = val; +} + emu_settings_type emu_settings::FindSettingsType(const cfg::_base* node) const { // Add key and value to static map on first use diff --git a/rpcs3/rpcs3qt/emu_settings.h b/rpcs3/rpcs3qt/emu_settings.h index 5da946dabe..c5a1e89252 100644 --- a/rpcs3/rpcs3qt/emu_settings.h +++ b/rpcs3/rpcs3qt/emu_settings.h @@ -78,9 +78,18 @@ public: /** Returns the value of the setting type.*/ std::string GetSetting(emu_settings_type type) const; + /** Returns the default map value of the setting type.*/ + std::map GetMapSettingDefault(emu_settings_type type) const; + + /** Returns the value of the setting type as map.*/ + std::map GetMapSetting(emu_settings_type type) const; + /** Sets the setting type to a given value.*/ void SetSetting(emu_settings_type type, const std::string& val) const; + /** Sets the setting type to a given map value.*/ + void SetMapSetting(emu_settings_type type, const std::map& val) const; + /** Try to find the settings type for a given string.*/ emu_settings_type FindSettingsType(const cfg::_base* node) const; diff --git a/rpcs3/rpcs3qt/emu_settings_type.h b/rpcs3/rpcs3qt/emu_settings_type.h index 6a5b6841b1..67238571d3 100644 --- a/rpcs3/rpcs3qt/emu_settings_type.h +++ b/rpcs3/rpcs3qt/emu_settings_type.h @@ -217,6 +217,9 @@ enum class emu_settings_type EmptyHdd0Tmp, LimitCacheSize, MaximumCacheSize, + + // Log + Log, }; /** A helper map that keeps track of where a given setting type is located*/ @@ -434,4 +437,7 @@ inline static const std::map settings_location { emu_settings_type::SuspendEmulationSavestateMode, { "Savestate", "Suspend Emulation Savestate Mode" }}, { emu_settings_type::CompatibleEmulationSavestateMode, { "Savestate", "Compatible Savestate Mode" }}, { emu_settings_type::StartSavestatePaused, { "Savestate", "Start Paused" }}, + + // Logs + { emu_settings_type::Log, { "Log" }}, }; diff --git a/rpcs3/rpcs3qt/log_level_dialog.cpp b/rpcs3/rpcs3qt/log_level_dialog.cpp new file mode 100644 index 0000000000..3f5fd3c58d --- /dev/null +++ b/rpcs3/rpcs3qt/log_level_dialog.cpp @@ -0,0 +1,155 @@ +#include "stdafx.h" +#include "log_level_dialog.h" +#include "emu_settings.h" + +#include +#include +#include +#include +#include +#include + +LOG_CHANNEL(cfg_log, "CFG"); + +log_level_dialog::log_level_dialog(QWidget* parent, std::shared_ptr emu_settings) + : QDialog(parent), m_emu_settings(emu_settings) +{ + setWindowTitle(tr("Configure minimum log levels")); + setObjectName("log_level_dialog"); + setAttribute(Qt::WA_DeleteOnClose); + setMinimumSize(QSize(700, 400)); + + const std::set channels = logs::get_channels(); + std::vector> levels; + + const auto add_level = [&levels](logs::level level, const QString& localized) + { + levels.push_back(std::pair(fmt::format("%s", level), localized)); + }; + + add_level(logs::level::always, tr("Always")); + add_level(logs::level::fatal, tr("Fatal")); + add_level(logs::level::error, tr("Error")); + add_level(logs::level::todo, tr("Todo")); + add_level(logs::level::success, tr("Success")); + add_level(logs::level::warning, tr("Warning")); + add_level(logs::level::notice, tr("Notice")); + add_level(logs::level::trace, tr("Trace")); + + const std::map current_settings = m_emu_settings->GetMapSetting(emu_settings_type::Log); + for (const auto& [channel, level] : current_settings) + { + if (!channels.contains(channel)) + { + cfg_log.warning("log_level_dialog: Ignoring unknown channel '%s' found in config file.", channel); + } + } + + m_table = new QTableWidget(static_cast(channels.size()), 2, this); + m_table->setHorizontalHeaderLabels({ tr("Channel"), tr("Level") }); + + int i = 0; + for (const std::string& channel : channels) + { + QComboBox* combo = new QComboBox(); + + for (const auto& [level, localized] : levels) + { + combo->addItem(localized, QString::fromStdString(level)); + } + + connect(combo, &QComboBox::currentIndexChanged, combo, [this, combo, ch = channel](int index) + { + if (index < 0) return; + + const QVariant var = combo->itemData(index); + if (!var.canConvert()) return; + + std::map settings = m_emu_settings->GetMapSetting(emu_settings_type::Log); + + settings[ch] = var.toString().toStdString(); + + m_emu_settings->SetMapSetting(emu_settings_type::Log, settings); + }); + + m_table->setItem(i, 0, new QTableWidgetItem(QString::fromStdString(channel))); + m_table->setCellWidget(i, 1, combo); + + i++; + } + + QLineEdit* filter_edit = new QLineEdit(this); + filter_edit->setPlaceholderText(tr("Filter channels")); + connect(filter_edit, &QLineEdit::textChanged, this, [this](const QString& text) + { + for (int i = 0; i < m_table->rowCount(); i++) + { + if (QTableWidgetItem* item = m_table->item(i, 0)) + { + m_table->setRowHidden(i, !text.isEmpty() && !item->text().contains(text, Qt::CaseInsensitive)); + } + } + }); + + QDialogButtonBox* button_box = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::RestoreDefaults); + connect(button_box, &QDialogButtonBox::clicked, this, [this, button_box, old_settings = m_emu_settings->GetMapSetting(emu_settings_type::Log)](QAbstractButton* button) + { + if (button == button_box->button(QDialogButtonBox::Ok)) + { + accept(); + } + else if (button == button_box->button(QDialogButtonBox::Cancel)) + { + m_emu_settings->SetMapSetting(emu_settings_type::Log, old_settings); + reject(); + } + else if (button == button_box->button(QDialogButtonBox::RestoreDefaults)) + { + m_emu_settings->SetMapSetting(emu_settings_type::Log, m_emu_settings->GetMapSettingDefault(emu_settings_type::Log)); + reload_page(); + } + }); + + reload_page(); + + m_table->resizeColumnsToContents(); + m_table->horizontalHeader()->stretchLastSection(); + + QVBoxLayout* layout = new QVBoxLayout(); + layout->addWidget(filter_edit); + layout->addWidget(m_table); + layout->addWidget(button_box); + setLayout(layout); +} + +log_level_dialog::~log_level_dialog() +{ +} + +void log_level_dialog::reload_page() +{ + const std::map settings = m_emu_settings->GetMapSetting(emu_settings_type::Log); + const QString def_str = QString::fromStdString(fmt::format("%s", logs::level::_default)); + + for (int i = 0; i < m_table->rowCount(); i++) + { + QTableWidgetItem* item = m_table->item(i, 0); + if (!item) continue; + + const std::string channel = item->text().toStdString(); + + if (QComboBox* combo = static_cast(m_table->cellWidget(i, 1))) + { + combo->blockSignals(true); + combo->setCurrentIndex(combo->findData(def_str)); + if (settings.contains(channel)) + { + if (const int index = combo->findData(QString::fromStdString(settings.at(channel))); index >= 0) + { + combo->setCurrentIndex(index); + } + } + combo->blockSignals(false); + } + } +} diff --git a/rpcs3/rpcs3qt/log_level_dialog.h b/rpcs3/rpcs3qt/log_level_dialog.h new file mode 100644 index 0000000000..87a0ccf8a4 --- /dev/null +++ b/rpcs3/rpcs3qt/log_level_dialog.h @@ -0,0 +1,19 @@ +#pragma once + +#include +#include + +class emu_settings; + +class log_level_dialog : public QDialog +{ +public: + log_level_dialog(QWidget* parent, std::shared_ptr emu_settings); + virtual ~log_level_dialog(); + +private: + void reload_page(); + + std::shared_ptr m_emu_settings; + QTableWidget* m_table = nullptr; +}; diff --git a/rpcs3/rpcs3qt/settings_dialog.cpp b/rpcs3/rpcs3qt/settings_dialog.cpp index 0c0fb63efd..b903db0f52 100644 --- a/rpcs3/rpcs3qt/settings_dialog.cpp +++ b/rpcs3/rpcs3qt/settings_dialog.cpp @@ -23,13 +23,13 @@ #include "emu_settings_type.h" #include "render_creator.h" #include "microphone_creator.h" -#include "Emu/NP/rpcn_countries.h" +#include "log_level_dialog.h" +#include "Emu/NP/rpcn_countries.h" #include "Emu/GameInfo.h" #include "Emu/System.h" #include "Emu/system_config.h" #include "Emu/title.h" - #include "Emu/Audio/audio_device_enumerator.h" #include "Loader/PSF.h" @@ -2496,6 +2496,14 @@ settings_dialog::settings_dialog(std::shared_ptr gui_settings, std m_emu_settings->EnhanceComboBox(ui->vulkansched, emu_settings_type::VulkanAsyncSchedulerDriver); SubscribeTooltip(ui->gb_vulkansched, tooltips.settings.vulkan_async_scheduler); + // Log levels + SubscribeTooltip(ui->gb_log_levels, tooltips.settings.vulkan_async_scheduler); + connect(ui->pb_log_levels, &QAbstractButton::clicked, this, [this]() + { + log_level_dialog* dlg = new log_level_dialog(this, m_emu_settings); + dlg->open(); + }); + if (!restoreGeometry(m_gui_settings->GetValue(gui::cfg_geometry).toByteArray())) { // Ignore. This will most likely only fail if the setting doesn't contain any values diff --git a/rpcs3/rpcs3qt/settings_dialog.ui b/rpcs3/rpcs3qt/settings_dialog.ui index e394407e11..76a418298d 100644 --- a/rpcs3/rpcs3qt/settings_dialog.ui +++ b/rpcs3/rpcs3qt/settings_dialog.ui @@ -265,7 +265,7 @@
- + @@ -2321,9 +2321,9 @@ - - Enable Clans - + + Enable Clans + @@ -4467,7 +4467,7 @@ - + 0 @@ -4545,6 +4545,22 @@ + + + + Log Levels + + + + + + Configure + + + + + + diff --git a/rpcs3/rpcs3qt/tooltips.h b/rpcs3/rpcs3qt/tooltips.h index 4f983dc18a..b56e093dff 100644 --- a/rpcs3/rpcs3qt/tooltips.h +++ b/rpcs3/rpcs3qt/tooltips.h @@ -59,6 +59,7 @@ public: const QString paused_savestates = tr("When this mode is on, savestates are loaded and paused on the first frame.\nThis allows players to prepare for gameplay without being thrown into the action immediately."); const QString spu_profiler = tr("When enabled, SPU performance is measured at runtime.\nEnable only at a developer's request because when enabled it reduces performance a bit by itself."); const QString use_ReBAR = tr("When enabled, Vulkan will try to use PCI-e resizable bar address space for GPU uploads of timing-sensitive data.\nThis yields a massive performance win on NVIDIA cards when the base framerate is low.\nFor games with very high framerates, this option can result in worse performance for all GPU vendors.\n"); + const QString log_levels = tr("Set the minimum log levels for any log channels."); // audio diff --git a/rpcs3/util/logs.cpp b/rpcs3/util/logs.cpp index 0276f90e0b..f0afc95bac 100644 --- a/rpcs3/util/logs.cpp +++ b/rpcs3/util/logs.cpp @@ -202,7 +202,7 @@ namespace logs for (auto&& pair : get_logger()->channels) { - pair.second->enabled.release(level::notice); + pair.second->enabled.release(level::_default); } } @@ -271,18 +271,17 @@ namespace logs } } - std::vector get_channels() + std::set get_channels() { - std::vector result; + std::set result; std::lock_guard lock(g_mutex); for (auto&& p : get_logger()->channels) { - // Copy names removing duplicates - if (result.empty() || result.back() != p.first) + if (!p.first.empty()) { - result.push_back(p.first); + result.insert(p.first); } } diff --git a/rpcs3/util/logs.hpp b/rpcs3/util/logs.hpp index 52d163ed43..1b75bd6499 100644 --- a/rpcs3/util/logs.hpp +++ b/rpcs3/util/logs.hpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include #include "util/atomic.hpp" #include "Utilities/StrFmt.h" @@ -20,6 +20,8 @@ namespace logs warning = 5, notice = 6, trace = 7, // Lowest severity (usually disabled) + + _default = notice }; struct channel; @@ -163,7 +165,7 @@ namespace logs registerer(channel& _ch); }; - // Log level control: set all channels to level::notice + // Log level control: set all channels to default level::notice void reset(); // Log level control: set all channels to level::always @@ -179,7 +181,7 @@ namespace logs void set_channel_levels(const std::map>& map); // Get all registered log channels - std::vector get_channels(); + std::set get_channels(); // Helper: no additional name specified consteval const char* make_channel_name(const char* name, const char* alt = nullptr) From ac30feeddb4d53f08397897574649228b8c187d1 Mon Sep 17 00:00:00 2001 From: RipleyTom Date: Fri, 6 Mar 2026 21:25:52 +0100 Subject: [PATCH 103/175] Revert enabling PPU jump elider --- rpcs3/Emu/Cell/PPUTranslator.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rpcs3/Emu/Cell/PPUTranslator.cpp b/rpcs3/Emu/Cell/PPUTranslator.cpp index 1c9f6e2b9d..ddf7d330a0 100644 --- a/rpcs3/Emu/Cell/PPUTranslator.cpp +++ b/rpcs3/Emu/Cell/PPUTranslator.cpp @@ -553,7 +553,9 @@ void PPUTranslator::CallFunction(u64 target, Value* indirect) std::unordered_set passed_targets{target_last}; // Try to follow unconditional branches as long as there is no infinite loop - while (true) + // !! Triggers compilation issues in Asura's Wrath in other parts of the code + // !! See https://github.com/RPCS3/rpcs3/issues/18287 + while (false) { const ppu_opcode_t op{*ensure(m_info.get_ptr(target_last))}; const ppu_itype::type itype = g_ppu_itype.decode(op.opcode); From 14789b536f2122e0f6fc8b9d34958a615ef34619 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sat, 7 Mar 2026 00:23:58 +0300 Subject: [PATCH 104/175] gl: Clean up the awful image copy API - Wrap everything in rsx::io_buffer and gl::buffer to avoid out of bounds issues. - Also abstracts away nasty things like OpenGL offset pointer casts. --- rpcs3/Emu/RSX/Common/io_buffer.h | 7 ++-- rpcs3/Emu/RSX/GL/GLGSRender.cpp | 9 ++--- rpcs3/Emu/RSX/GL/GLOverlays.cpp | 6 ++-- rpcs3/Emu/RSX/GL/GLPresent.cpp | 5 +-- rpcs3/Emu/RSX/GL/GLTexture.cpp | 18 +++------- rpcs3/Emu/RSX/GL/GLTextureCache.h | 4 +-- rpcs3/Emu/RSX/GL/glutils/image.cpp | 43 +++++++++++++++-------- rpcs3/Emu/RSX/GL/glutils/image.h | 13 ++++--- rpcs3/Emu/RSX/Overlays/overlay_controls.h | 5 +++ 9 files changed, 62 insertions(+), 48 deletions(-) diff --git a/rpcs3/Emu/RSX/Common/io_buffer.h b/rpcs3/Emu/RSX/Common/io_buffer.h index 64f95a5e61..59e8e6a32e 100644 --- a/rpcs3/Emu/RSX/Common/io_buffer.h +++ b/rpcs3/Emu/RSX/Common/io_buffer.h @@ -9,7 +9,7 @@ namespace rsx template concept SpanLike = requires(T t) { - { t.data() } -> std::convertible_to; + { t.data() } -> std::convertible_to; { t.size_bytes() } -> std::convertible_to; }; @@ -71,9 +71,10 @@ namespace rsx return static_cast(m_ptr); } - usz size() const + template + T size() const { - return m_size; + return static_cast(m_size); } template diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index ebff202303..408ea9f784 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -249,22 +249,23 @@ void GLGSRender::on_init_thread() // Fallback null texture instead of relying on texture0 { std::array pixeldata = { 0, 0, 0, 0, 0, 0, 0, 0 }; + const rsx::io_buffer src_buf = std::span(pixeldata); // 1D auto tex1D = std::make_unique(GL_TEXTURE_1D, 1, 1, 1, 1, 1, GL_RGBA8, RSX_FORMAT_CLASS_COLOR); - tex1D->copy_from(pixeldata.data(), gl::texture::format::rgba, gl::texture::type::uint_8_8_8_8, {}); + tex1D->copy_from(src_buf, gl::texture::format::rgba, gl::texture::type::uint_8_8_8_8, {}); // 2D auto tex2D = std::make_unique(GL_TEXTURE_2D, 1, 1, 1, 1, 1, GL_RGBA8, RSX_FORMAT_CLASS_COLOR); - tex2D->copy_from(pixeldata.data(), gl::texture::format::rgba, gl::texture::type::uint_8_8_8_8, {}); + tex2D->copy_from(src_buf, gl::texture::format::rgba, gl::texture::type::uint_8_8_8_8, {}); // 3D auto tex3D = std::make_unique(GL_TEXTURE_3D, 1, 1, 1, 1, 1, GL_RGBA8, RSX_FORMAT_CLASS_COLOR); - tex3D->copy_from(pixeldata.data(), gl::texture::format::rgba, gl::texture::type::uint_8_8_8_8, {}); + tex3D->copy_from(src_buf, gl::texture::format::rgba, gl::texture::type::uint_8_8_8_8, {}); // CUBE auto texCUBE = std::make_unique(GL_TEXTURE_CUBE_MAP, 1, 1, 1, 1, 1, GL_RGBA8, RSX_FORMAT_CLASS_COLOR); - texCUBE->copy_from(pixeldata.data(), gl::texture::format::rgba, gl::texture::type::uint_8_8_8_8, {}); + texCUBE->copy_from(src_buf, gl::texture::format::rgba, gl::texture::type::uint_8_8_8_8, {}); m_null_textures[GL_TEXTURE_1D] = std::move(tex1D); m_null_textures[GL_TEXTURE_2D] = std::move(tex2D); diff --git a/rpcs3/Emu/RSX/GL/GLOverlays.cpp b/rpcs3/Emu/RSX/GL/GLOverlays.cpp index 7d36e5598b..0c4732430c 100644 --- a/rpcs3/Emu/RSX/GL/GLOverlays.cpp +++ b/rpcs3/Emu/RSX/GL/GLOverlays.cpp @@ -223,7 +223,7 @@ namespace gl gl::texture_view* ui_overlay_renderer::load_simple_image(rsx::overlays::image_info_base* desc, bool temp_resource, u32 owner_uid) { auto tex = std::make_unique(GL_TEXTURE_2D, desc->w, desc->h, 1, 1, 1, GL_RGBA8, RSX_FORMAT_CLASS_COLOR); - tex->copy_from(desc->get_data(), gl::texture::format::rgba, gl::texture::type::uint_8_8_8_8, {}); + tex->copy_from(desc->as_span(), gl::texture::format::rgba, gl::texture::type::uint_8_8_8_8, {}); const GLenum remap[] = { GL_RED, GL_ALPHA, GL_BLUE, GL_GREEN }; auto view = std::make_unique(tex.get(), remap); @@ -308,7 +308,7 @@ namespace gl const std::vector& glyph_data = font->get_glyph_data(); auto tex = std::make_unique(GL_TEXTURE_2D_ARRAY, font_size.width, font_size.height, font_size.depth, 1, 1, GL_R8, RSX_FORMAT_CLASS_COLOR); - tex->copy_from(glyph_data.data(), gl::texture::format::r, gl::texture::type::ubyte, {}); + tex->copy_from(std::span(glyph_data), gl::texture::format::r, gl::texture::type::ubyte, {}); GLenum remap[] = { GL_RED, GL_RED, GL_RED, GL_RED }; auto view = std::make_unique(tex.get(), remap); @@ -332,7 +332,7 @@ namespace gl if (dirty) { - view->image()->copy_from(desc->get_data(), gl::texture::format::rgba, gl::texture::type::uint_8_8_8_8, {}); + view->image()->copy_from(desc->as_span(), gl::texture::format::rgba, gl::texture::type::uint_8_8_8_8, {}); } return view; diff --git a/rpcs3/Emu/RSX/GL/GLPresent.cpp b/rpcs3/Emu/RSX/GL/GLPresent.cpp index e7c03dfcf5..4c241d7d33 100644 --- a/rpcs3/Emu/RSX/GL/GLPresent.cpp +++ b/rpcs3/Emu/RSX/GL/GLPresent.cpp @@ -132,7 +132,8 @@ gl::texture* GLGSRender::get_present_source(gl::present_surface_info* info, cons const auto range = utils::address_range32::start_length(info->address, info->pitch * info->height); m_gl_texture_cache.invalidate_range(cmd, range, rsx::invalidation_cause::read); - flip_image->copy_from(vm::base(info->address), static_cast(expected_format), gl::texture::type::uint_8_8_8_8, unpack_settings); + const rsx::io_buffer read_buf = { vm::base(info->address), range.length() }; + flip_image->copy_from(read_buf, static_cast(expected_format), gl::texture::type::uint_8_8_8_8, unpack_settings); image = flip_image.get(); } else if (image->get_internal_format() != static_cast(expected_format)) @@ -368,7 +369,7 @@ void GLGSRender::flip(const rsx::display_flip_info_t& info) std::vector sshot_frame(buffer_height * buffer_width * 4); glGetError(); - tex->copy_to(sshot_frame.data(), gl::texture::format::rgba, gl::texture::type::ubyte, pack_settings); + tex->copy_to(std::span(sshot_frame), gl::texture::format::rgba, gl::texture::type::ubyte, pack_settings); m_sshot_tex.reset(); diff --git a/rpcs3/Emu/RSX/GL/GLTexture.cpp b/rpcs3/Emu/RSX/GL/GLTexture.cpp index 181e5058c8..40c3af180c 100644 --- a/rpcs3/Emu/RSX/GL/GLTexture.cpp +++ b/rpcs3/Emu/RSX/GL/GLTexture.cpp @@ -363,8 +363,7 @@ namespace gl } } - dst->bind(buffer::target::pixel_pack); - src->copy_to(reinterpret_cast(static_cast(dst_offset)), static_cast(pack_info.format), static_cast(pack_info.type), src_level, src_region, {}); + src->copy_to(*dst, dst_offset, static_cast(pack_info.format), static_cast(pack_info.type), src_level, src_region, {}); return false; }; @@ -611,9 +610,8 @@ namespace gl } glBindBuffer(GL_SHADER_STORAGE_BUFFER, GL_NONE); - transfer_buf->bind(buffer::target::pixel_unpack); - dst->copy_from(reinterpret_cast(u64(out_offset)), static_cast(unpack_info.format), + dst->copy_from(*transfer_buf, out_offset, static_cast(unpack_info.format), static_cast(unpack_info.type), dst_level, dst_region, {}); } } @@ -712,7 +710,6 @@ namespace gl pixel_buffer_layout mem_layout; std::span dst_buffer = staging_buffer; - void* out_pointer = staging_buffer.data(); u8 block_size_in_bytes = rsx::get_format_block_size_in_bytes(format); u64 image_linear_size = staging_buffer.size(); @@ -731,8 +728,6 @@ namespace gl g_compute_decode_buffer.remove(); g_compute_decode_buffer.create(gl::buffer::target::ssbo, min_required_buffer_size); } - - out_pointer = nullptr; } for (const rsx::subresource_layout& layout : input_layouts) @@ -867,7 +862,7 @@ namespace gl else { unpack_settings.swap_bytes(op.require_swap); - dst->copy_from(out_pointer, static_cast(gl_format), static_cast(gl_type), layout.level, region, unpack_settings); + dst->copy_from(staging_buffer, static_cast(gl_format), static_cast(gl_type), layout.level, region, unpack_settings); } } } @@ -1156,9 +1151,7 @@ namespace gl // Start pack operation pixel_pack_settings pack_settings{}; pack_settings.swap_bytes(pack_info.swap_bytes); - - g_typeless_transfer_buffer.get().bind(buffer::target::pixel_pack); - src->copy_to(nullptr, static_cast(pack_info.format), static_cast(pack_info.type), 0, src_region, pack_settings); + src->copy_to(g_typeless_transfer_buffer.get(), 0, static_cast(pack_info.format), static_cast(pack_info.type), 0, src_region, pack_settings); glBindBuffer(GL_PIXEL_PACK_BUFFER, GL_NONE); @@ -1166,8 +1159,7 @@ namespace gl pixel_unpack_settings unpack_settings{}; unpack_settings.swap_bytes(unpack_info.swap_bytes); - g_typeless_transfer_buffer.get().bind(buffer::target::pixel_unpack); - dst->copy_from(nullptr, static_cast(unpack_info.format), static_cast(unpack_info.type), 0, dst_region, unpack_settings); + dst->copy_from(g_typeless_transfer_buffer.get(), 0, static_cast(unpack_info.format), static_cast(unpack_info.type), 0, dst_region, unpack_settings); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, GL_NONE); } } diff --git a/rpcs3/Emu/RSX/GL/GLTextureCache.h b/rpcs3/Emu/RSX/GL/GLTextureCache.h index 2c16bc8ba5..704589cccf 100644 --- a/rpcs3/Emu/RSX/GL/GLTextureCache.h +++ b/rpcs3/Emu/RSX/GL/GLTextureCache.h @@ -233,13 +233,11 @@ namespace gl pack_unpack_swap_bytes = false; } - pbo.bind(buffer::target::pixel_pack); - pixel_pack_settings pack_settings; pack_settings.alignment(1); pack_settings.swap_bytes(pack_unpack_swap_bytes); - src->copy_to(reinterpret_cast(pbo_offset), format, type, 0, src_rgn, pack_settings); + src->copy_to(pbo, pbo_offset, format, type, 0, src_rgn, pack_settings); } if (auto error = glGetError()) diff --git a/rpcs3/Emu/RSX/GL/glutils/image.cpp b/rpcs3/Emu/RSX/GL/glutils/image.cpp index 7dbd7fc254..b70a61f367 100644 --- a/rpcs3/Emu/RSX/GL/glutils/image.cpp +++ b/rpcs3/Emu/RSX/GL/glutils/image.cpp @@ -175,7 +175,7 @@ namespace gl m_id = GL_NONE; } - void texture::copy_from(const void* src, texture::format format, texture::type type, int level, const coord3u region, const pixel_unpack_settings& pixel_settings) + void texture::copy_from(const rsx::io_buffer& src, texture::format format, texture::type type, int level, const coord3u region, const pixel_unpack_settings& pixel_settings) { ensure(m_samples <= 1, "Transfer operations are unsupported on multisampled textures."); @@ -185,30 +185,30 @@ namespace gl { case GL_TEXTURE_1D: { - DSA_CALL(TextureSubImage1D, m_id, GL_TEXTURE_1D, level, region.x, region.width, static_cast(format), static_cast(type), src); + DSA_CALL(TextureSubImage1D, m_id, GL_TEXTURE_1D, level, region.x, region.width, static_cast(format), static_cast(type), src.data()); break; } case GL_TEXTURE_2D: { - DSA_CALL(TextureSubImage2D, m_id, GL_TEXTURE_2D, level, region.x, region.y, region.width, region.height, static_cast(format), static_cast(type), src); + DSA_CALL(TextureSubImage2D, m_id, GL_TEXTURE_2D, level, region.x, region.y, region.width, region.height, static_cast(format), static_cast(type), src.data()); break; } case GL_TEXTURE_3D: case GL_TEXTURE_2D_ARRAY: { - DSA_CALL(TextureSubImage3D, m_id, target_, level, region.x, region.y, region.z, region.width, region.height, region.depth, static_cast(format), static_cast(type), src); + DSA_CALL(TextureSubImage3D, m_id, target_, level, region.x, region.y, region.z, region.width, region.height, region.depth, static_cast(format), static_cast(type), src.data()); break; } case GL_TEXTURE_CUBE_MAP: { if (get_driver_caps().ARB_direct_state_access_supported) { - glTextureSubImage3D(m_id, level, region.x, region.y, region.z, region.width, region.height, region.depth, static_cast(format), static_cast(type), src); + glTextureSubImage3D(m_id, level, region.x, region.y, region.z, region.width, region.height, region.depth, static_cast(format), static_cast(type), src.data()); } else { rsx_log.warning("Cubemap upload via texture::copy_from is halfplemented!"); - auto ptr = static_cast(src); + auto ptr = static_cast(src.data()); const auto end = std::min(6u, region.z + region.depth); for (unsigned face = region.z; face < end; ++face) { @@ -221,22 +221,25 @@ namespace gl } } - void texture::copy_from(buffer& buf, u32 gl_format_type, u32 offset, u32 length) + void texture::copy_from(buffer& buf, GLsizeiptr offset, texture::format format, texture::type type, int level, const coord3u region, const pixel_unpack_settings& pixel_settings) { ensure(m_samples <= 1, "Transfer operations are unsupported on multisampled textures."); - if (get_target() != target::textureBuffer) - fmt::throw_exception("OpenGL error: texture cannot copy from buffer"); + buf.bind(buffer::target::pixel_unpack); - DSA_CALL(TextureBufferRange, m_id, GL_TEXTURE_BUFFER, gl_format_type, buf.id(), offset, length); + const rsx::io_buffer src{ reinterpret_cast(static_cast(offset)), buf.size() - offset }; + copy_from(src, format, type, level, region, pixel_settings); } void texture::copy_from(buffer_view& view) { - copy_from(*view.value(), view.format(), view.offset(), view.range()); + if (get_target() != target::textureBuffer) + fmt::throw_exception("OpenGL error: texture cannot copy from buffer"); + + DSA_CALL(TextureBufferRange, m_id, GL_TEXTURE_BUFFER, view.format(), view.value()->id(), view.offset(), view.range()); } - void texture::copy_to(void* dst, texture::format format, texture::type type, int level, const coord3u& region, const pixel_pack_settings& pixel_settings) const + void texture::copy_to(const rsx::io_buffer& dst, texture::format format, texture::type type, int level, const coord3u& region, const pixel_pack_settings& pixel_settings) const { ensure(m_samples <= 1, "Transfer operations are unsupported on multisampled textures."); @@ -247,14 +250,14 @@ namespace gl region.width == m_width && region.height == m_height && region.depth == m_depth) { if (caps.ARB_direct_state_access_supported) - glGetTextureImage(m_id, level, static_cast(format), static_cast(type), s32{ smax }, dst); + glGetTextureImage(m_id, level, static_cast(format), static_cast(type), dst.size(), dst.data()); else - glGetTextureImageEXT(m_id, static_cast(m_target), level, static_cast(format), static_cast(type), dst); + glGetTextureImageEXT(m_id, static_cast(m_target), level, static_cast(format), static_cast(type), dst.data()); } else if (caps.ARB_direct_state_access_supported) { glGetTextureSubImage(m_id, level, region.x, region.y, region.z, region.width, region.height, region.depth, - static_cast(format), static_cast(type), s32{ smax }, dst); + static_cast(format), static_cast(type), s32{ smax }, dst.data()); } else { @@ -269,6 +272,16 @@ namespace gl } } + void texture::copy_to(buffer& buf, GLsizeiptr offset, texture::format format, texture::type type, int level, const coord3u& region, const pixel_pack_settings& pixel_settings) const + { + ensure(offset < buf.size(), "PBO write is out of range"); + + buf.bind(buffer::target::pixel_pack); + + const rsx::io_buffer dst{ reinterpret_cast(static_cast(offset)), buf.size() - offset }; + copy_to(dst, format, type, level, region, pixel_settings); + } + void texture_view::create(texture* data, GLenum target, GLenum sized_format, const subresource_range& range, const GLenum* argb_swizzle) { m_target = target; diff --git a/rpcs3/Emu/RSX/GL/glutils/image.h b/rpcs3/Emu/RSX/GL/glutils/image.h index 4112d833c7..6af4d28fa1 100644 --- a/rpcs3/Emu/RSX/GL/glutils/image.h +++ b/rpcs3/Emu/RSX/GL/glutils/image.h @@ -4,6 +4,7 @@ #include "Utilities/geometry.h" #include "Emu/RSX/Common/TextureUtils.h" +#include "Emu/RSX/Common/io_buffer.h" //using enum rsx::format_class; using namespace ::rsx::format_class_; @@ -321,22 +322,24 @@ namespace gl } // Data management - void copy_from(const void* src, texture::format format, texture::type type, int level, const coord3u region, const pixel_unpack_settings& pixel_settings); + void copy_from(const rsx::io_buffer& src, texture::format format, texture::type type, int level, const coord3u region, const pixel_unpack_settings& pixel_settings); - void copy_from(buffer& buf, u32 gl_format_type, u32 offset, u32 length); + void copy_from(buffer& buf, GLsizeiptr offset, texture::format format, texture::type type, int level, const coord3u region, const pixel_unpack_settings& pixel_settings); void copy_from(buffer_view& view); - void copy_to(void* dst, texture::format format, texture::type type, int level, const coord3u& region, const pixel_pack_settings& pixel_settings) const; + void copy_to(const rsx::io_buffer& dst, texture::format format, texture::type type, int level, const coord3u& region, const pixel_pack_settings& pixel_settings) const; + + void copy_to(buffer& buf, GLsizeiptr offset, texture::format format, texture::type type, int level, const coord3u& region, const pixel_pack_settings& pixel_settings) const; // Convenience wrappers - void copy_from(const void* src, texture::format format, texture::type type, const pixel_unpack_settings& pixel_settings) + void copy_from(const rsx::io_buffer& src, texture::format format, texture::type type, const pixel_unpack_settings& pixel_settings) { const coord3u region = { {}, size3D() }; copy_from(src, format, type, 0, region, pixel_settings); } - void copy_to(void* dst, texture::format format, texture::type type, const pixel_pack_settings& pixel_settings) const + void copy_to(const rsx::io_buffer& dst, texture::format format, texture::type type, const pixel_pack_settings& pixel_settings) const { const coord3u region = { {}, size3D() }; copy_to(dst, format, type, 0, region, pixel_settings); diff --git a/rpcs3/Emu/RSX/Overlays/overlay_controls.h b/rpcs3/Emu/RSX/Overlays/overlay_controls.h index 96090d1597..dd9dd98f4d 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_controls.h +++ b/rpcs3/Emu/RSX/Overlays/overlay_controls.h @@ -5,6 +5,7 @@ #include "Emu/localized_string.h" #include +#include // Definitions for common UI controls and their routines namespace rsx @@ -39,6 +40,9 @@ namespace rsx image_info_base() {} virtual ~image_info_base() {} virtual const u8* get_data() const = 0; + virtual usz size_bytes() const { return static_cast(w * h * bpp); } + + std::span as_span() const { return { get_data(), size_bytes() }; } }; struct image_info : public image_info_base @@ -56,6 +60,7 @@ namespace rsx void load_data(const std::vector& bytes, bool grayscaled = false); const u8* get_data() const override { return channels == 4 ? data : data_grey.empty() ? nullptr : data_grey.data(); } + usz size_bytes() const override { return data_grey.size(); } }; struct resource_config From 1e16b338b4303984d81a1075f6ad68bfcaf2aa63 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sat, 7 Mar 2026 03:04:59 +0300 Subject: [PATCH 105/175] gl: Add support for named objects --- rpcs3/Emu/RSX/GL/GLProcTable.h | 1 + rpcs3/Emu/RSX/GL/glutils/common.h | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/rpcs3/Emu/RSX/GL/GLProcTable.h b/rpcs3/Emu/RSX/GL/GLProcTable.h index 5278014b5c..ad8943bd4f 100644 --- a/rpcs3/Emu/RSX/GL/GLProcTable.h +++ b/rpcs3/Emu/RSX/GL/GLProcTable.h @@ -259,6 +259,7 @@ OPENGL_PROC(PFNGLDELETESYNCPROC, DeleteSync); // KHR_debug OPENGL_PROC(PFNGLDEBUGMESSAGECALLBACKPROC, DebugMessageCallback); +OPENGL_PROC(PFNGLOBJECTLABELPROC, ObjectLabel); // Immutable textures OPENGL_PROC(PFNGLTEXSTORAGE1DPROC, TexStorage1D); diff --git a/rpcs3/Emu/RSX/GL/glutils/common.h b/rpcs3/Emu/RSX/GL/glutils/common.h index f99c3590a6..a147a6e754 100644 --- a/rpcs3/Emu/RSX/GL/glutils/common.h +++ b/rpcs3/Emu/RSX/GL/glutils/common.h @@ -76,6 +76,26 @@ namespace gl } }; + template + struct named_object + { + protected: + GLuint m_id = GL_NONE; + std::string m_name = "Unnamed"; + + public: + void set_name(std::string_view name) + { + m_name = name.data(); + glObjectLabel(Ns, m_id, name.length(), name.data()); + } + + std::string_view name() const + { + return m_name; + } + }; + // Very useful util when capturing traces with RenderDoc static inline void push_debug_label(const char* label) { From 0ea692e9ab1f9bdf793eb539773ee372e514fadb Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sat, 7 Mar 2026 03:06:45 +0300 Subject: [PATCH 106/175] gl: Use named_object as the base class for images --- rpcs3/Emu/RSX/GL/glutils/image.cpp | 2 ++ rpcs3/Emu/RSX/GL/glutils/image.h | 7 +++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/rpcs3/Emu/RSX/GL/glutils/image.cpp b/rpcs3/Emu/RSX/GL/glutils/image.cpp index b70a61f367..4760bb1cc9 100644 --- a/rpcs3/Emu/RSX/GL/glutils/image.cpp +++ b/rpcs3/Emu/RSX/GL/glutils/image.cpp @@ -410,6 +410,8 @@ namespace gl auto view = std::make_unique(this, swizzle, aspect_flags); auto result = view.get(); views.emplace(key, std::move(view)); + + result->set_name(fmt::format("%s_%x", name(), remap.encoded)); return result; } diff --git a/rpcs3/Emu/RSX/GL/glutils/image.h b/rpcs3/Emu/RSX/GL/glutils/image.h index 6af4d28fa1..bd974c226a 100644 --- a/rpcs3/Emu/RSX/GL/glutils/image.h +++ b/rpcs3/Emu/RSX/GL/glutils/image.h @@ -59,7 +59,7 @@ namespace gl GLuint num_layers; }; - class texture + class texture : public named_object { friend class texture_view; @@ -181,7 +181,6 @@ namespace gl }; protected: - GLuint m_id = GL_NONE; GLuint m_width = 0; GLuint m_height = 0; GLuint m_depth = 0; @@ -346,10 +345,9 @@ namespace gl } }; - class texture_view + class texture_view : public named_object { protected: - GLuint m_id = GL_NONE; GLenum m_target = 0; GLenum m_format = 0; GLenum m_view_format = 0; @@ -465,6 +463,7 @@ namespace gl class viewable_image : public texture { + protected: std::unordered_map> views; public: From 4a51302c583da4747af60802a1f8c2bf4444ace1 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sat, 7 Mar 2026 03:07:57 +0300 Subject: [PATCH 107/175] gl: Propagate native layout from parent when creating temporary subresources --- rpcs3/Emu/RSX/GL/GLTextureCache.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rpcs3/Emu/RSX/GL/GLTextureCache.cpp b/rpcs3/Emu/RSX/GL/GLTextureCache.cpp index c2b0e3c252..e01385d51b 100644 --- a/rpcs3/Emu/RSX/GL/GLTextureCache.cpp +++ b/rpcs3/Emu/RSX/GL/GLTextureCache.cpp @@ -179,6 +179,10 @@ namespace gl auto components = get_component_mapping(gcm_format, rsx::component_order::default_); dst->set_native_component_layout(components); } + else + { + dst->set_native_component_layout(src->get_native_component_layout()); + } return dst->get_view(remap); } From 728d84b1fed0e99b00a7283d58014c4d3024d583 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sat, 7 Mar 2026 03:12:18 +0300 Subject: [PATCH 108/175] gl: Add debug names to some objects --- rpcs3/Emu/RSX/GL/GLTextureCache.cpp | 2 ++ rpcs3/Emu/RSX/GL/GLTextureCache.h | 1 + rpcs3/Emu/RSX/GL/glutils/image.cpp | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/rpcs3/Emu/RSX/GL/GLTextureCache.cpp b/rpcs3/Emu/RSX/GL/GLTextureCache.cpp index e01385d51b..f8aa9d95df 100644 --- a/rpcs3/Emu/RSX/GL/GLTextureCache.cpp +++ b/rpcs3/Emu/RSX/GL/GLTextureCache.cpp @@ -152,6 +152,8 @@ namespace gl dst = data.get(); dst->properties_encoding = match_key; m_temporary_surfaces.emplace_back(std::move(data)); + + dst->set_name(fmt::format("[Temp View] id=%u, fmt=0x%x", dst->id(), gcm_format)); } dst->add_ref(); diff --git a/rpcs3/Emu/RSX/GL/GLTextureCache.h b/rpcs3/Emu/RSX/GL/GLTextureCache.h index 704589cccf..8bfc92f902 100644 --- a/rpcs3/Emu/RSX/GL/GLTextureCache.h +++ b/rpcs3/Emu/RSX/GL/GLTextureCache.h @@ -745,6 +745,7 @@ namespace gl gl::upload_texture(cmd, section->get_raw_texture(), gcm_format, input_swizzled, subresource_layout); + section->get_raw_texture()->set_name(fmt::format("Raw Texture @0x%x", rsx_range.start)); section->last_write_tag = rsx::get_shared_tag(); return section; } diff --git a/rpcs3/Emu/RSX/GL/glutils/image.cpp b/rpcs3/Emu/RSX/GL/glutils/image.cpp index 4760bb1cc9..e99a6e15b2 100644 --- a/rpcs3/Emu/RSX/GL/glutils/image.cpp +++ b/rpcs3/Emu/RSX/GL/glutils/image.cpp @@ -411,7 +411,7 @@ namespace gl auto result = view.get(); views.emplace(key, std::move(view)); - result->set_name(fmt::format("%s_%x", name(), remap.encoded)); + result->set_name(fmt::format("%s, remap=%x", name(), remap.encoded)); return result; } From cae8ae63e343ec8acc479016c91a8d93f301b7ed Mon Sep 17 00:00:00 2001 From: kd-11 <15904127+kd-11@users.noreply.github.com> Date: Sat, 7 Mar 2026 13:16:39 +0300 Subject: [PATCH 109/175] gl: Use image dimensions to determine read buffer size --- rpcs3/Emu/RSX/Overlays/overlay_controls.h | 1 - 1 file changed, 1 deletion(-) diff --git a/rpcs3/Emu/RSX/Overlays/overlay_controls.h b/rpcs3/Emu/RSX/Overlays/overlay_controls.h index dd9dd98f4d..f64fdfa47f 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_controls.h +++ b/rpcs3/Emu/RSX/Overlays/overlay_controls.h @@ -60,7 +60,6 @@ namespace rsx void load_data(const std::vector& bytes, bool grayscaled = false); const u8* get_data() const override { return channels == 4 ? data : data_grey.empty() ? nullptr : data_grey.data(); } - usz size_bytes() const override { return data_grey.size(); } }; struct resource_config From 7dad9663b2f411458f79a10b1f341d95e153baf7 Mon Sep 17 00:00:00 2001 From: capriots <29807355+capriots@users.noreply.github.com> Date: Sat, 19 Jul 2025 13:59:21 +0200 Subject: [PATCH 110/175] cellDmuxPamf implementation part 1: SPU thread --- rpcs3/Emu/Cell/Modules/cellDmux.h | 4 +- rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp | 1145 ++++++++++++++++++++++- rpcs3/Emu/Cell/Modules/cellDmuxPamf.h | 661 +++++++++++++ rpcs3/Emu/Cell/Modules/cellPamf.h | 1 + rpcs3/Emu/savestate_utils.cpp | 3 +- 5 files changed, 1789 insertions(+), 25 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/cellDmux.h b/rpcs3/Emu/Cell/Modules/cellDmux.h index 1767165283..7c31bbf105 100644 --- a/rpcs3/Emu/Cell/Modules/cellDmux.h +++ b/rpcs3/Emu/Cell/Modules/cellDmux.h @@ -301,7 +301,7 @@ using CellDmuxCoreOpResetStream = error_code(vm::ptr); using CellDmuxCoreOpCreateThread = error_code(vm::ptr); using CellDmuxCoreOpJoinThread = error_code(vm::ptr); using CellDmuxCoreOpSetStream = error_code(vm::ptr, vm::cptr, u32, b8, u64); -using CellDmuxCoreOpFreeMemory = error_code(vm::ptr, vm::ptr, u32); +using CellDmuxCoreOpReleaseAu = error_code(vm::ptr, vm::ptr, u32); using CellDmuxCoreOpQueryEsAttr = error_code(vm::cptr, vm::cptr, vm::ptr); using CellDmuxCoreOpEnableEs = error_code(vm::ptr, vm::cptr, vm::cptr, vm::cptr>, vm::cptr>, vm::cptr, vm::pptr); using CellDmuxCoreOpDisableEs = u32(vm::ptr); @@ -318,7 +318,7 @@ struct CellDmuxCoreOps vm::bptr createThread; vm::bptr joinThread; vm::bptr setStream; - vm::bptr freeMemory; + vm::bptr releaseAu; vm::bptr queryEsAttr; vm::bptr enableEs; vm::bptr disableEs; diff --git a/rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp b/rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp index 70162d4031..7c0fd8ec39 100644 --- a/rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp +++ b/rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp @@ -1,16 +1,1126 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -#include "Emu/IdManager.h" +#include "Emu/Cell/lv2/sys_sync.h" -#include "cellDmux.h" #include "cellDmuxPamf.h" - +#include vm::gvar g_cell_dmux_core_ops_pamf; vm::gvar g_cell_dmux_core_ops_raw_es; LOG_CHANNEL(cellDmuxPamf) +inline std::pair dmuxPamfStreamIdToTypeChannel(u16 stream_id, u16 private_stream_id) +{ + if ((stream_id & 0xf0) == 0xe0) + { + return { DMUX_PAMF_STREAM_TYPE_INDEX_VIDEO, stream_id & 0x0f }; + } + + if ((stream_id & 0xff) != 0xbd) + { + return { DMUX_PAMF_STREAM_TYPE_INDEX_INVALID, 0 }; + } + + switch (private_stream_id & 0xf0) + { + case 0x40: return { DMUX_PAMF_STREAM_TYPE_INDEX_LPCM, private_stream_id & 0x0f }; + case 0x30: return { DMUX_PAMF_STREAM_TYPE_INDEX_AC3, private_stream_id & 0x0f }; + case 0x00: return { DMUX_PAMF_STREAM_TYPE_INDEX_ATRACX, private_stream_id & 0x0f }; + case 0x20: return { DMUX_PAMF_STREAM_TYPE_INDEX_USER_DATA, private_stream_id & 0x0f }; + default: return { DMUX_PAMF_STREAM_TYPE_INDEX_INVALID, 0 }; + } +} + + +// SPU thread + +void dmux_pamf_base::output_queue::pop_back(u32 au_size) +{ + ensure(back - au_size >= buffer.data(), "Invalid au_size"); + back -= au_size; +} + +void dmux_pamf_base::output_queue::pop_back(u8* au_addr) +{ + ensure(au_addr >= buffer.data() && au_addr < std::to_address(buffer.end()), "Invalid au_addr"); + + // If au_begin is in front of the back pointer, unwrap the back pointer (there are no more access units behind the back pointer) + if (au_addr > back) + { + wrap_pos = buffer.data(); + } + + back = au_addr; +} + +void dmux_pamf_base::output_queue::pop_front(u32 au_size) +{ + ensure(front + au_size <= std::to_address(buffer.end()), "Invalid au_size"); + front += au_size; + + // When front reaches wrap_pos, unwrap the queue + if (wrap_pos != buffer.data() && wrap_pos <= front) + { + ensure(wrap_pos == front, "Invalid au_size"); + front = buffer.data(); + wrap_pos = buffer.data(); + } +} + +void dmux_pamf_base::output_queue::push_unchecked(const access_unit_chunk& au_chunk) +{ + std::ranges::copy(au_chunk.cached_data, back); + std::ranges::copy(au_chunk.data, back + au_chunk.cached_data.size()); + back += au_chunk.data.size() + au_chunk.cached_data.size(); +} + +bool dmux_pamf_base::output_queue::push(const access_unit_chunk& au_chunk, const std::function& on_fatal_error) +{ + // If there are any unconsumed access units behind the back pointer, the distance between the front and back pointers is the remaining capacity, + // otherwise the distance between the end of the buffer and the back pointer is the remaining capacity + if (wrap_pos == buffer.data()) + { + // Since it was already checked if there is enough space for au_max_size, this can only occur if the current access unit is larger than au_max_size + if (au_chunk.data.size() + au_chunk.cached_data.size() > static_cast(std::to_address(buffer.end()) - back)) + { + cellDmuxPamf.error("Access unit larger than specified maximum access unit size"); + on_fatal_error(); + return false; + } + } + else if (au_chunk.data.size() + au_chunk.cached_data.size() + 0x10 > static_cast(front - back)) // + sizeof(v128) because of SPU shenanigans probably + { + return false; + } + + push_unchecked(au_chunk); + return true; +} + +bool dmux_pamf_base::output_queue::prepare_next_au(u32 au_max_size) +{ + // LLE always checks the distance between the end of the buffer and the back pointer, even if the back pointer is wrapped around and there are unconsumed access units behind it + if (std::to_address(buffer.end()) - back < au_max_size) + { + // Can't wrap the back pointer around again as long as there are unconsumed access units behind it + if (wrap_pos != buffer.data()) + { + return false; + } + + wrap_pos = back; + back = buffer.data(); + } + + return true; +} + +void dmux_pamf_base::elementary_stream::flush_es() +{ + if (current_au.accumulated_size != 0) + { + ensure(au_queue.get_free_size() >= cache.size()); + au_queue.push_unchecked({ {}, cache }); + + current_au.accumulated_size += static_cast(cache.size()); + + ctx.on_au_found(get_stream_id().first, get_stream_id().second, user_data, { au_queue.peek_back(current_au.accumulated_size), current_au.accumulated_size }, current_au.pts, current_au.dts, + current_au.rap, au_specific_info_size, current_au.au_specific_info_buf); + } + + reset(); + + while (!ctx.on_flush_done(get_stream_id().first, get_stream_id().second, user_data)) {} // The flush_done event is repeatedly fired until it succeeds +} + +void dmux_pamf_base::elementary_stream::reset_es(u8* au_addr) +{ + if (!au_addr) + { + reset(); + au_queue.clear(); + } + else + { + au_queue.pop_back(au_addr); + } +} + +void dmux_pamf_base::elementary_stream::discard_access_unit() +{ + au_queue.pop_back(current_au.accumulated_size - static_cast(au_chunk.data.size() + au_chunk.cached_data.size())); + reset(); + cache.clear(); +} + +template +u32 dmux_pamf_base::elementary_stream::parse_audio_stream_header(std::span pes_packet_data) +{ + u32 extra_header_size_unk = 0; // No clue what this is, I have not found a single instance in any PAMF stream where it is something other than zero + + if (!au_size_unk) // For some reason, LLE uses the member that stores the size of user data access units here as bool + { + // Not checked on LLE + if (pes_packet_data.size() < sizeof(u32)) + { + return umax; + } + + extra_header_size_unk = read_from_ptr>(pes_packet_data) & extra_header_size_unk_mask; + au_size_unk = true; + } + + return extra_header_size_unk + sizeof(u32); +} + +bool dmux_pamf_base::elementary_stream::process_pes_packet_data() +{ + ensure(pes_packet_data, "set_pes_packet_data() should be used before process_stream()"); + + for (;;) + { + switch (state) + { + case state::initial: + if (stream_chunk.empty()) + { + pes_packet_data.reset(); + return true; + } + + // Parse the current stream section and increment the reading position by the amount that was consumed + stream_chunk = stream_chunk.subspan(parse_stream(stream_chunk)); + + current_au.accumulated_size += static_cast(au_chunk.data.size() + au_chunk.cached_data.size()); + + // If the beginning of a new access unit was found, set the current timestamps and rap indicator + if (!current_au.timestamps_rap_set && (current_au.state == access_unit::state::commenced || current_au.state == access_unit::state::m2v_sequence + || (current_au.state == access_unit::state::complete && au_chunk.cached_data.empty()))) + { + set_au_timestamps_rap(); + } + + state = state::pushing_au_queue; + [[fallthrough]]; + + case state::pushing_au_queue: + if (!au_chunk.data.empty() || !au_chunk.cached_data.empty()) + { + if (!au_queue.push(au_chunk, std::bind_front(&dmux_pamf_base::on_fatal_error, &ctx))) + { + ctx.on_au_queue_full(); + return false; + } + + au_chunk.data = {}; + au_chunk.cached_data.clear(); + } + + // This happens if the distance between two delimiters is greater than the size indicated in the info header of the stream. + if (current_au.state == access_unit::state::size_mismatch) + { + // LLE cuts off one byte from the beginning of the current PES packet data and then starts over. + pes_packet_data = pes_packet_data->subspan<1>(); + stream_chunk = *pes_packet_data; + + // It also removes the entire current access unit from the queue, even if it began in an earlier PES packet + au_queue.pop_back(current_au.accumulated_size); + current_au.accumulated_size = 0; + + state = state::initial; + continue; + } + + state = state::notifying_au_found; + [[fallthrough]]; + + case state::notifying_au_found: + if (current_au.state == access_unit::state::complete && !ctx.on_au_found(get_stream_id().first, get_stream_id().second, user_data, + { au_queue.peek_back(current_au.accumulated_size), current_au.accumulated_size }, current_au.pts, current_au.dts, current_au.rap, au_specific_info_size, current_au.au_specific_info_buf)) + { + return false; + } + + state = state::preparing_for_next_au; + [[fallthrough]]; + + case state::preparing_for_next_au: + if (current_au.state == access_unit::state::complete) + { + if (!au_queue.prepare_next_au(au_max_size)) + { + ctx.on_au_queue_full(); + return false; + } + + current_au = {}; + } + + state = state::initial; + } + } +} + +template +u32 dmux_pamf_base::video_stream::parse_stream(std::span stream) +{ + if (current_au.state != access_unit::state::none && (avc || current_au.state != access_unit::state::m2v_sequence)) + { + current_au.state = access_unit::state::incomplete; + } + + // Concatenate the cache of the previous stream section and the beginning of the current section + std::array buf{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; // Prevent false positives (M2V pic start code ends with 0x00) + ensure(cache.size() <= 3, "The size of the cache should never exceed three bytes"); + std::ranges::copy(cache, buf.begin()); + std::copy_n(stream.begin(), std::min(sizeof(u32) - 1, stream.size()), buf.begin() + cache.size()); // Not entirely accurate: LLE always reads three bytes from the stream, even if it is smaller than that + + auto au_chunk_begin = stream.begin(); + s32 cache_idx = 0; + auto stream_it = stream.begin(); + [&] + { + // Search for delimiter in cache + for (; cache_idx < static_cast(cache.size()); cache_idx++) + { + if (const be_t code = read_from_ptr>(buf.data() + cache_idx); + (avc && code == AVC_AU_DELIMITER) || (!avc && (code == M2V_PIC_START || code == M2V_SEQUENCE_HEADER || code == M2V_SEQUENCE_END))) + { + if (current_au.state != access_unit::state::none && (avc || current_au.state != access_unit::state::m2v_sequence)) + { + // The sequence end code is included in the access unit + // LLE increments the stream pointer instead of the cache index, which will cause the access unit to be corrupted at the end + if (!avc && code == M2V_SEQUENCE_END) + { + cellDmuxPamf.warning("M2V sequence end code in cache"); + stream_it += std::min(sizeof(u32), stream.size()); // Not accurate, LLE always increments by four, regardless of the stream size + } + + current_au.state = access_unit::state::complete; + return; + } + + // If current_au.state is none and there was a delimiter found here, then LLE outputs the entire cache, even if the access unit starts at cache_idx > 0 + + current_au.state = avc || code == M2V_PIC_START ? access_unit::state::commenced : access_unit::state::m2v_sequence; + } + } + + // Search for delimiter in stream + for (; stream_it <= stream.end() - sizeof(u32); stream_it++) + { + if (const be_t code = read_from_ptr>(stream_it); + (avc && code == AVC_AU_DELIMITER) || (!avc && (code == M2V_PIC_START || code == M2V_SEQUENCE_HEADER || code == M2V_SEQUENCE_END))) + { + if (current_au.state != access_unit::state::none && (avc || current_au.state != access_unit::state::m2v_sequence)) + { + stream_it += !avc && code == M2V_SEQUENCE_END ? sizeof(u32) : 0; // The sequence end code is included in the access unit + current_au.state = access_unit::state::complete; + return; + } + + au_chunk_begin = avc || current_au.state == access_unit::state::none ? stream_it : au_chunk_begin; + current_au.state = avc || code == M2V_PIC_START ? access_unit::state::commenced : access_unit::state::m2v_sequence; + } + } + }(); + + if (current_au.state != access_unit::state::none) + { + au_chunk.data = { au_chunk_begin, stream_it }; + std::copy_n(cache.begin(), cache_idx, std::back_inserter(au_chunk.cached_data)); + cache.erase(cache.begin(), cache.begin() + cache_idx); + } + + // Cache the end of the stream if an access unit wasn't completed. There could be the beginning of a delimiter in the last three bytes + if (current_au.state != access_unit::state::complete) + { + std::copy(stream_it, stream.end(), std::back_inserter(cache)); + } + + return static_cast((current_au.state != access_unit::state::complete || stream_it > stream.end() ? stream.end() : stream_it) - stream.begin()); +} + +u32 dmux_pamf_base::lpcm_stream::parse_stream_header(std::span pes_packet_data, [[maybe_unused]] s8 pts_dts_flag) +{ + // Not checked on LLE + if (pes_packet_data.size() < sizeof(u8) + 0x10) + { + return umax; + } + + std::memcpy(au_specific_info_buf.data(), &pes_packet_data[1], au_specific_info_buf.size()); + return parse_audio_stream_header<0x7ff>(pes_packet_data); +} + +u32 dmux_pamf_base::lpcm_stream::parse_stream(std::span stream) +{ + if (current_au.state == access_unit::state::none) + { + current_au.au_specific_info_buf = au_specific_info_buf; + } + + if (au_max_size - current_au.accumulated_size > stream.size()) + { + au_chunk.data = stream; + current_au.state = current_au.state == access_unit::state::none ? access_unit::state::commenced : access_unit::state::incomplete; + } + else + { + au_chunk.data = stream.first(au_max_size - current_au.accumulated_size); + current_au.state = access_unit::state::complete; + } + + return static_cast(au_chunk.data.size()); +} + +template +u32 dmux_pamf_base::audio_stream::parse_stream(std::span stream) +{ + const auto parse_au_size = [](be_t data) -> u16 + { + if constexpr (ac3) + { + if (const u8 fscod = data >> 14, frmsizecod = data >> 8 & 0x3f; fscod < 3 && frmsizecod < 38) + { + return AC3_FRMSIZE_TABLE[fscod][frmsizecod] * sizeof(s16); + } + } + else if ((data & 0x3ff) < 0x200) + { + return ((data & 0x3ff) + 1) * 8 + ATRACX_ATS_HEADER_SIZE; + } + + return 0; + }; + + if (current_au.state != access_unit::state::none) + { + current_au.state = access_unit::state::incomplete; + } + + // Concatenate the cache of the previous stream section and the beginning of the current section + std::array buf{}; + ensure(cache.size() <= 3, "The size of the cache should never exceed three bytes"); + std::ranges::copy(cache, buf.begin()); + std::copy_n(stream.begin(), std::min(sizeof(u16) - 1, stream.size()), buf.begin() + cache.size()); + + auto au_chunk_begin = stream.begin(); + s32 cache_idx = 0; + auto stream_it = stream.begin(); + [&] + { + // Search for delimiter in cache + for (; cache_idx <= static_cast(cache.size() + std::min(sizeof(u16) - 1, stream.size()) - sizeof(u16)); cache_idx++) + { + if (const be_t tmp = read_from_ptr>(buf.data() + cache_idx); current_au.size_info_offset != 0) + { + if (--current_au.size_info_offset == 0) + { + current_au.parsed_size = parse_au_size(tmp); + } + } + else if (tmp == SYNC_WORD) + { + if (current_au.state == access_unit::state::none) + { + // If current_au.state is none and there was a delimiter found here, then LLE outputs the entire cache, even if the access unit starts at cache_idx > 0 + + current_au.size_info_offset = ac3 ? sizeof(u16) * 2 : sizeof(u16); + current_au.state = access_unit::state::commenced; + } + else if (const u32 au_size = current_au.accumulated_size + cache_idx; au_size >= current_au.parsed_size) + { + current_au.state = au_size == current_au.parsed_size ? access_unit::state::complete : access_unit::state::size_mismatch; + return; + } + } + } + + // As long as the current access unit hasn't reached the size indicated in its header, we don't need to parse the stream + if (current_au.state != access_unit::state::none && current_au.size_info_offset == 0 && current_au.accumulated_size + cache.size() < current_au.parsed_size) + { + stream_it += std::min(current_au.parsed_size - current_au.accumulated_size - cache.size(), stream.size() - sizeof(u32)); + } + + // Search for delimiter in stream + for (; stream_it <= stream.end() - sizeof(u32); stream_it++) // LLE uses sizeof(u32), even though the delimiter is only two bytes large + { + if (const be_t tmp = read_from_ptr>(stream_it); current_au.size_info_offset != 0) + { + if (--current_au.size_info_offset == 0) + { + current_au.parsed_size = parse_au_size(tmp); + } + } + else if (tmp == SYNC_WORD) + { + if (current_au.state == access_unit::state::none) + { + au_chunk_begin = stream_it; + current_au.size_info_offset = ac3 ? sizeof(u16) * 2 : sizeof(u16); + current_au.state = access_unit::state::commenced; + } + else if (const u32 au_size = static_cast(current_au.accumulated_size + stream_it - au_chunk_begin + cache.size()); au_size >= current_au.parsed_size) + { + current_au.state = au_size == current_au.parsed_size ? access_unit::state::complete : access_unit::state::size_mismatch; + return; + } + } + } + }(); + + if (current_au.state != access_unit::state::none) + { + au_chunk.data = { au_chunk_begin, stream_it }; + std::copy_n(cache.begin(), cache_idx, std::back_inserter(au_chunk.cached_data)); + cache.erase(cache.begin(), cache.begin() + cache_idx); + } + + // Cache the end of the stream if an access unit wasn't completed. There could be the beginning of a delimiter in the last three bytes + if (current_au.state != access_unit::state::complete && current_au.state != access_unit::state::size_mismatch) + { + std::copy(stream_it, stream.end(), std::back_inserter(cache)); + } + + return static_cast((current_au.state != access_unit::state::complete ? stream.end() : stream_it) - stream.begin()); +} + +u32 dmux_pamf_base::user_data_stream::parse_stream_header(std::span pes_packet_data, s8 pts_dts_flag) +{ + if (pts_dts_flag < 0) // PTS field exists + { + // Not checked on LLE + if (pes_packet_data.size() < 2 + sizeof(u32)) + { + return umax; + } + + au_size_unk = read_from_ptr>(pes_packet_data.begin() + 2) - sizeof(u32); + return 10; + } + + return 2; +} + +u32 dmux_pamf_base::user_data_stream::parse_stream(std::span stream) +{ + if (au_size_unk > stream.size()) + { + au_chunk.data = stream; + au_size_unk -= static_cast(stream.size()); + current_au.state = access_unit::state::commenced; // User data streams always use commenced + } + else + { + au_chunk.data = stream.first(au_size_unk); + au_size_unk = 0; + current_au.state = access_unit::state::complete; + } + + return static_cast(stream.size()); // Always consume the entire stream +} + +bool dmux_pamf_base::enable_es(u32 stream_id, u32 private_stream_id, bool is_avc, std::span au_queue_buffer, u32 au_max_size, bool raw_es, u32 user_data) +{ + const auto [type_idx, channel] = dmuxPamfStreamIdToTypeChannel(stream_id, private_stream_id); + + if (type_idx == DMUX_PAMF_STREAM_TYPE_INDEX_INVALID || elementary_stream::is_enabled(elementary_streams[type_idx][channel])) + { + return false; + } + + this->raw_es = raw_es; + pack_es_type_idx = type_idx; + + switch (type_idx) + { + case DMUX_PAMF_STREAM_TYPE_INDEX_VIDEO: + elementary_streams[0][channel] = is_avc ? static_cast>(std::make_unique>(channel, au_max_size, *this, user_data, au_queue_buffer)) + : std::make_unique>(channel, au_max_size, *this, user_data, au_queue_buffer); + return true; + + case DMUX_PAMF_STREAM_TYPE_INDEX_LPCM: elementary_streams[1][channel] = std::make_unique(channel, au_max_size, *this, user_data, au_queue_buffer); return true; + case DMUX_PAMF_STREAM_TYPE_INDEX_AC3: elementary_streams[2][channel] = std::make_unique>(channel, au_max_size, *this, user_data, au_queue_buffer); return true; + case DMUX_PAMF_STREAM_TYPE_INDEX_ATRACX: elementary_streams[3][channel] = std::make_unique>(channel, au_max_size, *this, user_data, au_queue_buffer); return true; + case DMUX_PAMF_STREAM_TYPE_INDEX_USER_DATA: elementary_streams[4][channel] = std::make_unique(channel, au_max_size, *this, user_data, au_queue_buffer); return true; + default: fmt::throw_exception("Unreachable"); + } +} + +bool dmux_pamf_base::disable_es(u32 stream_id, u32 private_stream_id) +{ + const auto [type_idx, channel] = dmuxPamfStreamIdToTypeChannel(stream_id, private_stream_id); + + if (type_idx == DMUX_PAMF_STREAM_TYPE_INDEX_INVALID || !elementary_stream::is_enabled(elementary_streams[type_idx][channel])) + { + return false; + } + + elementary_streams[type_idx][channel] = nullptr; + return true; +} + +bool dmux_pamf_base::release_au(u32 stream_id, u32 private_stream_id, u32 au_size) const +{ + const auto [type_idx, channel] = dmuxPamfStreamIdToTypeChannel(stream_id, private_stream_id); + + if (type_idx == DMUX_PAMF_STREAM_TYPE_INDEX_INVALID || !elementary_stream::is_enabled(elementary_streams[type_idx][channel])) + { + return false; + } + + elementary_streams[type_idx][channel]->release_au(au_size); + return true; +} + +bool dmux_pamf_base::flush_es(u32 stream_id, u32 private_stream_id) +{ + const auto [type_idx, channel] = dmuxPamfStreamIdToTypeChannel(stream_id, private_stream_id); + + if (type_idx == DMUX_PAMF_STREAM_TYPE_INDEX_INVALID || !elementary_stream::is_enabled(elementary_streams[type_idx][channel])) + { + return false; + } + + state = state::initial; + elementary_streams[type_idx][channel]->flush_es(); + return true; +} + +void dmux_pamf_base::set_stream(std::span stream, bool continuity) +{ + if (!continuity) + { + std::ranges::for_each(elementary_streams | std::views::join | std::views::filter(elementary_stream::is_enabled), &elementary_stream::discard_access_unit); + } + + state = state::initial; + + // Not checked on LLE, it would parse old memory contents or uninitialized memory if the size of the input stream set by the user is not a multiple of 0x800. + // Valid PAMF streams are always a multiple of 0x800 bytes large. + if ((stream.size() & 0x7ff) != 0) + { + cellDmuxPamf.warning("Invalid stream size"); + } + + this->stream = stream; + demux_done_notified = false; +} + +void dmux_pamf_base::reset_stream() +{ + std::ranges::for_each(elementary_streams | std::views::join | std::views::filter(elementary_stream::is_enabled), &elementary_stream::discard_access_unit); + state = state::initial; + stream.reset(); +} + +bool dmux_pamf_base::reset_es(u32 stream_id, u32 private_stream_id, u8* au_addr) +{ + const auto [type_idx, channel] = dmuxPamfStreamIdToTypeChannel(stream_id, private_stream_id); + + if (type_idx == DMUX_PAMF_STREAM_TYPE_INDEX_INVALID || !elementary_stream::is_enabled(elementary_streams[type_idx][channel])) + { + return false; + } + + if (!au_addr) + { + state = state::initial; + } + + elementary_streams[type_idx][channel]->reset_es(au_addr); + return true; +} + +bool dmux_pamf_base::process_next_pack() +{ + if (!stream) + { + demux_done_notified = demux_done_notified || on_demux_done(); + return true; + } + + switch (state) + { + case state::initial: + { + // Search for the next pack start code or prog end code + std::span pack{ static_cast(nullptr), PACK_SIZE }; // This initial value is not used, can't be default constructed + + for (;;) + { + if (stream->empty()) + { + stream.reset(); + demux_done_notified = on_demux_done(); + return true; + } + + pack = stream->subspan<0, PACK_SIZE>(); + stream = stream->subspan(); + + // If the input stream is a raw elementary stream, skip everything MPEG-PS related and go straight to elementary stream parsing + if (raw_es) + { + if (elementary_stream::is_enabled(elementary_streams[pack_es_type_idx][0])) + { + elementary_streams[pack_es_type_idx][0]->set_pes_packet_data(pack); + } + + state = state::elementary_stream; + return true; + } + + // While LLE is actually searching the entire section for a pack start code or program end code, + // it doesn't set its current reading position to the address where it found the code, so it would bug out if there isn't one at the start of the section + + if (const be_t code = read_from_ptr>(pack); code == PACK_START) + { + break; + } + else if (code == PROG_END) + { + if (!on_prog_end()) + { + state = state::prog_end; + } + + return true; + } + + cellDmuxPamf.warning("No start code found at the beginning of the current section"); + } + + // Skip over pack header + const u8 pack_stuffing_length = read_from_ptr(pack.subspan()) & 0x7; + std::span current_pes_packet = pack.subspan(PACK_STUFFING_LENGTH_OFFSET + sizeof(u8) + pack_stuffing_length); + + if (read_from_ptr>(current_pes_packet) >> 8 != PACKET_START_CODE_PREFIX) + { + cellDmuxPamf.error("Invalid start code after pack header"); + return false; + } + + // Skip over system header if present + if (read_from_ptr>(current_pes_packet) == SYSTEM_HEADER) + { + const u32 system_header_length = read_from_ptr>(current_pes_packet.begin() + PES_PACKET_LENGTH_OFFSET) + PES_PACKET_LENGTH_OFFSET + sizeof(u16); + + // Not checked on LLE, the SPU task would just increment the reading position and read random data in the SPU local store + if (system_header_length + PES_HEADER_DATA_LENGTH_OFFSET + sizeof(u8) > current_pes_packet.size()) + { + cellDmuxPamf.error("Invalid system header length"); + return false; + } + + current_pes_packet = current_pes_packet.subspan(system_header_length); + + // The SPU thread isn't doing load + rotate here for 4-byte loading (in valid PAMF streams, the next start code after a system header is always 0x10 byte aligned) + const u32 offset_low = (current_pes_packet.data() - pack.data()) & 0xf; + current_pes_packet = { current_pes_packet.begin() - offset_low, current_pes_packet.end() }; + + if (const be_t code = read_from_ptr>(current_pes_packet); code >> 8 != PACKET_START_CODE_PREFIX) + { + cellDmuxPamf.error("Invalid start code after system header"); + return false; + } + else if (code == PRIVATE_STREAM_2) + { + // A system header is optionally followed by a private stream 2 + // The first two bytes of the stream are the stream id of a video stream. The next access unit of that stream is a random access point/keyframe + + const u16 pes_packet_length = read_from_ptr>(current_pes_packet.begin() + PES_PACKET_LENGTH_OFFSET) + PES_PACKET_LENGTH_OFFSET + sizeof(u16); + + // Not checked on LLE, the SPU task would just increment the reading position and read random data in the SPU local store + if (pes_packet_length + PES_HEADER_DATA_LENGTH_OFFSET + sizeof(u8) > current_pes_packet.size()) + { + cellDmuxPamf.error("Invalid private stream 2 length"); + return false; + } + + if (const u8 channel = read_from_ptr>(current_pes_packet.begin() + PES_PACKET_LENGTH_OFFSET + sizeof(u16)) & 0xf; + elementary_stream::is_enabled(elementary_streams[0][channel])) + { + elementary_streams[0][channel]->set_rap(); + } + + current_pes_packet = current_pes_packet.subspan(pes_packet_length); + } + } + + // Parse PES packet + // LLE only parses the first PES packet per pack (valid PAMF streams only have one PES packet per pack, not including the system header + private stream 2) + + const u32 pes_packet_start_code = read_from_ptr>(current_pes_packet); + + if (pes_packet_start_code >> 8 != PACKET_START_CODE_PREFIX) + { + cellDmuxPamf.error("Invalid start code"); + return false; + } + + // The size of the stream is not checked here because if coming from a pack header, it is guaranteed that there is enough space, + // and if coming from a system header or private stream 2, it was already checked above + const u16 pes_packet_length = read_from_ptr>(current_pes_packet.begin() + PES_PACKET_LENGTH_OFFSET) + PES_PACKET_LENGTH_OFFSET + sizeof(u16); + const u8 pes_header_data_length = read_from_ptr(current_pes_packet.begin() + PES_HEADER_DATA_LENGTH_OFFSET) + PES_HEADER_DATA_LENGTH_OFFSET + sizeof(u8); + + // Not checked on LLE, the SPU task would just increment the reading position and read random data in the SPU local store + if (pes_packet_length > current_pes_packet.size() || pes_packet_length <= pes_header_data_length) + { + cellDmuxPamf.error("Invalid pes packet length"); + return false; + } + + const std::span pes_packet_data = current_pes_packet.subspan(pes_header_data_length, pes_packet_length - pes_header_data_length); + + const auto [type_idx, channel] = dmuxPamfStreamIdToTypeChannel(pes_packet_start_code, read_from_ptr(pes_packet_data)); + + if (type_idx == DMUX_PAMF_STREAM_TYPE_INDEX_INVALID) + { + cellDmuxPamf.error("Invalid stream type"); + return false; + } + + pack_es_type_idx = type_idx; + pack_es_channel = channel; + + if (elementary_stream::is_enabled(elementary_streams[type_idx][channel])) + { + const s8 pts_dts_flag = read_from_ptr(current_pes_packet.begin() + PTS_DTS_FLAG_OFFSET); + + if (pts_dts_flag < 0) + { + // The timestamps should be unsigned, but are sign-extended from s32 to u64 on LLE. They probably forgot about integer promotion + const s32 PTS_32_30 = read_from_ptr(current_pes_packet.begin() + 9) >> 1; + const s32 PTS_29_15 = read_from_ptr>(current_pes_packet.begin() + 10) >> 1; + const s32 PTS_14_0 = read_from_ptr>(current_pes_packet.begin() + 12) >> 1; + + elementary_streams[type_idx][channel]->set_pts(PTS_32_30 << 30 | PTS_29_15 << 15 | PTS_14_0); // Bit 32 is discarded + } + + if (pts_dts_flag & 0x40) + { + const s32 DTS_32_30 = read_from_ptr(current_pes_packet.begin() + 14) >> 1; + const s32 DTS_29_15 = read_from_ptr>(current_pes_packet.begin() + 15) >> 1; + const s32 DTS_14_0 = read_from_ptr>(current_pes_packet.begin() + 17) >> 1; + + elementary_streams[type_idx][channel]->set_dts(DTS_32_30 << 30 | DTS_29_15 << 15 | DTS_14_0); // Bit 32 is discarded + } + + const usz stream_header_size = elementary_streams[type_idx][channel]->parse_stream_header(pes_packet_data, pts_dts_flag); + + // Not checked on LLE, the SPU task would just increment the reading position and read random data in the SPU local store + if (stream_header_size > pes_packet_data.size()) + { + cellDmuxPamf.error("Invalid stream header size"); + return false; + } + + elementary_streams[type_idx][channel]->set_pes_packet_data(pes_packet_data.subspan(stream_header_size)); + } + + state = state::elementary_stream; + [[fallthrough]]; + } + case state::elementary_stream: + { + if (!elementary_stream::is_enabled(elementary_streams[pack_es_type_idx][pack_es_channel]) || elementary_streams[pack_es_type_idx][pack_es_channel]->process_pes_packet_data()) + { + state = state::initial; + } + + return true; + } + case state::prog_end: + { + if (on_prog_end()) + { + state = state::initial; + } + + return true; + } + default: + fmt::throw_exception("Unreachable"); + } +} + +u32 dmux_pamf_base::get_enabled_es_count() const +{ + return static_cast(std::ranges::count_if(elementary_streams | std::views::join, elementary_stream::is_enabled)); +} + +bool dmux_pamf_spu_context::get_next_cmd(DmuxPamfCommand& lhs, bool new_stream) const +{ + cellDmuxPamf.trace("Getting next command"); + + if (cmd_queue->pop(lhs)) + { + cellDmuxPamf.trace("Command type: %d", static_cast(lhs.type.get())); + return true; + } + + if ((new_stream || has_work()) && !wait_for_au_queue && !wait_for_event_queue) + { + cellDmuxPamf.trace("No new command, continuing demuxing"); + return false; + } + + cellDmuxPamf.trace("No new command and nothing to do, waiting..."); + + cmd_queue->wait(); + + if (thread_ctrl::state() == thread_state::aborting) + { + return false; + } + + ensure(cmd_queue->pop(lhs)); + + cellDmuxPamf.trace("Command type: %d", static_cast(lhs.type.get())); + return true; +} + +bool dmux_pamf_spu_context::send_event(auto&&... args) const +{ + if (event_queue->size() >= max_enqueued_events) + { + return false; + } + + return ensure(event_queue->emplace(std::forward(args)..., event_queue_was_too_full)); +} + +void dmux_pamf_spu_context::operator()() // cellSpursMain() +{ + DmuxPamfCommand cmd; + + while (thread_ctrl::state() != thread_state::aborting) + { + if (get_next_cmd(cmd, new_stream)) + { + event_queue_was_too_full = wait_for_event_queue; + wait_for_event_queue = false; + wait_for_au_queue = false; + + ensure(cmd_result_queue->emplace(static_cast(cmd.type.value()) + 1)); + + switch (cmd.type) + { + case DmuxPamfCommandType::enable_es: + max_enqueued_events += 2; + enable_es(cmd.enable_es.stream_id, cmd.enable_es.private_stream_id, cmd.enable_es.is_avc, { cmd.enable_es.au_queue_buffer.get_ptr(), cmd.enable_es.au_queue_buffer_size }, + cmd.enable_es.au_max_size, cmd.enable_es.is_raw_es, cmd.enable_es.user_data); + break; + + case DmuxPamfCommandType::disable_es: + disable_es(cmd.disable_flush_es.stream_id, cmd.disable_flush_es.private_stream_id); + max_enqueued_events -= 2; + break; + + case DmuxPamfCommandType::set_stream: + new_stream = true; + break; + + case DmuxPamfCommandType::release_au: + release_au(cmd.release_au.stream_id, cmd.release_au.private_stream_id, cmd.release_au.au_size); + break; + + case DmuxPamfCommandType::flush_es: + flush_es(cmd.disable_flush_es.stream_id, cmd.disable_flush_es.private_stream_id); + break; + + case DmuxPamfCommandType::close: + while (!send_event(DmuxPamfEventType::close)) {} + return; + + case DmuxPamfCommandType::reset_stream: + reset_stream(); + break; + + case DmuxPamfCommandType::reset_es: + reset_es(cmd.reset_es.stream_id, cmd.reset_es.private_stream_id, cmd.reset_es.au_addr ? cmd.reset_es.au_addr.get_ptr() : nullptr); + break; + + case DmuxPamfCommandType::resume: + break; + + default: + cellDmuxPamf.error("Invalid command"); + return; + } + } + else if (thread_ctrl::state() == thread_state::aborting) + { + return; + } + + // Only set the new stream once the previous one has been entirely consumed + if (new_stream && !has_work()) + { + new_stream = false; + + DmuxPamfStreamInfo stream_info; + ensure(stream_info_queue->pop(stream_info)); + + set_stream({ stream_info.stream_addr.get_ptr(), stream_info.stream_size }, stream_info.continuity); + } + + process_next_pack(); + } +} + +void dmux_pamf_base::elementary_stream::save(utils::serial& ar) +{ + // These need to be saved first since they need to be initialized in the constructor's initializer list + if (ar.is_writing()) + { + ar(au_max_size, user_data); + au_queue.save(ar); + } + + ar(state, au_size_unk, au_specific_info_buf, current_au, pts, dts, rap); + + if (state == state::pushing_au_queue) + { + ar(au_chunk.cached_data); + + if (ar.is_writing()) + { + ar(vm::get_addr(au_chunk.data.data()), static_cast(au_chunk.data.size())); + } + else + { + au_chunk.data = { vm::_ptr(ar.pop()), ar.pop() }; + } + } + + if (current_au.state != access_unit::state::complete) + { + ar(cache); + } + + bool save_stream = !!pes_packet_data; + ar(save_stream); + + if (save_stream) + { + if (ar.is_writing()) + { + ensure(stream_chunk.size() <= pes_packet_data->size()); + ar(vm::get_addr(pes_packet_data->data()), static_cast(pes_packet_data->size()), static_cast(stream_chunk.data() - pes_packet_data->data())); + } + else + { + pes_packet_data = { vm::_ptr(ar.pop()), ar.pop() }; + stream_chunk = { pes_packet_data->begin() + ar.pop(), pes_packet_data->end() }; + } + } +} + +void dmux_pamf_base::save_base(utils::serial& ar) +{ + bool stream_not_consumed = !!stream; + + ar(state, stream_not_consumed, demux_done_notified, pack_es_type_idx, raw_es); + + if (stream_not_consumed) + { + if (ar.is_writing()) + { + ar(vm::get_addr(stream->data()), static_cast(stream->size())); + } + else + { + stream = std::span{ vm::_ptr(ar.pop()), ar.pop() }; + } + } + + if (state == state::elementary_stream) + { + ar(pack_es_channel); + } + + std::array enabled_video_streams; + std::array avc_video_streams; + std::array enabled_lpcm_streams; + std::array enabled_ac3_streams; + std::array enabled_atracx_streams; + std::array enabled_user_data_streams; + + if (ar.is_writing()) + { + std::ranges::transform(elementary_streams[DMUX_PAMF_STREAM_TYPE_INDEX_VIDEO], enabled_video_streams.begin(), elementary_stream::is_enabled); + std::ranges::transform(elementary_streams[DMUX_PAMF_STREAM_TYPE_INDEX_VIDEO], avc_video_streams.begin(), [](auto& es){ return !!dynamic_cast*>(es.get()); }); + std::ranges::transform(elementary_streams[DMUX_PAMF_STREAM_TYPE_INDEX_LPCM], enabled_lpcm_streams.begin(), elementary_stream::is_enabled); + std::ranges::transform(elementary_streams[DMUX_PAMF_STREAM_TYPE_INDEX_AC3], enabled_ac3_streams.begin(), elementary_stream::is_enabled); + std::ranges::transform(elementary_streams[DMUX_PAMF_STREAM_TYPE_INDEX_ATRACX], enabled_atracx_streams.begin(), elementary_stream::is_enabled); + std::ranges::transform(elementary_streams[DMUX_PAMF_STREAM_TYPE_INDEX_USER_DATA], enabled_user_data_streams.begin(), elementary_stream::is_enabled); + } + + ar(enabled_video_streams, avc_video_streams, enabled_lpcm_streams, enabled_ac3_streams, enabled_atracx_streams, enabled_user_data_streams); + + if (ar.is_writing()) + { + std::ranges::for_each(elementary_streams | std::views::join | std::views::filter(elementary_stream::is_enabled), [&](const auto& es){ es->save(ar); }); + } + else + { + for (u32 ch = 0; ch < 0x10; ch++) + { + if (enabled_video_streams[ch]) + { + elementary_streams[DMUX_PAMF_STREAM_TYPE_INDEX_VIDEO][ch] = avc_video_streams[ch] ? static_cast>(std::make_unique>(ar, ch, *this)) + : std::make_unique>(ar, ch, *this); + } + } + + for (u32 ch = 0; ch < 0x10; ch++) + { + if (enabled_lpcm_streams[ch]) + { + elementary_streams[DMUX_PAMF_STREAM_TYPE_INDEX_LPCM][ch] = std::make_unique(ar, ch, *this); + } + } + + for (u32 ch = 0; ch < 0x10; ch++) + { + if (enabled_ac3_streams[ch]) + { + elementary_streams[DMUX_PAMF_STREAM_TYPE_INDEX_AC3][ch] = std::make_unique>(ar, ch, *this); + } + } + + for (u32 ch = 0; ch < 0x10; ch++) + { + if (enabled_atracx_streams[ch]) + { + elementary_streams[DMUX_PAMF_STREAM_TYPE_INDEX_ATRACX][ch] = std::make_unique>(ar, ch, *this); + } + } + + for (u32 ch = 0; ch < 0x10; ch++) + { + if (enabled_user_data_streams[ch]) + { + elementary_streams[DMUX_PAMF_STREAM_TYPE_INDEX_USER_DATA][ch] = std::make_unique(ar, ch, *this); + } + } + } +} + +void dmux_pamf_spu_context::save(utils::serial& ar) +{ + USING_SERIALIZATION_VERSION(cellDmuxPamf); + ar(cmd_queue, new_stream); // The queues are contiguous in guest memory, so we only need to save the address of the first one + save_base(ar); +} + + +// PPU thread + error_code _CellDmuxCoreOpQueryAttr(vm::cptr pamfSpecificInfo, vm::ptr pamfAttr) { cellDmuxPamf.todo("_CellDmuxCoreOpQueryAttr(pamfSpecificInfo=*0x%x, pamfAttr=*0x%x)", pamfSpecificInfo, pamfAttr); @@ -63,9 +1173,9 @@ error_code _CellDmuxCoreOpSetStream(vm::ptr handle, vm::cptr streamA return CELL_OK; } -error_code _CellDmuxCoreOpFreeMemory(vm::ptr esHandle, vm::ptr memAddr, u32 memSize) +error_code _CellDmuxCoreOpReleaseAu(vm::ptr esHandle, vm::ptr memAddr, u32 memSize) { - cellDmuxPamf.todo("_CellDmuxCoreOpFreeMemory(esHandle=*0x%x, memAddr=*0x%x, memSize=0x%x)", esHandle, memAddr, memSize); + cellDmuxPamf.todo("_CellDmuxCoreOpReleaseAu(esHandle=*0x%x, memAddr=*0x%x, memSize=0x%x)", esHandle, memAddr, memSize); return CELL_OK; } @@ -116,6 +1226,7 @@ error_code _CellDmuxCoreOpResetStreamAndWaitDone(vm::ptr handle) return CELL_OK; } +template static void init_gvar(const vm::gvar& var) { var->queryAttr.set(g_fxo->get().func_addr(FIND_FUNC(_CellDmuxCoreOpQueryAttr))); @@ -124,7 +1235,10 @@ static void init_gvar(const vm::gvar& var) var->resetStream.set(g_fxo->get().func_addr(FIND_FUNC(_CellDmuxCoreOpResetStream))); var->createThread.set(g_fxo->get().func_addr(FIND_FUNC(_CellDmuxCoreOpCreateThread))); var->joinThread.set(g_fxo->get().func_addr(FIND_FUNC(_CellDmuxCoreOpJoinThread))); - var->freeMemory.set(g_fxo->get().func_addr(FIND_FUNC(_CellDmuxCoreOpFreeMemory))); + var->setStream.set(g_fxo->get().func_addr(FIND_FUNC(_CellDmuxCoreOpSetStream))); + var->releaseAu.set(g_fxo->get().func_addr(FIND_FUNC(_CellDmuxCoreOpReleaseAu))); + var->queryEsAttr.set(g_fxo->get().func_addr(FIND_FUNC(_CellDmuxCoreOpQueryEsAttr))); + var->enableEs.set(g_fxo->get().func_addr(FIND_FUNC(_CellDmuxCoreOpEnableEs))); var->disableEs.set(g_fxo->get().func_addr(FIND_FUNC(_CellDmuxCoreOpDisableEs))); var->flushEs.set(g_fxo->get().func_addr(FIND_FUNC(_CellDmuxCoreOpFlushEs))); var->resetEs.set(g_fxo->get().func_addr(FIND_FUNC(_CellDmuxCoreOpResetEs))); @@ -133,21 +1247,8 @@ static void init_gvar(const vm::gvar& var) DECLARE(ppu_module_manager::cellDmuxPamf)("cellDmuxPamf", [] { - REG_VNID(cellDmuxPamf, 0x28b2b7b2, g_cell_dmux_core_ops_pamf).init = [] - { - g_cell_dmux_core_ops_pamf->setStream.set(g_fxo->get().func_addr(FIND_FUNC(_CellDmuxCoreOpSetStream))); - g_cell_dmux_core_ops_pamf->queryEsAttr.set(g_fxo->get().func_addr(FIND_FUNC(_CellDmuxCoreOpQueryEsAttr))); - g_cell_dmux_core_ops_pamf->enableEs.set(g_fxo->get().func_addr(FIND_FUNC(_CellDmuxCoreOpEnableEs))); - init_gvar(g_cell_dmux_core_ops_pamf); - }; - - REG_VNID(cellDmuxPamf, 0x9728a0e9, g_cell_dmux_core_ops_raw_es).init = [] - { - g_cell_dmux_core_ops_raw_es->setStream.set(g_fxo->get().func_addr(FIND_FUNC(_CellDmuxCoreOpSetStream))); - g_cell_dmux_core_ops_raw_es->queryEsAttr.set(g_fxo->get().func_addr(FIND_FUNC(_CellDmuxCoreOpQueryEsAttr))); - g_cell_dmux_core_ops_raw_es->enableEs.set(g_fxo->get().func_addr(FIND_FUNC(_CellDmuxCoreOpEnableEs))); - init_gvar(g_cell_dmux_core_ops_raw_es); - }; + REG_VNID(cellDmuxPamf, 0x28b2b7b2, g_cell_dmux_core_ops_pamf).init = []{ init_gvar(g_cell_dmux_core_ops_pamf); }; + REG_VNID(cellDmuxPamf, 0x9728a0e9, g_cell_dmux_core_ops_raw_es).init = []{ init_gvar(g_cell_dmux_core_ops_raw_es); }; REG_HIDDEN_FUNC(_CellDmuxCoreOpQueryAttr); REG_HIDDEN_FUNC(_CellDmuxCoreOpOpen); @@ -157,7 +1258,7 @@ DECLARE(ppu_module_manager::cellDmuxPamf)("cellDmuxPamf", [] REG_HIDDEN_FUNC(_CellDmuxCoreOpJoinThread); REG_HIDDEN_FUNC(_CellDmuxCoreOpSetStream); REG_HIDDEN_FUNC(_CellDmuxCoreOpSetStream); - REG_HIDDEN_FUNC(_CellDmuxCoreOpFreeMemory); + REG_HIDDEN_FUNC(_CellDmuxCoreOpReleaseAu); REG_HIDDEN_FUNC(_CellDmuxCoreOpQueryEsAttr); REG_HIDDEN_FUNC(_CellDmuxCoreOpQueryEsAttr); REG_HIDDEN_FUNC(_CellDmuxCoreOpEnableEs); diff --git a/rpcs3/Emu/Cell/Modules/cellDmuxPamf.h b/rpcs3/Emu/Cell/Modules/cellDmuxPamf.h index 01983b724a..c720fb89c5 100644 --- a/rpcs3/Emu/Cell/Modules/cellDmuxPamf.h +++ b/rpcs3/Emu/Cell/Modules/cellDmuxPamf.h @@ -1,5 +1,666 @@ #pragma once +#include "Emu/savestate_utils.hpp" +#include "Utilities/Thread.h" +#include "cellPamf.h" +#include "cellDmux.h" +#include + +// Replacement for CellSpursQueue +template requires(std::is_trivial_v && max_num_of_entries > 0) +class alignas(0x80) dmux_pamf_hle_spurs_queue +{ + T* buffer; + + alignas(atomic_t) std::array)> _size; // Stored in a byte array since the PPU context needs to be trivial + u32 front; + u32 back; + + template + bool _pop(T* lhs) + { + atomic_t& _size = *std::launder(reinterpret_cast*>(this->_size.data())); + + if (_size == 0) + { + return false; + } + + if (lhs) + { + *lhs = buffer[front]; + } + + if constexpr (!is_peek) + { + front = (front + 1) % max_num_of_entries; + _size--; + _size.notify_one(); + } + + return true; + } + +public: + void init(T (&buffer)[max_num_of_entries]) + { + this->buffer = buffer; + new (_size.data()) atomic_t(0); + front = 0; + back = 0; + } + + bool pop(T& lhs) { return _pop(&lhs); } + bool pop() { return _pop(nullptr); } + bool peek(T& lhs) const { return const_cast(this)->_pop(&lhs); } + bool emplace(auto&&... args) + { + atomic_t& _size = *std::launder(reinterpret_cast*>(this->_size.data())); + + if (_size >= max_num_of_entries) + { + return false; + } + + new (&buffer[back]) T(std::forward(args)...); + + back = (back + 1) % max_num_of_entries; + _size++; + _size.notify_one(); + + return true; + } + + [[nodiscard]] u32 size() const { return std::launder(reinterpret_cast*>(this->_size.data()))->observe(); } + + void wait() const + { + const atomic_t& _size = *std::launder(reinterpret_cast*>(this->_size.data())); + + while (_size == 0 && thread_ctrl::state() != thread_state::aborting) + { + thread_ctrl::wait_on(_size, 0); + } + } +}; + +enum class DmuxPamfCommandType : u32 +{ + enable_es = 0, + disable_es = 2, + set_stream = 4, + release_au = 6, + flush_es = 8, + close = 10, + reset_stream = 12, + reset_es = 14, + resume = 16, +}; + +struct alignas(0x80) DmuxPamfCommand +{ + be_t type; + + union + { + struct + { + be_t stream_id; + be_t private_stream_id; + be_t is_avc; + vm::bptr au_queue_buffer; + be_t au_queue_buffer_size; + be_t au_max_size; + be_t au_specific_info_size; + be_t is_raw_es; + be_t user_data; + } + enable_es; + + struct + { + be_t stream_id; + be_t private_stream_id; + } + disable_flush_es; + + struct + { + vm::ptr> au_addr; + be_t au_size; + be_t stream_id; + be_t private_stream_id; + } + release_au; + + struct + { + be_t stream_id; + be_t private_stream_id; + vm::ptr> au_addr; + } + reset_es; + }; + + DmuxPamfCommand() = default; + + DmuxPamfCommand(be_t&& type) + : type(type) + { + } + + DmuxPamfCommand(be_t&& type, const be_t& stream_id, const be_t& private_stream_id) + : type(type), disable_flush_es{ stream_id, private_stream_id } + { + } + + DmuxPamfCommand(be_t&& type, const be_t& stream_id, const be_t& private_stream_id, const vm::ptr>& au_addr) + : type(type), reset_es{ stream_id, private_stream_id, au_addr } + { + } + + DmuxPamfCommand(be_t&& type, const vm::ptr>& au_addr, const be_t& au_size, const be_t& stream_id, const be_t& private_stream_id) + : type(type), release_au{ au_addr, au_size, stream_id, private_stream_id } + { + } + + DmuxPamfCommand(be_t&& type, const be_t& stream_id, const be_t& private_stream_id, const be_t& is_avc, const vm::bptr& au_queue_buffer, + const be_t& au_queue_buffer_size, const be_t& au_max_size, const be_t& au_specific_info_size, const be_t& is_raw_es, const be_t& user_data) + : type(type), enable_es{ stream_id, private_stream_id, is_avc, au_queue_buffer, au_queue_buffer_size, au_max_size, au_specific_info_size, is_raw_es, user_data } + { + } +}; + +CHECK_SIZE_ALIGN(DmuxPamfCommand, 0x80, 0x80); + +enum class DmuxPamfEventType : u32 +{ + au_found, + demux_done, + fatal_error, + close, + flush_done, + prog_end_code, +}; + +struct alignas(0x80) DmuxPamfEvent +{ + be_t type; + + union + { + u8 pad[0x78]; + + struct + { + be_t stream_id; + be_t private_stream_id; + vm::ptr> au_addr; + CellCodecTimeStamp pts; + CellCodecTimeStamp dts; + be_t unk; + u8 reserved[4]; + be_t au_size; + be_t stream_header_size; + std::array stream_header_buf; + be_t user_data; + be_t is_rap; + } + au_found; + + struct + { + be_t stream_id; + be_t private_stream_id; + be_t user_data; + } + flush_done; + }; + + be_t event_queue_was_too_full; + + DmuxPamfEvent() = default; + + DmuxPamfEvent(be_t&& type, const be_t& event_queue_was_too_full) + : type(type), event_queue_was_too_full(event_queue_was_too_full) + { + } + + DmuxPamfEvent(be_t&& type, const be_t& stream_id, const be_t& private_stream_id, const be_t& user_data, const be_t& event_queue_was_too_full) + : type(type), flush_done{ stream_id, private_stream_id, user_data }, event_queue_was_too_full(event_queue_was_too_full) + { + } + + DmuxPamfEvent(be_t&& type, const be_t& stream_id, const be_t& private_stream_id, const vm::ptr>& au_addr, const CellCodecTimeStamp& pts, const CellCodecTimeStamp& dts, const be_t& unk, + const be_t& au_size, const be_t& au_specific_info_size, const std::array& au_specific_info, const be_t& user_data, const be_t& is_rap, const be_t& event_queue_was_too_full) + : type(type) + , au_found{ stream_id, private_stream_id, au_addr, pts, dts, static_cast>(unk), {}, au_size, au_specific_info_size, au_specific_info, user_data, is_rap } + , event_queue_was_too_full(event_queue_was_too_full) + { + } +}; + +CHECK_SIZE_ALIGN(DmuxPamfEvent, 0x80, 0x80); + +struct alignas(0x80) DmuxPamfStreamInfo +{ + vm::bcptr stream_addr; + be_t stream_size; + be_t user_data; + be_t continuity; + be_t is_raw_es; +}; + +CHECK_SIZE_ALIGN(DmuxPamfStreamInfo, 0x80, 0x80); + +enum DmuxPamfStreamTypeIndex +{ + DMUX_PAMF_STREAM_TYPE_INDEX_INVALID = -1, + DMUX_PAMF_STREAM_TYPE_INDEX_VIDEO, + DMUX_PAMF_STREAM_TYPE_INDEX_LPCM, + DMUX_PAMF_STREAM_TYPE_INDEX_AC3, + DMUX_PAMF_STREAM_TYPE_INDEX_ATRACX, + DMUX_PAMF_STREAM_TYPE_INDEX_USER_DATA, +}; + + +// SPU thread + +class dmux_pamf_base +{ + // Event handlers for the demuxer. These correspond to the events that the SPU thread sends to the PPU thread on LLE (except for au_queue_full(): the SPU thread just sets a global bool, + // but it is never notified to the PPU thread or the user). + + virtual bool on_au_found(u8 stream_id, u8 private_stream_id, u32 user_data, std::span au, u64 pts, u64 dts, bool rap, u8 au_specific_info_size, std::array au_specific_info_buf) = 0; + virtual bool on_demux_done() = 0; + virtual void on_fatal_error() = 0; + virtual bool on_flush_done(u8 stream_id, u8 private_stream_id, u32 user_data) = 0; + virtual bool on_prog_end() = 0; + virtual void on_au_queue_full() = 0; + +public: + virtual ~dmux_pamf_base() = default; + + bool enable_es(u32 stream_id, u32 private_stream_id, bool is_avc, std::span au_queue_buffer, u32 au_max_size, bool raw_es, u32 user_data); + bool disable_es(u32 stream_id, u32 private_stream_id); + bool release_au(u32 stream_id, u32 private_stream_id, u32 au_size) const; + bool flush_es(u32 stream_id, u32 private_stream_id); + void set_stream(std::span stream, bool continuity); + void reset_stream(); + bool reset_es(u32 stream_id, u32 private_stream_id, u8* au_addr); + bool process_next_pack(); + +protected: + void save_base(utils::serial& ar); + [[nodiscard]] bool has_work() const { return !!stream || !demux_done_notified; } + [[nodiscard]] u32 get_enabled_es_count() const; + +private: + static constexpr u16 PACK_SIZE = 0x800; + static constexpr s8 PACK_STUFFING_LENGTH_OFFSET = 0xd; + static constexpr s8 PES_PACKET_LENGTH_OFFSET = 0x4; + static constexpr s8 PES_HEADER_DATA_LENGTH_OFFSET = 0x8; + static constexpr s8 PTS_DTS_FLAG_OFFSET = 0x7; + static constexpr u8 PACKET_START_CODE_PREFIX = 1; + + static constexpr be_t M2V_PIC_START = 0x100; + static constexpr be_t AVC_AU_DELIMITER = 0x109; + static constexpr be_t M2V_SEQUENCE_HEADER = 0x1b3; + static constexpr be_t M2V_SEQUENCE_END = 0x1b7; + static constexpr be_t PACK_START = 0x1ba; + static constexpr be_t SYSTEM_HEADER = 0x1bb; + static constexpr be_t PRIVATE_STREAM_1 = 0x1bd; + static constexpr be_t PRIVATE_STREAM_2 = 0x1bf; + static constexpr be_t PROG_END = 0x1b9; + static constexpr be_t VIDEO_STREAM_BASE = 0x1e0; // The lower 4 bits indicate the channel + + // Partial access unit that will be written to the output queue + struct access_unit_chunk + { + std::vector cached_data; // Up to three bytes of data from the previous PES packet (copied into this vector, since it might not be in memory anymore) + std::span data; // Data of the current PES packet + }; + + // Output queue for access units + // The queue doesn't keep track of where access units are in the buffer (only which parts are used and which are free), this has to be done extenally + class output_queue + { + public: + explicit output_queue(std::span buffer) : buffer(buffer) {} + + explicit output_queue(utils::serial& ar) + : buffer{vm::_ptr(ar.pop()), ar.pop()} + , back(vm::_ptr(ar.pop())) + , front(vm::_ptr(ar.pop())) + , wrap_pos(vm::_ptr(ar.pop())) + { + } + + void save(utils::serial& ar) const { ar(vm::get_addr(buffer.data()), static_cast(buffer.size()), vm::get_addr(back), vm::get_addr(front), vm::get_addr(wrap_pos)); } + + // The queue itself doesn't keep track of the location of each access unit, so the pop and access operations need the size or address of the access unit to remove/return + void pop_back(u32 au_size); + void pop_back(u8* au_addr); + void pop_front(u32 au_size); + [[nodiscard]] const u8* peek_back(u32 au_size) const { return back - au_size; } + + void clear() { wrap_pos = front = back = buffer.data(); } + + void push_unchecked(const access_unit_chunk& au_chunk); + bool push(const access_unit_chunk& au_chunk, const std::function& on_fatal_error); + + [[nodiscard]] bool prepare_next_au(u32 au_max_size); + + [[nodiscard]] usz get_free_size() const { return wrap_pos != buffer.data() ? front - back : std::to_address(buffer.end()) - back; } + + private: + const std::span buffer; + + // Since access units have a variable size, uses pointers instead of indices + u8* back = buffer.data(); + const u8* front = buffer.data(); + const u8* wrap_pos = buffer.data(); // The address where the back pointer wrapped around to the beginning of the queue + }; + + // Base class for elementary streams and subclasses for each stream type + // Responsible for processing the data section of PES packets and splitting it into access units with the stream parsers of each subclass + class elementary_stream + { + public: + elementary_stream(u8 channel, u32 au_max_size, dmux_pamf_base& ctx, u32 user_data, u8 au_specific_info_size, std::span au_queue_buffer) + : channel(channel) + , au_max_size(au_max_size == umax || au_max_size > au_queue_buffer.size() ? 0x800 : au_max_size) + , ctx(ctx) + , au_specific_info_size(au_specific_info_size) + , user_data(user_data) + , au_queue(au_queue_buffer) + { + // The cache sizes will never exceed three bytes + cache.reserve(3); + au_chunk.cached_data.reserve(3); + } + + elementary_stream(utils::serial& ar, u8 channel, dmux_pamf_base& ctx, u8 au_specific_info_size) + : channel(channel) + , au_max_size(ar.pop()) + , ctx(ctx) + , au_specific_info_size(au_specific_info_size) + , user_data(ar.pop()) + , au_queue(ar) + { + save(ar); + } + + virtual ~elementary_stream() = default; + void save(utils::serial& ar); + + static bool is_enabled(const std::unique_ptr& es) { return !!es; } + + [[nodiscard]] virtual std::pair get_stream_id() const = 0; + + void set_pes_packet_data(std::span pes_packet_data) { ensure(!this->pes_packet_data); this->pes_packet_data = this->stream_chunk = pes_packet_data; } + void set_pts(u64 pts) { this->pts = pts; } + void set_dts(u64 dts) { this->dts = dts; } + void set_rap() { rap = true; } + + // Parses the proprietary header of private streams. Returns the size of the header or umax if the stream is invalid + virtual u32 parse_stream_header(std::span elementary_stream, s8 pts_dts_flag) = 0; + + // Processes the current PES packet. Returns true if it has been entirely consumed + bool process_pes_packet_data(); + + void release_au(u32 au_size) { au_queue.pop_front(au_size); } + void flush_es(); + void reset_es(u8* au_addr); + void discard_access_unit(); + + protected: + const u8 channel : 4; + const u32 au_max_size; // Maximum possible size of an access unit + u32 au_size_unk = 0; // For user data streams, used to store the size of the current access unit. For other private streams, used as a bool for some reason + alignas(0x10) std::array au_specific_info_buf{}; // For LPCM streams, stores the first 0x10 bytes of the current PES packet data, contains info like the number of channels + + // The access unit that is currently being cut out + struct access_unit + { + ENABLE_BITWISE_SERIALIZATION + + enum class state : u8 + { + none, // An access unit is not currently being cut out + incomplete, // An access unit is currently being cut out + commenced, // The current PES packet contains the beginning of an access unit + complete, // The current PES packet contains the end of an access unit + size_mismatch, // The distance between sync words and size indicated in the access unit's info header does not match + m2v_sequence, // Special case for M2V, access unit commenced, but the next start code does not complete the access unit + } + state = state::none; + + bool rap = false; + bool timestamps_rap_set = false; + + // Since the delimiters of compressed audio streams are allowed to appear anywhere in the stream (instead of just the beginning of an access unit), we need to parse the size of the access unit from the stream + u8 size_info_offset = 0; + u16 parsed_size = 0; + + u32 accumulated_size = 0; // Incremented after every access unit chunk cut out from the stream + + u64 pts = umax; + u64 dts = umax; + + alignas(0x10) std::array au_specific_info_buf{}; + } + current_au; + + access_unit_chunk au_chunk; // A partial access unit that will be written to the access unit queue. Set by the stream parsers + std::vector cache; // The last three bytes of the current PES packet need to be saved, since they could contain part of an access unit delimiter + + // Returns the stream header size of audio streams. The only difference between LPCM and compressed streams is the extra_header_size_unk_mask + template + u32 parse_audio_stream_header(std::span pes_packet_data); + + private: + dmux_pamf_base& ctx; // For access to event handlers + + enum class state : u8 + { + initial, + pushing_au_queue, + notifying_au_found, + preparing_for_next_au + } + state = state::initial; + + // Size of the "CellDmuxPamfAuSpecificInfo..." struct for the type of this stream ("reserved" fields are not counted, so for all stream types other than LPCM this will be 0) + // This does NOT correspond to the amount of data in au_specific_info_buf, the info in the buffer gets unpacked by the PPU thread + const u8 au_specific_info_size; + + const u32 user_data; + + // Data section of the current PES packet. Needs to be remembered separately from the span we're working with below + std::optional> pes_packet_data; + + std::span stream_chunk; // The current section of the PES packet data to be processed + u64 pts = umax; // Presentation time stamp of the current PES packet + u64 dts = umax; // Decoding time stamp of the current PES packet + bool rap = false; // Random access point indicator + + output_queue au_queue; + + // Extracts access units from the stream by searching for the access unit delimiter and setting au_chunk accordingly. Returns the number of bytes that were parsed + virtual u32 parse_stream(std::span stream) = 0; + + void reset() + { + state = state::initial; + pes_packet_data.reset(); + au_size_unk = 0; + pts = + dts = umax; + rap = false; + au_chunk.data = {}; + au_chunk.cached_data.clear(); + current_au = {}; + } + + void set_au_timestamps_rap() + { + current_au.pts = pts; + current_au.dts = dts; + current_au.rap = rap; + pts = + dts = umax; + rap = false; + current_au.timestamps_rap_set = true; + } + }; + + template + class video_stream final : public elementary_stream + { + public: + video_stream(u8 channel, u32 au_max_size, dmux_pamf_base& ctx, u32 user_data, std::span au_queue_buffer) : elementary_stream(channel, au_max_size, ctx, user_data, 0, au_queue_buffer) {} + video_stream(utils::serial& ar, u8 channel, dmux_pamf_base& ctx) : elementary_stream(ar, channel, ctx, 0) {} + + private: + u32 parse_stream(std::span stream) override; + u32 parse_stream_header([[maybe_unused]] std::span pes_packet_data, [[maybe_unused]] s8 pts_dts_flag) override { return 0; } + [[nodiscard]] std::pair get_stream_id() const override { return { 0xe0 | channel, 0 }; } + }; + + class lpcm_stream final : public elementary_stream + { + public: + lpcm_stream(u8 channel, u32 au_max_size, dmux_pamf_base& ctx, u32 user_data, std::span au_queue_buffer) : elementary_stream(channel, au_max_size, ctx, user_data, 3, au_queue_buffer) {} + lpcm_stream(utils::serial& ar, u8 channel, dmux_pamf_base& ctx) : elementary_stream(ar, channel, ctx, 3) {} + + private: + u32 parse_stream(std::span stream) override; + u32 parse_stream_header(std::span pes_packet_data, [[maybe_unused]] s8 pts_dts_flag) override; + [[nodiscard]] std::pair get_stream_id() const override { return { 0xbd, 0x40 | channel }; } + }; + + template + class audio_stream final : public elementary_stream + { + public: + audio_stream(u8 channel, u32 au_max_size, dmux_pamf_base& ctx, u32 user_data, std::span au_queue_buffer) : elementary_stream(channel, au_max_size, ctx, user_data, 0, au_queue_buffer) {} + audio_stream(utils::serial& ar, u8 channel, dmux_pamf_base& ctx) : elementary_stream(ar, channel, ctx, 0) {} + + private: + static constexpr be_t SYNC_WORD = ac3 ? 0x0b77 : 0x0fd0; + static constexpr u8 ATRACX_ATS_HEADER_SIZE = 8; + static constexpr u16 AC3_FRMSIZE_TABLE[3][38] = + { + { 0x40, 0x40, 0x50, 0x50, 0x60, 0x60, 0x70, 0x70, 0x80, 0x80, 0xa0, 0xa0, 0xc0, 0xc0, 0xe0, 0xe0, 0x100, 0x100, 0x140, 0x140, 0x180, 0x180, 0x1c0, 0x1c0, 0x200, 0x200, 0x280, 0x280, 0x300, 0x300, 0x380, 0x380, 0x400, 0x400, 0x480, 0x480, 0x500, 0x500 }, + { 0x45, 0x46, 0x57, 0x58, 0x68, 0x69, 0x79, 0x7a, 0x8b, 0x8c, 0xae, 0xaf, 0xd0, 0xd1, 0xf3, 0xf4, 0x116, 0x117, 0x15c, 0x15d, 0x1a1, 0x1a2, 0x1e7, 0x1e8, 0x22d, 0x22e, 0x2b8, 0x2b9, 0x343, 0x344, 0x3cf, 0x3d0, 0x45a, 0x45b, 0x4e5, 0x4e6, 0x571, 0x572 }, + { 0x60, 0x60, 0x78, 0x78, 0x90, 0x90, 0xa8, 0xa8, 0xc0, 0xc0, 0xf0, 0xf0, 0x120, 0x120, 0x150, 0x150, 0x180, 0x180, 0x1e0, 0x1e0, 0x240, 0x240, 0x2a0, 0x2a0, 0x300, 0x300, 0x3c0, 0x3c0, 0x480, 0x480, 0x540, 0x540, 0x600, 0x600, 0x6c0, 0x6c0, 0x780, 0x780 } + }; + + u32 parse_stream(std::span stream) override; + u32 parse_stream_header(std::span pes_packet_data, [[maybe_unused]] s8 pts_dts_flag) override { return parse_audio_stream_header<0xffff>(pes_packet_data); } + [[nodiscard]] std::pair get_stream_id() const override { return { 0xbd, (ac3 ? 0x30 : 0x00) | channel }; } + }; + + class user_data_stream final : public elementary_stream + { + public: + user_data_stream(u8 channel, u32 au_max_size, dmux_pamf_base& ctx, u32 user_data, std::span au_queue_buffer) : elementary_stream(channel, au_max_size, ctx, user_data, 0, au_queue_buffer) {} + user_data_stream(utils::serial& ar, u8 channel, dmux_pamf_base& ctx) : elementary_stream(ar, channel, ctx, 0) {} + + private: + u32 parse_stream(std::span stream) override; + u32 parse_stream_header(std::span pes_packet_data, s8 pts_dts_flag) override; + [[nodiscard]] std::pair get_stream_id() const override { return { 0xbd, 0x20 | channel }; } + }; + + + enum class state : u8 + { + initial, + elementary_stream, + prog_end + } + state = state::initial; + + bool demux_done_notified = true; // User was successfully notified that the stream has been consumed + + u8 pack_es_type_idx = umax; // Elementary stream type in the current pack + u8 pack_es_channel = 0; // Elementary stream channel in the current pack + + bool raw_es = false; // Indicates that the input stream is a raw elementary stream instead of a multiplexed MPEG program stream. If set to true, MPEG-PS related parsing will be skipped + + std::optional> stream; // The stream to be demultiplexed, provided by the user + + std::unique_ptr elementary_streams[5][0x10]; // One for each possible type and channel +}; + +// Implementation of the SPU thread +class dmux_pamf_spu_context : dmux_pamf_base +{ +public: + static constexpr u32 id_base = 0; + static constexpr u32 id_step = 1; + static constexpr u32 id_count = 0x400; + SAVESTATE_INIT_POS(std::numeric_limits::max()); // Doesn't depend on or is a dependency of anything + + dmux_pamf_spu_context(vm::ptr> cmd_queue, vm::ptr, 1>> cmd_result_queue, + vm::ptr> stream_info_queue, vm::ptr> event_queue) + : cmd_queue(cmd_queue), cmd_result_queue(cmd_result_queue), stream_info_queue(stream_info_queue), event_queue(event_queue) + { + } + + explicit dmux_pamf_spu_context(utils::serial& ar) + : cmd_queue(ar.pop>>()) + , cmd_result_queue(vm::ptr, 1>>::make(cmd_queue.addr() + sizeof(dmux_pamf_hle_spurs_queue))) + , stream_info_queue(vm::ptr>::make(cmd_result_queue.addr() + sizeof(dmux_pamf_hle_spurs_queue, 1>))) + , event_queue(vm::ptr>::make(stream_info_queue.addr() + sizeof(dmux_pamf_hle_spurs_queue))) + , new_stream(ar.pop()) + { + save_base(ar); + max_enqueued_events += 2 * get_enabled_es_count(); + } + + void save(utils::serial& ar); + + void operator()(); // cellSpursMain() + static constexpr auto thread_name = "HLE PAMF demuxer SPU thread"sv; + +private: + // These are globals in the SPU thread + const vm::ptr> cmd_queue; + const vm::ptr, 1>> cmd_result_queue; + const vm::ptr> stream_info_queue; + const vm::ptr> event_queue; + bool wait_for_au_queue = false; + bool wait_for_event_queue = false; + bool event_queue_was_too_full = false; // Sent to the PPU thread + u8 max_enqueued_events = 4; // 4 + 2 * number of enabled elementary streams + + // This is a local variable in cellSpursMain(), needs to be saved for savestates + bool new_stream = false; + + bool get_next_cmd(DmuxPamfCommand& lhs, bool new_stream) const; + bool send_event(auto&&... args) const; + + // The events are sent to the PPU thread via the event_queue + bool on_au_found(u8 stream_id, u8 private_stream_id, u32 user_data, std::span au, u64 pts, u64 dts, bool rap, u8 au_specific_info_size, std::array au_specific_info_buf) override + { + return !((wait_for_event_queue = !send_event(DmuxPamfEventType::au_found, stream_id, private_stream_id, vm::get_addr(au.data()), std::bit_cast(static_cast>(pts)), + std::bit_cast(static_cast>(dts)), 0, static_cast(au.size()), au_specific_info_size, au_specific_info_buf, user_data, rap))); + } + bool on_demux_done() override { return !((wait_for_event_queue = !send_event(DmuxPamfEventType::demux_done))); } + void on_fatal_error() override { send_event(DmuxPamfEventType::fatal_error); } + bool on_flush_done(u8 stream_id, u8 private_stream_id, u32 user_data) override { return send_event(DmuxPamfEventType::flush_done, stream_id, private_stream_id, user_data); } // The "flush done" event does not set wait_for_event_queue if the queue is full + bool on_prog_end() override { return !((wait_for_event_queue = !send_event(DmuxPamfEventType::prog_end_code))); } + void on_au_queue_full() override { wait_for_au_queue = true; } +}; + +using dmux_pamf_spu_thread = named_thread; + + +// PPU thread + struct CellDmuxPamfAttr { be_t maxEnabledEsNum; diff --git a/rpcs3/Emu/Cell/Modules/cellPamf.h b/rpcs3/Emu/Cell/Modules/cellPamf.h index e42acf60f4..abd89f8852 100644 --- a/rpcs3/Emu/Cell/Modules/cellPamf.h +++ b/rpcs3/Emu/Cell/Modules/cellPamf.h @@ -1,5 +1,6 @@ #pragma once +#include "Emu/Cell/ErrorCodes.h" #include "Emu/Memory/vm_ptr.h" // Error Codes diff --git a/rpcs3/Emu/savestate_utils.cpp b/rpcs3/Emu/savestate_utils.cpp index 5add3e8c6b..167a060262 100644 --- a/rpcs3/Emu/savestate_utils.cpp +++ b/rpcs3/Emu/savestate_utils.cpp @@ -23,7 +23,7 @@ struct serial_ver_t std::set compatible_versions; }; -static std::array s_serial_versions; +static std::array s_serial_versions; #define SERIALIZATION_VER(name, identifier, ...) \ \ @@ -85,6 +85,7 @@ SERIALIZATION_VER(LLE, 24, 1) SERIALIZATION_VER(HLE, 25, 1) SERIALIZATION_VER(cellSysutil, 26, 1, 2/*AVC2 Muting,Volume*/) +SERIALIZATION_VER(cellDmuxPamf, 27, 1) template <> void fmt_class_string>::format(std::string& out, u64 arg) From a3d09a7427efe193efba099f4cdffbdb9a4506cb Mon Sep 17 00:00:00 2001 From: capriots <29807355+capriots@users.noreply.github.com> Date: Sat, 19 Jul 2025 21:11:56 +0200 Subject: [PATCH 111/175] tests: cellDmuxPamf --- rpcs3/tests/test_dmux_pamf.cpp | 630 +++++++++++++++++++++++++++++++++ rpcs3/tests/test_dmux_pamf.h | 123 +++++++ 2 files changed, 753 insertions(+) create mode 100644 rpcs3/tests/test_dmux_pamf.cpp create mode 100644 rpcs3/tests/test_dmux_pamf.h diff --git a/rpcs3/tests/test_dmux_pamf.cpp b/rpcs3/tests/test_dmux_pamf.cpp new file mode 100644 index 0000000000..40a8a02b32 --- /dev/null +++ b/rpcs3/tests/test_dmux_pamf.cpp @@ -0,0 +1,630 @@ +#include "stdafx.h" +#include +#include "Emu/Cell/Modules/cellDmuxPamf.h" +#include "Crypto/sha1.h" +#include "test_dmux_pamf.h" + +using namespace testing; + +struct DmuxPamfMock : dmux_pamf_base +{ + MOCK_METHOD(bool, on_au_found, (u8 stream_id, u8 private_stream_id, u32 user_data, std::span au, u64 pts, u64 dts, bool rap, u8 au_specific_info_size, (std::array) au_specific_info_buf), (override)); + MOCK_METHOD(bool, on_demux_done, (), (override)); + MOCK_METHOD(void, on_fatal_error, (), (override)); + MOCK_METHOD(bool, on_flush_done, (u8 stream_id, u8 private_stream_id, u32 user_data), (override)); + MOCK_METHOD(bool, on_prog_end, (), (override)); + MOCK_METHOD(void, on_au_queue_full, (), (override)); +}; + +struct DmuxPamfTest : Test +{ + StrictMock demuxer; + MockFunction check_point; + std::array au_queue_buffer{}; + InSequence seq; +}; + +MATCHER_P(Sha1Is, expected_sha1, "") { std::array sha1_buf{}; sha1(arg.data(), arg.size(), sha1_buf.data()); return sha1_buf == expected_sha1; } + +struct DmuxPamfSinglePack : DmuxPamfTest, WithParamInterface, AccessUnit, std::optional>> {}; + +TEST_P(DmuxPamfSinglePack, Test) +{ + const auto& [stream_id, private_stream_id, is_avc, au_max_size, stream, au_1, au_2] = GetParam(); + + EXPECT_CALL(check_point, Call(0)); + EXPECT_CALL(demuxer, on_au_found(stream_id, private_stream_id, 0x12345678, Sha1Is(au_1.data_sha1), au_1.pts, au_1.dts, au_1.rap, au_1.specific_info_size, au_1.specific_info_buf)).WillOnce(Return(true)); + + if (au_2) + { + EXPECT_CALL(demuxer, on_au_found(stream_id, private_stream_id, 0x12345678, Sha1Is(au_2->data_sha1), au_2->pts, au_2->dts, au_2->rap, au_2->specific_info_size, au_2->specific_info_buf)); + } + + demuxer.enable_es(stream_id, private_stream_id, is_avc, au_queue_buffer, au_max_size, false, 0x12345678); + demuxer.set_stream(stream, false); + check_point.Call(0); + demuxer.process_next_pack(); +} + +// These streams are made of a single pack that contains two access units (one for the user data stream) +INSTANTIATE_TEST_SUITE_P(Basic, DmuxPamfSinglePack, Values +( + std::tuple{ 0xe0, 0x00, true, 0x800, AVC_SINGLE_PACK_STREAM, AVC_SINGLE_PACK_EXPECTED_AU_1, AVC_SINGLE_PACK_EXPECTED_AU_2 }, + std::tuple{ 0xe0, 0x00, false, 0x800, M2V_SINGLE_PACK_STREAM, M2V_SINGLE_PACK_EXPECTED_AU_1, M2V_SINGLE_PACK_EXPECTED_AU_2 }, + std::tuple{ 0xbd, 0x00, false, 0x800, ATRACX_SINGLE_PACK_STREAM, ATRACX_SINGLE_PACK_EXPECTED_AU_1, ATRACX_SINGLE_PACK_EXPECTED_AU_2 }, + std::tuple{ 0xbd, 0x30, false, 0x800, AC3_SINGLE_PACK_STREAM, AC3_SINGLE_PACK_EXPECTED_AU_1, AC3_SINGLE_PACK_EXPECTED_AU_2 }, + std::tuple{ 0xbd, 0x40, false, 0x369, LPCM_SINGLE_PACK_STREAM, LPCM_SINGLE_PACK_EXPECTED_AU_1, LPCM_SINGLE_PACK_EXPECTED_AU_2 }, + std::tuple{ 0xbd, 0x20, false, 0x800, USER_DATA_SINGLE_PACK_STREAM, USER_DATA_SINGLE_PACK_EXPECTED_AU, std::nullopt } // There can be at most one user data access unit in a single pack +)); + +// Tests buggy behavior: timestamps should be unsigned, but get sign-extended from s32 to u64 on LLE. They probably forgot about integer promotion +INSTANTIATE_TEST_SUITE_P(TimeStampSignExtended, DmuxPamfSinglePack, Values +( + std::tuple{ 0xbd, 0x20, false, 0x800, TIME_STAMP_SIGN_EXTENDED_STREAM, TIME_STAMP_SIGN_EXTENDED_EXPECTED_AU, std::nullopt } +)); + +// Tests buggy behavior: if there is no Pack Start Code at the beginning of the current stream section, LLE will search for the code. +// However, if it finds one, it will not set the reading position to where the code was found. It continues reading from the beginning of the stream section instead. +// Test disabled since this is not currently implemented +INSTANTIATE_TEST_SUITE_P(DISABLED_PackStartCodeNotAtBeginning, DmuxPamfSinglePack, Values +( + std::tuple{ 0xe0, 0x00, true, 0x800, []() { auto pack = AVC_SINGLE_PACK_STREAM; std::copy_n(pack.begin(), 4, pack.begin() + 0x93); std::fill_n(pack.begin(), 4, 0); return pack; }(), AVC_SINGLE_PACK_EXPECTED_AU_1, AVC_SINGLE_PACK_EXPECTED_AU_2 } +)); + +struct DmuxPamfMultiplePackSingleAu : DmuxPamfTest, WithParamInterface, AccessUnit>> {}; + +TEST_P(DmuxPamfMultiplePackSingleAu, Test) +{ + const auto& [stream_id, private_stream_id, is_avc, au_max_size, stream, au] = GetParam(); + + EXPECT_CALL(check_point, Call(0)); + EXPECT_CALL(demuxer, on_au_found(stream_id, private_stream_id, 0x12345678, Sha1Is(au.data_sha1), au.pts, au.dts, au.rap, au.specific_info_size, au.specific_info_buf)).WillOnce(Return(true)); + + demuxer.enable_es(stream_id, private_stream_id, is_avc, au_queue_buffer, au_max_size, false, 0x12345678); + demuxer.set_stream(stream, false); + + // Demultiplex all packs until the last one + for (u32 i = 0; i < stream.size() - 0x800; i += 0x800) + { + demuxer.process_next_pack(); + } + + // The next call to process_next_pack() should produce an access unit + check_point.Call(0); + demuxer.process_next_pack(); +} + +// These streams contain a single access unit that is split across four packs +INSTANTIATE_TEST_SUITE_P(Basic, DmuxPamfMultiplePackSingleAu, Values +( + std::tuple{ 0xe0, 0x00, true, 0x1800, AVC_LARGE_AU_STREAM, AVC_LARGE_AU_EXPECTED_AU }, + std::tuple{ 0xe0, 0x00, false, 0x1800, M2V_LARGE_AU_STREAM, M2V_LARGE_AU_EXPECTED_AU }, + std::tuple{ 0xbd, 0x00, false, 0x1800, ATRACX_LARGE_AU_STREAM, ATRACX_LARGE_AU_EXPECTED_AU }, + std::tuple{ 0xbd, 0x30, false, 0x1800, AC3_LARGE_AU_STREAM, AC3_LARGE_AU_EXPECTED_AU }, + std::tuple{ 0xbd, 0x40, false, 0x1400, LPCM_LARGE_AU_STREAM, LPCM_LARGE_AU_EXPECTED_AU }, + std::tuple{ 0xbd, 0x20, false, 0x1800, USER_DATA_LARGE_AU_STREAM, USER_DATA_LARGE_AU_EXPECTED_AU } +)); + +// PES packets with audio streams contain a proprietary header before the actual stream. +// The last two bytes of the header indicate how much of the stream should be skipped +// (note that I have not found a single PAMF stream in any game where this is not 0). +// These streams test if this is implemented properly, the first access unit should not be output +INSTANTIATE_TEST_SUITE_P(SkipByes, DmuxPamfMultiplePackSingleAu, Values +( + std::tuple{ 0xbd, 0x00, false, 0x1800, ATRACX_SKIP_BYTES_STREAM, ATRACX_SKIP_BYTES_EXPECTED_AU }, + std::tuple{ 0xbd, 0x30, false, 0x1800, AC3_SKIP_BYTES_STREAM, AC3_SKIP_BYTES_EXPECTED_AU }, + std::tuple{ 0xbd, 0x40, false, 0xb40, LPCM_SKIP_BYTES_STREAM, LPCM_SKIP_BYTES_EXPECTED_AU } +)); + +// Tests buggy behavior: if the start of an access unit in the last three bytes of the previous PES packet and the demuxer was not cutting out an access unit before that, +// LLE will always output all three bytes, even if the access unit starts at the second last or last byte +INSTANTIATE_TEST_SUITE_P(FirstDilimiterSplit, DmuxPamfMultiplePackSingleAu, Values +( + std::tuple{ 0xe0, 0x00, true, 0x1800, AVC_BEGIN_OF_AU_SPLIT_STREAM, AVC_BEGIN_OF_AU_SPLIT_EXPECTED_AU }, + std::tuple{ 0xe0, 0x00, false, 0x1800, M2V_BEGIN_OF_AU_SPLIT_STREAM, M2V_BEGIN_OF_AU_SPLIT_EXPECTED_AU }, + std::tuple{ 0xbd, 0x00, false, 0x1800, ATRACX_BEGIN_OF_AU_SPLIT_STREAM, ATRACX_BEGIN_OF_AU_SPLIT_EXPECTED_AU }, + std::tuple{ 0xbd, 0x30, false, 0x1800, AC3_BEGIN_OF_AU_SPLIT_STREAM, AC3_BEGIN_OF_AU_SPLIT_EXPECTED_AU } +)); + +// The distance of the access units in these streams do not match the size indicated in the ATRAC3plus ATS header/AC3 frmsizecod + fscod fields +// LLE repeatedly cuts off one byte at the beginning of the PES packet until the sizes match and clears the current access unit +INSTANTIATE_TEST_SUITE_P(SizeMismatch, DmuxPamfMultiplePackSingleAu, Values +( + std::tuple{ 0xbd, 0x00, false, 0x608, ATRACX_SIZE_MISMATCH_STREAM, ATRACX_SIZE_MISMATCH_EXPECTED_AU }, + std::tuple{ 0xbd, 0x30, false, 0x600, AC3_SIZE_MISMATCH_STREAM, AC3_SIZE_MISMATCH_EXPECTED_AU } +)); + +// Tests buggy behavior: if an M2V sequence end code is found, it should be included in the current access unit, unlike all other delimiters. +// If the sequence end code is split across two packs, LLE isn't properly including it in the access unit. +// Disabled because this behavior isn't properly implemented currently +INSTANTIATE_TEST_SUITE_P(DISABLED_M2vSequenceEndSplit, DmuxPamfMultiplePackSingleAu, Values +( + std::tuple{ 0xe0, 0x00, false, 0x1000, M2V_SEQUENCE_END_SPLIT_STREAM, M2V_SEQUENCE_END_SPLIT_EXPECTED_AU } +)); + +struct DmuxPamfSplitDelimiter : DmuxPamfTest, WithParamInterface, AccessUnit, AccessUnit, AccessUnit, AccessUnit>> {}; + +TEST_P(DmuxPamfSplitDelimiter, Test) +{ + const auto& [stream_id, private_stream_id, is_avc, au_max_size, stream, au_1, au_2, au_3, au_4] = GetParam(); + + EXPECT_CALL(check_point, Call(0)); + EXPECT_CALL(demuxer, on_au_found(stream_id, private_stream_id, 0x12345678, Sha1Is(au_1.data_sha1), au_1.pts, au_1.dts, au_1.rap, au_1.specific_info_size, au_1.specific_info_buf)).WillOnce(Return(true)); + EXPECT_CALL(check_point, Call(1)); + EXPECT_CALL(demuxer, on_au_found(stream_id, private_stream_id, 0x12345678, Sha1Is(au_2.data_sha1), au_2.pts, au_2.dts, au_2.rap, au_2.specific_info_size, au_2.specific_info_buf)).WillOnce(Return(true)); + EXPECT_CALL(check_point, Call(2)); + EXPECT_CALL(demuxer, on_au_found(stream_id, private_stream_id, 0x12345678, Sha1Is(au_3.data_sha1), au_3.pts, au_3.dts, au_3.rap, au_3.specific_info_size, au_3.specific_info_buf)).WillOnce(Return(true)); + EXPECT_CALL(demuxer, on_au_found(stream_id, private_stream_id, 0x12345678, Sha1Is(au_4.data_sha1), au_4.pts, au_4.dts, au_4.rap, au_4.specific_info_size, au_4.specific_info_buf)).WillOnce(Return(true)); + + demuxer.enable_es(stream_id, private_stream_id, is_avc, au_queue_buffer, au_max_size, false, 0x12345678); + demuxer.set_stream(stream, false); + demuxer.process_next_pack(); + check_point.Call(0); + demuxer.process_next_pack(); + check_point.Call(1); + demuxer.process_next_pack(); + check_point.Call(2); + demuxer.process_next_pack(); +} + +// The delimiters of each stream is split across two packs. Tests, if it is still found and the access units are extracted properly +INSTANTIATE_TEST_SUITE_P(Basic, DmuxPamfSplitDelimiter, Values +( + std::tuple{ 0xe0, 0x00, true, 0x800, AVC_MULTIPLE_PACK_STREAM, AVC_MULTIPLE_PACK_EXPECTED_AU_1, AVC_MULTIPLE_PACK_EXPECTED_AU_2, AVC_MULTIPLE_PACK_EXPECTED_AU_3, AVC_MULTIPLE_PACK_EXPECTED_AU_4 }, + std::tuple{ 0xe0, 0x00, false, 0x800, M2V_MULTIPLE_PACK_STREAM, M2V_MULTIPLE_PACK_EXPECTED_AU_1, M2V_MULTIPLE_PACK_EXPECTED_AU_2, M2V_MULTIPLE_PACK_EXPECTED_AU_3, M2V_MULTIPLE_PACK_EXPECTED_AU_4 }, + std::tuple{ 0xbd, 0x00, false, 0x800, ATRACX_MULTIPLE_PACK_STREAM, ATRACX_MULTIPLE_PACK_EXPECTED_AU_1, ATRACX_MULTIPLE_PACK_EXPECTED_AU_2, ATRACX_MULTIPLE_PACK_EXPECTED_AU_3, ATRACX_MULTIPLE_PACK_EXPECTED_AU_4 }, + std::tuple{ 0xbd, 0x30, false, 0x800, AC3_MULTIPLE_PACK_STREAM, AC3_MULTIPLE_PACK_EXPECTED_AU_1, AC3_MULTIPLE_PACK_EXPECTED_AU_2, AC3_MULTIPLE_PACK_EXPECTED_AU_3, AC3_MULTIPLE_PACK_EXPECTED_AU_4 } +)); + +struct DmuxPamfNoAccessUnits : DmuxPamfTest, WithParamInterface>> {}; + +TEST_P(DmuxPamfNoAccessUnits, Test) +{ + const auto& [stream_id, private_stream_id, is_avc, stream] = GetParam(); + + demuxer.enable_es(stream_id, private_stream_id, is_avc, au_queue_buffer, 0x1000, false, 0x12345678); + demuxer.set_stream(stream, false); + demuxer.process_next_pack(); + demuxer.process_next_pack(); + demuxer.process_next_pack(); + demuxer.process_next_pack(); +} + +// Tests buggy behavior: LLE doesn't handle multiple consecutive PES packets with less than three bytes correctly. +// These streams contain access units, but they are not found on LLE +INSTANTIATE_TEST_SUITE_P(TinyPackets, DmuxPamfNoAccessUnits, Values +( + std::tuple{ 0xe0, 0x00, true, AVC_TINY_PACKETS_STREAM }, + std::tuple{ 0xe0, 0x00, false, M2V_TINY_PACKETS_STREAM } +)); + +struct DmuxPamfInvalidStream : DmuxPamfTest, WithParamInterface> {}; + +TEST_P(DmuxPamfInvalidStream, Test) +{ + demuxer.set_stream(GetParam(), false); + demuxer.enable_es(0xbd, 0x00, false, au_queue_buffer, 0x800, false, 0); + demuxer.enable_es(0xbd, 0x20, false, au_queue_buffer, 0x800, false, 0); + demuxer.enable_es(0xbd, 0x40, false, au_queue_buffer, 0x800, false, 0); + EXPECT_FALSE(demuxer.process_next_pack()); +} + +// Tests if invalid streams are handled correctly. +// Each of these should fail a different check in process_next_pack() +// (LLE doesn't actually check anything, it would just read random things in the SPU local store) +INSTANTIATE_TEST_SUITE_P(Instance, DmuxPamfInvalidStream, Values +( + []() consteval { auto pack = AVC_SINGLE_PACK_STREAM; pack[0xe] = 0x01; return pack; }(), // Invalid code after pack header + []() consteval { auto pack = AVC_SINGLE_PACK_STREAM; pack[0x12] = 0x07; pack[0x13] = 0xe7; return pack; }(), // System header size too large + []() consteval { auto pack = AVC_SINGLE_PACK_STREAM; pack[0x20] = 0x01; return pack; }(), // Invalid code after system header + []() consteval { auto pack = AVC_SINGLE_PACK_STREAM; pack[0x24] = 0x07; pack[0x25] = 0xd2; return pack; }(), // Private stream 2 size too large + []() consteval { auto pack = AVC_SINGLE_PACK_STREAM; pack[0x114] = 0x01; return pack; }(), // Invalid code after private stream 2 + []() consteval { auto pack = AVC_SINGLE_PACK_STREAM; pack[0x117] = 0xbe; return pack; }(), // Invalid stream type + []() consteval { auto pack = AVC_SINGLE_PACK_STREAM; pack[0x119] = 0xe7; return pack; }(), // PES packet size too large + []() consteval { auto pack = AVC_SINGLE_PACK_STREAM; pack[0x118] = 0x00; pack[0x119] = 0x03; pack[0x11c] = 0x00; return pack; }(), // PES packet header size too large + []() consteval { auto pack = USER_DATA_SINGLE_PACK_STREAM; pack[0x118] = 0x00; pack[0x119] = 0x15; return pack; }(), // User data stream too small + []() consteval { auto pack = LPCM_SINGLE_PACK_STREAM; pack[0x118] = 0x00; pack[0x119] = 0x20; pack[0x12c] = 0x00; pack[0x12d] = 0x00; return pack; }(), // LPCM stream too small + []() consteval { auto pack = ATRACX_SINGLE_PACK_STREAM; pack[0x118] = 0x00; pack[0x119] = 0x13; pack[0x12c] = 0x00; pack[0x12d] = 0x00; return pack; }(), // Stream header too small + []() consteval { auto pack = AVC_SINGLE_PACK_STREAM; pack[0x118] = 0x00; pack[0x119] = 0x03; pack[0x11c] = 0x00; return pack; }() // PES packet header size too large +)); + +// Tests if the program end code is properly detected and the corresponding event is fired +TEST_F(DmuxPamfTest, ProgEnd) +{ + EXPECT_CALL(check_point, Call(0)); + EXPECT_CALL(demuxer, on_prog_end).WillOnce(Return(false)); // Since this returns false, the event should be fired again immediately after the next process_next_pack() call + EXPECT_CALL(check_point, Call(1)); + EXPECT_CALL(demuxer, on_prog_end).WillOnce(Return(true)); + + constexpr std::array stream = { 0x00, 0x00, 0x01, 0xb9 }; + + demuxer.set_stream(stream, false); + check_point.Call(0); + demuxer.process_next_pack(); + check_point.Call(1); + demuxer.process_next_pack(); +} + +// Tests if the output queue properly checks whether there is enough space to write an au_chunk to the queue +TEST_F(DmuxPamfTest, QueueNoSpaceForAuChunk) +{ + EXPECT_CALL(check_point, Call(0)); + EXPECT_CALL(demuxer, on_au_found).WillOnce(Return(true)); + EXPECT_CALL(demuxer, on_au_queue_full); + EXPECT_CALL(check_point, Call(1)); + EXPECT_CALL(demuxer, on_au_queue_full); + + // Set a large au_max_size, this causes the back pointer of the queue to wrap around to the beginning after the first access units + demuxer.enable_es(0xe0, 0x00, true, au_queue_buffer, 0x2c14, false, 0); + + demuxer.set_stream(AVC_SINGLE_PACK_STREAM, false); + + // Since the first access unit is behind the back pointer and there is no space to write the next au_chunk to the queue, this should cause the au_queue_full event to be fired + check_point.Call(0); + demuxer.process_next_pack(); + + // Since we didn't release the first access unit to remove it from the queue, this should result in au_queue_full again + check_point.Call(1); + demuxer.process_next_pack(); +} + +// Tests if access units are properly removed from the queue +TEST_F(DmuxPamfTest, QueueReleaseAu) +{ + EXPECT_CALL(check_point, Call(0)); + EXPECT_CALL(demuxer, on_au_found).WillOnce(Return(true)); + EXPECT_CALL(demuxer, on_au_queue_full); + EXPECT_CALL(check_point, Call(1)); + EXPECT_CALL(demuxer, on_au_found).WillOnce(Return(true)); + + demuxer.enable_es(0xe0, 0x00, true, au_queue_buffer, 0x2c14, false, 0); + demuxer.set_stream(AVC_SINGLE_PACK_STREAM, false); + check_point.Call(0); + demuxer.process_next_pack(); + demuxer.release_au(0xe0, 0x00, 0x3ed); // Should remove the first access unit from the queue + check_point.Call(1); + demuxer.process_next_pack(); // Since there is space again in the queue, the second access unit should now be found +} + +// LLE adds 0x10 bytes to the size of the au_chunk when checking whether there is enough space. +TEST_F(DmuxPamfTest, QueueNoSpaceSPUShenanigans) +{ + EXPECT_CALL(check_point, Call(0)); + EXPECT_CALL(demuxer, on_au_found).Times(2).WillRepeatedly(Return(true)); + EXPECT_CALL(demuxer, on_au_queue_full); + EXPECT_CALL(check_point, Call(1)); + EXPECT_CALL(demuxer, on_au_queue_full); + + std::array small_au_queue_buffer{}; + + demuxer.enable_es(0xe0, 0x00, true, small_au_queue_buffer, 0x400, false, 0); + demuxer.set_stream(AVC_SINGLE_PACK_STREAM, false); + check_point.Call(0); + demuxer.process_next_pack(); + demuxer.release_au(0xe0, 0x00, 0x3fc); // 0xf bytes more than needed, but this should still result in au_queue_full + demuxer.set_stream(AVC_SINGLE_PACK_STREAM, false); + check_point.Call(1); + demuxer.process_next_pack(); +} + +// After completing an access unit, it should be checked whether au_max_size fits into the queue. +TEST_F(DmuxPamfTest, QueueNoSpaceForMaxAu) +{ + EXPECT_CALL(check_point, Call(0)); + EXPECT_CALL(demuxer, on_au_found).WillOnce(Return(true)); + EXPECT_CALL(demuxer, on_au_queue_full); + EXPECT_CALL(check_point, Call(1)); + EXPECT_CALL(demuxer, on_au_found).WillOnce(Return(true)); + EXPECT_CALL(demuxer, on_au_queue_full); + + std::array small_au_queue_buffer{}; + + demuxer.enable_es(0xe0, 0x00, true, small_au_queue_buffer, 0x400, false, 0); + demuxer.set_stream(AVC_SINGLE_PACK_STREAM, false); + check_point.Call(0); + demuxer.process_next_pack(); + demuxer.release_au(0xe0, 0x00, 0x300); // This does not remove the entire access unit from the queue + + // Since there is still data behind the back pointer of the queue, it can't wrap around again. + // Because au_max_size won't fit between the back pointer and the end of the queue buffer after finding the next access unit, + // this should cause au_queue_full before starting to extract the next access unit + check_point.Call(1); + demuxer.process_next_pack(); +} + +// Tests if a fatal error is produced if an access unit in the stream is larger than au_max_size +TEST_F(DmuxPamfTest, QueueAuLargerThanMaxSize) +{ + EXPECT_CALL(check_point, Call(0)); + EXPECT_CALL(demuxer, on_fatal_error); + EXPECT_CALL(demuxer, on_au_queue_full); + EXPECT_CALL(check_point, Call(1)); + EXPECT_CALL(demuxer, on_fatal_error); + EXPECT_CALL(demuxer, on_au_queue_full); + + std::array small_au_queue_buffer{}; + + demuxer.enable_es(0xe0, 0x00, true, small_au_queue_buffer, 0x800, false, 0); // au_max_size is smaller than the access unit in the stream + demuxer.set_stream(AVC_LARGE_AU_STREAM, false); + demuxer.process_next_pack(); + check_point.Call(0); + demuxer.process_next_pack(); + check_point.Call(1); + demuxer.process_next_pack(); +} + +// LLE sets au_max_size to 0x800 if it is too large (no fatal error or anything else) +TEST_F(DmuxPamfTest, EnableEsAuMaxSizeTooLarge) +{ + EXPECT_CALL(check_point, Call(0)); + EXPECT_CALL(demuxer, on_au_found).Times(2).WillRepeatedly(Return(true)); + + demuxer.enable_es(0xe0, 0x00, true, au_queue_buffer, std::numeric_limits::max(), false, 0); // The access unit max size will be set to 0x800 if it is larger than the queue buffer size or UINT32_MAX + demuxer.set_stream(AVC_SINGLE_PACK_STREAM, false); + + // Normally, this would cause the event au_queue_full because au_max_size wouldn't fit in the queue. + // However, since au_max_size gets set to 0x800, this doesn't occur + check_point.Call(0); + demuxer.process_next_pack(); +} + +// Tests if the demux_done event is fired when process_next_pack() is called after the end of the stream has been reached +TEST_F(DmuxPamfTest, DemuxDone) +{ + EXPECT_CALL(check_point, Call(0)); + EXPECT_CALL(demuxer, on_demux_done).WillOnce(Return(true)); + + demuxer.enable_es(0xe0, 0x00, true, au_queue_buffer, 0x1800, false, 0); + demuxer.set_stream({ AVC_MULTIPLE_PACK_STREAM.begin(), 0x800 }, false); + demuxer.process_next_pack(); + check_point.Call(0); + demuxer.process_next_pack(); + demuxer.process_next_pack(); // Since on_demux_done was already called and returned true, it should not produce another demux_done event +} + +// process_next_pack() should skip through the stream until it finds a start code or the end of the stream is reached +TEST_F(DmuxPamfTest, DemuxDoneEmptyStream) +{ + EXPECT_CALL(check_point, Call(0)); + EXPECT_CALL(demuxer, on_demux_done).WillOnce(Return(true)); + + constexpr std::array stream{}; + + demuxer.set_stream(stream, false); + + // Should immediately cause demux_done since there is no start code in the stream + check_point.Call(0); + demuxer.process_next_pack(); +} + +// Tests if the demuxer handles an input stream that is a continuation of the previous one correctly +TEST_F(DmuxPamfTest, StreamContinuity) +{ + EXPECT_CALL(check_point, Call(0)); + EXPECT_CALL(demuxer, on_au_found).WillOnce(Return(true)); + + demuxer.enable_es(0xe0, 0x00, true, au_queue_buffer, 0x1800, false, 0); + demuxer.set_stream({ AVC_MULTIPLE_PACK_STREAM.begin(), 0x800 }, false); + demuxer.process_next_pack(); + demuxer.set_stream({ AVC_MULTIPLE_PACK_STREAM.begin() + 0x800, AVC_MULTIPLE_PACK_STREAM.end() }, true); + check_point.Call(0); + demuxer.process_next_pack(); +} + +// Flushing an elementary stream manually produces an au_found event +TEST_F(DmuxPamfTest, Flush) +{ + EXPECT_CALL(check_point, Call(0)); + EXPECT_CALL(demuxer, on_au_found(0xe0, 0x00, 0, Sha1Is(AVC_FLUSH_EXPECTED_AU_SHA1), 0x15f90, 0x159b2, true, 0, Each(0))).WillOnce(Return(true)); + EXPECT_CALL(demuxer, on_flush_done).Times(10).WillRepeatedly(Return(false)); // The flush_done event is fired repeatedly in a loop until it returns true + EXPECT_CALL(demuxer, on_flush_done).WillOnce(Return(true)); + + demuxer.enable_es(0xe0, 0x00, true, au_queue_buffer, 0x800, false, 0); + demuxer.set_stream(AVC_MULTIPLE_PACK_STREAM, false); + demuxer.process_next_pack(); + check_point.Call(0); + demuxer.flush_es(0xe0, 0x00); + demuxer.process_next_pack(); // The elementary stream should be reset after a flush, so this should not find the next access unit +} + +// Tests resetting the stream +// On LLE, it is necessary to reset the stream before setting a new one, if the current stream has not been entirely consumed yet +TEST_F(DmuxPamfTest, ResetStream) +{ + EXPECT_CALL(check_point, Call(0)); + EXPECT_CALL(demuxer, on_demux_done).WillOnce(Return(true)); + + demuxer.enable_es(0xe0, 0x00, true, au_queue_buffer, 0x1800, false, 0); + demuxer.set_stream(AVC_MULTIPLE_PACK_STREAM, false); + demuxer.reset_stream(); + check_point.Call(0); + demuxer.process_next_pack(); // Should produce a demux_done event and shouldn't find an access unit since the stream was reset + demuxer.process_next_pack(); +} + +// Disabling an elementary stream should clear the access unit queue and internal state, and the disabled stream should not be demultiplexed anymore +TEST_F(DmuxPamfTest, DisableEs) +{ + demuxer.enable_es(0xe0, 0x00, true, au_queue_buffer, 0x1800, false, 0); + demuxer.set_stream(AVC_MULTIPLE_PACK_STREAM, false); + demuxer.process_next_pack(); + demuxer.disable_es(0xe0, 0x00); + + // Should not find an access unit since the elementary stream was disabled + demuxer.process_next_pack(); + demuxer.process_next_pack(); + demuxer.process_next_pack(); +} + +// Resetting an elementary stream should clear the queue and internal state, like disabling, except the elementary stream remains enabled +TEST_F(DmuxPamfTest, ResetEs) +{ + EXPECT_CALL(check_point, Call(0)); + EXPECT_CALL(demuxer, on_au_found).WillOnce(Return(0)); + + demuxer.enable_es(0xe0, 0x00, true, au_queue_buffer, 0x1800, false, 0); + demuxer.set_stream(AVC_MULTIPLE_PACK_STREAM, false); + demuxer.process_next_pack(); + demuxer.reset_es(0xe0, 0x00, nullptr); + demuxer.process_next_pack(); // Should not find an access unit since the output queue and the current access unit state was cleared + check_point.Call(0); + demuxer.process_next_pack(); +} + +// If reset_es is called with an address, only the most recent access unit should be removed from the queue. Nothing else should be reset +TEST_F(DmuxPamfTest, ResetEsSingleAu) +{ + EXPECT_CALL(check_point, Call(0)); + EXPECT_CALL(demuxer, on_au_found).Times(2).WillRepeatedly(Return(true)); + EXPECT_CALL(demuxer, on_au_queue_full); + EXPECT_CALL(check_point, Call(1)); + EXPECT_CALL(demuxer, on_au_found).WillOnce(Return(true)); + EXPECT_CALL(demuxer, on_au_queue_full); + + std::array small_au_queue_buffer{}; + + demuxer.enable_es(0xe0, 0x00, true, small_au_queue_buffer, 0x400, false, 0); + demuxer.set_stream(AVC_SINGLE_PACK_STREAM, false); + check_point.Call(0); + demuxer.process_next_pack(); + demuxer.set_stream(AVC_SINGLE_PACK_STREAM, false); + demuxer.reset_es(0xe0, 0x00, small_au_queue_buffer.data() + 0x400); + check_point.Call(1); + demuxer.process_next_pack(); +} + +// Tests the raw elementary stream mode, which skips all MPEG program stream related parsing +// (this isn't actually available through the abstraction layer cellDmux/libdmux.sprx, but the related PPU functions are exported in libdmuxpamf.sprx) +TEST_F(DmuxPamfTest, RawEs) +{ + // Zero out MPEG-PS related stuff from the stream, so that only the elementary stream remains + constexpr std::array stream = []() consteval { auto pack = AVC_SINGLE_PACK_STREAM; std::fill_n(pack.begin(), 0x12a, 0); return pack; }(); + + EXPECT_CALL(check_point, Call(0)); + EXPECT_CALL(demuxer, on_au_found(0xe0, 0x00, 0, Sha1Is(AVC_SINGLE_PACK_EXPECTED_AU_1.data_sha1), std::numeric_limits::max(), std::numeric_limits::max(), false, _, _)).WillOnce(Return(true)); + EXPECT_CALL(demuxer, on_au_found(0xe0, 0x00, 0, Sha1Is(AVC_SINGLE_PACK_EXPECTED_AU_2.data_sha1), std::numeric_limits::max(), std::numeric_limits::max(), false, _, _)).WillOnce(Return(true)); + + demuxer.enable_es(0xe0, 0x00, true, au_queue_buffer, 0x400, true, 0); + demuxer.set_stream(stream, false); + + // In raw elementary stream mode, the demuxer still processes the stream in chunks of 0x800 bytes. + // The first call to process_next_pack() each chunk does nothing, it only sets the internal state to elementary stream parsing + demuxer.process_next_pack(); + check_point.Call(0); + demuxer.process_next_pack(); +} + +// If any of the event handlers return false (on LLE this happens if the event queue is full), the state of process_next_pack() should be saved and return immediately. +// The next time process_next_pack() is called, it should resume where it left off +TEST_F(DmuxPamfTest, EventHandlersReturnFalse) +{ + EXPECT_CALL(check_point, Call(0)); + EXPECT_CALL(demuxer, on_au_found(0xe0, 0x00, 0, Sha1Is(AVC_SINGLE_PACK_EXPECTED_AU_1.data_sha1), AVC_SINGLE_PACK_EXPECTED_AU_1.pts, AVC_SINGLE_PACK_EXPECTED_AU_1.dts, AVC_SINGLE_PACK_EXPECTED_AU_1.rap, _, _)).WillOnce(Return(false)); + EXPECT_CALL(check_point, Call(1)); + EXPECT_CALL(demuxer, on_au_found(0xe0, 0x00, 0, Sha1Is(AVC_SINGLE_PACK_EXPECTED_AU_1.data_sha1), AVC_SINGLE_PACK_EXPECTED_AU_1.pts, AVC_SINGLE_PACK_EXPECTED_AU_1.dts, AVC_SINGLE_PACK_EXPECTED_AU_1.rap, _, _)).WillOnce(Return(true)); + EXPECT_CALL(demuxer, on_au_found(0xe0, 0x00, 0, Sha1Is(AVC_SINGLE_PACK_EXPECTED_AU_2.data_sha1), AVC_SINGLE_PACK_EXPECTED_AU_2.pts, AVC_SINGLE_PACK_EXPECTED_AU_2.dts, AVC_SINGLE_PACK_EXPECTED_AU_2.rap, _, _)).WillOnce(Return(false)); + EXPECT_CALL(check_point, Call(2)); + EXPECT_CALL(demuxer, on_au_found(0xe0, 0x00, 0, Sha1Is(AVC_SINGLE_PACK_EXPECTED_AU_2.data_sha1), AVC_SINGLE_PACK_EXPECTED_AU_2.pts, AVC_SINGLE_PACK_EXPECTED_AU_2.dts, AVC_SINGLE_PACK_EXPECTED_AU_2.rap, _, _)).WillOnce(Return(true)); + + EXPECT_CALL(check_point, Call(3)); + EXPECT_CALL(demuxer, on_demux_done).WillOnce(Return(false)); + EXPECT_CALL(check_point, Call(4)); + EXPECT_CALL(demuxer, on_demux_done).WillOnce(Return(true)); + + demuxer.enable_es(0xe0, 0x00, true, au_queue_buffer, 0x800, false, 0); + demuxer.set_stream(AVC_SINGLE_PACK_STREAM, false); + check_point.Call(0); + demuxer.process_next_pack(); + check_point.Call(1); + demuxer.process_next_pack(); + check_point.Call(2); + demuxer.process_next_pack(); + + check_point.Call(3); + demuxer.process_next_pack(); + check_point.Call(4); + demuxer.process_next_pack(); + demuxer.process_next_pack(); + demuxer.process_next_pack(); +} + +// Tests if invalid stream ids are handled properly +TEST_F(DmuxPamfTest, InvalidStreamIds) +{ + const auto test = [&](u8 stream_id, u8 private_stream_id) + { + EXPECT_FALSE(demuxer.release_au(stream_id, private_stream_id, 0x800)); + EXPECT_FALSE(demuxer.disable_es(stream_id, private_stream_id)); + EXPECT_FALSE(demuxer.reset_es(stream_id, private_stream_id, nullptr)); + EXPECT_FALSE(demuxer.flush_es(stream_id, private_stream_id)); + }; + + // Trying to use or disable already disabled elementary streams should result in failures + for (u32 stream_id = 0xe0; stream_id < 0xf0; stream_id++) + { + test(stream_id, 0x00); + } + for (u32 private_stream_id = 0x00; private_stream_id < 0x10; private_stream_id++) + { + test(0xbd, private_stream_id); + } + for (u32 private_stream_id = 0x20; private_stream_id < 0x50; private_stream_id++) + { + test(0xbd, private_stream_id); + } + + // Enabling all possible elementary streams + for (u32 stream_id = 0xe0; stream_id < 0xf0; stream_id++) + { + EXPECT_TRUE(demuxer.enable_es(stream_id, 0x00, true, au_queue_buffer, 0x800, false, 0)); + } + for (u32 private_stream_id = 0x00; private_stream_id < 0x10; private_stream_id++) + { + EXPECT_TRUE(demuxer.enable_es(0xbd, private_stream_id, true, au_queue_buffer, 0x800, false, 0)); + } + for (u32 private_stream_id = 0x20; private_stream_id < 0x50; private_stream_id++) + { + EXPECT_TRUE(demuxer.enable_es(0xbd, private_stream_id, true, au_queue_buffer, 0x800, false, 0)); + } + + // Attempting to enable them again should result in failures + for (u32 stream_id = 0xe0; stream_id < 0xf0; stream_id++) + { + EXPECT_FALSE(demuxer.enable_es(stream_id, 0x00, true, au_queue_buffer, 0x800, false, 0)); + } + for (u32 private_stream_id = 0x00; private_stream_id < 0x10; private_stream_id++) + { + EXPECT_FALSE(demuxer.enable_es(0xbd, private_stream_id, true, au_queue_buffer, 0x800, false, 0)); + } + for (u32 private_stream_id = 0x20; private_stream_id < 0x50; private_stream_id++) + { + EXPECT_FALSE(demuxer.enable_es(0xbd, private_stream_id, true, au_queue_buffer, 0x800, false, 0)); + } + + // Testing all possible invalid IDs + for (u32 stream_id = 0; stream_id < 0xbd; stream_id++) + { + EXPECT_FALSE(demuxer.enable_es(stream_id, 0x00, true, au_queue_buffer, 0x800, false, 0)); + test(stream_id, 0x00); + } + for (u32 stream_id = 0xbe; stream_id < 0xe0; stream_id++) + { + EXPECT_FALSE(demuxer.enable_es(stream_id, 0x00, true, au_queue_buffer, 0x800, false, 0)); + test(stream_id, 0x00); + } + for (u32 stream_id = 0xf0; stream_id <= 0xff; stream_id++) + { + EXPECT_FALSE(demuxer.enable_es(stream_id, 0x00, true, au_queue_buffer, 0x800, false, 0)); + test(stream_id, 0x00); + } + for (u32 private_stream_id = 0x10; private_stream_id < 0x20; private_stream_id++) + { + EXPECT_FALSE(demuxer.enable_es(0xbd, private_stream_id, true, au_queue_buffer, 0x800, false, 0)); + test(0xbd, private_stream_id); + } + for (u32 private_stream_id = 0x50; private_stream_id <= 0xff; private_stream_id++) + { + EXPECT_FALSE(demuxer.enable_es(0xbd, private_stream_id, true, au_queue_buffer, 0x800, false, 0)); + test(0xbd, private_stream_id); + } +} diff --git a/rpcs3/tests/test_dmux_pamf.h b/rpcs3/tests/test_dmux_pamf.h new file mode 100644 index 0000000000..841051a4e0 --- /dev/null +++ b/rpcs3/tests/test_dmux_pamf.h @@ -0,0 +1,123 @@ +#pragma once + +struct AccessUnit +{ + u64 pts; + u64 dts; + bool rap; + u8 specific_info_size; + std::array specific_info_buf; + std::array data_sha1; +}; + +constexpr std::array AVC_SINGLE_PACK_STREAM = { 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xe0, 0x06, 0xe6, 0x81, 0xc1, 0x0d, 0x31, 0x00, 0x05, 0xbf, 0x21, 0x11, 0x00, 0x05, 0xb3, 0x65, 0x1e, 0x69, 0xb2, 0x00, 0x00, 0x01, 0x09, 0x36, 0x2c, 0xe0, 0x95, 0x35, 0x29, 0xce, 0xf6, 0xc8, 0xc9, 0xc1, 0x2b, 0xa1, 0xc5, 0xae, 0xfd, 0xa6, 0x0d, 0x98, 0xa7, 0x39, 0x66, 0xe2, 0xd9, 0xbc, 0x1a, 0xbe, 0xba, 0x03, 0xcc, 0x80, 0x90, 0x3a, 0xe9, 0x5b, 0xa7, 0xa0, 0x31, 0x21, 0xbf, 0xee, 0xd2, 0x90, 0x1e, 0x9c, 0x79, 0xbf, 0x15, 0xce, 0xac, 0x02, 0xcf, 0x85, 0xe1, 0xf9, 0x9a, 0xcb, 0x97, 0x2f, 0xd9, 0x97, 0x67, 0x63, 0xed, 0xa3, 0x6d, 0x1b, 0xa3, 0x8b, 0xef, 0x0d, 0x54, 0xd6, 0xb6, 0x4b, 0x42, 0x9b, 0x5e, 0xc4, 0x47, 0xbc, 0x21, 0x02, 0x83, 0xa0, 0x00, 0x08, 0x27, 0x83, 0x2f, 0x5a, 0x02, 0x54, 0xda, 0xe6, 0x16, 0x57, 0x93, 0x09, 0xd6, 0xe4, 0x4a, 0xd9, 0x90, 0xc0, 0x8f, 0x3e, 0xe2, 0xcc, 0xc6, 0xec, 0x8b, 0x4e, 0xf3, 0x96, 0xa7, 0x86, 0x06, 0xca, 0xae, 0xf7, 0xb5, 0xde, 0xe6, 0xcd, 0x41, 0x6e, 0x3e, 0x8e, 0x33, 0xb5, 0x2b, 0xf4, 0xbb, 0xd4, 0x5b, 0xad, 0x1d, 0xfe, 0x5e, 0xc8, 0x03, 0xdd, 0x9d, 0x7e, 0xb9, 0x55, 0xd3, 0x41, 0x76, 0xa0, 0xf1, 0xca, 0x00, 0xe5, 0x80, 0x93, 0x4f, 0x30, 0x15, 0x8c, 0x4b, 0xa6, 0xda, 0xc1, 0xac, 0x1d, 0xe5, 0x96, 0xc4, 0x88, 0x6a, 0x64, 0x4a, 0x10, 0x18, 0x94, 0xe3, 0x18, 0xc2, 0x4d, 0xe7, 0xa0, 0x5e, 0xa3, 0x7c, 0x4a, 0x47, 0x7f, 0xd6, 0x22, 0xc9, 0x44, 0xc2, 0xd1, 0x99, 0xba, 0xdf, 0xa7, 0xfd, 0x24, 0xc6, 0x4c, 0x3c, 0x32, 0xf6, 0xb1, 0x98, 0x30, 0xd1, 0x51, 0x00, 0x18, 0x76, 0xe6, 0xe5, 0x86, 0xdc, 0x4a, 0x6d, 0x28, 0x18, 0x3e, 0x0f, 0x5c, 0xb9, 0x65, 0x2b, 0x48, 0x3c, 0x90, 0x20, 0xe7, 0x88, 0x3f, 0x65, 0x6d, 0x64, 0x83, 0x7d, 0xf6, 0xd3, 0xb0, 0xc7, 0x21, 0xc0, 0xf0, 0x9a, 0xad, 0xc8, 0x53, 0x6d, 0x05, 0xa4, 0x66, 0x2d, 0x87, 0x3f, 0x03, 0x3c, 0x76, 0xd9, 0xa7, 0x6c, 0x25, 0x34, 0xe7, 0x36, 0x46, 0xf9, 0x56, 0xf4, 0x37, 0xe7, 0xa3, 0x8c, 0x32, 0xfc, 0x3f, 0x1b, 0xb6, 0x93, 0xc9, 0x4c, 0x10, 0xaa, 0xba, 0xde, 0xed, 0x3e, 0x98, 0x5f, 0x38, 0x1b, 0xe0, 0xee, 0x48, 0xab, 0xeb, 0x18, 0x1f, 0xa0, 0xc5, 0x08, 0x97, 0x00, 0x85, 0xdf, 0xd4, 0x0a, 0x96, 0xb1, 0x59, 0xeb, 0xce, 0x35, 0xc9, 0x97, 0x83, 0x15, 0xc7, 0xef, 0x01, 0xce, 0x4f, 0xb2, 0x48, 0x36, 0xef, 0xd6, 0x46, 0x54, 0x4f, 0x47, 0xa3, 0x62, 0xf0, 0xd3, 0xbd, 0xd6, 0xe5, 0xec, 0x12, 0x63, 0x60, 0xe5, 0xe7, 0x2c, 0xc1, 0xeb, 0x72, 0xb5, 0x96, 0x50, 0x34, 0x8a, 0x48, 0xc0, 0x6c, 0x48, 0xfe, 0xb0, 0x04, 0xa7, 0x1a, 0xac, 0x3a, 0x08, 0x96, 0xae, 0x9b, 0x93, 0x66, 0x56, 0x9c, 0x22, 0x6a, 0x5a, 0x57, 0x2e, 0xc7, 0xef, 0x6e, 0x54, 0xdb, 0x7f, 0x7d, 0xf1, 0x88, 0x9c, 0x01, 0x95, 0x5d, 0xa1, 0x5a, 0xbb, 0x00, 0xc1, 0xe0, 0x88, 0x9a, 0x17, 0x3f, 0x6b, 0xab, 0x96, 0x95, 0x01, 0x6e, 0x79, 0xa4, 0x54, 0x34, 0xa2, 0x79, 0xdc, 0x53, 0xf5, 0xfa, 0x4a, 0xee, 0x3f, 0x3f, 0xeb, 0xe0, 0x0b, 0x06, 0x64, 0xa5, 0x1a, 0xae, 0x92, 0xd6, 0xdc, 0x1c, 0x3e, 0x8b, 0x1c, 0x72, 0x8f, 0x1d, 0x0b, 0xac, 0xe5, 0x0a, 0x57, 0x65, 0xa9, 0x1e, 0xae, 0x6c, 0x42, 0x63, 0x4a, 0x54, 0x55, 0xa3, 0x34, 0xcd, 0x29, 0x9a, 0xcb, 0xb0, 0x26, 0xf9, 0xc7, 0x55, 0x9c, 0xe1, 0x38, 0x81, 0x3e, 0x8a, 0x72, 0x2c, 0x7f, 0xff, 0xcb, 0x66, 0x75, 0x11, 0xda, 0xe6, 0xb0, 0x12, 0xa8, 0x4c, 0x22, 0x50, 0x6a, 0x69, 0x9e, 0x3d, 0xdc, 0x46, 0x68, 0x2f, 0x9d, 0x27, 0x03, 0x70, 0xe8, 0x46, 0xa2, 0x12, 0x2d, 0x3f, 0x57, 0x45, 0x2a, 0x8f, 0x5a, 0xb9, 0x0d, 0xf0, 0x61, 0x41, 0x7b, 0x51, 0x6c, 0x2d, 0xc5, 0x93, 0x5e, 0x50, 0xcd, 0x98, 0x20, 0xdb, 0x95, 0x3e, 0xf9, 0x80, 0x7d, 0xfd, 0xae, 0xd1, 0xec, 0xa2, 0x96, 0x2b, 0xd5, 0xd5, 0x29, 0x71, 0xd1, 0xb2, 0xbd, 0x4e, 0x03, 0xb2, 0xa3, 0x30, 0x54, 0xbe, 0xbc, 0x08, 0x7b, 0x05, 0xa3, 0x86, 0x8d, 0x7f, 0xa3, 0x6e, 0x9b, 0xad, 0xbd, 0xc8, 0x59, 0xe4, 0xcf, 0x9e, 0x3e, 0x19, 0x6f, 0xcf, 0xda, 0x2b, 0x9b, 0x6b, 0x9d, 0xb7, 0xc5, 0xbc, 0x9a, 0x67, 0x4c, 0x08, 0x0e, 0xa1, 0xa2, 0x19, 0xc6, 0x3c, 0x0d, 0x87, 0xcb, 0x11, 0x0f, 0x53, 0x85, 0x9b, 0xa9, 0x97, 0xa0, 0xba, 0x04, 0x98, 0x66, 0x57, 0xa5, 0xb9, 0x09, 0x31, 0xfe, 0xa9, 0xd2, 0xb4, 0x30, 0xa9, 0x9c, 0x0e, 0x6c, 0x62, 0x3a, 0x04, 0xcd, 0x2a, 0x64, 0x91, 0xfe, 0xee, 0x19, 0xa6, 0xa8, 0x6d, 0x87, 0xa2, 0x1a, 0xda, 0xb6, 0xf1, 0x27, 0x35, 0x95, 0x47, 0x64, 0xfa, 0x1f, 0xed, 0xcf, 0x7b, 0xdc, 0x9a, 0x18, 0x2e, 0xfe, 0xf3, 0x56, 0x6d, 0x28, 0xce, 0xcd, 0x16, 0x03, 0x59, 0x14, 0x4a, 0x90, 0xc2, 0xe3, 0x20, 0x6b, 0x96, 0xd5, 0x30, 0x20, 0x3f, 0xc4, 0xeb, 0x48, 0xe5, 0x9c, 0x34, 0xdf, 0x8d, 0x46, 0x73, 0x1d, 0x54, 0x11, 0x65, 0x5b, 0xe4, 0xab, 0xb3, 0xa6, 0x1e, 0x40, 0x43, 0xb5, 0x84, 0x61, 0x94, 0x01, 0xea, 0x92, 0xd4, 0x9f, 0xb9, 0xc6, 0x26, 0x2d, 0x56, 0xda, 0xa4, 0x11, 0x5f, 0xf6, 0x3f, 0xa2, 0xd8, 0xcb, 0xda, 0xb7, 0x0e, 0xc6, 0x0e, 0x6d, 0xbe, 0x0d, 0x9a, 0x46, 0xc2, 0x77, 0x7d, 0x3a, 0x0d, 0x67, 0xf9, 0x58, 0xf4, 0xba, 0x65, 0xb2, 0xe0, 0x39, 0x60, 0xcf, 0x76, 0xd4, 0x15, 0x73, 0x46, 0xdf, 0x14, 0x22, 0xa7, 0x25, 0x6f, 0xd3, 0x9f, 0x8f, 0xa9, 0x60, 0x1f, 0xbb, 0x13, 0x71, 0x1b, 0x43, 0x4f, 0x9f, 0x66, 0x17, 0x4a, 0xd7, 0x56, 0xd6, 0x84, 0xec, 0x65, 0xd1, 0xb1, 0x64, 0x48, 0x65, 0x18, 0x61, 0x8f, 0x7e, 0xef, 0xdf, 0x5d, 0xea, 0x7d, 0x67, 0xb2, 0x66, 0x95, 0xfe, 0xf3, 0x6c, 0xf4, 0xaa, 0x1d, 0x14, 0x0e, 0x73, 0x0e, 0xca, 0x32, 0xc1, 0x52, 0x23, 0x77, 0xba, 0x94, 0x31, 0x4b, 0x26, 0x44, 0xce, 0x34, 0xe6, 0xd0, 0x6a, 0xa9, 0x5c, 0x58, 0xbd, 0xf8, 0xc6, 0xf4, 0x0b, 0xac, 0xab, 0x1e, 0x5a, 0x81, 0xee, 0x4a, 0xe4, 0x7a, 0x4b, 0xf0, 0x92, 0xad, 0xad, 0x75, 0xd3, 0x0a, 0xa1, 0x71, 0xab, 0x1f, 0x90, 0xbd, 0x8c, 0x80, 0xcd, 0x09, 0x7f, 0x9a, 0x46, 0xbd, 0xd5, 0x92, 0x66, 0x8b, 0xc9, 0xc0, 0x3b, 0xbc, 0xdb, 0xff, 0xa6, 0x99, 0x08, 0xb6, 0x73, 0xf9, 0x79, 0x6e, 0x8d, 0xee, 0x51, 0xdd, 0xd7, 0xe5, 0xec, 0xb4, 0xa1, 0x92, 0x58, 0xab, 0xdc, 0x79, 0xfe, 0xc9, 0xad, 0x55, 0xf3, 0x07, 0x86, 0x56, 0x81, 0x4d, 0x90, 0x52, 0x48, 0x15, 0xbf, 0x56, 0xa1, 0xd4, 0x96, 0xae, 0x44, 0x3c, 0x35, 0x25, 0x06, 0x39, 0xde, 0x60, 0x86, 0x88, 0xb0, 0xc6, 0xcc, 0x98, 0x8f, 0x06, 0x14, 0xb7, 0xed, 0x5b, 0x92, 0x7f, 0x64, 0xc4, 0xd0, 0xf1, 0x2a, 0x89, 0x08, 0x32, 0xab, 0x26, 0x28, 0x55, 0xff, 0xd7, 0xca, 0xf0, 0x41, 0xfe, 0x7d, 0x90, 0xd3, 0x52, 0xcb, 0x6b, 0x1b, 0x2d, 0xfa, 0x05, 0x01, 0x2f, 0xf1, 0xda, 0x84, 0xbe, 0x5c, 0x86, 0xcd, 0x41, 0x09, 0xfe, 0x92, 0xbf, 0x74, 0xc9, 0x75, 0x21, 0x89, 0x70, 0xac, 0x1c, 0x70, 0xdd, 0x56, 0xcb, 0xb0, 0xe1, 0xb9, 0xb4, 0xf8, 0x1c, 0x00, 0x00, 0x01, 0x09, 0x22, 0x6d, 0x07, 0x49, 0x80, 0xdb, 0x25, 0x5c, 0xeb, 0xa5, 0x99, 0x4a, 0xb0, 0x12, 0x9c, 0xc1, 0xce, 0x89, 0xca, 0xc8, 0x57, 0x99, 0x56, 0x40, 0x18, 0xe7, 0xb1, 0xe7, 0x47, 0x97, 0x47, 0xc2, 0xa4, 0x7a, 0xae, 0x3e, 0xe2, 0xb3, 0xec, 0xc2, 0x69, 0x43, 0xd9, 0xe3, 0x9c, 0x95, 0xde, 0x01, 0x95, 0xb7, 0xb4, 0x08, 0x8d, 0x7f, 0x1d, 0x2e, 0x95, 0x0f, 0x3c, 0xdd, 0x9e, 0x64, 0xd6, 0xf3, 0xe6, 0xa0, 0x24, 0xe5, 0x19, 0xf0, 0x96, 0x92, 0x0a, 0xde, 0xc5, 0x12, 0xf7, 0x3a, 0xa3, 0x26, 0x12, 0x84, 0x7b, 0x73, 0x1d, 0xd5, 0xbc, 0xf4, 0x47, 0xfd, 0x81, 0xf7, 0xd9, 0x03, 0xc4, 0x34, 0x06, 0x2b, 0x05, 0x40, 0xa7, 0x2e, 0x1d, 0xbd, 0x5c, 0x85, 0x27, 0x77, 0xf7, 0x75, 0xca, 0xd5, 0x34, 0x5b, 0xf5, 0x40, 0x7e, 0x06, 0x92, 0x5c, 0x94, 0x89, 0x0a, 0xa3, 0x0e, 0x63, 0x95, 0x5d, 0x54, 0x28, 0x86, 0x68, 0x17, 0x2d, 0xd3, 0xc3, 0x46, 0x93, 0xbb, 0x9c, 0xae, 0xea, 0x35, 0xdd, 0xda, 0xc4, 0x1b, 0xa3, 0xba, 0xee, 0x1e, 0x7e, 0xab, 0xb9, 0xba, 0xe4, 0x8d, 0x5e, 0x98, 0x9f, 0x84, 0xba, 0x0c, 0x7c, 0x29, 0x63, 0xed, 0xae, 0x90, 0x54, 0x9c, 0x74, 0x2a, 0x80, 0xe4, 0x4d, 0xbc, 0x5b, 0xaa, 0xd5, 0xbe, 0x64, 0xae, 0xab, 0xc1, 0x45, 0xb7, 0xfd, 0xc1, 0x48, 0xd3, 0x48, 0x32, 0x82, 0xea, 0x3f, 0x93, 0x3c, 0xa5, 0xef, 0xf1, 0x45, 0x73, 0xae, 0x60, 0x98, 0x36, 0x5e, 0xb1, 0xaa, 0x7c, 0x1b, 0x23, 0x68, 0xaa, 0x7f, 0x5c, 0x6a, 0x2d, 0xad, 0x23, 0xa5, 0x82, 0x9a, 0x0e, 0x65, 0x62, 0xca, 0x91, 0x61, 0x39, 0xfd, 0xd1, 0x3f, 0x6f, 0xc0, 0xf0, 0xa2, 0x2d, 0xcc, 0x99, 0x96, 0xd3, 0x6b, 0xe3, 0x51, 0x5c, 0x12, 0x3c, 0x23, 0x88, 0xc3, 0x8d, 0x42, 0x7c, 0xf3, 0xec, 0x9e, 0x5c, 0x69, 0xb7, 0xb6, 0xf7, 0xa7, 0x07, 0xd5, 0x56, 0x8b, 0x8b, 0x2c, 0x3f, 0x29, 0x02, 0x03, 0xb1, 0xde, 0xe6, 0xeb, 0xbd, 0x52, 0x4c, 0xf3, 0x4e, 0x03, 0xf9, 0x9f, 0x4a, 0x2d, 0x23, 0x10, 0x57, 0xf5, 0x96, 0xd2, 0x0e, 0x8c, 0x72, 0xd2, 0x56, 0xdf, 0x44, 0x1a, 0xcb, 0x36, 0xe9, 0x03, 0x67, 0xca, 0xa9, 0xbf, 0x38, 0x43, 0x73, 0x49, 0xb8, 0x9a, 0x13, 0x4c, 0x78, 0x89, 0xac, 0xc7, 0xb9, 0x8c, 0x2c, 0xee, 0x80, 0x04, 0xf7, 0x75, 0x4f, 0xd2, 0x7c, 0xb5, 0x20, 0xe2, 0x3b, 0xb8, 0xc5, 0x57, 0x2e, 0xc8, 0x9f, 0xcb, 0xd1, 0xee, 0xcf, 0x59, 0x6c, 0xc1, 0x85, 0xe6, 0x34, 0x42, 0xe2, 0x65, 0x7b, 0xbb, 0xae, 0x2e, 0x97, 0x0b, 0x3f, 0x1b, 0xfb, 0xd3, 0xcc, 0x5d, 0x01, 0xba, 0xf9, 0x30, 0x62, 0xa5, 0xd6, 0xe0, 0xca, 0xce, 0xde, 0x52, 0x68, 0x90, 0x76, 0xa3, 0x82, 0x88, 0x52, 0xa2, 0xb0, 0x9c, 0xa1, 0x3d, 0xf8, 0x95, 0x35, 0x31, 0x8d, 0x0a, 0x9c, 0xaa, 0xac, 0xb7, 0x2f, 0x30, 0x4e, 0xda, 0x0b, 0x56, 0x32, 0x8d, 0xda, 0xd5, 0xc2, 0xd3, 0x1b, 0x7f, 0xc1, 0xf6, 0xd1, 0xde, 0x07, 0xe4, 0x94, 0x34, 0xb9, 0x00, 0x40, 0x05, 0xa3, 0x6a, 0x0d, 0x8f, 0xd8, 0x44, 0x0b, 0xc3, 0x64, 0xd0, 0x53, 0x70, 0x5c, 0xc9, 0x99, 0x13, 0xac, 0xc8, 0x09, 0x85, 0x44, 0x3c, 0x1d, 0x99, 0x26, 0x52, 0x3c, 0xce, 0x50, 0xe4, 0x44, 0xd0, 0xd0, 0xa5, 0xa8, 0xad, 0x6b, 0xae, 0xf0, 0xca, 0x58, 0x22, 0x9f, 0x61, 0xf6, 0xb3, 0x6b, 0xd0, 0x34, 0x9b, 0x3b, 0x45, 0x25, 0x5e, 0x0e, 0xac, 0xf6, 0x82, 0x2b, 0x01, 0xa4, 0x49, 0x72, 0x23, 0xd7, 0xd3, 0x31, 0xb9, 0x36, 0xb2, 0x3e, 0x06, 0xcc, 0xfc, 0x82, 0xee, 0x12, 0x97, 0x26, 0xae, 0xe5, 0x03, 0xb5, 0x54, 0x3f, 0x45, 0xde, 0x94, 0xb1, 0x39, 0xbd, 0xd7, 0xe3, 0x20, 0xca, 0x85, 0xa1, 0x83, 0x04, 0xfc, 0x93, 0x8d, 0xbf, 0x2d, 0x49, 0x36, 0x8e, 0xf2, 0x82, 0x3f, 0xcf, 0xcf, 0xfb, 0xae, 0x31, 0x35, 0x45, 0xa4, 0xde, 0xd7, 0xc7, 0x07, 0xdd, 0xdc, 0x12, 0x68, 0x6f, 0x93, 0x44, 0xef, 0xd5, 0x96, 0x00, 0x04, 0x1a, 0xc7, 0x46, 0xe7, 0x51, 0x76, 0xd4, 0x3a, 0x50, 0x40, 0xce, 0x9a, 0x55, 0x1e, 0xd6, 0x9a, 0x8d, 0xd9, 0xc8, 0x34, 0xea, 0xda, 0xdc, 0x5f, 0x51, 0x88, 0x80, 0xcf, 0xf9, 0xb9, 0x20, 0x8b, 0x60, 0xf9, 0xbf, 0x2a, 0x24, 0x18, 0x8f, 0x86, 0xc8, 0xaa, 0x00, 0xf9, 0x05, 0xef, 0x38, 0x59, 0xa2, 0xe9, 0x36, 0xac, 0x01, 0xd5, 0xa6, 0x09, 0x22, 0x5c, 0xd7, 0xca, 0xc3, 0x15, 0xb4, 0x8f, 0x6f, 0x1e, 0xe9, 0xca, 0xe4, 0xad, 0x77, 0x28, 0x99, 0x8f, 0xdd, 0x8a, 0x5d, 0x82, 0x17, 0xa7, 0x58, 0x6f, 0x71, 0x66, 0x8f, 0x74, 0x69, 0xc9, 0x0e, 0x58, 0xf3, 0xc6, 0x37, 0x93, 0xf9, 0xff, 0xf6, 0x6b, 0x51, 0xa7, 0x5c, 0x61, 0x12, 0x92, 0x0d, 0xc9, 0x3b, 0x59, 0xe9, 0xea, 0x14, 0x25, 0x29, 0x28, 0xd1, 0x51, 0xc6, 0x1c, 0x39, 0x80, 0x2f, 0x99, 0xbd, 0xd0, 0xcd, 0x03, 0x71, 0xba, 0xb4, 0x1c, 0xd3, 0x2f, 0xa9, 0xaf, 0xc6, 0x24, 0x24, 0xb9, 0xd5, 0xc7, 0xe3, 0xda, 0xf1, 0xd2, 0x4d, 0xc2, 0x69, 0x31, 0x64, 0xc6, 0xfd, 0xb5, 0xce, 0x00, 0x3a, 0xc7, 0x9c, 0x95, 0xfd, 0x88, 0xb5, 0x58, 0xc5, 0x7d, 0x52, 0xf4, 0x58, 0x83, 0x4a, 0xc8, 0x07, 0xd3, 0x45, 0x53, 0x66, 0x00, 0x00, 0x01, 0x09 }; +constexpr AccessUnit AVC_SINGLE_PACK_EXPECTED_AU_1 = { 0x15f90, 0x159b2, true, 0, {}, { 0xdb, 0x46, 0x52, 0xf7, 0x3e, 0x38, 0x99, 0x16, 0xe6, 0x60, 0x20, 0x01, 0x4d, 0xce, 0x65, 0x8f, 0xfa, 0xb5, 0x8f, 0x3a } }; +constexpr AccessUnit AVC_SINGLE_PACK_EXPECTED_AU_2 = { std::numeric_limits::max(), std::numeric_limits::max(), false, 0, {}, { 0xd2, 0x40, 0xa9, 0x31, 0x5a, 0x2f, 0x92, 0xb0, 0x3c, 0x26, 0xa9, 0xd0, 0xdf, 0xfb, 0x97, 0x2d, 0xb3, 0xf1, 0x4d, 0x78 } }; + +constexpr std::array M2V_SINGLE_PACK_STREAM = { 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xe0, 0x06, 0xe6, 0x81, 0xc1, 0x0d, 0x31, 0x00, 0x05, 0xbf, 0x21, 0x11, 0x00, 0x05, 0xb3, 0x65, 0x1e, 0x69, 0xb2, 0x00, 0x00, 0x01, 0xb3, 0x5f, 0x55, 0xe4, 0xf8, 0x98, 0x9f, 0x07, 0x15, 0x3e, 0x0f, 0x8d, 0x16, 0xed, 0xcd, 0x0a, 0xa8, 0x39, 0xbf, 0xb5, 0xba, 0x30, 0xf0, 0x64, 0x37, 0x31, 0xba, 0xec, 0x8e, 0xa0, 0x68, 0xcc, 0xa1, 0xfd, 0x1f, 0x93, 0xff, 0xc3, 0xd1, 0xbf, 0x05, 0x6f, 0x8f, 0x71, 0x78, 0x90, 0xeb, 0xc1, 0x9e, 0xe6, 0x63, 0xad, 0x00, 0x07, 0xcb, 0x8f, 0x60, 0x57, 0xc6, 0x3c, 0xbb, 0x4b, 0x47, 0xe8, 0xc9, 0x8c, 0x58, 0x5c, 0x78, 0x12, 0x21, 0x20, 0xc8, 0x54, 0xa7, 0x85, 0x65, 0x2d, 0x4a, 0x86, 0xb3, 0x66, 0x5e, 0x89, 0x8e, 0xeb, 0xd6, 0x37, 0xaa, 0xcb, 0xab, 0xb0, 0x42, 0x94, 0xe6, 0x77, 0x86, 0xfd, 0x21, 0x8e, 0xb8, 0xe5, 0x4d, 0x5f, 0x94, 0x38, 0xc1, 0x0c, 0xaa, 0x92, 0xb4, 0xf4, 0x20, 0x75, 0x2d, 0x60, 0xa8, 0x83, 0x7b, 0x1d, 0xa1, 0x91, 0x7c, 0xf9, 0x82, 0xfb, 0x89, 0x19, 0x8e, 0x3b, 0xb2, 0x8b, 0xb9, 0x61, 0x3e, 0x62, 0x29, 0x96, 0xe6, 0x64, 0x91, 0xce, 0x61, 0x11, 0xb9, 0x69, 0x4d, 0xcb, 0xcb, 0x9c, 0xe2, 0xca, 0xa4, 0x97, 0x3a, 0x3a, 0xc5, 0xea, 0xeb, 0x2b, 0xf1, 0x08, 0xad, 0x68, 0xe3, 0xd2, 0xd0, 0xff, 0x49, 0x34, 0xb6, 0x09, 0x91, 0xa3, 0xfe, 0xc2, 0x4f, 0x69, 0x7e, 0xaf, 0xf5, 0x15, 0x42, 0x47, 0xc2, 0x8e, 0x14, 0xc6, 0x99, 0x80, 0x2f, 0x57, 0xbe, 0x39, 0x6e, 0x5e, 0xb2, 0x7f, 0x96, 0x21, 0xe5, 0x96, 0x6b, 0x4c, 0x99, 0xb5, 0x18, 0xcf, 0x87, 0x28, 0x5a, 0x66, 0x03, 0xaa, 0xcc, 0xd5, 0xce, 0x1d, 0x42, 0x99, 0xb4, 0x58, 0xf8, 0xf8, 0x82, 0x58, 0x8a, 0x94, 0x4a, 0xce, 0x92, 0x53, 0xec, 0xeb, 0x00, 0x00, 0x01, 0x00, 0xdd, 0xdc, 0xcc, 0xa9, 0x9d, 0x30, 0xfa, 0x65, 0xff, 0xd5, 0xc6, 0xb5, 0x2f, 0x5a, 0x14, 0xab, 0x0a, 0x86, 0x18, 0x98, 0x8c, 0x02, 0x49, 0x11, 0x05, 0x78, 0xf7, 0xae, 0x21, 0x7a, 0x5e, 0xa8, 0x1d, 0x5e, 0x1c, 0x1b, 0x7f, 0x8d, 0xe9, 0x05, 0x0b, 0x93, 0x4f, 0x98, 0xaa, 0x11, 0x71, 0x91, 0x0f, 0x8b, 0x47, 0x43, 0x69, 0x12, 0x1b, 0x30, 0x31, 0x3b, 0x8d, 0x5a, 0x09, 0x91, 0x19, 0x83, 0xd8, 0x68, 0x0d, 0xc9, 0x25, 0xf6, 0xdf, 0x42, 0xb2, 0x49, 0x76, 0xcf, 0x98, 0x6a, 0x54, 0xfa, 0x10, 0xd8, 0x5b, 0x51, 0x75, 0xb8, 0x80, 0x7e, 0xfd, 0x92, 0x7f, 0x57, 0xcf, 0x9c, 0xad, 0xb4, 0x90, 0xb1, 0x42, 0x3e, 0xa0, 0xea, 0xde, 0xea, 0x66, 0x7b, 0xd6, 0xa0, 0xf3, 0xc3, 0xa6, 0xe0, 0x4b, 0x3c, 0x97, 0xf0, 0x11, 0x95, 0xb7, 0xb7, 0xd1, 0x94, 0x0a, 0x32, 0x11, 0x4d, 0x34, 0x8d, 0x72, 0xc5, 0xfd, 0x96, 0xfc, 0x44, 0xd7, 0x59, 0xcf, 0xa5, 0xd7, 0x2d, 0x3a, 0xd0, 0x7d, 0x1c, 0x88, 0xac, 0x7d, 0x63, 0xad, 0xcd, 0x35, 0xd1, 0xba, 0x66, 0xc5, 0x20, 0xb7, 0x65, 0x41, 0xe3, 0x41, 0x39, 0xfe, 0xdd, 0x90, 0x40, 0x52, 0xe8, 0x51, 0x86, 0x2c, 0xb0, 0x1f, 0x36, 0x57, 0x77, 0x8c, 0xe7, 0xf6, 0x8f, 0xc6, 0x5d, 0xfe, 0xa4, 0x4c, 0x65, 0x01, 0x53, 0x0b, 0xe6, 0x8a, 0xc5, 0x6b, 0x17, 0xa0, 0xe7, 0x31, 0xe1, 0xce, 0x1e, 0xc8, 0xc8, 0xb3, 0x8d, 0x04, 0x0e, 0x7f, 0x6a, 0xaa, 0x32, 0x4e, 0x24, 0xe8, 0xc8, 0xbf, 0x8c, 0xec, 0xea, 0xcd, 0xb2, 0xd4, 0xdc, 0x0c, 0xb6, 0xc9, 0xac, 0x6e, 0x66, 0xa7, 0x22, 0xa5, 0x26, 0xe0, 0x90, 0xad, 0x6f, 0xef, 0x96, 0x85, 0xee, 0x53, 0xfb, 0xdd, 0xd6, 0x6a, 0xa7, 0x45, 0xb9, 0x64, 0x3b, 0x4d, 0xfc, 0xce, 0x21, 0x7d, 0x33, 0x70, 0xb4, 0xb6, 0x43, 0x97, 0x77, 0xcc, 0x8e, 0x38, 0xee, 0x82, 0x54, 0x26, 0x1e, 0xc1, 0x6e, 0x86, 0x1c, 0x39, 0x62, 0x46, 0xf5, 0x11, 0x95, 0xbf, 0x64, 0xa0, 0xf9, 0x1d, 0x1a, 0x23, 0x34, 0x42, 0x0b, 0x11, 0x6b, 0x55, 0x19, 0x37, 0xb8, 0x43, 0xa2, 0x24, 0x22, 0x08, 0xca, 0xa0, 0xb9, 0x90, 0xae, 0x74, 0x57, 0xb3, 0x7b, 0x31, 0x1a, 0x50, 0xc3, 0xe6, 0xb9, 0xaa, 0xb1, 0xc9, 0x41, 0xcd, 0x7f, 0x11, 0xac, 0xf2, 0x4f, 0x92, 0xeb, 0xe7, 0xd1, 0xd5, 0x58, 0x6a, 0xdd, 0x15, 0x1c, 0xd6, 0x9f, 0x4e, 0xb3, 0xa5, 0x7a, 0xdc, 0xde, 0x33, 0x25, 0x14, 0x59, 0x58, 0x21, 0x96, 0x8f, 0x5c, 0x78, 0x08, 0x5b, 0xe6, 0xa0, 0xca, 0x75, 0x83, 0x2a, 0x76, 0x16, 0x10, 0x34, 0x1f, 0x6f, 0x4b, 0x60, 0x8d, 0x8e, 0xf8, 0xb1, 0xe2, 0xac, 0xe5, 0xe3, 0x48, 0xcb, 0x99, 0xdb, 0x5e, 0xc8, 0xad, 0x15, 0x35, 0x44, 0xac, 0x92, 0x83, 0x95, 0x19, 0x91, 0x0c, 0x7f, 0x0a, 0xf2, 0x17, 0xc7, 0xff, 0x95, 0xd2, 0xee, 0x10, 0xad, 0xde, 0x03, 0xe2, 0x20, 0x1e, 0xd9, 0x4f, 0xda, 0x80, 0xf8, 0xba, 0x7e, 0x6d, 0x0c, 0x9e, 0xce, 0xbe, 0x61, 0x89, 0x16, 0x2a, 0x2f, 0xf6, 0x58, 0xce, 0x50, 0x4d, 0x23, 0x02, 0x5a, 0xf4, 0x11, 0xf3, 0xd7, 0x5a, 0x15, 0xaa, 0xd2, 0x74, 0xa1, 0x9b, 0x87, 0x40, 0xec, 0x37, 0x9f, 0x36, 0x05, 0x36, 0xd6, 0xf1, 0x7d, 0x2d, 0xd4, 0x16, 0x38, 0xf1, 0xe3, 0x64, 0xeb, 0x8d, 0x69, 0xa5, 0x6e, 0xac, 0xd6, 0x1c, 0x8b, 0x3d, 0x7a, 0x52, 0xb5, 0x50, 0xe4, 0x57, 0x61, 0xb8, 0xf2, 0xde, 0x77, 0x5c, 0x4b, 0x4a, 0x5a, 0x76, 0x97, 0x0d, 0x82, 0x50, 0xb6, 0x8a, 0x72, 0x64, 0x9f, 0xc2, 0x14, 0xbf, 0xbb, 0x4f, 0xe9, 0x5b, 0x34, 0x41, 0x27, 0xf3, 0x04, 0x8e, 0x9e, 0xd2, 0xc4, 0xc0, 0x56, 0xd5, 0x91, 0x99, 0x18, 0xbb, 0xd4, 0x41, 0xb3, 0xe4, 0x0a, 0xaf, 0x3f, 0xc2, 0xde, 0x4c, 0x97, 0x00, 0x4d, 0xc2, 0x83, 0x1c, 0x1c, 0xd9, 0x49, 0xd5, 0x24, 0x25, 0xab, 0x90, 0x8b, 0xac, 0x39, 0x58, 0x55, 0x1b, 0x17, 0xc3, 0x41, 0x66, 0x91, 0xa1, 0x78, 0x6e, 0x01, 0x20, 0x82, 0x54, 0x7e, 0xad, 0x0b, 0x6d, 0x05, 0x51, 0x00, 0x00, 0x01, 0x00, 0x12, 0xb7, 0x73, 0x59, 0x4c, 0x73, 0x73, 0x28, 0xdb, 0x82, 0x34, 0xcf, 0x9a, 0xa1, 0x13, 0xe9, 0xdf, 0x22, 0x5c, 0x02, 0xf7, 0x43, 0x86, 0x56, 0x99, 0x20, 0x4c, 0x74, 0x5b, 0x39, 0xe7, 0x55, 0x28, 0x06, 0x7e, 0x18, 0x1e, 0xbf, 0xaf, 0xbd, 0x73, 0xa5, 0x15, 0xb5, 0xc7, 0x8c, 0x1a, 0x07, 0x78, 0x78, 0xed, 0x02, 0x10, 0xe7, 0x34, 0xbd, 0x09, 0x14, 0xb9, 0xb3, 0xf8, 0x15, 0xe9, 0xd4, 0xa0, 0x41, 0x93, 0x69, 0x97, 0x46, 0xd1, 0x41, 0x0c, 0x3f, 0xa3, 0x2d, 0x24, 0xda, 0x2f, 0x2b, 0x04, 0xad, 0x07, 0x61, 0x91, 0xf0, 0x8f, 0x55, 0xa6, 0x70, 0x51, 0x5c, 0x2d, 0xfc, 0x30, 0xad, 0xc6, 0x47, 0xc4, 0x35, 0x6e, 0x47, 0xe0, 0x25, 0x02, 0x51, 0x2f, 0xed, 0xf5, 0x34, 0xe0, 0xe8, 0x4e, 0x9f, 0xc0, 0x43, 0x68, 0x05, 0x5c, 0x66, 0x54, 0x7d, 0x19, 0x19, 0xba, 0xf3, 0x12, 0xf1, 0xa6, 0xb1, 0xe3, 0x22, 0x2d, 0x71, 0x55, 0xe6, 0xce, 0x91, 0x0d, 0x92, 0x0d, 0x94, 0x1d, 0x7a, 0xc4, 0xa5, 0x53, 0x1c, 0x9b, 0xa7, 0x7f, 0xaa, 0xd2, 0x3b, 0xdd, 0x0f, 0x92, 0xc5, 0xef, 0x5f, 0xbd, 0x1a, 0xc4, 0xa1, 0x7b, 0x9a, 0xc6, 0xc2, 0x51, 0x8a, 0x8f, 0x02, 0x26, 0x0d, 0x49, 0x4b, 0x36, 0xfa, 0x1c, 0xfe, 0x62, 0xcd, 0x81, 0x95, 0x7c, 0x98, 0x7a, 0x45, 0x0d, 0xc5, 0x84, 0x75, 0x7e, 0x14, 0xaf, 0x11, 0x06, 0x23, 0x90, 0x8b, 0x50, 0x27, 0x8c, 0x57, 0xcc, 0x55, 0xa0, 0xa9, 0x52, 0x1a, 0x94, 0x9e, 0x96, 0x52, 0xdf, 0x7f, 0x6d, 0xcf, 0x37, 0x87, 0xae, 0x01, 0x28, 0x41, 0xde, 0x29, 0x70, 0x0c, 0x90, 0xf8, 0xcc, 0x7c, 0x2e, 0x6a, 0x37, 0x12, 0x9d, 0x49, 0xfe, 0x3f, 0xec, 0x6d, 0x21, 0xce, 0x67, 0x8b, 0xc9, 0xab, 0x20, 0x38, 0x80, 0x8b, 0x93, 0x24, 0x3f, 0x62, 0x03, 0x57, 0x59, 0x83, 0xb4, 0x6c, 0xdd, 0x68, 0xdd, 0x4c, 0x89, 0xfc, 0x79, 0x64, 0x47, 0x0e, 0x44, 0x96, 0xb7, 0x0b, 0x0a, 0xab, 0x9a, 0x1e, 0xc5, 0x24, 0x92, 0x3c, 0xf5, 0x91, 0x77, 0x39, 0x67, 0x41, 0x5a, 0xdd, 0x62, 0x91, 0x95, 0xe5, 0x64, 0x56, 0x0a, 0x2d, 0xee, 0xf4, 0x65, 0x98, 0xa6, 0x73, 0x28, 0x71, 0xb8, 0xa0, 0x9b, 0xa8, 0x95, 0x6e, 0xa6, 0xec, 0xb3, 0xf7, 0x19, 0xf5, 0xcd, 0x60, 0xf2, 0x5d, 0x1e, 0x23, 0x4c, 0xeb, 0x53, 0xad, 0x28, 0xd1, 0x7e, 0xa2, 0xbb, 0x83, 0xf8, 0x55, 0x9e, 0x08, 0x85, 0xfb, 0x47, 0x3c, 0x9e, 0x3b, 0xbb, 0x81, 0xa2, 0x13, 0xc0, 0x8e, 0x18, 0x37, 0x2e, 0x98, 0x61, 0x88, 0x3e, 0x13, 0x06, 0x67, 0x1e, 0x03, 0xea, 0x7a, 0xb1, 0x3e, 0x6b, 0xef, 0x68, 0x09, 0x11, 0xfb, 0x80, 0x16, 0x12, 0x34, 0xc3, 0xb1, 0x14, 0x13, 0x64, 0x64, 0xc6, 0x6d, 0xf9, 0x43, 0x2c, 0xc2, 0x08, 0xac, 0xb5, 0x72, 0xe2, 0xf6, 0x44, 0x65, 0x90, 0x0a, 0xdc, 0x80, 0xab, 0x69, 0xdf, 0x63, 0x22, 0x57, 0x9d, 0x8e, 0xd7, 0x7d, 0x8d, 0xd5, 0x10, 0xd1, 0xc8, 0xd1, 0xbd, 0x39, 0xd9, 0x71, 0x7b, 0x0f, 0x10, 0x7f, 0x9a, 0x35, 0xdb, 0x1f, 0x3e, 0x69, 0x7c, 0x79, 0x6c, 0x5e, 0x2f, 0x5e, 0x97, 0xd4, 0xfc, 0xff, 0x7f, 0xf3, 0x5c, 0x68, 0xa7, 0xd6, 0x3d, 0xce, 0x5c, 0x90, 0x98, 0x61, 0x0e, 0x13, 0xe6, 0x3d, 0xa0, 0x24, 0xae, 0x75, 0x0d, 0x2d, 0xfc, 0xd7, 0x93, 0xae, 0x17, 0xf6, 0x9a, 0x27, 0xb8, 0x78, 0xca, 0xfa, 0x5d, 0x54, 0x10, 0x12, 0xf2, 0x54, 0x71, 0x46, 0xf3, 0xf7, 0x32, 0xe4, 0xb6, 0xb7, 0xab, 0x9a, 0xe5, 0xd4, 0x12, 0xd8, 0x09, 0xdc, 0x35, 0xa1, 0xe9, 0x5e, 0x39, 0x47, 0xe2, 0x9d, 0x79, 0xf7, 0x56, 0x34, 0x73, 0x51, 0x48, 0x3d, 0xce, 0xef, 0x3c, 0xbd, 0xe8, 0xd5, 0xd5, 0x5b, 0x95, 0x64, 0xf0, 0x12, 0x57, 0xac, 0x66, 0xa0, 0x73, 0x43, 0xd9, 0x35, 0x40, 0x0e, 0x98, 0x1d, 0x3e, 0x7b, 0x35, 0xa6, 0xaa, 0xfe, 0xad, 0x7d, 0x5a, 0xe6, 0x10, 0x0b, 0xc8, 0x27, 0x7a, 0x1c, 0xb2, 0x72, 0x78, 0x16, 0xbf, 0x87, 0x3e, 0xc9, 0xe3, 0xf2, 0xea, 0x44, 0x4a, 0x4c, 0x65, 0x5c, 0x2e, 0xe1, 0xfc, 0xb8, 0x69, 0xfe, 0xf2, 0xdd, 0xe6, 0x96, 0x45, 0x84, 0xf8, 0xd2, 0xc2, 0x8b, 0xe3, 0x05, 0x9b, 0x32, 0x59, 0xf8, 0xba, 0xcf, 0x2d, 0xa8, 0x05, 0x26, 0x03, 0x5a, 0x1d, 0x9e, 0xc5, 0x1a, 0xdb, 0xb8, 0x9a, 0x9d, 0xab, 0x05, 0x3a, 0x15, 0x45, 0x20, 0x88, 0xe4, 0xd4, 0x89, 0x3b, 0x2d, 0xf8, 0x91, 0x21, 0x4f, 0xed, 0x30, 0xfd, 0xc7, 0x0c, 0x6b, 0x94, 0xb3, 0xa8, 0x56, 0x9b, 0x05, 0x94, 0x96, 0x4c, 0x06, 0xdf, 0x1b, 0xf6, 0xc8, 0xc8, 0x5c, 0xe6, 0x51, 0x4c, 0x93, 0xf0, 0x92, 0x1b, 0x9f, 0x89, 0xf9, 0xe7, 0x0d, 0xbd, 0x17, 0x8f, 0xc1, 0x27, 0x77, 0x8a, 0xde, 0xb4, 0xb3, 0x2b, 0xe3, 0x6a, 0xcb, 0xe7, 0xf2, 0x42, 0x3f, 0x7c, 0x3d, 0xa6, 0xa5, 0xcf, 0x82, 0x52, 0x99, 0x69, 0xbd, 0xee, 0xf1, 0xbf, 0xcd, 0x64, 0x03, 0x37, 0x64, 0xf3, 0x24, 0x8a, 0x57, 0x49, 0x6c, 0x20, 0xfd, 0x09, 0x69, 0xd8, 0x65, 0x04, 0x7d, 0xbe, 0x35, 0x5a, 0xd3, 0x4b, 0xe2, 0x4e, 0xa7, 0x0c, 0xee, 0x7b, 0xac, 0x7f, 0xb5, 0x02, 0x4f, 0x84, 0x87, 0xf7, 0x17, 0x22, 0xa2, 0x6f, 0x33, 0x94, 0x79, 0xc1, 0xb9, 0xc1, 0x14, 0xd6, 0x7a, 0x11, 0x70, 0xa8, 0xb7, 0x08, 0x3e, 0x7a, 0x36, 0x00, 0x26, 0x9d, 0x82, 0x08, 0x7f, 0x65, 0x81, 0x11, 0x2d, 0xf7, 0x63, 0xa1, 0xf0, 0x2c, 0x66, 0x7e, 0xf3, 0x35, 0xf8, 0x49, 0x5c, 0x17, 0xd0, 0x56, 0xc5, 0xbb, 0x78, 0x1c, 0xe8, 0x77, 0xde, 0xd9, 0x20, 0x82, 0xad, 0xc3, 0x0d, 0x2e, 0x7c, 0xc6, 0x9c, 0x7f, 0x6f, 0xb8, 0xc6, 0x20, 0x6c, 0x93, 0x62, 0x32, 0x1d, 0x1d, 0x79, 0xba, 0xaa, 0x59, 0x44, 0xfb, 0xcd, 0x66, 0xa5, 0x49, 0xae, 0xab, 0x0d, 0xa3, 0xcf, 0x29, 0x8b, 0xb4, 0x3a, 0x90, 0xc0, 0x2e, 0x64, 0x91, 0x78, 0x86, 0xfc, 0x75, 0x81, 0xed, 0xa8, 0x7d, 0x58, 0x65, 0xc4, 0x72, 0xf8, 0x3b, 0x6b, 0xbd, 0xe6, 0x09, 0x3d, 0x63, 0x87, 0x39, 0xbc, 0xf2, 0xbf, 0xe6, 0x75, 0x66, 0x2e, 0x50, 0x06, 0xe5, 0xf7, 0xab, 0x5a, 0xb5, 0x88, 0x91, 0x04, 0x81, 0x7f, 0xb7, 0x7b, 0xfa, 0x37, 0xa6, 0x6b, 0x7d, 0x8e, 0x96, 0x17, 0xcc, 0xf1, 0x9e, 0xb3, 0x5a, 0xd6, 0xf9, 0xa1, 0x70, 0x15, 0x63, 0x22, 0xaf, 0xe2, 0x0f, 0x6d, 0xb3, 0x34, 0x0c, 0x86, 0xb5, 0x48, 0x91, 0x1e, 0x70, 0x63, 0xb3, 0xa6, 0x14, 0x8f, 0xfe, 0x54, 0xaa, 0x5d, 0x26, 0xdb, 0x78, 0x24, 0xc1, 0xfe, 0x2b, 0x83, 0x7e, 0x1f, 0xd1, 0xf5, 0x50, 0x30, 0x1a, 0x3a, 0xf0, 0x3c, 0x58, 0xa5, 0x00, 0x00, 0x01, 0xb7 }; +constexpr AccessUnit M2V_SINGLE_PACK_EXPECTED_AU_1 = { 0x15f90, 0x159b2, true, 0, {}, { 0xcc, 0xde, 0x79, 0xd3, 0x4e, 0x18, 0x1d, 0xe1, 0xd9, 0xb6, 0x96, 0x08, 0x89, 0x4d, 0x21, 0xc9, 0x3c, 0x69, 0xf0, 0x97 } }; +constexpr AccessUnit M2V_SINGLE_PACK_EXPECTED_AU_2 = { std::numeric_limits::max(), std::numeric_limits::max(), false, 0, {}, { 0x62, 0xee, 0x39, 0x77, 0xee, 0xb9, 0x4b, 0xa8, 0x02, 0x81, 0xb1, 0x65, 0x11, 0x6b, 0xa8, 0x40, 0xd8, 0x80, 0xff, 0xf3 } }; + +constexpr std::array ATRACX_SINGLE_PACK_STREAM = { 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xbd, 0x06, 0xe6, 0x81, 0xc1, 0x0d, 0x31, 0x00, 0x05, 0xbf, 0x21, 0x11, 0x00, 0x05, 0xb3, 0x65, 0x1e, 0x69, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xd0, 0x00, 0x00, 0xf9, 0x59, 0xfb, 0xc5, 0x0f, 0xd0, 0x00, 0xd6, 0xa6, 0x43, 0x65, 0x4e, 0x0f, 0xd0, 0x00, 0xd5, 0x0b, 0xf0, 0x8b, 0x9a, 0x6b, 0x02, 0xf9, 0xe8, 0xc3, 0x80, 0x7f, 0x21, 0xad, 0xe3, 0x55, 0xe4, 0x2b, 0xb3, 0x50, 0xad, 0x7d, 0xb8, 0x7b, 0x69, 0xaa, 0x09, 0xf6, 0x6f, 0xb1, 0x31, 0x57, 0x04, 0x1b, 0x22, 0x91, 0x9a, 0xc0, 0x05, 0xe6, 0x27, 0x6a, 0x65, 0xee, 0xac, 0xc9, 0x56, 0xa3, 0x4e, 0xcf, 0xef, 0xcb, 0xff, 0x5a, 0x4d, 0x31, 0xed, 0x72, 0xa4, 0xb0, 0x26, 0x8a, 0x7e, 0xd6, 0x28, 0x8a, 0x51, 0x77, 0x4a, 0x51, 0x9f, 0x38, 0x7a, 0xa5, 0xac, 0x69, 0xcf, 0x7b, 0x22, 0xbb, 0xc1, 0x0d, 0x1b, 0x7b, 0x50, 0x1e, 0x66, 0xce, 0xc0, 0x98, 0x33, 0x4f, 0x04, 0xcb, 0xd3, 0x44, 0x89, 0x54, 0xe4, 0xb9, 0x0d, 0x05, 0x86, 0xfd, 0x21, 0xf1, 0x5f, 0xda, 0xcb, 0x19, 0x74, 0xb9, 0x90, 0xa8, 0x10, 0xe4, 0xf8, 0xbc, 0x9b, 0x04, 0xc1, 0x67, 0x11, 0x6b, 0x13, 0x82, 0xec, 0x62, 0x48, 0x3b, 0x44, 0xa7, 0xf1, 0x45, 0x54, 0x2f, 0x51, 0x77, 0xfc, 0xa5, 0xed, 0xd3, 0x24, 0x2e, 0xf6, 0xfa, 0x8d, 0xff, 0x06, 0x13, 0x66, 0xda, 0x5f, 0x70, 0x4e, 0x3e, 0xcf, 0xe2, 0xd1, 0x03, 0x8e, 0xa2, 0xec, 0x22, 0x50, 0x81, 0x0f, 0xdf, 0x3f, 0x8e, 0x99, 0x0f, 0xb9, 0x5c, 0x05, 0x32, 0xa9, 0x0a, 0x0d, 0xd1, 0xfb, 0xcb, 0xdf, 0x21, 0x13, 0xf1, 0x35, 0xcc, 0x39, 0xb8, 0xb2, 0x09, 0xc7, 0xa8, 0x01, 0x33, 0xb4, 0x0d, 0x15, 0x59, 0x0f, 0xca, 0x36, 0x3c, 0x64, 0xb7, 0x91, 0x35, 0xe9, 0x0d, 0x40, 0x1a, 0xd3, 0xe0, 0xe9, 0x00, 0xd0, 0x9d, 0x98, 0x0b, 0x1a, 0x54, 0xf6, 0x9a, 0x1b, 0x46, 0x66, 0x87, 0xea, 0x21, 0xc6, 0x30, 0xb3, 0x32, 0xaa, 0xd0, 0xb3, 0x4e, 0x70, 0x36, 0xc5, 0xfd, 0xae, 0x35, 0xb1, 0x65, 0x6c, 0xfd, 0xa8, 0xe4, 0xe6, 0x00, 0x7a, 0x51, 0x0d, 0xcf, 0x99, 0x62, 0x16, 0xc6, 0xde, 0x7f, 0x79, 0xc4, 0xe7, 0x0f, 0xed, 0xc5, 0x6e, 0xaa, 0xd2, 0x98, 0xef, 0xb4, 0x34, 0x76, 0x58, 0x1b, 0x74, 0x62, 0xa4, 0x87, 0x3a, 0x37, 0x45, 0x1f, 0x48, 0xc0, 0xe5, 0xb7, 0xd5, 0x15, 0xe7, 0x4b, 0xc6, 0xef, 0x39, 0x19, 0x49, 0x89, 0x85, 0x41, 0xa3, 0xd3, 0x6f, 0x2f, 0xb1, 0x00, 0x8b, 0xa4, 0xf0, 0xcd, 0x40, 0x73, 0xfa, 0xf8, 0x46, 0x95, 0x75, 0xe0, 0xb1, 0x63, 0x74, 0xf1, 0x5c, 0xd7, 0xf0, 0x38, 0x21, 0xc7, 0xad, 0xa4, 0xa6, 0xbd, 0x47, 0x13, 0xc2, 0x6f, 0x2f, 0xbe, 0x87, 0x05, 0x36, 0x3e, 0x00, 0xe7, 0x8d, 0xb7, 0x00, 0xcd, 0xc1, 0xb7, 0xbc, 0x94, 0x5b, 0x45, 0x8f, 0xf3, 0x05, 0x35, 0xa1, 0xc9, 0x84, 0xde, 0x52, 0x5b, 0xc9, 0xe8, 0xc0, 0x60, 0x14, 0x7f, 0x81, 0xe6, 0xb2, 0xdb, 0x5a, 0xd1, 0xfd, 0x38, 0xe8, 0x3d, 0x63, 0x55, 0x00, 0x0c, 0xae, 0xf0, 0x7f, 0xb2, 0x39, 0x9b, 0xff, 0x25, 0x87, 0xc9, 0x2a, 0x94, 0xf3, 0xfc, 0x11, 0xcd, 0x3f, 0x8b, 0x1a, 0xca, 0x14, 0xe5, 0x26, 0x5f, 0xed, 0xc5, 0xe4, 0x4d, 0xb9, 0x20, 0x04, 0x24, 0x0e, 0xeb, 0x2e, 0x8e, 0x0e, 0x9e, 0xa4, 0xea, 0x1a, 0x92, 0xb3, 0x37, 0xe9, 0x08, 0x39, 0x8c, 0xe0, 0x96, 0x3d, 0x4c, 0xa3, 0xb5, 0xd9, 0xb1, 0x24, 0xea, 0x40, 0xeb, 0x99, 0x21, 0x7d, 0x91, 0xc7, 0xae, 0x36, 0x7a, 0x95, 0xd0, 0x79, 0x65, 0xa8, 0x6f, 0xf7, 0x87, 0xf3, 0x99, 0x95, 0xfd, 0xe6, 0x35, 0x1e, 0xf9, 0x8d, 0xd1, 0xdb, 0x3d, 0x46, 0xe0, 0xd4, 0x5c, 0x94, 0x59, 0x86, 0x34, 0x47, 0xae, 0x63, 0xb0, 0x4c, 0xea, 0xa0, 0x99, 0x03, 0x71, 0x2d, 0xd3, 0x92, 0xea, 0x5a, 0x8e, 0x82, 0x06, 0x27, 0xd7, 0xce, 0xc1, 0x3c, 0xbc, 0xa7, 0xb6, 0x5a, 0xfc, 0x5c, 0x58, 0x1e, 0x5a, 0x66, 0x77, 0xae, 0x20, 0xa7, 0x8e, 0xb9, 0x3a, 0x96, 0xef, 0x1f, 0xfc, 0x6c, 0x89, 0x36, 0xae, 0x75, 0xac, 0xff, 0x40, 0xca, 0x95, 0x5d, 0xa0, 0x61, 0x65, 0x33, 0x3a, 0xae, 0x67, 0x0f, 0x2e, 0x12, 0x69, 0x9f, 0x8c, 0x21, 0x2b, 0x6a, 0x74, 0xe2, 0xbc, 0xf3, 0xfc, 0xe9, 0xa5, 0x19, 0xf7, 0xb5, 0x0f, 0x69, 0x0f, 0x5f, 0x06, 0xc2, 0xac, 0x06, 0x2d, 0xea, 0x1a, 0x49, 0x02, 0x01, 0x50, 0xd1, 0xa7, 0xbf, 0x6a, 0xbf, 0x15, 0x21, 0xcf, 0xf1, 0x21, 0xae, 0x1e, 0x25, 0x48, 0x34, 0x30, 0x77, 0x65, 0xca, 0x91, 0x9d, 0xa1, 0xff, 0xb0, 0xd7, 0xdd, 0x9e, 0xd2, 0x8a, 0x7e, 0x8f, 0x95, 0x16, 0xae, 0x1e, 0x37, 0xc4, 0x43, 0x29, 0x35, 0x4d, 0x8f, 0xe0, 0xbe, 0x0a, 0x42, 0x9c, 0x16, 0x32, 0x65, 0x1a, 0x8e, 0xea, 0xb6, 0xda, 0x90, 0xb3, 0x18, 0x5b, 0x26, 0xcb, 0x95, 0xfd, 0xaf, 0x59, 0x4b, 0x74, 0xc7, 0xbe, 0x26, 0xa2, 0x27, 0x85, 0x64, 0xd7, 0x45, 0xe7, 0x90, 0x4f, 0x25, 0xa3, 0x47, 0x5c, 0xbe, 0x24, 0xa8, 0x20, 0xb9, 0xda, 0x42, 0x4e, 0xea, 0x71, 0x02, 0x9e, 0xb0, 0x64, 0x18, 0x38, 0xb0, 0x53, 0x2f, 0x5c, 0x4f, 0x10, 0x91, 0x31, 0x66, 0xa3, 0x51, 0xa0, 0xf4, 0x75, 0x9f, 0x3f, 0xd6, 0xaf, 0x5e, 0x42, 0xde, 0xd1, 0x7d, 0xa8, 0x46, 0x1d, 0xf8, 0xe6, 0xb8, 0x34, 0x50, 0xc7, 0x8d, 0xa5, 0x56, 0x8a, 0xce, 0xec, 0x03, 0xc8, 0xb1, 0xa1, 0x7e, 0xb6, 0x40, 0xf4, 0x0b, 0x6b, 0x17, 0x4d, 0xbe, 0x87, 0x2a, 0xe4, 0xe5, 0xc0, 0x1a, 0x05, 0x40, 0xe8, 0x3b, 0xbe, 0x97, 0x1d, 0xca, 0xee, 0xfb, 0xc7, 0x8f, 0xf5, 0x96, 0xa4, 0xbb, 0xc7, 0x1e, 0x79, 0x5a, 0x95, 0x6f, 0x12, 0x6d, 0x46, 0x37, 0xa5, 0x9a, 0xbb, 0xe4, 0xb6, 0xbe, 0x82, 0xb0, 0x7f, 0xe5, 0x63, 0xa4, 0xbd, 0x73, 0x41, 0x5c, 0xbf, 0xd5, 0x59, 0x44, 0x83, 0x1a, 0x26, 0xf9, 0xaa, 0x03, 0xa0, 0xaf, 0x72, 0xb1, 0x3a, 0x17, 0x01, 0x80, 0xf1, 0xca, 0x4e, 0x18, 0x00, 0x0c, 0x1b, 0xd9, 0xaa, 0xce, 0x2e, 0xe9, 0x89, 0xf0, 0x42, 0x32, 0x19, 0x4f, 0x74, 0x5f, 0x2f, 0x04, 0x6f, 0xe7, 0x8a, 0x03, 0x81, 0x6f, 0x76, 0x74, 0xc0, 0xfc, 0xba, 0x92, 0x73, 0xbe, 0x95, 0xc5, 0x4b, 0x78, 0xcd, 0x30, 0x7a, 0x0f, 0xca, 0x1c, 0x36, 0x85, 0xfb, 0xc7, 0xd9, 0xc4, 0xb0, 0xd5, 0xb9, 0xf4, 0x23, 0x70, 0x6a, 0x9a, 0x27, 0x86, 0x24, 0xa6, 0xb0, 0x96, 0xfb, 0xaa, 0xe7, 0xf0, 0x5d, 0x80, 0xb6, 0x19, 0x80, 0x01, 0xf5, 0x9c, 0x0f, 0x08, 0x49, 0x82, 0x58, 0x59, 0x16, 0x99, 0xbb, 0x78, 0x65, 0xe0, 0x2c, 0x6c, 0x1c, 0xf3, 0xda, 0x67, 0xb9, 0xf3, 0xb1, 0xa2, 0x19, 0x4f, 0x9b, 0x30, 0x2e, 0xc3, 0xc0, 0x01, 0x90, 0x7d, 0x4e, 0x05, 0xda, 0xde, 0x49, 0x40, 0xe5, 0x53, 0xf1, 0x0b, 0x66, 0x3b, 0x7f, 0x5d, 0xda, 0xcd, 0x28, 0x38, 0xfa, 0x44, 0x3f, 0xe6, 0x27, 0x06, 0x58, 0x27, 0x96, 0xaa, 0xe1, 0x1a, 0xe5, 0x1c, 0xc4, 0xa6, 0xc7, 0xbe, 0x27, 0xd3, 0xb8, 0x53, 0xc6, 0x71, 0xd8, 0x44, 0x2f, 0xe9, 0x6d, 0xae, 0xe8, 0x06, 0x62, 0xad, 0xfc, 0x7d, 0x1e, 0xc0, 0x67, 0x8a, 0xb3, 0x18, 0xd6, 0xb5, 0x14, 0xe7, 0xc9, 0x99, 0xeb, 0x3d, 0xab, 0x1c, 0x4f, 0xda, 0x56, 0xde, 0xba, 0x5b, 0xe6, 0xed, 0x58, 0x22, 0x3a, 0xc9, 0x89, 0xef, 0x4e, 0xf1, 0xaa, 0xdf, 0xae, 0x81, 0xbe, 0x34, 0x29, 0x5e, 0x18, 0x90, 0xe9, 0x7c, 0x89, 0xa4, 0xeb, 0x11, 0x33, 0x39, 0x3b, 0x36, 0x18, 0x00, 0x43, 0xac, 0xa3, 0x02, 0xe6, 0xd9, 0x6b, 0x0d, 0xa9, 0xea, 0x31, 0x6f, 0x66, 0xc8, 0xab, 0x3d, 0x9f, 0x11, 0x8a, 0x17, 0x13, 0x43, 0x13, 0xd2, 0xc1, 0x37, 0x90, 0x9f, 0x57, 0xc7, 0x03, 0xcf, 0x05, 0x9c, 0x74, 0x8d, 0xd5, 0xe1, 0xd9, 0x75, 0xe2, 0x12, 0x04, 0x41, 0x30, 0x24, 0x6e, 0x52, 0xf3, 0xf8, 0xbc, 0xa4, 0xba, 0x39, 0x39, 0xff, 0xea, 0x71, 0x78, 0x9f, 0x38, 0xbe, 0xbd, 0xcd, 0x74, 0xc5, 0x56, 0xb8, 0x35, 0x5c, 0xf5, 0x01, 0x9e, 0xbf, 0x8a, 0xc4, 0x2c, 0x3c, 0x7c, 0xb5, 0x78, 0x36, 0x27, 0xc3, 0x19, 0xb8, 0x37, 0x6e, 0xa2, 0x02, 0xc0, 0x1f, 0x09, 0x6c, 0x2e, 0xf6, 0xcc, 0xcf, 0x05, 0xbf, 0xdb, 0xa3, 0x23, 0xe4, 0x6f, 0xb2, 0x33, 0xd8, 0xc5, 0xa1, 0x83, 0x04, 0x15, 0x45, 0xcc, 0xf9, 0xc5, 0xba, 0x98, 0xc5, 0x82, 0xf5, 0xda, 0x08, 0x64, 0xf0, 0xb9, 0x54, 0x5f, 0x34, 0x2c, 0x23, 0x57, 0x22, 0x81, 0xf5, 0xb7, 0x01, 0xdb, 0x41, 0x29, 0x78, 0xbb, 0x93, 0xe7, 0x08, 0x85, 0x86, 0x84, 0xf1, 0x6d, 0x9e, 0xc4, 0x91, 0x18, 0x74, 0xd8, 0xd3, 0x5f, 0xb5, 0x33, 0x56, 0x76, 0xc1, 0xd2, 0x39, 0x83, 0x29, 0x44, 0xf8, 0x1d, 0xf6, 0xd0, 0xd2, 0x4b, 0x50, 0x01, 0xc0, 0xf4, 0xa2, 0xac, 0x1a, 0x04, 0x77, 0xce, 0xf1, 0x3e, 0x53, 0xea, 0xe0, 0xfb, 0xc8, 0xe6, 0xe0, 0xda, 0x23, 0xa9, 0xcc, 0x88, 0x50, 0x95, 0x5c, 0x0f, 0x48, 0x31, 0x4d, 0x6a, 0x46, 0xc8, 0xad, 0xa3, 0xbe, 0xb0, 0x8a, 0x70, 0x3e, 0x4a, 0x79, 0x77, 0x07, 0xb1, 0xfc, 0x8f, 0xdd, 0x2d, 0x2e, 0x1d, 0x10, 0x33, 0xcf, 0x62, 0x35, 0x55, 0x12, 0x40, 0x50, 0x24, 0xc2, 0x0f, 0xb6, 0x59, 0x88, 0x1e, 0x87, 0xbf, 0x77, 0x1c, 0x78, 0x77, 0x7e, 0xad, 0x8d, 0x43, 0xf4, 0xe4, 0xe4, 0x00, 0x7a, 0x71, 0xff, 0x3b, 0x3f, 0x3e, 0x17, 0x4f, 0x19, 0xa1, 0x4d, 0x6f, 0xa8, 0xec, 0x30, 0x87, 0xd7, 0xff, 0x46, 0x9d, 0x4d, 0x2e, 0xa8, 0x61, 0x45, 0x06, 0x51, 0xd0, 0x7b, 0x2e, 0xbe, 0x5e, 0x7d, 0x45, 0x3e, 0x95, 0x52, 0xff, 0x64, 0xb6, 0x28, 0x7e, 0x2a, 0x7b, 0x33, 0xb4, 0x80, 0x17, 0x57, 0xc6, 0x80, 0xde, 0xfc, 0x3f, 0x25, 0xe4, 0x35, 0x85, 0xd1, 0xce, 0xa1, 0x2a, 0xd7, 0x6e, 0x83, 0x6c, 0x61, 0x5d, 0xa8, 0xaf, 0xa0, 0x1e, 0x15, 0x51, 0x57, 0x93, 0xd0, 0x51, 0x21, 0x68, 0x79, 0x99, 0x25, 0xbe, 0x51, 0xc2, 0xf4, 0x72, 0x5c, 0x05, 0x60, 0x05, 0x81, 0xff, 0x20, 0x81, 0x28, 0xb7, 0x38, 0xb4, 0xb2, 0x1a, 0xdd, 0xe9, 0xab, 0xc7, 0x29, 0x4f, 0x24, 0xef, 0x99, 0xae, 0x0c, 0xcc, 0xe7, 0x24, 0xca, 0xa8, 0x71, 0x15, 0xef, 0x58, 0xb2, 0x58, 0x4b, 0xbe, 0x64, 0xbe, 0x68, 0xcc, 0x9f, 0xbf, 0x31, 0xa5, 0x0c, 0x44, 0x71, 0xec, 0x47, 0xa0, 0xda, 0xa5, 0xde, 0x54, 0x19, 0x30, 0xa9, 0x1c, 0x19, 0xbc, 0x18, 0x65, 0x71, 0x70, 0xbc, 0x53, 0x95, 0xe3, 0x44, 0x3f, 0x02, 0x24, 0x15, 0xc9, 0xe0, 0x7e, 0xb2, 0x29, 0xc9, 0x8b, 0x73, 0x28, 0xab, 0xc5, 0xde, 0x37, 0x0f, 0x44, 0x0d, 0x3e, 0x80, 0x52, 0x44, 0xe2, 0xe2, 0x0d, 0xe2, 0x6e, 0xd5, 0xc6, 0xa0, 0xb5, 0xe9, 0x70, 0x0d, 0xcc, 0x52, 0x1f, 0xc3, 0xaa, 0x64, 0x0e, 0xbe, 0x83, 0x0e, 0xfe, 0xb6, 0xee, 0xe0, 0xee, 0xb9, 0x50, 0x47, 0xe3, 0xa1, 0x8d, 0xff, 0x33, 0x8c, 0x6b, 0x45, 0xfb, 0xa0, 0x2c, 0xb6, 0xae, 0xf3, 0x93, 0xb3, 0xca, 0x27, 0xf2, 0x43, 0x83, 0x15, 0x26, 0xa5, 0xe8, 0x48, 0xc4, 0x91, 0x43, 0x42, 0xa2, 0x59, 0x38, 0xff, 0x55, 0x08, 0x0c, 0xf2, 0x22, 0x56, 0x25, 0xda, 0xf9, 0x33, 0xa9, 0xff, 0x0a, 0xbb, 0x83, 0x68, 0xee, 0xc1, 0xa0, 0xde, 0x2d, 0x75, 0x67, 0x3d, 0xa2, 0x4a, 0xef, 0xf5, 0x05, 0x62, 0x6a, 0x5e, 0x3c, 0x26, 0x86, 0xb6, 0xed, 0x22, 0xea, 0x96, 0xbb, 0x91, 0xa7, 0xee, 0x20, 0x77, 0x3a, 0x59, 0x97, 0x31, 0x47, 0x07, 0xad, 0xcd, 0xe3, 0x96, 0x27, 0x43, 0xab, 0xc2, 0xa4, 0xb7, 0x69, 0xef, 0x25, 0xb1, 0x97, 0xa4, 0x79, 0x17, 0x81, 0xbd, 0x68, 0xb5, 0x97, 0x60, 0x66, 0xb1, 0x97, 0x2b, 0x7a, 0x50, 0xf3, 0xc2, 0x10, 0xec, 0xd4, 0xf1, 0x38, 0x1c, 0xdf, 0xa0, 0x08, 0xb8, 0xb8, 0x9f, 0x46, 0x0e, 0x57, 0x53, 0x34, 0xf8, 0x14, 0xa5, 0xdc, 0x69, 0xef, 0x96, 0xe3, 0x54, 0xcf, 0x13, 0xcb, 0x02, 0xb7, 0x24, 0x77, 0xb5, 0xd6, 0xc0, 0x74, 0x65, 0x65, 0xb4, 0x97, 0x0d, 0x15, 0x2e, 0xa9, 0xc7, 0x24, 0x22, 0x13, 0xf7, 0x50, 0x5f, 0xf5, 0xb1, 0x79, 0xce, 0xf6, 0x15, 0xcf, 0x47, 0x1c, 0x4c, 0x40, 0x61, 0x84, 0x74, 0x23, 0x6e, 0xae, 0xaa, 0x00, 0x3a, 0x34, 0x26, 0x8e, 0x92, 0xa2, 0x55, 0xae, 0x89, 0xc1, 0xbc, 0xb9, 0x13, 0xe1, 0x22, 0x8b, 0x52, 0x62, 0x45, 0xa1, 0x01, 0x4f, 0x97, 0x4e, 0xc7, 0xc3, 0xfd, 0xc9, 0x9e, 0x92, 0x67, 0xbb, 0x21, 0x31, 0x5d, 0x10, 0xbc, 0x3a, 0x27, 0xe8, 0x55, 0x48, 0x46, 0x21, 0x56, 0x8a, 0x0f, 0xd0, 0x62, 0x9a, 0xe1, 0xd0, 0xe1, 0x77, 0x53, 0x0b }; +constexpr AccessUnit ATRACX_SINGLE_PACK_EXPECTED_AU_1 = { 0x15f90, 0x159b2, false, 0, {}, { 0xca, 0x9d, 0x63, 0xb7, 0xda, 0xcd, 0xd6, 0xb1, 0xa0, 0x27, 0xf2, 0x61, 0xc1, 0x56, 0x3e, 0x3e, 0xb1, 0x1c, 0x5e, 0x76 } }; +constexpr AccessUnit ATRACX_SINGLE_PACK_EXPECTED_AU_2 = { std::numeric_limits::max(), std::numeric_limits::max(), false, 0, {}, { 0xeb, 0x30, 0x7d, 0xad, 0x5f, 0xcb, 0xc1, 0x17, 0xc1, 0x10, 0x19, 0xef, 0xd5, 0xd3, 0xaa, 0x72, 0x6f, 0xd2, 0x5d, 0x5b } }; + +constexpr std::array AC3_SINGLE_PACK_STREAM = { 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xbd, 0x06, 0xe6, 0x81, 0xc1, 0x0d, 0x31, 0x00, 0x05, 0xbf, 0x21, 0x11, 0x00, 0x05, 0xb3, 0x65, 0x1e, 0x69, 0xb2, 0x30, 0x00, 0x00, 0x00, 0x0b, 0x77, 0x59, 0x66, 0x00, 0x87, 0x05, 0xf4, 0xa8, 0x09, 0x93, 0x66, 0x9e, 0xcf, 0x4e, 0x3e, 0x1e, 0xc6, 0x10, 0x6b, 0xaa, 0x2b, 0x3d, 0x5c, 0xec, 0x4b, 0x2e, 0xd1, 0x47, 0x6f, 0x9c, 0x77, 0x35, 0x7a, 0x6a, 0xcf, 0x95, 0x42, 0x66, 0xca, 0x6c, 0x31, 0xae, 0x53, 0xc3, 0x84, 0xf1, 0x00, 0x1a, 0x5a, 0x11, 0xb4, 0xd0, 0x32, 0x15, 0xaa, 0x97, 0x7e, 0xb8, 0x2f, 0xc6, 0x5e, 0x79, 0xd8, 0xf5, 0x85, 0x8b, 0x2a, 0x4b, 0x8c, 0xfd, 0x0b, 0xb0, 0x5a, 0x05, 0x0b, 0x77, 0x76, 0xd7, 0x69, 0x3c, 0xf2, 0xad, 0x10, 0x4f, 0xc7, 0x20, 0x30, 0x68, 0xb3, 0x72, 0x47, 0x58, 0x13, 0xcb, 0x17, 0x94, 0xe0, 0x13, 0xd8, 0xa2, 0xf7, 0xf2, 0x71, 0xbe, 0xdc, 0x9f, 0x15, 0x23, 0xfd, 0x98, 0x1c, 0x5b, 0x79, 0xca, 0xe0, 0x6f, 0x8e, 0xa2, 0x7a, 0xce, 0xa6, 0xc5, 0x41, 0xd5, 0x30, 0x83, 0x22, 0x0b, 0x77, 0x99, 0x0a, 0x99, 0x5c, 0xaa, 0xc6, 0x49, 0x3c, 0x95, 0x33, 0x0a, 0x9f, 0x5c, 0x73, 0xfb, 0x0e, 0xa9, 0xaf, 0x4e, 0x0d, 0xec, 0xfc, 0xbb, 0x0f, 0x61, 0x9a, 0x9f, 0xa0, 0x5b, 0x14, 0x88, 0x6b, 0x76, 0x43, 0x7a, 0x0d, 0x2d, 0x1b, 0x6d, 0xea, 0x84, 0x13, 0x0f, 0xe2, 0x89, 0xb3, 0xef, 0xe2, 0xe7, 0x2b, 0xbd, 0xde, 0x20, 0x07, 0x61, 0x99, 0xbd, 0x24, 0x94, 0xd5, 0x0c, 0xa8, 0x69, 0x99, 0xb9, 0xf3, 0x7d, 0x9c, 0x5b, 0xbd, 0x76, 0x6f, 0x1f, 0x8b, 0x61, 0x20, 0x83, 0x53, 0xb0, 0xd5, 0x86, 0xd9, 0xd9, 0xcf, 0x49, 0x4a, 0x3a, 0xd6, 0x51, 0xf6, 0x09, 0x4a, 0x09, 0x1b, 0xc5, 0xce, 0xbf, 0x35, 0xfa, 0x93, 0x75, 0x5f, 0x7c, 0x04, 0xc3, 0xd2, 0x17, 0xd8, 0x76, 0x0d, 0xc0, 0x86, 0xc3, 0x7e, 0xfc, 0x7c, 0x2a, 0xe3, 0xc9, 0x13, 0x74, 0xec, 0x5b, 0x8d, 0x9b, 0x45, 0x6b, 0x12, 0xa5, 0x1f, 0xeb, 0xf5, 0x75, 0x24, 0x22, 0xa8, 0xbf, 0xc6, 0xb8, 0x35, 0xe5, 0x95, 0x69, 0xaf, 0xfc, 0xc1, 0xe6, 0x49, 0x01, 0x0d, 0x4b, 0xc8, 0xf0, 0x02, 0x9e, 0x4a, 0xb2, 0x43, 0xb4, 0x4f, 0xb2, 0xd6, 0x6a, 0x38, 0xfe, 0xe8, 0x80, 0x6e, 0x73, 0x51, 0x2f, 0xd4, 0x9e, 0x56, 0xd8, 0xa0, 0x40, 0x9b, 0x65, 0xb5, 0xc2, 0x04, 0x86, 0x15, 0x92, 0xe0, 0x7a, 0x26, 0x0c, 0xc9, 0x6a, 0x27, 0xd9, 0xfc, 0x4e, 0x50, 0xc5, 0xac, 0xe5, 0x45, 0xec, 0x2a, 0x13, 0x95, 0xaf, 0xf3, 0x81, 0xe1, 0x5b, 0xc7, 0x87, 0x50, 0x67, 0xdb, 0xc2, 0x79, 0xd5, 0x2e, 0xdd, 0x42, 0x51, 0x3b, 0x14, 0x1d, 0x83, 0x3c, 0x25, 0x4b, 0xe7, 0x77, 0x48, 0xa8, 0xed, 0x1d, 0x55, 0x75, 0xf1, 0x65, 0xca, 0x6d, 0x5a, 0x13, 0x7c, 0x9b, 0xdb, 0x95, 0x7d, 0xf3, 0x42, 0xcf, 0x49, 0x17, 0xe5, 0x07, 0xbb, 0x7d, 0xf0, 0x6f, 0x9d, 0xcb, 0x9e, 0x07, 0x11, 0x5a, 0x51, 0x9b, 0x80, 0x5e, 0x77, 0xc6, 0x3c, 0xa8, 0xa5, 0x22, 0xa8, 0xb2, 0x83, 0x97, 0x8a, 0xdf, 0x75, 0x49, 0x43, 0x59, 0x5d, 0x5c, 0x32, 0x14, 0x6c, 0xc3, 0xb4, 0xf5, 0x25, 0xe7, 0xdf, 0xb0, 0xb3, 0xc6, 0xb7, 0x1f, 0x3f, 0x7c, 0xfd, 0xe4, 0xf5, 0x0c, 0xbe, 0x92, 0xcb, 0xb6, 0x72, 0xa0, 0x8a, 0x9f, 0x3b, 0xfd, 0x76, 0x5d, 0xb2, 0xdf, 0xee, 0x21, 0x19, 0xd4, 0x5a, 0x05, 0x6a, 0xb9, 0x9f, 0xdb, 0x9c, 0xe1, 0xc0, 0xd4, 0x14, 0xb4, 0x5e, 0x4d, 0x2e, 0x3d, 0xca, 0x73, 0xc6, 0x01, 0xd6, 0x73, 0x01, 0x24, 0xef, 0x2b, 0x6c, 0xfc, 0xa0, 0xea, 0xb4, 0x54, 0x57, 0x70, 0xfb, 0x31, 0x0d, 0xc9, 0xcb, 0xef, 0x49, 0x64, 0x2e, 0x9b, 0xea, 0x6d, 0x68, 0x09, 0x5c, 0x86, 0xb8, 0xc5, 0x03, 0xd5, 0x34, 0x62, 0x9f, 0xf7, 0x38, 0x0d, 0x2b, 0x9f, 0x54, 0x90, 0x14, 0x48, 0xd9, 0xaf, 0xa7, 0x9e, 0x20, 0x4e, 0x4a, 0x68, 0x60, 0x95, 0x7b, 0x53, 0x96, 0x9e, 0x05, 0x70, 0x7c, 0xbc, 0xe8, 0x95, 0xfd, 0xa7, 0x16, 0x1e, 0x98, 0x5d, 0x45, 0xda, 0x3b, 0x93, 0x21, 0xc3, 0xc3, 0x22, 0xe6, 0x55, 0x99, 0xcb, 0x9a, 0x57, 0xcf, 0x34, 0x5d, 0x52, 0xf8, 0xce, 0x28, 0xe6, 0xcf, 0xac, 0x4e, 0x34, 0x82, 0x81, 0x1f, 0x99, 0x63, 0xcc, 0xcc, 0x07, 0x5d, 0xcc, 0x7e, 0x7b, 0x33, 0x5e, 0xba, 0x7d, 0xc3, 0xa7, 0xc7, 0x4b, 0x23, 0xb4, 0x64, 0x80, 0x6e, 0x5b, 0x79, 0x0d, 0xc0, 0x54, 0x03, 0x96, 0x5d, 0x63, 0xe7, 0x4b, 0xd9, 0x86, 0x65, 0xcf, 0xfb, 0x3e, 0x29, 0xdf, 0x3c, 0xd4, 0xcf, 0xdd, 0x96, 0x4a, 0x27, 0x73, 0x69, 0xd2, 0x40, 0xb6, 0xb7, 0xa5, 0xe0, 0x56, 0x37, 0x1f, 0xc2, 0x95, 0xe2, 0xb8, 0x4d, 0x42, 0x22, 0xc1, 0xbd, 0xd2, 0x57, 0x11, 0x27, 0x49, 0x6a, 0x88, 0x3d, 0x8e, 0x09, 0x87, 0x87, 0xd0, 0xf2, 0xf6, 0x05, 0xac, 0x47, 0xab, 0xf7, 0x5c, 0xa0, 0xa1, 0xb0, 0x0a, 0x74, 0x01, 0xd5, 0xeb, 0x04, 0xa6, 0x53, 0x2e, 0x8f, 0xc3, 0x68, 0xe1, 0x0a, 0x59, 0xcb, 0xee, 0xf3, 0xde, 0x94, 0x35, 0xe8, 0x78, 0x44, 0x73, 0x87, 0x0b, 0xe2, 0x87, 0xa3, 0xd1, 0xa2, 0x87, 0x8d, 0x64, 0x3a, 0x53, 0xd8, 0x09, 0xba, 0xae, 0x04, 0x7e, 0x07, 0xc2, 0x07, 0x98, 0xc0, 0x87, 0x56, 0x12, 0x86, 0x14, 0xdb, 0x4c, 0xc4, 0xed, 0x84, 0xad, 0xca, 0xf3, 0x2e, 0x1a, 0x28, 0x64, 0x76, 0x0c, 0x4c, 0x27, 0x9d, 0xab, 0x12, 0x7d, 0xb3, 0xfa, 0xed, 0x5c, 0xf0, 0x77, 0xdc, 0xf3, 0x45, 0x5d, 0x31, 0x27, 0x5f, 0x4c, 0xe2, 0x96, 0x98, 0x25, 0xab, 0xcd, 0x3d, 0x22, 0x64, 0xc6, 0x00, 0x47, 0xbd, 0xb8, 0xde, 0x65, 0xdb, 0x54, 0xd5, 0xc6, 0x62, 0x1b, 0x45, 0x6b, 0xd8, 0x9d, 0x00, 0xb7, 0xe3, 0xfc, 0x84, 0x03, 0xf0, 0x6c, 0xf8, 0x23, 0x14, 0xf6, 0x92, 0x73, 0xc6, 0x42, 0xcc, 0x67, 0xd3, 0x3e, 0xaa, 0xc4, 0x3d, 0x81, 0x13, 0xfb, 0x13, 0x22, 0xd3, 0x9b, 0xc8, 0xf5, 0x0b, 0x78, 0x47, 0x9b, 0x83, 0xb5, 0xd7, 0x98, 0xe9, 0x3f, 0x7c, 0x8f, 0x42, 0xa3, 0xef, 0x1f, 0x94, 0x99, 0x75, 0x21, 0x95, 0xd1, 0xcf, 0x74, 0xfd, 0x5f, 0x80, 0xec, 0x40, 0x22, 0x28, 0x92, 0x9e, 0x65, 0x73, 0x8b, 0xc5, 0x30, 0xe5, 0xb0, 0xb6, 0xf2, 0x03, 0x24, 0x00, 0x2e, 0x6a, 0xa3, 0x74, 0x62, 0xad, 0xbe, 0x11, 0x80, 0x61, 0xcf, 0x23, 0x3f, 0xd8, 0x0a, 0xf0, 0x2d, 0x4a, 0x58, 0x49, 0xf4, 0x63, 0xf3, 0x05, 0x9b, 0x78, 0xc7, 0xf7, 0xb7, 0x31, 0x02, 0x16, 0x63, 0x87, 0x08, 0x3b, 0x7b, 0x7b, 0xd1, 0xb1, 0xb8, 0x99, 0x39, 0xfe, 0x71, 0x49, 0xac, 0xb7, 0x79, 0x84, 0x47, 0x15, 0x74, 0x5e, 0x29, 0x01, 0xb7, 0x93, 0x9a, 0x87, 0xbd, 0x1a, 0x59, 0xff, 0xec, 0xe5, 0xb8, 0xb9, 0x30, 0x8c, 0x29, 0xd6, 0x0d, 0x32, 0x22, 0x28, 0xd4, 0x4d, 0x25, 0x06, 0x9f, 0x6a, 0xf7, 0x92, 0x16, 0x4b, 0xb6, 0x17, 0xbc, 0xa7, 0xca, 0x17, 0xa6, 0x76, 0x48, 0x46, 0x51, 0xd9, 0xed, 0xc1, 0x69, 0x60, 0xf4, 0x00, 0x64, 0x17, 0x5c, 0x76, 0x18, 0xc4, 0xd1, 0x74, 0x06, 0x67, 0x34, 0xa5, 0xd4, 0x77, 0x1c, 0x62, 0x6d, 0xbb, 0x76, 0x5d, 0x49, 0x5b, 0x08, 0x60, 0x5a, 0x29, 0x4c, 0xec, 0x92, 0x99, 0x55, 0xc0, 0xcc, 0x64, 0xdc, 0x4c, 0x22, 0x37, 0x3d, 0xdb, 0x3b, 0xb0, 0x3f, 0x19, 0x95, 0x6a, 0x04, 0x47, 0x09, 0xf4, 0xd7, 0xe4, 0xf7, 0x28, 0x4f, 0xef, 0xf7, 0x30, 0x37, 0x28, 0xa6, 0xdc, 0x82, 0xfe, 0x2c, 0x7c, 0x67, 0xf8, 0x73, 0x0a, 0x0d, 0x5c, 0xaa, 0x4e, 0x09, 0x0b, 0x47, 0x45, 0x07, 0x44, 0x49, 0x21, 0xe8, 0x12, 0xd1, 0x3e, 0x29, 0x6d, 0xe5, 0x2f, 0xe6, 0x52, 0xd6, 0xa2, 0x76, 0x0f, 0x8c, 0xbb, 0x87, 0xd4, 0x72, 0x49, 0xba, 0xa4, 0x1b, 0x9b, 0x52, 0xe2, 0xa0, 0x82, 0x72, 0x8d, 0x4a, 0x25, 0xf2, 0xe5, 0xb7, 0x59, 0xff, 0x47, 0x69, 0xb5, 0x26, 0x8b, 0x35, 0x76, 0xd7, 0xd3, 0xf4, 0xab, 0x8d, 0x4b, 0x5b, 0x3d, 0xda, 0xec, 0xb6, 0xb8, 0x9c, 0x4a, 0xd1, 0x2d, 0x9d, 0x0c, 0x39, 0x89, 0x58, 0xa6, 0x37, 0x96, 0x2e, 0x7e, 0x21, 0xe4, 0x05, 0xad, 0xdd, 0xf7, 0x5c, 0xf0, 0x7d, 0x79, 0x0a, 0x66, 0x11, 0xcf, 0x46, 0x8a, 0x28, 0xbc, 0x62, 0xbe, 0x4b, 0xf4, 0xb3, 0x4f, 0xba, 0x9c, 0xf7, 0xc2, 0xc4, 0xa0, 0xb3, 0x0e, 0x5c, 0x30, 0x25, 0x3e, 0x94, 0x03, 0x73, 0x81, 0x98, 0xfa, 0x2e, 0xa6, 0xad, 0x6b, 0xf5, 0x6a, 0x08, 0xf9, 0x75, 0xde, 0xb4, 0xdc, 0xf9, 0xad, 0xb2, 0x31, 0xe5, 0x9f, 0xba, 0x86, 0xb6, 0x59, 0x4e, 0xae, 0xcf, 0xf9, 0xef, 0xf9, 0x16, 0xc3, 0x5f, 0xce, 0x90, 0xbe, 0xce, 0xd0, 0xf3, 0x49, 0x1f, 0x44, 0xae, 0xce, 0x5d, 0x8e, 0xcd, 0x12, 0x07, 0x19, 0xf9, 0x0a, 0x3e, 0x29, 0xbb, 0x97, 0x8d, 0x56, 0x48, 0x69, 0x62, 0xf7, 0x68, 0xe8, 0xbc, 0x41, 0x90, 0xd6, 0x26, 0x26, 0xa5, 0x0d, 0xd9, 0x4c, 0x52, 0x0c, 0x4f, 0x20, 0xc7, 0x6e, 0x62, 0xfd, 0x91, 0xc2, 0x57, 0xef, 0x8e, 0x43, 0xc1, 0x48, 0x82, 0x73, 0x16, 0xed, 0x1e, 0x10, 0x66, 0x49, 0xda, 0xaf, 0x83, 0xc1, 0x48, 0xb4, 0x41, 0xd5, 0xa5, 0x9e, 0xa1, 0x44, 0x41, 0x75, 0x5c, 0x50, 0xd0, 0x7a, 0x5a, 0x0d, 0xd2, 0x32, 0xe8, 0x0c, 0x88, 0x4c, 0xb8, 0x72, 0x07, 0xbf, 0xe2, 0x85, 0xef, 0xb4, 0x20, 0xb5, 0x24, 0x00, 0x9d, 0x23, 0xca, 0x6e, 0x53, 0xf8, 0x62, 0xe4, 0x21, 0xbe, 0x79, 0x21, 0x8e, 0x5d, 0xde, 0x91, 0x0b, 0x8a, 0xcd, 0x0c, 0x89, 0xa0, 0x5b, 0xd5, 0xbe, 0x91, 0xdb, 0xa1, 0x71, 0x79, 0xfb, 0xbf, 0xc8, 0x22, 0x19, 0x7e, 0x66, 0x13, 0x9c, 0x94, 0xf2, 0xbc, 0xc1, 0x1a, 0x8a, 0xf6, 0xc2, 0x62, 0xcd, 0x11, 0xda, 0xc0, 0xa5, 0x34, 0x6c, 0x0c, 0x24, 0x60, 0xda, 0x5c, 0x71, 0x0d, 0x77, 0xbc, 0x0e, 0x59, 0xb7, 0xea, 0xa7, 0x81, 0x32, 0x27, 0xf8, 0x9c, 0xdf, 0x75, 0x41, 0x59, 0xdf, 0xb2, 0x56, 0x13, 0x93, 0x22, 0x2c, 0x30, 0x27, 0xc6, 0xa3, 0x29, 0x34, 0x17, 0xf1, 0xe3, 0xc1, 0xa0, 0x38, 0x53, 0x0c, 0xe5, 0x2e, 0xaf, 0x4e, 0x8f, 0xca, 0x9b, 0x9c, 0xe1, 0xc6, 0x6f, 0x9e, 0x8c, 0x91, 0xa2, 0xc9, 0x39, 0xa9, 0x20, 0xd3, 0x61, 0x4e, 0x7c, 0x33, 0xc8, 0x6f, 0x13, 0xbd, 0x74, 0xdd, 0xcd, 0xca, 0xa7, 0x0b, 0x00, 0x74, 0xa2, 0xbe, 0x55, 0x6e, 0xe8, 0x72, 0x57, 0x9c, 0x30, 0x19, 0xe0, 0x4a, 0xb2, 0xa3, 0xdd, 0xb9, 0xb9, 0x6a, 0x30, 0xea, 0xc3, 0xd4, 0xb8, 0x8b, 0x32, 0xdf, 0x5c, 0x04, 0x8c, 0x82, 0x0a, 0x19, 0x9a, 0x78, 0xa9, 0xd2, 0xc2, 0x3c, 0xaf, 0xcd, 0x5d, 0xc7, 0x9a, 0x9f, 0x51, 0x8b, 0x72, 0xee, 0x26, 0xe7, 0xba, 0x24, 0xfb, 0xef, 0xf2, 0x9f, 0x73, 0x51, 0xb3, 0x6a, 0xe6, 0x1f, 0x26, 0xa6, 0x93, 0xde, 0xe3, 0xaf, 0x06, 0x96, 0x25, 0x61, 0x98, 0x9d, 0xc8, 0x0e, 0x5b, 0xb3, 0x3f, 0x60, 0xb3, 0xdf, 0xe2, 0xfb, 0xd7, 0x11, 0x52, 0x40, 0xdd, 0x90, 0x93, 0xbd, 0xbf, 0xd5, 0x76, 0x40, 0x27, 0xb2, 0xe7, 0xe8, 0x16, 0xfa, 0x89, 0xca, 0xdf, 0xfa, 0xbd, 0x5a, 0x38, 0xba, 0x58, 0x5a, 0xd8, 0xc4, 0xd5, 0x53, 0x2c, 0x5a, 0x2d, 0x65, 0xe7, 0xce, 0x8d, 0xe1, 0x9b, 0x29, 0x2f, 0xa4, 0x70, 0xa2, 0x3c, 0xa3, 0x69, 0x89, 0x11, 0x01, 0x90, 0x6f, 0xa2, 0x3d, 0x0e, 0xac, 0xeb, 0x6e, 0x2a, 0x5e, 0x19, 0x28, 0x21, 0x95, 0xa1, 0xf1, 0x63, 0x16, 0x68, 0x5a, 0x2f, 0xf0, 0xc4, 0xe2, 0xca, 0xc8, 0xe3, 0xee, 0xcd, 0x23, 0x19, 0xf9, 0x38, 0x90, 0x6f, 0x8c, 0x23, 0x8f, 0x71, 0x8b, 0x3e, 0xa9, 0xee, 0x0e, 0x37, 0xca, 0xbb, 0x44, 0x06, 0xbe, 0x07, 0x81, 0xd0, 0x22, 0x1f, 0x3c, 0x20, 0x02, 0x34, 0x16, 0xd8, 0x28, 0x99, 0x46, 0x3f, 0x0a, 0xbe, 0x24, 0x30, 0xb3, 0xba, 0x8b, 0xfa, 0x11, 0xed, 0x47, 0xe2, 0xf5, 0x36, 0x27, 0x7d, 0x9b, 0x36, 0xb3, 0x33, 0x62, 0x1c, 0x4d, 0xd4, 0x38, 0x30, 0x0b, 0xb4, 0x92, 0xe4, 0x1e, 0xf4, 0xd2, 0x17, 0x3d, 0x36, 0xba, 0x28, 0x39, 0x0b, 0x77, 0x93, 0xb8, 0x91, 0x4f, 0x44, 0xb3, 0x3d, 0xef, 0x72, 0xdc, 0x39, 0xd3, 0x90, 0x9a, 0x27, 0xcd, 0xdb, 0x47, 0xde, 0xe0, 0x5e, 0x14, 0x76, 0x81, 0x09, 0xd6, 0x00, 0x37, 0xb8, 0x97, 0x1b, 0xc1, 0x0f, 0xbe, 0x0d, 0xcd, 0xe6, 0x33, 0x3a, 0x52, 0xe9, 0x40, 0x8e, 0x18, 0xfa, 0xbe, 0xd6, 0xd7, 0x6a, 0xa9, 0x49, 0xbd, 0x49, 0xe9, 0x0d, 0x57, 0xee, 0xb0, 0x31, 0xa1, 0x18, 0xbb, 0xb8, 0x4f, 0x31, 0xc5, 0x63, 0xa5, 0x74, 0xb4, 0x26, 0x67, 0x67, 0x70, 0x66, 0x39, 0x2b, 0x96, 0xde, 0x26 }; +constexpr AccessUnit AC3_SINGLE_PACK_EXPECTED_AU_1 = { 0x15f90, 0x159b2, false, 0, {}, { 0xe4, 0x34, 0x28, 0xe9, 0x7e, 0x1b, 0xa0, 0xea, 0x42, 0x2c, 0xd7, 0x21, 0x26, 0x44, 0x70, 0x9f, 0x0e, 0x3d, 0x4f, 0x23 } }; +constexpr AccessUnit AC3_SINGLE_PACK_EXPECTED_AU_2 = { std::numeric_limits::max(), std::numeric_limits::max(), false, 0, {}, { 0xf9, 0x27, 0xd1, 0x79, 0x4b, 0x94, 0xd7, 0x63, 0x4c, 0x57, 0x74, 0x46, 0xa3, 0xc2, 0x9d, 0xf0, 0x99, 0x18, 0x78, 0x3c } }; + +constexpr std::array LPCM_SINGLE_PACK_STREAM = { 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xbd, 0x06, 0xe6, 0x81, 0xc1, 0x0d, 0x31, 0x00, 0x05, 0xbf, 0x21, 0x11, 0x00, 0x05, 0xb3, 0x65, 0x1e, 0x69, 0xb2, 0x40, 0xb1, 0x40, 0x00, 0xda, 0x2c, 0xae, 0xd8, 0xf8, 0x31, 0x4d, 0x58, 0x96, 0x3f, 0x03, 0x7e, 0x2e, 0x5d, 0xb9, 0x16, 0xf9, 0x14, 0x26, 0x07, 0x3f, 0x85, 0xc1, 0x78, 0xcb, 0xf1, 0x73, 0xc1, 0xd6, 0xc2, 0x80, 0x8d, 0xaf, 0xa9, 0x76, 0xb1, 0xb2, 0x83, 0xcf, 0xce, 0x89, 0x25, 0xe4, 0x78, 0xe7, 0x06, 0x10, 0x18, 0xdd, 0x52, 0xf6, 0x17, 0x36, 0xe0, 0xba, 0x91, 0xc5, 0x0b, 0x07, 0xca, 0x35, 0x6b, 0xe0, 0x1c, 0xbf, 0xdf, 0x36, 0xfb, 0xca, 0x06, 0x73, 0x67, 0x8d, 0xcf, 0xb0, 0xf8, 0x8d, 0x34, 0xef, 0x73, 0x07, 0x1b, 0x74, 0x31, 0x13, 0xf4, 0x5a, 0x45, 0x77, 0xf9, 0xc2, 0x7e, 0x0c, 0x9b, 0xb1, 0x3a, 0xf9, 0x48, 0xbb, 0x8e, 0xda, 0xc6, 0x9f, 0x68, 0xfd, 0x4a, 0x39, 0xcd, 0x81, 0xa1, 0x4e, 0xcc, 0x6e, 0x2a, 0x49, 0x32, 0xc4, 0xb2, 0xee, 0xb9, 0xcd, 0x5d, 0x92, 0x07, 0x53, 0x9e, 0xca, 0x7f, 0xfc, 0x6c, 0xe0, 0xa5, 0xc8, 0xed, 0xba, 0x5d, 0x35, 0xc9, 0x4d, 0x1a, 0x86, 0x1b, 0xaf, 0xfc, 0x44, 0xb4, 0xec, 0xf8, 0xeb, 0xdc, 0x22, 0x08, 0x5f, 0x29, 0x85, 0x81, 0xdb, 0xe9, 0x8f, 0x4e, 0xf2, 0xb9, 0xd9, 0x09, 0x58, 0x11, 0xd4, 0xfa, 0x2a, 0x01, 0x5d, 0xf1, 0x07, 0x6f, 0xe8, 0x75, 0x66, 0x39, 0xac, 0x1b, 0x28, 0x57, 0x6b, 0xd3, 0xd4, 0x06, 0xee, 0xd0, 0x86, 0xde, 0xc4, 0x88, 0x99, 0x62, 0x52, 0x37, 0xd9, 0xed, 0x44, 0x3d, 0xc7, 0xa4, 0x2c, 0x2f, 0x96, 0xed, 0xfd, 0xba, 0xd8, 0xd1, 0x72, 0xf6, 0xbb, 0xf3, 0x5f, 0x3b, 0x3e, 0xc3, 0x2c, 0x23, 0xca, 0xb2, 0x72, 0x69, 0xb7, 0x14, 0xcc, 0x81, 0x1a, 0x24, 0x9b, 0x95, 0xd4, 0xc7, 0x97, 0x9f, 0xd3, 0x5b, 0x22, 0xa6, 0x57, 0x63, 0xec, 0x27, 0x20, 0xc4, 0x76, 0x6e, 0xd9, 0xf0, 0x56, 0xaa, 0x0d, 0x54, 0xb7, 0x49, 0x39, 0xf2, 0x19, 0x7d, 0x56, 0xa2, 0x70, 0x7e, 0xce, 0x89, 0x46, 0x08, 0xb2, 0x7f, 0xba, 0x73, 0x9a, 0x2d, 0x11, 0xdd, 0x74, 0x90, 0x70, 0x36, 0xd6, 0x97, 0x62, 0xf0, 0xf7, 0x39, 0x99, 0xf6, 0x50, 0xb2, 0xd4, 0xff, 0x42, 0x8e, 0xbe, 0xf1, 0x57, 0x0e, 0xc8, 0x29, 0x6f, 0x16, 0xa7, 0x86, 0xdb, 0xd9, 0x81, 0x43, 0x9b, 0x95, 0x24, 0xbd, 0x9a, 0x0c, 0x54, 0x2e, 0x71, 0x72, 0x42, 0xe6, 0x25, 0x41, 0xa9, 0x6e, 0x1c, 0x2e, 0x74, 0xb1, 0xe0, 0x4e, 0x66, 0xc3, 0xda, 0xb6, 0x16, 0xb2, 0x84, 0xc5, 0x1f, 0x1f, 0x65, 0xf2, 0xc8, 0x3d, 0x9c, 0xb4, 0x28, 0xed, 0xd3, 0xe2, 0xa2, 0xf8, 0x24, 0xd8, 0x84, 0x16, 0x9f, 0x72, 0x57, 0xa0, 0xfd, 0x28, 0x81, 0x97, 0xb3, 0x7b, 0x5d, 0x29, 0x37, 0xa3, 0x81, 0x2a, 0x5f, 0x45, 0x6b, 0xd3, 0xbd, 0x13, 0x78, 0x4a, 0x63, 0x9f, 0x7a, 0x34, 0x3c, 0xf4, 0x45, 0x7f, 0x51, 0xe9, 0x58, 0xdc, 0xcb, 0x39, 0x38, 0x87, 0xab, 0xb4, 0x0d, 0xaf, 0x4d, 0x63, 0x4b, 0x0f, 0x2e, 0xac, 0xc6, 0xd6, 0x04, 0x1b, 0x3a, 0xda, 0x9d, 0x3b, 0x20, 0x90, 0x3b, 0x19, 0x4f, 0x6e, 0x82, 0x93, 0x85, 0x53, 0x18, 0xf7, 0xa6, 0x1a, 0x2f, 0x98, 0xc8, 0x1f, 0xe3, 0x59, 0x5b, 0x43, 0x76, 0xc4, 0xd4, 0x37, 0xef, 0x0e, 0xce, 0xa3, 0x35, 0xc9, 0x4d, 0x43, 0x13, 0x24, 0xe3, 0x6c, 0x5a, 0xc8, 0x8d, 0xb2, 0x68, 0x5d, 0xc0, 0xd2, 0xd0, 0x06, 0x1d, 0x77, 0x80, 0x65, 0xcd, 0x0a, 0xc0, 0x93, 0xb1, 0x8c, 0xf8, 0x1b, 0xf6, 0x8c, 0x59, 0xf5, 0x99, 0x7f, 0xec, 0x34, 0x0e, 0x16, 0x4e, 0x6a, 0x0c, 0x86, 0xba, 0x1b, 0xd8, 0x53, 0x66, 0x1e, 0xdc, 0x66, 0x8d, 0x91, 0x1b, 0x2b, 0xb4, 0xdd, 0xe2, 0x54, 0x1e, 0xea, 0xc2, 0x5b, 0x6b, 0x56, 0x96, 0x8c, 0xfb, 0xf8, 0x21, 0x22, 0x8f, 0x1e, 0xbb, 0xd7, 0xe7, 0x7b, 0xd7, 0xbf, 0x0c, 0xbb, 0x9e, 0xe2, 0x6c, 0x31, 0x3a, 0xaa, 0xcd, 0xd3, 0xfb, 0xcb, 0x6e, 0xc6, 0x82, 0x7f, 0x01, 0xda, 0x0e, 0x0b, 0xc8, 0x21, 0xc4, 0x6c, 0x2b, 0xe3, 0x88, 0xcd, 0x0c, 0xb3, 0x3d, 0x89, 0xf6, 0xd9, 0x75, 0x16, 0xf8, 0x0e, 0x6d, 0xee, 0x5a, 0xd6, 0xaf, 0xe1, 0x63, 0xe0, 0x77, 0x55, 0x78, 0x39, 0xf9, 0xc4, 0xa2, 0xa7, 0x96, 0x34, 0x17, 0xe0, 0x4f, 0x79, 0xcc, 0x0c, 0x3f, 0x67, 0x31, 0x55, 0xc9, 0xe0, 0x3b, 0x2c, 0x45, 0xaf, 0xbb, 0xbc, 0x73, 0x7c, 0x13, 0xe6, 0x0a, 0x5b, 0x87, 0xd5, 0x91, 0x35, 0xbc, 0x63, 0xd2, 0x31, 0x41, 0x4f, 0x17, 0xb2, 0xf3, 0x44, 0x33, 0xbf, 0x41, 0x7f, 0x49, 0x2f, 0xab, 0x38, 0xd4, 0x9e, 0xf8, 0x9d, 0xb7, 0xe4, 0x97, 0x0f, 0x0e, 0xec, 0xa3, 0xe8, 0xda, 0x9a, 0x4f, 0x23, 0xab, 0x2f, 0xa8, 0x0f, 0x7e, 0x17, 0xed, 0x56, 0xc8, 0x69, 0x5b, 0xe6, 0xc1, 0xbd, 0x01, 0x19, 0xe5, 0xc3, 0xa6, 0x96, 0x91, 0x84, 0x36, 0x9e, 0xb1, 0x25, 0x72, 0xc5, 0x60, 0x3a, 0xcb, 0x77, 0xf9, 0x9b, 0x70, 0x78, 0x6a, 0x67, 0xd4, 0x9e, 0x7b, 0x48, 0x59, 0xa9, 0x6a, 0xed, 0x72, 0x70, 0x22, 0x5a, 0xfe, 0x07, 0x66, 0x1a, 0xb2, 0x3a, 0x7a, 0x1e, 0xcf, 0x3c, 0xc8, 0x94, 0xe0, 0x97, 0xcb, 0xba, 0x4b, 0x1c, 0xb9, 0xab, 0x5f, 0xa5, 0xeb, 0xf7, 0x25, 0x94, 0xce, 0x66, 0x5a, 0xf3, 0xdb, 0xf7, 0x3e, 0xca, 0xb2, 0x64, 0xf2, 0x04, 0xb3, 0xc5, 0x44, 0xf1, 0x6d, 0x2e, 0xfe, 0x16, 0xfa, 0xcc, 0x49, 0x6a, 0x61, 0x6f, 0x27, 0x4f, 0x0b, 0x85, 0x92, 0x17, 0xcc, 0x07, 0xe1, 0x93, 0x9e, 0x5f, 0x34, 0x6f, 0x9d, 0x65, 0xae, 0x03, 0x6a, 0x55, 0xa5, 0x45, 0x9f, 0x41, 0x0f, 0x29, 0xee, 0x87, 0xf5, 0x2d, 0x1e, 0xf3, 0x78, 0xa7, 0x4b, 0xb7, 0x80, 0x62, 0x5f, 0x90, 0x22, 0x80, 0x22, 0x44, 0xaa, 0xb2, 0x41, 0x33, 0xcd, 0x7c, 0xa7, 0x2b, 0x44, 0x5c, 0x3d, 0x54, 0x25, 0xfd, 0x6e, 0x47, 0xcb, 0x81, 0x46, 0x77, 0x8b, 0x75, 0x84, 0xe6, 0x94, 0x58, 0xa3, 0xd9, 0xbe, 0x54, 0x11, 0x25, 0xd7, 0x43, 0x53, 0xba, 0x43, 0x85, 0xfd, 0xec, 0x5b, 0x59, 0xe0, 0x03, 0x0e, 0x57, 0x80, 0x97, 0x7a, 0x0f, 0xf3, 0x17, 0x27, 0x50, 0x88, 0x72, 0x85, 0xb0, 0x14, 0x9d, 0x28, 0xec, 0x09, 0xb1, 0xb4, 0x56, 0x9b, 0x36, 0x4f, 0xa9, 0x8f, 0xb9, 0x66, 0x1f, 0xac, 0xea, 0xc3, 0x9f, 0xfe, 0x5a, 0xb8, 0xe8, 0xde, 0x63, 0xeb, 0x6f, 0xb8, 0x26, 0xdf, 0x42, 0x4b, 0x46, 0x94, 0xe0, 0xdb, 0x61, 0xae, 0x0a, 0x6f, 0xd6, 0xbf, 0xb3, 0x3b, 0x13, 0x82, 0xd6, 0x3e, 0xaf, 0x18, 0x2e, 0x4b, 0x03, 0xca, 0xf9, 0xa8, 0x83, 0x61, 0x2f, 0x04, 0x0b, 0x6e, 0xf0, 0x0e, 0x8c, 0xc2, 0x19, 0x9b, 0x10, 0x78, 0x3b, 0x36, 0xf6, 0x54, 0x12, 0x9b, 0xa1, 0xad, 0xf8, 0x02, 0x3b, 0x7b, 0x51, 0x53, 0x56, 0x8b, 0xc7, 0xeb, 0xaa, 0x5c, 0xfe, 0x38, 0x80, 0x59, 0x6c, 0x37, 0x79, 0x5e, 0x33, 0x77, 0xc7, 0x8b, 0x6b, 0x78, 0x1b, 0x9b, 0xd9, 0x91, 0x2f, 0xfb, 0x9b, 0x42, 0xca, 0x9b, 0xfe, 0xc8, 0x8f, 0x6a, 0xba, 0x47, 0x04, 0x94, 0xfd, 0xa2, 0x1a, 0x07, 0xb3, 0xc2, 0xb8, 0xaf, 0x0d, 0x9f, 0x7e, 0x2a, 0x6b, 0x1e, 0x82, 0x91, 0xe1, 0x17, 0xc0, 0x51, 0xf3, 0xc9, 0x14, 0xef, 0xf4, 0xbe, 0xe3, 0xa8, 0x57, 0xec, 0x2d, 0xb3, 0x1d, 0x26, 0x62, 0xd1, 0xb4, 0xad, 0x89, 0x58, 0x72, 0xc3, 0x87, 0x6a, 0xfb, 0x0f, 0x89, 0xa7, 0x1e, 0x34, 0x89, 0x3a, 0x3b, 0x96, 0x85, 0xa3, 0x91, 0x64, 0xf1, 0x59, 0x66, 0x66, 0x91, 0xa1, 0x76, 0x3a, 0x73, 0xc2, 0x93, 0x43, 0x07, 0xc3, 0xed, 0xb7, 0xf0, 0x9d, 0x6a, 0x48, 0x6c, 0xc8, 0xb4, 0x56, 0x12, 0xa6, 0xc2, 0x52, 0x50, 0x25, 0xf9, 0xd4, 0x1d, 0xfc, 0x4d, 0xbe, 0x0e, 0x48, 0x02, 0x31, 0xa9, 0xea, 0xce, 0xcb, 0x9a, 0xe9, 0x31, 0x9b, 0xd2, 0x8d, 0xdc, 0x37, 0x52, 0x95, 0x85, 0xdb, 0x36, 0x05, 0x1f, 0x1a, 0x6a, 0xbd, 0xc5, 0x73, 0x61, 0xdb, 0x27, 0xbf, 0x2a, 0x13, 0x47, 0x16, 0xde, 0x29, 0xa7, 0xc1, 0x24, 0xe4, 0x85, 0x23, 0x78, 0x13, 0x3a, 0x31, 0xc4, 0x32, 0x37, 0xbc, 0x30, 0x67, 0xd3, 0xdc, 0x47, 0x5c, 0xa6, 0x34, 0x8a, 0xd4, 0xb3, 0x7c, 0x5f, 0x5f, 0xb2, 0x14, 0x53, 0x50, 0xd8, 0xc4, 0x9d, 0xf0, 0xe5, 0x0d, 0x37, 0xa0, 0xd4, 0x43, 0x18, 0x05, 0xbc, 0x91, 0x33, 0x3a, 0x39, 0x06, 0x21, 0x53, 0x35, 0xd5, 0x15, 0xc0, 0x19, 0xac, 0x4d, 0xf0, 0x89, 0x8d, 0x0a, 0x07, 0x44, 0x43, 0xb7, 0xe0, 0x66, 0x1f, 0xc3, 0xcd, 0x30, 0x8b, 0x01, 0xd0, 0x8a, 0xa4, 0x21, 0x06, 0x25, 0xef, 0x3d, 0x19, 0xd0, 0xa3, 0x6c, 0x15, 0x7a, 0x32, 0x12, 0xad, 0xce, 0xfa, 0xba, 0xa2, 0xc9, 0x0d, 0xe0, 0x84, 0x56, 0x7e, 0xc8, 0x6b, 0x59, 0xbe, 0x86, 0xc8, 0xa4, 0xdc, 0x65, 0xac, 0xf1, 0x80, 0x44, 0x5d, 0x6b, 0x3c, 0x13, 0x11, 0x47, 0xf6, 0x16, 0x35, 0x4e, 0xa3, 0xbf, 0xf2, 0x2a, 0x31, 0xee, 0x38, 0x47, 0xf4, 0x78, 0x42, 0x61, 0x6d, 0x4a, 0xab, 0xc0, 0x58, 0x04, 0xb2, 0x96, 0xb6, 0x30, 0xed, 0xec, 0x9a, 0x85, 0x09, 0x21, 0xfc, 0xbe, 0x5c, 0xbd, 0xec, 0xa4, 0x1e, 0xa4, 0x3d, 0xb1, 0x4e, 0xf8, 0x5e, 0xfb, 0x3a, 0x0f, 0xf8, 0xdc, 0x45, 0xda, 0xd3, 0x78, 0x82, 0x4f, 0x99, 0x8a, 0x42, 0x1a, 0xd7, 0x73, 0x55, 0x79, 0x42, 0xb9, 0x05, 0x19, 0xba, 0x57, 0x7f, 0xb1, 0x58, 0xc5, 0x55, 0x61, 0x4c, 0xed, 0x0d, 0x3e, 0x24, 0xf1, 0x04, 0x5e, 0xf3, 0xe7, 0x3e, 0x02, 0x36, 0x38, 0xdc, 0xca, 0x3b, 0x9f, 0xe1, 0x25, 0xf5, 0xa8, 0xc6, 0xc4, 0xdc, 0x39, 0xb0, 0xc0, 0xd8, 0x61, 0x84, 0xcd, 0xcf, 0xbe, 0xb7, 0x07, 0x08, 0x12, 0xef, 0x53, 0x37, 0xd7, 0xf8, 0x3e, 0x41, 0xde, 0x12, 0x1f, 0xe3, 0xa7, 0x90, 0x01, 0xce, 0x91, 0x87, 0x62, 0xdd, 0x7a, 0x9f, 0xde, 0xdf, 0xb0, 0x62, 0x96, 0x66, 0x6e, 0x9c, 0xd4, 0x82, 0x43, 0xa1, 0xa7, 0xde, 0x03, 0x7a, 0x49, 0xc8, 0x8a, 0x72, 0x2d, 0xee, 0x42, 0x7f, 0x6b, 0x1e, 0x81, 0x31, 0xee, 0x61, 0xe5, 0x97, 0x38, 0xe4, 0x6f, 0xf3, 0x42, 0x5e, 0x38, 0xb3, 0x37, 0xe5, 0x53, 0x5c, 0xeb, 0x7d, 0x86, 0xcf, 0xfa, 0xe2, 0x8d, 0xb5, 0x57, 0x44, 0x59, 0x48, 0x30, 0x51, 0xe6, 0x7b, 0x9a, 0xc4, 0x25, 0x61, 0x51, 0x68, 0xf9, 0x42, 0x28, 0x8c, 0x6c, 0xba, 0x70, 0x3d, 0x0d, 0xa2, 0x8d, 0xcd, 0xcf, 0xf2, 0x4b, 0x85, 0xd6, 0xd6, 0x14, 0xe6, 0x1a, 0x9b, 0x18, 0x22, 0x67, 0x22, 0xa5, 0xb8, 0x7c, 0xec, 0x6d, 0x66, 0xf5, 0xa4, 0x29, 0x13, 0x5c, 0x1c, 0x4f, 0xcd, 0x8b, 0xbc, 0x0f, 0x27, 0x75, 0xda, 0xc6, 0x77, 0xd2, 0x5f, 0x37, 0xee, 0x46, 0xd4, 0xb1, 0x18, 0x72, 0xfb, 0xb7, 0x5f, 0x62, 0x08, 0xff, 0x7f, 0x2e, 0x50, 0x36, 0x29, 0x53, 0x0b, 0x62, 0x38, 0xc6, 0x5a, 0x3e, 0xe9, 0xba, 0x36, 0xe2, 0xcb, 0x7d, 0xf4, 0x67, 0xd8, 0x98, 0x88, 0xf6, 0x39, 0xf9, 0x85, 0x64, 0xeb, 0xc4, 0x7f, 0xb6, 0xc9, 0xf8, 0x03, 0x1a, 0xca, 0x0d, 0x35, 0x94, 0xe2, 0xc3, 0xcc, 0xef, 0x5d, 0x5a, 0x83, 0x28, 0x50, 0x8e, 0x88, 0x67, 0x31, 0xd3, 0xa0, 0x5c, 0x69, 0x83, 0x6d, 0x21, 0x0e, 0x2a, 0x67, 0x35, 0x68, 0x9a, 0xb2, 0x41, 0x67, 0x87, 0x8b, 0x1a, 0x84, 0x53, 0x78, 0xa3, 0x26, 0x1b, 0xc3, 0x0f, 0x24, 0x5f, 0x76, 0xbf, 0x0c, 0x50, 0xff, 0x40, 0x38, 0x98, 0x55, 0x6d, 0x24, 0x44, 0x84, 0x05, 0x79, 0x20, 0x36, 0xe0, 0xb8, 0x04, 0xcb, 0x69, 0x63, 0x91, 0x81, 0xb9, 0x07, 0xa9, 0xa6, 0x28, 0x91, 0xf3, 0xe6, 0xf9, 0xa0, 0xbb, 0x77, 0xaa, 0xe1, 0xe9, 0x90, 0xe8, 0x36, 0x60, 0x15, 0x5b, 0xb3, 0x9b, 0x72, 0x7b, 0x1c, 0x17, 0xcb, 0xd5, 0xf0, 0x1b, 0x2f, 0xce, 0x76, 0xf9, 0xae, 0x50, 0x7b, 0x70, 0xc5, 0xe8, 0x3a, 0x08, 0x96, 0x08, 0xa2, 0x9f, 0x22, 0xbb, 0x39, 0x4f, 0x37, 0x3c, 0x72, 0x36, 0x71, 0x1b, 0x4b, 0x09, 0x25, 0x71, 0x6e, 0xcf, 0xc1, 0x09, 0x42, 0x7f, 0x5c, 0xa4, 0xc8, 0xf2, 0x8e, 0xa7, 0x21, 0xc7, 0x89, 0xa7, 0x51, 0xbc, 0xf3, 0x87, 0x3d, 0x57, 0xd0, 0x38, 0x0e, 0xde, 0x3c, 0x28, 0x02, 0x1b, 0x75, 0x5c, 0x01, 0x90, 0xa2, 0xd7, 0x5a, 0x39, 0x0a, 0xe6, 0x01, 0x16, 0x80, 0xad, 0x98, 0x21, 0x82, 0xf4, 0x31, 0xca, 0x50, 0x76, 0x98, 0xd1, 0xd7, 0x62, 0xd2, 0xfb, 0xf4, 0x94, 0x61, 0x34, 0x30, 0x5b, 0x90, 0xe0, 0x98, 0x66, 0xf3, 0xba, 0x10, 0xa4, 0x3f, 0x30, 0x06, 0x0e, 0xcc, 0x2b, 0x61, 0xa3, 0xaa, 0x3b, 0xef, 0x8a, 0x26, 0x59, 0xdf, 0x6b, 0xd2, 0xc5, 0x8e, 0x8d }; +constexpr AccessUnit LPCM_SINGLE_PACK_EXPECTED_AU_1 = { 0x15f90, 0x159b2, false, 3, { 0xb1, 0x40, 0x00, 0xda, 0x2c, 0xae, 0xd8, 0xf8, 0x31, 0x4d, 0x58, 0x96, 0x3f, 0x03, 0x7e, 0x2e }, { 0xec, 0x7a, 0x1d, 0x5c, 0xa0, 0xca, 0x0e, 0xdc, 0x52, 0x1a, 0x9c, 0xc1, 0x52, 0xdc, 0xcd, 0xa6, 0x9e, 0x28, 0x97, 0xde } }; +constexpr AccessUnit LPCM_SINGLE_PACK_EXPECTED_AU_2 = { std::numeric_limits::max(), std::numeric_limits::max(), false, 3, { 0xb1, 0x40, 0x00, 0xda, 0x2c, 0xae, 0xd8, 0xf8, 0x31, 0x4d, 0x58, 0x96, 0x3f, 0x03, 0x7e, 0x2e }, { 0x09, 0xa0, 0xb5, 0x46, 0xd8, 0x95, 0xf7, 0x34, 0x86, 0xc9, 0x2c, 0x8f, 0xe0, 0xb6, 0x69, 0x72, 0x75, 0x0b, 0xa9, 0x59 } }; + +constexpr std::array USER_DATA_SINGLE_PACK_STREAM = { 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xbd, 0x06, 0xe6, 0x81, 0xc1, 0x0d, 0x31, 0x00, 0x05, 0xbf, 0x21, 0x11, 0x00, 0x05, 0xb3, 0x65, 0x1e, 0x69, 0xb2, 0x20, 0xb1, 0x00, 0x00, 0x04, 0x29, 0xae, 0xd8, 0xf8, 0x31, 0x4d, 0x58, 0x96, 0x3f, 0x03, 0x7e, 0x2e, 0x5d, 0xb9, 0x16, 0xf9, 0x14, 0x26, 0x07, 0x3f, 0x85, 0xc1, 0x78, 0xcb, 0xf1, 0x73, 0xc1, 0xd6, 0xc2, 0x80, 0x8d, 0xaf, 0xa9, 0x76, 0xb1, 0xb2, 0x83, 0xcf, 0xce, 0x89, 0x25, 0xe4, 0x78, 0xe7, 0x06, 0x10, 0x18, 0xdd, 0x52, 0xf6, 0x17, 0x36, 0xe0, 0xba, 0x91, 0xc5, 0x0b, 0x07, 0xca, 0x35, 0x6b, 0xe0, 0x1c, 0xbf, 0xdf, 0x36, 0xfb, 0xca, 0x06, 0x73, 0x67, 0x8d, 0xcf, 0xb0, 0xf8, 0x8d, 0x34, 0xef, 0x73, 0x07, 0x1b, 0x74, 0x31, 0x13, 0xf4, 0x5a, 0x45, 0x77, 0xf9, 0xc2, 0x7e, 0x0c, 0x9b, 0xb1, 0x3a, 0xf9, 0x48, 0xbb, 0x8e, 0xda, 0xc6, 0x9f, 0x68, 0xfd, 0x4a, 0x39, 0xcd, 0x81, 0xa1, 0x4e, 0xcc, 0x6e, 0x2a, 0x49, 0x32, 0xc4, 0xb2, 0xee, 0xb9, 0xcd, 0x5d, 0x92, 0x07, 0x53, 0x9e, 0xca, 0x7f, 0xfc, 0x6c, 0xe0, 0xa5, 0xc8, 0xed, 0xba, 0x5d, 0x35, 0xc9, 0x4d, 0x1a, 0x86, 0x1b, 0xaf, 0xfc, 0x44, 0xb4, 0xec, 0xf8, 0xeb, 0xdc, 0x22, 0x08, 0x5f, 0x29, 0x85, 0x81, 0xdb, 0xe9, 0x8f, 0x4e, 0xf2, 0xb9, 0xd9, 0x09, 0x58, 0x11, 0xd4, 0xfa, 0x2a, 0x01, 0x5d, 0xf1, 0x07, 0x6f, 0xe8, 0x75, 0x66, 0x39, 0xac, 0x1b, 0x28, 0x57, 0x6b, 0xd3, 0xd4, 0x06, 0xee, 0xd0, 0x86, 0xde, 0xc4, 0x88, 0x99, 0x62, 0x52, 0x37, 0xd9, 0xed, 0x44, 0x3d, 0xc7, 0xa4, 0x2c, 0x2f, 0x96, 0xed, 0xfd, 0xba, 0xd8, 0xd1, 0x72, 0xf6, 0xbb, 0xf3, 0x5f, 0x3b, 0x3e, 0xc3, 0x2c, 0x23, 0xca, 0xb2, 0x72, 0x69, 0xb7, 0x14, 0xcc, 0x81, 0x1a, 0x24, 0x9b, 0x95, 0xd4, 0xc7, 0x97, 0x9f, 0xd3, 0x5b, 0x22, 0xa6, 0x57, 0x63, 0xec, 0x27, 0x20, 0xc4, 0x76, 0x6e, 0xd9, 0xf0, 0x56, 0xaa, 0x0d, 0x54, 0xb7, 0x49, 0x39, 0xf2, 0x19, 0x7d, 0x56, 0xa2, 0x70, 0x7e, 0xce, 0x89, 0x46, 0x08, 0xb2, 0x7f, 0xba, 0x73, 0x9a, 0x2d, 0x11, 0xdd, 0x74, 0x90, 0x70, 0x36, 0xd6, 0x97, 0x62, 0xf0, 0xf7, 0x39, 0x99, 0xf6, 0x50, 0xb2, 0xd4, 0xff, 0x42, 0x8e, 0xbe, 0xf1, 0x57, 0x0e, 0xc8, 0x29, 0x6f, 0x16, 0xa7, 0x86, 0xdb, 0xd9, 0x81, 0x43, 0x9b, 0x95, 0x24, 0xbd, 0x9a, 0x0c, 0x54, 0x2e, 0x71, 0x72, 0x42, 0xe6, 0x25, 0x41, 0xa9, 0x6e, 0x1c, 0x2e, 0x74, 0xb1, 0xe0, 0x4e, 0x66, 0xc3, 0xda, 0xb6, 0x16, 0xb2, 0x84, 0xc5, 0x1f, 0x1f, 0x65, 0xf2, 0xc8, 0x3d, 0x9c, 0xb4, 0x28, 0xed, 0xd3, 0xe2, 0xa2, 0xf8, 0x24, 0xd8, 0x84, 0x16, 0x9f, 0x72, 0x57, 0xa0, 0xfd, 0x28, 0x81, 0x97, 0xb3, 0x7b, 0x5d, 0x29, 0x37, 0xa3, 0x81, 0x2a, 0x5f, 0x45, 0x6b, 0xd3, 0xbd, 0x13, 0x78, 0x4a, 0x63, 0x9f, 0x7a, 0x34, 0x3c, 0xf4, 0x45, 0x7f, 0x51, 0xe9, 0x58, 0xdc, 0xcb, 0x39, 0x38, 0x87, 0xab, 0xb4, 0x0d, 0xaf, 0x4d, 0x63, 0x4b, 0x0f, 0x2e, 0xac, 0xc6, 0xd6, 0x04, 0x1b, 0x3a, 0xda, 0x9d, 0x3b, 0x20, 0x90, 0x3b, 0x19, 0x4f, 0x6e, 0x82, 0x93, 0x85, 0x53, 0x18, 0xf7, 0xa6, 0x1a, 0x2f, 0x98, 0xc8, 0x1f, 0xe3, 0x59, 0x5b, 0x43, 0x76, 0xc4, 0xd4, 0x37, 0xef, 0x0e, 0xce, 0xa3, 0x35, 0xc9, 0x4d, 0x43, 0x13, 0x24, 0xe3, 0x6c, 0x5a, 0xc8, 0x8d, 0xb2, 0x68, 0x5d, 0xc0, 0xd2, 0xd0, 0x06, 0x1d, 0x77, 0x80, 0x65, 0xcd, 0x0a, 0xc0, 0x93, 0xb1, 0x8c, 0xf8, 0x1b, 0xf6, 0x8c, 0x59, 0xf5, 0x99, 0x7f, 0xec, 0x34, 0x0e, 0x16, 0x4e, 0x6a, 0x0c, 0x86, 0xba, 0x1b, 0xd8, 0x53, 0x66, 0x1e, 0xdc, 0x66, 0x8d, 0x91, 0x1b, 0x2b, 0xb4, 0xdd, 0xe2, 0x54, 0x1e, 0xea, 0xc2, 0x5b, 0x6b, 0x56, 0x96, 0x8c, 0xfb, 0xf8, 0x21, 0x22, 0x8f, 0x1e, 0xbb, 0xd7, 0xe7, 0x7b, 0xd7, 0xbf, 0x0c, 0xbb, 0x9e, 0xe2, 0x6c, 0x31, 0x3a, 0xaa, 0xcd, 0xd3, 0xfb, 0xcb, 0x6e, 0xc6, 0x82, 0x7f, 0x01, 0xda, 0x0e, 0x0b, 0xc8, 0x21, 0xc4, 0x6c, 0x2b, 0xe3, 0x88, 0xcd, 0x0c, 0xb3, 0x3d, 0x89, 0xf6, 0xd9, 0x75, 0x16, 0xf8, 0x0e, 0x6d, 0xee, 0x5a, 0xd6, 0xaf, 0xe1, 0x63, 0xe0, 0x77, 0x55, 0x78, 0x39, 0xf9, 0xc4, 0xa2, 0xa7, 0x96, 0x34, 0x17, 0xe0, 0x4f, 0x79, 0xcc, 0x0c, 0x3f, 0x67, 0x31, 0x55, 0xc9, 0xe0, 0x3b, 0x2c, 0x45, 0xaf, 0xbb, 0xbc, 0x73, 0x7c, 0x13, 0xe6, 0x0a, 0x5b, 0x87, 0xd5, 0x91, 0x35, 0xbc, 0x63, 0xd2, 0x31, 0x41, 0x4f, 0x17, 0xb2, 0xf3, 0x44, 0x33, 0xbf, 0x41, 0x7f, 0x49, 0x2f, 0xab, 0x38, 0xd4, 0x9e, 0xf8, 0x9d, 0xb7, 0xe4, 0x97, 0x0f, 0x0e, 0xec, 0xa3, 0xe8, 0xda, 0x9a, 0x4f, 0x23, 0xab, 0x2f, 0xa8, 0x0f, 0x7e, 0x17, 0xed, 0x56, 0xc8, 0x69, 0x5b, 0xe6, 0xc1, 0xbd, 0x01, 0x19, 0xe5, 0xc3, 0xa6, 0x96, 0x91, 0x84, 0x36, 0x9e, 0xb1, 0x25, 0x72, 0xc5, 0x60, 0x3a, 0xcb, 0x77, 0xf9, 0x9b, 0x70, 0x78, 0x6a, 0x67, 0xd4, 0x9e, 0x7b, 0x48, 0x59, 0xa9, 0x6a, 0xed, 0x72, 0x70, 0x22, 0x5a, 0xfe, 0x07, 0x66, 0x1a, 0xb2, 0x3a, 0x7a, 0x1e, 0xcf, 0x3c, 0xc8, 0x94, 0xe0, 0x97, 0xcb, 0xba, 0x4b, 0x1c, 0xb9, 0xab, 0x5f, 0xa5, 0xeb, 0xf7, 0x25, 0x94, 0xce, 0x66, 0x5a, 0xf3, 0xdb, 0xf7, 0x3e, 0xca, 0xb2, 0x64, 0xf2, 0x04, 0xb3, 0xc5, 0x44, 0xf1, 0x6d, 0x2e, 0xfe, 0x16, 0xfa, 0xcc, 0x49, 0x6a, 0x61, 0x6f, 0x27, 0x4f, 0x0b, 0x85, 0x92, 0x17, 0xcc, 0x07, 0xe1, 0x93, 0x9e, 0x5f, 0x34, 0x6f, 0x9d, 0x65, 0xae, 0x03, 0x6a, 0x55, 0xa5, 0x45, 0x9f, 0x41, 0x0f, 0x29, 0xee, 0x87, 0xf5, 0x2d, 0x1e, 0xf3, 0x78, 0xa7, 0x4b, 0xb7, 0x80, 0x62, 0x5f, 0x90, 0x22, 0x80, 0x22, 0x44, 0xaa, 0xb2, 0x41, 0x33, 0xcd, 0x7c, 0xa7, 0x2b, 0x44, 0x5c, 0x3d, 0x54, 0x25, 0xfd, 0x6e, 0x47, 0xcb, 0x81, 0x46, 0x77, 0x8b, 0x75, 0x84, 0xe6, 0x94, 0x58, 0xa3, 0xd9, 0xbe, 0x54, 0x11, 0x25, 0xd7, 0x43, 0x53, 0xba, 0x43, 0x85, 0xfd, 0xec, 0x5b, 0x59, 0xe0, 0x03, 0x0e, 0x57, 0x80, 0x97, 0x7a, 0x0f, 0xf3, 0x17, 0x27, 0x50, 0x88, 0x72, 0x85, 0xb0, 0x14, 0x9d, 0x28, 0xec, 0x09, 0xb1, 0xb4, 0x56, 0x9b, 0x36, 0x4f, 0xa9, 0x8f, 0xb9, 0x66, 0x1f, 0xac, 0xea, 0xc3, 0x9f, 0xfe, 0x5a, 0xb8, 0xe8, 0xde, 0x63, 0xeb, 0x6f, 0xb8, 0x26, 0xdf, 0x42, 0x4b, 0x46, 0x94, 0xe0, 0xdb, 0x61, 0xae, 0x0a, 0x6f, 0xd6, 0xbf, 0xb3, 0x3b, 0x13, 0x82, 0xd6, 0x3e, 0xaf, 0x18, 0x2e, 0x4b, 0x03, 0xca, 0xf9, 0xa8, 0x83, 0x61, 0x2f, 0x04, 0x0b, 0x6e, 0xf0, 0x0e, 0x8c, 0xc2, 0x19, 0x9b, 0x10, 0x78, 0x3b, 0x36, 0xf6, 0x54, 0x12, 0x9b, 0xa1, 0xad, 0xf8, 0x02, 0x3b, 0x7b, 0x51, 0x53, 0x56, 0x8b, 0xc7, 0xeb, 0xaa, 0x5c, 0xfe, 0x38, 0x80, 0x59, 0x6c, 0x37, 0x79, 0x5e, 0x33, 0x77, 0xc7, 0x8b, 0x6b, 0x78, 0x1b, 0x9b, 0xd9, 0x91, 0x2f, 0xfb, 0x9b, 0x42, 0xca, 0x9b, 0xfe, 0xc8, 0x8f, 0x6a, 0xba, 0x47, 0x04, 0x94, 0xfd, 0xa2, 0x1a, 0x07, 0xb3, 0xc2, 0xb8, 0xaf, 0x0d, 0x9f, 0x7e, 0x2a, 0x6b, 0x1e, 0x82, 0x91, 0xe1, 0x17, 0xc0, 0x51, 0xf3, 0xc9, 0x14, 0xef, 0xf4, 0xbe, 0xe3, 0xa8, 0x57, 0xec, 0x2d, 0xb3, 0x1d, 0x26, 0x62, 0xd1, 0xb4, 0xad, 0x89, 0x58, 0x72, 0xc3, 0x87, 0x6a, 0xfb, 0x0f, 0x89, 0xa7, 0x1e, 0x34, 0x89, 0x3a, 0x3b, 0x96, 0x85, 0xa3, 0x91, 0x64, 0xf1, 0x59, 0x66, 0x66, 0x91, 0xa1, 0x76, 0x3a, 0x73, 0xc2, 0x93, 0x43, 0x07, 0xc3, 0xed, 0xb7, 0xf0, 0x9d, 0x6a, 0x48, 0x6c, 0xc8, 0xb4, 0x56, 0x12, 0xa6, 0xc2, 0x52, 0x50, 0x25, 0xf9, 0xd4, 0x1d, 0xfc, 0x4d, 0xbe, 0x0e, 0x48, 0x02, 0x31, 0xa9, 0xea, 0xce, 0xcb, 0x9a, 0xe9, 0x31, 0x9b, 0xd2, 0x8d, 0xdc, 0x37, 0x52, 0x95, 0x85, 0xdb, 0x36, 0x05, 0x1f, 0x1a, 0x6a, 0xbd, 0xc5, 0x73, 0x61, 0xdb, 0x27, 0xbf, 0x2a, 0x13, 0x47, 0x16, 0xde, 0x29, 0xa7, 0xc1, 0x24, 0xe4, 0x85, 0x23, 0x78, 0x13, 0x3a, 0x31, 0xc4, 0x32, 0x37, 0xbc, 0x30, 0x67, 0xd3, 0xdc, 0x47, 0x5c, 0xa6, 0x34, 0x8a, 0xd4, 0xb3, 0x7c, 0x5f, 0x5f, 0xb2, 0x14, 0x53, 0x50, 0xd8, 0xc4, 0x9d, 0xf0, 0xe5, 0x0d, 0x37, 0xa0, 0xd4, 0x43, 0x18, 0x05, 0xbc, 0x91, 0x33, 0x3a, 0x39, 0x06, 0x21, 0x53, 0x35, 0xd5, 0x15, 0xc0, 0x19, 0xac, 0x4d, 0xf0, 0x89, 0x8d, 0x0a, 0x07, 0x44, 0x43, 0xb7, 0xe0, 0x66, 0x1f, 0xc3, 0xcd, 0x30, 0x8b, 0x01, 0xd0, 0x8a, 0xa4, 0x21, 0x06, 0x25, 0xef, 0x3d, 0x19, 0xd0, 0xa3, 0x6c, 0x15, 0x7a, 0x32, 0x12, 0xad, 0xce, 0xfa, 0xba, 0xa2, 0xc9, 0x0d, 0xe0, 0x84, 0x56, 0x7e, 0xc8, 0x6b, 0x59, 0xbe, 0x86, 0xc8, 0xa4, 0xdc, 0x65, 0xac, 0xf1, 0x80, 0x44, 0x5d, 0x6b, 0x3c, 0x13, 0x11, 0x47, 0xf6, 0x16, 0x35, 0x4e, 0xa3, 0xbf, 0xf2, 0x2a, 0x31, 0xee, 0x38, 0x47, 0xf4, 0x78, 0x42, 0x61, 0x6d, 0x4a, 0xab, 0xc0, 0x58, 0x04, 0xb2, 0x96, 0xb6, 0x30, 0xed, 0xec, 0x9a, 0x85, 0x09, 0x21, 0xfc, 0xbe, 0x5c, 0xbd, 0xec, 0xa4, 0x1e, 0xa4, 0x3d, 0xb1, 0x4e, 0xf8, 0x5e, 0xfb, 0x3a, 0x0f, 0xf8, 0xdc, 0x45, 0xda, 0xd3, 0x78, 0x82, 0x4f, 0x99, 0x8a, 0x42, 0x1a, 0xd7, 0x73, 0x55, 0x79, 0x42, 0xb9, 0x05, 0x19, 0xba, 0x57, 0x7f, 0xb1, 0x58, 0xc5, 0x55, 0x61, 0x4c, 0xed, 0x0d, 0x3e, 0x24, 0xf1, 0x04, 0x5e, 0xf3, 0xe7, 0x3e, 0x02, 0x36, 0x38, 0xdc, 0xca, 0x3b, 0x9f, 0xe1, 0x25, 0xf5, 0xa8, 0xc6, 0xc4, 0xdc, 0x39, 0xb0, 0xc0, 0xd8, 0x61, 0x84, 0xcd, 0xcf, 0xbe, 0xb7, 0x07, 0x08, 0x12, 0xef, 0x53, 0x37, 0xd7, 0xf8, 0x3e, 0x41, 0xde, 0x12, 0x1f, 0xe3, 0xa7, 0x90, 0x01, 0xce, 0x91, 0x87, 0x62, 0xdd, 0x7a, 0x9f, 0xde, 0xdf, 0xb0, 0x62, 0x96, 0x66, 0x6e, 0x9c, 0xd4, 0x82, 0x43, 0xa1, 0xa7, 0xde, 0x03, 0x7a, 0x49, 0xc8, 0x8a, 0x72, 0x2d, 0xee, 0x42, 0x7f, 0x6b, 0x1e, 0x81, 0x31, 0xee, 0x61, 0xe5, 0x97, 0x38, 0xe4, 0x6f, 0xf3, 0x42, 0x5e, 0x38, 0xb3, 0x37, 0xe5, 0x53, 0x5c, 0xeb, 0x7d, 0x86, 0xcf, 0xfa, 0xe2, 0x8d, 0xb5, 0x57, 0x44, 0x59, 0x48, 0x30, 0x51, 0xe6, 0x7b, 0x9a, 0xc4, 0x25, 0x61, 0x51, 0x68, 0xf9, 0x42, 0x28, 0x8c, 0x6c, 0xba, 0x70, 0x3d, 0x0d, 0xa2, 0x8d, 0xcd, 0xcf, 0xf2, 0x4b, 0x85, 0xd6, 0xd6, 0x14, 0xe6, 0x1a, 0x9b, 0x18, 0x22, 0x67, 0x22, 0xa5, 0xb8, 0x7c, 0xec, 0x6d, 0x66, 0xf5, 0xa4, 0x29, 0x13, 0x5c, 0x1c, 0x4f, 0xcd, 0x8b, 0xbc, 0x0f, 0x27, 0x75, 0xda, 0xc6, 0x77, 0xd2, 0x5f, 0x37, 0xee, 0x46, 0xd4, 0xb1, 0x18, 0x72, 0xfb, 0xb7, 0x5f, 0x62, 0x08, 0xff, 0x7f, 0x2e, 0x50, 0x36, 0x29, 0x53, 0x0b, 0x62, 0x38, 0xc6, 0x5a, 0x3e, 0xe9, 0xba, 0x36, 0xe2, 0xcb, 0x7d, 0xf4, 0x67, 0xd8, 0x98, 0x88, 0xf6, 0x39, 0xf9, 0x85, 0x64, 0xeb, 0xc4, 0x7f, 0xb6, 0xc9, 0xf8, 0x03, 0x1a, 0xca, 0x0d, 0x35, 0x94, 0xe2, 0xc3, 0xcc, 0xef, 0x5d, 0x5a, 0x83, 0x28, 0x50, 0x8e, 0x88, 0x67, 0x31, 0xd3, 0xa0, 0x5c, 0x69, 0x83, 0x6d, 0x21, 0x0e, 0x2a, 0x67, 0x35, 0x68, 0x9a, 0xb2, 0x41, 0x67, 0x87, 0x8b, 0x1a, 0x84, 0x53, 0x78, 0xa3, 0x26, 0x1b, 0xc3, 0x0f, 0x24, 0x5f, 0x76, 0xbf, 0x0c, 0x50, 0xff, 0x40, 0x38, 0x98, 0x55, 0x6d, 0x24, 0x44, 0x84, 0x05, 0x79, 0x20, 0x36, 0xe0, 0xb8, 0x04, 0xcb, 0x69, 0x63, 0x91, 0x81, 0xb9, 0x07, 0xa9, 0xa6, 0x28, 0x91, 0xf3, 0xe6, 0xf9, 0xa0, 0xbb, 0x77, 0xaa, 0xe1, 0xe9, 0x90, 0xe8, 0x36, 0x60, 0x15, 0x5b, 0xb3, 0x9b, 0x72, 0x7b, 0x1c, 0x17, 0xcb, 0xd5, 0xf0, 0x1b, 0x2f, 0xce, 0x76, 0xf9, 0xae, 0x50, 0x7b, 0x70, 0xc5, 0xe8, 0x3a, 0x08, 0x96, 0x08, 0xa2, 0x9f, 0x22, 0xbb, 0x39, 0x4f, 0x37, 0x3c, 0x72, 0x36, 0x71, 0x1b, 0x4b, 0x09, 0x25, 0x71, 0x6e, 0xcf, 0xc1, 0x09, 0x42, 0x7f, 0x5c, 0xa4, 0xc8, 0xf2, 0x8e, 0xa7, 0x21, 0xc7, 0x89, 0xa7, 0x51, 0xbc, 0xf3, 0x87, 0x3d, 0x57, 0xd0, 0x38, 0x0e, 0xde, 0x3c, 0x28, 0x02, 0x1b, 0x75, 0x5c, 0x01, 0x90, 0xa2, 0xd7, 0x5a, 0x39, 0x0a, 0xe6, 0x01, 0x16, 0x80, 0xad, 0x98, 0x21, 0x82, 0xf4, 0x31, 0xca, 0x50, 0x76, 0x98, 0xd1, 0xd7, 0x62, 0xd2, 0xfb, 0xf4, 0x94, 0x61, 0x34, 0x30, 0x5b, 0x90, 0xe0, 0x98, 0x66, 0xf3, 0xba, 0x10, 0xa4, 0x3f, 0x30, 0x06, 0x0e, 0xcc, 0x2b, 0x61, 0xa3, 0xaa, 0x3b, 0xef, 0x8a, 0x26, 0x59, 0xdf, 0x6b, 0xd2, 0xc5, 0x8e, 0x8d }; +constexpr AccessUnit USER_DATA_SINGLE_PACK_EXPECTED_AU = { 0x15f90, 0x159b2, false, 0, {}, { 0x65, 0x94, 0x4b, 0xa5, 0x88, 0x59, 0x24, 0xa3, 0x5a, 0x30, 0x33, 0x6d, 0xaf, 0xb2, 0x95, 0x4b, 0x84, 0x08, 0x72, 0xd6 } }; + + +constexpr std::array TIME_STAMP_SIGN_EXTENDED_STREAM = []() constexpr { auto pack = USER_DATA_SINGLE_PACK_STREAM; pack[0x11d] |= 0x4; pack[0x122] |= 0x4; return pack; }(); // Set 31st bits of the timestamps +constexpr AccessUnit TIME_STAMP_SIGN_EXTENDED_EXPECTED_AU = { 0xffffffff'80015f90ull, 0xffffffff'800159b2ull, false, 0, {}, { 0x65, 0x94, 0x4b, 0xa5, 0x88, 0x59, 0x24, 0xa3, 0x5a, 0x30, 0x33, 0x6d, 0xaf, 0xb2, 0x95, 0x4b, 0x84, 0x08, 0x72, 0xd6 } }; + + +const std::vector AVC_LARGE_AU_STREAM = { 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xe0, 0x06, 0xe6, 0x81, 0xc1, 0x0d, 0x31, 0x00, 0x05, 0xbf, 0x21, 0x11, 0x00, 0x05, 0xb3, 0x65, 0x1e, 0x69, 0xb2, 0x00, 0x00, 0x00, 0x01, 0x09, 0xf6, 0xc0, 0x00, 0x4f, 0x57, 0x7f, 0xb7, 0xec, 0x51, 0xfa, 0xd4, 0x23, 0xdf, 0x05, 0x0a, 0x7a, 0x74, 0x3b, 0xbc, 0x91, 0xb6, 0xc8, 0x73, 0x6b, 0xe4, 0x1d, 0x28, 0xe9, 0xf2, 0x5f, 0xf8, 0x91, 0x13, 0xe6, 0xdb, 0x83, 0x92, 0x7f, 0x24, 0x04, 0x68, 0x57, 0x5c, 0x20, 0x6a, 0x4d, 0xfe, 0x93, 0x47, 0xe9, 0xf0, 0xf0, 0x18, 0xe2, 0xef, 0x2a, 0x94, 0xa9, 0xe4, 0xac, 0xc7, 0x1b, 0x62, 0x71, 0x96, 0xc8, 0x9e, 0xf6, 0x91, 0x44, 0x83, 0x34, 0x23, 0xf8, 0xb7, 0x35, 0x15, 0x1d, 0xe9, 0xc5, 0x1a, 0x61, 0xbd, 0x48, 0x21, 0x6b, 0xff, 0xd6, 0x2d, 0x85, 0xc8, 0x37, 0xf5, 0x6b, 0xaa, 0x59, 0x24, 0xf8, 0x33, 0xb5, 0xc8, 0xbc, 0x0a, 0x43, 0x3f, 0x82, 0xea, 0xd8, 0x8c, 0xdc, 0xd0, 0x6e, 0x92, 0x20, 0x3e, 0xce, 0x6c, 0x36, 0x3c, 0x43, 0xbf, 0x6e, 0x47, 0x92, 0xaa, 0xa3, 0x2a, 0x21, 0x95, 0x4c, 0x2e, 0x06, 0xbd, 0x64, 0x07, 0xf7, 0xdd, 0x15, 0x58, 0xf4, 0x15, 0xde, 0x47, 0x02, 0xe5, 0x2b, 0x9a, 0xce, 0x25, 0x2a, 0x85, 0x48, 0x3e, 0x05, 0xc2, 0xd2, 0xc6, 0x5a, 0x6d, 0xfe, 0xe8, 0x8b, 0xda, 0xe4, 0x4a, 0x6e, 0xc7, 0xc4, 0xff, 0x94, 0xe4, 0x46, 0xac, 0xf1, 0xa1, 0x8b, 0xdd, 0x54, 0xe0, 0xac, 0xd7, 0x1f, 0x76, 0x3c, 0xa6, 0x8f, 0x24, 0x37, 0xc1, 0xd2, 0xa6, 0xa4, 0x95, 0xdd, 0x53, 0x28, 0x5d, 0xb4, 0x89, 0xfd, 0x8f, 0x16, 0xa1, 0x9d, 0x5a, 0x1a, 0x7c, 0xda, 0x50, 0xa0, 0x33, 0x3e, 0x9b, 0x1a, 0x33, 0xa6, 0x4a, 0xc0, 0xfa, 0x14, 0xbf, 0xb9, 0x24, 0xa0, 0x99, 0x64, 0xb8, 0x9d, 0xb1, 0xfb, 0x98, 0xc9, 0xcf, 0xac, 0x7b, 0xcb, 0x9e, 0x85, 0x6f, 0x1e, 0xb3, 0x56, 0x33, 0xaf, 0x68, 0x42, 0xd9, 0xf7, 0x0c, 0x79, 0x2b, 0xfe, 0x61, 0x14, 0xa6, 0x59, 0x8c, 0x72, 0x97, 0xb3, 0x5e, 0x4e, 0xce, 0x25, 0xea, 0x1c, 0x09, 0x40, 0x1e, 0xfc, 0x6b, 0x31, 0xf1, 0xe3, 0x43, 0x10, 0xe4, 0x3b, 0x66, 0xa3, 0xde, 0x3b, 0xcc, 0x94, 0x5f, 0x97, 0xfd, 0xb6, 0x5a, 0x69, 0x9d, 0x28, 0xc9, 0xf0, 0xc9, 0x19, 0xd0, 0xe5, 0x52, 0xb9, 0x2b, 0x2d, 0xac, 0x15, 0xe3, 0x14, 0x3d, 0xea, 0x32, 0xc5, 0x49, 0x8e, 0x7f, 0xfc, 0x26, 0xe8, 0xc9, 0xbc, 0x60, 0x2f, 0x7c, 0xc9, 0x42, 0xca, 0xfe, 0x81, 0xe1, 0x02, 0x08, 0x91, 0x03, 0xe4, 0xe6, 0xca, 0x00, 0xef, 0x06, 0x5b, 0x3e, 0x8a, 0x91, 0xc8, 0x0e, 0x3c, 0xa7, 0x94, 0x08, 0x4f, 0x09, 0x92, 0x98, 0xc8, 0x48, 0xb0, 0x2d, 0xf3, 0x95, 0xe7, 0x01, 0x83, 0xee, 0x90, 0xb0, 0xc7, 0xbf, 0x27, 0x77, 0xfc, 0x19, 0xaf, 0xb4, 0xc2, 0x36, 0xad, 0x95, 0xca, 0xab, 0xa9, 0xf1, 0x1a, 0xaa, 0xfc, 0x2e, 0x56, 0x8a, 0xd8, 0x97, 0x8e, 0x91, 0xd7, 0xee, 0x80, 0x85, 0x9d, 0x33, 0x6d, 0xa6, 0x3d, 0xcd, 0x78, 0xb1, 0xcb, 0x58, 0xdd, 0x43, 0x59, 0xd3, 0x6b, 0xaa, 0x34, 0xcc, 0x56, 0xd5, 0x09, 0x5f, 0x0c, 0x62, 0x53, 0xb2, 0x69, 0x3d, 0xcd, 0xe2, 0x5e, 0x21, 0xfa, 0x34, 0x1e, 0xa7, 0x35, 0x04, 0x8b, 0xfc, 0x45, 0x3b, 0x9a, 0x56, 0x61, 0x2d, 0x09, 0xe3, 0xdc, 0xa4, 0xf1, 0xb2, 0xb0, 0xdc, 0x48, 0xdb, 0x41, 0xb0, 0x9b, 0xef, 0x0e, 0x55, 0x02, 0x83, 0x5c, 0x97, 0xe3, 0x90, 0x4b, 0xdb, 0x81, 0x03, 0xc5, 0x60, 0x91, 0x9e, 0xf6, 0x80, 0x7c, 0x7e, 0xe4, 0xdf, 0x91, 0x1b, 0xcd, 0x71, 0x2d, 0xe5, 0xa6, 0x19, 0x95, 0x09, 0xfc, 0x9b, 0x82, 0x8e, 0x99, 0xde, 0x4c, 0x4d, 0x11, 0x87, 0x2b, 0x9a, 0x3d, 0xdc, 0xc8, 0xd3, 0x23, 0x35, 0x7d, 0x87, 0xbb, 0xcb, 0xbe, 0x89, 0x7a, 0x8e, 0xa8, 0x84, 0x6e, 0xcf, 0x4d, 0x2f, 0x1f, 0xd1, 0xfb, 0x65, 0x4f, 0x58, 0xc1, 0xa3, 0xa7, 0x5c, 0x71, 0x8a, 0x01, 0x98, 0xee, 0x99, 0xd1, 0xde, 0xac, 0xd9, 0x1c, 0x23, 0x70, 0x88, 0x28, 0x83, 0x3b, 0x13, 0xd1, 0xc8, 0x87, 0x31, 0xe5, 0xdf, 0x56, 0x71, 0xa7, 0x81, 0xe7, 0x82, 0x25, 0x9e, 0x95, 0xb8, 0xc9, 0x8c, 0x82, 0xc6, 0xc7, 0x29, 0x80, 0xa1, 0xa6, 0x90, 0x5e, 0xbc, 0x2e, 0x13, 0x49, 0x51, 0x94, 0x67, 0x48, 0xd8, 0x54, 0x05, 0xe9, 0xe5, 0x0b, 0x48, 0xcf, 0x7e, 0x7e, 0x17, 0x7e, 0x05, 0xa0, 0x2f, 0x92, 0xbe, 0xd0, 0x28, 0xae, 0xac, 0x65, 0xae, 0x4b, 0x61, 0x6f, 0x37, 0x2e, 0xd8, 0xb2, 0x54, 0xe6, 0xfd, 0x9d, 0x03, 0x70, 0xcf, 0xb9, 0x29, 0xe7, 0x8c, 0xef, 0x4a, 0xf2, 0xcf, 0xd9, 0x85, 0xfe, 0xf1, 0x69, 0x60, 0x98, 0xe0, 0x0d, 0x87, 0xe0, 0x04, 0x70, 0x53, 0xeb, 0x90, 0x26, 0x7a, 0xa5, 0x57, 0x3a, 0x96, 0x84, 0x0e, 0x60, 0x73, 0x9f, 0x37, 0x0c, 0xb1, 0x4e, 0xc5, 0x29, 0xbe, 0x32, 0x1b, 0x6e, 0xed, 0xdc, 0x28, 0xa2, 0x48, 0x57, 0x3b, 0x78, 0x10, 0xbf, 0x98, 0x39, 0x91, 0x58, 0x35, 0xc4, 0x21, 0x48, 0x13, 0xf1, 0xc3, 0x63, 0xa4, 0x63, 0x97, 0x66, 0x49, 0x6b, 0x32, 0x4c, 0xe5, 0x1b, 0xd8, 0x50, 0xd2, 0x44, 0x91, 0x26, 0xe2, 0x2d, 0x04, 0xab, 0x52, 0x67, 0xe3, 0x8f, 0x29, 0x1c, 0x04, 0x4f, 0xc7, 0xc0, 0xa2, 0x19, 0xb0, 0x87, 0xdd, 0x50, 0xe7, 0xa8, 0xdb, 0x86, 0x78, 0xa4, 0x78, 0x6d, 0xc9, 0xd0, 0x88, 0x69, 0x87, 0xaf, 0xa4, 0x95, 0x61, 0x61, 0xdb, 0x83, 0x94, 0x53, 0xa6, 0xb4, 0xb2, 0x52, 0x24, 0xca, 0x83, 0x5f, 0x14, 0x16, 0xc7, 0x98, 0x51, 0xb5, 0x20, 0xb0, 0xc8, 0xb7, 0xdb, 0xd3, 0xd0, 0x95, 0xce, 0x0d, 0xef, 0xd4, 0x1e, 0x10, 0x8d, 0x8d, 0x8f, 0xb1, 0x12, 0x55, 0x03, 0xd8, 0x64, 0x0b, 0x14, 0xa8, 0xc8, 0x6f, 0x48, 0x47, 0x69, 0x46, 0x96, 0x81, 0xbe, 0xed, 0xf2, 0x39, 0x87, 0x71, 0xc7, 0x95, 0xf8, 0xb1, 0x4c, 0xd9, 0x07, 0xfa, 0x35, 0x93, 0xba, 0x09, 0x70, 0x79, 0xdf, 0x1f, 0x78, 0x8b, 0x12, 0x26, 0x06, 0x1d, 0x8e, 0xf0, 0x16, 0x8a, 0x18, 0xd9, 0xd8, 0xd3, 0x9a, 0x50, 0x76, 0x61, 0x22, 0xdd, 0x87, 0x3d, 0x4c, 0x5a, 0xdf, 0xe3, 0xe9, 0x47, 0x98, 0x5c, 0xac, 0x7a, 0x65, 0x55, 0xb5, 0xd7, 0xd5, 0xe3, 0x2b, 0x7b, 0x26, 0xa9, 0xce, 0xcc, 0x7c, 0x21, 0x8f, 0x7c, 0xcf, 0x28, 0x7e, 0x59, 0xfa, 0x8e, 0xb7, 0xee, 0x60, 0xda, 0x7b, 0xae, 0x73, 0xbe, 0x03, 0xb8, 0x8d, 0xab, 0xa2, 0x0a, 0x55, 0x27, 0xaf, 0x59, 0x96, 0xa0, 0xa5, 0xb4, 0xf0, 0xbc, 0xf8, 0xbe, 0xa6, 0x9d, 0x9b, 0x12, 0xd5, 0x03, 0xfa, 0x38, 0x4b, 0x00, 0x14, 0x4f, 0xe0, 0xe7, 0x49, 0x06, 0x83, 0x96, 0x60, 0x53, 0xe9, 0x08, 0x66, 0xb2, 0x3d, 0x4d, 0xf1, 0x65, 0x51, 0x09, 0x1c, 0x0c, 0x2a, 0x6f, 0xc8, 0x76, 0x3a, 0x4c, 0x98, 0x08, 0x3b, 0x1e, 0xd3, 0x8d, 0x6c, 0x2e, 0xd4, 0xf6, 0x4b, 0x1c, 0xba, 0xfc, 0x75, 0x94, 0xee, 0x1b, 0xa1, 0xa3, 0x9a, 0xa5, 0x57, 0xbc, 0x7e, 0xdb, 0xef, 0x81, 0x65, 0x39, 0x2f, 0x5f, 0x1e, 0x42, 0x5b, 0xb4, 0xe4, 0xf1, 0x46, 0x92, 0x3f, 0x86, 0x89, 0x24, 0xdd, 0x4b, 0x18, 0x49, 0x76, 0xfc, 0x65, 0xbf, 0xe7, 0x11, 0x8a, 0xb8, 0x78, 0xd6, 0x40, 0xe4, 0xd4, 0xc1, 0x8e, 0xa9, 0xe2, 0xb4, 0x9c, 0x8e, 0x7a, 0xcb, 0xca, 0x39, 0x2a, 0xf6, 0x17, 0x0e, 0x69, 0x91, 0xc1, 0x83, 0x1a, 0xe3, 0xfd, 0x49, 0xc1, 0x1f, 0x17, 0xc6, 0xf6, 0x6b, 0x20, 0x86, 0xea, 0xf2, 0x35, 0xaf, 0xf5, 0x3e, 0xd9, 0x11, 0x14, 0xf9, 0x3f, 0x46, 0x71, 0x2a, 0x47, 0x7b, 0xeb, 0xf3, 0xd5, 0xe6, 0x3e, 0xd0, 0xdc, 0xd3, 0x3e, 0x32, 0x82, 0x3d, 0xf2, 0xb8, 0x91, 0xfc, 0xa9, 0x54, 0x43, 0x6a, 0x6f, 0x68, 0xb4, 0x75, 0x49, 0x7f, 0x3e, 0xb9, 0x4e, 0x88, 0x4e, 0xb3, 0xf5, 0xd3, 0x91, 0x21, 0xde, 0xf8, 0x75, 0xd6, 0xed, 0x6c, 0xa0, 0x2c, 0x3a, 0x26, 0x5c, 0xea, 0x82, 0x9d, 0x6c, 0x25, 0x1b, 0x93, 0x64, 0x74, 0x8e, 0xca, 0x8e, 0x1f, 0xba, 0x6d, 0x6c, 0x08, 0xae, 0x42, 0xba, 0x1f, 0x0a, 0x8c, 0xa0, 0x66, 0xd4, 0xda, 0x44, 0x48, 0x29, 0x78, 0x6b, 0xdb, 0x2a, 0x2b, 0xbf, 0x32, 0xd9, 0xb5, 0xf1, 0xf9, 0xc0, 0x78, 0x7b, 0x4a, 0x1f, 0xd8, 0xff, 0xa7, 0xdc, 0x20, 0x1a, 0x69, 0x1c, 0x97, 0x77, 0x49, 0x21, 0x83, 0xf1, 0xb2, 0x5b, 0xfb, 0x4b, 0xb0, 0x7e, 0x32, 0xae, 0x47, 0xb5, 0x2b, 0x3e, 0x34, 0x62, 0xce, 0x5c, 0x37, 0x85, 0x3f, 0x51, 0x4b, 0xa9, 0x98, 0x1f, 0x18, 0x8d, 0xfa, 0x7f, 0x81, 0x70, 0x50, 0x97, 0x48, 0xa7, 0xec, 0x6b, 0xd4, 0xf0, 0x1c, 0x16, 0xfd, 0x54, 0xdc, 0x5d, 0x39, 0x2a, 0x6f, 0x6b, 0x02, 0x75, 0xbb, 0x7b, 0x24, 0xe9, 0xa7, 0xc4, 0xd8, 0xd4, 0x00, 0xbb, 0x8f, 0x17, 0x82, 0x87, 0x06, 0x55, 0x11, 0xd4, 0xd9, 0x95, 0x03, 0x84, 0x13, 0xec, 0xf7, 0x60, 0x30, 0xb5, 0xf1, 0xcb, 0x4b, 0xa7, 0x60, 0xd4, 0x4f, 0x4c, 0xfd, 0x37, 0x3b, 0x13, 0x89, 0xc2, 0x95, 0xbe, 0x90, 0xf8, 0x00, 0x7e, 0xcb, 0x24, 0x1e, 0xd9, 0x54, 0x73, 0x7f, 0x1e, 0xdc, 0x6c, 0x27, 0x57, 0x39, 0x2b, 0x94, 0x03, 0x41, 0x4b, 0xeb, 0xa7, 0x2b, 0x03, 0xd6, 0xf4, 0xb2, 0xc4, 0x3f, 0xa1, 0x60, 0x2d, 0x76, 0xa3, 0x43, 0x1f, 0x7c, 0xfe, 0x0e, 0x2f, 0x07, 0xb0, 0x4f, 0x7e, 0xd8, 0xca, 0x9f, 0xcb, 0xec, 0x32, 0x77, 0xce, 0x67, 0xcf, 0x06, 0xbd, 0xd1, 0xe4, 0x3c, 0x24, 0x6e, 0x9e, 0x82, 0x7a, 0x4c, 0xa9, 0xa2, 0xd5, 0xe5, 0xe7, 0x8c, 0x94, 0x1f, 0x6b, 0x1a, 0xf8, 0x2b, 0x31, 0xb1, 0x87, 0xbd, 0xd3, 0x76, 0x0d, 0x41, 0xeb, 0x72, 0x0a, 0xd0, 0x15, 0xad, 0x74, 0x16, 0xb8, 0x53, 0x79, 0xd6, 0xf9, 0xa7, 0x67, 0x6d, 0x0d, 0x22, 0xc2, 0xe2, 0x7c, 0xb6, 0xbc, 0x06, 0x77, 0xe9, 0x1e, 0xcb, 0xd2, 0xfa, 0xfd, 0x68, 0x57, 0x3e, 0x22, 0x5c, 0xe9, 0xe4, 0x61, 0x12, 0xd0, 0x9f, 0xfa, 0x38, 0x31, 0x5f, 0x40, 0xe2, 0x3d, 0xbe, 0x39, 0xff, 0x02, 0x78, 0x31, 0xa4, 0x39, 0xc4, 0xe2, 0xcc, 0x3c, 0xde, 0x8b, 0x24, 0x89, 0x8c, 0xba, 0x3f, 0x2f, 0x1a, 0x23, 0x1c, 0x27, 0x38, 0x34, 0xeb, 0x7a, 0x99, 0x0b, 0x61, 0x2c, 0x6a, 0xd8, 0xe8, 0xcd, 0x64, 0xce, 0x9d, 0x63, 0x31, 0xb0, 0xad, 0xdf, 0x0b, 0x81, 0xcc, 0x78, 0x5b, 0x3f, 0xa7, 0x52, 0x92, 0x5d, 0xf0, 0xd4, 0xed, 0x6f, 0xb1, 0xc3, 0x37, 0xde, 0x57, 0x05, 0xd6, 0xdd, 0x10, 0x14, 0x7c, 0x00, 0xde, 0x08, 0x54, 0x8f, 0x07, 0xb5, 0xd7, 0x8d, 0x1f, 0x5f, 0x6f, 0x5f, 0x27, 0x3c, 0x80, 0xd5, 0xfa, 0xdb, 0x26, 0x0f, 0x63, 0xda, 0x1c, 0xf4, 0xb7, 0x36, 0xc1, 0x1c, 0x79, 0x9d, 0xe3, 0xbd, 0xae, 0x3f, 0xfb, 0x41, 0xe2, 0x41, 0xe8, 0xa9, 0x6e, 0x01, 0x16, 0x59, 0xf0, 0x1c, 0x2b, 0x25, 0xc7, 0x05, 0xc6, 0x72, 0x51, 0x40, 0x4d, 0xa1, 0x2e, 0x31, 0xbf, 0xd9, 0x13, 0x4f, 0x9d, 0x6b, 0xce, 0xfb, 0x4a, 0xb1, 0xb5, 0xfa, 0x1f, 0x94, 0x88, 0x07, 0x43, 0x48, 0x12, 0x63, 0x40, 0x24, 0xaf, 0xfd, 0x67, 0x50, 0x21, 0xc9, 0xf0, 0x3f, 0xaa, 0xeb, 0xb1, 0xcf, 0x48, 0x2d, 0x93, 0x92, 0xfd, 0xdf, 0x21, 0xb1, 0xda, 0xa1, 0x26, 0xca, 0x9d, 0x76, 0xc1, 0xab, 0x01, 0x76, 0x7b, 0x5e, 0x08, 0xa7, 0xd1, 0x1f, 0x1c, 0x89, 0x50, 0x25, 0x39, 0x0e, 0xa5, 0x04, 0x1c, 0x13, 0xf6, 0x21, 0x6e, 0xbe, 0x6f, 0xc9, 0x6e, 0x6c, 0x84, 0xa1, 0x41, 0xdd, 0xa3, 0x95, 0x65, 0x50, 0xcf, 0xca, 0xac, 0x1a, 0xa3, 0x4d, 0x86, 0x12, 0x23, 0x5b, 0x3a, 0xaa, 0x43, 0xac, 0x04, 0x43, 0x81, 0x77, 0xa8, 0x59, 0xf8, 0x0f, 0xb9, 0x33, 0xd9, 0x24, 0x18, 0x3b, 0x53, 0xea, 0x97, 0x88, 0x30, 0x84, 0xb0, 0x72, 0x5b, 0x49, 0x6d, 0x27, 0xbe, 0x14, 0x71, 0x5a, 0xf2, 0x9d, 0x21, 0xae, 0xc2, 0xf6, 0x37, 0x31, 0xd1, 0xba, 0x66, 0x58, 0xfe, 0xf9, 0x31, 0x3e, 0x51, 0x95, 0xd4, 0x8f, 0x27, 0x7f, 0x91, 0xeb, 0xe6, 0x94, 0x16, 0xb6, 0x0e, 0x2e, 0x28, 0x9f, 0x8d, 0x2e, 0x47, 0x37, 0x01, 0x9c, 0x60, 0x16, 0xc1, 0xd6, 0x06, 0xfc, 0x59, 0x55, 0x1d, 0x2e, 0xbf, 0x62, 0x72, 0xc3, 0xaa, 0x18, 0x5e, 0x97, 0x33, 0x61, 0x8a, 0x8a, 0xa0, 0xdd, 0x4a, 0x41, 0x4e, 0x72, 0xf9, 0x98, 0xbf, 0xc7, 0x06, 0xbb, 0x35, 0x61, 0x48, 0x60, 0xdf, 0xa1, 0xba, 0xcf, 0x25, 0x4a, 0x09, 0x3b, 0xff, 0xd6, 0xf1, 0xc0, 0xc7, 0xa3, 0x2e, 0x50, 0x3e, 0x07, 0xb7, 0x02, 0x29, 0xbd, 0x69, 0x70, 0xd7, 0xa5, 0xc4, 0xda, 0x7a, 0xc5, 0xdb, 0x0c, 0x2e, 0xde, 0xc7, 0x4d, 0x57, 0x93, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x02, 0xe4, 0x61, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xe0, 0x07, 0xec, 0x81, 0x00, 0x00, 0x48, 0x7d, 0x43, 0xe1, 0xdb, 0x54, 0x90, 0x90, 0x65, 0x1f, 0xe2, 0xac, 0x42, 0x11, 0xbc, 0x94, 0x4c, 0xa0, 0x08, 0x07, 0x9e, 0x23, 0x7d, 0x4f, 0x8b, 0xe8, 0x12, 0x1c, 0x18, 0xbb, 0x03, 0x67, 0x80, 0x32, 0x88, 0x98, 0x45, 0x91, 0xb1, 0x4a, 0x0f, 0xca, 0x75, 0xf8, 0x03, 0x59, 0x88, 0x96, 0x5a, 0x37, 0xf3, 0xd1, 0xe0, 0x0d, 0x27, 0x07, 0x66, 0x0c, 0xe5, 0x75, 0x2d, 0x29, 0x88, 0xfc, 0xc4, 0x71, 0x0a, 0xd0, 0x78, 0xab, 0xb1, 0x96, 0xca, 0x3f, 0xa5, 0x71, 0x15, 0xc7, 0x16, 0x2e, 0xd6, 0xf4, 0x10, 0x42, 0xf0, 0x28, 0x8d, 0xba, 0xae, 0x36, 0xcc, 0x72, 0xe1, 0x78, 0x40, 0xb1, 0x6d, 0xc9, 0x4b, 0x21, 0x8d, 0xc1, 0xa6, 0x66, 0x4d, 0xa3, 0x4e, 0x4e, 0xc1, 0x0c, 0x6f, 0x54, 0xe3, 0xb8, 0xab, 0x1b, 0xc5, 0xe3, 0x58, 0x9c, 0xbd, 0x89, 0xfb, 0xca, 0xaa, 0x65, 0x2b, 0xf9, 0x7e, 0x59, 0x08, 0xde, 0xb9, 0xc9, 0xde, 0x56, 0x72, 0x61, 0xba, 0xe2, 0x9f, 0x4a, 0x02, 0x03, 0x86, 0xa2, 0x96, 0x33, 0xf8, 0x52, 0xc6, 0xf3, 0x05, 0xb7, 0x80, 0x74, 0xeb, 0x05, 0x6d, 0x07, 0x07, 0x44, 0x2f, 0xf7, 0xc2, 0xf5, 0xd7, 0x20, 0x3a, 0xbb, 0x07, 0x13, 0x70, 0xcc, 0xb1, 0x76, 0x51, 0x4d, 0xfc, 0x33, 0xf4, 0x60, 0x09, 0xf8, 0x47, 0xc8, 0xde, 0x4e, 0x7c, 0x2b, 0x0a, 0x59, 0x9a, 0x89, 0x9c, 0x56, 0x6c, 0xd8, 0x3d, 0x85, 0x8e, 0xa3, 0xe4, 0x20, 0x13, 0xf9, 0xf0, 0x84, 0x4b, 0x51, 0x4e, 0x75, 0xbd, 0xac, 0xd8, 0x5b, 0x04, 0x4b, 0x2e, 0xbe, 0xf3, 0xb7, 0xa3, 0x0a, 0xe2, 0x14, 0x4e, 0xc5, 0xc7, 0x30, 0xc0, 0xe1, 0xab, 0x2c, 0x9d, 0xec, 0x74, 0x64, 0x83, 0x19, 0x6c, 0x05, 0x81, 0x5c, 0x89, 0xf5, 0x99, 0xa2, 0x8b, 0x8b, 0x86, 0x9f, 0xcf, 0xb3, 0x3f, 0xcf, 0x1a, 0x12, 0x49, 0xc6, 0xa6, 0xaa, 0x5c, 0x60, 0x06, 0x99, 0x97, 0x1e, 0x6f, 0x65, 0xe6, 0x91, 0x51, 0x0b, 0x76, 0xca, 0x14, 0x05, 0x37, 0x77, 0x7f, 0x9c, 0x0e, 0xc9, 0x15, 0x05, 0xd7, 0xd9, 0x52, 0x16, 0x68, 0x41, 0x27, 0xb4, 0x95, 0xe1, 0xf1, 0xe6, 0x35, 0x66, 0x0f, 0x26, 0xc5, 0x42, 0xde, 0xab, 0xa8, 0x34, 0x16, 0xb1, 0x4e, 0x7c, 0x5a, 0xc1, 0xe7, 0x29, 0x5b, 0x32, 0x44, 0x3d, 0xea, 0xa0, 0x59, 0xf6, 0xa9, 0x7a, 0x94, 0x9f, 0x14, 0x0c, 0xc5, 0x75, 0xc7, 0x94, 0xfc, 0xcf, 0xd7, 0x0c, 0xe6, 0x1b, 0x79, 0x9b, 0x9e, 0x25, 0xfd, 0x0e, 0xa1, 0xe3, 0xb7, 0xf4, 0x35, 0x71, 0x7e, 0xd0, 0x18, 0x50, 0x07, 0xf6, 0xe8, 0xf5, 0x82, 0x29, 0xd6, 0x47, 0xa8, 0x4f, 0xa7, 0xd0, 0xcb, 0x87, 0x60, 0xdb, 0x7a, 0xe8, 0x7b, 0x30, 0xbc, 0xeb, 0x43, 0x81, 0x9f, 0x1e, 0x1b, 0xec, 0xef, 0x0e, 0x52, 0x9b, 0xd8, 0x5d, 0xb5, 0x45, 0x3e, 0x35, 0x33, 0xc7, 0x99, 0x7b, 0xdb, 0x12, 0xb9, 0x92, 0xa7, 0xd6, 0xb3, 0xf1, 0x7e, 0x53, 0x61, 0x40, 0x1f, 0xf2, 0x48, 0x45, 0xc3, 0x9f, 0xbe, 0x1f, 0xb8, 0x24, 0x2b, 0xa3, 0xcb, 0x0d, 0xbf, 0xe5, 0xb0, 0x1a, 0x0a, 0xc0, 0xd8, 0x68, 0x51, 0x1e, 0x06, 0xfe, 0xad, 0x88, 0x0f, 0xd3, 0xe5, 0x49, 0x9e, 0xf6, 0x79, 0x21, 0x68, 0x98, 0xda, 0x23, 0x5b, 0x55, 0xd9, 0xba, 0xd9, 0xa4, 0x6a, 0x47, 0x46, 0x3d, 0xbc, 0xd7, 0xdb, 0xa6, 0x95, 0x8a, 0x24, 0xc8, 0x52, 0x95, 0xfd, 0xcd, 0xf2, 0x71, 0x8c, 0x60, 0x7e, 0x60, 0xa4, 0xe4, 0xe0, 0x42, 0x25, 0x2c, 0x33, 0x5a, 0x94, 0x87, 0xd0, 0x95, 0x00, 0xd8, 0xd1, 0xa2, 0x85, 0xa5, 0x04, 0xd6, 0x61, 0xb3, 0x3b, 0xa1, 0x01, 0xb1, 0xe8, 0x1d, 0xd0, 0x1b, 0xf1, 0xbc, 0xda, 0xe7, 0xa9, 0x07, 0x58, 0xd5, 0x82, 0x68, 0x09, 0x1a, 0xe3, 0xb4, 0x1e, 0x98, 0x8b, 0xce, 0xe1, 0x73, 0xf2, 0x5e, 0xa8, 0xe7, 0xa3, 0x66, 0xb1, 0x47, 0x61, 0x56, 0x70, 0x90, 0xb2, 0xe0, 0x39, 0x24, 0x7f, 0x02, 0x73, 0x65, 0x0d, 0x0f, 0x51, 0x93, 0x22, 0x82, 0x20, 0xd1, 0xdd, 0x4c, 0x3e, 0xe8, 0xf6, 0xe1, 0x16, 0x58, 0xaf, 0x1f, 0x03, 0xd5, 0x8b, 0x28, 0x2d, 0x19, 0x74, 0x28, 0xe5, 0xbc, 0x76, 0xb2, 0x0e, 0xb5, 0xb4, 0x69, 0x5b, 0xf4, 0x87, 0x5a, 0xd9, 0xcd, 0x9f, 0xf4, 0xe0, 0xfc, 0x92, 0xf2, 0x16, 0x34, 0x9a, 0xc7, 0x36, 0x62, 0xff, 0x47, 0x19, 0x11, 0x02, 0x45, 0x67, 0xfa, 0xec, 0x45, 0xf0, 0xaf, 0x5b, 0x85, 0x21, 0x10, 0x49, 0xcc, 0x1b, 0xeb, 0x60, 0x02, 0x89, 0x52, 0x06, 0xf7, 0x72, 0xeb, 0xd2, 0xf6, 0x69, 0x44, 0xe4, 0xbe, 0xc0, 0x46, 0x16, 0xf7, 0x61, 0x55, 0x0b, 0x15, 0x61, 0x37, 0x4a, 0x7e, 0x1e, 0xa5, 0xd3, 0xe7, 0xab, 0x13, 0xca, 0xab, 0x33, 0x13, 0x77, 0x25, 0x9e, 0x2e, 0xf1, 0xe2, 0x00, 0x9c, 0x17, 0x38, 0x65, 0xb1, 0x49, 0x34, 0xea, 0xd8, 0x28, 0x3d, 0x6f, 0xc3, 0x6d, 0xc6, 0x9e, 0xdc, 0xe3, 0x28, 0xae, 0xe4, 0xf2, 0x2b, 0x6e, 0x78, 0x0b, 0x78, 0x09, 0xdb, 0x76, 0x56, 0x98, 0x8e, 0x71, 0xb4, 0x09, 0x76, 0x72, 0xd0, 0xfe, 0x3a, 0x5c, 0x6f, 0x0f, 0x30, 0x68, 0xb5, 0x14, 0x84, 0x83, 0xfc, 0xd4, 0x65, 0x92, 0x35, 0xec, 0x32, 0xbd, 0xb7, 0x76, 0x5f, 0xa9, 0x51, 0x61, 0x54, 0x00, 0x69, 0x67, 0x2f, 0x74, 0x2c, 0x42, 0xf6, 0xed, 0x17, 0x0d, 0x40, 0x43, 0x68, 0xcf, 0x66, 0xb2, 0x98, 0x36, 0x99, 0x2a, 0x72, 0x69, 0xff, 0x4c, 0xa4, 0x71, 0x69, 0xf3, 0x62, 0xb5, 0x21, 0xac, 0x9f, 0x7c, 0x5e, 0x15, 0x95, 0xd4, 0xbb, 0xa1, 0x5b, 0xc8, 0x73, 0x9a, 0x1f, 0xdb, 0x57, 0x7e, 0x3e, 0x9e, 0x80, 0x99, 0xab, 0xb6, 0xd4, 0x9f, 0xf0, 0xaf, 0x95, 0x2b, 0xf6, 0x39, 0x41, 0xb1, 0x77, 0x53, 0x45, 0xc7, 0x66, 0x17, 0xa9, 0xce, 0xac, 0xd5, 0xa9, 0xcf, 0xc3, 0x9e, 0x51, 0xe0, 0x5b, 0x1a, 0x84, 0xbe, 0xcd, 0xc7, 0xa6, 0x56, 0x29, 0x05, 0x57, 0x3a, 0xfe, 0xf1, 0x6f, 0x3e, 0xc6, 0x02, 0x2b, 0xbe, 0xd9, 0xa8, 0xa3, 0x6e, 0x0e, 0xe1, 0x86, 0x3a, 0xdc, 0x9a, 0x81, 0x71, 0xd8, 0x1d, 0xb4, 0xd7, 0xf0, 0xd7, 0x20, 0x45, 0x41, 0x79, 0xe3, 0x1c, 0xe1, 0x80, 0xb4, 0xb1, 0x11, 0xab, 0x25, 0xdd, 0xb5, 0x4e, 0x75, 0x29, 0x40, 0xcf, 0x83, 0x81, 0xd8, 0x28, 0x07, 0x36, 0x9c, 0xa8, 0x9c, 0x77, 0x6d, 0x77, 0x5f, 0xc6, 0x70, 0xf3, 0x5a, 0x95, 0x04, 0x1f, 0x13, 0x1d, 0x14, 0xad, 0xa5, 0xb9, 0x9c, 0xcb, 0xdf, 0xda, 0xe1, 0x71, 0xb4, 0x08, 0x26, 0x2b, 0x4e, 0x44, 0xd7, 0x0d, 0x7c, 0xfb, 0xb9, 0x1a, 0xab, 0xb3, 0xab, 0x03, 0x01, 0xda, 0xb1, 0x99, 0x15, 0x23, 0x8e, 0xaa, 0x46, 0x3f, 0x93, 0x36, 0xb6, 0x94, 0x96, 0x0e, 0x6e, 0x92, 0x70, 0x3c, 0x27, 0xf8, 0x7e, 0x89, 0xfa, 0xcd, 0x2d, 0xa8, 0xf0, 0xb7, 0x81, 0x38, 0x54, 0xac, 0xca, 0xec, 0xc0, 0x3b, 0x51, 0x7f, 0x86, 0xb7, 0xa3, 0x03, 0x0c, 0x71, 0xf4, 0xa3, 0x8d, 0x4a, 0x73, 0x03, 0x81, 0xe8, 0x5c, 0x20, 0x39, 0x97, 0xbd, 0x1b, 0x05, 0xcc, 0xe0, 0x9d, 0x7e, 0x7b, 0x48, 0x7e, 0xdb, 0x39, 0xdf, 0xe6, 0xf2, 0xc4, 0x45, 0xf5, 0xe2, 0xc7, 0xb7, 0xe8, 0xb8, 0x1b, 0x50, 0xa3, 0xf5, 0xf4, 0xb1, 0x81, 0x60, 0xbd, 0x69, 0x20, 0x6e, 0x63, 0xa3, 0x80, 0xe6, 0x54, 0x4b, 0x57, 0x93, 0x9d, 0x9e, 0xa2, 0x6a, 0xb4, 0x43, 0x6b, 0x02, 0xdd, 0x1d, 0xa0, 0xec, 0xe3, 0xa1, 0x3c, 0x64, 0x4d, 0xec, 0xf4, 0x33, 0x37, 0x5e, 0x24, 0x1e, 0x96, 0x42, 0x89, 0x86, 0x0b, 0x47, 0x88, 0xf1, 0x8a, 0xa9, 0x30, 0xb3, 0x54, 0xc1, 0xa7, 0x1f, 0x88, 0xb5, 0xac, 0xf7, 0x70, 0xfc, 0x00, 0x14, 0xd7, 0xdc, 0x43, 0x4e, 0xbd, 0x20, 0x1f, 0x55, 0x63, 0xb3, 0x04, 0xff, 0x01, 0x83, 0xcb, 0x37, 0x6b, 0xf7, 0x18, 0x81, 0x0c, 0xf3, 0x95, 0x0e, 0xe2, 0x1e, 0x2b, 0x55, 0x69, 0xbe, 0x05, 0x66, 0xe0, 0x8e, 0x67, 0x90, 0xe6, 0xcf, 0xb9, 0x1b, 0xa3, 0x83, 0x17, 0x43, 0xdb, 0x06, 0xe7, 0x38, 0x38, 0x69, 0x08, 0x8f, 0x82, 0xc0, 0xa7, 0x33, 0xdf, 0xf4, 0x84, 0xe0, 0x43, 0xd2, 0x20, 0x0d, 0xcf, 0x15, 0x63, 0x67, 0xa9, 0xe1, 0xb3, 0x9d, 0xe5, 0x5c, 0x90, 0xc3, 0x11, 0xfc, 0x4d, 0x88, 0x3c, 0x5e, 0x26, 0x57, 0x15, 0x3e, 0xcd, 0xce, 0x7b, 0xd3, 0xfd, 0x2d, 0x5e, 0x0c, 0x9e, 0x48, 0x9b, 0xb9, 0x20, 0x0f, 0x7a, 0xce, 0x92, 0x86, 0xc8, 0x50, 0xef, 0xa5, 0xe8, 0x84, 0x9a, 0xb5, 0x2b, 0xa5, 0x0e, 0xdc, 0x2c, 0x2c, 0x47, 0x68, 0x2a, 0x1c, 0xb9, 0x3c, 0x91, 0x24, 0x60, 0x24, 0xe7, 0xfd, 0x22, 0x78, 0xcd, 0x64, 0x3e, 0x05, 0xb9, 0x4f, 0x28, 0x98, 0x4b, 0x83, 0x73, 0x81, 0x21, 0x00, 0xea, 0x33, 0x03, 0x7e, 0xe2, 0x6c, 0x22, 0xac, 0x71, 0xcc, 0x38, 0x6f, 0xdd, 0x93, 0xd0, 0xef, 0x27, 0x6e, 0xb8, 0xf9, 0x15, 0x60, 0xfe, 0x59, 0x76, 0xb7, 0x30, 0x65, 0xaf, 0xdd, 0xc7, 0x89, 0x06, 0x15, 0x89, 0x82, 0x49, 0x2a, 0xcb, 0x9a, 0xda, 0xbe, 0x98, 0x74, 0xa4, 0x38, 0x41, 0xd0, 0x8e, 0x37, 0x59, 0x00, 0x82, 0x12, 0xec, 0xe1, 0x98, 0x6a, 0x7e, 0xc8, 0x19, 0xee, 0xba, 0xd2, 0xb3, 0xf3, 0x66, 0x75, 0xc4, 0xf6, 0x35, 0x80, 0xc2, 0x39, 0x04, 0xc2, 0x78, 0xde, 0xd9, 0xa7, 0x19, 0x4e, 0xb8, 0xc0, 0xf1, 0xda, 0x29, 0x01, 0xee, 0xd1, 0xda, 0xa4, 0xb0, 0xdd, 0x1e, 0x15, 0x90, 0x0d, 0x0d, 0x86, 0xd3, 0xb4, 0xf2, 0xf4, 0x3b, 0x05, 0x67, 0x8c, 0x39, 0x6f, 0xfe, 0x4b, 0xa5, 0xa1, 0x21, 0x24, 0x0f, 0x81, 0xf4, 0x3c, 0x38, 0xff, 0xd6, 0x0d, 0x26, 0xb5, 0x3f, 0xd8, 0x2b, 0xcd, 0x77, 0xe2, 0xab, 0xd0, 0xa6, 0xa4, 0x70, 0xfb, 0x2a, 0x8a, 0xbe, 0x07, 0x4e, 0x91, 0x6f, 0x3b, 0x1e, 0xe8, 0x13, 0xfa, 0xd3, 0xd6, 0xf6, 0x74, 0x67, 0xc9, 0xb1, 0xf1, 0x7f, 0x9a, 0xe8, 0xae, 0x0c, 0x1f, 0xa8, 0xf9, 0xcc, 0x34, 0x39, 0x04, 0x96, 0x28, 0x6b, 0x5e, 0xa9, 0x11, 0x37, 0xe1, 0xf5, 0x53, 0x40, 0x17, 0x40, 0xea, 0x99, 0x81, 0x93, 0x99, 0x4c, 0x6a, 0x78, 0x4d, 0x54, 0x4c, 0x6a, 0x66, 0x93, 0xf3, 0xe8, 0x8f, 0x8e, 0xfa, 0xd7, 0x13, 0x0f, 0xe8, 0xcc, 0x46, 0x3c, 0x92, 0x1a, 0xb3, 0x66, 0x15, 0x3b, 0x9d, 0xab, 0x81, 0x34, 0x6f, 0xac, 0x15, 0x62, 0x44, 0xa3, 0x67, 0x50, 0xa9, 0x77, 0x1d, 0x1e, 0x0f, 0xac, 0xb4, 0xcb, 0xaf, 0x29, 0xbc, 0x36, 0xfb, 0xdb, 0x5c, 0x83, 0x4b, 0x35, 0xd5, 0x77, 0x59, 0x0e, 0x21, 0x46, 0x57, 0x21, 0xb6, 0x1a, 0x10, 0xcb, 0xc1, 0x7a, 0x7f, 0x58, 0xfd, 0xe7, 0xaa, 0x5b, 0xcb, 0xa4, 0xdd, 0x2c, 0x12, 0x2d, 0xd2, 0xf3, 0x62, 0xda, 0xe7, 0x4e, 0x57, 0x34, 0xcf, 0x76, 0xf7, 0x01, 0x2f, 0x7b, 0xa1, 0x65, 0x02, 0x98, 0xad, 0xe2, 0xa2, 0x60, 0xf0, 0xf6, 0xed, 0x98, 0xcc, 0xc3, 0x33, 0x4f, 0x19, 0xf7, 0xee, 0x85, 0xd4, 0x26, 0x2c, 0x22, 0xb8, 0x34, 0xe6, 0xfe, 0xce, 0xec, 0x4d, 0x96, 0x87, 0x58, 0x83, 0xd5, 0x36, 0x04, 0x6d, 0x52, 0x60, 0x65, 0x0e, 0x31, 0x59, 0x53, 0xb7, 0x12, 0x06, 0x6b, 0x0a, 0xf6, 0x45, 0x56, 0x5e, 0xaf, 0x86, 0x17, 0xbc, 0x1b, 0x10, 0xc8, 0x04, 0x63, 0xe6, 0xf2, 0xa9, 0x55, 0xe5, 0x00, 0x16, 0xc8, 0x7c, 0x0e, 0xa2, 0x1a, 0x60, 0x94, 0xf8, 0x75, 0x5e, 0x08, 0x67, 0xcd, 0x3a, 0x84, 0x45, 0x88, 0x71, 0x45, 0x82, 0x93, 0x01, 0xd0, 0x80, 0x12, 0x02, 0x2c, 0x55, 0xe2, 0x70, 0x0c, 0x05, 0xdf, 0xff, 0xa3, 0x8e, 0x57, 0x1f, 0xbe, 0x01, 0x6b, 0x98, 0x40, 0xde, 0x60, 0xdb, 0x18, 0xa3, 0xe6, 0xfc, 0x79, 0x4e, 0xac, 0x04, 0x99, 0x8c, 0xca, 0xb2, 0x32, 0xc9, 0x51, 0x7c, 0x6f, 0x97, 0xca, 0x42, 0x4c, 0xd4, 0x07, 0x2b, 0x0c, 0x19, 0x69, 0x32, 0x1c, 0x86, 0xa2, 0x57, 0x6d, 0xbd, 0x0c, 0x6c, 0xd7, 0xb4, 0x24, 0xff, 0x63, 0x88, 0xe8, 0xef, 0x2b, 0x66, 0x63, 0xa8, 0xea, 0x4b, 0x27, 0x02, 0xac, 0x5b, 0x01, 0xa8, 0xdf, 0x9f, 0x5b, 0x8a, 0xf0, 0xaf, 0x60, 0x9b, 0xe4, 0x90, 0xd0, 0x90, 0x92, 0x6c, 0x5b, 0x9a, 0x0c, 0x03, 0x9f, 0xd7, 0x5d, 0x28, 0xfa, 0x27, 0xcb, 0x1d, 0x6b, 0x2b, 0x43, 0x50, 0x6b, 0xca, 0xd5, 0x1b, 0x41, 0x35, 0x59, 0x28, 0x97, 0x56, 0x2f, 0xa8, 0x03, 0x9a, 0xd9, 0x91, 0xff, 0x17, 0x32, 0x0b, 0x28, 0x49, 0x11, 0x37, 0x07, 0x05, 0xb3, 0x21, 0x51, 0xf3, 0x08, 0x81, 0x7a, 0xc1, 0x5d, 0x37, 0x40, 0xa5, 0xe8, 0x31, 0xcf, 0x85, 0x01, 0x3f, 0xa6, 0xff, 0xa4, 0x06, 0xcb, 0x8a, 0x8b, 0xd8, 0x18, 0xa7, 0x90, 0xaf, 0x81, 0x36, 0x4d, 0xdf, 0x81, 0xd9, 0xd0, 0x63, 0x61, 0x9e, 0xc8, 0x33, 0x5a, 0xd5, 0xc9, 0xaa, 0x66, 0xcb, 0x56, 0x57, 0xc5, 0x06, 0x71, 0x68, 0xbf, 0xe0, 0x1a, 0x8e, 0xf7, 0x7a, 0x02, 0xa9, 0x62, 0x43, 0xc0, 0xe7, 0x31, 0x7d, 0x27, 0xfe, 0xc6, 0xd9, 0xd5, 0xb4, 0xee, 0x0d, 0x50, 0x8a, 0x2a, 0xf4, 0xac, 0x9b, 0x78, 0x10, 0x0d, 0xc9, 0xef, 0x01, 0x84, 0x34, 0xd4, 0x0e, 0x7a, 0xfb, 0xc9, 0x1c, 0x13, 0x4e, 0xd6, 0x44, 0xd1, 0xed, 0x3c, 0xf4, 0x04, 0x15, 0xd0, 0x7a, 0xbc, 0x0f, 0x5c, 0x2d, 0xa6, 0x42, 0xaa, 0xdf, 0xfc, 0xde, 0x35, 0xf4, 0x7b, 0x38, 0x7f, 0xe3, 0x99, 0x72, 0x5f, 0x07, 0x33, 0x9f, 0x71, 0x73, 0x02, 0x2f, 0x5a, 0xba, 0x5a, 0xd3, 0x21, 0x42, 0x56, 0xf4, 0x52, 0x7d, 0x2a, 0xe7, 0x00, 0x23, 0xea, 0x76, 0xea, 0x2e, 0xb4, 0x89, 0xc5, 0x5a, 0x0d, 0x69, 0xa0, 0x0b, 0xad, 0x8e, 0xd5, 0x20, 0x23, 0x2d, 0xb0, 0xf8, 0x8e, 0xa2, 0x78, 0xc3, 0xea, 0xd4, 0x48, 0x4d, 0x66, 0x88, 0x83, 0xc1, 0xa6, 0x9f, 0xf7, 0x6d, 0x3d, 0x44, 0xce, 0x22, 0x4d, 0x4a, 0x43, 0xcd, 0x81, 0xa1, 0x06, 0xa9, 0x32, 0xfc, 0x47, 0x0c, 0x41, 0x5c, 0xa1, 0x74, 0x0e, 0x36, 0xd5, 0x9c, 0x93, 0x23, 0x0a, 0xdb, 0x15, 0x33, 0x6c, 0xa3, 0xa1, 0xa1, 0xf6, 0x7a, 0xbc, 0xe9, 0xa3, 0x5e, 0x83, 0x0a, 0xa1, 0x9a, 0xd7, 0xb5, 0x70, 0x78, 0xc5, 0xb1, 0xdf, 0x94, 0xf6, 0x16, 0xa4, 0x5e, 0xe6, 0x4b, 0xa6, 0x2e, 0x89, 0x7f, 0xb2, 0xde, 0x40, 0x50, 0x39, 0x8e, 0xf5, 0x52, 0x80, 0xbe, 0x56, 0x8f, 0x5e, 0x3e, 0xd0, 0x91, 0x82, 0x73, 0xf7, 0x9a, 0xe9, 0xef, 0x2a, 0x70, 0xe1, 0x5d, 0xbf, 0xf8, 0xca, 0x05, 0x0c, 0x20, 0xd8, 0xf9, 0xb7, 0x1f, 0xf9, 0xdf, 0xc8, 0x38, 0xd2, 0x21, 0x77, 0xd8, 0x2e, 0x6b, 0xda, 0x11, 0x7d, 0x01, 0xfa, 0x5d, 0x95, 0x44, 0x86, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x02, 0xe4, 0x61, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xe0, 0x07, 0xec, 0x81, 0x00, 0x00, 0xc4, 0x7a, 0x33, 0xf0, 0xf1, 0x4a, 0x5d, 0x7b, 0xe7, 0x1a, 0x12, 0xf2, 0x08, 0x12, 0xe6, 0x62, 0x45, 0x6b, 0x2e, 0x93, 0x7b, 0x50, 0x92, 0x1f, 0x9a, 0x78, 0x3c, 0x07, 0x79, 0xb9, 0x82, 0x19, 0xd8, 0x11, 0xfe, 0x50, 0x92, 0x8d, 0x73, 0x56, 0xea, 0xc3, 0x5c, 0xa3, 0x91, 0x81, 0x82, 0x45, 0xc7, 0x40, 0x35, 0xcf, 0xe3, 0x65, 0xa3, 0xbc, 0xf5, 0xe2, 0xc6, 0xc2, 0x05, 0xc0, 0xe3, 0x4d, 0x44, 0xc5, 0xa3, 0xd7, 0xea, 0x96, 0x0f, 0x34, 0xb2, 0x87, 0x35, 0xaa, 0x76, 0xb8, 0xe3, 0x3e, 0x97, 0x71, 0x5f, 0xbc, 0xc8, 0x27, 0x9e, 0x78, 0xbd, 0x1c, 0x0f, 0x04, 0x19, 0x0f, 0x1e, 0x42, 0x25, 0x98, 0xea, 0x68, 0x09, 0x1c, 0x6a, 0xb9, 0xb6, 0xe2, 0xec, 0x1d, 0x7d, 0xf7, 0xca, 0x9f, 0x24, 0xe1, 0x97, 0x2b, 0xb5, 0x1e, 0xc8, 0x2e, 0x8f, 0x98, 0x5f, 0xc2, 0x32, 0xe0, 0x39, 0xc7, 0xd9, 0xf9, 0x8d, 0x58, 0xae, 0xb5, 0x2e, 0xee, 0xda, 0xf7, 0x85, 0x28, 0x9b, 0x49, 0xb9, 0xd4, 0x62, 0x72, 0x54, 0x9a, 0xac, 0x78, 0x42, 0x58, 0xdd, 0x00, 0x42, 0x77, 0xd1, 0xc0, 0xdc, 0xc2, 0xdd, 0xe8, 0x43, 0x35, 0x5a, 0x69, 0xa8, 0x58, 0xe0, 0xe1, 0x11, 0xe7, 0x8a, 0xa8, 0x37, 0x4a, 0xbd, 0x79, 0x03, 0x17, 0x9e, 0xd8, 0xa5, 0x3f, 0x0d, 0x7e, 0x78, 0xf8, 0xa2, 0x50, 0x40, 0x82, 0x34, 0xf2, 0x95, 0x89, 0x72, 0x61, 0xd3, 0x2b, 0x33, 0x25, 0x90, 0x7f, 0xba, 0x74, 0xde, 0xed, 0x69, 0x71, 0x01, 0xad, 0x0a, 0x9b, 0x89, 0x03, 0xcc, 0x2a, 0x87, 0xfb, 0x55, 0x5c, 0xc3, 0xce, 0xd9, 0x3b, 0x59, 0x26, 0xa3, 0x57, 0x00, 0xb2, 0x81, 0x90, 0x26, 0x2f, 0x24, 0x8b, 0x83, 0xa7, 0x85, 0x76, 0xb8, 0xcd, 0xe1, 0x5c, 0xd4, 0xac, 0x38, 0x78, 0x19, 0x9a, 0xff, 0x3b, 0xa5, 0x68, 0x2c, 0x04, 0xed, 0xfd, 0x11, 0x28, 0xda, 0xdc, 0xf3, 0xf9, 0x43, 0x06, 0x8b, 0x76, 0xb4, 0xd2, 0xaf, 0xb2, 0x4f, 0x52, 0xa9, 0x40, 0xaf, 0x53, 0x1c, 0xac, 0xdb, 0x51, 0x82, 0xda, 0x7b, 0xba, 0x11, 0xef, 0x4f, 0xa3, 0x9c, 0x71, 0x7c, 0xd8, 0x9c, 0x22, 0x5c, 0x1f, 0x21, 0xbf, 0x42, 0xce, 0xce, 0x4b, 0x2a, 0xdb, 0x37, 0xaa, 0x6d, 0x71, 0x75, 0xf2, 0x84, 0x39, 0x3f, 0xac, 0x2e, 0xcd, 0xa2, 0x8e, 0xde, 0x90, 0x0d, 0xcb, 0x3c, 0x7b, 0x40, 0xa9, 0xc8, 0x2c, 0x1f, 0x45, 0x77, 0x04, 0xef, 0x7d, 0xfd, 0x42, 0x37, 0x06, 0x22, 0xc7, 0x13, 0x55, 0x17, 0x0b, 0xd7, 0xeb, 0xea, 0x29, 0x6e, 0x83, 0xa8, 0x09, 0xc8, 0x97, 0x27, 0x11, 0x4a, 0xd0, 0x92, 0xcf, 0x96, 0xf7, 0x38, 0x0f, 0x05, 0xe4, 0xe2, 0x8f, 0xc5, 0x4e, 0x26, 0xf6, 0x97, 0xf0, 0x49, 0x47, 0xe6, 0xf6, 0x38, 0x47, 0xc4, 0xf8, 0x33, 0x6b, 0x78, 0xca, 0x83, 0x4d, 0xbc, 0xaf, 0xf2, 0x08, 0xde, 0x9d, 0xcf, 0xb4, 0xe3, 0xc1, 0x8b, 0x17, 0x37, 0x3e, 0x08, 0x9f, 0x9b, 0x8b, 0xc7, 0x07, 0x84, 0x26, 0x04, 0xb6, 0x9d, 0x3d, 0x43, 0x7a, 0xf1, 0x4a, 0x92, 0xec, 0x21, 0xcc, 0x0c, 0xe5, 0x77, 0x29, 0xf1, 0x68, 0xd6, 0x5d, 0x19, 0x3f, 0x4f, 0xa3, 0x4c, 0x66, 0x60, 0x8f, 0xf4, 0x6e, 0x66, 0x87, 0xdd, 0x75, 0x80, 0x95, 0x77, 0xf1, 0xb7, 0x95, 0x82, 0xc1, 0xab, 0x3d, 0xa0, 0x65, 0xbb, 0xc3, 0xeb, 0xa2, 0x84, 0xa6, 0x6e, 0x4a, 0xf5, 0x52, 0x92, 0x35, 0x7b, 0xb1, 0x7d, 0xb0, 0x28, 0x34, 0xa1, 0x4e, 0x91, 0xcf, 0x9d, 0xea, 0x5c, 0x4e, 0xa5, 0xa8, 0xe1, 0x80, 0x35, 0x33, 0x0c, 0x15, 0x9a, 0x6a, 0xf3, 0x28, 0x14, 0x4d, 0x31, 0x52, 0x62, 0x70, 0x89, 0x8a, 0x78, 0x7a, 0x99, 0xa8, 0x64, 0x33, 0x24, 0xb5, 0xe1, 0x51, 0x78, 0x05, 0xb4, 0x27, 0xb4, 0xec, 0xe6, 0x53, 0x4d, 0x1f, 0x3b, 0x41, 0xb5, 0x04, 0x49, 0xe6, 0x1e, 0x1b, 0x2a, 0x7b, 0x88, 0x46, 0xf7, 0xc2, 0x57, 0xa2, 0x6a, 0x8b, 0xca, 0x95, 0x56, 0xf9, 0xf1, 0x27, 0x96, 0x57, 0xf1, 0x30, 0x41, 0x5e, 0x8e, 0x95, 0x5b, 0xc8, 0xd2, 0xbd, 0xe7, 0x2b, 0x39, 0x0a, 0xf3, 0xd9, 0xd0, 0xb0, 0xd7, 0x98, 0x24, 0xf5, 0xeb, 0x1d, 0xde, 0x1c, 0x89, 0xb9, 0x39, 0x0c, 0xd0, 0x54, 0xc8, 0xc2, 0x9d, 0x6c, 0x58, 0xb5, 0xcc, 0xc9, 0xfb, 0x43, 0x82, 0x70, 0x87, 0xe5, 0xae, 0xb3, 0x84, 0x21, 0x1e, 0x16, 0xce, 0xb2, 0xed, 0x08, 0xee, 0xee, 0xd1, 0x97, 0x8d, 0xd7, 0x27, 0x20, 0xe9, 0x61, 0x8d, 0x7a, 0x7e, 0xc8, 0x4c, 0xa8, 0x91, 0xfc, 0x7e, 0x8b, 0x44, 0xa1, 0xdd, 0x87, 0x61, 0x39, 0xc6, 0x85, 0x5d, 0xff, 0x32, 0x65, 0x23, 0x46, 0x8b, 0xe6, 0xaa, 0x62, 0x7c, 0x71, 0xca, 0x6e, 0xf5, 0xeb, 0xde, 0xb8, 0x98, 0x1f, 0x21, 0x6b, 0xe2, 0xe4, 0x1b, 0x2c, 0x25, 0x4b, 0x07, 0xae, 0x2d, 0x32, 0xf2, 0x53, 0x24, 0x11, 0xd5, 0xfd, 0x52, 0x49, 0x56, 0x6e, 0x60, 0xd0, 0x17, 0x3a, 0xa4, 0x5c, 0xda, 0x12, 0x49, 0x7c, 0x0d, 0xed, 0x0f, 0xce, 0xc0, 0x42, 0x01, 0xe9, 0x12, 0x13, 0x06, 0x62, 0x36, 0x69, 0x8a, 0xca, 0xdf, 0xda, 0x1a, 0xac, 0xc1, 0x4b, 0x12, 0xb2, 0xbd, 0xbd, 0x75, 0x60, 0x64, 0x83, 0x7d, 0xfb, 0x4c, 0xad, 0xad, 0x03, 0x7b, 0x01, 0x3e, 0x27, 0x26, 0x30, 0xb3, 0x22, 0x27, 0x44, 0x95, 0xe6, 0x82, 0xd0, 0xcd, 0x49, 0xfd, 0x6e, 0x0b, 0x8b, 0x24, 0xd7, 0x14, 0xf4, 0xc2, 0xf3, 0xb1, 0x2d, 0x66, 0xa6, 0x51, 0x4e, 0x12, 0xd6, 0x4f, 0x7e, 0xa8, 0x4d, 0x73, 0x5d, 0x9d, 0xe9, 0x29, 0xfe, 0xc2, 0xcb, 0x83, 0x1a, 0x03, 0x19, 0x91, 0xd8, 0x3d, 0x88, 0x5e, 0x35, 0xb9, 0x9a, 0x96, 0x0b, 0x3d, 0x3a, 0x1a, 0xc9, 0xa9, 0x03, 0x61, 0x18, 0xfd, 0xcf, 0x5c, 0x1c, 0x6d, 0xa5, 0x59, 0xe0, 0xcf, 0x1a, 0x08, 0x5a, 0xbf, 0xd7, 0x7d, 0x55, 0xc9, 0xd9, 0x50, 0x72, 0x2b, 0xad, 0xc6, 0xc5, 0x05, 0xb4, 0xad, 0x06, 0xf7, 0xda, 0xb0, 0xc0, 0xa2, 0x9b, 0xc2, 0xfd, 0xf9, 0x4a, 0xdf, 0x3f, 0x67, 0xde, 0x18, 0x2f, 0xe5, 0xc9, 0x62, 0x26, 0x5e, 0x69, 0xf4, 0x1b, 0x1d, 0x74, 0xa2, 0xcb, 0x9f, 0xde, 0xa8, 0xbb, 0xa9, 0xaa, 0xe5, 0xa8, 0x80, 0x5b, 0x16, 0x60, 0xaf, 0xe8, 0xee, 0x21, 0x5c, 0x17, 0x61, 0xa2, 0x1b, 0x1e, 0x63, 0xc7, 0x01, 0x71, 0x4c, 0x73, 0xd8, 0xed, 0x74, 0xf8, 0xa5, 0x3e, 0x8c, 0xec, 0x6e, 0xd5, 0x54, 0xb6, 0x59, 0x91, 0xf9, 0x28, 0xb8, 0xb4, 0x50, 0x28, 0x1c, 0xf9, 0x5e, 0x0e, 0x60, 0x1b, 0xb4, 0x9d, 0xad, 0x1e, 0x6e, 0xa3, 0x8e, 0xfd, 0xfb, 0x4e, 0x28, 0xd2, 0x3f, 0x51, 0x5f, 0xc0, 0xb4, 0x52, 0xa1, 0x29, 0xf1, 0x25, 0xa0, 0x84, 0x14, 0xc9, 0x87, 0xc7, 0xda, 0xc1, 0xad, 0x5c, 0xf8, 0x9c, 0x53, 0x11, 0xa8, 0x76, 0xba, 0xeb, 0x50, 0x33, 0x66, 0xf5, 0xab, 0xdc, 0xb8, 0xab, 0x57, 0x57, 0x5d, 0xc9, 0x54, 0x8a, 0x9f, 0x97, 0x3b, 0x51, 0x07, 0xdb, 0xc6, 0xa8, 0xaf, 0x6c, 0x86, 0x16, 0x04, 0x0f, 0x48, 0x97, 0xa9, 0xab, 0x17, 0x8b, 0x08, 0x35, 0xc7, 0xba, 0x6a, 0xa9, 0xe0, 0xed, 0x58, 0x80, 0x24, 0xe8, 0x37, 0xb3, 0x04, 0x8f, 0x96, 0xa0, 0x57, 0x63, 0xfb, 0xe3, 0x47, 0xd5, 0x42, 0x98, 0x6a, 0xda, 0x20, 0xef, 0xa1, 0xfb, 0x0c, 0xcb, 0x97, 0x86, 0xe6, 0x17, 0x0f, 0xda, 0x30, 0x0c, 0x79, 0xd2, 0xec, 0x51, 0x7d, 0x3f, 0x6b, 0x52, 0x62, 0x23, 0xbf, 0x73, 0x00, 0xa4, 0x00, 0xb4, 0x8a, 0xd5, 0x42, 0x88, 0x36, 0x86, 0x86, 0xb6, 0x6f, 0xbe, 0x69, 0x16, 0x65, 0x7d, 0x3d, 0x33, 0x34, 0xa0, 0x06, 0x4f, 0xa8, 0x6d, 0xd7, 0x96, 0xb5, 0x98, 0xd3, 0xe6, 0xda, 0xb8, 0xd1, 0x7e, 0x4f, 0x2c, 0x97, 0xa7, 0x2e, 0xf2, 0x08, 0xc7, 0xac, 0x32, 0x67, 0x45, 0xbf, 0x47, 0xb7, 0xe1, 0x55, 0x3a, 0x07, 0x0c, 0xb8, 0xb4, 0x51, 0x00, 0xfd, 0x81, 0x33, 0x4a, 0xb8, 0xde, 0x16, 0x38, 0xfd, 0x74, 0x4f, 0x3d, 0xad, 0xf5, 0x0f, 0x5f, 0x0c, 0x53, 0xd2, 0x0b, 0xa5, 0x49, 0xb6, 0xd0, 0x6e, 0x88, 0x0f, 0x0e, 0x9b, 0x4d, 0x26, 0xf3, 0xff, 0x59, 0x95, 0x93, 0x69, 0x85, 0xc2, 0xf5, 0x41, 0xc8, 0x35, 0x5c, 0x31, 0x02, 0xd8, 0x6c, 0x0c, 0x8e, 0xae, 0xb7, 0x54, 0x3c, 0x29, 0xa3, 0xae, 0x58, 0x70, 0xe6, 0x4c, 0xf7, 0x61, 0xdd, 0xc6, 0x25, 0xd4, 0xb0, 0x37, 0x37, 0xb5, 0xff, 0x27, 0x58, 0x08, 0xae, 0x79, 0x1b, 0xc5, 0xf5, 0x28, 0x8a, 0x37, 0x15, 0x40, 0x95, 0x6f, 0x5a, 0x6e, 0x3f, 0x94, 0xf3, 0xfc, 0x09, 0x3d, 0xfd, 0x40, 0xc8, 0x21, 0xd4, 0x37, 0x4b, 0x89, 0xf3, 0x81, 0x6d, 0xf5, 0xa1, 0x96, 0x68, 0xa3, 0xbf, 0xb6, 0x8e, 0xd2, 0xba, 0x4f, 0x1c, 0x91, 0x8d, 0x07, 0xa5, 0x05, 0xb7, 0x20, 0x9f, 0xe3, 0x88, 0x92, 0x62, 0xc9, 0x73, 0xed, 0x43, 0x3f, 0x9d, 0x59, 0x5b, 0xd8, 0xd5, 0x3d, 0x62, 0xde, 0x56, 0x3d, 0x63, 0x85, 0x7d, 0x58, 0x90, 0xd2, 0xb9, 0x70, 0xad, 0x13, 0xf3, 0xde, 0xc9, 0x5c, 0xd1, 0x89, 0x04, 0x50, 0x05, 0xf7, 0xf2, 0xbe, 0x1c, 0x6d, 0xa9, 0x04, 0x7d, 0x0e, 0xcf, 0x17, 0x51, 0x57, 0xbc, 0x0a, 0xc6, 0xa7, 0x0f, 0x9e, 0xbb, 0x88, 0xa8, 0x7a, 0xa9, 0x8c, 0x42, 0xb9, 0x19, 0x89, 0xee, 0x62, 0xda, 0x10, 0xd9, 0x90, 0xc9, 0x66, 0x23, 0x45, 0x36, 0xc9, 0x25, 0xb4, 0x45, 0x30, 0x9b, 0x34, 0x81, 0xa5, 0x70, 0xfc, 0xc3, 0xed, 0xb5, 0xfa, 0xf3, 0xeb, 0xfe, 0xc8, 0x49, 0xc7, 0x9c, 0x05, 0x23, 0x7f, 0x4c, 0x9f, 0x5a, 0xf8, 0x71, 0xce, 0xc0, 0xe1, 0xb6, 0x6f, 0x8e, 0xfd, 0xd5, 0x20, 0xbf, 0x18, 0x1e, 0x5a, 0x47, 0x29, 0xc5, 0x61, 0x89, 0x9b, 0x97, 0x4c, 0x2e, 0x88, 0x33, 0xf5, 0xcb, 0x08, 0xe4, 0x6a, 0x10, 0x3b, 0x22, 0x32, 0x2b, 0x8f, 0x52, 0x7b, 0xa2, 0xe7, 0x50, 0xb9, 0x39, 0x77, 0x63, 0x2f, 0x78, 0x91, 0x56, 0x03, 0xb3, 0x69, 0x2e, 0xbb, 0x71, 0x00, 0xc2, 0x53, 0x11, 0xdb, 0x3f, 0xc6, 0x49, 0x4c, 0xdc, 0xb0, 0x02, 0x36, 0x12, 0x05, 0x6b, 0x50, 0x5c, 0xa6, 0xad, 0x7f, 0xd6, 0x5b, 0xd3, 0x39, 0xe6, 0x9a, 0xd1, 0xbc, 0x75, 0xd3, 0x0a, 0xbc, 0x9a, 0x2e, 0x95, 0x2a, 0xa0, 0xc0, 0x33, 0x83, 0x4a, 0x5e, 0x10, 0x9a, 0x03, 0x99, 0xbc, 0xec, 0x71, 0xcb, 0xb7, 0xed, 0xbd, 0xd7, 0xa3, 0xa7, 0xfa, 0xa5, 0xb5, 0xf5, 0x1a, 0xd8, 0xed, 0x9f, 0x2b, 0xcc, 0x75, 0x7c, 0x7d, 0x4e, 0x1a, 0xcc, 0x6e, 0x21, 0xa6, 0x00, 0x51, 0xee, 0xf4, 0xf2, 0x01, 0xcd, 0x6a, 0x35, 0x3f, 0x43, 0xa5, 0xf7, 0x43, 0x86, 0xbb, 0x0f, 0xbd, 0x96, 0x6c, 0x26, 0x1f, 0x6f, 0xc2, 0xaa, 0x20, 0x9e, 0x81, 0x9c, 0x53, 0x57, 0xce, 0xf7, 0x33, 0x4e, 0xe7, 0x12, 0xe9, 0xeb, 0x56, 0x14, 0x22, 0x0a, 0x29, 0xe8, 0xf6, 0x45, 0x01, 0x4b, 0x40, 0xab, 0x83, 0x31, 0x33, 0x87, 0xb6, 0xa2, 0x57, 0xa8, 0xa7, 0x3a, 0x2a, 0xd2, 0x35, 0xe1, 0x69, 0x94, 0xde, 0x75, 0xdb, 0x8d, 0x1e, 0x34, 0x78, 0x79, 0x07, 0x93, 0xea, 0x7b, 0x20, 0x14, 0xf8, 0xba, 0x5f, 0xb1, 0xbc, 0x15, 0x7f, 0xa6, 0x42, 0x04, 0x9d, 0xfe, 0x8c, 0xd2, 0x22, 0xe8, 0x39, 0x1f, 0x8a, 0x44, 0xcf, 0x8e, 0x58, 0x19, 0x33, 0x4b, 0xc8, 0x44, 0x20, 0x40, 0xba, 0x57, 0x3c, 0xd0, 0x55, 0xb2, 0x73, 0xea, 0x95, 0x32, 0x3d, 0xb1, 0xae, 0xe0, 0xb0, 0x04, 0xe9, 0x74, 0xff, 0xcb, 0xba, 0xe1, 0xed, 0x6d, 0x35, 0x10, 0xaf, 0x3e, 0xc3, 0xca, 0xbb, 0x6b, 0xdc, 0xfe, 0x65, 0x81, 0xa1, 0x2e, 0x1a, 0x5e, 0x15, 0x3e, 0xe8, 0x56, 0x8f, 0x90, 0x6b, 0xd8, 0x1a, 0xae, 0x2a, 0xc2, 0xbd, 0xff, 0xb5, 0xf2, 0x36, 0xd0, 0x2d, 0x0d, 0x1e, 0x4f, 0x0c, 0xa6, 0xcc, 0x5d, 0x57, 0xac, 0x1e, 0x8f, 0x92, 0x0f, 0x7c, 0x04, 0xeb, 0x79, 0x54, 0x41, 0x6f, 0x2c, 0x9c, 0xeb, 0x56, 0x8b, 0x19, 0x5f, 0x7b, 0x79, 0xa1, 0xff, 0x68, 0xe2, 0xe3, 0x3e, 0x0d, 0x75, 0xe3, 0x92, 0x54, 0x06, 0x57, 0x25, 0x52, 0x9e, 0x0a, 0xb9, 0xdf, 0x88, 0x19, 0x85, 0x1a, 0x81, 0xb9, 0x3f, 0x3d, 0x42, 0x59, 0x7c, 0xb5, 0x74, 0xd8, 0xfa, 0x29, 0x96, 0x66, 0x7e, 0xf6, 0xad, 0x49, 0x93, 0x38, 0x17, 0x3c, 0x3f, 0x73, 0xb0, 0x33, 0x70, 0x5c, 0xee, 0x8d, 0xbc, 0xf1, 0x74, 0x45, 0x7f, 0x46, 0xa2, 0x91, 0x1a, 0xab, 0x00, 0x34, 0x3c, 0xb9, 0x25, 0xc3, 0x5c, 0x76, 0x07, 0xd5, 0xb4, 0x8b, 0x2d, 0xf0, 0x6b, 0xa8, 0x11, 0x77, 0xa9, 0xc6, 0xf8, 0x6c, 0x75, 0x57, 0xaa, 0xd4, 0x94, 0x9d, 0x7e, 0xb8, 0xfa, 0x5b, 0xee, 0xb7, 0xaa, 0x47, 0x6e, 0x28, 0x30, 0xb4, 0x84, 0x52, 0x49, 0x8c, 0x39, 0x41, 0x07, 0x5c, 0x24, 0x4f, 0xe4, 0x5e, 0xab, 0xfa, 0x69, 0xcd, 0x90, 0x6c, 0x81, 0x55, 0x62, 0x23, 0x3b, 0x81, 0x76, 0x14, 0x3c, 0x3e, 0x56, 0x89, 0x19, 0x30, 0xa2, 0x2f, 0x34, 0x23, 0x3a, 0x07, 0xf2, 0x6b, 0x9f, 0x03, 0x62, 0x47, 0x97, 0x5a, 0xc4, 0xda, 0x3d, 0xaa, 0x79, 0x35, 0x03, 0x41, 0xf9, 0x7d, 0x61, 0xd5, 0x2b, 0x23, 0xc0, 0xb1, 0x72, 0xfe, 0x2a, 0x38, 0x93, 0x32, 0x8a, 0xe1, 0x87, 0xaf, 0xb2, 0x0c, 0xaf, 0xf3, 0x98, 0xf3, 0x01, 0x00, 0x7b, 0x12, 0x48, 0x48, 0x72, 0xfc, 0xc8, 0xcf, 0xc1, 0xf9, 0x88, 0x87, 0x92, 0x22, 0x3b, 0x4b, 0xf8, 0x67, 0x1d, 0xb5, 0x5f, 0x87, 0x0a, 0x57, 0x9c, 0x7e, 0x91, 0x4f, 0xac, 0xc8, 0x1b, 0xc5, 0x1e, 0xba, 0xb8, 0xb4, 0x4c, 0x4b, 0x46, 0x7f, 0x18, 0xb6, 0x09, 0x4f, 0x43, 0xb8, 0x87, 0xd3, 0x4f, 0x51, 0xef, 0x50, 0xcc, 0xa0, 0x7f, 0x30, 0xbd, 0xcd, 0x80, 0x80, 0x96, 0x13, 0xf8, 0x95, 0xc4, 0xeb, 0xb3, 0xca, 0x60, 0x99, 0xc0, 0x76, 0x44, 0x51, 0x9a, 0x20, 0xef, 0x54, 0x8d, 0xeb, 0xea, 0xd1, 0xb6, 0x55, 0xc4, 0x4e, 0xfd, 0x9f, 0xf9, 0x6e, 0xe1, 0xbd, 0xbc, 0x6e, 0x6f, 0x9b, 0x24, 0x36, 0xaf, 0x23, 0x27, 0x39, 0xf6, 0x4a, 0xf3, 0xde, 0x58, 0x9d, 0xcb, 0xea, 0xcf, 0x63, 0xdf, 0xbe, 0xe2, 0x02, 0x4d, 0x51, 0xed, 0x06, 0x83, 0xb3, 0xee, 0x06, 0x2f, 0xb1, 0xb1, 0x46, 0x55, 0x61, 0xdf, 0xa8, 0xcb, 0x77, 0x3a, 0x81, 0xac, 0x27, 0x53, 0xd8, 0xaa, 0xbe, 0xae, 0xab, 0x16, 0xe6, 0x85, 0xda, 0xec, 0xc0, 0xa3, 0xdd, 0x60, 0xcf, 0x96, 0x2f, 0x10, 0xb8, 0x6b, 0x8d, 0x81, 0x34, 0x74, 0x9b, 0xc7, 0x37, 0xde, 0x1c, 0x04, 0x41, 0xd5, 0x26, 0x8e, 0xfb, 0x38, 0x7e, 0x72, 0xe3, 0x7a, 0xf8, 0x68, 0x8b, 0x81, 0x1e, 0xd3, 0x00, 0x00, 0x01, 0x09 }; +constexpr AccessUnit AVC_LARGE_AU_EXPECTED_AU = { 0x15f90, 0x159b2, true, 0, {}, { 0x59, 0x01, 0x7a, 0x65, 0x04, 0xcc, 0xfb, 0xf8, 0x14, 0x0a, 0x82, 0xb6, 0xa0, 0xb8, 0xe9, 0x55, 0x47, 0x35, 0x9c, 0x90 } }; + +const std::vector M2V_LARGE_AU_STREAM = { 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xe0, 0x06, 0xe6, 0x81, 0xc1, 0x0d, 0x31, 0x00, 0x05, 0xbf, 0x21, 0x11, 0x00, 0x05, 0xb3, 0x65, 0x1e, 0x69, 0xb2, 0x00, 0x00, 0x01, 0xb3, 0xad, 0x05, 0x26, 0xaa, 0xe6, 0x35, 0x3c, 0xd3, 0x39, 0xd0, 0x8e, 0x3e, 0x56, 0x34, 0x97, 0x50, 0xf0, 0x75, 0x62, 0x8f, 0x4f, 0x2e, 0x75, 0x9c, 0x56, 0xc5, 0xcb, 0x1f, 0xa9, 0x84, 0xd5, 0xe2, 0x85, 0xec, 0xcf, 0x29, 0xcc, 0xbd, 0xc6, 0x77, 0xff, 0x7d, 0x1b, 0xec, 0x2c, 0x85, 0x65, 0x1f, 0xeb, 0x71, 0x26, 0x0d, 0x71, 0x01, 0x09, 0x7a, 0xb2, 0xed, 0x0b, 0x50, 0x39, 0x71, 0x96, 0xc9, 0x38, 0x98, 0x7b, 0x43, 0x4c, 0xa1, 0x7f, 0xac, 0xe2, 0x26, 0x30, 0xfc, 0xc0, 0x89, 0xb2, 0x6b, 0x09, 0xbf, 0x39, 0x02, 0x2f, 0x9f, 0x40, 0x3d, 0x17, 0xd3, 0x29, 0x03, 0xa4, 0x28, 0x30, 0x55, 0xa9, 0x36, 0x87, 0x10, 0xf3, 0x31, 0x88, 0x89, 0xda, 0x33, 0x88, 0x04, 0x49, 0x00, 0x81, 0x49, 0x5c, 0xe3, 0x8c, 0x83, 0x11, 0xc0, 0x84, 0xcd, 0xb5, 0x95, 0x29, 0x91, 0x83, 0x4b, 0xc8, 0x50, 0xf4, 0x5d, 0xb5, 0xeb, 0x28, 0xdc, 0x3a, 0x79, 0x68, 0x6e, 0x2b, 0x78, 0x06, 0x67, 0x83, 0x3b, 0x10, 0x7e, 0xba, 0x58, 0x72, 0x06, 0xce, 0x41, 0xed, 0xe1, 0xb7, 0x4d, 0x0e, 0x3d, 0x4a, 0xc2, 0x0b, 0xb7, 0xb1, 0x3b, 0x9a, 0x23, 0x6e, 0x1c, 0xaf, 0x02, 0xfa, 0x73, 0x0d, 0x58, 0x15, 0x33, 0x4f, 0x2f, 0x6b, 0x91, 0x82, 0x1a, 0x8d, 0xb6, 0xc2, 0x44, 0x96, 0x08, 0x9e, 0x69, 0x53, 0xb1, 0x5b, 0x2d, 0x3d, 0xa4, 0xac, 0xac, 0xf1, 0x54, 0xb3, 0xfe, 0x6a, 0x21, 0x67, 0x19, 0xfa, 0x37, 0x99, 0x41, 0x08, 0x81, 0xf6, 0xac, 0x12, 0x1d, 0x98, 0xef, 0x7a, 0x4b, 0xcc, 0xb2, 0xea, 0xdb, 0x08, 0x5e, 0xad, 0x02, 0xe6, 0x6e, 0x83, 0x10, 0x12, 0x3b, 0x7e, 0xc7, 0xdc, 0xc0, 0xd7, 0x26, 0x48, 0x6a, 0x66, 0x01, 0x11, 0x35, 0xc3, 0x4a, 0xce, 0xd6, 0x03, 0xe7, 0x29, 0x6a, 0x22, 0x3a, 0x8e, 0x55, 0x8c, 0x8a, 0xc8, 0xad, 0x3b, 0x22, 0xb9, 0xfa, 0xc1, 0x05, 0x4e, 0xd2, 0x9e, 0x84, 0xdf, 0x6f, 0xec, 0x2a, 0x75, 0x9b, 0x7f, 0xcc, 0x3b, 0xeb, 0x59, 0xb9, 0xf3, 0x02, 0x99, 0x50, 0x79, 0x41, 0x1e, 0x58, 0x8b, 0x6c, 0x39, 0x08, 0xce, 0x90, 0xb6, 0x5c, 0x59, 0x2c, 0x0b, 0xd2, 0xa0, 0xae, 0x47, 0xa9, 0x01, 0x81, 0xe4, 0xda, 0x5c, 0xdb, 0x68, 0xac, 0xda, 0xa5, 0xcf, 0xfe, 0x71, 0xed, 0xab, 0x00, 0x4a, 0xcf, 0x62, 0x95, 0xce, 0x74, 0xf4, 0x48, 0x18, 0xab, 0x00, 0xe2, 0x43, 0x5a, 0x9f, 0xff, 0x03, 0xdd, 0xd5, 0xd3, 0xd4, 0x22, 0xcb, 0x83, 0x9d, 0x25, 0xc0, 0x43, 0x1f, 0x3d, 0xfa, 0x0c, 0x39, 0x89, 0x33, 0x4f, 0x6c, 0xdd, 0x40, 0x8e, 0xb8, 0x4d, 0x75, 0x38, 0x3d, 0x1e, 0x6c, 0x0a, 0x8f, 0xd4, 0x07, 0x71, 0xcf, 0x8b, 0xa8, 0x65, 0x4a, 0xb4, 0xc9, 0x9f, 0x4a, 0x6f, 0xee, 0xab, 0x2a, 0xee, 0xc1, 0x5b, 0x88, 0xe6, 0x93, 0x7c, 0x7b, 0x23, 0xee, 0x1a, 0xab, 0xb6, 0x82, 0x03, 0x63, 0x24, 0x8e, 0xea, 0xd3, 0xdc, 0x1f, 0x8e, 0x3d, 0x6a, 0xb9, 0x96, 0x79, 0xd2, 0x8f, 0x37, 0x23, 0x9d, 0x1b, 0x58, 0x38, 0xb4, 0x9e, 0x50, 0x8e, 0x13, 0x00, 0xcc, 0x22, 0x17, 0x25, 0x04, 0xde, 0x29, 0xea, 0x36, 0xac, 0x1a, 0x70, 0x7a, 0x15, 0x22, 0xbd, 0x14, 0x70, 0x08, 0x62, 0xfa, 0x1d, 0xeb, 0x37, 0xe1, 0xcd, 0x16, 0x8b, 0x3b, 0x24, 0x39, 0xec, 0xe8, 0x76, 0x4e, 0x50, 0x4a, 0x9f, 0x83, 0xc2, 0xb5, 0x9d, 0x1d, 0x71, 0xb3, 0x7f, 0xcd, 0x8d, 0x5d, 0x3e, 0x75, 0x6d, 0x3e, 0xd9, 0x2d, 0xfb, 0x3e, 0x0d, 0x95, 0x63, 0x3b, 0xe0, 0x34, 0x85, 0x91, 0xb3, 0x88, 0x6c, 0x87, 0x58, 0x60, 0x1c, 0x10, 0x4e, 0xd0, 0x18, 0x10, 0x77, 0x9f, 0xe1, 0x73, 0x05, 0x69, 0xd0, 0xc3, 0xe0, 0xa9, 0x7d, 0x11, 0x5f, 0xe8, 0xee, 0x05, 0xc3, 0x97, 0x19, 0x5b, 0x6f, 0xa9, 0x9f, 0xb8, 0x1c, 0x6c, 0x43, 0x40, 0x88, 0x7b, 0xc1, 0xf0, 0x5a, 0x2e, 0x5e, 0x2c, 0xf9, 0xd4, 0xbb, 0xef, 0x4a, 0x84, 0xe3, 0x3e, 0x9b, 0xbf, 0x62, 0x99, 0x8d, 0x5f, 0x26, 0x76, 0x39, 0x13, 0xc7, 0x8d, 0x36, 0xff, 0xa1, 0xf1, 0xd7, 0x47, 0xf7, 0x73, 0x10, 0x6e, 0x24, 0x1a, 0x44, 0xad, 0xca, 0xbd, 0xbc, 0xa6, 0xa8, 0xb4, 0x56, 0x26, 0xfc, 0x1f, 0x57, 0xe0, 0xca, 0x6e, 0x67, 0x33, 0x3e, 0x5f, 0x39, 0x47, 0x82, 0xb6, 0x54, 0xde, 0xc5, 0x92, 0xa8, 0xb7, 0xbc, 0x82, 0x03, 0xa7, 0x3d, 0x7b, 0x13, 0x70, 0x64, 0x57, 0x29, 0xa5, 0x33, 0x27, 0x63, 0xc1, 0xaa, 0x60, 0x3b, 0xe1, 0x91, 0xfd, 0x6c, 0x01, 0x88, 0x34, 0xc0, 0x07, 0xc3, 0x85, 0xfb, 0x1f, 0x12, 0xd7, 0x31, 0xfe, 0x78, 0xb8, 0x15, 0xe5, 0xc7, 0xf2, 0x97, 0x60, 0x05, 0xd1, 0x35, 0x34, 0x1b, 0x25, 0x4f, 0x35, 0xc6, 0x98, 0x12, 0x17, 0xc1, 0xe6, 0x42, 0xd0, 0xa3, 0xd7, 0xc8, 0xef, 0xed, 0x01, 0x7c, 0x3e, 0xc5, 0xc1, 0xf5, 0x02, 0xd7, 0x92, 0xea, 0x53, 0xfc, 0x65, 0xc4, 0x84, 0x85, 0x08, 0x1a, 0xbc, 0x07, 0xd2, 0xbc, 0xc4, 0x28, 0xf6, 0xab, 0xb0, 0x22, 0x9e, 0x05, 0x9b, 0xc6, 0xb4, 0x5e, 0x5f, 0xb5, 0xf5, 0x1f, 0x6c, 0xe0, 0xc8, 0xdb, 0x17, 0xd8, 0xe3, 0xdb, 0x50, 0x65, 0xef, 0x2a, 0xda, 0x40, 0x34, 0xc3, 0x21, 0x21, 0x13, 0x79, 0x12, 0x04, 0x84, 0x35, 0x34, 0x7f, 0x82, 0x37, 0xe8, 0x14, 0x29, 0x61, 0x2f, 0x19, 0xd2, 0xa2, 0x42, 0x93, 0x6f, 0x6d, 0x85, 0x38, 0x30, 0x6e, 0x25, 0x45, 0x78, 0xd5, 0x2a, 0xc4, 0x0e, 0xfd, 0xa0, 0xab, 0xa6, 0xae, 0xdc, 0x93, 0xa7, 0x72, 0x2a, 0x09, 0x04, 0xb4, 0x4e, 0xf2, 0x56, 0x00, 0x15, 0x98, 0x7f, 0x3b, 0x4f, 0x43, 0x90, 0x08, 0x42, 0xd0, 0x11, 0x93, 0x58, 0xd1, 0x23, 0xd4, 0x9a, 0x9a, 0x80, 0x0b, 0xf6, 0xa8, 0xe4, 0x17, 0x1a, 0xa8, 0xe3, 0x3d, 0x5a, 0x05, 0xf4, 0x73, 0xa7, 0x2d, 0xe6, 0xee, 0xa9, 0x78, 0xa2, 0x6e, 0x1b, 0xc2, 0x07, 0x04, 0xb8, 0x31, 0xb2, 0x01, 0x76, 0xba, 0x19, 0x0c, 0x0f, 0x4f, 0xce, 0xbe, 0x63, 0xa2, 0xb8, 0x80, 0xf2, 0x22, 0x8d, 0x0c, 0xdb, 0x25, 0x66, 0x7a, 0x40, 0xa3, 0x0b, 0xe2, 0x2f, 0x47, 0x4a, 0xfe, 0xd4, 0xd6, 0x12, 0x0f, 0x26, 0x5b, 0x04, 0xf4, 0x8c, 0xdf, 0x6b, 0x67, 0x45, 0x67, 0xe9, 0x62, 0xf3, 0x1d, 0x2c, 0x2e, 0x1a, 0xd6, 0x58, 0x43, 0x62, 0x03, 0x0a, 0xf1, 0xe6, 0x2d, 0xf8, 0xe0, 0x1a, 0x77, 0xbf, 0xe6, 0x39, 0x4c, 0x45, 0xaa, 0xce, 0xbf, 0x6c, 0x6c, 0xbb, 0x55, 0x91, 0x51, 0xd5, 0x49, 0x05, 0x1d, 0x39, 0xe4, 0xf6, 0x22, 0x20, 0x24, 0xc4, 0xb2, 0x83, 0xda, 0xb7, 0xb3, 0x86, 0xdf, 0x37, 0xe0, 0x01, 0xe1, 0x5b, 0x55, 0xd9, 0x60, 0x8b, 0x55, 0xcb, 0x28, 0x7f, 0xf9, 0xfa, 0x50, 0x0b, 0x4c, 0xc0, 0x18, 0x1d, 0x2e, 0x92, 0x19, 0x05, 0xa4, 0xd7, 0xde, 0xc7, 0x3e, 0xc4, 0x3f, 0x27, 0x56, 0x35, 0x00, 0xf5, 0xe3, 0x32, 0x71, 0xcb, 0xa0, 0x34, 0xa2, 0xbd, 0x3c, 0x6b, 0x17, 0x1e, 0x94, 0xb9, 0x7b, 0x62, 0xb8, 0xcb, 0xa4, 0xa2, 0x8a, 0x90, 0xb0, 0xc0, 0xb6, 0xc3, 0xfa, 0x9e, 0x1f, 0xa3, 0x75, 0x09, 0x71, 0x5d, 0x9c, 0x23, 0xdd, 0xf6, 0x6d, 0x4f, 0x42, 0xd2, 0xaf, 0x8d, 0x89, 0x54, 0xc1, 0xfd, 0x36, 0x25, 0x2c, 0x06, 0x2e, 0x4a, 0xea, 0x41, 0x63, 0x0e, 0x3d, 0xfc, 0x40, 0xa7, 0x71, 0x1c, 0x3c, 0x9c, 0x75, 0x02, 0xcb, 0xb3, 0x32, 0x6e, 0x33, 0xf5, 0x30, 0xb9, 0x63, 0x40, 0xd2, 0xb4, 0xff, 0xd5, 0x9e, 0xcd, 0x44, 0x9b, 0xeb, 0x4a, 0x43, 0x1d, 0x20, 0xf1, 0x60, 0xa6, 0xad, 0x0a, 0xb7, 0x6d, 0xef, 0x82, 0x15, 0x02, 0x35, 0xd8, 0x4d, 0xdc, 0x1b, 0xdf, 0x1f, 0x69, 0x2c, 0x86, 0xdd, 0x11, 0x91, 0x22, 0x70, 0x74, 0x3e, 0x64, 0xef, 0x3f, 0xb2, 0xb1, 0xc3, 0xbe, 0x6e, 0x9d, 0x13, 0x8c, 0x8f, 0xff, 0xd6, 0x74, 0x0b, 0xc0, 0x89, 0x6a, 0x87, 0xd0, 0xe5, 0x4b, 0x3c, 0x30, 0xd7, 0x27, 0xad, 0xf1, 0xc8, 0x0c, 0x07, 0x1d, 0xea, 0x31, 0xfe, 0x37, 0x5b, 0x0b, 0xeb, 0xfe, 0xc2, 0x43, 0x55, 0xa4, 0xf6, 0x92, 0x11, 0x38, 0xa4, 0x71, 0xbc, 0x77, 0x59, 0x8e, 0x38, 0x24, 0xe3, 0xd3, 0xb0, 0x61, 0x5f, 0xe5, 0x76, 0x20, 0x93, 0x81, 0xba, 0x0f, 0x8d, 0xc4, 0x86, 0x73, 0x78, 0x74, 0xdf, 0x7a, 0xb4, 0x93, 0x58, 0xf2, 0x02, 0x40, 0x4e, 0x10, 0x93, 0xe4, 0xdd, 0xeb, 0x1e, 0x8d, 0x96, 0xa2, 0x32, 0x0a, 0x4b, 0xfe, 0xa7, 0x48, 0x2d, 0x72, 0x1e, 0x89, 0xa7, 0x50, 0x5c, 0x10, 0xe8, 0x52, 0x49, 0x4a, 0x13, 0xcc, 0x51, 0xba, 0x22, 0x7c, 0xa3, 0xca, 0xc8, 0xcf, 0x31, 0x79, 0x40, 0x2a, 0x6f, 0xf6, 0x6d, 0x82, 0x5c, 0x6c, 0xb5, 0x3a, 0x6c, 0xa7, 0x4f, 0xdf, 0x52, 0x94, 0xe0, 0x1a, 0xaa, 0xe6, 0x43, 0x20, 0x2f, 0xa6, 0x27, 0x67, 0x08, 0xbb, 0x31, 0x5c, 0x3d, 0xfd, 0x9a, 0xf9, 0x2e, 0x42, 0x95, 0x56, 0x8f, 0xad, 0x86, 0x20, 0xae, 0xd4, 0x04, 0x74, 0x1f, 0xfe, 0xe2, 0x0d, 0x0f, 0x69, 0xb3, 0x73, 0x2a, 0x57, 0x26, 0xca, 0x2f, 0xdd, 0xa5, 0xdd, 0x4d, 0x77, 0x44, 0x43, 0x54, 0x37, 0xf5, 0xda, 0x70, 0x36, 0x59, 0x89, 0x3d, 0x91, 0x3f, 0x6b, 0xff, 0x8f, 0x29, 0x3d, 0x8f, 0x4b, 0x07, 0xb8, 0x70, 0x7f, 0x13, 0x89, 0x9d, 0x03, 0xe9, 0x81, 0xcb, 0x19, 0xc5, 0x98, 0xde, 0xcd, 0x32, 0xdf, 0x33, 0x14, 0x69, 0xbf, 0x9b, 0xb1, 0x39, 0xdc, 0xec, 0x29, 0xf2, 0x3a, 0x88, 0x1d, 0x23, 0x1b, 0xec, 0xd1, 0x0f, 0xc4, 0x82, 0x94, 0xf7, 0xc1, 0x55, 0x3f, 0x98, 0xc9, 0xd8, 0x34, 0xd9, 0x80, 0x05, 0x59, 0xb7, 0xca, 0x24, 0x85, 0xbe, 0xf1, 0xfc, 0xb7, 0x42, 0xa0, 0x1b, 0xd5, 0x1c, 0x10, 0x6b, 0x1c, 0x99, 0x20, 0x4c, 0x7e, 0xa8, 0x8d, 0xf6, 0x27, 0x07, 0x48, 0xf3, 0x18, 0x99, 0x73, 0x42, 0x37, 0x96, 0x4e, 0x34, 0x1d, 0x38, 0x91, 0x5a, 0x0e, 0x61, 0x6b, 0x9f, 0xfa, 0xe0, 0x39, 0x3a, 0x54, 0x87, 0xfc, 0x5d, 0xcf, 0x13, 0xba, 0x74, 0x8c, 0xc3, 0xa2, 0xa3, 0x89, 0x91, 0x7c, 0x97, 0xbe, 0xf8, 0x26, 0x0f, 0x54, 0x5c, 0x40, 0xb4, 0x61, 0x3f, 0xbb, 0x87, 0xa1, 0xdd, 0x62, 0x5d, 0x5c, 0x49, 0x93, 0x85, 0x50, 0x30, 0x32, 0x8a, 0xd7, 0x2c, 0x83, 0xf0, 0x4b, 0x76, 0x4a, 0xac, 0x87, 0x0e, 0x6e, 0xff, 0x7a, 0x11, 0xbd, 0x49, 0x71, 0xaf, 0x2d, 0xa7, 0x44, 0x7b, 0xcc, 0x71, 0xc3, 0xb8, 0x13, 0x28, 0xe9, 0x62, 0x1a, 0xa5, 0x67, 0x78, 0xb6, 0x19, 0x83, 0xc5, 0xa7, 0x15, 0xd2, 0x3d, 0xf9, 0x85, 0xb1, 0x99, 0xd8, 0x18, 0x4d, 0x16, 0x1d, 0x17, 0x3e, 0x29, 0x63, 0x8f, 0x07, 0x86, 0x03, 0x9f, 0x0f, 0xc5, 0xcf, 0x76, 0x9d, 0xef, 0xe3, 0xaa, 0x0a, 0xac, 0x37, 0xa4, 0xfc, 0x49, 0x25, 0xa5, 0x8f, 0x1c, 0x4e, 0xab, 0x2b, 0x68, 0x3f, 0x59, 0xbb, 0x9f, 0x80, 0x47, 0x82, 0x31, 0x92, 0x64, 0xf3, 0xab, 0x6b, 0xd3, 0xd1, 0x42, 0xe7, 0x26, 0xb4, 0x73, 0x5e, 0xac, 0x08, 0xdd, 0x48, 0x89, 0xbd, 0xd3, 0x68, 0xa1, 0xfa, 0x20, 0x05, 0xe3, 0x39, 0x37, 0x84, 0x78, 0x52, 0x3d, 0x0f, 0xe8, 0x2b, 0xa2, 0x8c, 0x3c, 0xd3, 0x5b, 0x60, 0x31, 0xf1, 0x60, 0x20, 0xd6, 0x64, 0xb2, 0x9c, 0xa4, 0x99, 0xf5, 0x90, 0xd9, 0xca, 0x5f, 0xf2, 0x39, 0x1c, 0x6e, 0xd2, 0x0d, 0x65, 0xda, 0x0c, 0x2a, 0x67, 0x16, 0x6f, 0x63, 0x88, 0x6f, 0x66, 0xc7, 0x39, 0x4b, 0xf6, 0x5b, 0xaa, 0x30, 0x2b, 0xc2, 0xb9, 0x40, 0x88, 0xda, 0x10, 0xb4, 0x2d, 0x5f, 0x9b, 0x16, 0xc1, 0xb5, 0x19, 0x2f, 0x70, 0xa7, 0x22, 0xdf, 0x2d, 0xe8, 0x7b, 0x1c, 0x6d, 0xa8, 0xce, 0x75, 0xb9, 0x5b, 0x68, 0x01, 0xb3, 0x36, 0x95, 0xcd, 0x0c, 0x98, 0x5b, 0xf1, 0x1d, 0xfe, 0xaa, 0x20, 0xf2, 0xd8, 0x9b, 0xdd, 0xeb, 0x5b, 0x98, 0x6d, 0x59, 0xd1, 0xd4, 0xe8, 0x83, 0x05, 0xf1, 0x15, 0x9d, 0x56, 0xb2, 0x5a, 0xd6, 0xfd, 0x05, 0x7e, 0x7b, 0x89, 0xf6, 0x53, 0xcf, 0x5a, 0x43, 0xef, 0x49, 0x99, 0xf5, 0xee, 0xa0, 0x36, 0x5f, 0x07, 0x02, 0x3d, 0x08, 0xd9, 0xb1, 0xfc, 0xd2, 0xb5, 0x72, 0x60, 0xee, 0xa9, 0xaf, 0x27, 0x48, 0x96, 0x86, 0x97, 0xf5, 0x37, 0x74, 0x56, 0x2e, 0x80, 0x02, 0xc5, 0xf1, 0x80, 0x2e, 0xa8, 0xc1, 0x20, 0xcf, 0x60, 0x78, 0xcc, 0xa6, 0x48, 0xea, 0xf1, 0x72, 0xce, 0xb7, 0x23, 0xeb, 0x58, 0x51, 0x9f, 0xfa, 0xf6, 0x3d, 0x13, 0x5b, 0x82, 0xa6, 0x1c, 0x25, 0xac, 0x71, 0x94, 0xe9, 0x86, 0x60, 0xf7, 0x86, 0xe3, 0xab, 0x11, 0x0a, 0xbf, 0x23, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x02, 0xe4, 0x61, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xe0, 0x07, 0xec, 0x81, 0x00, 0x00, 0x3d, 0x4f, 0xe8, 0x8a, 0x84, 0x70, 0xd4, 0x47, 0x10, 0x56, 0xdf, 0x21, 0xf4, 0xb6, 0x51, 0xed, 0x6a, 0xba, 0xf6, 0x41, 0x64, 0xac, 0x13, 0xd8, 0x9e, 0xee, 0xeb, 0xc1, 0xc1, 0xc5, 0xd5, 0x88, 0x4e, 0xa9, 0x5a, 0x51, 0x4d, 0xd6, 0xbc, 0x4e, 0xa1, 0x0d, 0x56, 0x46, 0xed, 0x11, 0xba, 0xe2, 0xa8, 0x7a, 0xd8, 0xd6, 0x42, 0x13, 0x27, 0x53, 0xc6, 0x42, 0x41, 0x1f, 0xed, 0x44, 0x76, 0x11, 0x1d, 0x89, 0xcb, 0x39, 0x99, 0x03, 0xa8, 0x6e, 0x6a, 0x89, 0x13, 0xfc, 0xa3, 0x40, 0x1c, 0x08, 0x40, 0x19, 0x68, 0xc2, 0x4e, 0xc2, 0x7d, 0x03, 0x33, 0xa6, 0x04, 0xf1, 0x78, 0xac, 0xc1, 0xdb, 0x78, 0x38, 0xfc, 0x01, 0x3a, 0x81, 0xed, 0xc6, 0xa1, 0x42, 0xd3, 0x22, 0x0c, 0x41, 0x7a, 0x8a, 0x30, 0x99, 0x12, 0x4d, 0xab, 0x94, 0xe7, 0xb4, 0xba, 0x1f, 0x9c, 0xbd, 0xfd, 0x49, 0xef, 0x93, 0x74, 0xf4, 0x88, 0x72, 0xc4, 0x75, 0xc2, 0x95, 0x76, 0x21, 0x86, 0xf8, 0x24, 0xc3, 0x4c, 0x22, 0x8d, 0x60, 0xd2, 0x8f, 0xec, 0xca, 0x20, 0x99, 0x87, 0x4b, 0x69, 0xc2, 0x45, 0xff, 0x89, 0xab, 0xe8, 0x9b, 0x7e, 0x51, 0x00, 0xf2, 0x0b, 0xc7, 0x7e, 0xe2, 0xdd, 0x16, 0x94, 0xb3, 0x76, 0x24, 0xf9, 0xe5, 0x0a, 0x3e, 0xc1, 0x7b, 0xd7, 0x1a, 0x40, 0x23, 0x99, 0x3d, 0x16, 0x8e, 0xe0, 0x7b, 0xcc, 0x67, 0xeb, 0xeb, 0xab, 0xee, 0xab, 0x17, 0xca, 0xd6, 0xca, 0xb3, 0x37, 0xe4, 0x4b, 0x93, 0x85, 0x0c, 0x65, 0xe0, 0x7e, 0x16, 0xd4, 0x5f, 0x5b, 0x3c, 0x57, 0x3d, 0x1f, 0x6a, 0x7a, 0x81, 0xf3, 0x94, 0x93, 0x52, 0xf4, 0x7f, 0xac, 0x56, 0xdf, 0xf1, 0xa9, 0xed, 0xca, 0xb3, 0x2b, 0x6b, 0x23, 0x2d, 0x12, 0x40, 0x6f, 0xfe, 0x07, 0x8a, 0x53, 0x19, 0x1d, 0x42, 0x65, 0x2d, 0x3d, 0x99, 0xf6, 0x39, 0xb5, 0x01, 0x7f, 0xca, 0x30, 0x88, 0x0a, 0x4a, 0xe6, 0x3e, 0xc2, 0x50, 0xd0, 0x2a, 0x8e, 0xe7, 0xdd, 0xcb, 0xfc, 0x4e, 0xdd, 0xb2, 0x7a, 0x21, 0x79, 0xbc, 0x7c, 0xfc, 0x96, 0xe1, 0x71, 0xfa, 0xf0, 0x28, 0x05, 0x18, 0x8c, 0x8f, 0x41, 0x00, 0x9f, 0x6d, 0xe4, 0xd2, 0x82, 0xb9, 0xe5, 0x21, 0xdf, 0xc0, 0xfc, 0x73, 0x38, 0xd4, 0x11, 0x38, 0x88, 0x06, 0x16, 0x59, 0x14, 0x92, 0xbe, 0x13, 0xa2, 0xc7, 0x53, 0xf2, 0xe2, 0xe6, 0x01, 0x51, 0x30, 0x12, 0x3f, 0xf2, 0x1e, 0xe1, 0x78, 0xe9, 0x9d, 0xac, 0xfe, 0x47, 0x6a, 0x96, 0x85, 0x08, 0xe3, 0x11, 0x34, 0x7c, 0xfe, 0xe8, 0x9d, 0x2d, 0x36, 0x58, 0x22, 0x03, 0xaf, 0x9f, 0x10, 0x5e, 0xb7, 0x04, 0xed, 0x47, 0xbb, 0xcb, 0x96, 0xed, 0xca, 0xde, 0x1f, 0xf5, 0xe6, 0x84, 0x12, 0xa3, 0x31, 0x06, 0xd9, 0xb2, 0x32, 0xe2, 0xc5, 0x32, 0xa4, 0x8a, 0x7e, 0x56, 0xcd, 0x17, 0x4b, 0xc8, 0x20, 0xd9, 0xa4, 0xc3, 0x23, 0xda, 0x0c, 0x62, 0x56, 0xa2, 0xaf, 0xf5, 0xcd, 0x1a, 0xdf, 0x9b, 0xcd, 0x63, 0xf9, 0xdc, 0xae, 0xf5, 0x43, 0xb1, 0x83, 0x21, 0x33, 0xb2, 0x75, 0x2a, 0xd7, 0xa8, 0x4f, 0x70, 0x37, 0x61, 0xd5, 0xa6, 0x6c, 0xec, 0x98, 0x89, 0x0c, 0xfc, 0x2b, 0x0e, 0x35, 0x0f, 0xca, 0xa0, 0x1d, 0x03, 0xd8, 0x4f, 0xc2, 0x11, 0x4d, 0x7e, 0x72, 0xd3, 0xa9, 0xb9, 0x04, 0xee, 0x4e, 0xd0, 0xa2, 0xb6, 0xbb, 0x70, 0x9d, 0xd5, 0x25, 0x3e, 0x92, 0xab, 0xe1, 0x10, 0x7d, 0xe4, 0x75, 0xe9, 0xd7, 0x44, 0x6e, 0xa5, 0x60, 0x88, 0xc3, 0x14, 0x67, 0x89, 0x65, 0xb5, 0x52, 0xf5, 0x97, 0x9c, 0xf7, 0x2d, 0xa7, 0xa4, 0xda, 0xb6, 0x63, 0x93, 0x28, 0x6c, 0x81, 0xb4, 0x8a, 0x36, 0x8c, 0x2d, 0xa1, 0xa4, 0xde, 0xac, 0x7e, 0xee, 0x91, 0xe5, 0xb9, 0x68, 0x4f, 0x6d, 0x56, 0xbb, 0x81, 0xf9, 0xa1, 0xdb, 0x39, 0xb6, 0x6b, 0xf9, 0xd6, 0x3d, 0x5e, 0x7d, 0x4f, 0x14, 0x97, 0xae, 0x83, 0xf7, 0x56, 0xe1, 0xa6, 0x78, 0x49, 0x69, 0x81, 0x44, 0x29, 0x99, 0xf4, 0xbb, 0x49, 0xaa, 0x9b, 0x7c, 0x73, 0xdf, 0xe8, 0x6c, 0xd2, 0x3c, 0x8c, 0xb4, 0xcc, 0xde, 0xea, 0x55, 0x70, 0x58, 0xca, 0x72, 0x47, 0x49, 0xe2, 0x36, 0xb0, 0x90, 0x6e, 0x40, 0xd8, 0xb6, 0x8d, 0x0c, 0xcd, 0xab, 0xa8, 0x3c, 0x25, 0x6f, 0x37, 0xc5, 0x01, 0xf0, 0xa5, 0x11, 0x0a, 0xa0, 0x77, 0x9b, 0x02, 0xd5, 0x20, 0xfa, 0x06, 0x37, 0x4e, 0x6c, 0xa7, 0x44, 0xdd, 0x84, 0x77, 0x3e, 0xe6, 0x59, 0x65, 0x33, 0xb3, 0x66, 0x79, 0x4f, 0x1a, 0xd3, 0x2f, 0x7d, 0xd2, 0xde, 0x29, 0x10, 0x41, 0xa5, 0x1b, 0x06, 0xe7, 0x99, 0xfd, 0x07, 0x55, 0x98, 0xfe, 0x61, 0xdd, 0x90, 0xc4, 0x85, 0x46, 0xcb, 0x09, 0x39, 0xf3, 0xd2, 0x29, 0xf2, 0x52, 0x15, 0xc3, 0xb3, 0xad, 0x65, 0x3d, 0xa4, 0xb3, 0x73, 0x9f, 0x2f, 0xd7, 0xc7, 0x3f, 0xc4, 0x06, 0xa9, 0x40, 0xcd, 0x1a, 0xb0, 0xb1, 0x22, 0x32, 0x80, 0xe8, 0x58, 0xc2, 0x79, 0x9e, 0x5a, 0xf0, 0x2d, 0xad, 0xa0, 0x8a, 0xcc, 0x65, 0x30, 0x91, 0xa9, 0xe9, 0xae, 0xce, 0xe9, 0xf6, 0x30, 0x44, 0x6f, 0x7f, 0xc2, 0x60, 0xa6, 0xa6, 0x16, 0xd3, 0x4b, 0x92, 0x4f, 0xa1, 0xd9, 0x7a, 0xbe, 0x14, 0x24, 0xac, 0xa8, 0xc4, 0xed, 0xd9, 0x01, 0xde, 0xea, 0x45, 0x83, 0x92, 0x52, 0xfa, 0xc1, 0xdd, 0xc7, 0xf3, 0x62, 0x8e, 0x2b, 0x0e, 0x1d, 0x6e, 0xcc, 0x00, 0xe6, 0x0d, 0xba, 0xb2, 0x4c, 0x98, 0x81, 0xab, 0x12, 0x42, 0x8b, 0x05, 0x66, 0x9a, 0xfe, 0xa5, 0xc4, 0xc5, 0x16, 0xc4, 0xa9, 0xb7, 0x97, 0x6c, 0x5d, 0x92, 0x45, 0xf6, 0xf9, 0xe9, 0x38, 0x8f, 0xec, 0x0e, 0x14, 0xb3, 0x97, 0x26, 0x66, 0x4c, 0xeb, 0x14, 0x01, 0x18, 0xb1, 0xc8, 0x1e, 0x83, 0x49, 0x54, 0x98, 0x30, 0xf3, 0xa7, 0x03, 0x08, 0x98, 0x2b, 0x5e, 0x63, 0xbf, 0x79, 0xe1, 0x8e, 0xf9, 0xbd, 0x85, 0xc8, 0xdb, 0x79, 0xd8, 0x14, 0x93, 0xc5, 0x78, 0xf7, 0x67, 0xe1, 0xa9, 0xeb, 0xab, 0xf2, 0xa9, 0x16, 0x2b, 0xfa, 0x65, 0x45, 0x0b, 0x6e, 0xa8, 0xcd, 0x9c, 0x43, 0x3c, 0xb7, 0x24, 0xe5, 0x68, 0x92, 0x96, 0x50, 0xd5, 0x8b, 0xf2, 0x32, 0xf7, 0x49, 0xe3, 0x4c, 0xbb, 0xb1, 0xaa, 0x39, 0xfe, 0xc4, 0xa1, 0xf3, 0xf2, 0x1e, 0x77, 0xd4, 0x4f, 0x7f, 0x7c, 0x61, 0x28, 0x05, 0x55, 0xb3, 0xd2, 0xd6, 0x05, 0xbb, 0x38, 0x4c, 0x82, 0xc5, 0x19, 0x58, 0x53, 0xd8, 0xdb, 0xf3, 0x85, 0xb3, 0x12, 0x5e, 0xe6, 0x03, 0xa8, 0x2a, 0x9e, 0xc0, 0xfd, 0xcf, 0x87, 0x87, 0xe5, 0x64, 0x98, 0xf2, 0x44, 0x2e, 0x27, 0x3d, 0x7a, 0x91, 0x02, 0x2e, 0x4f, 0xac, 0xa1, 0x86, 0xc5, 0x64, 0x8e, 0xb9, 0x75, 0xf5, 0x94, 0xfe, 0x01, 0xfd, 0x73, 0xc2, 0xd6, 0xfb, 0x39, 0xda, 0xae, 0x91, 0x3b, 0xae, 0xb7, 0x70, 0x6c, 0x87, 0xfe, 0x89, 0x31, 0x8d, 0x1a, 0xdb, 0x95, 0x1c, 0x8d, 0xdf, 0x86, 0x27, 0x0b, 0x00, 0x7d, 0x9a, 0xfc, 0xb5, 0xaa, 0xf0, 0x79, 0x30, 0xf8, 0xab, 0xc1, 0xac, 0x2f, 0xdf, 0x8a, 0x36, 0x63, 0x59, 0xca, 0x77, 0x98, 0x00, 0x00, 0x01, 0x00, 0xca, 0xc7, 0x4a, 0x81, 0xaf, 0xcb, 0x45, 0x6a, 0xe9, 0x9d, 0xa3, 0x03, 0x70, 0xb3, 0x07, 0xd0, 0xca, 0x3d, 0xac, 0xad, 0xca, 0x8c, 0x63, 0xbd, 0x65, 0x83, 0x99, 0x84, 0x62, 0xb4, 0xe0, 0x9d, 0xdd, 0x1f, 0x41, 0x1e, 0x53, 0x28, 0x0c, 0xd3, 0x15, 0x7d, 0xd3, 0x69, 0x5c, 0xbe, 0xcc, 0xeb, 0xf0, 0xe7, 0xb7, 0xf2, 0x54, 0xd6, 0x8b, 0xee, 0x2c, 0xcb, 0x5c, 0x02, 0x17, 0x34, 0x07, 0xb3, 0x42, 0x41, 0xaf, 0x2a, 0x1d, 0xdc, 0x40, 0x50, 0x10, 0x6d, 0x2e, 0x00, 0xff, 0xe9, 0x8b, 0x9b, 0x8f, 0xc2, 0x9c, 0x74, 0x33, 0xd3, 0x69, 0x3f, 0x22, 0x34, 0xc5, 0x2f, 0xcd, 0x3a, 0x66, 0xc7, 0x7d, 0x23, 0x15, 0x8d, 0x1e, 0x26, 0x4b, 0x09, 0xf0, 0x10, 0x5d, 0x4a, 0x87, 0x8b, 0xf2, 0x94, 0xda, 0x9e, 0x98, 0x69, 0x28, 0x7c, 0x01, 0x04, 0x26, 0xb1, 0xea, 0x16, 0x4e, 0x6a, 0x88, 0x58, 0x1f, 0xb2, 0x44, 0xf2, 0x65, 0xe3, 0x75, 0x53, 0x1c, 0x34, 0x67, 0x47, 0x34, 0x2f, 0x61, 0x28, 0x5a, 0x70, 0x00, 0x4f, 0xb6, 0x47, 0x25, 0x8a, 0x34, 0x1f, 0xa8, 0x68, 0xcb, 0x05, 0x92, 0x5e, 0xf0, 0x6f, 0xa0, 0x41, 0x3c, 0x68, 0xf1, 0xb3, 0x9e, 0x11, 0x2a, 0xe5, 0xc9, 0xff, 0xa0, 0x79, 0x8e, 0x1c, 0xf2, 0x86, 0xbe, 0xd2, 0x7a, 0xf4, 0xaa, 0xd9, 0x2b, 0x7b, 0x6f, 0xfc, 0x97, 0x1b, 0x02, 0x98, 0x6b, 0x28, 0x43, 0x79, 0x2c, 0x49, 0x0c, 0x7c, 0x12, 0x02, 0x91, 0xf6, 0x7e, 0xf9, 0xfe, 0x13, 0x3d, 0x4a, 0x47, 0xed, 0x24, 0xae, 0xae, 0x7f, 0xfc, 0x3b, 0x93, 0xc4, 0x64, 0x8c, 0xcb, 0x79, 0xfc, 0xff, 0x8b, 0xdd, 0xcc, 0x16, 0x02, 0x0b, 0xd6, 0x95, 0xcc, 0x02, 0x74, 0xd5, 0x9b, 0xe5, 0x05, 0x1d, 0x0a, 0x8e, 0xb9, 0x5d, 0xe5, 0xf5, 0xda, 0xf3, 0xbd, 0x93, 0xb3, 0x1f, 0x7f, 0xfe, 0x8c, 0x5a, 0x9e, 0x9e, 0x3c, 0x44, 0x29, 0x2b, 0x2c, 0x2b, 0x02, 0x7d, 0xe7, 0x76, 0xac, 0x20, 0xe5, 0x51, 0x7b, 0xa6, 0x6d, 0xba, 0x00, 0x73, 0xcd, 0xe0, 0xa1, 0x9d, 0x0b, 0x52, 0xe0, 0x11, 0x46, 0xff, 0x18, 0x46, 0x0a, 0x80, 0x1c, 0xe7, 0xc7, 0x11, 0x6a, 0x06, 0x77, 0xec, 0x40, 0xfc, 0x45, 0xe1, 0xe2, 0x8e, 0x3d, 0xc2, 0x6e, 0x01, 0xa4, 0x07, 0x56, 0xd7, 0xa8, 0x39, 0x8c, 0x54, 0x88, 0xa7, 0x96, 0x8f, 0x0b, 0x55, 0x41, 0x39, 0x2e, 0x62, 0x83, 0x8e, 0x96, 0xe4, 0x42, 0xc8, 0xd9, 0x36, 0x5b, 0x4c, 0x2a, 0xdc, 0x3a, 0x4c, 0x73, 0x7a, 0xde, 0x75, 0x9f, 0x98, 0x4d, 0xf1, 0x23, 0xd5, 0x53, 0xf3, 0x51, 0x79, 0x26, 0x3a, 0x48, 0xc9, 0xd0, 0xa3, 0x0a, 0xb9, 0x38, 0x43, 0x84, 0x33, 0x5d, 0x66, 0x76, 0x1d, 0xcb, 0xef, 0x98, 0x9b, 0xab, 0xb4, 0xef, 0x11, 0x5d, 0x61, 0xbe, 0x84, 0xcf, 0x6a, 0x05, 0x0e, 0x46, 0x7c, 0x9b, 0x7c, 0xd9, 0x1e, 0x14, 0xea, 0x03, 0xa3, 0xf4, 0x19, 0x59, 0xf0, 0xa1, 0xb8, 0x5c, 0xd0, 0x53, 0x85, 0x09, 0x82, 0x4a, 0x67, 0x6c, 0xe7, 0x2f, 0x69, 0x98, 0x4f, 0x7f, 0xbe, 0x83, 0x93, 0x82, 0x40, 0xde, 0x28, 0xfd, 0xec, 0xd7, 0x59, 0x49, 0xc8, 0x0e, 0x2e, 0x98, 0x69, 0x51, 0x34, 0x71, 0x75, 0x19, 0xac, 0x7c, 0xac, 0x6f, 0xdb, 0x24, 0x48, 0xbb, 0xa5, 0x13, 0x23, 0x02, 0xbc, 0xe2, 0x62, 0x32, 0x12, 0xa9, 0x15, 0x15, 0x16, 0x92, 0x54, 0x4f, 0xa3, 0xa2, 0x27, 0x8b, 0x14, 0x61, 0x57, 0x8d, 0x6d, 0x24, 0x87, 0x0d, 0x36, 0x5c, 0x5d, 0x10, 0xf1, 0x27, 0xf2, 0x36, 0xf1, 0xc4, 0x32, 0x28, 0x20, 0x23, 0xc2, 0x83, 0x51, 0x21, 0xe5, 0xe1, 0x60, 0x10, 0x2e, 0x38, 0xc8, 0xc2, 0x05, 0x73, 0xd2, 0x6e, 0xb3, 0x0f, 0x20, 0xfe, 0xd9, 0x1b, 0x99, 0xbc, 0x09, 0x3a, 0x69, 0x20, 0xd6, 0xb6, 0x08, 0xc2, 0x62, 0xa5, 0x2d, 0xf5, 0x09, 0x1b, 0x12, 0xf2, 0x2b, 0x36, 0x29, 0xff, 0xfa, 0xec, 0x20, 0x0c, 0xdf, 0x15, 0x52, 0x56, 0x91, 0x34, 0x40, 0xbc, 0xdd, 0x86, 0x93, 0x01, 0x7d, 0xb9, 0x70, 0xdb, 0xff, 0xfa, 0x12, 0xe5, 0x4a, 0x1b, 0xec, 0x61, 0x8f, 0x28, 0x9e, 0xaa, 0x60, 0x31, 0x00, 0xc7, 0x7f, 0xcb, 0x1f, 0x94, 0x79, 0xd6, 0x79, 0x03, 0xce, 0x6b, 0x4c, 0x62, 0x26, 0xc8, 0x4f, 0xae, 0x9c, 0x14, 0x89, 0x54, 0x3c, 0x29, 0x74, 0xdd, 0x69, 0x9d, 0x84, 0x79, 0x40, 0x90, 0xc9, 0xe2, 0xbc, 0xfa, 0x94, 0x87, 0x86, 0x09, 0x19, 0x71, 0x29, 0x53, 0x77, 0xd2, 0x24, 0xf8, 0x69, 0xcb, 0x14, 0x34, 0x51, 0x58, 0x89, 0xa2, 0xd6, 0x17, 0xf2, 0xee, 0x51, 0x4f, 0x03, 0x9a, 0x9e, 0x6f, 0x58, 0x5f, 0xb8, 0xf9, 0x0f, 0x4f, 0x9c, 0x11, 0x64, 0x84, 0xa2, 0x89, 0x94, 0xca, 0x9a, 0x7a, 0x9e, 0xd1, 0xf8, 0x92, 0x4e, 0x45, 0xae, 0xd1, 0xab, 0x09, 0x4f, 0x0b, 0x32, 0x76, 0xf0, 0x39, 0x55, 0x77, 0x1e, 0xfe, 0xa5, 0xc2, 0xce, 0x3d, 0x3b, 0xd5, 0xc6, 0x6d, 0xb6, 0x70, 0x7a, 0x2b, 0x64, 0x20, 0x47, 0x71, 0x23, 0xf9, 0x40, 0x58, 0xd2, 0x68, 0x66, 0xf2, 0x8b, 0x48, 0xfa, 0x66, 0xa4, 0x80, 0x13, 0x4a, 0xc3, 0xe5, 0x2e, 0x65, 0xae, 0xd8, 0x61, 0xfb, 0xba, 0x67, 0x8d, 0x20, 0x54, 0x07, 0xa4, 0x91, 0x2f, 0x94, 0x08, 0x7c, 0xae, 0xc3, 0x6e, 0x79, 0x3a, 0xf4, 0xa3, 0xe9, 0xaf, 0xf7, 0x7b, 0x13, 0xa7, 0x29, 0xdb, 0xf5, 0x93, 0x3e, 0x9a, 0x14, 0xd6, 0x61, 0x45, 0x52, 0x9b, 0x19, 0xfe, 0xa3, 0x85, 0xc4, 0x00, 0x13, 0x31, 0xc8, 0x0d, 0x72, 0x72, 0x8e, 0x68, 0xd0, 0x82, 0x4f, 0x4b, 0xe5, 0x13, 0xe1, 0x96, 0x18, 0xb3, 0x8d, 0xcc, 0x50, 0x59, 0x2a, 0x46, 0xb2, 0x21, 0x98, 0x78, 0xf6, 0xf6, 0xc6, 0x3d, 0xce, 0x38, 0x92, 0x21, 0x33, 0x2a, 0x76, 0x70, 0xec, 0x58, 0x72, 0xfa, 0xde, 0x64, 0xda, 0x08, 0xc9, 0x93, 0x4c, 0xde, 0x1c, 0x86, 0x35, 0x52, 0x58, 0x5b, 0xb0, 0x8e, 0x03, 0x6e, 0x7e, 0xab, 0x11, 0x5e, 0x67, 0x18, 0x74, 0xc5, 0x83, 0xab, 0x6c, 0x10, 0x38, 0x73, 0x0f, 0x2e, 0x92, 0x28, 0x61, 0x7a, 0xd6, 0x45, 0xcb, 0xc0, 0x35, 0x57, 0x72, 0x03, 0x11, 0x12, 0x1f, 0x2b, 0x5d, 0xee, 0x9b, 0xdb, 0xa9, 0x10, 0xd6, 0x21, 0xb0, 0x1e, 0xfd, 0xbe, 0x6e, 0x4b, 0x27, 0xec, 0xc7, 0xc5, 0x46, 0xde, 0x0a, 0x53, 0x53, 0x64, 0xcf, 0x35, 0xc7, 0xf5, 0x02, 0x3a, 0x39, 0xb9, 0xf9, 0xfb, 0x2a, 0x8d, 0xc7, 0x67, 0x63, 0x09, 0x5e, 0x09, 0xd9, 0x16, 0x27, 0x8c, 0x9a, 0xfb, 0xb6, 0xf9, 0x5d, 0xa8, 0x37, 0x92, 0xde, 0x9f, 0x7b, 0x0b, 0x2d, 0xb1, 0x48, 0x09, 0x2e, 0x2e, 0x6a, 0x1c, 0x05, 0x2f, 0x27, 0x83, 0xf5, 0x37, 0xd2, 0x3f, 0xf3, 0x2c, 0x45, 0x80, 0xdc, 0x31, 0x68, 0x05, 0x81, 0x65, 0xa3, 0x1b, 0x6e, 0x5c, 0xaa, 0xf8, 0xa6, 0x60, 0x6a, 0x2e, 0x4d, 0x9d, 0x9c, 0x2f, 0xbf, 0x4c, 0x2e, 0xf3, 0x01, 0xc0, 0xa5, 0x59, 0x00, 0x7d, 0x61, 0x42, 0x21, 0xec, 0x2b, 0x13, 0xfd, 0x3c, 0x45, 0xb4, 0xcd, 0x01, 0x7c, 0x40, 0x47, 0x50, 0xdc, 0x7a, 0x33, 0x26, 0xc0, 0x9a, 0xb9, 0xf4, 0x8c, 0xa8, 0x00, 0xfb, 0x51, 0xbf, 0x04, 0x9b, 0x92, 0x4b, 0xd8, 0x06, 0xb2, 0x71, 0x8b, 0x3a, 0xee, 0x69, 0xc0, 0x2c, 0xc9, 0x5f, 0x57, 0x45, 0x62, 0xa2, 0xdc, 0x89, 0x14, 0xcb, 0x40, 0x74, 0xbb, 0x99, 0x56, 0x0c, 0xb5, 0xdd, 0x11, 0x12, 0xc3, 0x9b, 0x5e, 0x17, 0xdd, 0x4d, 0xcf, 0x1c, 0x4b, 0x5f, 0x3e, 0xd2, 0x45, 0x20, 0x12, 0xc2, 0xeb, 0x70, 0x09, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x02, 0xe4, 0x61, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xe0, 0x07, 0xec, 0x81, 0x00, 0x00, 0xb3, 0x9c, 0x26, 0x3a, 0x16, 0x44, 0x6e, 0xe1, 0xfb, 0x28, 0x93, 0x4d, 0x84, 0x3a, 0x9f, 0xe0, 0xb6, 0x9c, 0x08, 0xe9, 0xb2, 0x19, 0xe5, 0xb2, 0xb4, 0x79, 0x1c, 0x3c, 0x44, 0xa3, 0xe5, 0x33, 0x62, 0xf2, 0x26, 0xdd, 0xef, 0x55, 0x90, 0x47, 0x4c, 0xb6, 0xc2, 0x33, 0x7f, 0xc4, 0xd0, 0x9d, 0x79, 0xcd, 0x9b, 0xf0, 0x47, 0xe4, 0x57, 0xa5, 0x81, 0x51, 0xd8, 0x0c, 0x8d, 0xa4, 0x73, 0xd9, 0xae, 0x6f, 0xaa, 0xfc, 0x73, 0x96, 0xe1, 0x01, 0x40, 0xe8, 0x30, 0xb7, 0x8d, 0x11, 0x95, 0x0d, 0xc8, 0x31, 0x8e, 0x24, 0x93, 0x6e, 0xb4, 0xfc, 0xe8, 0xe0, 0x94, 0x29, 0x6a, 0x6e, 0x98, 0x01, 0x6d, 0x04, 0xde, 0x04, 0xac, 0xf0, 0xcf, 0x89, 0xaf, 0x79, 0xd6, 0xc1, 0xf4, 0x82, 0x90, 0x78, 0xd0, 0x91, 0x8c, 0x6f, 0x0d, 0xc8, 0x80, 0xce, 0x67, 0x3f, 0x2a, 0x86, 0x43, 0x4a, 0x6e, 0x33, 0x87, 0x9c, 0xc5, 0x72, 0xae, 0xc1, 0x90, 0xda, 0x96, 0x46, 0xf1, 0x86, 0x0c, 0x3b, 0xe1, 0x52, 0xad, 0x7b, 0x90, 0xbe, 0x81, 0x91, 0x22, 0xa5, 0xee, 0x65, 0xef, 0xb4, 0x3c, 0xd6, 0x21, 0xd5, 0x30, 0xc7, 0x24, 0x4f, 0x2a, 0x70, 0x81, 0xf4, 0x27, 0xab, 0x2f, 0x2d, 0x75, 0xc6, 0x34, 0xda, 0x36, 0x3c, 0xfa, 0x55, 0x79, 0xd1, 0xe3, 0xee, 0xcd, 0x88, 0x84, 0xd7, 0x1e, 0x95, 0x9c, 0x68, 0x73, 0x07, 0xbb, 0xff, 0x9b, 0x50, 0xbc, 0xdf, 0x12, 0xde, 0xfb, 0xb4, 0x14, 0xe1, 0x41, 0x9f, 0x1e, 0xe3, 0x96, 0xb3, 0xc4, 0x12, 0x2b, 0x7f, 0xb6, 0x73, 0x7c, 0x25, 0x66, 0xa9, 0x6d, 0x4b, 0x81, 0x7f, 0xda, 0x66, 0x88, 0xca, 0x9a, 0x40, 0xa8, 0x57, 0xed, 0x56, 0x7b, 0x39, 0xe9, 0x53, 0x00, 0xeb, 0x7c, 0x7b, 0x7e, 0x96, 0x21, 0x78, 0x13, 0xee, 0x24, 0x52, 0xdd, 0x14, 0x54, 0xc7, 0x98, 0xff, 0x01, 0x9f, 0x63, 0x3b, 0xc1, 0x11, 0x31, 0x96, 0x63, 0x2b, 0xca, 0x38, 0x9d, 0xb3, 0xda, 0xcb, 0x48, 0x72, 0xa2, 0x60, 0xaa, 0x4e, 0xb4, 0xb3, 0xad, 0x66, 0xed, 0x2c, 0x27, 0x43, 0xa2, 0x88, 0x05, 0x39, 0x62, 0x47, 0x79, 0x9d, 0x3f, 0xe3, 0x7d, 0xc5, 0xfb, 0x9f, 0x6a, 0x72, 0xce, 0x24, 0xbf, 0x61, 0x02, 0x23, 0xde, 0x00, 0x84, 0xcc, 0xd8, 0xd5, 0x8e, 0xe3, 0xd3, 0xc9, 0x47, 0x29, 0x83, 0x7a, 0x81, 0xc0, 0x52, 0xcb, 0x4e, 0x1f, 0x61, 0x16, 0x3f, 0x95, 0xc8, 0x2a, 0xf9, 0x0d, 0x3b, 0xb2, 0x6f, 0x2b, 0x89, 0x22, 0xd4, 0xf3, 0x62, 0xc8, 0x49, 0x45, 0xce, 0x7d, 0xa9, 0x4b, 0xc5, 0x02, 0x17, 0x96, 0x9c, 0xcd, 0x87, 0x99, 0x1c, 0xa8, 0xb3, 0xb3, 0xf9, 0xab, 0x27, 0x04, 0xf9, 0x3a, 0xf9, 0xd8, 0x92, 0xb8, 0x3f, 0x3c, 0x66, 0x0e, 0x62, 0xf9, 0x86, 0xfe, 0x4e, 0xe6, 0x57, 0xf7, 0xa2, 0x7f, 0x0b, 0x7f, 0xf5, 0x42, 0xbb, 0xb0, 0x5e, 0xc2, 0xc3, 0x4c, 0x8f, 0xc7, 0x97, 0xa8, 0x63, 0xbb, 0x20, 0x41, 0xc8, 0x67, 0x61, 0x08, 0x27, 0x4a, 0x4b, 0x72, 0x81, 0x4c, 0xca, 0x85, 0xed, 0x93, 0x81, 0x41, 0x60, 0x16, 0x85, 0xaa, 0x7e, 0x56, 0x07, 0x65, 0xd3, 0xe9, 0x35, 0x0b, 0xf7, 0x96, 0xbc, 0x00, 0x31, 0x5a, 0xae, 0x68, 0xe7, 0x94, 0x97, 0x29, 0x2a, 0xec, 0x0b, 0xc7, 0x89, 0xa0, 0x03, 0xd2, 0xc0, 0x35, 0x11, 0xa9, 0xe7, 0x19, 0x6e, 0x5b, 0x83, 0x40, 0xe6, 0xf5, 0xf4, 0x90, 0x6c, 0xdc, 0x8c, 0xe4, 0xac, 0xde, 0xb7, 0x9f, 0x15, 0x54, 0xaa, 0x46, 0x56, 0xf1, 0x60, 0xe6, 0x77, 0x1b, 0x80, 0xa5, 0x21, 0xb9, 0x5b, 0x93, 0x6d, 0x7e, 0xf0, 0x06, 0x5f, 0x65, 0xc7, 0xdc, 0x5f, 0x12, 0x88, 0x31, 0x2f, 0x78, 0x8b, 0x56, 0xea, 0x23, 0x9a, 0xf7, 0x7c, 0xcc, 0x96, 0x56, 0xc8, 0x49, 0x86, 0xb0, 0x90, 0x71, 0xc0, 0x83, 0xc5, 0xdd, 0xa3, 0x40, 0xa2, 0x11, 0x7d, 0xc3, 0xc5, 0x07, 0x05, 0xe1, 0x19, 0x6c, 0xed, 0x23, 0x01, 0xf8, 0xbe, 0x96, 0xa9, 0x6f, 0x66, 0xb3, 0xcd, 0x88, 0xc2, 0xf0, 0x19, 0xaf, 0x4b, 0x79, 0x16, 0xdf, 0x84, 0x28, 0x28, 0x3e, 0x05, 0xe4, 0xcb, 0xf7, 0x69, 0x45, 0xf8, 0x31, 0xb9, 0x35, 0xad, 0xc0, 0x71, 0xf5, 0xd9, 0x38, 0xc7, 0xa2, 0xd3, 0xf6, 0x5b, 0xf6, 0xb4, 0xc0, 0x3d, 0x3f, 0x1d, 0xdf, 0xad, 0x05, 0xf6, 0x15, 0x01, 0x1f, 0xdd, 0x03, 0x3d, 0x9e, 0xb5, 0x9a, 0x16, 0xdc, 0xf5, 0x6c, 0x8e, 0x59, 0x03, 0xa8, 0x84, 0x6b, 0x16, 0x43, 0xf0, 0x57, 0xcb, 0x5e, 0xa4, 0x74, 0x26, 0x88, 0xac, 0x41, 0x8d, 0x97, 0xd0, 0x69, 0x6c, 0xeb, 0x32, 0xc4, 0xda, 0x5e, 0x02, 0xa2, 0x36, 0x5e, 0x07, 0x81, 0x26, 0x38, 0x0c, 0x73, 0x26, 0x12, 0x8f, 0x90, 0xff, 0xdc, 0x5b, 0x69, 0xd9, 0x2f, 0xc4, 0x67, 0xbb, 0xc6, 0x14, 0x36, 0xba, 0xee, 0x3b, 0x2c, 0xb4, 0x22, 0x13, 0x89, 0x2e, 0xf4, 0x65, 0x1d, 0x22, 0x19, 0xbe, 0x9c, 0xf4, 0x00, 0x6c, 0xb2, 0x42, 0x5b, 0x65, 0x1a, 0x8a, 0x11, 0xae, 0xf6, 0x29, 0x8a, 0xbc, 0xef, 0xce, 0x8d, 0xeb, 0x7a, 0x9e, 0xb7, 0xb3, 0x5d, 0xfa, 0x07, 0xa4, 0x98, 0xa2, 0xbc, 0xbc, 0xb6, 0xca, 0x72, 0x00, 0x7c, 0xbf, 0xde, 0xe9, 0x5c, 0x12, 0x1f, 0x1e, 0x03, 0xaa, 0x15, 0xde, 0x7e, 0xfc, 0xfa, 0x4c, 0x97, 0x21, 0x77, 0xb1, 0xfa, 0x16, 0xa8, 0x8d, 0x88, 0x00, 0xc5, 0x9b, 0xb2, 0x2e, 0xd3, 0x65, 0xfc, 0x68, 0x44, 0x86, 0xf1, 0x08, 0xec, 0xa7, 0x88, 0xcd, 0x56, 0xf1, 0x09, 0x55, 0x1e, 0x6a, 0x6b, 0x71, 0x4b, 0x7b, 0x7f, 0x58, 0xf0, 0xd7, 0xd7, 0xe6, 0xb9, 0xe6, 0x5e, 0xef, 0xa2, 0xc0, 0x24, 0x8a, 0xee, 0xd5, 0xeb, 0x38, 0x0e, 0x9b, 0x18, 0x8b, 0x9c, 0x5f, 0xb2, 0x1e, 0x21, 0xb5, 0x1f, 0xb7, 0xef, 0xf5, 0xa4, 0xdf, 0xae, 0x07, 0xcd, 0xf8, 0x7f, 0xe4, 0x13, 0x0a, 0x90, 0x2e, 0x2a, 0x6d, 0xd3, 0x2b, 0x30, 0x06, 0x2f, 0xea, 0xd7, 0x26, 0x06, 0x94, 0xc3, 0x97, 0x6e, 0x00, 0x29, 0x80, 0x85, 0xa9, 0xb9, 0xfc, 0x86, 0x52, 0x78, 0x19, 0xdc, 0x82, 0xc7, 0xae, 0xda, 0x54, 0xc3, 0x27, 0x6d, 0xf9, 0x2e, 0xf8, 0x62, 0xcf, 0xe7, 0xd1, 0x27, 0x44, 0x2b, 0x7f, 0x97, 0xf1, 0xe7, 0x1a, 0x4f, 0x0d, 0xae, 0x93, 0x77, 0x96, 0x41, 0xfb, 0x3c, 0x40, 0xb0, 0xc2, 0xef, 0x5e, 0x7b, 0x50, 0x4e, 0xb3, 0x73, 0xbb, 0xf9, 0x29, 0x22, 0x82, 0x3a, 0x0f, 0xf9, 0x99, 0x42, 0x1a, 0xf5, 0x4e, 0x13, 0xa1, 0x16, 0xc5, 0x00, 0xd9, 0xa6, 0x25, 0xdd, 0x14, 0xf8, 0xd7, 0x87, 0xc7, 0x67, 0x13, 0xc4, 0x09, 0xaa, 0xa9, 0xab, 0x51, 0x2b, 0xf2, 0xbf, 0x81, 0xfb, 0xcd, 0x8d, 0x53, 0xf7, 0xc7, 0x9b, 0xe2, 0xdc, 0xe9, 0x7c, 0xa3, 0x27, 0x79, 0xe4, 0xc5, 0x00, 0x8f, 0x40, 0xf8, 0x71, 0xcf, 0x80, 0xf6, 0xa2, 0xc2, 0x9e, 0x62, 0xcc, 0x71, 0x2c, 0xc8, 0x88, 0xde, 0x76, 0xdd, 0x5e, 0xfa, 0xbc, 0xdd, 0x9e, 0x30, 0xbd, 0x2f, 0x90, 0x0d, 0x0b, 0x3f, 0x66, 0x5a, 0xb3, 0x76, 0x0f, 0x3a, 0xd8, 0x14, 0xec, 0xc2, 0x24, 0x56, 0x5b, 0xe2, 0xf8, 0xe2, 0xac, 0x05, 0x70, 0x92, 0xf6, 0x5b, 0xf5, 0x77, 0x60, 0xa8, 0x55, 0xbe, 0x6a, 0xf1, 0x54, 0x87, 0x62, 0xfe, 0x0c, 0xb5, 0x2c, 0x25, 0x8f, 0xc7, 0xff, 0xdf, 0x0e, 0x66, 0x2a, 0xd5, 0xb2, 0x4d, 0x75, 0x8e, 0xa7, 0xcc, 0x17, 0x10, 0x32, 0xfb, 0xeb, 0x67, 0xc0, 0x19, 0x80, 0x0d, 0xd0, 0xfc, 0x69, 0xaa, 0xd0, 0xe1, 0x9e, 0xff, 0xd6, 0x41, 0xbb, 0xe9, 0x1a, 0x04, 0x13, 0x4f, 0x82, 0x1e, 0x30, 0x20, 0xea, 0x77, 0x85, 0x05, 0x75, 0x6c, 0x0c, 0xc8, 0x66, 0x62, 0x77, 0xbd, 0xaf, 0xf3, 0xfa, 0x06, 0x4b, 0xb9, 0xc3, 0xb2, 0xc3, 0x63, 0x64, 0x02, 0x81, 0x2a, 0x8d, 0x02, 0x5a, 0x87, 0x94, 0x0f, 0x4f, 0x22, 0x1e, 0x30, 0x4c, 0x44, 0xac, 0xf0, 0x2d, 0x87, 0xe1, 0x56, 0x61, 0xe9, 0xa6, 0xcc, 0xa6, 0x39, 0xba, 0xac, 0xeb, 0x49, 0x7c, 0x04, 0xbb, 0xeb, 0x77, 0x5c, 0x9b, 0xc8, 0x69, 0xf4, 0x9a, 0xfb, 0xac, 0xa6, 0x54, 0xd7, 0x7b, 0x4e, 0x53, 0x74, 0x95, 0x6a, 0xa2, 0x7a, 0x9b, 0x10, 0x0a, 0x10, 0x1d, 0xae, 0x4e, 0xf7, 0xf4, 0x38, 0xd7, 0x4f, 0x94, 0xb4, 0xc1, 0x16, 0xee, 0xce, 0xab, 0x0f, 0xaf, 0x89, 0x85, 0x2a, 0x66, 0xb9, 0x5c, 0xfb, 0xf8, 0xd1, 0xa8, 0xc5, 0x01, 0xf6, 0x98, 0xac, 0x77, 0xce, 0x4b, 0xaa, 0xc3, 0xe3, 0x1d, 0x23, 0x23, 0xec, 0xb4, 0x92, 0xcf, 0xa5, 0xbf, 0x9f, 0xac, 0x92, 0x6f, 0xa7, 0xdf, 0xf4, 0x46, 0x81, 0x3d, 0x93, 0x85, 0x03, 0x7a, 0x7a, 0x65, 0xed, 0xe1, 0x22, 0xd5, 0x5a, 0xcb, 0x9b, 0x6b, 0x3c, 0xa0, 0x81, 0xc3, 0xc2, 0x3b, 0x8c, 0x2e, 0x7e, 0xfb, 0xf2, 0x97, 0x9d, 0x2b, 0x5f, 0x81, 0x31, 0xdc, 0xce, 0xec, 0x88, 0x9c, 0x70, 0x84, 0xed, 0x5f, 0xac, 0xbd, 0x76, 0x0e, 0xab, 0x1f, 0x15, 0x97, 0xbe, 0xd1, 0x74, 0x5d, 0x3a, 0x0a, 0xe0, 0xd7, 0x4a, 0x79, 0xb0, 0xd2, 0xf5, 0x70, 0x72, 0x6a, 0xa0, 0x50, 0xd2, 0x15, 0x97, 0xc9, 0xb6, 0x6f, 0x3c, 0xd7, 0x71, 0x94, 0x64, 0x7e, 0x15, 0xa1, 0x90, 0xe2, 0xa4, 0xed, 0xef, 0x00, 0x4d, 0xb8, 0xea, 0x48, 0x00, 0x18, 0x73, 0x24, 0x54, 0xb7, 0x96, 0x37, 0x5f, 0x04, 0xb3, 0x50, 0x06, 0xfe, 0x1c, 0x2e, 0x23, 0x19, 0xce, 0x8a, 0x64, 0x02, 0xfa, 0x6e, 0x77, 0xd2, 0xd4, 0x0b, 0x96, 0xc5, 0xfa, 0x04, 0xc5, 0x35, 0x24, 0x9d, 0x55, 0x6a, 0xac, 0x4e, 0x2a, 0x85, 0x44, 0xa8, 0xba, 0xde, 0x2d, 0x54, 0x26, 0xf4, 0x51, 0x78, 0x47, 0x93, 0x0b, 0x00, 0xa8, 0x88, 0x24, 0xac, 0x05, 0x56, 0x6c, 0xb7, 0xe0, 0x4c, 0xc6, 0xc4, 0x74, 0xe7, 0xc5, 0x77, 0xfd, 0x8f, 0x3a, 0x77, 0x1b, 0xb8, 0xc7, 0xca, 0x12, 0x9c, 0xcc, 0x86, 0x0a, 0x77, 0xba, 0x1d, 0x79, 0x42, 0xba, 0x01, 0x52, 0x97, 0x9d, 0x84, 0xdb, 0xdc, 0xbf, 0x27, 0x1e, 0x82, 0x22, 0x2e, 0x10, 0xb3, 0x1a, 0x2a, 0x95, 0x34, 0x84, 0x1d, 0x68, 0xda, 0xec, 0xc3, 0xc7, 0x19, 0xcb, 0xe1, 0x12, 0x98, 0xac, 0x78, 0xad, 0x18, 0xe7, 0xa0, 0xfe, 0x26, 0xae, 0xd7, 0xda, 0x38, 0xce, 0x83, 0x0d, 0xdb, 0x0d, 0xea, 0x02, 0x21, 0x3e, 0x03, 0x71, 0x9a, 0x4d, 0xc6, 0x2f, 0x8a, 0xe6, 0x5f, 0x12, 0x60, 0xfe, 0x88, 0x4b, 0x1d, 0x1f, 0x9c, 0x6f, 0x72, 0x0e, 0xdb, 0x5d, 0xcf, 0x19, 0x95, 0xeb, 0x9e, 0x18, 0xa6, 0x14, 0xe2, 0x81, 0x50, 0x45, 0x7d, 0x0b, 0xb4, 0x27, 0x56, 0xda, 0x22, 0x9a, 0x4b, 0x98, 0xed, 0x3e, 0x0e, 0xd8, 0xe7, 0x96, 0xe9, 0xa0, 0x5b, 0x41, 0xbe, 0x3a, 0x5c, 0x11, 0x99, 0x98, 0x86, 0x5a, 0xe6, 0xba, 0xe5, 0xc7, 0x3f, 0xa8, 0x13, 0x26, 0x26, 0x53, 0x4c, 0x8b, 0x76, 0xa6, 0xee, 0x0f, 0x04, 0x02, 0x5d, 0x34, 0xf1, 0x94, 0x79, 0x4d, 0x44, 0x8d, 0x8b, 0xf6, 0x9e, 0xbf, 0x3c, 0x88, 0xee, 0xcf, 0x75, 0x28, 0xfe, 0xfb, 0x89, 0x77, 0xb7, 0x33, 0xd9, 0xe0, 0x3c, 0x92, 0x14, 0x1c, 0x8e, 0xcb, 0x9b, 0x49, 0x4b, 0xd7, 0x02, 0x4d, 0xdd, 0xea, 0x57, 0x5c, 0x03, 0xd2, 0xbe, 0x06, 0x67, 0x75, 0x55, 0x48, 0x06, 0x78, 0xc6, 0x6f, 0xe9, 0x80, 0x61, 0xc3, 0xc5, 0xeb, 0xdd, 0x44, 0xd7, 0xd6, 0x22, 0x13, 0xeb, 0x4b, 0x22, 0xfc, 0xfa, 0xa0, 0xa9, 0xd7, 0x6f, 0x20, 0x29, 0x74, 0xe9, 0x27, 0x19, 0xbc, 0x57, 0x30, 0x91, 0x1c, 0x16, 0x86, 0x7a, 0xf4, 0x71, 0xbe, 0x67, 0x33, 0xde, 0xfc, 0x96, 0x61, 0xa9, 0x8e, 0x9b, 0x3f, 0x7e, 0xc9, 0xb2, 0xe2, 0xea, 0x07, 0xe2, 0x0c, 0xf6, 0x58, 0x12, 0x2d, 0x18, 0x73, 0x9e, 0x8b, 0xfe, 0xe1, 0x7c, 0x55, 0x7c, 0x81, 0x35, 0x85, 0x0d, 0xf1, 0x0d, 0xa2, 0x0a, 0x5f, 0x32, 0x52, 0x90, 0xd5, 0xad, 0xc4, 0xcc, 0xdf, 0x2f, 0xd4, 0xf1, 0x65, 0xeb, 0xdd, 0xf0, 0x77, 0x9e, 0x70, 0x25, 0x8d, 0x44, 0xae, 0x6b, 0x25, 0x1b, 0x1a, 0xce, 0x39, 0x2e, 0xe0, 0xc7, 0xa4, 0xc5, 0x8a, 0x96, 0xd7, 0x25, 0x28, 0xb2, 0x38, 0x35, 0x62, 0xbd, 0x8b, 0x12, 0x84, 0x47, 0xa4, 0xf3, 0x72, 0x06, 0x33, 0x7f, 0xc7, 0x35, 0xa5, 0x5c, 0x8b, 0x57, 0x9d, 0xd5, 0x3f, 0xc6, 0x64, 0xa8, 0xaf, 0xbf, 0x51, 0x8f, 0xcc, 0x88, 0x15, 0x34, 0xea, 0xc3, 0x13, 0x71, 0x02, 0x12, 0xa6, 0xb9, 0x01, 0x58, 0xe7, 0x3a, 0x24, 0x8f, 0x31, 0xa7, 0xfb, 0x4d, 0x1e, 0x76, 0x44, 0xb2, 0xd8, 0x15, 0xe5, 0xf6, 0x79, 0x37, 0x00, 0x0d, 0x3f, 0x12, 0xcf, 0x2b, 0x10, 0xa2, 0x51, 0x28, 0x99, 0x88, 0xc6, 0x33, 0xf7, 0xf3, 0x3f, 0xf9, 0xd2, 0xa9, 0x00, 0x3a, 0x1f, 0xfa, 0x28, 0xb2, 0xe5, 0x2c, 0xd0, 0x7d, 0x9a, 0x14, 0xcd, 0x2e, 0x20, 0x27, 0x71, 0x57, 0x73, 0x78, 0x61, 0x99, 0x9b, 0x2b, 0x98, 0xa0, 0x0b, 0xf3, 0x4a, 0x36, 0x1c, 0xd1, 0x38, 0x91, 0xda, 0x0c, 0xf2, 0x38, 0x27, 0x41, 0x69, 0xa7, 0xe9, 0x88, 0x9d, 0xe8, 0xcf, 0xe7, 0x0c, 0xe2, 0x61, 0x25, 0x5a, 0xb4, 0xce, 0x4e, 0x1d, 0xbd, 0x6f, 0x8f, 0x06, 0x20, 0xb1, 0x4a, 0x24, 0x46, 0x84, 0xfe, 0xaa, 0x82, 0x07, 0x59, 0x08, 0x79, 0xd9, 0xc3, 0xb5, 0x14, 0xce, 0x1a, 0xd8, 0x76, 0x06, 0x39, 0x09, 0x2f, 0x18, 0x4e, 0x6b, 0x1c, 0xe3, 0xb6, 0xff, 0x96, 0xbe, 0x39, 0x8d, 0xa1, 0x46, 0xe4, 0x3b, 0xeb, 0x85, 0xf5, 0xe5, 0x7c, 0x05, 0xf2, 0x39, 0xcd, 0x0d, 0x7b, 0xa0, 0x95, 0x5c, 0x03, 0x99, 0xaa, 0x53, 0xca, 0x12, 0xb3, 0x25, 0x9a, 0x0a, 0x2f, 0x4b, 0x3f, 0x89, 0x28, 0x12, 0x27, 0x31, 0x2c, 0xce, 0x55, 0x2f, 0x4d, 0xb1, 0xfb, 0x2a, 0x5e, 0x3b, 0x8f, 0x73, 0x1d, 0x4d, 0xfa, 0x20, 0x8f, 0x3b, 0x8d, 0x83, 0x08, 0xb3, 0x53, 0xb6, 0x0f, 0xcb, 0xe9, 0xa3, 0xde, 0x25, 0xa1, 0xbc, 0x0e, 0x1c, 0x15, 0x9c, 0xc4, 0x2f, 0xee, 0x39, 0x41, 0xf9, 0xe4, 0x57, 0x14, 0xf3, 0x4a, 0x92, 0xeb, 0xae, 0xbf, 0x1c, 0x18, 0x01, 0xbd, 0x78, 0xa1, 0xf6, 0xbe, 0x40, 0x0e, 0xcb, 0x35, 0x1c, 0x7e, 0x17, 0x8c, 0x2e, 0xc3, 0xb3, 0x8d, 0xa1, 0xbe, 0xec, 0x04, 0x35, 0x6a, 0x2f, 0xe0, 0xd0, 0x94, 0x63, 0xca, 0x86, 0x19, 0x1a, 0xdc, 0x70, 0xf9, 0x5d, 0x06, 0xf1, 0xeb, 0x4c, 0x04, 0x05, 0x25, 0x7e, 0xe1, 0xfa, 0x14, 0x01, 0x06, 0x21, 0x95, 0x50, 0x8b, 0x3f, 0xd8, 0xee, 0x11, 0xc2, 0x79, 0xb7, 0x54, 0x50, 0x66, 0x0d, 0xed, 0x83, 0x5c, 0x38, 0xed, 0x54, 0x11, 0x0a, 0xb3, 0x52, 0x50, 0x05, 0x7a, 0x58, 0xb9, 0xe2, 0xea, 0xde, 0x00, 0x00, 0x01, 0xb7 }; +constexpr AccessUnit M2V_LARGE_AU_EXPECTED_AU = { 0x15f90, 0x159b2, true, 0, {}, { 0x60, 0x03, 0x38, 0xf1, 0x3d, 0xc4, 0xab, 0x4f, 0x09, 0xbd, 0xc3, 0xae, 0x12, 0xf0, 0xc2, 0xb8, 0x16, 0x3e, 0xa1, 0x92 } }; + +const std::vector ATRACX_LARGE_AU_STREAM = { 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xbd, 0x06, 0xe6, 0x81, 0xc1, 0x0d, 0x31, 0x00, 0x05, 0xbf, 0x21, 0x11, 0x00, 0x05, 0xb3, 0x65, 0x1e, 0x69, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xd0, 0xfd, 0xff, 0xe6, 0x35, 0x3c, 0xd3, 0x39, 0xd0, 0x8e, 0x3e, 0x56, 0x34, 0x97, 0x50, 0xf0, 0x75, 0x62, 0x8f, 0x4f, 0x2e, 0x75, 0x9c, 0x56, 0xc5, 0xcb, 0x1f, 0xa9, 0x84, 0xd5, 0xe2, 0x85, 0xec, 0xcf, 0x29, 0xcc, 0xbd, 0xc6, 0x77, 0xff, 0x7d, 0x1b, 0xec, 0x2c, 0x85, 0x65, 0x1f, 0xeb, 0x71, 0x26, 0x0d, 0x71, 0x01, 0x09, 0x7a, 0xb2, 0xed, 0x0b, 0x50, 0x39, 0x71, 0x96, 0xc9, 0x38, 0x98, 0x7b, 0x43, 0x4c, 0xa1, 0x7f, 0xac, 0xe2, 0x26, 0x30, 0xfc, 0xc0, 0x89, 0xb2, 0x6b, 0x09, 0xbf, 0x39, 0x02, 0x2f, 0x9f, 0x40, 0x3d, 0x17, 0xd3, 0x29, 0x03, 0xa4, 0x28, 0x30, 0x55, 0xa9, 0x36, 0x87, 0x10, 0xf3, 0x31, 0x88, 0x89, 0xda, 0x33, 0x88, 0x04, 0x49, 0x00, 0x81, 0x49, 0x5c, 0xe3, 0x8c, 0x83, 0x11, 0xc0, 0x84, 0xcd, 0xb5, 0x95, 0x29, 0x91, 0x83, 0x4b, 0xc8, 0x50, 0xf4, 0x5d, 0xb5, 0xeb, 0x28, 0xdc, 0x3a, 0x79, 0x68, 0x6e, 0x2b, 0x78, 0x06, 0x67, 0x83, 0x3b, 0x10, 0x7e, 0xba, 0x58, 0x72, 0x06, 0xce, 0x41, 0xed, 0xe1, 0xb7, 0x4d, 0x0e, 0x3d, 0x4a, 0xc2, 0x0b, 0xb7, 0xb1, 0x3b, 0x9a, 0x23, 0x6e, 0x1c, 0xaf, 0x02, 0xfa, 0x73, 0x0d, 0x58, 0x15, 0x33, 0x4f, 0x2f, 0x6b, 0x91, 0x82, 0x1a, 0x8d, 0xb6, 0xc2, 0x44, 0x96, 0x08, 0x9e, 0x69, 0x53, 0xb1, 0x5b, 0x2d, 0x3d, 0xa4, 0xac, 0xac, 0xf1, 0x54, 0xb3, 0xfe, 0x6a, 0x21, 0x67, 0x19, 0xfa, 0x37, 0x99, 0x41, 0x08, 0x81, 0xf6, 0xac, 0x12, 0x1d, 0x98, 0xef, 0x7a, 0x4b, 0xcc, 0xb2, 0xea, 0xdb, 0x08, 0x5e, 0xad, 0x02, 0xe6, 0x6e, 0x83, 0x10, 0x12, 0x3b, 0x7e, 0xc7, 0xdc, 0xc0, 0xd7, 0x26, 0x48, 0x6a, 0x66, 0x01, 0x11, 0x35, 0xc3, 0x4a, 0xce, 0xd6, 0x03, 0xe7, 0x29, 0x6a, 0x22, 0x3a, 0x8e, 0x55, 0x8c, 0x8a, 0xc8, 0xad, 0x3b, 0x22, 0xb9, 0xfa, 0xc1, 0x05, 0x4e, 0xd2, 0x9e, 0x84, 0xdf, 0x6f, 0xec, 0x2a, 0x75, 0x9b, 0x7f, 0xcc, 0x3b, 0xeb, 0x59, 0xb9, 0xf3, 0x02, 0x99, 0x50, 0x79, 0x41, 0x1e, 0x58, 0x8b, 0x6c, 0x39, 0x08, 0xce, 0x90, 0xb6, 0x5c, 0x59, 0x2c, 0x0b, 0xd2, 0xa0, 0xae, 0x47, 0xa9, 0x01, 0x81, 0xe4, 0xda, 0x5c, 0xdb, 0x68, 0xac, 0xda, 0xa5, 0xcf, 0xfe, 0x71, 0xed, 0xab, 0x00, 0x4a, 0xcf, 0x62, 0x95, 0xce, 0x74, 0xf4, 0x48, 0x18, 0xab, 0x00, 0xe2, 0x43, 0x5a, 0x9f, 0xff, 0x03, 0xdd, 0xd5, 0xd3, 0xd4, 0x22, 0xcb, 0x83, 0x9d, 0x0f, 0xd0, 0x43, 0x1f, 0x3d, 0xfa, 0x0c, 0x39, 0x89, 0x33, 0x4f, 0x6c, 0xdd, 0x40, 0x8e, 0xb8, 0x4d, 0x75, 0x38, 0x3d, 0x1e, 0x6c, 0x0a, 0x8f, 0xd4, 0x07, 0x71, 0xcf, 0x8b, 0xa8, 0x65, 0x4a, 0xb4, 0xc9, 0x9f, 0x4a, 0x6f, 0xee, 0xab, 0x2a, 0xee, 0xc1, 0x5b, 0x88, 0xe6, 0x93, 0x7c, 0x7b, 0x23, 0xee, 0x1a, 0xab, 0xb6, 0x82, 0x03, 0x63, 0x24, 0x8e, 0xea, 0xd3, 0xdc, 0x1f, 0x8e, 0x3d, 0x6a, 0xb9, 0x96, 0x79, 0xd2, 0x8f, 0x37, 0x23, 0x9d, 0x1b, 0x58, 0x38, 0xb4, 0x9e, 0x50, 0x8e, 0x13, 0x00, 0xcc, 0x22, 0x17, 0x25, 0x04, 0xde, 0x29, 0xea, 0x36, 0xac, 0x1a, 0x70, 0x7a, 0x15, 0x22, 0xbd, 0x14, 0x70, 0x08, 0x62, 0xfa, 0x1d, 0xeb, 0x37, 0xe1, 0xcd, 0x16, 0x8b, 0x3b, 0x24, 0x39, 0xec, 0xe8, 0x76, 0x4e, 0x50, 0x4a, 0x9f, 0x83, 0xc2, 0xb5, 0x9d, 0x1d, 0x71, 0xb3, 0x7f, 0xcd, 0x8d, 0x5d, 0x3e, 0x75, 0x6d, 0x3e, 0xd9, 0x2d, 0xfb, 0x3e, 0x0d, 0x95, 0x63, 0x3b, 0xe0, 0x34, 0x85, 0x91, 0xb3, 0x88, 0x6c, 0x87, 0x58, 0x60, 0x1c, 0x10, 0x4e, 0xd0, 0x18, 0x10, 0x77, 0x9f, 0xe1, 0x73, 0x05, 0x69, 0xd0, 0xc3, 0xe0, 0xa9, 0x7d, 0x11, 0x5f, 0xe8, 0xee, 0x05, 0xc3, 0x97, 0x19, 0x5b, 0x6f, 0xa9, 0x9f, 0xb8, 0x1c, 0x6c, 0x43, 0x40, 0x88, 0x7b, 0xc1, 0xf0, 0x5a, 0x2e, 0x5e, 0x2c, 0xf9, 0xd4, 0xbb, 0xef, 0x4a, 0x84, 0xe3, 0x3e, 0x9b, 0xbf, 0x62, 0x99, 0x8d, 0x5f, 0x26, 0x76, 0x39, 0x13, 0xc7, 0x8d, 0x36, 0xff, 0xa1, 0xf1, 0xd7, 0x47, 0xf7, 0x73, 0x10, 0x6e, 0x24, 0x1a, 0x44, 0xad, 0xca, 0xbd, 0xbc, 0xa6, 0xa8, 0xb4, 0x56, 0x26, 0xfc, 0x1f, 0x57, 0xe0, 0xca, 0x6e, 0x67, 0x33, 0x3e, 0x5f, 0x39, 0x47, 0x82, 0xb6, 0x54, 0xde, 0xc5, 0x92, 0xa8, 0xb7, 0xbc, 0x82, 0x03, 0xa7, 0x3d, 0x7b, 0x13, 0x70, 0x64, 0x57, 0x29, 0xa5, 0x33, 0x27, 0x63, 0xc1, 0xaa, 0x60, 0x3b, 0xe1, 0x91, 0xfd, 0x6c, 0x01, 0x88, 0x34, 0xc0, 0x07, 0xc3, 0x85, 0xfb, 0x1f, 0x12, 0xd7, 0x31, 0xfe, 0x78, 0xb8, 0x15, 0xe5, 0xc7, 0xf2, 0x97, 0x60, 0x05, 0xd1, 0x35, 0x34, 0x1b, 0x25, 0x4f, 0x35, 0xc6, 0x98, 0x12, 0x17, 0xc1, 0xe6, 0x42, 0xd0, 0xa3, 0xd7, 0xc8, 0xef, 0xed, 0x01, 0x7c, 0x3e, 0xc5, 0xc1, 0xf5, 0x02, 0xd7, 0x92, 0xea, 0x53, 0xfc, 0x65, 0xc4, 0x84, 0x85, 0x08, 0x1a, 0xbc, 0x07, 0xd2, 0xbc, 0xc4, 0x28, 0xf6, 0xab, 0xb0, 0x22, 0x9e, 0x05, 0x9b, 0xc6, 0xb4, 0x5e, 0x5f, 0xb5, 0xf5, 0x1f, 0x6c, 0xe0, 0xc8, 0xdb, 0x17, 0xd8, 0xe3, 0xdb, 0x50, 0x65, 0xef, 0x2a, 0xda, 0x40, 0x34, 0xc3, 0x21, 0x21, 0x13, 0x79, 0x12, 0x04, 0x84, 0x35, 0x34, 0x7f, 0x82, 0x37, 0xe8, 0x14, 0x29, 0x61, 0x2f, 0x19, 0xd2, 0xa2, 0x42, 0x93, 0x6f, 0x6d, 0x85, 0x38, 0x30, 0x6e, 0x25, 0x45, 0x78, 0xd5, 0x2a, 0xc4, 0x0e, 0xfd, 0xa0, 0xab, 0xa6, 0xae, 0xdc, 0x93, 0xa7, 0x72, 0x2a, 0x09, 0x04, 0xb4, 0x4e, 0xf2, 0x56, 0x00, 0x15, 0x98, 0x7f, 0x3b, 0x4f, 0x43, 0x90, 0x08, 0x42, 0xd0, 0x11, 0x93, 0x58, 0xd1, 0x23, 0xd4, 0x9a, 0x9a, 0x80, 0x0b, 0xf6, 0xa8, 0xe4, 0x17, 0x1a, 0xa8, 0xe3, 0x3d, 0x5a, 0x05, 0xf4, 0x73, 0xa7, 0x2d, 0xe6, 0xee, 0xa9, 0x78, 0xa2, 0x6e, 0x1b, 0xc2, 0x07, 0x04, 0xb8, 0x31, 0xb2, 0x01, 0x76, 0xba, 0x19, 0x0c, 0x0f, 0x4f, 0xce, 0xbe, 0x63, 0xa2, 0xb8, 0x80, 0xf2, 0x22, 0x8d, 0x0c, 0xdb, 0x25, 0x66, 0x7a, 0x40, 0xa3, 0x0b, 0xe2, 0x2f, 0x47, 0x4a, 0xfe, 0xd4, 0xd6, 0x12, 0x0f, 0x26, 0x5b, 0x04, 0xf4, 0x8c, 0xdf, 0x6b, 0x67, 0x45, 0x67, 0xe9, 0x62, 0xf3, 0x1d, 0x2c, 0x2e, 0x1a, 0xd6, 0x58, 0x43, 0x62, 0x03, 0x0a, 0xf1, 0xe6, 0x2d, 0xf8, 0xe0, 0x1a, 0x77, 0xbf, 0xe6, 0x39, 0x4c, 0x45, 0xaa, 0xce, 0xbf, 0x6c, 0x6c, 0xbb, 0x55, 0x91, 0x51, 0xd5, 0x49, 0x05, 0x1d, 0x39, 0xe4, 0xf6, 0x22, 0x20, 0x24, 0xc4, 0xb2, 0x83, 0xda, 0xb7, 0xb3, 0x86, 0xdf, 0x37, 0xe0, 0x01, 0xe1, 0x5b, 0x55, 0xd9, 0x60, 0x8b, 0x55, 0xcb, 0x28, 0x7f, 0xf9, 0xfa, 0x50, 0x0b, 0x4c, 0xc0, 0x18, 0x1d, 0x2e, 0x92, 0x19, 0x05, 0xa4, 0xd7, 0xde, 0xc7, 0x3e, 0xc4, 0x3f, 0x27, 0x56, 0x35, 0x00, 0xf5, 0xe3, 0x32, 0x71, 0xcb, 0xa0, 0x34, 0xa2, 0xbd, 0x3c, 0x6b, 0x17, 0x1e, 0x94, 0xb9, 0x7b, 0x62, 0xb8, 0xcb, 0xa4, 0xa2, 0x8a, 0x90, 0xb0, 0xc0, 0xb6, 0xc3, 0xfa, 0x9e, 0x1f, 0xa3, 0x75, 0x09, 0x71, 0x5d, 0x9c, 0x23, 0xdd, 0xf6, 0x6d, 0x4f, 0x42, 0xd2, 0xaf, 0x8d, 0x89, 0x54, 0xc1, 0xfd, 0x36, 0x25, 0x2c, 0x06, 0x2e, 0x4a, 0xea, 0x41, 0x63, 0x0e, 0x3d, 0xfc, 0x40, 0xa7, 0x71, 0x1c, 0x3c, 0x9c, 0x75, 0x02, 0xcb, 0xb3, 0x32, 0x6e, 0x33, 0xf5, 0x30, 0xb9, 0x63, 0x40, 0xd2, 0xb4, 0xff, 0xd5, 0x9e, 0xcd, 0x44, 0x9b, 0xeb, 0x4a, 0x43, 0x1d, 0x0f, 0xd0, 0x60, 0xa6, 0xad, 0x0a, 0xb7, 0x6d, 0xef, 0x82, 0x15, 0x02, 0x35, 0xd8, 0x4d, 0xdc, 0x1b, 0xdf, 0x1f, 0x69, 0x2c, 0x86, 0xdd, 0x11, 0x91, 0x22, 0x70, 0x74, 0x3e, 0x64, 0xef, 0x3f, 0xb2, 0xb1, 0xc3, 0xbe, 0x6e, 0x9d, 0x13, 0x8c, 0x8f, 0xff, 0xd6, 0x74, 0x0b, 0xc0, 0x89, 0x6a, 0x87, 0xd0, 0xe5, 0x4b, 0x3c, 0x30, 0xd7, 0x27, 0xad, 0xf1, 0xc8, 0x0c, 0x07, 0x1d, 0xea, 0x31, 0xfe, 0x37, 0x5b, 0x0b, 0xeb, 0xfe, 0xc2, 0x43, 0x55, 0xa4, 0xf6, 0x92, 0x11, 0x38, 0xa4, 0x71, 0xbc, 0x77, 0x59, 0x8e, 0x38, 0x24, 0xe3, 0xd3, 0xb0, 0x61, 0x5f, 0xe5, 0x76, 0x20, 0x93, 0x81, 0xba, 0x0f, 0x8d, 0xc4, 0x86, 0x73, 0x78, 0x74, 0xdf, 0x7a, 0xb4, 0x93, 0x58, 0xf2, 0x02, 0x40, 0x4e, 0x10, 0x93, 0xe4, 0xdd, 0xeb, 0x1e, 0x8d, 0x96, 0xa2, 0x32, 0x0a, 0x4b, 0xfe, 0xa7, 0x48, 0x2d, 0x72, 0x1e, 0x89, 0xa7, 0x50, 0x5c, 0x10, 0xe8, 0x52, 0x49, 0x4a, 0x13, 0xcc, 0x51, 0xba, 0x22, 0x7c, 0xa3, 0xca, 0xc8, 0xcf, 0x31, 0x79, 0x40, 0x2a, 0x6f, 0xf6, 0x6d, 0x82, 0x5c, 0x6c, 0xb5, 0x3a, 0x6c, 0xa7, 0x4f, 0xdf, 0x52, 0x94, 0xe0, 0x1a, 0xaa, 0xe6, 0x43, 0x20, 0x2f, 0xa6, 0x27, 0x67, 0x08, 0xbb, 0x31, 0x5c, 0x3d, 0xfd, 0x9a, 0xf9, 0x2e, 0x42, 0x95, 0x56, 0x8f, 0xad, 0x86, 0x20, 0xae, 0xd4, 0x04, 0x74, 0x1f, 0xfe, 0xe2, 0x0d, 0x0f, 0x69, 0xb3, 0x73, 0x2a, 0x57, 0x26, 0xca, 0x2f, 0xdd, 0xa5, 0xdd, 0x4d, 0x77, 0x44, 0x43, 0x54, 0x37, 0xf5, 0xda, 0x70, 0x36, 0x59, 0x89, 0x3d, 0x91, 0x3f, 0x6b, 0xff, 0x8f, 0x29, 0x3d, 0x8f, 0x4b, 0x07, 0xb8, 0x70, 0x7f, 0x13, 0x89, 0x9d, 0x03, 0xe9, 0x81, 0xcb, 0x19, 0xc5, 0x98, 0xde, 0xcd, 0x32, 0xdf, 0x33, 0x14, 0x69, 0xbf, 0x9b, 0xb1, 0x39, 0xdc, 0xec, 0x29, 0xf2, 0x3a, 0x88, 0x1d, 0x23, 0x1b, 0xec, 0xd1, 0x0f, 0xc4, 0x82, 0x94, 0xf7, 0xc1, 0x55, 0x3f, 0x98, 0xc9, 0xd8, 0x34, 0xd9, 0x80, 0x05, 0x59, 0xb7, 0xca, 0x24, 0x85, 0xbe, 0xf1, 0xfc, 0xb7, 0x42, 0xa0, 0x1b, 0xd5, 0x1c, 0x10, 0x6b, 0x1c, 0x99, 0x20, 0x4c, 0x7e, 0xa8, 0x8d, 0xf6, 0x27, 0x07, 0x48, 0xf3, 0x18, 0x99, 0x73, 0x42, 0x37, 0x96, 0x4e, 0x34, 0x1d, 0x38, 0x91, 0x5a, 0x0e, 0x61, 0x6b, 0x9f, 0xfa, 0xe0, 0x39, 0x3a, 0x54, 0x87, 0xfc, 0x5d, 0xcf, 0x13, 0xba, 0x74, 0x8c, 0xc3, 0xa2, 0xa3, 0x89, 0x91, 0x7c, 0x97, 0xbe, 0xf8, 0x26, 0x0f, 0x54, 0x5c, 0x40, 0xb4, 0x61, 0x3f, 0xbb, 0x87, 0xa1, 0xdd, 0x62, 0x5d, 0x5c, 0x49, 0x93, 0x85, 0x50, 0x30, 0x32, 0x8a, 0xd7, 0x2c, 0x83, 0xf0, 0x4b, 0x76, 0x4a, 0xac, 0x87, 0x0e, 0x6e, 0xff, 0x7a, 0x11, 0xbd, 0x49, 0x71, 0xaf, 0x2d, 0xa7, 0x44, 0x7b, 0xcc, 0x71, 0xc3, 0xb8, 0x13, 0x28, 0xe9, 0x62, 0x1a, 0xa5, 0x67, 0x78, 0xb6, 0x19, 0x83, 0xc5, 0xa7, 0x15, 0xd2, 0x3d, 0xf9, 0x85, 0xb1, 0x99, 0xd8, 0x18, 0x4d, 0x16, 0x1d, 0x17, 0x3e, 0x29, 0x63, 0x8f, 0x07, 0x86, 0x03, 0x9f, 0x0f, 0xc5, 0xcf, 0x76, 0x9d, 0xef, 0xe3, 0xaa, 0x0a, 0xac, 0x37, 0xa4, 0xfc, 0x49, 0x25, 0xa5, 0x8f, 0x1c, 0x4e, 0xab, 0x2b, 0x68, 0x3f, 0x59, 0xbb, 0x9f, 0x80, 0x47, 0x82, 0x31, 0x92, 0x64, 0xf3, 0xab, 0x6b, 0xd3, 0xd1, 0x42, 0xe7, 0x26, 0xb4, 0x73, 0x5e, 0xac, 0x08, 0xdd, 0x48, 0x89, 0xbd, 0xd3, 0x68, 0xa1, 0xfa, 0x20, 0x05, 0xe3, 0x39, 0x37, 0x84, 0x78, 0x52, 0x3d, 0x0f, 0xe8, 0x2b, 0xa2, 0x8c, 0x3c, 0xd3, 0x5b, 0x60, 0x31, 0xf1, 0x60, 0x20, 0xd6, 0x64, 0xb2, 0x9c, 0xa4, 0x99, 0xf5, 0x90, 0xd9, 0xca, 0x5f, 0xf2, 0x39, 0x1c, 0x6e, 0xd2, 0x0d, 0x65, 0xda, 0x0c, 0x2a, 0x67, 0x16, 0x6f, 0x63, 0x88, 0x6f, 0x66, 0xc7, 0x39, 0x4b, 0xf6, 0x5b, 0xaa, 0x30, 0x2b, 0xc2, 0xb9, 0x40, 0x88, 0xda, 0x10, 0xb4, 0x2d, 0x5f, 0x9b, 0x16, 0xc1, 0xb5, 0x19, 0x2f, 0x70, 0xa7, 0x22, 0xdf, 0x2d, 0xe8, 0x7b, 0x1c, 0x6d, 0xa8, 0xce, 0x75, 0xb9, 0x5b, 0x68, 0x01, 0xb3, 0x36, 0x95, 0xcd, 0x0c, 0x98, 0x5b, 0xf1, 0x1d, 0xfe, 0xaa, 0x20, 0xf2, 0xd8, 0x9b, 0xdd, 0xeb, 0x5b, 0x98, 0x6d, 0x59, 0xd1, 0xd4, 0xe8, 0x83, 0x05, 0xf1, 0x15, 0x9d, 0x56, 0xb2, 0x5a, 0xd6, 0xfd, 0x05, 0x7e, 0x7b, 0x89, 0xf6, 0x53, 0xcf, 0x5a, 0x43, 0xef, 0x49, 0x99, 0xf5, 0xee, 0xa0, 0x36, 0x5f, 0x07, 0x02, 0x3d, 0x08, 0xd9, 0xb1, 0xfc, 0xd2, 0xb5, 0x72, 0x60, 0xee, 0xa9, 0xaf, 0x27, 0x48, 0x96, 0x86, 0x97, 0xf5, 0x37, 0x74, 0x56, 0x2e, 0x80, 0x02, 0xc5, 0xf1, 0x80, 0x2e, 0xa8, 0xc1, 0x20, 0xcf, 0x60, 0x78, 0xcc, 0xa6, 0x48, 0xea, 0xf1, 0x72, 0xce, 0xb7, 0x23, 0xeb, 0x58, 0x51, 0x9f, 0xfa, 0xf6, 0x3d, 0x13, 0x5b, 0x82, 0xa6, 0x1c, 0x25, 0xac, 0x71, 0x94, 0xe9, 0x86, 0x60, 0xf7, 0x86, 0xe3, 0xab, 0x11, 0x0a, 0xbf, 0x23, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x02, 0xe4, 0x61, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbd, 0x07, 0xec, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x75, 0x77, 0xd9, 0xe4, 0xa6, 0x14, 0x6e, 0x44, 0x44, 0xa3, 0xd5, 0x48, 0xc2, 0x54, 0x30, 0xb1, 0xbe, 0x24, 0x0f, 0x09, 0xf3, 0xb4, 0xb1, 0xb4, 0x97, 0x47, 0xff, 0x0a, 0xe2, 0x1e, 0xa2, 0xff, 0xcf, 0x78, 0x49, 0x56, 0xe6, 0x64, 0xfc, 0x68, 0xcd, 0xf8, 0x61, 0xef, 0x67, 0xf1, 0x44, 0x5e, 0x70, 0x90, 0xf3, 0xf2, 0x4e, 0x4e, 0x8c, 0xae, 0x31, 0xca, 0x70, 0xc6, 0x31, 0xed, 0x4b, 0x1c, 0xac, 0x2d, 0x6a, 0x0b, 0xaa, 0xb4, 0x08, 0xc8, 0xb6, 0xd3, 0xef, 0xf6, 0x2b, 0x5f, 0x8b, 0xe4, 0xd4, 0x3b, 0x7a, 0x73, 0x76, 0x75, 0x4f, 0xe7, 0x61, 0xd5, 0x66, 0xca, 0x4f, 0xd1, 0x16, 0xfb, 0x53, 0x9f, 0x1b, 0x1e, 0xd5, 0x2c, 0xdb, 0x0b, 0x11, 0x95, 0xb8, 0xa5, 0x29, 0xf6, 0xa3, 0x00, 0x61, 0x73, 0x0f, 0x5f, 0xbc, 0x6a, 0x87, 0xe0, 0x84, 0x4e, 0xcc, 0x91, 0x9d, 0x8a, 0x5c, 0x4a, 0x63, 0x67, 0xd5, 0xa7, 0x31, 0xe2, 0xc8, 0x79, 0xc3, 0x42, 0xce, 0xa2, 0x0f, 0x68, 0x3c, 0x8a, 0x84, 0xad, 0x53, 0xd7, 0x4f, 0x27, 0xfa, 0x65, 0xcf, 0x48, 0xd5, 0x50, 0xdc, 0x83, 0x29, 0xfc, 0x2c, 0xcf, 0x41, 0x07, 0xe8, 0xf8, 0x90, 0x03, 0xf1, 0x12, 0x8c, 0x9c, 0xee, 0x42, 0x19, 0x2a, 0xff, 0xf8, 0xf8, 0x0f, 0x64, 0x32, 0x28, 0x79, 0xf6, 0xe4, 0xad, 0x07, 0x2e, 0x1f, 0xef, 0x3b, 0xc6, 0xc9, 0x01, 0x08, 0x94, 0xfe, 0x22, 0x10, 0x05, 0x07, 0x7f, 0x01, 0x19, 0x86, 0xf1, 0xf6, 0x86, 0x79, 0x62, 0xb4, 0xe3, 0x0c, 0x92, 0x3c, 0x0b, 0x82, 0xb7, 0x7f, 0x8b, 0x4e, 0x3e, 0x85, 0x7e, 0xe1, 0x84, 0x5e, 0xc1, 0xa6, 0xf9, 0xdc, 0xc9, 0x8e, 0xec, 0x09, 0x7d, 0x9e, 0x52, 0xeb, 0xe6, 0x70, 0x9b, 0xa6, 0x8a, 0xbe, 0x09, 0xd6, 0xea, 0x34, 0x30, 0x26, 0x5c, 0x70, 0xc6, 0x55, 0x7c, 0x4d, 0xfc, 0xb6, 0xb5, 0x76, 0x8b, 0x5a, 0xa1, 0x96, 0x72, 0x81, 0xba, 0x47, 0xd4, 0x3e, 0xde, 0x29, 0x94, 0xa6, 0xcb, 0x59, 0xe4, 0xff, 0x44, 0xc9, 0xc4, 0xf5, 0x6c, 0x9a, 0xef, 0x52, 0xe4, 0x82, 0x5d, 0x51, 0xdd, 0x8b, 0x17, 0xfd, 0x56, 0x01, 0x8f, 0x9a, 0x36, 0xc8, 0xe5, 0x92, 0x40, 0xdb, 0x8c, 0x21, 0x30, 0x02, 0xdf, 0x4f, 0xd3, 0x42, 0x0f, 0xd1, 0x72, 0x01, 0x42, 0x5b, 0xe6, 0xb8, 0x27, 0x0c, 0xb6, 0x57, 0xf4, 0xf4, 0x81, 0xdb, 0x88, 0x24, 0x87, 0xa3, 0xb7, 0x06, 0x09, 0x4a, 0x9c, 0x1d, 0x42, 0xa6, 0x3d, 0x20, 0x5c, 0x14, 0x24, 0x53, 0xb3, 0x02, 0x32, 0xcd, 0xea, 0x10, 0xab, 0xa7, 0x79, 0x00, 0xd9, 0xa4, 0x44, 0xa3, 0x2d, 0x8a, 0xa2, 0xdd, 0x44, 0xf3, 0x32, 0x35, 0x10, 0x31, 0xf7, 0x59, 0x5a, 0x0b, 0x5a, 0x87, 0x51, 0xa7, 0x6b, 0x3b, 0xea, 0xcb, 0xd5, 0xf8, 0x07, 0x56, 0x1a, 0x53, 0xd9, 0xd8, 0x83, 0x77, 0xf3, 0xf4, 0xec, 0x3d, 0x0b, 0xc7, 0xea, 0x91, 0x4f, 0xe5, 0xaf, 0x4d, 0x8a, 0xb9, 0xcf, 0xd5, 0x86, 0x61, 0x5a, 0x94, 0xaa, 0x84, 0xb9, 0xad, 0x62, 0xeb, 0x1f, 0x26, 0x1b, 0x64, 0xb8, 0xdc, 0xe9, 0xe7, 0x8f, 0x8c, 0xfd, 0x19, 0xf5, 0x9d, 0xff, 0x6a, 0xb9, 0x01, 0x7c, 0x93, 0x70, 0x3f, 0x45, 0x4d, 0x29, 0xcc, 0x45, 0xcb, 0xba, 0x43, 0xc6, 0x2e, 0x03, 0xda, 0x4c, 0xd6, 0x21, 0x57, 0x8f, 0x74, 0x99, 0x31, 0x0f, 0xd0, 0x9b, 0x54, 0x8c, 0x57, 0xb0, 0x14, 0xd0, 0xdd, 0x26, 0xec, 0xbb, 0xb4, 0x2f, 0xb1, 0xfe, 0xb1, 0xba, 0x50, 0xd9, 0x24, 0xd1, 0x49, 0xbb, 0x68, 0x7a, 0x88, 0xeb, 0x38, 0xc8, 0x1e, 0x8e, 0x11, 0xb0, 0x58, 0x88, 0xaf, 0xa1, 0xf3, 0xb7, 0x7f, 0xc9, 0xab, 0xc2, 0x29, 0xec, 0x5c, 0x85, 0xc8, 0x18, 0xb8, 0x8d, 0xd6, 0x7f, 0xbb, 0xc2, 0x48, 0xfc, 0x73, 0xfa, 0xb4, 0x6a, 0xaa, 0x3c, 0x0f, 0x7c, 0x90, 0x75, 0x52, 0xed, 0x0e, 0x24, 0xdd, 0x5f, 0xbe, 0x1d, 0x88, 0xce, 0xbb, 0xeb, 0xf3, 0xcc, 0x24, 0x02, 0xed, 0xad, 0x97, 0x7e, 0x73, 0x1f, 0x82, 0x52, 0x35, 0x9b, 0xd9, 0x95, 0x9a, 0x2f, 0x2e, 0x91, 0x07, 0xa9, 0xb1, 0x5c, 0x39, 0xe8, 0xe4, 0x60, 0x7e, 0x1a, 0xa1, 0x45, 0xa2, 0xc8, 0xdb, 0x6f, 0xbb, 0x82, 0x33, 0x54, 0x46, 0xca, 0x97, 0xc6, 0xa5, 0xf6, 0x16, 0x7d, 0x98, 0x10, 0x6a, 0x66, 0x82, 0x22, 0x4a, 0x35, 0x35, 0x6b, 0x8c, 0xd3, 0xe7, 0x36, 0x39, 0x0f, 0x1a, 0x9c, 0xa5, 0xf2, 0x5d, 0x8b, 0x57, 0x16, 0xc8, 0xc3, 0xa6, 0xa9, 0x34, 0xa7, 0x30, 0x82, 0x12, 0x79, 0x6a, 0x75, 0x5e, 0x38, 0xef, 0x37, 0xaf, 0xad, 0x8b, 0xf1, 0x60, 0xdc, 0x6c, 0xb3, 0x97, 0xf5, 0x06, 0x56, 0x11, 0xdc, 0x96, 0xf2, 0x37, 0x12, 0x75, 0xac, 0xa7, 0x40, 0xb4, 0xd7, 0x43, 0x97, 0x4e, 0x70, 0x56, 0xef, 0xf0, 0x5e, 0xfb, 0xbe, 0xc2, 0xc2, 0x9a, 0xc3, 0xf5, 0xfb, 0x75, 0xde, 0x2a, 0xc6, 0x6e, 0x44, 0x3b, 0x65, 0x2d, 0xa4, 0xd2, 0x3b, 0x39, 0x21, 0x64, 0x4a, 0xc8, 0x14, 0xa5, 0xb9, 0x4a, 0x38, 0x6d, 0x8c, 0x46, 0x4c, 0x22, 0x76, 0x20, 0x9b, 0x00, 0x71, 0x32, 0x98, 0xd4, 0xea, 0x9e, 0x38, 0x89, 0xdb, 0x83, 0xd2, 0x9d, 0xbc, 0x04, 0x55, 0x55, 0x38, 0x0e, 0x03, 0x51, 0x57, 0x33, 0x75, 0x82, 0x07, 0x8c, 0x2a, 0xe7, 0x64, 0xe1, 0x18, 0x2c, 0x1f, 0x9e, 0xca, 0x3e, 0x35, 0xda, 0xaa, 0x08, 0x8c, 0xa7, 0x59, 0x5c, 0xaa, 0x92, 0x53, 0xc3, 0x87, 0x66, 0x14, 0x2a, 0x94, 0x35, 0xda, 0x03, 0x3b, 0xea, 0xea, 0x54, 0xea, 0x27, 0x25, 0x65, 0x64, 0x78, 0xbc, 0x76, 0x50, 0xd7, 0xd4, 0xc3, 0x3f, 0x62, 0x71, 0xbb, 0xe5, 0x85, 0x5d, 0xf9, 0x39, 0xc4, 0xdf, 0x6a, 0xa7, 0x46, 0x18, 0x4f, 0x71, 0x34, 0x6e, 0x1a, 0x3b, 0x5d, 0x9a, 0xa3, 0xde, 0xe0, 0xc1, 0xd7, 0xa1, 0xc5, 0x49, 0x68, 0x4e, 0xd1, 0xc8, 0xb6, 0x2b, 0xbe, 0xda, 0xdf, 0xc1, 0x68, 0x63, 0xdd, 0xef, 0xed, 0x86, 0x5e, 0xc1, 0x15, 0x73, 0x2d, 0x40, 0x2f, 0xe9, 0xeb, 0x16, 0x10, 0x34, 0x5e, 0xdf, 0x5d, 0xee, 0x75, 0x43, 0xe0, 0x29, 0x8e, 0x5e, 0xe3, 0x3f, 0xbb, 0xd1, 0x04, 0x9c, 0x91, 0xf1, 0x4b, 0xd7, 0x44, 0xeb, 0xba, 0xbe, 0x0c, 0x06, 0x0f, 0x5d, 0x05, 0x2c, 0x2f, 0x46, 0x46, 0x01, 0x7d, 0xae, 0x50, 0x2b, 0xe5, 0x38, 0xec, 0x44, 0x6f, 0x32, 0x27, 0xcc, 0x54, 0xfa, 0xf9, 0x97, 0x9a, 0xa6, 0xaf, 0xa5, 0x11, 0x6c, 0x59, 0xf5, 0x51, 0xd1, 0xd2, 0x5a, 0xfa, 0x6e, 0x58, 0xf0, 0xd0, 0xd0, 0xca, 0x84, 0x8d, 0x07, 0x3f, 0xb1, 0xe9, 0x27, 0x4d, 0x6d, 0x1e, 0x3e, 0x09, 0xaf, 0xd3, 0x5a, 0x6b, 0x36, 0x06, 0x7d, 0x85, 0xbe, 0x72, 0x76, 0x8d, 0x8f, 0xf3, 0x14, 0x82, 0xad, 0xbe, 0x89, 0xf3, 0x46, 0x78, 0xd9, 0x32, 0x49, 0xdb, 0x96, 0x19, 0xe2, 0x86, 0x29, 0xcf, 0x2f, 0x41, 0x4a, 0xdd, 0xab, 0xb1, 0xad, 0x36, 0xf0, 0x4a, 0xc3, 0x31, 0xa2, 0x95, 0xc2, 0xdb, 0xfc, 0x6b, 0xda, 0xf6, 0x07, 0x39, 0x55, 0x53, 0x21, 0x28, 0x06, 0x3d, 0xaf, 0xf2, 0x6c, 0x56, 0x94, 0xc4, 0x9d, 0xd2, 0x80, 0xac, 0x53, 0xc2, 0xc7, 0xaf, 0x55, 0x60, 0x6c, 0x18, 0x34, 0x37, 0x9f, 0x57, 0xdc, 0xb8, 0xdb, 0x96, 0x0d, 0x03, 0x23, 0xaf, 0xff, 0xfd, 0x03, 0x3d, 0x4f, 0x7e, 0x33, 0xa3, 0x24, 0xd8, 0x61, 0x23, 0xfc, 0x18, 0x76, 0xed, 0xa0, 0xaf, 0xb6, 0x09, 0x87, 0x3c, 0x7f, 0x1d, 0xae, 0x23, 0x2b, 0x50, 0x17, 0x39, 0x02, 0x72, 0x55, 0xc7, 0x67, 0xc7, 0x04, 0x0e, 0x31, 0x40, 0x7f, 0xb3, 0x84, 0xe7, 0x10, 0x89, 0x2f, 0xef, 0xe6, 0xfd, 0x1e, 0xfb, 0xcf, 0x3b, 0x10, 0xe8, 0x24, 0x50, 0x81, 0x72, 0xc3, 0x31, 0xd2, 0xa7, 0x65, 0xf2, 0xed, 0x95, 0xc4, 0x2a, 0xd9, 0x7e, 0x98, 0x4f, 0x50, 0xe3, 0xb1, 0x9d, 0x60, 0xbf, 0x3c, 0x50, 0x4f, 0xb4, 0x33, 0xd6, 0x19, 0xb6, 0xeb, 0x66, 0x36, 0x16, 0xd9, 0x39, 0x50, 0xcd, 0x16, 0xce, 0xdf, 0x52, 0x48, 0x8f, 0x01, 0x64, 0xff, 0x3d, 0x6c, 0x7e, 0x8a, 0xb4, 0x14, 0x5f, 0xc7, 0x8c, 0x29, 0xb9, 0xc5, 0xc7, 0x18, 0x47, 0xfe, 0xe3, 0x9e, 0xe8, 0xea, 0x65, 0x14, 0xe5, 0x40, 0x43, 0x71, 0xb9, 0x93, 0x3f, 0x7b, 0xf2, 0x81, 0x5d, 0x9b, 0x66, 0x1b, 0x08, 0x51, 0x0a, 0x4d, 0x27, 0x35, 0x54, 0x62, 0xb5, 0x71, 0x00, 0x99, 0x61, 0x79, 0xfe, 0x45, 0xa3, 0xaa, 0x72, 0x5c, 0xec, 0x5d, 0x0a, 0x7b, 0xee, 0xa2, 0x9b, 0x1f, 0xff, 0xf2, 0x53, 0x40, 0x9b, 0xce, 0xae, 0x9f, 0xd5, 0x07, 0x60, 0x18, 0x86, 0xb9, 0xdb, 0xc1, 0x2e, 0x61, 0xc8, 0xba, 0x73, 0x60, 0x2c, 0x7c, 0x14, 0x55, 0x6e, 0xce, 0x9d, 0x23, 0xf6, 0xcb, 0xbf, 0x3f, 0x3b, 0x9a, 0xd6, 0x21, 0x3b, 0x73, 0x27, 0x5f, 0xf3, 0xda, 0x99, 0x19, 0xb6, 0x81, 0xd9, 0x7e, 0xc0, 0x2e, 0x29, 0x4e, 0xcb, 0xa2, 0x3f, 0x67, 0xf3, 0x69, 0xde, 0xa7, 0xa5, 0xed, 0x9c, 0xb4, 0x4e, 0xcd, 0xd2, 0x74, 0xa3, 0xce, 0x3d, 0x59, 0x7d, 0x71, 0x72, 0x83, 0xb7, 0x10, 0x07, 0xd4, 0x2c, 0x03, 0xa3, 0x26, 0xe2, 0xed, 0x3c, 0x8b, 0xd7, 0xab, 0xf5, 0xb2, 0xe7, 0xf7, 0xe1, 0x0a, 0xeb, 0xe2, 0x3d, 0xcf, 0x1c, 0x96, 0x92, 0xa7, 0xe1, 0x35, 0x45, 0x3d, 0x7f, 0xe9, 0x58, 0x5b, 0xae, 0xfe, 0x6b, 0xfd, 0xaf, 0xd9, 0x68, 0x33, 0x26, 0xee, 0x6d, 0x9e, 0xc3, 0x0d, 0x17, 0x22, 0x0a, 0xf6, 0x55, 0x24, 0x2b, 0x26, 0x05, 0xaf, 0x66, 0x1d, 0xfb, 0x19, 0xec, 0x7c, 0x01, 0x1f, 0x71, 0xa3, 0x86, 0x50, 0x82, 0xb1, 0x61, 0x5a, 0x30, 0xac, 0x58, 0xe7, 0x62, 0xe1, 0x9f, 0xf9, 0x0c, 0x99, 0x06, 0x6d, 0xf9, 0x0f, 0xd0, 0x78, 0x79, 0x46, 0x65, 0x27, 0xe4, 0x03, 0xf2, 0x25, 0xb4, 0xa5, 0xe2, 0x95, 0x14, 0x5d, 0x49, 0x71, 0x9b, 0x5e, 0xf7, 0x0f, 0xe7, 0x6b, 0xe3, 0xe9, 0xce, 0x92, 0xb4, 0xef, 0x15, 0x3f, 0x1a, 0x5b, 0x73, 0xe9, 0x7e, 0x45, 0x4d, 0x8b, 0xdb, 0x58, 0x56, 0x67, 0x10, 0xbd, 0xd8, 0xe4, 0x83, 0x6f, 0x42, 0x67, 0x55, 0x78, 0xa7, 0x2a, 0xe6, 0xf7, 0x0b, 0x21, 0x04, 0x19, 0x2b, 0xbe, 0x5c, 0x40, 0x3c, 0xa0, 0x7e, 0x94, 0x56, 0x7c, 0xcd, 0x85, 0x49, 0x28, 0xf9, 0xec, 0x85, 0x94, 0xfc, 0x8c, 0x4f, 0x60, 0xd6, 0x9a, 0x58, 0xaa, 0x83, 0xbe, 0x9a, 0xf1, 0x99, 0xeb, 0x02, 0xce, 0xb5, 0x74, 0x27, 0x49, 0x35, 0xd1, 0xcd, 0xdc, 0x05, 0xab, 0x07, 0x81, 0xac, 0x36, 0xf4, 0x1a, 0x4d, 0x6b, 0xd9, 0xc4, 0xd5, 0x1a, 0x41, 0xab, 0x90, 0x34, 0xe8, 0xbb, 0xe1, 0xb7, 0xad, 0x46, 0x5d, 0x11, 0x17, 0x2f, 0x60, 0xa1, 0x2e, 0x4a, 0xbf, 0xea, 0x75, 0xba, 0x65, 0xd7, 0x30, 0xf5, 0x75, 0x92, 0xba, 0xbb, 0x69, 0x2e, 0x2b, 0x5d, 0x72, 0xcc, 0xec, 0xf3, 0x19, 0x74, 0x2d, 0x1c, 0x1b, 0xb3, 0xf5, 0xe8, 0xd8, 0xc8, 0x9f, 0xe7, 0x6e, 0x83, 0x44, 0x61, 0xbb, 0x5e, 0x8c, 0xaf, 0x3f, 0xc1, 0x8b, 0x7f, 0xaf, 0x2c, 0xc9, 0x4d, 0xfe, 0xde, 0x37, 0xa1, 0x96, 0x32, 0x76, 0x38, 0xcb, 0xc3, 0x38, 0xce, 0x96, 0x12, 0x9b, 0xb9, 0x8c, 0x91, 0xac, 0x9f, 0x95, 0x0d, 0x27, 0x3c, 0xb2, 0x1d, 0xfb, 0xc3, 0x94, 0x29, 0xc8, 0xc2, 0xa9, 0xd8, 0x3f, 0x29, 0x85, 0xa7, 0x16, 0x37, 0xb9, 0xc3, 0x96, 0x52, 0x76, 0xe2, 0x01, 0xa3, 0x4e, 0x54, 0xb5, 0x3b, 0x0a, 0x29, 0x6d, 0x90, 0xc1, 0xd1, 0x97, 0x56, 0x04, 0xd7, 0x78, 0x0a, 0x1d, 0x5c, 0x5e, 0x27, 0xa0, 0x46, 0x95, 0xb8, 0x7d, 0x0e, 0xad, 0x2c, 0xe7, 0x1f, 0xea, 0xa1, 0x80, 0xc9, 0x20, 0x21, 0xf7, 0x98, 0xca, 0x9c, 0x06, 0x31, 0x34, 0xec, 0x75, 0xd2, 0x10, 0x50, 0xe8, 0xae, 0x95, 0x54, 0x96, 0xc2, 0x45, 0x70, 0xef, 0x32, 0xae, 0x38, 0xd1, 0x69, 0x95, 0xba, 0xa8, 0x8a, 0x9f, 0xae, 0x8f, 0xea, 0x06, 0x57, 0x98, 0xe7, 0xdd, 0x3f, 0xd8, 0x7d, 0x9a, 0xff, 0xf5, 0xb4, 0x4b, 0xe1, 0x72, 0x2d, 0x5f, 0x53, 0xdb, 0x8a, 0x3a, 0xff, 0xe5, 0x58, 0x7d, 0xa1, 0xe9, 0xdb, 0x9b, 0x71, 0xf6, 0xb9, 0x0b, 0x43, 0x04, 0x70, 0xad, 0x29, 0xd1, 0x98, 0x0f, 0x1b, 0xbe, 0x27, 0x94, 0x7d, 0xf6, 0x1c, 0x7d, 0x39, 0x1d, 0x8d, 0x3d, 0x25, 0xbb, 0x1c, 0x8e, 0x67, 0x3b, 0x22, 0xa9, 0x5e, 0x5c, 0x95, 0x6e, 0x2c, 0x61, 0x1e, 0x5d, 0x18, 0x4b, 0xd0, 0x41, 0x6f, 0x9b, 0x1c, 0x6d, 0x5d, 0x8b, 0x8a, 0x10, 0x4b, 0x14, 0xc0, 0x91, 0xcf, 0xc9, 0x69, 0x77, 0x08, 0x3b, 0x1d, 0x4f, 0x2b, 0x8e, 0x7b, 0xc7, 0x66, 0xe1, 0x0b, 0xda, 0x69, 0xbb, 0xcc, 0x21, 0x09, 0x07, 0xaa, 0x47, 0xd3, 0x6c, 0x91, 0xc3, 0x43, 0xdb, 0x07, 0x5a, 0xd4, 0xbf, 0x88, 0xca, 0x23, 0xcb, 0xcc, 0xf9, 0x0c, 0x09, 0xc6, 0xdf, 0xe2, 0xe1, 0xa4, 0x7c, 0x42, 0x4a, 0x0d, 0xf9, 0xa7, 0xf1, 0x1a, 0x6c, 0xb9, 0x5c, 0x09, 0xa9, 0x92, 0x90, 0xe9, 0xce, 0xa5, 0x62, 0xd4, 0x51, 0x6b, 0x32, 0xc1, 0x2f, 0x70, 0x68, 0x40, 0x11, 0x3d, 0x6a, 0x35, 0xa0, 0xde, 0x38, 0x3a, 0x10, 0x0f, 0x6e, 0x9b, 0x23, 0x6a, 0x3d, 0x2e, 0xab, 0x7b, 0x77, 0x5e, 0xa2, 0x11, 0xbc, 0xa1, 0x8e, 0x05, 0xcd, 0x27, 0x97, 0x98, 0x4b, 0x9c, 0xec, 0x30, 0x8b, 0x2b, 0xdf, 0x84, 0x30, 0xa2, 0x72, 0xc7, 0x59, 0xdb, 0xbf, 0x4f, 0xc8, 0x9e, 0x90, 0x3f, 0x33, 0x4a, 0x86, 0xd5, 0x43, 0x8f, 0xa0, 0x7f, 0x75, 0x90, 0xb1, 0x51, 0xbd, 0xc8, 0x58, 0xe6, 0xbb, 0x55, 0x24, 0x62, 0x28, 0x54, 0xb9, 0x85, 0xe7, 0x09, 0x8d, 0xec, 0xfb, 0xe5, 0x55, 0x4a, 0x09, 0x08, 0xc0, 0xbc, 0x2a, 0x29, 0xb7, 0xbe, 0x69, 0x73, 0x68, 0xd4, 0xc2, 0xaa, 0x24, 0xd0, 0x69, 0x9d, 0xc2, 0xcd, 0xf5, 0x78, 0x80, 0xbe, 0xe0, 0xcc, 0xe1, 0x1d, 0x7d, 0xcc, 0xe1, 0x1e, 0x3b, 0x40, 0xfb, 0x17, 0xa2, 0x11, 0xa5, 0xa5, 0x7a, 0x22, 0xf3, 0x98, 0x9c, 0x85, 0xa8, 0x2f, 0x01, 0x6f, 0xb5, 0x7b, 0xb4, 0x2f, 0xde, 0x0b, 0x85, 0x02, 0x7c, 0x1b, 0xba, 0x0e, 0x40, 0xcb, 0x1f, 0xac, 0x88, 0x35, 0x84, 0xe3, 0x30, 0x90, 0x77, 0xe7, 0xc9, 0xf5, 0x1c, 0xf7, 0x3a, 0x21, 0x8a, 0x26, 0x2a, 0xc8, 0x98, 0x1a, 0xaf, 0xbd, 0x4e, 0x12, 0xe3, 0x76, 0x01, 0x20, 0x17, 0x2e, 0x57, 0x15, 0xe0, 0xab, 0x1c, 0xf6, 0x89, 0x1b, 0x45, 0xfa, 0x20, 0x1f, 0x3d, 0xc0, 0x40, 0xf4, 0x83, 0x03, 0x76, 0x38, 0x81, 0xe1, 0x35, 0xdc, 0x7a, 0x88, 0x13, 0x50, 0x47, 0x72, 0x9c, 0x8d, 0x8f, 0x69, 0x70, 0xcd, 0xc0, 0x6f, 0x7a, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x02, 0xe4, 0x61, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbd, 0x07, 0xec, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xab, 0x7d, 0x70, 0x64, 0xa8, 0x3f, 0x8a, 0x3a, 0x5c, 0xdc, 0xc3, 0xb6, 0x0e, 0x2e, 0x85, 0x44, 0x01, 0x62, 0xb2, 0x2b, 0x63, 0xcb, 0x0a, 0xab, 0xa1, 0xf7, 0x60, 0xae, 0x98, 0xa1, 0x3a, 0xf7, 0xd6, 0xc8, 0x39, 0x4d, 0x37, 0xe5, 0x42, 0x0e, 0x62, 0xfc, 0x7c, 0x33, 0x38, 0xdc, 0xaa, 0x14, 0x67, 0xa7, 0xed, 0xaa, 0xc6, 0xc7, 0x96, 0xb7, 0xf5, 0x5a, 0x9d, 0x23, 0xbd, 0x0f, 0x50, 0xa8, 0x0d, 0x4d, 0x27, 0x48, 0xfe, 0x79, 0xc6, 0x13, 0x6f, 0x4e, 0xd3, 0xd7, 0xae, 0xd7, 0xcc, 0xf5, 0x43, 0x07, 0x5b, 0x81, 0x4e, 0x23, 0x4e, 0x29, 0x16, 0x22, 0xb7, 0xa1, 0x90, 0x0a, 0x99, 0x23, 0xdd, 0xac, 0x5f, 0xb3, 0x36, 0x23, 0x84, 0x64, 0xf9, 0xf3, 0x8d, 0x4a, 0x3c, 0x70, 0x43, 0x39, 0x9d, 0x5d, 0xf4, 0x23, 0x2e, 0x02, 0xd2, 0x7f, 0x78, 0x5e, 0x73, 0x3b, 0xfd, 0x8f, 0x68, 0x59, 0x82, 0x2c, 0x64, 0xfe, 0x7e, 0x36, 0x68, 0x89, 0x59, 0x75, 0xa4, 0x07, 0x8b, 0xfc, 0x87, 0x32, 0xcf, 0x98, 0xee, 0xa4, 0xda, 0x37, 0x1d, 0x3d, 0x09, 0x17, 0x70, 0x25, 0x11, 0x90, 0xc9, 0xda, 0x0e, 0xca, 0xa7, 0x6f, 0xc8, 0x7f, 0x12, 0xe9, 0x18, 0xf0, 0xb0, 0xa9, 0xbf, 0x94, 0x00, 0x5e, 0x3b, 0x76, 0xa1, 0x41, 0x14, 0xec, 0x57, 0x3b, 0x67, 0x6c, 0x0d, 0xaa, 0x20, 0x52, 0xc5, 0x82, 0x19, 0xd3, 0x37, 0x34, 0x5e, 0xd2, 0x62, 0xe2, 0x66, 0x95, 0xf9, 0x58, 0x25, 0x16, 0x77, 0xff, 0xff, 0x8e, 0xd1, 0xfc, 0xb2, 0xa5, 0x60, 0x15, 0x21, 0x34, 0xf0, 0x2e, 0x74, 0xf2, 0x85, 0x23, 0x60, 0x57, 0x01, 0xaa, 0x9f, 0x18, 0x70, 0x3a, 0x4c, 0x87, 0xa2, 0x7f, 0xaf, 0xb4, 0xfa, 0x6d, 0xba, 0xaa, 0xfe, 0x12, 0x9c, 0x04, 0x2a, 0x28, 0xcd, 0x14, 0x9a, 0x18, 0xf9, 0xc9, 0x2e, 0x08, 0x5f, 0x3a, 0x8c, 0x11, 0xe4, 0x52, 0x0a, 0xdf, 0x2e, 0x26, 0xd4, 0x99, 0xf8, 0x4c, 0xa7, 0xbf, 0x2a, 0xb3, 0x90, 0x07, 0x9c, 0xc0, 0x43, 0x0b, 0x07, 0x5a, 0xa5, 0x9b, 0x1d, 0x25, 0x69, 0x1a, 0x5c, 0x35, 0x5a, 0x59, 0x06, 0x26, 0xa2, 0xe3, 0xf7, 0x03, 0x58, 0x01, 0x90, 0x37, 0x07, 0x8b, 0x44, 0x64, 0xc6, 0xf3, 0x0b, 0x64, 0x79, 0xff, 0x59, 0x3e, 0xe0, 0x82, 0xaf, 0xac, 0x06, 0x31, 0x7a, 0x93, 0x69, 0x67, 0xe3, 0xca, 0x22, 0xcf, 0xc2, 0x0f, 0xd0, 0xec, 0xc5, 0x75, 0xbf, 0x9b, 0x02, 0x0f, 0xd0, 0x09, 0x1d, 0x02, 0x80, 0x31, 0x6c, 0x7b, 0xeb, 0x11, 0xe5, 0x06, 0xe8, 0x84, 0x27, 0x9f, 0x9a, 0xbf, 0x39, 0x73, 0xbe, 0xef, 0x5b, 0xce, 0x05, 0x60, 0xe7, 0x02, 0x47, 0xf2, 0x59, 0x4f, 0xd9, 0xfd, 0x1a, 0x4f, 0x13, 0x69, 0xc0, 0xdc, 0xd9, 0xfa, 0xfa, 0x18, 0xaa, 0x8d, 0x8f, 0xd8, 0x42, 0xee, 0x3a, 0x12, 0xcf, 0xe6, 0xaa, 0x64, 0x3d, 0x98, 0xc9, 0x28, 0x1f, 0x01, 0x63, 0xa4, 0xe6, 0x4a, 0xb0, 0x69, 0x30, 0x4c, 0x52, 0x8a, 0xbc, 0xa9, 0x18, 0x31, 0xe9, 0x14, 0x55, 0xf7, 0xdf, 0x79, 0x12, 0x0b, 0x8c, 0x69, 0xf3, 0xb3, 0x8a, 0xb8, 0x86, 0x90, 0x21, 0x96, 0x1c, 0x5b, 0xd8, 0x0a, 0x10, 0xbe, 0xc3, 0xd7, 0x15, 0xae, 0xcb, 0x19, 0x2b, 0xf9, 0xa8, 0x24, 0x5f, 0x04, 0x8c, 0xfe, 0xc3, 0x93, 0x8e, 0x8c, 0x01, 0x44, 0x6b, 0x92, 0x27, 0x06, 0xc4, 0x4b, 0x41, 0xf1, 0x6c, 0xd4, 0xfa, 0xf2, 0x51, 0xd5, 0xaa, 0xac, 0x5b, 0xcd, 0xa3, 0xb0, 0x14, 0xb7, 0x48, 0x5c, 0x77, 0xf1, 0x12, 0xeb, 0xcd, 0x17, 0x04, 0xb0, 0xea, 0x37, 0x3b, 0xc4, 0xa2, 0x47, 0x35, 0x87, 0x4d, 0x8c, 0x9d, 0x61, 0xdb, 0xad, 0x95, 0x76, 0xad, 0x11, 0x72, 0x8c, 0xff, 0xed, 0x8e, 0x94, 0xbf, 0xd3, 0xb5, 0xe8, 0xfd, 0xa9, 0x60, 0x17, 0x8b, 0xec, 0xaa, 0x4e, 0x8d, 0x1b, 0xf3, 0xa0, 0xca, 0x56, 0x1a, 0xe8, 0x95, 0x48, 0x35, 0xa2, 0xa3, 0xd1, 0xd7, 0xd2, 0x99, 0x14, 0x4c, 0x96, 0x53, 0x9a, 0x8b, 0x4e, 0xa8, 0x0b, 0xb1, 0xaa, 0x6d, 0x9b, 0x43, 0x7e, 0x6c, 0xe9, 0x77, 0x68, 0x75, 0x09, 0x43, 0xd5, 0xa7, 0x36, 0xc6, 0x3b, 0xf4, 0x2c, 0xd4, 0x65, 0x6f, 0xa0, 0xe2, 0x80, 0x81, 0xc7, 0xbf, 0x19, 0x92, 0xb1, 0x1a, 0x00, 0x4f, 0xa0, 0x4a, 0x5b, 0xad, 0x62, 0x9a, 0xad, 0x50, 0x86, 0xf2, 0x88, 0x04, 0x80, 0x35, 0x08, 0x3a, 0x34, 0x4b, 0xde, 0xc3, 0x3d, 0xd8, 0x2a, 0x7a, 0x53, 0x9d, 0x88, 0xca, 0xca, 0x47, 0xa4, 0xcb, 0xff, 0x2e, 0xbf, 0x8d, 0x34, 0xba, 0x79, 0xdf, 0x7b, 0x2a, 0xa2, 0xa3, 0x5f, 0x05, 0x85, 0x7e, 0x90, 0x81, 0xb2, 0xf6, 0xa3, 0xd4, 0x82, 0x0f, 0xc9, 0x64, 0x06, 0x92, 0x0c, 0x09, 0x47, 0x72, 0x37, 0x34, 0x84, 0x8a, 0x02, 0x34, 0x49, 0x9a, 0xae, 0xa2, 0x47, 0xa2, 0xb6, 0x17, 0x3d, 0x32, 0xb3, 0x0a, 0x6b, 0x0a, 0xb4, 0x2c, 0xbc, 0x80, 0x06, 0x84, 0xcd, 0x86, 0xec, 0x9e, 0x21, 0x6d, 0xb6, 0xbb, 0x1c, 0x60, 0x96, 0x0b, 0xe8, 0xe3, 0x28, 0x03, 0xc6, 0x2e, 0x89, 0xd3, 0x87, 0x1b, 0xf5, 0x14, 0xdd, 0x37, 0x50, 0x6a, 0xd1, 0x93, 0x37, 0x0b, 0x82, 0x78, 0x93, 0x18, 0x56, 0x9c, 0x95, 0x0b, 0x37, 0x37, 0xfe, 0xfd, 0x88, 0xc3, 0xad, 0xb8, 0x56, 0x16, 0xa4, 0xa2, 0xda, 0x0c, 0x92, 0xa5, 0xa2, 0xe9, 0x37, 0x55, 0x9c, 0x24, 0x90, 0x3a, 0x53, 0x81, 0xee, 0x6d, 0x98, 0x9e, 0x7a, 0x46, 0xb9, 0x42, 0x22, 0xfd, 0x2a, 0xb9, 0xc2, 0xa2, 0xde, 0x01, 0x0d, 0x5c, 0x5d, 0x91, 0x0f, 0x31, 0x52, 0xec, 0x23, 0x72, 0x5c, 0xee, 0x63, 0x81, 0xfa, 0x96, 0x9f, 0x1e, 0x4f, 0x62, 0x00, 0xb8, 0xb5, 0xf1, 0x03, 0x2a, 0x7f, 0xe0, 0x7b, 0x2c, 0x38, 0xf0, 0xb6, 0x50, 0xfc, 0xf3, 0xbc, 0xe2, 0x7c, 0xf8, 0xf3, 0x4f, 0x6b, 0x98, 0xf8, 0x9b, 0x02, 0x6d, 0xcc, 0x34, 0x2b, 0xfb, 0xfc, 0x59, 0x13, 0xb2, 0x2f, 0x7e, 0x50, 0x90, 0xe5, 0x99, 0x4d, 0x6b, 0xa0, 0xe9, 0x0f, 0x71, 0x73, 0xff, 0xaf, 0xcd, 0x14, 0xf1, 0x70, 0x31, 0x6c, 0x2d, 0x51, 0x3c, 0xf4, 0xe6, 0x4a, 0x25, 0x90, 0x51, 0x86, 0x86, 0x66, 0xce, 0x20, 0xdd, 0x5c, 0xe0, 0x35, 0x0a, 0xf9, 0x9b, 0xe0, 0xd5, 0xa5, 0x76, 0xf6, 0x7f, 0x9a, 0x96, 0x3b, 0x92, 0x37, 0xe5, 0xb1, 0xb7, 0xba, 0x0c, 0xe0, 0x73, 0x07, 0x99, 0xac, 0xa4, 0x3d, 0x2f, 0x14, 0x69, 0x6f, 0x70, 0xf5, 0x2b, 0xe5, 0x11, 0x31, 0x71, 0x02, 0xca, 0x77, 0xb2, 0x81, 0x1c, 0xc5, 0xe9, 0xf4, 0xcd, 0x85, 0xb0, 0xd0, 0x97, 0x10, 0xa9, 0xc5, 0xa9, 0xc5, 0xcf, 0x6c, 0xd3, 0x5d, 0xe5, 0x55, 0xe2, 0x2a, 0xb3, 0x23, 0xda, 0x36, 0x63, 0xa7, 0xd7, 0x1c, 0xb8, 0xba, 0x5a, 0x2b, 0xd2, 0x88, 0xdb, 0xe1, 0x77, 0xf9, 0x2b, 0xf6, 0x9f, 0xa5, 0xa5, 0xcd, 0x08, 0x8e, 0x2e, 0x72, 0x35, 0xac, 0x50, 0xe5, 0x5f, 0xfa, 0xf9, 0xa4, 0x9d, 0x7c, 0xfd, 0xf8, 0x15, 0x35, 0x38, 0xa1, 0x7e, 0x26, 0x0c, 0x9a, 0x16, 0x3a, 0x14, 0x22, 0x14, 0x9d, 0x26, 0x33, 0x55, 0x76, 0x53, 0x2e, 0xaa, 0x84, 0xb0, 0xb0, 0x2d, 0x4d, 0xff, 0x4d, 0x08, 0x01, 0x69, 0x2a, 0x97, 0xdc, 0xff, 0x41, 0x35, 0x27, 0xc1, 0x93, 0xed, 0xd7, 0xe7, 0x70, 0xcb, 0x9c, 0xa1, 0x8a, 0xa0, 0xce, 0x42, 0xd7, 0x41, 0x5d, 0x9a, 0xef, 0x08, 0x58, 0xd2, 0x8b, 0x72, 0x3f, 0x21, 0xeb, 0xcf, 0x20, 0xaf, 0xed, 0x0b, 0xc4, 0x25, 0x14, 0xe9, 0x57, 0xd5, 0x0d, 0xc7, 0xcb, 0x56, 0x10, 0x89, 0x11, 0xa5, 0x92, 0xb3, 0xbb, 0xb1, 0xc7, 0xc7, 0x94, 0x4f, 0x0a, 0x9d, 0xcd, 0x10, 0x62, 0x06, 0xa7, 0x48, 0x68, 0x2e, 0x67, 0xf0, 0xb0, 0x1e, 0x12, 0xd6, 0x27, 0xaf, 0xef, 0xe9, 0xa5, 0x6e, 0x58, 0x79, 0x6a, 0x4f, 0xc6, 0xad, 0xee, 0xb3, 0x5d, 0xd4, 0xf8, 0x51, 0x47, 0x71, 0x55, 0x5f, 0x25, 0xc6, 0x57, 0x0d, 0xbe, 0xba, 0x8a, 0xa9, 0xf6, 0x25, 0x24, 0x32, 0x76, 0x9f, 0x75, 0x3b, 0xfa, 0x30, 0xf2, 0xa1, 0x5e, 0xea, 0x69, 0xa4, 0x4b, 0xa3, 0x27, 0x25, 0x3c, 0x3f, 0xe1, 0xb1, 0x1f, 0xd3, 0x03, 0x52, 0xf4, 0x8e, 0xf4, 0xf3, 0x10, 0x83, 0x69, 0x81, 0x58, 0x44, 0x3f, 0x93, 0xb6, 0x41, 0x1b, 0x86, 0x5d, 0x9d, 0xe4, 0x16, 0x51, 0xac, 0x02, 0xb1, 0xdb, 0x77, 0xdc, 0x51, 0x61, 0x8d, 0x5b, 0x04, 0x08, 0xa6, 0x8d, 0xa0, 0x89, 0x11, 0xf4, 0x95, 0xd8, 0xc1, 0x87, 0xb2, 0xa9, 0xe1, 0xb1, 0x68, 0xbb, 0x0d, 0xdf, 0x2d, 0x14, 0xa5, 0x0f, 0x1b, 0x5a, 0xbd, 0x32, 0x2f, 0x88, 0x9b, 0x5d, 0x78, 0xdf, 0x89, 0x13, 0x62, 0xc3, 0x4f, 0x6b, 0x29, 0xa0, 0x0c, 0x65, 0x21, 0x9a, 0x4f, 0x18, 0xbc, 0x4c, 0x94, 0x21, 0x37, 0x76, 0x22, 0xf8, 0x39, 0x21, 0xe2, 0xb3, 0x7c, 0x83, 0xe3, 0x13, 0x1b, 0x92, 0x30, 0x9e, 0x07, 0xc9, 0x78, 0xe5, 0xe9, 0x4a, 0x0b, 0x09, 0xe3, 0x9c, 0x8e, 0x00, 0x98, 0x1b, 0x57, 0x92, 0x1e, 0x3b, 0x78, 0x24, 0xc2, 0xf7, 0x24, 0x31, 0x15, 0x99, 0x5b, 0xc8, 0x58, 0xc0, 0x32, 0xde, 0x31, 0x3a, 0xb8, 0xb4, 0xac, 0xde, 0xfe, 0x2f, 0x1b, 0x82, 0x42, 0xe9, 0xb0, 0x7e, 0xd0, 0x68, 0x0d, 0x69, 0xce, 0xa4, 0x2a, 0x2a, 0x63, 0xc2, 0xfd, 0xc3, 0xd4, 0x73, 0x0e, 0x2c, 0xd5, 0x8e, 0x5c, 0xeb, 0x2b, 0x7e, 0x31, 0xd4, 0x1a, 0x49, 0x64, 0xd0, 0xb4, 0x5b, 0x06, 0x4c, 0xb4, 0x55, 0x25, 0xf1, 0x8e, 0xc6, 0xd7, 0xe9, 0x37, 0x11, 0x46, 0x40, 0x43, 0xb2, 0x9d, 0x51, 0xfe, 0x83, 0x51, 0xf6, 0xd4, 0xca, 0xd3, 0xed, 0x0c, 0x0f, 0x74, 0xa5, 0x4c, 0xc7, 0x29, 0x4f, 0x55, 0xf1, 0x71, 0x6d, 0x90, 0x9a, 0x36, 0x51, 0x3a, 0x7f, 0xbb, 0xd1, 0x37, 0x8a, 0xde, 0xd6, 0xfe, 0xb7, 0x1c, 0xbe, 0xe4, 0xc6, 0x4e, 0xb0, 0x91, 0x54, 0xd2, 0xf3, 0x1b, 0xbe, 0xaa, 0x1a, 0xf6, 0x70, 0xbd, 0x07, 0x5d, 0x65, 0xa9, 0xd4, 0xbd, 0xda, 0xa3, 0x35, 0xad, 0x2f, 0x88, 0x7e, 0xb4, 0x0c, 0x8c, 0x62, 0x5a, 0x9a, 0x03, 0x3b, 0x9d, 0x67, 0x1b, 0x94, 0xa2, 0xce, 0x7d, 0x9d, 0x05, 0x0d, 0x19, 0xe2, 0x84, 0x3e, 0xb4, 0x5d, 0xc2, 0xf1, 0x72, 0x9f, 0xbd, 0xad, 0x52, 0xa4, 0x7a, 0xa2, 0x4a, 0x99, 0x28, 0x5b, 0x9a, 0x47, 0xb0, 0xac, 0xc5, 0x02, 0x4b, 0x2d, 0x3f, 0xc5, 0x20, 0xed, 0xcd, 0x8c, 0xda, 0x44, 0x73, 0x0f, 0x68, 0x86, 0x19, 0xce, 0xf0, 0xf5, 0x58, 0x44, 0x0d, 0xb6, 0x4e, 0x4d, 0x1e, 0xf6, 0x72, 0xcb, 0x3a, 0xff, 0xfb, 0xd1, 0x2a, 0xf6, 0x7e, 0x1f, 0xe0, 0xe0, 0x29, 0xdf, 0xb8, 0x0c, 0x75, 0x2d, 0x28, 0x48, 0x29, 0xa2, 0xd5, 0xcc, 0xe7, 0x9c, 0xf2, 0x0b, 0x12, 0x27, 0x19, 0xd9, 0xb7, 0x10, 0x31, 0x36, 0xc5, 0x51, 0xaa, 0xe5, 0x94, 0xeb, 0x0f, 0x36, 0xaf, 0xb5, 0xdf, 0x22, 0xd5, 0x32, 0xbc, 0xeb, 0xf7, 0x38, 0x68, 0x86, 0x3a, 0x19, 0x43, 0xed, 0x78, 0x1a, 0x15, 0x9e, 0xb9, 0xc2, 0x9c, 0x98, 0x04, 0x10, 0x28, 0x1d, 0x22, 0xd9, 0x3d, 0x20, 0x99, 0x62, 0xfb, 0xd8, 0xec, 0x13, 0x7f, 0xc0, 0x79, 0x99, 0xe2, 0x73, 0x74, 0xf7, 0xa9, 0xc9, 0x05, 0x18, 0xdb, 0x15, 0x11, 0x12, 0x5c, 0xd7, 0xeb, 0x53, 0x6f, 0xba, 0x3b, 0x7c, 0x8c, 0x7d, 0xd8, 0x74, 0xa1, 0x32, 0x8e, 0x3c, 0x3f, 0x59, 0x5d, 0x3c, 0xcf, 0xf5, 0xee, 0x62, 0x2d, 0x50, 0x23, 0xbd, 0x3d, 0x13, 0xce, 0x0d, 0x90, 0xc9, 0xf5, 0xbd, 0x80, 0x2e, 0xf8, 0x7d, 0x9c, 0x9d, 0xbd, 0xd2, 0x2b, 0xad, 0x2b, 0x44, 0x0f, 0x47, 0x07, 0x7b, 0x64, 0x57, 0x2e, 0x9e, 0xbd, 0xff, 0x63, 0xa2, 0xf6, 0x6c, 0xc0, 0x2a, 0x93, 0x77, 0xfb, 0xb8, 0x9c, 0x7a, 0x77, 0x4b, 0x24, 0x6b, 0x0e, 0xb0, 0x2b, 0xa3, 0xcf, 0xa9, 0xec, 0x5c, 0x7d, 0x4c, 0xcd, 0xbf, 0x65, 0xbb, 0x5d, 0x8b, 0x43, 0x69, 0x45, 0xdb, 0x8b, 0x81, 0xdf, 0x3b, 0x34, 0xd6, 0x8c, 0x74, 0xc8, 0x63, 0xd5, 0x88, 0x5c, 0xfe, 0xd7, 0x9b, 0xd8, 0x32, 0x42, 0x88, 0x79, 0x81, 0x33, 0xaa, 0x9c, 0x0e, 0x0e, 0x90, 0x52, 0xf8, 0x44, 0x10, 0xb3, 0x01, 0x07, 0xf9, 0x3b, 0x67, 0x26, 0x71, 0xf2, 0x7b, 0x39, 0xf0, 0x1e, 0xe8, 0xc8, 0xd2, 0xbd, 0xbe, 0x36, 0xae, 0x28, 0x8f, 0xe7, 0xf3, 0x1a, 0xb5, 0x92, 0xf2, 0x46, 0x48, 0xf6, 0xc1, 0xc3, 0x1d, 0x05, 0xe5, 0x26, 0xd3, 0xba, 0x32, 0xcd, 0x17, 0x64, 0xbd, 0xc1, 0xfc, 0xd1, 0x53, 0xbf, 0x8d, 0xd4, 0xf4, 0x03, 0x48, 0x24, 0xb8, 0x16, 0x40, 0x63, 0xce, 0xd3, 0xd1, 0xf2, 0x21, 0x38, 0x9e, 0x01, 0xc4, 0x6a, 0xfb, 0x0b, 0x27, 0x35, 0x6d, 0xf5, 0x65, 0x67, 0xe2, 0x2a, 0x20, 0x32, 0xbc, 0xa8, 0xca, 0x95, 0x24, 0xb2, 0xe9, 0xab, 0xaa, 0xa8, 0xcf, 0xa3, 0xb6, 0xc4, 0x29, 0xe2, 0x5b, 0x72, 0x00, 0x64, 0x64, 0x96, 0x25, 0x04, 0xb0, 0x98, 0x74, 0xfb, 0xe8, 0x90, 0x83, 0x4e, 0x9f, 0x08, 0x0e, 0xbe, 0x71, 0xfa, 0xf5, 0x5f, 0x0d, 0xd9, 0xb3, 0x1e, 0x11, 0xb8, 0x50, 0x28, 0x5d, 0x21, 0xd9, 0x77, 0x28, 0xa7, 0xa8, 0x63, 0x84, 0xeb, 0xab, 0xa1, 0x29, 0x35, 0xf9, 0xc6, 0x6a, 0xfa, 0x7b, 0x31, 0xbb, 0xdc, 0x4a, 0xce, 0x86, 0xd4, 0xcd, 0x64, 0x53, 0x45, 0x4b, 0x0b, 0x8c, 0x1d, 0x76, 0x8d, 0xd2, 0x27, 0x74, 0xf2, 0x37, 0x95, 0x84, 0xe3, 0xfd, 0x43, 0xf6, 0x0c, 0x44, 0xea, 0xbc, 0x4c, 0x52, 0x6f, 0xca, 0x23, 0x48, 0x92, 0xa8, 0x43, 0x3e, 0x64, 0xd6, 0x0e, 0xd1, 0x59, 0xf2, 0xe2, 0xfe, 0xe5, 0xdc, 0x12, 0x9a, 0x65, 0x26, 0x1d, 0x18, 0x1f, 0x8d, 0xf8, 0xeb, 0xc5, 0x92, 0xcc, 0x47, 0x1d, 0x32, 0x60, 0xe7, 0x7b, 0xa6, 0xd2, 0x09, 0xaa, 0x70, 0xfc, 0x1e, 0x02, 0x70, 0x54, 0xff, 0x71, 0x93, 0xa5, 0x28, 0xc9, 0xf4, 0x08, 0x5a, 0xa6, 0x29, 0x85, 0x77, 0xaa, 0xdc, 0xdb, 0x8e, 0xb6, 0x52, 0x48, 0x97, 0x02, 0x16, 0x4c, 0x87, 0x19, 0x06, 0x2f, 0x3f, 0x31, 0x1a, 0x42, 0xc0, 0xd3, 0xed, 0xcf, 0xd5, 0x43, 0x82, 0xcc, 0xc8, 0xbf, 0x4f, 0x45, 0x0f, 0x09, 0x3e, 0xc3, 0x80, 0x39, 0xd2, 0x08, 0xe5, 0x02, 0x63, 0xfe, 0x35, 0xe8, 0x27, 0x9a, 0xb7, 0x54, 0xb2, 0x9d, 0x06, 0x24, 0x2a, 0x22, 0x90, 0xbf, 0x99, 0x48, 0x7a, 0x1a, 0x9e, 0xc7, 0xb5, 0x1f, 0xea, 0x63, 0x2c, 0x45, 0xff, 0x41, 0x59, 0xa7, 0x5e, 0xd1, 0xb4, 0x54, 0x93, 0x30, 0x9f, 0xa7, 0x7e, 0xbb, 0x1f, 0x90, 0x27, 0x32, 0xc1, 0x9d, 0x55, 0x45, 0xf7, 0x25, 0x40, 0x4d, 0xbc, 0xdf, 0x23, 0xd4, 0xcf, 0x5d, 0x2f, 0x03, 0xdf, 0xda }; +constexpr AccessUnit ATRACX_LARGE_AU_EXPECTED_AU = { 0x15f90, 0x159b2, false, 0, {}, { 0x11, 0x92, 0xc6, 0xab, 0x16, 0x53, 0x3d, 0x96, 0x54, 0xa0, 0x81, 0xef, 0x3b, 0x10, 0x94, 0x47, 0x4a, 0x4d, 0x0a, 0x36 } }; + +const std::vector AC3_LARGE_AU_STREAM = { 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xbd, 0x06, 0xe6, 0x81, 0xc1, 0x0d, 0x31, 0x00, 0x05, 0xbf, 0x21, 0x11, 0x00, 0x05, 0xb3, 0x65, 0x1e, 0x69, 0xb2, 0x30, 0x00, 0x00, 0x00, 0x0b, 0x77, 0xe2, 0x05, 0xa5, 0xda, 0x2b, 0xef, 0x62, 0xd4, 0xa5, 0xaf, 0xd9, 0x1b, 0xd0, 0x7c, 0xec, 0x75, 0x5e, 0x09, 0x04, 0x80, 0xb4, 0x45, 0x05, 0x0e, 0xb6, 0xa6, 0x5d, 0x0d, 0x01, 0x68, 0x40, 0xce, 0x9f, 0x93, 0xf9, 0x3e, 0xda, 0x08, 0x41, 0x76, 0xeb, 0x39, 0xfa, 0xbb, 0xe6, 0xd6, 0x8e, 0x40, 0x05, 0x75, 0xbc, 0x84, 0x47, 0x2b, 0x79, 0x20, 0x5e, 0x94, 0x66, 0x36, 0x39, 0x4c, 0xd4, 0xa9, 0xa9, 0xf7, 0xf7, 0x9e, 0x0e, 0x80, 0xe8, 0x5a, 0x63, 0xb4, 0x53, 0x04, 0x59, 0xe5, 0xf6, 0x31, 0xc9, 0x6d, 0xe3, 0x29, 0x13, 0x81, 0xd5, 0x17, 0x70, 0xf3, 0x9c, 0x2c, 0x7a, 0xec, 0xcf, 0x9b, 0xb2, 0xe9, 0x62, 0x25, 0xf3, 0x1f, 0x4b, 0x08, 0xcc, 0x67, 0xaf, 0x7c, 0x21, 0x7a, 0xac, 0xda, 0xf6, 0x06, 0x6d, 0x3f, 0x48, 0xac, 0x8e, 0xc6, 0x0a, 0x49, 0xe3, 0xf6, 0x60, 0x07, 0x62, 0x7b, 0xa6, 0x86, 0x85, 0xf2, 0xac, 0xa2, 0x11, 0x7b, 0xda, 0x9d, 0xa3, 0xad, 0x10, 0xe4, 0xe1, 0x7d, 0x13, 0x8a, 0xe6, 0xcb, 0xe0, 0xf7, 0xec, 0xc0, 0x51, 0x1e, 0xf5, 0x51, 0x4f, 0x08, 0xbc, 0x30, 0xcf, 0xaa, 0x9c, 0x6b, 0xf7, 0xc4, 0x85, 0xe6, 0x72, 0x06, 0xbf, 0x1f, 0x0a, 0x59, 0xf2, 0x27, 0x8e, 0xb2, 0xde, 0x77, 0x1c, 0x4a, 0x6d, 0x3a, 0x10, 0x31, 0x70, 0x19, 0x30, 0x4e, 0x73, 0xbb, 0xf6, 0xf2, 0xf4, 0x7f, 0x5f, 0xb5, 0x08, 0x34, 0x72, 0x40, 0x66, 0x9a, 0xa0, 0xe7, 0xb2, 0x60, 0x12, 0x0b, 0x0a, 0x01, 0x6b, 0x18, 0x0b, 0x63, 0xc9, 0xf2, 0x9c, 0x63, 0xde, 0xf7, 0x41, 0xca, 0xfb, 0x4f, 0x62, 0x69, 0x31, 0x44, 0xd4, 0x78, 0xf6, 0xce, 0xc9, 0xc5, 0x3d, 0x89, 0x7b, 0xee, 0xf9, 0x7b, 0xab, 0x0a, 0x1b, 0xb3, 0x32, 0xc8, 0xad, 0x1a, 0xdc, 0x4c, 0xf4, 0x6d, 0x5d, 0xc0, 0x7a, 0x9b, 0x17, 0x2f, 0xf4, 0x49, 0x15, 0xe3, 0x17, 0x1f, 0x4e, 0x40, 0x2e, 0x51, 0x41, 0xa8, 0x71, 0x0d, 0x9c, 0x7b, 0x4f, 0xad, 0x57, 0xc3, 0xb3, 0xa6, 0x38, 0x50, 0xa0, 0x43, 0x68, 0xa2, 0x38, 0xc1, 0xf3, 0x42, 0xfc, 0x3f, 0xa3, 0x29, 0x06, 0x2b, 0x8a, 0xff, 0x58, 0xa4, 0x61, 0xef, 0xc0, 0xbf, 0x34, 0x99, 0x6b, 0x86, 0xaf, 0x92, 0x4b, 0x00, 0xcd, 0xfe, 0xe8, 0xae, 0x26, 0xfc, 0x9f, 0xb4, 0x55, 0x52, 0x84, 0x5c, 0x06, 0x99, 0xf8, 0x08, 0x98, 0x09, 0x4d, 0x67, 0x7e, 0xc9, 0xa2, 0x98, 0xe0, 0x55, 0xc1, 0x30, 0x87, 0x85, 0x4d, 0xdf, 0xaf, 0x57, 0x09, 0x37, 0x43, 0x3b, 0x49, 0xee, 0x13, 0x69, 0xc8, 0x53, 0xa7, 0x9c, 0xb2, 0x87, 0x87, 0xd5, 0xcf, 0x4b, 0xa8, 0xb0, 0x4a, 0x2e, 0xd2, 0x47, 0x31, 0xad, 0x77, 0x29, 0x43, 0xf7, 0x69, 0x90, 0x8f, 0x84, 0xd5, 0x8a, 0xea, 0xb2, 0x1f, 0x27, 0x7a, 0x2a, 0xf7, 0x6b, 0x90, 0x0f, 0xed, 0x72, 0x97, 0xdf, 0xf2, 0x03, 0xb3, 0xd3, 0xee, 0x99, 0x6e, 0xce, 0x6c, 0x3f, 0x9d, 0xc5, 0x0a, 0x57, 0xcd, 0xbd, 0x5f, 0x25, 0x7b, 0x64, 0x27, 0xb3, 0xef, 0x34, 0xaa, 0x06, 0x1c, 0x6c, 0x75, 0xd2, 0x9d, 0xc8, 0xd5, 0x96, 0x0c, 0x31, 0x9f, 0xdd, 0x75, 0x99, 0x0e, 0x77, 0x10, 0xe5, 0x77, 0xda, 0xc8, 0xde, 0xc5, 0xf5, 0x3b, 0xae, 0x2f, 0xe2, 0x08, 0xc1, 0x43, 0x02, 0xf0, 0x13, 0x15, 0xfc, 0x86, 0xbf, 0xaa, 0x31, 0xac, 0x6b, 0xdd, 0xac, 0x60, 0x4e, 0xe2, 0x69, 0x26, 0xd9, 0x8b, 0xdb, 0x69, 0x41, 0xc8, 0x04, 0x76, 0x29, 0xa1, 0xb3, 0xba, 0xee, 0xf8, 0xa5, 0x1e, 0x02, 0x86, 0x2c, 0x62, 0x0a, 0x00, 0x7d, 0xba, 0x57, 0x39, 0x85, 0xd3, 0x03, 0x7e, 0x42, 0x0c, 0x06, 0x74, 0x15, 0x5b, 0xba, 0x82, 0x96, 0x61, 0x6a, 0x3d, 0x93, 0x8a, 0xae, 0x0c, 0xf1, 0x45, 0x61, 0x22, 0x58, 0xcc, 0xd7, 0x64, 0xb4, 0x23, 0x0a, 0xa7, 0xf1, 0xd8, 0x82, 0xce, 0xb8, 0x3b, 0xf1, 0xc8, 0x9d, 0xb4, 0xb2, 0x2b, 0x9a, 0xc4, 0xf3, 0x9d, 0x6c, 0xe9, 0x5a, 0xca, 0x37, 0x8f, 0x03, 0xb2, 0xad, 0x52, 0x67, 0xd0, 0x53, 0x72, 0xd2, 0xeb, 0xc6, 0x93, 0x41, 0x31, 0x83, 0x60, 0x18, 0x48, 0xb7, 0xe8, 0xe4, 0x93, 0xbc, 0x0b, 0xab, 0xd6, 0x78, 0x8a, 0x7d, 0x24, 0x83, 0x49, 0xf4, 0x80, 0x77, 0xfa, 0xb1, 0xa1, 0xa6, 0x7a, 0x7f, 0xd7, 0xba, 0x9d, 0x62, 0x46, 0x30, 0xc4, 0x38, 0xf5, 0x97, 0x11, 0x00, 0xdc, 0xfe, 0x93, 0xe9, 0xcd, 0xbf, 0xd0, 0x55, 0xea, 0xce, 0xb0, 0x70, 0x76, 0x2d, 0x69, 0x2b, 0xdc, 0xe9, 0x6a, 0xfe, 0xda, 0x36, 0x3b, 0xca, 0x3d, 0x0a, 0x7d, 0x76, 0x7e, 0x0d, 0xad, 0x93, 0xe8, 0xa6, 0xfc, 0x17, 0x31, 0xb0, 0x0b, 0x77, 0xc7, 0x9f, 0x75, 0x41, 0xe3, 0xe3, 0xea, 0x48, 0xc6, 0xe9, 0x62, 0x69, 0xbd, 0x87, 0x86, 0x5f, 0xe4, 0x13, 0xbf, 0xb9, 0x63, 0xc8, 0xb4, 0x24, 0x49, 0x17, 0x5c, 0xe5, 0x5f, 0xc1, 0x4d, 0x77, 0x78, 0x26, 0xbd, 0x66, 0x21, 0xcf, 0xd0, 0x3b, 0x7e, 0x01, 0x06, 0x49, 0x9a, 0x99, 0x46, 0x89, 0x18, 0xa3, 0x3e, 0x1b, 0xae, 0x6a, 0x33, 0xdd, 0xca, 0x36, 0x33, 0x34, 0xa8, 0xa8, 0xd3, 0x18, 0x6c, 0x6b, 0x7e, 0x1e, 0x0f, 0xca, 0x12, 0x35, 0x78, 0xc2, 0x30, 0x84, 0xcf, 0xc4, 0xe5, 0x81, 0x65, 0xc7, 0xf3, 0xb5, 0xed, 0x89, 0xaa, 0x65, 0xcf, 0x9d, 0x71, 0xd8, 0x06, 0x5a, 0xac, 0xe5, 0x66, 0xf2, 0x18, 0xc4, 0x28, 0x54, 0xdc, 0x45, 0x1b, 0x16, 0x7b, 0xd9, 0x56, 0x70, 0x9f, 0x66, 0x92, 0x65, 0x50, 0x95, 0x27, 0x75, 0x2c, 0x85, 0x67, 0x8d, 0x6e, 0x6e, 0x12, 0x09, 0xa5, 0x34, 0x62, 0x55, 0x50, 0xc8, 0xb0, 0xe6, 0xd8, 0x63, 0x81, 0x63, 0xc7, 0x44, 0xf1, 0x35, 0x5e, 0xc6, 0x41, 0x24, 0x6c, 0x00, 0xb3, 0xba, 0x5f, 0x7b, 0x4a, 0x01, 0x49, 0x6a, 0x64, 0x45, 0x7b, 0xf1, 0xce, 0x3b, 0xe3, 0x59, 0xeb, 0x83, 0xd1, 0xda, 0xa7, 0x5e, 0x60, 0x8f, 0x16, 0x32, 0x06, 0xa9, 0xd8, 0x88, 0x2d, 0x5a, 0xf9, 0x21, 0x51, 0xb2, 0x1b, 0x62, 0x2a, 0x6a, 0xce, 0xd3, 0x02, 0x06, 0xc1, 0xf5, 0x2f, 0xe7, 0xb4, 0x6e, 0x22, 0x2b, 0x52, 0x80, 0x94, 0x7c, 0x86, 0xc6, 0x0f, 0xfd, 0xc1, 0xd0, 0x7e, 0xb1, 0x8d, 0xd1, 0x5f, 0xa6, 0xd9, 0x1b, 0x42, 0x62, 0x88, 0x11, 0x68, 0x21, 0x9e, 0x66, 0x6e, 0xca, 0xf6, 0xa0, 0x9a, 0x05, 0xef, 0x4c, 0xa4, 0xf4, 0x59, 0x7a, 0x33, 0x25, 0x22, 0xdc, 0xf8, 0x32, 0x34, 0xbb, 0x2f, 0x0a, 0xf0, 0xb7, 0x2f, 0x47, 0x1a, 0x08, 0x62, 0xcb, 0x46, 0xaf, 0x67, 0xf0, 0x9d, 0x02, 0xb9, 0x24, 0x26, 0x2a, 0x84, 0x61, 0x62, 0x3e, 0x44, 0x36, 0xd0, 0x41, 0x37, 0xf6, 0x48, 0xd7, 0x6d, 0x02, 0x4e, 0xef, 0xe1, 0x57, 0xc3, 0x0a, 0xc4, 0xe3, 0x9f, 0x63, 0x49, 0xed, 0x3a, 0xda, 0x68, 0xd5, 0x51, 0x96, 0x58, 0x05, 0xa6, 0xdc, 0xf9, 0xcb, 0xeb, 0x7d, 0x1a, 0xfe, 0x99, 0x0f, 0xca, 0x35, 0x65, 0xdc, 0x82, 0xae, 0x3b, 0x05, 0x02, 0x0e, 0xad, 0xf7, 0x55, 0xfb, 0xc6, 0x1d, 0xc1, 0x00, 0x50, 0x29, 0x1b, 0x10, 0xa2, 0x4d, 0x7f, 0x58, 0xea, 0x85, 0x56, 0x13, 0x74, 0x76, 0x4e, 0xd4, 0x30, 0xc4, 0xec, 0x81, 0xc2, 0x2d, 0x8d, 0x54, 0x61, 0x50, 0xb2, 0x98, 0xab, 0x89, 0x16, 0x7d, 0xaf, 0x78, 0xa7, 0x99, 0xdd, 0x91, 0xa8, 0x20, 0xc0, 0x0f, 0xf9, 0x76, 0xde, 0xaa, 0x16, 0x2d, 0xcb, 0xc3, 0x12, 0xeb, 0x6a, 0x9c, 0x57, 0xfa, 0x76, 0xb0, 0x30, 0x3a, 0x0e, 0x82, 0xc1, 0x6f, 0x9a, 0x43, 0xfa, 0x8d, 0xf6, 0xf9, 0x97, 0x1a, 0xf9, 0x70, 0x44, 0xa5, 0x04, 0x13, 0xc5, 0x5e, 0x89, 0x68, 0xf5, 0x3c, 0x53, 0xa7, 0xd2, 0x2d, 0x15, 0x77, 0x7a, 0xfc, 0x3e, 0x94, 0xe4, 0xa7, 0x66, 0xbe, 0xe6, 0xcd, 0x72, 0x34, 0xa8, 0x92, 0x64, 0x18, 0x81, 0x16, 0x8a, 0x7c, 0x12, 0xdd, 0x9a, 0xc0, 0x3e, 0x2f, 0x0b, 0xb7, 0x55, 0xfe, 0xc3, 0x2a, 0x04, 0x60, 0x0d, 0x98, 0x4c, 0x63, 0xfb, 0x13, 0x2b, 0xb9, 0x07, 0xc3, 0xb0, 0x69, 0xec, 0x56, 0x55, 0xe4, 0x50, 0xc5, 0x60, 0xb7, 0xd6, 0x2d, 0xf2, 0xff, 0xbb, 0x26, 0xeb, 0xb3, 0xc5, 0x41, 0xdd, 0x11, 0x20, 0x97, 0xb3, 0x4a, 0xa8, 0x14, 0xb0, 0xa0, 0xd4, 0x35, 0xaa, 0x5a, 0xa7, 0x68, 0xb5, 0xcc, 0x8d, 0xab, 0xa2, 0x68, 0x38, 0x9a, 0x9e, 0xbb, 0xe6, 0x3d, 0x2f, 0xc0, 0xd3, 0xe9, 0x9c, 0x74, 0x51, 0xe8, 0xce, 0x5d, 0x0d, 0xcf, 0xea, 0x44, 0x01, 0x32, 0x39, 0x8e, 0x00, 0x0e, 0xa4, 0x0e, 0x28, 0x04, 0xf1, 0x1b, 0xa2, 0xd1, 0x34, 0xa6, 0x52, 0xc5, 0x2c, 0xd4, 0xf2, 0xd5, 0x53, 0x99, 0x67, 0x07, 0x92, 0x6e, 0x6c, 0x66, 0xfe, 0x29, 0xbd, 0xdf, 0x63, 0x72, 0x82, 0xde, 0xb1, 0x2a, 0xb7, 0x06, 0xc1, 0xa6, 0x71, 0x61, 0x61, 0x79, 0xc0, 0x0c, 0x1f, 0x56, 0x5e, 0x97, 0xe6, 0xb8, 0xfb, 0xe6, 0x00, 0xcd, 0x1a, 0xb5, 0x18, 0xf9, 0xad, 0x35, 0x6b, 0x9d, 0xf8, 0x9a, 0xfc, 0x87, 0x7a, 0xb6, 0x3b, 0x10, 0xa0, 0xb7, 0x67, 0xc5, 0xa0, 0xdb, 0xd8, 0x59, 0xde, 0xb2, 0x18, 0x81, 0xce, 0x84, 0xbc, 0xf0, 0xfe, 0xa2, 0x53, 0x96, 0x15, 0x17, 0x0f, 0x94, 0x4c, 0xac, 0x3b, 0x4c, 0x11, 0x1f, 0xd7, 0x07, 0x79, 0x12, 0xe0, 0x1a, 0xbc, 0x16, 0x16, 0x30, 0x54, 0x71, 0x05, 0x0f, 0x66, 0x7f, 0xb9, 0x2e, 0xd7, 0x38, 0xbe, 0xaf, 0x78, 0x7d, 0x91, 0x6a, 0xee, 0x33, 0xa0, 0xea, 0xe0, 0xed, 0xbf, 0x0f, 0x59, 0x2d, 0xe3, 0x07, 0xd4, 0xa0, 0xe3, 0xb8, 0xdf, 0x83, 0x1a, 0xd8, 0x22, 0x9b, 0x42, 0x5a, 0x08, 0x2e, 0x7a, 0x4b, 0x17, 0xf4, 0x92, 0xb9, 0xb2, 0x99, 0x5e, 0x28, 0x0f, 0x4e, 0x51, 0x4f, 0x97, 0x7a, 0x1a, 0xa0, 0x7b, 0x5a, 0x0d, 0x4e, 0xab, 0x46, 0xed, 0x93, 0xa0, 0xc2, 0x04, 0x9b, 0x6f, 0xde, 0xc9, 0xf5, 0xf4, 0xb3, 0x7c, 0x37, 0xef, 0x4a, 0x93, 0xf7, 0x9b, 0x1f, 0x7a, 0x23, 0xe8, 0x08, 0x87, 0x19, 0x2f, 0xe2, 0xb8, 0xe6, 0x34, 0xac, 0x96, 0x66, 0x61, 0xf0, 0xdc, 0x16, 0x15, 0x79, 0x43, 0x3c, 0xc0, 0x43, 0x6c, 0x11, 0x51, 0x91, 0x8a, 0xd8, 0x48, 0x8d, 0xae, 0x1c, 0x69, 0xec, 0x76, 0x60, 0xdd, 0xb8, 0xc6, 0x1c, 0x40, 0x2b, 0xf0, 0x29, 0x11, 0x27, 0xc1, 0x36, 0x2c, 0x49, 0x74, 0xbd, 0xc1, 0xfe, 0x0d, 0x12, 0x3f, 0x1f, 0xd4, 0x27, 0x30, 0xc3, 0x4e, 0xfd, 0x87, 0x72, 0x25, 0xd7, 0x45, 0x12, 0xce, 0x9a, 0x93, 0x50, 0x24, 0xd2, 0x70, 0xf9, 0x46, 0x1b, 0x53, 0x59, 0x6b, 0x9e, 0x65, 0x39, 0x60, 0x01, 0xe1, 0xbd, 0x0c, 0x61, 0xfb, 0x3c, 0x0a, 0x7f, 0x3c, 0xd1, 0x5f, 0x4b, 0x82, 0xfb, 0x55, 0xde, 0x86, 0x66, 0xd1, 0xb6, 0x7c, 0x6e, 0xd9, 0xe1, 0x9f, 0x41, 0x45, 0x56, 0x2f, 0x91, 0xaf, 0xc5, 0x65, 0x45, 0xd8, 0x34, 0x31, 0x7d, 0xbe, 0xb1, 0xf5, 0xe6, 0x13, 0x8e, 0x72, 0x2e, 0x3b, 0x76, 0xbc, 0x3f, 0x34, 0x82, 0x25, 0x35, 0x6f, 0xaf, 0xe2, 0x90, 0xef, 0x08, 0xc6, 0xb4, 0xdc, 0xa5, 0x11, 0xea, 0xbb, 0x23, 0x8b, 0x71, 0x4e, 0xba, 0x6e, 0x6f, 0xb2, 0x70, 0xca, 0xf0, 0xe1, 0xfa, 0xc2, 0x93, 0x37, 0xc9, 0x24, 0xa3, 0xb9, 0x38, 0x7e, 0x38, 0xc6, 0xde, 0x2c, 0x73, 0x70, 0x1d, 0x21, 0x4b, 0xae, 0x3e, 0x46, 0x2c, 0x6f, 0x9f, 0x10, 0xd0, 0xb0, 0xee, 0x1b, 0x14, 0x19, 0x55, 0x59, 0x72, 0x7c, 0xcb, 0x53, 0x61, 0xdc, 0x52, 0x1d, 0xea, 0x47, 0x7b, 0xed, 0xe6, 0x06, 0x6e, 0xbf, 0xe8, 0x56, 0xa8, 0xa7, 0xd7, 0x5d, 0xb8, 0xd0, 0x8c, 0x9f, 0xcf, 0xc3, 0x33, 0xae, 0x5a, 0x73, 0x02, 0xc2, 0x76, 0x7f, 0x65, 0x82, 0x23, 0x58, 0xed, 0x6c, 0x5e, 0xde, 0x98, 0x6c, 0x3e, 0x36, 0xec, 0x8a, 0xc1, 0x0b, 0xa4, 0x28, 0x20, 0x2c, 0xf8, 0xcd, 0xe7, 0x49, 0x50, 0xec, 0x6f, 0xe0, 0xcc, 0x76, 0x03, 0x10, 0x6b, 0xdf, 0xf8, 0x94, 0x2d, 0x71, 0x2b, 0x11, 0xd5, 0x64, 0x3f, 0xeb, 0x62, 0x50, 0x40, 0xf8, 0x94, 0x9f, 0xa4, 0x10, 0x61, 0x6c, 0x18, 0x50, 0xa1, 0x0c, 0xaf, 0x13, 0x5b, 0x96, 0x2b, 0x17, 0x05, 0x19, 0xd3, 0xba, 0x83, 0xba, 0xc2, 0xed, 0xb7, 0x58, 0xe5, 0x57, 0xd5, 0x26, 0xf4, 0xaf, 0xac, 0x0b, 0x06, 0x28, 0x79, 0xee, 0xbf, 0x76, 0xf8, 0xee, 0x93, 0xcd, 0x0a, 0x88, 0x00, 0xc2, 0xfe, 0x5a, 0x44, 0xce, 0x0b, 0xc7, 0xb5, 0x5d, 0xb8, 0x8c, 0x5c, 0x91, 0xbf, 0xd6, 0x4d, 0x16, 0xfd, 0x76, 0x5f, 0xd6, 0x2c, 0x71, 0xf7, 0x45, 0xe7, 0xf0, 0x61, 0x24, 0x55, 0x86, 0xb1, 0x88, 0x0b, 0x77, 0xc7, 0xe0, 0x54, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x02, 0xe4, 0x61, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbd, 0x07, 0xec, 0x81, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0xf2, 0x8f, 0x7b, 0xf7, 0x90, 0x80, 0xe5, 0x04, 0x40, 0xe5, 0x72, 0xe8, 0x0f, 0x33, 0x29, 0xa8, 0x11, 0x1b, 0xf6, 0xd9, 0x92, 0x2a, 0xf4, 0x5f, 0xe7, 0x96, 0x33, 0xc4, 0xd5, 0x56, 0x52, 0x07, 0x63, 0xc8, 0xa5, 0xc7, 0x4b, 0x1a, 0xf6, 0x7a, 0x9f, 0x9e, 0x15, 0x3f, 0x8d, 0x9c, 0xd2, 0xb9, 0x72, 0x78, 0x4b, 0xbe, 0x51, 0xbd, 0xca, 0xa2, 0xc7, 0xb0, 0x15, 0x55, 0x23, 0x79, 0x2b, 0x7e, 0x48, 0x2a, 0x9d, 0x5a, 0xb9, 0xc6, 0x9c, 0xbd, 0x91, 0x2f, 0x94, 0x4b, 0xff, 0x05, 0xd9, 0xb8, 0x6c, 0xb7, 0xd5, 0x13, 0x16, 0xd7, 0x7e, 0xd3, 0x73, 0xd8, 0x18, 0x4b, 0x8c, 0x1b, 0x89, 0xdd, 0xdb, 0x43, 0x39, 0x73, 0x7b, 0x9f, 0x65, 0x20, 0x03, 0x74, 0xc8, 0xf4, 0x31, 0x23, 0xe8, 0xae, 0xcd, 0x7b, 0x08, 0x9d, 0x38, 0xa0, 0x48, 0x8b, 0xa2, 0xe5, 0xe6, 0xa6, 0x72, 0x1f, 0x2a, 0x71, 0x84, 0x15, 0x4d, 0xde, 0x68, 0x3e, 0xb3, 0x74, 0x0d, 0xe1, 0x5a, 0xa5, 0xc0, 0x5b, 0x95, 0x57, 0x39, 0x24, 0xda, 0xde, 0x36, 0x36, 0x59, 0x85, 0x5a, 0x8b, 0x5d, 0x6f, 0x7a, 0xfe, 0x20, 0x12, 0x9e, 0x01, 0x6e, 0xe1, 0x2d, 0x3a, 0xb5, 0xa9, 0x53, 0xcc, 0x20, 0x55, 0xcc, 0x9f, 0xe7, 0xda, 0xb0, 0x91, 0x71, 0xb3, 0xa1, 0x71, 0x49, 0xab, 0xa4, 0x41, 0xeb, 0x44, 0xb0, 0x14, 0x70, 0x69, 0xd9, 0x61, 0x3d, 0x08, 0x39, 0xee, 0x44, 0xb0, 0x14, 0x0b, 0xdb, 0xb5, 0xa6, 0x75, 0x6d, 0x11, 0x06, 0x61, 0x5f, 0x99, 0xdf, 0xd8, 0x20, 0x17, 0x96, 0x07, 0xee, 0xa8, 0x11, 0xc3, 0xbc, 0x5b, 0x1d, 0x23, 0x76, 0x87, 0x50, 0x99, 0xc8, 0x59, 0x31, 0xa1, 0x7d, 0x89, 0x46, 0x65, 0x74, 0x9c, 0x07, 0xc6, 0x9d, 0x9a, 0x53, 0xd3, 0x81, 0x68, 0xf0, 0xf5, 0x9b, 0xb9, 0x10, 0x1d, 0x5d, 0x5b, 0x34, 0x2a, 0xc6, 0x29, 0xbb, 0xd2, 0x00, 0xef, 0xee, 0x86, 0xfc, 0xcd, 0x6b, 0x5d, 0xf8, 0xa0, 0x46, 0x8a, 0xd3, 0x6d, 0x8f, 0xc1, 0x69, 0x29, 0xad, 0xa2, 0xcc, 0x33, 0x10, 0x53, 0x1f, 0xbd, 0xc6, 0x08, 0x0e, 0xd7, 0x3f, 0xcc, 0xd0, 0xaf, 0xae, 0x54, 0x16, 0x40, 0x0e, 0x64, 0xc4, 0x91, 0x50, 0xd5, 0xc3, 0x2d, 0xe9, 0xe7, 0x2e, 0x9b, 0x97, 0xd7, 0xd5, 0x63, 0xdd, 0xb5, 0x29, 0x46, 0x2c, 0xec, 0xc5, 0x02, 0x1b, 0x3c, 0xb4, 0xe4, 0xb4, 0xae, 0xa7, 0x25, 0x84, 0x0b, 0x77, 0xd3, 0xd3, 0x02, 0xdd, 0x1f, 0xab, 0x25, 0x18, 0x63, 0xe3, 0xa5, 0xb6, 0x67, 0x97, 0x42, 0xae, 0x8d, 0x77, 0x0f, 0xaa, 0x8b, 0xe2, 0x67, 0x49, 0xa2, 0x87, 0xd8, 0x66, 0x5d, 0xc5, 0xb3, 0x12, 0x52, 0x88, 0xb3, 0x34, 0x8c, 0x03, 0xda, 0x92, 0x1e, 0xbc, 0x73, 0xba, 0x4f, 0x54, 0xb4, 0x70, 0x17, 0x0e, 0x2b, 0xa9, 0x3b, 0x61, 0x32, 0x2b, 0x22, 0xb2, 0xb8, 0x61, 0xfc, 0xbb, 0xe6, 0x84, 0xa3, 0x1c, 0x65, 0xe8, 0xe4, 0x08, 0x55, 0xf0, 0x7a, 0xfc, 0x66, 0x2b, 0x7f, 0xaf, 0xe2, 0x74, 0xdd, 0x06, 0xb4, 0xa2, 0x2f, 0x44, 0xb3, 0x40, 0x84, 0xba, 0x95, 0xf5, 0x6d, 0xf9, 0x4b, 0xa2, 0x33, 0x92, 0xfe, 0x89, 0x2d, 0xd6, 0x32, 0xd4, 0xe0, 0x2b, 0x10, 0x9f, 0x65, 0xe9, 0x18, 0x76, 0x23, 0xa6, 0x78, 0x4d, 0xdf, 0x7f, 0xce, 0x87, 0xf7, 0x5a, 0xfe, 0x8f, 0x6b, 0xd7, 0x68, 0xcd, 0x00, 0x75, 0xaf, 0x14, 0xdd, 0xea, 0x85, 0x39, 0x83, 0x73, 0x2b, 0xe5, 0x64, 0x78, 0x03, 0x51, 0x4b, 0x06, 0x67, 0x32, 0x73, 0x58, 0x0c, 0x86, 0xcc, 0x09, 0xfb, 0x41, 0x7f, 0x2d, 0x67, 0xe9, 0xcf, 0x0e, 0x5d, 0x73, 0x0b, 0x76, 0x12, 0xb1, 0x66, 0x5f, 0xd0, 0x46, 0x57, 0x23, 0xad, 0xb9, 0xf8, 0x8e, 0x99, 0xc4, 0xd2, 0xb6, 0x88, 0x40, 0x7a, 0x48, 0xe1, 0x38, 0x08, 0xc3, 0x90, 0xec, 0x32, 0xd5, 0x68, 0x38, 0xfb, 0x58, 0xc4, 0x9e, 0xb2, 0x0d, 0x9e, 0xb2, 0x22, 0x22, 0xb4, 0x62, 0x49, 0x56, 0x26, 0x5f, 0xbc, 0x1f, 0xb9, 0x1b, 0x02, 0x6e, 0x0b, 0x22, 0xcc, 0x31, 0x7e, 0x64, 0x82, 0xc5, 0x75, 0x78, 0xf5, 0xa7, 0x56, 0x2e, 0x19, 0xf8, 0x73, 0x66, 0xea, 0x16, 0x52, 0x0c, 0xc4, 0xcb, 0x55, 0xf0, 0x34, 0x2d, 0x42, 0x2f, 0x0c, 0x50, 0x41, 0xc5, 0x68, 0x09, 0xd1, 0x14, 0xab, 0x6b, 0x46, 0x45, 0x35, 0x92, 0x93, 0xd0, 0x49, 0x72, 0xdb, 0x99, 0x10, 0xcd, 0x31, 0x5b, 0x97, 0x6c, 0xb7, 0x1a, 0xea, 0x04, 0x77, 0xd5, 0xb5, 0x05, 0x52, 0xe6, 0x43, 0xc9, 0x07, 0x67, 0xf7, 0xb4, 0xf1, 0x05, 0x2b, 0xb2, 0x88, 0x9a, 0x20, 0xe6, 0x4a, 0x8b, 0x8f, 0xb9, 0x32, 0x0a, 0x85, 0x2e, 0x1c, 0xcb, 0x5d, 0xdc, 0x56, 0x7f, 0x2f, 0x7a, 0x59, 0x4b, 0xf2, 0x6b, 0xb7, 0x37, 0xf8, 0x46, 0xf2, 0x85, 0xfb, 0x19, 0x37, 0x69, 0x46, 0x48, 0xbb, 0xe6, 0x3d, 0x70, 0xba, 0xbf, 0x18, 0xf7, 0xbf, 0x9d, 0xc4, 0xf6, 0xb8, 0xda, 0xdb, 0xc5, 0x14, 0x35, 0xe4, 0x2c, 0x35, 0x33, 0x13, 0x6d, 0xe6, 0xb2, 0x04, 0x9b, 0xed, 0x4c, 0x9c, 0xd3, 0xf6, 0x6d, 0x34, 0xca, 0xb7, 0xbd, 0xf0, 0x4e, 0x98, 0xbe, 0xbd, 0x70, 0xb8, 0x82, 0xef, 0xd9, 0x2c, 0x9e, 0x75, 0x14, 0x2d, 0xd3, 0x74, 0x7f, 0xf2, 0xb0, 0x6b, 0x7f, 0xb6, 0x38, 0x02, 0x1f, 0x56, 0xe0, 0xf1, 0x91, 0x55, 0x53, 0xf6, 0xad, 0x26, 0xde, 0xcc, 0x64, 0x86, 0xc7, 0xb2, 0x11, 0x74, 0x0a, 0x09, 0x91, 0x53, 0x98, 0x94, 0x44, 0xd0, 0xe5, 0x9a, 0x5f, 0x68, 0x3e, 0x21, 0x14, 0xc6, 0x3f, 0x17, 0x9a, 0x3e, 0x93, 0x6b, 0x8a, 0xbd, 0x34, 0xfe, 0x4e, 0xa8, 0x72, 0xca, 0x20, 0x01, 0x09, 0x52, 0x51, 0x67, 0x36, 0x29, 0xd3, 0x07, 0x5e, 0xbf, 0xed, 0xce, 0x56, 0xfa, 0x98, 0x5b, 0x1c, 0x68, 0xad, 0x92, 0x42, 0xb8, 0x19, 0xfe, 0x3a, 0xbf, 0x4e, 0x1f, 0x06, 0xea, 0xd2, 0x78, 0x02, 0x91, 0x21, 0xfd, 0x88, 0x83, 0x49, 0xc2, 0x31, 0x4e, 0x40, 0x6e, 0x8e, 0x41, 0xbc, 0xd0, 0x74, 0xc4, 0x07, 0xa1, 0x39, 0x8b, 0x95, 0x4c, 0x33, 0x3d, 0x4a, 0x1a, 0xdd, 0x26, 0x1b, 0xcc, 0x03, 0xf5, 0xe6, 0xc3, 0xae, 0xb4, 0x90, 0x33, 0x75, 0x8b, 0xbd, 0xfc, 0xa6, 0x22, 0xea, 0x6b, 0x5d, 0x39, 0x15, 0x1f, 0x15, 0x60, 0xea, 0x56, 0x00, 0xcd, 0x65, 0x28, 0x40, 0x59, 0x87, 0xf6, 0x40, 0x08, 0x61, 0x65, 0x8e, 0xc8, 0xde, 0x2a, 0x5e, 0x4a, 0x2b, 0xfb, 0x1c, 0x61, 0xea, 0xd0, 0xe8, 0x2f, 0xd4, 0xcd, 0x5c, 0xb4, 0xfa, 0x93, 0x87, 0xfd, 0x87, 0x56, 0x83, 0x87, 0x25, 0x25, 0xfb, 0x80, 0x87, 0x59, 0xca, 0x85, 0x55, 0x86, 0x8e, 0xd6, 0x63, 0xfd, 0x0f, 0x15, 0xb5, 0x7c, 0xf7, 0x87, 0xb9, 0x09, 0xa7, 0xbf, 0x9b, 0x36, 0x2b, 0x8c, 0x5b, 0xd1, 0xa6, 0x8a, 0xc2, 0x27, 0x6a, 0xbc, 0xb1, 0xea, 0xa2, 0x04, 0xe0, 0x6e, 0x34, 0xbf, 0x4b, 0x1d, 0x2a, 0xf2, 0xe2, 0x22, 0xfc, 0xb0, 0x58, 0x33, 0x35, 0x01, 0x51, 0x27, 0x03, 0x7f, 0x6a, 0x24, 0xb8, 0xe9, 0x8b, 0x42, 0xbd, 0x7e, 0x60, 0x39, 0xaf, 0x43, 0xfd, 0xfb, 0xb3, 0x4a, 0xc9, 0xb8, 0x21, 0xbd, 0x06, 0xad, 0x39, 0x67, 0x55, 0xc3, 0x8c, 0x01, 0x23, 0x70, 0x48, 0x7c, 0x5b, 0x5b, 0x94, 0xd3, 0x37, 0xd2, 0x27, 0xac, 0x11, 0x78, 0xd9, 0x8e, 0xbb, 0x52, 0xdf, 0x75, 0x96, 0x4d, 0x2f, 0xe0, 0x7a, 0x52, 0x02, 0xb5, 0xed, 0xc5, 0xd1, 0xe4, 0x41, 0xa5, 0x1f, 0xba, 0x3e, 0xf3, 0x1b, 0x7c, 0x61, 0x08, 0xce, 0x2e, 0xba, 0xf3, 0xa4, 0x5b, 0x46, 0x9a, 0x59, 0x64, 0xe2, 0xd6, 0x0c, 0x3e, 0x8d, 0x2d, 0xd4, 0x92, 0x15, 0xec, 0xf8, 0xfb, 0xeb, 0x35, 0x05, 0x13, 0x7c, 0x70, 0x37, 0x88, 0x3e, 0x59, 0xe4, 0x51, 0x53, 0x31, 0xc8, 0x09, 0x51, 0xf7, 0x30, 0xbe, 0xad, 0x8d, 0xe2, 0x63, 0xc8, 0x48, 0xc1, 0xee, 0x3e, 0x71, 0xc4, 0x56, 0xb7, 0x5f, 0xf9, 0x32, 0x58, 0x33, 0x14, 0x7d, 0x51, 0xbf, 0xeb, 0x23, 0x19, 0x4a, 0x07, 0x3e, 0x73, 0xd4, 0xd2, 0xc8, 0xc8, 0x2a, 0x72, 0x24, 0x0e, 0xed, 0xf0, 0xb6, 0x95, 0x0e, 0xea, 0x24, 0xcb, 0x92, 0xdb, 0xa6, 0xf3, 0xc2, 0xef, 0x73, 0x9a, 0xef, 0x3e, 0xb9, 0x00, 0xf3, 0xda, 0xe2, 0x28, 0x3b, 0xb4, 0xfa, 0x5f, 0x9e, 0xc2, 0x4b, 0x8b, 0x4a, 0xbb, 0x7c, 0x25, 0xf6, 0x32, 0xf8, 0x60, 0x07, 0xeb, 0x11, 0xb6, 0x75, 0xf2, 0xc9, 0x66, 0x87, 0xb3, 0x31, 0x96, 0x1b, 0x13, 0x99, 0x13, 0x00, 0x9e, 0xd6, 0xd7, 0x59, 0xba, 0x90, 0xf8, 0xda, 0x00, 0x96, 0x94, 0x0f, 0xa1, 0x74, 0x84, 0x9f, 0xd7, 0xc1, 0xbb, 0xd3, 0xae, 0xe6, 0x7f, 0x0f, 0x82, 0x70, 0x13, 0x4d, 0x55, 0xdc, 0x0a, 0x5f, 0xa6, 0x48, 0xae, 0x16, 0x24, 0x83, 0x38, 0x42, 0x39, 0x7b, 0x23, 0x29, 0x3f, 0x98, 0x76, 0x04, 0x3d, 0x9b, 0x60, 0x51, 0xf7, 0xc7, 0xdb, 0x50, 0x39, 0x4d, 0x87, 0x7c, 0xef, 0x1b, 0xbc, 0xf0, 0x0c, 0xa6, 0x1b, 0x27, 0x4a, 0x0c, 0x6b, 0x09, 0x3b, 0x9f, 0xc3, 0x67, 0x86, 0x0d, 0xdb, 0x11, 0xd2, 0x50, 0xbb, 0x19, 0xe8, 0xb8, 0x18, 0xf2, 0x51, 0xce, 0xa8, 0x9b, 0x12, 0x69, 0x49, 0x3f, 0x22, 0x81, 0xfe, 0x23, 0x50, 0x02, 0xc0, 0xbd, 0x4b, 0xe4, 0x36, 0xd8, 0xe5, 0x5d, 0x11, 0x29, 0x10, 0x79, 0xd9, 0x6e, 0xd0, 0xdb, 0x81, 0x57, 0x9e, 0xa7, 0x54, 0x1f, 0x85, 0xb8, 0x1a, 0xdf, 0xa6, 0xbf, 0x0a, 0x43, 0x74, 0xc2, 0xb8, 0x6c, 0x09, 0x20, 0xbe, 0x59, 0xae, 0x05, 0xc7, 0x52, 0xe2, 0x67, 0xa8, 0x00, 0x21, 0x23, 0xbd, 0x3e, 0x6a, 0x2f, 0x10, 0x44, 0x09, 0xfb, 0x62, 0x35, 0xe0, 0x9a, 0x41, 0x1f, 0x06, 0x72, 0x12, 0x49, 0xed, 0x26, 0x78, 0x67, 0xdd, 0xfb, 0x9e, 0x28, 0xe4, 0x8d, 0xe1, 0x7a, 0xa2, 0x2f, 0x64, 0xca, 0xda, 0xa0, 0xee, 0x51, 0xc5, 0x2c, 0x8d, 0x65, 0x8c, 0xb1, 0x01, 0xd0, 0x91, 0x5f, 0x60, 0x8f, 0xba, 0xbd, 0x6a, 0x7f, 0x35, 0x40, 0x74, 0xaa, 0x24, 0xad, 0x42, 0xcc, 0xfa, 0xba, 0x02, 0xc4, 0xdc, 0xda, 0x24, 0x87, 0xb7, 0xd6, 0xc9, 0x1e, 0x3e, 0xd5, 0xb2, 0x31, 0x83, 0xc8, 0x32, 0x99, 0x9e, 0xef, 0xec, 0x94, 0xe6, 0x0c, 0xba, 0x6d, 0x0d, 0x0e, 0x18, 0x3e, 0x5c, 0xfb, 0xa1, 0xbc, 0xda, 0x16, 0xec, 0x71, 0xd7, 0x67, 0xe6, 0xbb, 0x2e, 0x88, 0x4c, 0x37, 0x14, 0x71, 0x23, 0x38, 0x6d, 0xae, 0x4b, 0xb0, 0x7a, 0xd1, 0xdb, 0x2a, 0x6d, 0xbb, 0xd5, 0x9f, 0x38, 0xdf, 0x4b, 0x43, 0xe5, 0xfa, 0x27, 0x5c, 0x95, 0x45, 0x28, 0x6a, 0xfe, 0x29, 0x82, 0x49, 0x24, 0x11, 0x59, 0xc1, 0x81, 0x37, 0x22, 0x18, 0xf6, 0x35, 0xf3, 0x74, 0x54, 0xea, 0x4c, 0xed, 0x04, 0x71, 0x14, 0x20, 0x09, 0xbf, 0x79, 0x34, 0xa5, 0x15, 0xdb, 0x9c, 0xa0, 0x18, 0x67, 0xbc, 0x74, 0x83, 0x5f, 0x7e, 0x7e, 0xbf, 0x1a, 0x8a, 0x8b, 0xf3, 0xb8, 0xe8, 0x9e, 0xb6, 0x98, 0x4a, 0x99, 0x0b, 0x77, 0x9a, 0xf6, 0x47, 0x24, 0x34, 0xf3, 0xcb, 0xc3, 0x48, 0x73, 0x6b, 0x17, 0x52, 0x3a, 0xf5, 0x50, 0xcd, 0x9e, 0xc2, 0xec, 0xf6, 0x15, 0x4b, 0x67, 0xf5, 0x8c, 0x90, 0xdc, 0x4b, 0x0a, 0xb4, 0x53, 0xf8, 0x63, 0x10, 0x9d, 0x01, 0x5d, 0x97, 0xc7, 0x9e, 0xc0, 0xcf, 0x99, 0xcd, 0x71, 0x4b, 0x71, 0xd4, 0xf2, 0x3d, 0xb8, 0x79, 0xc1, 0x15, 0xfd, 0xe2, 0xc0, 0xe9, 0xb5, 0x5b, 0xef, 0xb7, 0xc4, 0x72, 0xf9, 0x65, 0x14, 0xad, 0x96, 0x2b, 0x26, 0x3e, 0x75, 0xac, 0xb1, 0xea, 0x9b, 0xd2, 0xe1, 0xd1, 0xb6, 0xe1, 0x5e, 0x46, 0xa7, 0x4f, 0x50, 0xde, 0x00, 0x3b, 0xb2, 0x7d, 0xb0, 0xdf, 0x59, 0x69, 0xd6, 0xac, 0xa1, 0x64, 0xe8, 0xdf, 0xb9, 0x71, 0xf2, 0x31, 0x45, 0x1f, 0xd2, 0x4d, 0x8b, 0x67, 0x18, 0xd9, 0x67, 0x9c, 0xd6, 0x90, 0x64, 0x04, 0x5b, 0x46, 0x12, 0x45, 0xd3, 0xb7, 0xa0, 0xc9, 0xb8, 0x25, 0x79, 0xb7, 0x7c, 0x0e, 0x08, 0xc4, 0x4b, 0x01, 0xef, 0x36, 0x6b, 0xda, 0x9a, 0xb9, 0x34, 0x1b, 0x2c, 0xba, 0xf7, 0xc9, 0xfa, 0x5a, 0x16, 0xec, 0xbb, 0x4d, 0x94, 0x40, 0x1b, 0x37, 0xaf, 0x57, 0x9c, 0x7d, 0xd1, 0x69, 0x12, 0xeb, 0xb7, 0x20, 0x0b, 0x4b, 0x67, 0x9d, 0xfb, 0x6a, 0x58, 0x81, 0xaa, 0x9a, 0xe9, 0xd4, 0xf8, 0xbb, 0x0d, 0x68, 0x8c, 0xe0, 0x88, 0x91, 0x4d, 0xd7, 0x57, 0x73, 0x62, 0x88, 0xd5, 0xb7, 0xc6, 0x2e, 0x53, 0xa1, 0xfa, 0x7b, 0x1f, 0xdf, 0xc4, 0x78, 0x48, 0xcf, 0x06, 0x52, 0xbf, 0xff, 0xa3, 0xf6, 0x97, 0xa4, 0x04, 0x4e, 0xeb, 0x56, 0xa7, 0xf9, 0x39, 0x78, 0x8e, 0x23, 0x0a, 0xbf, 0xd9, 0x4a, 0xde, 0xda, 0x9f, 0x0a, 0x94, 0x2d, 0x8b, 0xb5, 0x7e, 0x28, 0x88, 0xa0, 0xfb, 0x72, 0x63, 0x3c, 0x26, 0xa3, 0x2f, 0xd4, 0x4b, 0xd0, 0x25, 0x6d, 0xc7, 0x9b, 0x34, 0x3d, 0x54, 0xb7, 0xd2, 0x4b, 0x89, 0x81, 0x07, 0x01, 0x89, 0x0e, 0x0f, 0x22, 0x64, 0xce, 0x21, 0xff, 0x4d, 0xfd, 0x9b, 0x04, 0x0f, 0xb8, 0x44, 0xd2, 0xe1, 0x2f, 0x0c, 0x41, 0xdd, 0xf3, 0x72, 0xdd, 0x02, 0x89, 0xca, 0x3e, 0xb6, 0xc8, 0xce, 0xff, 0xaf, 0x20, 0xd1, 0x8e, 0x9b, 0xf5, 0x87, 0x94, 0x49, 0x5b, 0x9f, 0x82, 0x28, 0xd4, 0x3c, 0xe3, 0xb9, 0x46, 0x4e, 0x0a, 0x48, 0xfb, 0x8c, 0x77, 0x7b, 0xf1, 0x10, 0x6f, 0x07, 0x8b, 0x75, 0x4f, 0xaa, 0x66, 0x45, 0x6a, 0xef, 0xee, 0x6f, 0x2c, 0x3c, 0x58, 0x30, 0x3c, 0x0d, 0xa2, 0x52, 0x32, 0x6a, 0x37, 0xda, 0x25, 0xd5, 0x02, 0xf9, 0x64, 0x36, 0x0e, 0x42, 0xb9, 0xb6, 0x88, 0xa9, 0xd5, 0xd1, 0x58, 0x3d, 0x33, 0x4d, 0x92, 0xa0, 0x10, 0xe0, 0x05, 0x63, 0xc8, 0x0a, 0x72, 0x6a, 0x95, 0xa7, 0x71, 0x18, 0x6c, 0x23, 0x65, 0xab, 0x01, 0x77, 0xa7, 0x23, 0x38, 0xd9, 0x1a, 0xec, 0x4e, 0x58, 0x1f, 0x5e, 0xfc, 0xf0, 0x7c, 0xf6, 0x3e, 0x00, 0x06, 0xfc, 0x10, 0x92, 0xf9, 0x07, 0x2c, 0x60, 0xcf, 0xbd, 0x74, 0xb6, 0x5b, 0xe4, 0x81, 0x07, 0x7b, 0x92, 0x8c, 0x0b, 0xf1, 0xc1, 0xf9, 0x60, 0x96, 0x1c, 0x1f, 0xf6, 0x6e, 0x21, 0x99, 0xea, 0xce, 0x12, 0x8f, 0x9b, 0xe4, 0x69, 0xaf, 0x3e, 0x61, 0x85, 0xca, 0x96, 0xbf, 0xcb, 0xbd, 0xb3, 0x91, 0x65, 0x9a, 0xcf, 0xe8, 0xcc, 0x98, 0xb1, 0xa5, 0x5a, 0xd4, 0xaa, 0xff, 0x07, 0x54, 0x4e, 0xb9, 0x1c, 0x0b, 0x77, 0xef, 0x10, 0x11, 0x0f, 0xa7, 0x75, 0xf8, 0x24, 0xe8, 0xe2, 0xf5, 0x9f, 0xe0, 0x91, 0xd4, 0x39, 0xad, 0xd9, 0x97, 0x44, 0xc0, 0xd1, 0x00, 0x66, 0xfa, 0x69, 0xad, 0xd1, 0x2c, 0xbc, 0x46, 0x5b, 0xe7, 0x4f, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x02, 0xe4, 0x61, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbd, 0x07, 0xec, 0x81, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x97, 0xe6, 0x8b, 0xbe, 0x78, 0x2d, 0xeb, 0xc6, 0x0e, 0x8e, 0x5a, 0xa9, 0xee, 0x19, 0xd4, 0x5a, 0x17, 0x32, 0xb0, 0xf9, 0x3c, 0x7e, 0x4a, 0xb1, 0x7f, 0x9b, 0xc0, 0x9e, 0xf5, 0x0d, 0x22, 0x73, 0x1e, 0x93, 0xac, 0x8f, 0x06, 0xea, 0x26, 0x10, 0x2f, 0xca, 0x13, 0xc0, 0x8e, 0xcd, 0x52, 0x13, 0x59, 0xdf, 0x30, 0xda, 0x86, 0x9b, 0x82, 0x5a, 0xbd, 0x13, 0x34, 0xcb, 0x58, 0x31, 0xad, 0x08, 0x49, 0xc3, 0x08, 0x5b, 0xf2, 0xf8, 0x13, 0xec, 0x7a, 0x0b, 0x77, 0x1a, 0x06, 0x1f, 0xe7, 0x4b, 0xf8, 0xf8, 0x1e, 0x75, 0xab, 0xa3, 0x3e, 0xb5, 0x5f, 0x85, 0xc3, 0x77, 0xc9, 0x81, 0xeb, 0x46, 0xd9, 0x3b, 0x91, 0xe6, 0xc2, 0x13, 0x16, 0x39, 0xf0, 0x50, 0x89, 0xa6, 0x79, 0x83, 0xba, 0xe4, 0x0e, 0x6c, 0x1b, 0x8b, 0xf2, 0x46, 0xc7, 0x63, 0x01, 0xb8, 0x36, 0x45, 0x6d, 0x89, 0xdb, 0xff, 0x30, 0xa8, 0xb7, 0x67, 0x48, 0xa7, 0x74, 0xe3, 0x08, 0xbf, 0x1a, 0xa0, 0xeb, 0x24, 0xa9, 0xfb, 0x11, 0x33, 0xb0, 0x11, 0xc6, 0x22, 0x6f, 0x23, 0x99, 0x3a, 0xf2, 0x8d, 0xc7, 0x9d, 0x3c, 0xab, 0xf1, 0xaa, 0x7f, 0x19, 0x9b, 0x2f, 0xcf, 0x3f, 0xf4, 0xe7, 0x2d, 0xda, 0x49, 0x70, 0x09, 0x12, 0xb3, 0xe8, 0xc5, 0xec, 0x29, 0xd9, 0xf0, 0x36, 0x40, 0xdf, 0xdc, 0x10, 0x54, 0xba, 0x4e, 0xad, 0xbd, 0x6b, 0xe8, 0xc0, 0xed, 0x81, 0x8e, 0x57, 0xb0, 0x1c, 0xd3, 0x6c, 0x7f, 0x10, 0x1c, 0x5e, 0x51, 0x34, 0x50, 0x48, 0x9b, 0x90, 0x01, 0x50, 0x7e, 0x36, 0x28, 0x3a, 0x75, 0x90, 0x13, 0x17, 0xe6, 0x43, 0x33, 0xc8, 0xac, 0xba, 0xa8, 0x00, 0x2c, 0xa2, 0xd0, 0x98, 0xfc, 0x97, 0x8b, 0x14, 0x70, 0xa7, 0x6e, 0x80, 0xc3, 0x0f, 0xe9, 0x1d, 0x00, 0xe5, 0xac, 0x53, 0x6d, 0x0f, 0xd4, 0xc5, 0x92, 0x0d, 0xf8, 0x2f, 0x75, 0x32, 0x72, 0x8b, 0x87, 0x05, 0xb3, 0xf8, 0xce, 0x1c, 0x1a, 0x41, 0x44, 0xe8, 0x1a, 0x8b, 0x8b, 0x6a, 0x82, 0x29, 0xa7, 0x35, 0x31, 0xe8, 0xee, 0x7f, 0x9f, 0x10, 0xe4, 0xe8, 0xd0, 0xaf, 0x04, 0x18, 0x71, 0xbc, 0x45, 0xdf, 0x59, 0x84, 0xd6, 0xca, 0x1f, 0x8f, 0xd7, 0x29, 0xff, 0xc1, 0x3d, 0x18, 0xc7, 0x91, 0x16, 0x53, 0x90, 0x36, 0x70, 0x7c, 0xad, 0x7f, 0xf2, 0x67, 0x30, 0x22, 0x31, 0x5b, 0x19, 0x21, 0x86, 0x37, 0xd7, 0x82, 0x82, 0x14, 0x35, 0x06, 0xbc, 0x73, 0x55, 0x39, 0x54, 0xbb, 0xf5, 0x6e, 0xd9, 0x47, 0xc3, 0xdc, 0xd0, 0xf8, 0xd0, 0x8b, 0x1c, 0x25, 0x89, 0xdf, 0x78, 0x09, 0xb8, 0xcd, 0x98, 0x8f, 0xe8, 0xf3, 0xbe, 0x88, 0xf1, 0x26, 0x3b, 0x97, 0x02, 0x6e, 0xaa, 0xe9, 0x95, 0x5d, 0x9e, 0xe4, 0xd0, 0x53, 0xa6, 0x91, 0xa0, 0x88, 0x84, 0xc6, 0x2f, 0x0d, 0x41, 0x0c, 0x9d, 0x0f, 0x51, 0x3f, 0xea, 0xf8, 0x85, 0x14, 0x17, 0x70, 0x00, 0xf2, 0x57, 0xa8, 0x6e, 0x79, 0xce, 0x2f, 0x28, 0x3f, 0x6c, 0xb3, 0x28, 0x8b, 0x29, 0xec, 0xe5, 0x42, 0x4e, 0xf1, 0x6f, 0x1b, 0x09, 0x4e, 0x57, 0x49, 0xf8, 0xac, 0x0b, 0x32, 0x9f, 0x84, 0x01, 0x6c, 0xcf, 0x11, 0xc7, 0xb9, 0x01, 0xe1, 0xe2, 0x8d, 0x74, 0xe0, 0xff, 0xcc, 0xb6, 0x26, 0xfb, 0xf2, 0xce, 0xa3, 0x78, 0x59, 0xc5, 0x64, 0x84, 0x72, 0xed, 0xaf, 0xa8, 0x5f, 0x7d, 0xe2, 0x17, 0xa1, 0xb2, 0xc9, 0x21, 0xb0, 0x83, 0x5b, 0x2a, 0xea, 0xc6, 0xa8, 0xe0, 0x63, 0x61, 0x73, 0x1e, 0x43, 0xc8, 0xc4, 0x29, 0x19, 0xa8, 0x21, 0x1b, 0xb5, 0x80, 0x15, 0x23, 0xf4, 0xeb, 0x3e, 0x3a, 0xcc, 0x88, 0x88, 0xae, 0x5c, 0x52, 0xd5, 0xb3, 0x2f, 0x9e, 0x74, 0x97, 0x61, 0x14, 0x1b, 0x82, 0xaa, 0x75, 0xdf, 0x08, 0x58, 0x94, 0x27, 0xe8, 0x59, 0x6b, 0xc8, 0xd6, 0x2e, 0x2a, 0xc5, 0x83, 0x80, 0x64, 0x32, 0x77, 0xd9, 0xf1, 0x7c, 0xca, 0x27, 0xe2, 0x68, 0xbc, 0xf2, 0x41, 0x49, 0x5f, 0x52, 0xbf, 0xef, 0xf6, 0xcc, 0x70, 0x94, 0x37, 0xa8, 0x2d, 0xb2, 0x15, 0x9a, 0xab, 0x45, 0x26, 0xee, 0x5c, 0x5c, 0x06, 0x03, 0x24, 0x21, 0xff, 0xc5, 0x86, 0x08, 0xbe, 0x96, 0xda, 0x36, 0x45, 0x6a, 0x4d, 0xa7, 0xb6, 0xce, 0xd4, 0xde, 0x66, 0x87, 0x4e, 0xc3, 0xbb, 0x3c, 0xe7, 0xf6, 0xe5, 0x56, 0x38, 0xd0, 0x3a, 0x94, 0x9a, 0xe4, 0xea, 0x97, 0x5c, 0x1e, 0xe6, 0x1a, 0x99, 0xc8, 0xf6, 0x50, 0x3d, 0x76, 0xf9, 0xfc, 0x37, 0xbd, 0xd0, 0x7a, 0xc3, 0x51, 0x02, 0x2e, 0xea, 0xb4, 0x43, 0x88, 0x1f, 0xcb, 0x95, 0x6a, 0xda, 0x05, 0xfc, 0x8a, 0xa4, 0x2e, 0xa0, 0x60, 0x90, 0x7c, 0x66, 0xdb, 0xa7, 0x70, 0xb8, 0x39, 0xe2, 0xca, 0x74, 0x0c, 0xf8, 0x60, 0x59, 0x15, 0xa2, 0x62, 0x76, 0x73, 0xfa, 0xf3, 0x74, 0x4f, 0x57, 0xc4, 0xd4, 0xba, 0xca, 0x2e, 0x40, 0x9c, 0x45, 0x59, 0xbb, 0x6c, 0x88, 0xbb, 0x30, 0x8e, 0xdf, 0x01, 0xbb, 0x9d, 0xbc, 0xae, 0x64, 0x2f, 0xe2, 0x48, 0xbd, 0x10, 0xd6, 0xad, 0x31, 0x93, 0xb8, 0xff, 0x06, 0xf8, 0xc6, 0x01, 0x8c, 0x0e, 0x87, 0x63, 0xbb, 0x9d, 0x80, 0xa5, 0x5e, 0x0e, 0x8b, 0xc1, 0xb6, 0xec, 0xfe, 0x46, 0x23, 0x64, 0x54, 0x52, 0x46, 0x46, 0x79, 0x07, 0x4e, 0xd0, 0xd7, 0x6d, 0x8d, 0xe1, 0x9a, 0xd1, 0xfe, 0xa2, 0x38, 0xfb, 0xdf, 0x03, 0x47, 0x78, 0xd5, 0x01, 0x5c, 0xf9, 0x48, 0xa6, 0x63, 0xa0, 0xe4, 0xfb, 0x50, 0x35, 0x9f, 0xb8, 0xce, 0x80, 0x9f, 0xb5, 0x2b, 0x01, 0xcf, 0x78, 0x31, 0x72, 0x2c, 0x44, 0x66, 0xb7, 0x7d, 0x6f, 0xfd, 0x00, 0x25, 0x0e, 0xf9, 0x04, 0x98, 0x49, 0xf5, 0xc1, 0xeb, 0xae, 0x27, 0x95, 0xe4, 0x47, 0xc3, 0xb5, 0x27, 0x64, 0x2d, 0x1a, 0xa5, 0x0b, 0x57, 0xde, 0xa3, 0x23, 0xda, 0x11, 0xd5, 0xeb, 0xa9, 0xec, 0xdc, 0x6f, 0xeb, 0xc2, 0x95, 0x56, 0xf4, 0x26, 0x6d, 0xb4, 0x64, 0x8e, 0x8c, 0x88, 0x1d, 0x59, 0x25, 0xb6, 0x56, 0x78, 0x85, 0x3d, 0xf4, 0xd9, 0x12, 0xa0, 0x7a, 0xc8, 0xd2, 0x49, 0x0c, 0xfc, 0x68, 0x1c, 0xbd, 0xf5, 0xe6, 0x9a, 0x0f, 0x54, 0x1e, 0x37, 0x60, 0x9e, 0x93, 0xe5, 0xe7, 0x46, 0x9d, 0x0d, 0x2f, 0xd7, 0x61, 0xfc, 0x4c, 0xdf, 0x6c, 0x39, 0x07, 0x4f, 0x4b, 0x04, 0xfb, 0xec, 0x5c, 0x83, 0x54, 0x06, 0x14, 0x80, 0x05, 0x5f, 0xba, 0xf9, 0xec, 0x2f, 0xe3, 0x43, 0x74, 0xc6, 0x4d, 0xb9, 0x48, 0x93, 0xd8, 0xc8, 0x37, 0xdd, 0xf5, 0x39, 0x0a, 0x64, 0xb7, 0x91, 0x79, 0xf8, 0x85, 0x03, 0xbb, 0x41, 0xa1, 0xb1, 0x62, 0x2c, 0xd7, 0xec, 0x62, 0xc4, 0xc6, 0xc5, 0xc4, 0xdb, 0xb8, 0xf7, 0x5f, 0x41, 0xb7, 0x92, 0xe7, 0x17, 0xfc, 0xcf, 0x4f, 0x35, 0xb3, 0x49, 0xaf, 0xf1, 0x32, 0x3c, 0x16, 0x46, 0xc7, 0xb2, 0xef, 0xf4, 0x5d, 0x42, 0x11, 0x36, 0x29, 0x68, 0x92, 0x44, 0xb8, 0x1a, 0x14, 0xa0, 0x25, 0x94, 0x71, 0xdf, 0xa5, 0xbd, 0xa2, 0x30, 0xa8, 0xe5, 0xaf, 0x6b, 0x46, 0x62, 0xff, 0xcd, 0x34, 0xe6, 0x09, 0x4c, 0x96, 0x06, 0x5d, 0xb2, 0xb4, 0xcb, 0xc0, 0x54, 0x61, 0x56, 0x8f, 0x8e, 0xef, 0x59, 0x0f, 0x8e, 0xc2, 0x62, 0x83, 0x01, 0x50, 0x2f, 0x16, 0x6d, 0xe8, 0x6e, 0xda, 0xd6, 0x7b, 0x9d, 0xf6, 0xca, 0x30, 0x10, 0x59, 0xc7, 0x06, 0x92, 0x9d, 0xdd, 0x98, 0xd3, 0x07, 0x06, 0x3d, 0x35, 0xba, 0xe6, 0x4e, 0xf1, 0x49, 0x4f, 0x11, 0x4a, 0x75, 0x23, 0x5b, 0xc2, 0xec, 0x0c, 0x43, 0xd4, 0x9d, 0x3b, 0xfc, 0xc8, 0xc9, 0x75, 0x77, 0xee, 0x96, 0x0a, 0x52, 0xbe, 0xa5, 0x76, 0xde, 0x8e, 0x40, 0x85, 0x1d, 0x32, 0x3a, 0xe8, 0x75, 0xd1, 0x1d, 0x2b, 0x65, 0xfd, 0x40, 0xbe, 0x7d, 0x5b, 0x25, 0x95, 0xdf, 0x60, 0xde, 0xa9, 0x70, 0x5d, 0x53, 0x2d, 0xe0, 0xa1, 0x6d, 0xdb, 0xe5, 0xd5, 0xd8, 0x77, 0x19, 0xeb, 0x4e, 0xa3, 0x32, 0x82, 0x25, 0x5b, 0xe4, 0xfa, 0x90, 0x16, 0x6e, 0xfa, 0x0d, 0x77, 0xa7, 0xee, 0xf4, 0xf6, 0x50, 0xe7, 0xdb, 0x46, 0x6e, 0xe0, 0x7b, 0x37, 0xe5, 0xf6, 0xee, 0x81, 0x0b, 0x90, 0x39, 0x4f, 0x0e, 0x1a, 0x1f, 0xb5, 0x4d, 0x80, 0x7c, 0x31, 0xbd, 0x86, 0x5c, 0x30, 0x50, 0x38, 0x93, 0x18, 0x78, 0x5d, 0xbb, 0x23, 0x4b, 0x60, 0x8b, 0x42, 0x69, 0x7e, 0xfd, 0xf4, 0xaa, 0xe2, 0x9a, 0xb6, 0xe1, 0x28, 0x83, 0x37, 0x1b, 0x62, 0x17, 0x2f, 0x9b, 0xc5, 0xa1, 0x9d, 0x0b, 0xea, 0x0e, 0x9e, 0x68, 0x8b, 0xa9, 0x04, 0xf8, 0x5c, 0x21, 0x94, 0xad, 0x0b, 0x94, 0xc0, 0x43, 0x92, 0x7d, 0xd0, 0xc2, 0x09, 0x36, 0x47, 0x59, 0x4f, 0x85, 0x70, 0xba, 0x03, 0x91, 0xd0, 0x25, 0xb6, 0xf5, 0xc7, 0xd2, 0xf5, 0x38, 0x67, 0x5a, 0x26, 0xdd, 0xcb, 0xff, 0x7b, 0xac, 0xe0, 0x26, 0x13, 0xfa, 0x2d, 0xb9, 0x05, 0x86, 0xa9, 0xf6, 0xc4, 0xb8, 0x8f, 0x5d, 0x94, 0xe0, 0x51, 0xfe, 0x38, 0x6b, 0x71, 0x26, 0x3f, 0xa4, 0x93, 0x6f, 0x6d, 0xf4, 0xd8, 0x53, 0xdd, 0x08, 0xb2, 0x51, 0x7f, 0x30, 0xab, 0x46, 0x4d, 0xaa, 0x15, 0xa0, 0xba, 0xed, 0x38, 0x90, 0xb9, 0x28, 0x62, 0x2f, 0xfd, 0xae, 0xf6, 0xa1, 0x1d, 0x82, 0xfa, 0xc2, 0x50, 0x8a, 0xfe, 0xf1, 0x82, 0xaf, 0x58, 0x3e, 0xec, 0x78, 0x94, 0x54, 0x2d, 0xaa, 0x8e, 0x5f, 0xe0, 0x11, 0x41, 0xd5, 0xcf, 0x25, 0x0b, 0x37, 0x4d, 0xc0, 0x1f, 0xf0, 0x98, 0x55, 0x3e, 0x6c, 0x75, 0xd7, 0xd1, 0x60, 0xe7, 0x03, 0x03, 0x4d, 0x48, 0x5b, 0x30, 0x75, 0xb3, 0x95, 0x0b, 0xa2, 0x2f, 0x34, 0xe6, 0x23, 0xdc, 0x04, 0x36, 0x5e, 0x32, 0x5b, 0x25, 0x49, 0xe1, 0x26, 0x11, 0xbf, 0x5c, 0x27, 0xba, 0xa7, 0x1c, 0x11, 0xbb, 0xcc, 0x0b, 0x83, 0xb3, 0x46, 0x1d, 0x7b, 0xbc, 0x51, 0x11, 0x45, 0xc4, 0xbd, 0x85, 0x2a, 0xda, 0x0a, 0x86, 0xb2, 0x7b, 0x61, 0x6b, 0x3f, 0x5e, 0x6b, 0xcf, 0x77, 0x48, 0x4f, 0x59, 0xf0, 0x2f, 0x10, 0x53, 0xeb, 0x52, 0x98, 0x4d, 0xf5, 0x8f, 0xee, 0xb5, 0x97, 0xaa, 0xe7, 0xdc, 0xa5, 0x92, 0xfb, 0xd8, 0xec, 0x3b, 0x23, 0xd1, 0xbf, 0x9a, 0x99, 0xc3, 0x07, 0x56, 0xc1, 0x68, 0x99, 0x8f, 0xc6, 0xbc, 0x39, 0xf2, 0x3e, 0x20, 0xd1, 0xa3, 0xa5, 0xc5, 0x1c, 0xe6, 0x4d, 0x73, 0x83, 0x8a, 0x86, 0xbd, 0xde, 0x63, 0xdd, 0xe4, 0x78, 0x99, 0xcc, 0x8a, 0x24, 0x4b, 0x08, 0x74, 0x22, 0x11, 0x14, 0xd3, 0xfa, 0x3a, 0x90, 0xd4, 0xd6, 0xe1, 0x43, 0x2c, 0xc4, 0xfa, 0x43, 0x2e, 0x42, 0x79, 0x48, 0xb2, 0x52, 0x48, 0x76, 0x06, 0x93, 0xc1, 0x92, 0x76, 0x7a, 0xb8, 0xa8, 0x35, 0x5b, 0xb6, 0x63, 0x5d, 0x74, 0x3e, 0xb6, 0x10, 0xa1, 0x4a, 0xf7, 0x3c, 0xb1, 0x67, 0x35, 0x2a, 0x62, 0xbd, 0xd6, 0x44, 0x11, 0x0d, 0x25, 0xf5, 0xe1, 0xd2, 0xd6, 0x98, 0xfb, 0xc0, 0xc7, 0x5b, 0x0a, 0xae, 0x2d, 0x1d, 0x4e, 0x5c, 0xcf, 0x82, 0x8e, 0xd7, 0x54, 0x85, 0x93, 0xb9, 0xbe, 0x09, 0x61, 0xa9, 0x51, 0x74, 0xc8, 0xb5, 0x0f, 0xa6, 0xb2, 0x23, 0x3f, 0x5e, 0x06, 0xa4, 0x36, 0x95, 0xaa, 0xd7, 0xfa, 0x05, 0x8d, 0x32, 0x30, 0x6b, 0xae, 0x97, 0x0a, 0xf5, 0x51, 0x4b, 0x88, 0x61, 0x29, 0x81, 0xee, 0xc9, 0xde, 0xe0, 0x46, 0x19, 0x2d, 0xe8, 0xc6, 0x88, 0x0c, 0x01, 0x5c, 0xf8, 0x8c, 0xf6, 0x66, 0xa0, 0x21, 0x5b, 0x65, 0x79, 0x46, 0x7f, 0xb3, 0x85, 0x8d, 0x51, 0xd8, 0xfb, 0x94, 0xcc, 0x0b, 0x94, 0x79, 0x29, 0xcc, 0x07, 0x6b, 0xb0, 0x2e, 0x9f, 0x3b, 0x81, 0xab, 0x62, 0x0b, 0x3c, 0x2e, 0x09, 0x46, 0x6a, 0x22, 0x95, 0x04, 0x1c, 0xd1, 0x9e, 0x6c, 0x59, 0xe1, 0x0d, 0xf4, 0xc0, 0x9c, 0x58, 0x52, 0xa2, 0xf1, 0x68, 0x30, 0xe1, 0x8e, 0x4b, 0x4c, 0x3c, 0xbc, 0x0e, 0xb1, 0x5a, 0x54, 0x97, 0xef, 0x0c, 0x69, 0x6a, 0x7b, 0xbc, 0x2b, 0x02, 0xc6, 0x84, 0xfa, 0x0a, 0x92, 0xe7, 0xea, 0x11, 0x89, 0x2f, 0x16, 0xf4, 0x0b, 0xfc, 0x7d, 0xc0, 0x21, 0x7f, 0x10, 0xb7, 0x98, 0x3d, 0x50, 0x51, 0x4e, 0xcb, 0x4f, 0x06, 0x85, 0x1b, 0xda, 0xdb, 0x39, 0x15, 0x8a, 0x86, 0xe5, 0xe9, 0xa7, 0xc9, 0x52, 0xde, 0x56, 0xca, 0x87, 0x1d, 0xb1, 0x92, 0x14, 0x2a, 0x64, 0x3e, 0x3a, 0x44, 0x4e, 0x48, 0x5d, 0x1f, 0x8a, 0x26, 0x92, 0xd3, 0xf5, 0xbc, 0x0d, 0x33, 0x0c, 0x94, 0xe8, 0x47, 0x62, 0x8c, 0x86, 0xaa, 0x50, 0x5d, 0x5b, 0xb8, 0x37, 0xc0, 0x21, 0x8f, 0x10, 0xba, 0x0a, 0xd1, 0xb4, 0x33, 0xa3, 0x6b, 0xe8, 0xe3, 0x29, 0x2e, 0xfd, 0x4a, 0xd4, 0xfb, 0xa5, 0x06, 0x55, 0x3a, 0xe4, 0xba, 0x69, 0x61, 0x80, 0x5d, 0x43, 0x92, 0xb5, 0xd9, 0xeb, 0x40, 0x50, 0x4c, 0xd5, 0x74, 0x2e, 0xfa, 0x88, 0xe4, 0xf1, 0xf3, 0x36, 0xb1, 0x19, 0xf7, 0xd7, 0xba, 0x6a, 0x11, 0xc3, 0x84, 0x28, 0xc2, 0xa7, 0xda, 0x6e, 0x0b, 0xad, 0x0e, 0x8b, 0xe5, 0x32, 0xe8, 0xee, 0x77, 0x3d, 0xfe, 0xc5, 0x25, 0x76, 0xb3, 0x1a, 0x08, 0xa9, 0xf6, 0x01, 0x5d, 0x3f, 0xdb, 0xd1, 0x25, 0x59, 0xb9, 0x3f, 0x54, 0x88, 0x29, 0x42, 0xd9, 0xfd, 0xa6, 0x89, 0x01, 0x16, 0x1b, 0xbe, 0x72, 0xb5, 0x41, 0x00, 0x44, 0x15, 0xd9, 0xd0, 0xca, 0x5c, 0x50, 0xbb, 0x45, 0x76, 0x4d, 0xa3, 0x28, 0x2e, 0x76, 0x7c, 0x4d, 0xef, 0xfc, 0x95, 0x21, 0x19, 0x45, 0x77, 0xfe, 0xe6, 0x51, 0xc3, 0xad, 0xbf, 0x37, 0x41, 0xf0, 0xb6, 0x65, 0x96, 0x8b, 0xa9, 0x72, 0x64, 0x57, 0xc1, 0xcc, 0x43, 0xd5, 0x1a, 0xff, 0xcf, 0x8c, 0x03, 0x30, 0xd8, 0x92, 0x18, 0xa2, 0xf0, 0x74, 0xab, 0xb0, 0xa4, 0xf2, 0xab, 0x73, 0x66, 0x85, 0x4a, 0x07, 0x4b, 0xcb, 0x7f, 0xb2, 0x19, 0x3a, 0xa0, 0xc8, 0x89, 0x4c, 0x1f, 0x57, 0x15, 0x3a, 0x1d, 0x9d, 0xca, 0x39, 0x19, 0xe7, 0x2a, 0xf6, 0x03, 0x33, 0x41, 0x5d, 0x94, 0xf5, 0xc2, 0x40, 0xdf, 0xf0, 0x20, 0xd1, 0x68, 0x25, 0xfa, 0x4d, 0x50, 0xdc, 0x00, 0x30, 0x93, 0xa1, 0xc6, 0xc9, 0x17, 0xd5, 0x8a, 0xb7, 0xb5, 0x34, 0xb7, 0xaf, 0xad, 0x92, 0x7f, 0xb6, 0x30, 0x37, 0x7d, 0xc8, 0x22, 0x26, 0x56, 0x63, 0xe0, 0xbe, 0x23, 0x23, 0x81, 0xeb, 0xe7, 0xe4, 0x1a, 0x06, 0x1a, 0x12, 0x7e, 0x6a, 0xb6, 0xab, 0x27, 0xd6, 0xff, 0x81, 0xa7, 0x91, 0x68, 0x3d, 0x7d, 0x82, 0xce, 0xf5, 0xc0, 0x58, 0x2c, 0x3d, 0xd0, 0xc8, 0x9e, 0x19, 0x91, 0x13, 0x8a, 0xf7, 0x0e, 0xab, 0xc3, 0x0f, 0x92, 0xe8, 0x56, 0xed, 0x64, 0xbf, 0x84, 0x99, 0xd7, 0xdb, 0xbc, 0xc8, 0x99, 0xad, 0x6e, 0xcc, 0xd5, 0xc3, 0xe4, 0x44, 0xb5, 0x03, 0x1f }; +constexpr AccessUnit AC3_LARGE_AU_EXPECTED_AU = { 0x15f90, 0x159b2, false, 0, {}, { 0x15, 0x52, 0x08, 0x0e, 0x4a, 0x8b, 0xd1, 0xa1, 0xfe, 0x30, 0xc1, 0x4b, 0xc9, 0x96, 0x59, 0xc4, 0x6c, 0x6b, 0x42, 0xed } }; + +const std::vector LPCM_LARGE_AU_STREAM = { 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xbd, 0x06, 0xe6, 0x81, 0xc1, 0x0d, 0x31, 0x00, 0x05, 0xbf, 0x21, 0x11, 0x00, 0x05, 0xb3, 0x65, 0x1e, 0x69, 0xb2, 0x40, 0x00, 0x00, 0x00, 0xfb, 0xba, 0x2b, 0xca, 0x88, 0x65, 0x2b, 0x01, 0xf4, 0xe6, 0xfc, 0x43, 0xc2, 0xad, 0x45, 0xe3, 0xf1, 0x0b, 0x86, 0x17, 0x75, 0x98, 0x11, 0x62, 0xb4, 0xd9, 0xb5, 0x6c, 0x1e, 0xac, 0xf0, 0xaa, 0xf6, 0xc4, 0x4a, 0xcc, 0x5d, 0xb3, 0x3d, 0xd3, 0x40, 0x11, 0xbc, 0x73, 0x09, 0x49, 0x80, 0xe4, 0xef, 0x95, 0xb2, 0xc8, 0xb4, 0x48, 0x20, 0xe2, 0x49, 0x07, 0x94, 0x7c, 0xe7, 0xab, 0x73, 0x0b, 0xa9, 0x97, 0xbd, 0x8b, 0xf3, 0x90, 0x3c, 0x12, 0x29, 0xec, 0xe8, 0x5a, 0x8a, 0xbb, 0x35, 0x60, 0xf5, 0x6c, 0xaa, 0x93, 0xf1, 0x3c, 0x86, 0x8b, 0x63, 0x11, 0xa8, 0x22, 0x32, 0x90, 0x4a, 0x57, 0xa0, 0x91, 0xbf, 0x95, 0x45, 0xef, 0x98, 0xa1, 0x11, 0xf7, 0x59, 0x05, 0xc2, 0x0f, 0x13, 0x86, 0x27, 0xd4, 0x28, 0x21, 0x27, 0x74, 0x31, 0xdb, 0xe6, 0xf9, 0xa5, 0xbd, 0xe1, 0x19, 0x79, 0x9f, 0xc6, 0xd4, 0x49, 0x14, 0x06, 0x59, 0x03, 0x0f, 0x07, 0x16, 0x93, 0x95, 0x2e, 0xae, 0x82, 0x99, 0xbb, 0x86, 0x36, 0xda, 0x6e, 0xf2, 0x3e, 0x77, 0xa9, 0x74, 0x79, 0x92, 0x0c, 0x28, 0x24, 0x4a, 0x1f, 0x0e, 0x16, 0xf8, 0xdf, 0xa9, 0x4f, 0x67, 0xb8, 0xe1, 0xfa, 0x83, 0x42, 0x3a, 0x38, 0x2e, 0x12, 0xb3, 0x10, 0x54, 0x59, 0x0c, 0xdb, 0xa1, 0xe8, 0x64, 0x0d, 0x87, 0x6b, 0xac, 0xd1, 0x2c, 0x90, 0x15, 0xd6, 0xed, 0x5e, 0x78, 0x94, 0x05, 0x2d, 0x15, 0xb0, 0xf0, 0xbd, 0xd6, 0x02, 0xa1, 0xf7, 0xf2, 0x2a, 0xf1, 0x1a, 0xe7, 0xf0, 0x3c, 0x36, 0xd9, 0x24, 0xb6, 0x98, 0x4e, 0xda, 0x73, 0x39, 0x33, 0xda, 0x5c, 0xb1, 0x4e, 0x4c, 0xca, 0x01, 0xa2, 0x96, 0x13, 0x9f, 0x8a, 0x87, 0xdb, 0x3f, 0x09, 0x14, 0x6b, 0x2c, 0x99, 0x55, 0x37, 0xe4, 0xe5, 0x08, 0x61, 0xf5, 0x4e, 0xb2, 0x0a, 0x3e, 0xbd, 0xb8, 0x52, 0xdf, 0xea, 0x8b, 0xee, 0x49, 0x98, 0x7d, 0x94, 0x95, 0x2c, 0x1c, 0x29, 0x67, 0xb5, 0xa2, 0x38, 0x06, 0x91, 0x25, 0x22, 0xd3, 0x3c, 0xd6, 0xd0, 0x7d, 0x2f, 0xd1, 0x03, 0x2a, 0xec, 0xea, 0xa9, 0xfa, 0xab, 0x70, 0x49, 0xf4, 0xde, 0x5d, 0xfd, 0xda, 0x7f, 0xf7, 0xf1, 0xfc, 0x56, 0x52, 0x1e, 0x85, 0x1c, 0x9f, 0xaa, 0xbd, 0x6f, 0x3d, 0xda, 0x46, 0xe2, 0x58, 0x80, 0xe1, 0x3d, 0xae, 0xed, 0x51, 0xf8, 0x1c, 0x65, 0x71, 0x9b, 0xf0, 0x04, 0x31, 0xdd, 0xb8, 0x4b, 0x15, 0x29, 0xf5, 0xaa, 0x82, 0x11, 0x26, 0x1c, 0xaf, 0xb7, 0x47, 0xa0, 0x72, 0x26, 0x48, 0x73, 0x7e, 0xa2, 0xaa, 0x0b, 0x9f, 0x86, 0x44, 0xa5, 0xfd, 0xfa, 0xb5, 0x58, 0x21, 0x1b, 0x46, 0x4b, 0x46, 0xd7, 0x6b, 0xc8, 0xcd, 0xc3, 0x08, 0x60, 0x6d, 0xc8, 0x65, 0xd7, 0xa5, 0x67, 0x63, 0xf9, 0x07, 0x8b, 0x68, 0x16, 0xce, 0x35, 0x37, 0xe3, 0x71, 0xb7, 0xb1, 0x5f, 0x73, 0x3b, 0xba, 0xe3, 0xd6, 0x38, 0x2b, 0x35, 0x77, 0x06, 0x11, 0x2e, 0x63, 0xf2, 0xdc, 0x26, 0x34, 0x8d, 0x86, 0x81, 0x05, 0x70, 0xd3, 0x0a, 0x65, 0xec, 0x7a, 0xf4, 0x6a, 0xcc, 0x36, 0x93, 0x19, 0xe4, 0x40, 0xd7, 0x2c, 0x33, 0x8e, 0xab, 0xc0, 0x19, 0x2c, 0xd5, 0x60, 0x7f, 0x5e, 0x99, 0x82, 0x09, 0x23, 0x08, 0xe0, 0x2c, 0x50, 0x5d, 0x88, 0xd7, 0x7f, 0x13, 0xdc, 0xb3, 0x0f, 0xfb, 0x99, 0x4b, 0x75, 0xfb, 0x40, 0xa0, 0x8b, 0x13, 0xbc, 0x74, 0x03, 0xe4, 0x36, 0x18, 0x28, 0x50, 0x26, 0xfa, 0x94, 0x3d, 0xa6, 0x41, 0x6c, 0xff, 0xd1, 0x14, 0x35, 0x81, 0xe8, 0x9c, 0x6d, 0x15, 0xea, 0xc2, 0xef, 0x61, 0x80, 0x56, 0x97, 0xd9, 0xec, 0x66, 0x3d, 0xf8, 0x6f, 0x74, 0xb0, 0x18, 0x50, 0x9d, 0x12, 0x4a, 0x96, 0xdc, 0x86, 0xf7, 0x2c, 0xa1, 0x8a, 0x43, 0x03, 0x3b, 0xe8, 0x4e, 0xd9, 0x43, 0x2e, 0x46, 0xa5, 0xa9, 0xce, 0x92, 0x38, 0x12, 0xab, 0xe1, 0x47, 0x18, 0x8e, 0x26, 0x44, 0x17, 0x7a, 0xe9, 0xd0, 0x58, 0xd7, 0x6a, 0xc4, 0xc5, 0x00, 0x04, 0x24, 0x47, 0xb5, 0xaa, 0x61, 0x2b, 0x9d, 0x41, 0xbd, 0x97, 0x63, 0x03, 0x3c, 0x55, 0x85, 0x15, 0x2d, 0x3f, 0xb8, 0x68, 0x3f, 0xb9, 0x80, 0x57, 0x59, 0xcf, 0x50, 0xb1, 0x53, 0xda, 0x5e, 0xfb, 0xff, 0xde, 0x85, 0x1e, 0xaf, 0x1c, 0x95, 0x87, 0xe1, 0xbd, 0xe2, 0x10, 0x42, 0xb4, 0x44, 0x42, 0xf3, 0x5a, 0xbf, 0x16, 0xd9, 0xbf, 0x45, 0x36, 0x8e, 0x00, 0xd7, 0xaf, 0x72, 0xb3, 0x85, 0xf7, 0x98, 0xbf, 0x3d, 0xb0, 0x20, 0xc3, 0x92, 0xb6, 0x2e, 0xda, 0x71, 0x0c, 0x6e, 0xdd, 0x05, 0x74, 0x30, 0xbe, 0xd7, 0x35, 0x66, 0x07, 0xcc, 0x43, 0x75, 0xc8, 0xbe, 0xce, 0x66, 0x1e, 0x36, 0xcd, 0x1f, 0xe8, 0x63, 0x7e, 0x0b, 0x9c, 0x86, 0x85, 0xdc, 0xfd, 0xd4, 0x71, 0xb1, 0x0f, 0xe8, 0x69, 0xd8, 0x91, 0xa9, 0xc4, 0x26, 0xde, 0x57, 0xd7, 0xcd, 0x35, 0xd8, 0x40, 0xb8, 0x79, 0xfa, 0x33, 0xb0, 0x4c, 0xb2, 0xe2, 0x76, 0x21, 0x75, 0x72, 0x08, 0xf4, 0x45, 0x3d, 0x0b, 0xaa, 0x98, 0x0c, 0x5a, 0x72, 0x15, 0x17, 0x49, 0xf0, 0xcc, 0x33, 0x0d, 0x55, 0x04, 0x58, 0x17, 0x1a, 0x5c, 0x52, 0xb6, 0x5d, 0x22, 0xaa, 0x73, 0x24, 0xe5, 0x3b, 0x3e, 0xa4, 0x6a, 0xcc, 0xc9, 0x23, 0x6d, 0xc6, 0x9b, 0xc6, 0x5c, 0xe8, 0x6e, 0x7c, 0x0a, 0xa1, 0xa0, 0xb8, 0x05, 0x17, 0xb1, 0x18, 0xb8, 0x27, 0x38, 0x7e, 0xff, 0x89, 0x73, 0x6e, 0x79, 0x7d, 0xf9, 0x1e, 0x35, 0xb3, 0x2f, 0x9b, 0x85, 0xda, 0xd0, 0xbc, 0xb2, 0xd2, 0x2c, 0x56, 0x99, 0x12, 0xba, 0x62, 0xbc, 0x62, 0xc9, 0xaf, 0x3c, 0x62, 0x53, 0xf3, 0xb6, 0x64, 0xa1, 0xd8, 0x43, 0xda, 0x97, 0xe7, 0x68, 0xb0, 0x2f, 0xba, 0x8a, 0x0f, 0x09, 0x13, 0xbf, 0x6a, 0xe2, 0x92, 0x04, 0xf5, 0xb3, 0xd3, 0x3b, 0xfa, 0x28, 0xb8, 0x76, 0x55, 0x7a, 0xe8, 0x0a, 0xa5, 0x41, 0x62, 0xfe, 0xf3, 0xd9, 0x50, 0x68, 0xc7, 0xb2, 0x6d, 0xde, 0xc7, 0x77, 0x1e, 0x7e, 0x50, 0x79, 0xc0, 0xf2, 0xd2, 0x83, 0x8b, 0x0d, 0x9e, 0xce, 0xaf, 0x9b, 0x33, 0x20, 0xd9, 0x8b, 0xf5, 0xf1, 0x3c, 0x92, 0xb7, 0x5d, 0x93, 0x38, 0xda, 0xd4, 0x84, 0xe6, 0xbe, 0xcd, 0x65, 0x14, 0x94, 0x60, 0xae, 0x26, 0x6b, 0x1d, 0x15, 0x99, 0xf3, 0x56, 0xac, 0x20, 0x5e, 0x0a, 0x2e, 0x90, 0x5e, 0x69, 0x6a, 0xb2, 0xf0, 0xe2, 0xf2, 0x96, 0xfe, 0x61, 0xcd, 0xe8, 0x44, 0x52, 0x0a, 0x5d, 0x2a, 0x3d, 0x4e, 0x45, 0xc5, 0xef, 0x95, 0x55, 0x59, 0xe1, 0x7f, 0x9e, 0x43, 0x05, 0x7c, 0x09, 0xd5, 0xd8, 0x32, 0x9a, 0x41, 0x40, 0xa5, 0x22, 0x3a, 0xf9, 0x28, 0x85, 0x5c, 0x94, 0x89, 0x63, 0xbf, 0x81, 0x06, 0xa9, 0x6f, 0x63, 0x66, 0x2d, 0x9d, 0x66, 0x87, 0xfb, 0x6f, 0xdc, 0x0d, 0x75, 0x76, 0x61, 0x16, 0xd1, 0xda, 0xfa, 0x65, 0xe1, 0x3d, 0x32, 0xea, 0x01, 0x11, 0x71, 0x38, 0x20, 0x5a, 0x27, 0x3b, 0x6c, 0x9d, 0xb2, 0xda, 0xb0, 0x7b, 0xef, 0x26, 0x6a, 0x96, 0x86, 0x62, 0x80, 0x6f, 0x59, 0xcb, 0xc2, 0x79, 0x49, 0x24, 0x95, 0x8f, 0xd0, 0x4a, 0x65, 0x94, 0x0f, 0xbf, 0x9f, 0x9b, 0xc7, 0x1f, 0x7b, 0x46, 0x56, 0x29, 0x21, 0xa9, 0xdf, 0x01, 0xba, 0x89, 0x3d, 0x24, 0xef, 0x6f, 0x4b, 0x24, 0x6f, 0x4c, 0x74, 0xe7, 0x40, 0x0c, 0xde, 0x60, 0xbf, 0xe2, 0x86, 0x78, 0x26, 0xe6, 0xd6, 0xd3, 0x27, 0x10, 0x57, 0xd9, 0xb8, 0x09, 0x85, 0x3f, 0x28, 0xdf, 0x36, 0xba, 0x4d, 0x4f, 0xc3, 0xa3, 0x65, 0x81, 0x6d, 0xdf, 0x94, 0xc9, 0x90, 0xce, 0x65, 0xc2, 0x7e, 0x42, 0xc9, 0x4c, 0x11, 0x53, 0x45, 0xa7, 0x95, 0x97, 0x7a, 0x2d, 0xc5, 0x79, 0xee, 0x61, 0x0e, 0x5c, 0xe9, 0x9c, 0xfc, 0xb4, 0xba, 0x19, 0x7f, 0x64, 0x60, 0xac, 0x94, 0x6e, 0xc7, 0xc1, 0x5c, 0x3f, 0x9e, 0xac, 0xfb, 0x78, 0x52, 0xc8, 0x8a, 0x91, 0x02, 0x5c, 0x3c, 0xf7, 0x45, 0xe0, 0x14, 0x94, 0x2f, 0x8a, 0x02, 0x43, 0x83, 0x03, 0x67, 0x82, 0x5b, 0xc6, 0xc7, 0xe0, 0x0a, 0xe2, 0x06, 0x90, 0x1f, 0x80, 0xdc, 0x12, 0x52, 0xc7, 0x1d, 0x6a, 0x2a, 0xcd, 0x71, 0x85, 0xb1, 0x51, 0x9a, 0xa1, 0x2e, 0xc6, 0x07, 0x88, 0xa3, 0x3a, 0xd5, 0xdd, 0x8f, 0x55, 0xbd, 0xe4, 0x63, 0xd1, 0x95, 0x98, 0x4b, 0xe6, 0xea, 0x8f, 0x70, 0x0e, 0x67, 0x91, 0x74, 0xd6, 0x79, 0x9c, 0x17, 0xfd, 0xef, 0xf2, 0x8b, 0xa6, 0xf6, 0x26, 0xdf, 0x0e, 0x5c, 0xc2, 0x5d, 0x1d, 0x9c, 0x4d, 0xe5, 0xb2, 0xf7, 0xb4, 0xb5, 0x63, 0x15, 0x4b, 0x16, 0x3f, 0x21, 0x77, 0xe1, 0x8b, 0x1a, 0x92, 0x0d, 0x02, 0x39, 0x9b, 0xdf, 0x74, 0x79, 0x73, 0x08, 0x78, 0x69, 0x6d, 0xcb, 0x8d, 0xc2, 0x57, 0x85, 0xed, 0x2a, 0x54, 0xeb, 0x75, 0x14, 0xfe, 0x16, 0xc8, 0x4a, 0x72, 0xa2, 0x58, 0x01, 0xd9, 0x2c, 0xbb, 0x9e, 0x42, 0x8f, 0xf6, 0x1d, 0x6c, 0x50, 0x7c, 0x78, 0x69, 0x15, 0x57, 0x05, 0x6a, 0x55, 0x04, 0x66, 0x31, 0xf2, 0x2e, 0x96, 0x28, 0x59, 0x86, 0xbd, 0xcf, 0x83, 0x69, 0xc8, 0x76, 0xe7, 0xf3, 0x61, 0xac, 0x1a, 0x02, 0x7a, 0xf3, 0x2e, 0x8a, 0x65, 0x99, 0x6a, 0x06, 0xc0, 0xca, 0x3d, 0x28, 0x83, 0x66, 0xde, 0x2b, 0xf4, 0xfa, 0x78, 0xa0, 0x3b, 0xa8, 0x6c, 0x75, 0x22, 0x51, 0xd4, 0x0e, 0xcb, 0x3e, 0x88, 0x65, 0x02, 0x9e, 0xde, 0xb1, 0x2a, 0x46, 0x00, 0xc0, 0x50, 0x57, 0x67, 0xdf, 0x8d, 0xa5, 0x78, 0x68, 0xbb, 0x6f, 0x8d, 0x41, 0xb6, 0x37, 0x6d, 0x4e, 0x1a, 0x78, 0x71, 0x3b, 0x72, 0xe9, 0x04, 0x84, 0x8b, 0x84, 0xc9, 0x79, 0xce, 0x83, 0xaa, 0x2b, 0xeb, 0x2c, 0x61, 0xa2, 0x8a, 0xc8, 0x91, 0xe4, 0x77, 0x9b, 0x89, 0x4a, 0x46, 0x34, 0x39, 0x74, 0xdb, 0xe4, 0x29, 0x8f, 0x94, 0xf1, 0x2f, 0xf6, 0x58, 0x0d, 0x3f, 0x4f, 0x4e, 0x99, 0x59, 0xda, 0x14, 0x4c, 0x8f, 0xd6, 0x80, 0x7b, 0x6f, 0xb4, 0x71, 0x52, 0xaf, 0x2a, 0x9e, 0xe5, 0x61, 0x75, 0xec, 0x45, 0x21, 0x45, 0x27, 0x72, 0x0b, 0xa3, 0xe2, 0xf0, 0x02, 0xd7, 0xd6, 0xf3, 0xc9, 0xe1, 0x6b, 0xb1, 0xbd, 0x33, 0xda, 0x38, 0xa9, 0x69, 0x4e, 0x27, 0x9d, 0x1c, 0xf4, 0x77, 0x47, 0xc5, 0xa2, 0x31, 0x3d, 0x46, 0xbe, 0x21, 0xd3, 0xdb, 0x41, 0xbe, 0x09, 0x94, 0x2a, 0x6e, 0xfe, 0x7a, 0x21, 0xaa, 0x00, 0x0b, 0x5a, 0xa6, 0x3c, 0xd6, 0x5a, 0xb0, 0xe4, 0x3e, 0x74, 0x5d, 0x82, 0x15, 0x0a, 0x83, 0x58, 0x08, 0x03, 0xb4, 0x32, 0x44, 0x4c, 0xb3, 0x2b, 0xd8, 0x28, 0x3a, 0x6c, 0xca, 0x4d, 0xa9, 0xec, 0x8b, 0x87, 0x0b, 0x1b, 0xd4, 0x17, 0x24, 0x4e, 0xf5, 0x05, 0xd8, 0x37, 0xa7, 0x60, 0xee, 0x8a, 0x17, 0xa8, 0x7b, 0x1e, 0xd2, 0x79, 0xe1, 0x91, 0x39, 0xab, 0x96, 0x5c, 0x63, 0xcc, 0x1c, 0xc9, 0x54, 0xdd, 0xdb, 0xbd, 0x36, 0xec, 0x95, 0x87, 0x4b, 0xb8, 0x43, 0xfe, 0x0f, 0x16, 0xcd, 0x36, 0x55, 0x7c, 0x64, 0xd8, 0x69, 0x88, 0x31, 0x79, 0xc0, 0x53, 0xe5, 0x93, 0x5c, 0x94, 0x66, 0x87, 0xb2, 0x63, 0x39, 0x66, 0x7e, 0x79, 0x3a, 0x0e, 0xbe, 0x66, 0xdb, 0xac, 0x0a, 0xbe, 0xdb, 0x28, 0x69, 0xd9, 0x8e, 0x5c, 0x39, 0xea, 0x6f, 0xec, 0x83, 0x72, 0xee, 0xd7, 0x66, 0x82, 0xce, 0xa4, 0x4e, 0x25, 0x26, 0xbc, 0x8c, 0x4c, 0x19, 0x69, 0x0c, 0x35, 0x39, 0x42, 0x6d, 0xde, 0x7b, 0x23, 0x63, 0x82, 0x4f, 0xfd, 0x1a, 0x02, 0xbf, 0x38, 0x76, 0xc0, 0xb1, 0x4b, 0x85, 0x3f, 0xde, 0x99, 0x7b, 0x8d, 0x13, 0x76, 0x45, 0x77, 0x69, 0x2b, 0x6a, 0xf5, 0x3b, 0x5c, 0x55, 0xbb, 0x25, 0x9d, 0x02, 0xb1, 0xd8, 0xa7, 0xae, 0x89, 0xc6, 0x4d, 0x56, 0x82, 0xb4, 0x86, 0x01, 0x25, 0xc4, 0x25, 0x1e, 0xd4, 0xed, 0x99, 0xc4, 0x46, 0xba, 0xea, 0xb9, 0x6c, 0xa2, 0x49, 0xe4, 0x59, 0xf6, 0xfd, 0x4c, 0x24, 0xcb, 0xc5, 0x38, 0xc9, 0x11, 0xa1, 0x81, 0x1d, 0xae, 0xab, 0x28, 0x5d, 0x61, 0xda, 0xb9, 0x16, 0x5a, 0x9b, 0x9f, 0xda, 0x94, 0xa0, 0xb3, 0x5e, 0x65, 0x6a, 0xd6, 0x64, 0x68, 0x98, 0xb4, 0x4c, 0x82, 0xf0, 0x98, 0xeb, 0xf0, 0x05, 0xb8, 0xbf, 0x3f, 0x61, 0xb2, 0xe3, 0x99, 0x4a, 0x36, 0x52, 0x4b, 0x08, 0x7c, 0x47, 0x55, 0x1e, 0xfa, 0x9d, 0x5f, 0xbe, 0x77, 0xf9, 0x51, 0x81, 0x02, 0x0a, 0x9c, 0x4c, 0xd1, 0xdf, 0x3a, 0xcc, 0x13, 0x6c, 0x1b, 0xd1, 0xbb, 0xd9, 0x30, 0x09, 0x66, 0xb0, 0x2b, 0xdc, 0xe4, 0xcd, 0x0e, 0xb8, 0xf5, 0xf9, 0x2c, 0x0c, 0x7d, 0x26, 0xc0, 0xe4, 0xc1, 0x6f, 0x4f, 0x32, 0xe6, 0x60, 0xbf, 0x5e, 0xae, 0x0b, 0xb3, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x02, 0xe4, 0x61, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbd, 0x07, 0xec, 0x81, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0xfc, 0x48, 0xcd, 0xae, 0x7c, 0x9e, 0x15, 0x6f, 0x47, 0x49, 0x2b, 0x4d, 0x91, 0xaf, 0x65, 0x47, 0x4d, 0x69, 0x82, 0xc6, 0x41, 0xa3, 0xe8, 0x85, 0xb0, 0x66, 0x08, 0x86, 0xb8, 0x99, 0x25, 0x99, 0xa5, 0xb1, 0xdf, 0x6b, 0x6d, 0x6f, 0xd0, 0x08, 0xfe, 0x3d, 0xee, 0x78, 0xfc, 0xa8, 0xb5, 0x9a, 0x9b, 0xb8, 0x8e, 0x8e, 0x20, 0x89, 0x9a, 0x5c, 0x4e, 0x4f, 0x9e, 0x4f, 0x22, 0xc9, 0x77, 0xe9, 0xa7, 0x9c, 0x68, 0xaf, 0xe2, 0xcc, 0xf6, 0xa0, 0x3b, 0x71, 0x83, 0xdd, 0x64, 0xc4, 0xf2, 0x9a, 0x17, 0x98, 0x44, 0xc6, 0xa8, 0x9a, 0xe0, 0xcd, 0x0c, 0x64, 0xd8, 0x34, 0x90, 0x43, 0x16, 0x5a, 0x65, 0x25, 0x4d, 0x14, 0x1b, 0x53, 0x03, 0x24, 0x89, 0xf8, 0x00, 0x3b, 0xfe, 0xe8, 0x91, 0xf9, 0x4e, 0x4d, 0x8a, 0xb6, 0x4d, 0xb8, 0x81, 0xa9, 0x13, 0x53, 0x9f, 0x6a, 0xd3, 0xeb, 0xa2, 0x5c, 0x17, 0xcc, 0x7a, 0x53, 0xd5, 0xad, 0x44, 0x3a, 0xa5, 0xd7, 0x2e, 0x45, 0xe5, 0xff, 0x55, 0x79, 0xc8, 0x99, 0x2e, 0x4c, 0x6f, 0x70, 0xc8, 0xf1, 0x8b, 0x02, 0xe5, 0x19, 0x38, 0xcc, 0xb7, 0xe4, 0x12, 0xac, 0x53, 0x07, 0x93, 0xd0, 0x69, 0xd2, 0xb1, 0x5c, 0x79, 0x8f, 0xbc, 0xcb, 0x19, 0x2f, 0xe0, 0x11, 0xea, 0xb2, 0x6f, 0x0a, 0x0e, 0x53, 0x2d, 0xc1, 0x05, 0x09, 0x67, 0xd7, 0x58, 0xed, 0x1c, 0xf2, 0xc4, 0x20, 0x6d, 0x12, 0x75, 0x71, 0xc6, 0xeb, 0xe7, 0x51, 0x81, 0x08, 0x4a, 0x95, 0x24, 0x55, 0xd8, 0x7a, 0x26, 0x79, 0xe6, 0x76, 0x26, 0x63, 0x1c, 0x10, 0xeb, 0xab, 0xba, 0x2a, 0x92, 0x35, 0xc8, 0x0f, 0x2c, 0x2b, 0x6f, 0x76, 0x45, 0xf1, 0x30, 0x07, 0x11, 0xc1, 0x8c, 0xb2, 0xe4, 0x44, 0x81, 0x20, 0xaa, 0xab, 0xc4, 0xa6, 0x31, 0xe7, 0x6f, 0xd8, 0x1f, 0x92, 0x2b, 0x57, 0xe3, 0xbe, 0x66, 0xe0, 0xe1, 0xa2, 0x76, 0x13, 0xb0, 0x6d, 0xfa, 0x36, 0x9f, 0x6d, 0x35, 0x14, 0xd3, 0xf0, 0xc3, 0x94, 0x9e, 0x88, 0x52, 0x1d, 0x41, 0xff, 0xe1, 0xc3, 0xa7, 0xd7, 0xa8, 0x6e, 0x3c, 0xf5, 0xba, 0xc8, 0xca, 0x4c, 0x06, 0x0c, 0x26, 0xbc, 0x0e, 0xda, 0xc0, 0x3c, 0x49, 0x65, 0x09, 0x64, 0x0a, 0x1e, 0xaf, 0x35, 0x32, 0x03, 0x04, 0x7d, 0x85, 0xc3, 0xd5, 0x87, 0x22, 0x3a, 0x1f, 0xe0, 0xd2, 0x18, 0xfc, 0x5f, 0xc5, 0xa9, 0x1c, 0x6f, 0x6f, 0x54, 0x6c, 0x6b, 0xd5, 0x3f, 0xa7, 0x7a, 0x09, 0x22, 0xad, 0x88, 0x4a, 0xf1, 0x16, 0xae, 0x17, 0x38, 0x6d, 0x9a, 0x89, 0x4f, 0x6b, 0xb7, 0x23, 0x80, 0x4e, 0x1a, 0x53, 0x80, 0x25, 0xd9, 0xc8, 0x1b, 0xb5, 0xf3, 0x8a, 0xb7, 0x5f, 0x1e, 0x5f, 0xa7, 0x86, 0xf7, 0x1f, 0x43, 0x17, 0xfd, 0xb5, 0x49, 0x27, 0x91, 0x6f, 0xa9, 0x03, 0x2d, 0x94, 0x35, 0x9d, 0x64, 0x53, 0x2a, 0x44, 0xce, 0x4d, 0x47, 0x8e, 0x7a, 0xf9, 0x8e, 0x22, 0x19, 0xb4, 0xe8, 0x59, 0x54, 0x1b, 0xa5, 0x75, 0xda, 0xdc, 0xc0, 0x16, 0xf4, 0x45, 0x75, 0x83, 0xe7, 0x31, 0xc0, 0x3f, 0x1b, 0x50, 0x0f, 0xae, 0x33, 0x46, 0x29, 0xf2, 0x1d, 0xb2, 0xcf, 0xe8, 0xb0, 0x2d, 0x7e, 0x73, 0x3d, 0xfd, 0x7d, 0xdc, 0x85, 0x7a, 0x8f, 0x8d, 0xbc, 0x14, 0x60, 0xaf, 0xcf, 0x44, 0x48, 0x6f, 0xd3, 0x05, 0x5d, 0x37, 0x77, 0x81, 0xd5, 0x63, 0xb5, 0x31, 0x72, 0xc0, 0xd4, 0x3e, 0x79, 0x56, 0x9c, 0x2d, 0xb4, 0xe9, 0xed, 0xa6, 0x00, 0x87, 0x47, 0x26, 0xf9, 0x1c, 0x0b, 0xe1, 0xce, 0x0b, 0xaa, 0x20, 0x71, 0x6c, 0x80, 0x88, 0x65, 0x17, 0x9b, 0x06, 0x66, 0x25, 0xcc, 0x57, 0x55, 0x3d, 0x7c, 0x4a, 0x8a, 0xde, 0x6d, 0xe1, 0x53, 0x46, 0x8d, 0xd7, 0xaa, 0xb5, 0x7d, 0xd8, 0x4a, 0x85, 0xe0, 0x2a, 0x1d, 0x1c, 0xab, 0x72, 0x10, 0xd8, 0x83, 0x77, 0x36, 0xe9, 0xab, 0x7a, 0xe8, 0xc3, 0xd3, 0xf7, 0x9f, 0xb1, 0xc6, 0x36, 0x3b, 0x8c, 0x78, 0x80, 0x04, 0x4f, 0x29, 0x33, 0x77, 0x17, 0xa3, 0x68, 0xf4, 0x00, 0x37, 0xf1, 0x11, 0x20, 0x14, 0x61, 0x90, 0x70, 0xe7, 0xaf, 0xd4, 0x1b, 0xc4, 0x3d, 0x84, 0x47, 0x35, 0xfa, 0x11, 0xc1, 0x8a, 0xe6, 0x8c, 0x9b, 0x8b, 0x07, 0xbd, 0xd4, 0x8b, 0x99, 0x94, 0xeb, 0x85, 0x28, 0x90, 0x36, 0x8d, 0x4a, 0x86, 0xad, 0xbd, 0xf1, 0x33, 0x95, 0xd4, 0x99, 0xfa, 0xa2, 0x3f, 0x03, 0x56, 0xb5, 0x72, 0x30, 0xcb, 0x4d, 0x39, 0x91, 0x64, 0x47, 0xa9, 0xa8, 0xa3, 0x0a, 0x3f, 0x91, 0xac, 0xd7, 0xca, 0xaf, 0x7b, 0x46, 0x9d, 0x9d, 0xc3, 0xa3, 0x28, 0x23, 0x9f, 0x01, 0xae, 0xf8, 0x07, 0xec, 0x79, 0xa0, 0x4f, 0x97, 0x25, 0x85, 0xa3, 0x39, 0xae, 0x0e, 0x37, 0xc1, 0x32, 0x98, 0xae, 0xb5, 0xa2, 0x5a, 0x11, 0xa6, 0xd3, 0x38, 0x90, 0xda, 0x92, 0xc2, 0x2b, 0x7c, 0xd0, 0xd2, 0xf3, 0xe4, 0x23, 0x11, 0x9b, 0x7b, 0x0f, 0x61, 0xfa, 0xe3, 0x4b, 0x4c, 0xbb, 0x0a, 0x4c, 0x93, 0x60, 0x15, 0x51, 0x0d, 0x76, 0x41, 0x37, 0x39, 0x02, 0x21, 0x80, 0x3b, 0x04, 0xc5, 0x1b, 0xf0, 0x97, 0x2e, 0x17, 0x5f, 0xf4, 0xa0, 0x19, 0x55, 0xf3, 0x2f, 0xe8, 0x53, 0x07, 0xae, 0xdf, 0x98, 0xe4, 0xc3, 0xd0, 0xe9, 0x32, 0x0e, 0x34, 0x00, 0x3b, 0x7d, 0xe8, 0x1b, 0xb6, 0x9d, 0x60, 0x67, 0xff, 0x57, 0xa4, 0x04, 0x32, 0x14, 0x95, 0xe5, 0xa5, 0x06, 0xb0, 0xd4, 0x94, 0xb2, 0xc1, 0xe4, 0x5b, 0x14, 0x44, 0x7d, 0xee, 0x01, 0x81, 0xe2, 0x2d, 0xfb, 0x01, 0x39, 0x41, 0xdf, 0x6b, 0xd8, 0x16, 0x80, 0x4c, 0x9c, 0xdf, 0x5c, 0x8a, 0x75, 0xf6, 0x99, 0xcb, 0xcc, 0xf3, 0x39, 0x78, 0x31, 0xfe, 0x8c, 0xe8, 0x74, 0x02, 0xa3, 0x44, 0x36, 0xf8, 0x20, 0xcf, 0x3a, 0x97, 0xcd, 0x18, 0xec, 0xda, 0xac, 0x4c, 0xbe, 0xe6, 0x03, 0xf3, 0xe2, 0x4b, 0x62, 0x93, 0x0e, 0xc5, 0xb9, 0x17, 0x33, 0xc9, 0xa1, 0xef, 0x2c, 0x7e, 0x02, 0x41, 0xec, 0xe8, 0x8e, 0x86, 0x71, 0xd3, 0xe7, 0xad, 0x42, 0x5e, 0x37, 0xb0, 0x05, 0xba, 0x8c, 0xdd, 0xb1, 0x35, 0x66, 0xe8, 0xf5, 0x41, 0x22, 0xd0, 0x1b, 0xd5, 0x38, 0x85, 0x5d, 0xc0, 0xa1, 0x79, 0x1e, 0x29, 0x9c, 0x1c, 0xc3, 0x2d, 0x4b, 0x42, 0xe7, 0xe6, 0xcc, 0x0b, 0x19, 0xc1, 0xa4, 0x4b, 0xb2, 0x74, 0x4c, 0xf7, 0x07, 0x52, 0x34, 0x9d, 0xf4, 0x69, 0xd7, 0xd1, 0x80, 0xe5, 0xfb, 0x41, 0xf9, 0x08, 0xef, 0x03, 0x26, 0xd8, 0xf4, 0xd5, 0xf0, 0x25, 0xcf, 0x90, 0xb4, 0x39, 0x39, 0x55, 0x6b, 0x2c, 0x1b, 0x16, 0xde, 0x81, 0xce, 0x4f, 0x39, 0x65, 0xad, 0xee, 0x69, 0x7c, 0xd0, 0xf9, 0x10, 0xcd, 0x94, 0xf5, 0x5c, 0xa9, 0x6c, 0xb4, 0x60, 0x1f, 0xbf, 0x64, 0x18, 0x43, 0x7e, 0xf2, 0x22, 0xcc, 0x9d, 0xde, 0x21, 0xbb, 0xcb, 0x2c, 0xdf, 0xb4, 0xda, 0xb6, 0xb8, 0xe1, 0x79, 0x02, 0xb2, 0x06, 0xcb, 0xec, 0xf0, 0x6d, 0x38, 0xf5, 0x99, 0xe6, 0x72, 0xce, 0x68, 0x79, 0x15, 0x90, 0x35, 0x6b, 0xdd, 0x51, 0x31, 0x21, 0xcd, 0x3b, 0x2d, 0x54, 0x0d, 0x49, 0x80, 0xa1, 0x22, 0x70, 0x50, 0x4c, 0x97, 0xd2, 0xef, 0x68, 0xaa, 0x65, 0xa9, 0x0f, 0x1c, 0x46, 0xcf, 0x55, 0x15, 0xbc, 0x60, 0x93, 0xd9, 0xbc, 0xd7, 0x53, 0xef, 0xdb, 0xbf, 0x9d, 0xc1, 0xc9, 0xac, 0xa3, 0x88, 0x23, 0x59, 0xff, 0x78, 0xb0, 0x6b, 0x6d, 0x7e, 0x31, 0xf3, 0xc2, 0xf0, 0x02, 0xc6, 0xa6, 0x5a, 0x1b, 0x97, 0xc3, 0x77, 0xa6, 0xb9, 0x0b, 0xdd, 0x3b, 0x70, 0x6b, 0x20, 0xbd, 0xd7, 0xdb, 0x2d, 0xd6, 0x28, 0xc8, 0x1c, 0x09, 0x8d, 0x43, 0x4f, 0xb5, 0x5b, 0x56, 0xb0, 0x57, 0x67, 0xf2, 0xb4, 0x01, 0xa4, 0x13, 0x9f, 0x24, 0xf0, 0x93, 0x7a, 0x9d, 0xbe, 0xdf, 0xfa, 0xcc, 0x60, 0x4d, 0xdf, 0x8e, 0xeb, 0x43, 0x48, 0x82, 0x2a, 0x38, 0xec, 0xdd, 0x4a, 0x0e, 0x2e, 0x34, 0x14, 0x13, 0xee, 0x52, 0x39, 0x04, 0x48, 0x82, 0x6d, 0x03, 0xa0, 0xac, 0xef, 0x3b, 0x3d, 0x37, 0x58, 0x4d, 0x9c, 0x2a, 0xb1, 0x88, 0x38, 0x1b, 0x1f, 0xfc, 0x97, 0x40, 0xa5, 0xfe, 0xdb, 0xc0, 0x51, 0x2a, 0x96, 0x77, 0xa3, 0x4d, 0xec, 0x61, 0xe4, 0x27, 0x21, 0x30, 0x45, 0x70, 0xd9, 0x67, 0xae, 0x62, 0xb2, 0xba, 0x98, 0xf1, 0x4d, 0x4b, 0x70, 0x88, 0x21, 0x03, 0x98, 0xc8, 0x4d, 0xf8, 0xe6, 0x00, 0x64, 0x34, 0x9b, 0x80, 0x87, 0xc9, 0x48, 0xa2, 0x5c, 0x18, 0x1e, 0xd9, 0x40, 0xfc, 0x27, 0x8f, 0xbf, 0x9f, 0x9a, 0xe6, 0x83, 0x8d, 0xcb, 0xde, 0x18, 0x66, 0x13, 0xa9, 0x7b, 0x86, 0x22, 0x90, 0x8f, 0x0a, 0xbd, 0x1d, 0x07, 0x08, 0xe6, 0x03, 0x26, 0x08, 0xa3, 0x4b, 0xcd, 0xf9, 0xf1, 0x8b, 0x67, 0xd0, 0xe6, 0x81, 0xa9, 0xbd, 0x71, 0x88, 0x66, 0xe4, 0xef, 0xe8, 0xd6, 0x3e, 0xb4, 0x33, 0x0e, 0x48, 0x8f, 0x1f, 0x12, 0x86, 0x92, 0xa1, 0xc8, 0x13, 0x42, 0xe0, 0xe3, 0x3c, 0xb7, 0x68, 0x9f, 0x56, 0xc9, 0xe2, 0xd1, 0x40, 0xa5, 0x40, 0x27, 0xa6, 0xce, 0x2b, 0x63, 0xa7, 0xd7, 0xeb, 0xdf, 0x16, 0xa2, 0xb6, 0xe0, 0xfa, 0x78, 0x77, 0xae, 0x9f, 0x46, 0xe7, 0x63, 0xe2, 0x19, 0xd0, 0xa9, 0x00, 0x2b, 0x5d, 0xb0, 0x5e, 0x8a, 0x1e, 0xd9, 0xaa, 0x57, 0x03, 0x92, 0x52, 0x30, 0xda, 0x8e, 0xba, 0x0c, 0x61, 0xbe, 0x1c, 0xbf, 0x99, 0xf2, 0x08, 0x24, 0x57, 0xd3, 0x81, 0x48, 0xc6, 0x7d, 0x36, 0x8b, 0xd1, 0x9c, 0xa8, 0x21, 0x91, 0xdb, 0xf0, 0x2c, 0x44, 0x61, 0x82, 0x25, 0x11, 0x08, 0xcc, 0x67, 0xe3, 0x71, 0x58, 0xf3, 0x09, 0xd5, 0x66, 0x99, 0x6d, 0x4e, 0x97, 0x20, 0x50, 0x90, 0x91, 0xbd, 0x79, 0x5b, 0x7e, 0x32, 0xab, 0x65, 0x1d, 0x2d, 0xdc, 0xda, 0x4c, 0x0c, 0x5c, 0xae, 0xbd, 0xa2, 0x61, 0xc9, 0xb4, 0x5f, 0x7e, 0x65, 0x8b, 0xc3, 0xc2, 0xdd, 0x60, 0xf0, 0x8d, 0xec, 0x83, 0x6f, 0x3e, 0x33, 0x5b, 0x76, 0x2d, 0x28, 0x19, 0xe1, 0xb9, 0x60, 0x6c, 0x1d, 0xcb, 0x3a, 0x68, 0x94, 0x5a, 0xca, 0xc8, 0xa4, 0x11, 0x03, 0x6d, 0xcb, 0x20, 0x68, 0x70, 0x26, 0x60, 0xdb, 0xc4, 0x6c, 0xe8, 0x57, 0xa7, 0xcb, 0xea, 0x86, 0xb6, 0xb4, 0x7b, 0x48, 0xe9, 0xfc, 0x06, 0x87, 0x1c, 0x38, 0xe9, 0xdb, 0x93, 0xd0, 0x69, 0xd8, 0xee, 0x0c, 0x2c, 0x80, 0x67, 0x3f, 0xcc, 0xbf, 0xd1, 0x49, 0x9f, 0x04, 0x30, 0x1a, 0x33, 0xd8, 0x31, 0x50, 0x0c, 0x26, 0x66, 0xd6, 0x02, 0x47, 0x56, 0xdb, 0x8f, 0x55, 0x9d, 0x53, 0xf2, 0x4b, 0x96, 0x46, 0xa1, 0x8b, 0xf0, 0x9f, 0xcf, 0xf4, 0x6a, 0x0f, 0x0b, 0x98, 0xd9, 0x9d, 0xa7, 0xbb, 0xe3, 0xd5, 0xc0, 0xbc, 0x0b, 0xc3, 0xcb, 0x5a, 0x87, 0x17, 0xf6, 0xe2, 0x86, 0xad, 0x00, 0x27, 0x4d, 0xe3, 0x63, 0x72, 0x7d, 0x7f, 0xe8, 0xec, 0xf6, 0x7e, 0xbe, 0x57, 0x60, 0x16, 0xd7, 0xa8, 0x03, 0x7d, 0x0d, 0xbf, 0xc3, 0x1e, 0x0d, 0xd6, 0x54, 0x79, 0x2b, 0xe5, 0xc1, 0x59, 0x51, 0xcd, 0x16, 0xf4, 0x97, 0xd2, 0x09, 0xe6, 0x90, 0xff, 0x43, 0x8b, 0x25, 0x35, 0xd1, 0xb3, 0x53, 0x34, 0x68, 0xcf, 0x9d, 0xde, 0x13, 0x38, 0xca, 0x3a, 0x2a, 0xd2, 0xd8, 0xd1, 0xf4, 0xb6, 0x7d, 0x1b, 0x38, 0x9b, 0x37, 0xcb, 0xd5, 0xb8, 0x00, 0x09, 0xc4, 0x0b, 0x6b, 0x46, 0x2e, 0x63, 0x85, 0x72, 0x37, 0xce, 0x25, 0x1f, 0xf3, 0xfa, 0x2b, 0xd1, 0xf7, 0x73, 0x3d, 0xa0, 0xec, 0x8e, 0x7d, 0xe8, 0x0f, 0x44, 0x07, 0x89, 0xf6, 0xc0, 0xca, 0xb6, 0xaf, 0x39, 0x94, 0x78, 0x3d, 0xfe, 0x92, 0x26, 0xf1, 0x88, 0x78, 0x7f, 0xf8, 0x37, 0x3f, 0x5a, 0x4c, 0x62, 0xfe, 0x5d, 0x4a, 0xa8, 0xd1, 0x5e, 0xfd, 0xc3, 0x92, 0x78, 0x53, 0x87, 0x31, 0xbd, 0x44, 0x87, 0x7e, 0xac, 0x59, 0x86, 0x93, 0x23, 0x48, 0xad, 0x57, 0x31, 0x1c, 0x60, 0x24, 0xef, 0x13, 0x07, 0xa0, 0x01, 0x0f, 0xb3, 0xc7, 0x81, 0x62, 0xfa, 0x26, 0xfb, 0x6e, 0x1b, 0xd6, 0x9e, 0x1f, 0xbe, 0x0e, 0x38, 0x1d, 0x11, 0xb3, 0xbc, 0x24, 0x76, 0x9d, 0x57, 0xd6, 0xb1, 0x27, 0x04, 0xbd, 0x54, 0x15, 0x57, 0xa1, 0xb3, 0x38, 0x11, 0x0f, 0x2f, 0x40, 0x42, 0xdc, 0x8d, 0x88, 0x9f, 0xbb, 0x6b, 0xf1, 0x02, 0x4c, 0x11, 0x29, 0xa7, 0xb9, 0xc3, 0x19, 0xc1, 0xeb, 0x3d, 0x8a, 0xa9, 0x7a, 0x02, 0x02, 0x4f, 0xe8, 0xa6, 0x39, 0xbb, 0xa7, 0x80, 0xa5, 0xfb, 0x1e, 0x05, 0x04, 0x8f, 0x56, 0xba, 0xb1, 0x85, 0xf0, 0xc0, 0xd9, 0xe7, 0xf2, 0xf7, 0x15, 0x85, 0x0f, 0x84, 0x0e, 0x31, 0x24, 0xae, 0x19, 0xc5, 0xaa, 0xfb, 0xf2, 0x80, 0x8d, 0x7e, 0x1e, 0x00, 0xd3, 0x89, 0xac, 0x0a, 0x9c, 0x29, 0xfe, 0xe3, 0xc2, 0x8b, 0xa4, 0xb9, 0x19, 0xc9, 0xf7, 0x37, 0x4e, 0x60, 0xb6, 0x93, 0x20, 0xf8, 0xcf, 0xf9, 0xe1, 0xbf, 0x25, 0x33, 0x67, 0xa9, 0xd4, 0xce, 0xc5, 0x74, 0xdd, 0xbf, 0x62, 0xfa, 0xfd, 0x5f, 0x25, 0xcc, 0x36, 0x30, 0x28, 0xf1, 0x4c, 0x67, 0x31, 0x2d, 0x1e, 0xc0, 0x93, 0x0d, 0x2e, 0xb1, 0xfe, 0xe1, 0xf7, 0x17, 0xe8, 0x55, 0x83, 0x24, 0x94, 0x44, 0xe1, 0xaf, 0xa5, 0xa4, 0x90, 0x42, 0x93, 0x16, 0x7c, 0xdf, 0x7b, 0xc7, 0x03, 0x5a, 0x61, 0x1c, 0x04, 0xdd, 0xf7, 0x7a, 0xf6, 0xc7, 0xe9, 0xa7, 0x9e, 0x94, 0xe8, 0x36, 0x6e, 0x4d, 0x75, 0xa7, 0x60, 0x68, 0x28, 0x5d, 0x27, 0xce, 0xc5, 0x79, 0x88, 0x13, 0xfc, 0x88, 0x6a, 0x16, 0x3e, 0x02, 0x49, 0xed, 0x8f, 0x32, 0x0e, 0x80, 0x7e, 0x19, 0x7d, 0xcf, 0xbe, 0x84, 0xcb, 0x4b, 0xfd, 0x8d, 0xba, 0x85, 0x75, 0x10, 0x87, 0x6a, 0xd5, 0xfd, 0xe1, 0x54, 0xd4, 0x8f, 0xaf, 0x0c, 0xf7, 0x37, 0x04, 0x19, 0xbe, 0xfa, 0x3e, 0xf8, 0xb4, 0x14, 0x73, 0x7c, 0x33, 0x99, 0xdf, 0xe7, 0x09, 0xb4, 0x3f, 0x2d, 0x1f, 0x6f, 0x5b, 0x40, 0xa0, 0x6b, 0x6d, 0x9b, 0x51, 0xac, 0xa9, 0x96, 0x65, 0x13, 0xbf, 0xf2, 0xb5, 0xe3, 0xab, 0xc5, 0xe2, 0xa8, 0x3a, 0x4c, 0x38, 0xf6, 0x30, 0xd4, 0xfe, 0xf9, 0x59, 0x66, 0x74, 0x8a, 0x99, 0xa3, 0xa2, 0x7c, 0x81, 0xae, 0xbc, 0xa3, 0xdc, 0x16, 0xe4, 0xd4, 0xa4, 0x3b, 0x62, 0x9f, 0x56, 0xb2, 0x21, 0xee, 0xb0, 0x86, 0xe7, 0xae, 0xa8, 0x4c, 0x09, 0x4a, 0xc4, 0x52, 0x92, 0x73, 0x2e, 0xa2, 0x5d, 0x8b, 0x38, 0x76, 0xcc, 0x43, 0xe1, 0x1a, 0xbf, 0x9e, 0x89, 0x82, 0xd6, 0x5c, 0x5f, 0x4c, 0x00, 0xb7, 0xd5, 0x56, 0x72, 0x63, 0x64, 0xca, 0xde, 0xaf, 0x58, 0xe9, 0xf9, 0x3f, 0x17, 0x3a, 0xa4, 0x49, 0x0a, 0x21, 0xea, 0x9f, 0x4a, 0xbf, 0xe9, 0x4e, 0x82, 0x43, 0x29, 0xbc, 0x70, 0xad, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x02, 0xe4, 0x61, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbd, 0x07, 0xec, 0x81, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0xc6, 0xd7, 0x7c, 0xc0, 0xcb, 0xc4, 0x09, 0x67, 0x85, 0xf1, 0x8e, 0x19, 0x9c, 0xef, 0x6b, 0xd4, 0xab, 0x9e, 0x39, 0xa2, 0xa3, 0x6d, 0x71, 0xea, 0x44, 0x1e, 0x39, 0xc7, 0x45, 0x57, 0xe2, 0x12, 0xe8, 0x75, 0x6f, 0x3b, 0xc0, 0x3e, 0x83, 0x3b, 0x76, 0x00, 0x4f, 0x11, 0x4e, 0xdd, 0x59, 0x7e, 0xb3, 0xaf, 0x36, 0x2f, 0x90, 0xfb, 0xb5, 0x14, 0x64, 0x62, 0xb8, 0x40, 0x6e, 0xfa, 0xb3, 0xee, 0x58, 0xdf, 0xb8, 0xfe, 0xcb, 0x89, 0x65, 0x04, 0x03, 0xca, 0x5c, 0xc5, 0xf8, 0x39, 0x08, 0xb6, 0x4a, 0xe1, 0xc4, 0x1a, 0x92, 0xf3, 0x4b, 0x47, 0xcf, 0x00, 0xcd, 0xfd, 0xce, 0xb4, 0x7a, 0x25, 0x31, 0x43, 0xc4, 0xf9, 0x9d, 0x9b, 0x62, 0x30, 0x25, 0xae, 0xcb, 0x56, 0x8a, 0xd0, 0xa9, 0x47, 0x3e, 0x29, 0x3b, 0x0f, 0x69, 0x80, 0xb9, 0x4b, 0x7f, 0x52, 0xa3, 0xa6, 0x62, 0xe8, 0xa8, 0x62, 0x2f, 0x64, 0x82, 0xad, 0xba, 0x18, 0x75, 0xcb, 0x09, 0x68, 0x96, 0x65, 0x48, 0xae, 0x2c, 0xfb, 0x88, 0xb9, 0x0c, 0x07, 0x9a, 0x4c, 0x3b, 0x85, 0xe8, 0x30, 0xce, 0xbb, 0xce, 0x24, 0x9d, 0x6d, 0xcb, 0xd9, 0xed, 0x05, 0x22, 0xb0, 0x65, 0x62, 0x45, 0x28, 0xb9, 0xcf, 0x2d, 0x06, 0xe3, 0xef, 0x93, 0x42, 0x68, 0xa5, 0xce, 0xe3, 0x57, 0x6a, 0x8b, 0x69, 0x7e, 0x0e, 0xeb, 0x12, 0x6a, 0x1f, 0xf5, 0xf4, 0x8a, 0x96, 0x5a, 0x4f, 0x82, 0xbf, 0x1c, 0x5c, 0xb0, 0xdb, 0xad, 0x21, 0x28, 0xd4, 0x05, 0x70, 0xf6, 0x14, 0x7d, 0x6b, 0xa0, 0xca, 0x22, 0xd2, 0xbb, 0x55, 0x4c, 0x52, 0x84, 0xc9, 0x8c, 0xe3, 0x59, 0xb3, 0x1b, 0xd9, 0x0e, 0x87, 0x2e, 0x6e, 0x49, 0x27, 0xc9, 0xe4, 0xbf, 0xb2, 0x2e, 0xa7, 0xde, 0x16, 0xc6, 0x62, 0x9b, 0x72, 0xbe, 0x11, 0x20, 0x38, 0xaa, 0x35, 0x54, 0xc1, 0xc6, 0x5f, 0xd2, 0x4d, 0x42, 0xce, 0xc4, 0xe6, 0xf1, 0x81, 0x11, 0x59, 0x8d, 0x0c, 0x43, 0x35, 0x7f, 0x3f, 0x74, 0xc2, 0xdd, 0x05, 0x12, 0x8b, 0x05, 0x40, 0xd8, 0x74, 0x9d, 0x5b, 0x45, 0x36, 0xff, 0x6e, 0xe9, 0xb7, 0xa2, 0x9e, 0x95, 0x95, 0x41, 0xef, 0x2c, 0x39, 0xc5, 0x78, 0xe8, 0xe5, 0x9d, 0x54, 0x68, 0x78, 0x7f, 0x81, 0xb1, 0x40, 0xbf, 0x7c, 0x11, 0xb0, 0x41, 0xbf, 0xaa, 0x04, 0x71, 0x34, 0x2a, 0x72, 0x30, 0xbb, 0x75, 0xb1, 0xf5, 0x0c, 0x07, 0x9b, 0xa7, 0xab, 0xd0, 0x38, 0x80, 0x9e, 0x64, 0xb1, 0x19, 0x70, 0x6f, 0xa9, 0x45, 0x66, 0x1b, 0x41, 0xd6, 0xd9, 0x73, 0xb3, 0xa6, 0xfb, 0x2e, 0x62, 0xf6, 0x18, 0x1d, 0x38, 0x63, 0x07, 0x68, 0x5e, 0xbf, 0x14, 0xa4, 0xec, 0x4e, 0x47, 0x49, 0xa7, 0x8c, 0xdf, 0x32, 0xfb, 0xec, 0x80, 0xca, 0xbd, 0xfc, 0xc3, 0x70, 0xac, 0x7c, 0x5e, 0x6a, 0xc9, 0x67, 0x4b, 0x7a, 0x07, 0xd5, 0xcd, 0xef, 0xba, 0x70, 0x73, 0x5b, 0x66, 0x75, 0xd9, 0x85, 0xfe, 0x72, 0x65, 0xcb, 0x74, 0xe8, 0x14, 0xde, 0xf1, 0xb9, 0xe7, 0xac, 0x6e, 0x2f, 0xc9, 0x8f, 0x94, 0x06, 0x05, 0x9d, 0x48, 0xe7, 0xc6, 0x96, 0xeb, 0x8c, 0x44, 0x84, 0x91, 0x14, 0xa8, 0x76, 0x4c, 0x4f, 0x78, 0xba, 0x9a, 0x18, 0x23, 0x56, 0x86, 0xb9, 0x38, 0xd9, 0x62, 0xeb, 0x36, 0x5b, 0xbf, 0x1b, 0x9a, 0xb6, 0x6d, 0x8a, 0x0a, 0x69, 0x33, 0x87, 0x1e, 0xbd, 0x07, 0x85, 0xcc, 0x86, 0xa0, 0x17, 0x2b, 0x00, 0x51, 0x19, 0x93, 0xbd, 0x64, 0x25, 0x47, 0xad, 0x5d, 0xa1, 0xbd, 0x84, 0xe6, 0xf5, 0xaa, 0x1d, 0x61, 0x19, 0x49, 0x9a, 0x59, 0xdc, 0x40, 0xd7, 0xf7, 0x4e, 0xda, 0x0a, 0x93, 0x39, 0x0f, 0x39, 0xdd, 0x54, 0x95, 0x14, 0x30, 0xcb, 0x25, 0xdd, 0x63, 0xf5, 0x00, 0xf2, 0x75, 0x33, 0x5c, 0xea, 0x7a, 0xac, 0x20, 0xb2, 0xfe, 0xab, 0x94, 0x76, 0x7d, 0x0b, 0x15, 0x67, 0x3a, 0x4c, 0x1e, 0xa8, 0x3d, 0x75, 0x0d, 0x31, 0xcb, 0xdf, 0xe2, 0xa7, 0xa3, 0xff, 0xb1, 0x95, 0x14, 0x42, 0x3b, 0x53, 0xba, 0x1b, 0xb4, 0xcd, 0x97, 0x02, 0xc3, 0x63, 0x91, 0x7d, 0x91, 0xa0, 0xbf, 0xca, 0x29, 0xd5, 0xfb, 0xc0, 0x54, 0x49, 0x1c, 0xff, 0x15, 0x65, 0xff, 0xda, 0x36, 0x66, 0xe6, 0x66, 0xbc, 0x1e, 0x29, 0x46, 0xca, 0xf2, 0xaf, 0x93, 0xb8, 0x82, 0xb4, 0xdc, 0x43, 0x05, 0xf1, 0xd9, 0x71, 0x3f, 0x18, 0x75, 0xb6, 0x5f, 0x12, 0x7f, 0x2e, 0x35, 0xf7, 0xf8, 0x50, 0xf3, 0xa8, 0xd7, 0xc4, 0xad, 0xa6, 0x11, 0x6d, 0x83, 0xe5, 0xe1, 0x14, 0x3a, 0x33, 0x32, 0xb0, 0x17, 0x36, 0xd9, 0xcd, 0x98, 0x05, 0x81, 0x13, 0xcd, 0x87, 0x37, 0x87, 0x48, 0x3e, 0x12, 0x61, 0xea, 0x09, 0x7e, 0x93, 0x4d, 0x10, 0x98, 0x6d, 0xa6, 0x6f, 0x87, 0x4f, 0x7c, 0x05, 0x41, 0x7e, 0x3d, 0x6b, 0xc8, 0x5b, 0x63, 0xdb, 0x34, 0x2b, 0xc4, 0xc9, 0x2a, 0x25, 0xbe, 0x03, 0x67, 0x0c, 0xd4, 0xc8, 0x95, 0x3e, 0xb5, 0xf5, 0xf4, 0xc2, 0xa7, 0xce, 0x23, 0xd9, 0x0c, 0x0f, 0x73, 0xc3, 0x19, 0xeb, 0xae, 0x18, 0x47, 0x4c, 0xdc, 0xba, 0x7e, 0xdd, 0x5a, 0xec, 0x8f, 0x41, 0xef, 0x8d, 0xf9, 0x7f, 0x23, 0x88, 0xf2, 0xda, 0x3e, 0x8e, 0x78, 0xef, 0xeb, 0x46, 0xae, 0xea, 0xa6, 0x86, 0x49, 0x6e, 0x01, 0x37, 0xf8, 0x83, 0x9c, 0x21, 0x73, 0x68, 0xff, 0x29, 0x3e, 0xf4, 0x65, 0xab, 0x22, 0x15, 0xdf, 0x5f, 0xfb, 0x53, 0x98, 0xec, 0xee, 0xe5, 0x6e, 0xa5, 0xae, 0x1f, 0xac, 0x58, 0x3e, 0x1a, 0x53, 0xc3, 0x3a, 0xa8, 0x72, 0xf2, 0x53, 0xf9, 0x37, 0x7d, 0xba, 0xec, 0xb3, 0x91, 0xfd, 0x05, 0xd2, 0x5c, 0xb9, 0x24, 0xb1, 0xf6, 0xe5, 0xb1, 0x1f, 0xc8, 0x27, 0x2d, 0xa7, 0x49, 0x77, 0xfd, 0xe2, 0x39, 0x37, 0x48, 0x5b, 0x70, 0x28, 0x85, 0x83, 0x12, 0xdf, 0xbc, 0xb0, 0x65, 0x05, 0x02, 0xa1, 0x73, 0x71, 0x0e, 0xd3, 0x8f, 0x3a, 0x27, 0xb8, 0xc4, 0x5b, 0xe4, 0xb1, 0x12, 0x18, 0xa8, 0x6c, 0xc8, 0x17, 0xe2, 0x13, 0xf1, 0x51, 0x49, 0xb4, 0x0f, 0xb7, 0xf5, 0x88, 0x94, 0x20, 0xc2, 0x8e, 0x95, 0xff, 0xd6, 0xfd, 0xda, 0x4f, 0xda, 0x19, 0xa9, 0x59, 0x49, 0x71, 0x01, 0xf5, 0x5c, 0xdf, 0x2c, 0x93, 0xb5, 0x7f, 0xd7, 0x42, 0x57, 0x6e, 0x76, 0xd8, 0x03, 0x5e, 0xd6, 0xfa, 0x0e, 0x79, 0xa2, 0x91, 0xbd, 0xb0, 0xda, 0x6b, 0xa7, 0x38, 0xfc, 0x95, 0x39, 0x8b, 0xf0, 0x7f, 0xfe, 0xb9, 0x5a, 0xbb, 0x5d, 0xa2, 0x8e, 0x3a, 0xd1, 0x6e, 0x60, 0xb6, 0x55, 0x24, 0xfb, 0x05, 0xce, 0x75, 0x19, 0xb3, 0x53, 0x79, 0x11, 0xb9, 0xbb, 0xff, 0x0c, 0xcf, 0x3c, 0x42, 0xaf, 0xec, 0xf4, 0x51, 0x20, 0x0b, 0xc0, 0x10, 0xc8, 0x69, 0x52, 0x03, 0xc4, 0xcb, 0x67, 0x08, 0xb5, 0x06, 0x4c, 0x78, 0xf5, 0x39, 0xd9, 0x44, 0x03, 0x17, 0xbf, 0xa2, 0xb6, 0x45, 0x0b, 0xfb, 0xca, 0xb5, 0xe1, 0xc0, 0x33, 0x53, 0xe5, 0x4f, 0x0b, 0x40, 0xc5, 0xda, 0x6a, 0x40, 0x35, 0x10, 0x24, 0xac, 0x43, 0xd5, 0x8b, 0x17, 0xac, 0x84, 0x64, 0x37, 0xc6, 0x48, 0x1f, 0x9f, 0x68, 0x52, 0xa5, 0x5a, 0x08, 0xac, 0x92, 0x19, 0xa9, 0xe0, 0xa7, 0xbe, 0x98, 0x8c, 0x9e, 0xd1, 0xfe, 0x14, 0x27, 0x76, 0x58, 0x9d, 0x02, 0xc6, 0x9a, 0x31, 0xbc, 0x73, 0x9a, 0x73, 0x26, 0x65, 0x05, 0xe0, 0x7f, 0x46, 0xe3, 0x2f, 0xf9, 0x6d, 0xd5, 0x96, 0x35, 0xab, 0xea, 0x75, 0x04, 0xe6, 0xa1, 0x57, 0x3d, 0x8c, 0x3b, 0x76, 0xcc, 0xfc, 0x50, 0x25, 0xe8, 0xbe, 0x8d, 0x6b, 0xe2, 0x60, 0xdc, 0xa2, 0x41, 0xc0, 0xa9, 0xc8, 0x92, 0xdb, 0xa0, 0x7f, 0xb4, 0xb3, 0x80, 0xcb, 0x68, 0xc0, 0x4a, 0x0a, 0xda, 0xda, 0x79, 0xed, 0x3d, 0x66, 0x62, 0xcb, 0x28, 0xdf, 0x06, 0x88, 0x74, 0x09, 0x24, 0xe9, 0xeb, 0x55, 0xd4, 0x15, 0x45, 0x28, 0xb2, 0xb1, 0xc7, 0x0e, 0x7c, 0x67, 0x73, 0xe3, 0x57, 0xf7, 0x26, 0x79, 0x7c, 0x0f, 0x7a, 0x31, 0x8f, 0x4b, 0xf4, 0xd9, 0xef, 0xc3, 0xda, 0x12, 0x8b, 0x24, 0x8d, 0x41, 0xde, 0xbb, 0x6f, 0x20, 0x19, 0xae, 0x0f, 0xad, 0xd5, 0xd5, 0xba, 0x4a, 0x8e, 0x74, 0x36, 0x2e, 0x86, 0x02, 0xbf, 0x87, 0x33, 0x2f, 0xd3, 0x52, 0xe5, 0xce, 0x06, 0xc2, 0x00, 0xa0, 0x93, 0x54, 0x47, 0x27, 0x6e, 0xa5, 0xdd, 0xee, 0x51, 0x24, 0xdb, 0x19, 0xb2, 0x9d, 0xf0, 0x6d, 0x5e, 0x01, 0x73, 0x91, 0x4f, 0x89, 0x70, 0xc5, 0x41, 0x7c, 0xc4, 0x31, 0x4d, 0xc0, 0x1e, 0x7a, 0x0a, 0x07, 0xbb, 0xce, 0x45, 0x8c, 0x7c, 0x70, 0x44, 0xc4, 0x26, 0xa6, 0xc9, 0x98, 0xaa, 0x3a, 0xf2, 0xaf, 0xc9, 0x03, 0x62, 0x10, 0xa6, 0xa5, 0x7c, 0x66, 0x2f, 0xc7, 0x00, 0x43, 0x9d, 0xf7, 0x04, 0x9f, 0x66, 0x58, 0x78, 0x3a, 0xc9, 0xc3, 0xca, 0x98, 0x7a, 0x56, 0x1f, 0xa6, 0x6b, 0x5b, 0x60, 0x45, 0xb0, 0x57, 0x17, 0x90, 0x1f, 0xa9, 0x5c, 0x0a, 0x4c, 0xbb, 0x7c, 0x63, 0xf0, 0x0c, 0x77, 0x63, 0x11, 0x52, 0xc8, 0xa9, 0x36, 0x39, 0x4b, 0xfb, 0x07, 0x07, 0x60, 0xd7, 0x77, 0x1e, 0x4e, 0xbe, 0x0d, 0xf6, 0xdb, 0xcd, 0x09, 0x98, 0x66, 0x5a, 0xc2, 0xc7, 0x36, 0x79, 0x92, 0xa8, 0x21, 0xc3, 0x03, 0xb7, 0x40, 0x93, 0x58, 0x28, 0xb3, 0xa4, 0x2d, 0x7c, 0xa2, 0xeb, 0x33, 0x3c, 0x97, 0xbd, 0x34, 0x37, 0x38, 0x33, 0x6b, 0xe6, 0x0c, 0xfd, 0x95, 0x39, 0x8b, 0x72, 0xbc, 0x49, 0x6d, 0xfc, 0x74, 0x97, 0x59, 0xfe, 0x87, 0x7c, 0xec, 0x50, 0xde, 0x72, 0x83, 0x9c, 0x35, 0x3b, 0x84, 0xa4, 0x96, 0x46, 0x7e, 0xe0, 0x3a, 0xcd, 0xb8, 0xa3, 0x4e, 0x82, 0x4b, 0x59, 0xaa, 0x0b, 0xc4, 0x18, 0xb4, 0x36, 0x97, 0x41, 0xad, 0x6c, 0xd7, 0x13, 0x6a, 0x4e, 0x86, 0x0e, 0x8f, 0xe5, 0x90, 0xf2, 0x03, 0x94, 0x5c, 0x1d, 0x13, 0xda, 0x0f, 0x7c, 0xd7, 0xc1, 0x31, 0xa0, 0x50, 0x2a, 0x4c, 0x7e, 0xb0, 0xd2, 0x9b, 0xc0, 0xd7, 0x7e, 0x72, 0x2d, 0xf2, 0x25, 0x2e, 0xd5, 0x85, 0xf2, 0xb2, 0x82, 0x9f, 0x8e, 0x5c, 0x8e, 0x5a, 0xe9, 0x5f, 0x1d, 0x87, 0xcd, 0xdb, 0x14, 0x5f, 0x9d, 0xa3, 0x95, 0x35, 0x73, 0x48, 0x10, 0xc1, 0xd4, 0x30, 0x0d, 0x79, 0xe9, 0x56, 0xab, 0xbf, 0xf7, 0x07, 0xe6, 0x06, 0xa2, 0x24, 0xa1, 0x78, 0x6b, 0x2a, 0xdf, 0xd1, 0x6a, 0x8a, 0x18, 0x84, 0x4e, 0xaf, 0x37, 0x9a, 0xea, 0x86, 0x08, 0xf0, 0x8f, 0x88, 0xa4, 0xb5, 0x3d, 0x94, 0x5e, 0xec, 0x24, 0x15, 0x06, 0xbf, 0x09, 0x8b, 0x4e, 0xa5, 0xef, 0x48, 0x87, 0xa1, 0xe5, 0x1a, 0x4f, 0x32, 0x16, 0x8c, 0x5a, 0x97, 0xae, 0x68, 0x6f, 0x66, 0x15, 0xb0, 0x24, 0x62, 0x1b, 0x17, 0x51, 0xc9, 0xab, 0x51, 0x69, 0x63, 0x96, 0x0f, 0x59, 0x61, 0xad, 0xe7, 0x34, 0x4e, 0xad, 0xc6, 0x74, 0xaa, 0x79, 0xfb, 0x67, 0x66, 0x58, 0xf8, 0x6f, 0x98, 0x03, 0x17, 0x09, 0x86, 0x1e, 0x5b, 0xe4, 0x13, 0x50, 0xcc, 0xaf, 0x1a, 0x4d, 0xd1, 0x5b, 0xf2, 0x8e, 0x85, 0x8d, 0x29, 0x2d, 0xc8, 0x71, 0x74, 0xcd, 0x68, 0xa3, 0x4c, 0xc1, 0xc8, 0xc8, 0x02, 0x20, 0xc7, 0xcd, 0x26, 0x7f, 0x7f, 0xa3, 0x83, 0xa0, 0x4f, 0x9f, 0x50, 0x9d, 0x99, 0x21, 0x0c, 0x05, 0xd4, 0x68, 0xd2, 0xfe, 0xd3, 0x3e, 0x64, 0xf7, 0xe0, 0x81, 0x45, 0x91, 0x25, 0xeb, 0x0a, 0x81, 0x5c, 0xdb, 0xc6, 0x9d, 0x0e, 0xe0, 0x83, 0x4c, 0x4d, 0x6f, 0x66, 0xf9, 0x91, 0xf0, 0x91, 0x5a, 0x1f, 0x74, 0x57, 0xcd, 0x20, 0x6b, 0x79, 0x72, 0xf5, 0x51, 0xb0, 0x51, 0x68, 0x34, 0x6f, 0xf0, 0x80, 0x85, 0x7e, 0x68, 0x6c, 0xd5, 0x10, 0x63, 0x35, 0x77, 0x37, 0xf2, 0xf5, 0x91, 0x06, 0xfd, 0x81, 0xa4, 0x20, 0xf2, 0x72, 0x66, 0xe3, 0x7d, 0x32, 0x05, 0xa3, 0xdc, 0xf4, 0xda, 0x36, 0x58, 0x8d, 0xae, 0x20, 0x34, 0x0f, 0x8e, 0xe0, 0xd1, 0x82, 0x0c, 0xcf, 0x2b, 0xac, 0x5e, 0xda, 0x3e, 0x49, 0x4d, 0xb4, 0x2c, 0x17, 0x15, 0xda, 0xe2, 0x30, 0x9b, 0x86, 0x01, 0xa8, 0x71, 0x20, 0xdb, 0x18, 0x27, 0x3d, 0xcf, 0xe6, 0x01, 0x09, 0x6d, 0xe0, 0xf2, 0xa9, 0xea, 0x4c, 0x80, 0x56, 0xab, 0x3b, 0x56, 0xfb, 0x4f, 0xe2, 0x5f, 0x80, 0x7a, 0x6c, 0xe8, 0x02, 0x6b, 0x65, 0xef, 0x3a, 0xd6, 0x66, 0xe4, 0x9f, 0xa1, 0x15, 0x50, 0x21, 0xe1, 0x37, 0x84, 0xfc, 0x5e, 0xe4, 0xf2, 0x89, 0xdb, 0x57, 0xa7, 0x9a, 0x68, 0x7c, 0x3d, 0x75, 0xf3, 0x64, 0x54, 0xca, 0xff, 0x83, 0xc7, 0x9e, 0x39, 0xc5, 0x98, 0x6a, 0xb3, 0x79, 0x30, 0x6f, 0xd6, 0x96, 0x2e, 0xa3, 0xdd, 0x4a, 0x84, 0xa7, 0x9f, 0x48, 0x06, 0xa1, 0x47, 0x1b, 0x79, 0xeb, 0x75, 0x12, 0x8d, 0xf9, 0xde, 0x43, 0xbd, 0x5f, 0xfa, 0xba, 0x28, 0x5e, 0x8e, 0x4c, 0xfb, 0xf9, 0x85, 0xd0, 0xe5, 0x37, 0xdc, 0x23, 0x99, 0x56, 0xea, 0x84, 0x8a, 0xa2, 0xe6, 0xdd, 0x1f, 0x25, 0xfb, 0x7d, 0x1c, 0x0b, 0xd9, 0x46, 0xc1, 0xfe, 0xf9, 0xc9, 0xf4, 0x51, 0xaf, 0xe9, 0x67, 0x1a, 0xe0, 0xeb, 0x22, 0xf2, 0xe0, 0x66, 0xa6, 0x2a, 0x47, 0x8d, 0xdd, 0xe3, 0x82, 0x9c, 0x92, 0x51, 0x05, 0x4f, 0x3f, 0x2f, 0xf6, 0xfb, 0x40, 0x3b, 0xf7, 0x73, 0xbb, 0xcd, 0xe1, 0xc5, 0xd1, 0xe4, 0xe0, 0x5d, 0xd2, 0xbb, 0xa8, 0xe4, 0x9e, 0x83, 0xf0, 0x7a, 0x77, 0x0e, 0x42, 0x7c, 0xd9, 0xeb, 0xe4, 0xb9, 0xb1, 0x17, 0x53, 0x8c, 0x17, 0xdc, 0xaf, 0x64, 0x99, 0x49, 0x76, 0xf3, 0xf0, 0x8e, 0x76, 0x54, 0xba, 0xde, 0x81, 0xce, 0x52, 0xaf, 0x0c, 0xb8, 0xec, 0x28, 0x99, 0x36, 0x75, 0xb8, 0x6e, 0x2f, 0x07, 0xd5, 0x41, 0x1b, 0x27, 0xfe, 0x12, 0xc6, 0x00, 0xe7, 0x90, 0x8b, 0x8d, 0xcb, 0xb4, 0x61, 0x09, 0x29, 0x7d, 0x50, 0xc0, 0xdc, 0x93, 0xb0, 0xa3, 0x2e, 0x2f, 0x7e, 0x2b, 0xc5, 0x0e, 0x87, 0x7a, 0xa4, 0x32, 0xd1, 0x90, 0xf0, 0xbe, 0x3c, 0x78, 0x9d, 0xd5, 0xae, 0xe5, 0xa8, 0xa1, 0x9b, 0xed, 0x03, 0xa2, 0xfe, 0x1a, 0x26, 0x13, 0x15, 0x99, 0xe6, 0xf5, 0x2d, 0x58, 0x68, 0x42, 0xe1, 0xda, 0x25, 0x1c, 0x8e, 0x0d, 0xed, 0x78, 0x4f, 0x42, 0x10, 0x8f, 0x1d, 0x2b, 0x24, 0x01, 0x94, 0xcf, 0xe1, 0x65, 0xeb, 0x67, 0x96, 0x08, 0xa2, 0x10, 0xa0, 0x9c, 0x45, 0x0b, 0x01, 0xf3, 0xa9, 0x38, 0x1e, 0xab, 0xbe, 0x24, 0x80, 0x07, 0xff, 0x43, 0xa7, 0x32, 0xf2, 0x54, 0xee, 0xba, 0xe7, 0x63, 0xfd, 0xc3, 0x5b, 0x26, 0x27, 0x36, 0x4f, 0xf0, 0xbd, 0x5b, 0xfc, 0x9a, 0x58, 0xe1, 0xb9, 0x60, 0x60, 0x3f, 0x5b, 0x92, 0x61, 0xa8, 0x7b, 0x13, 0xf2, 0xed, 0x9d, 0x9d, 0xee, 0x2a, 0x6b, 0x06, 0xd4 }; +constexpr AccessUnit LPCM_LARGE_AU_EXPECTED_AU = { 0x15f90, 0x159b2, false, 3, { 0x00, 0x00, 0x00, 0xfb, 0xba, 0x2b, 0xca, 0x88, 0x65, 0x2b, 0x01, 0xf4, 0xe6, 0xfc, 0x43, 0xc2 }, { 0xd6, 0x8c, 0x4f, 0x4c, 0xff, 0x84, 0x68, 0xd3, 0xb0, 0x60, 0x67, 0xd0, 0x3c, 0x90, 0x37, 0x14, 0x84, 0xba, 0x7a, 0xca } }; + +const std::vector USER_DATA_LARGE_AU_STREAM = { 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xbd, 0x06, 0xe6, 0x81, 0xc1, 0x0d, 0x31, 0x00, 0x05, 0xbf, 0x21, 0x11, 0x00, 0x05, 0xb3, 0x65, 0x1e, 0x69, 0xb2, 0x20, 0x4d, 0x00, 0x00, 0x12, 0x34, 0x5c, 0x19, 0xda, 0x7f, 0x08, 0x26, 0x84, 0x39, 0xe1, 0xd5, 0x52, 0x91, 0x8d, 0x44, 0xa5, 0xfc, 0xcb, 0x75, 0x65, 0x49, 0xd3, 0xaf, 0x92, 0x68, 0x5b, 0x79, 0x65, 0x28, 0x51, 0x4e, 0x74, 0xf7, 0xe6, 0xe6, 0x11, 0xe6, 0x89, 0x46, 0xcf, 0x5c, 0x3b, 0xe3, 0xaa, 0x7e, 0xc0, 0xee, 0xb8, 0x5a, 0xca, 0xf1, 0x60, 0x2d, 0x4b, 0xcd, 0x10, 0x79, 0xca, 0xf5, 0xc6, 0x3a, 0x63, 0x4e, 0xc5, 0x7e, 0x09, 0xeb, 0x6b, 0x12, 0x8f, 0x74, 0x71, 0x4f, 0x7e, 0x73, 0xd1, 0xe8, 0xe6, 0x6d, 0x4a, 0xc9, 0xf7, 0x0b, 0x96, 0x55, 0xcc, 0xcf, 0x96, 0x5b, 0xd2, 0x3e, 0x26, 0x5d, 0x61, 0x46, 0x73, 0xfe, 0x20, 0x18, 0xe7, 0xc7, 0xeb, 0x69, 0x02, 0xd8, 0xd8, 0x34, 0x94, 0xf9, 0xcb, 0x3c, 0xd7, 0x41, 0xd9, 0x8c, 0xa8, 0xbd, 0x8b, 0x18, 0xf1, 0x5d, 0xa0, 0x94, 0xdf, 0xd0, 0xa0, 0x72, 0xb2, 0xc3, 0x29, 0x05, 0xd6, 0x61, 0x95, 0xba, 0xa8, 0x13, 0x8b, 0x56, 0xcf, 0xb7, 0x65, 0x0d, 0xbb, 0xaf, 0xe9, 0x4e, 0x4c, 0xb6, 0xd4, 0xf6, 0x43, 0x81, 0x46, 0x46, 0xb1, 0x0f, 0xf7, 0x59, 0x3d, 0xe3, 0xc5, 0x1b, 0x3f, 0x60, 0x9f, 0x80, 0x71, 0x60, 0x19, 0x37, 0xb6, 0x7a, 0x2b, 0x7e, 0x1e, 0x6a, 0x13, 0x64, 0x5a, 0x80, 0xcb, 0xda, 0xaa, 0x6f, 0xd0, 0xfd, 0x9c, 0x32, 0x36, 0xac, 0x24, 0x9d, 0x9e, 0xfa, 0xfc, 0x26, 0xcb, 0x5d, 0x3a, 0x74, 0x56, 0xd3, 0x0e, 0xea, 0xc2, 0x4e, 0xaf, 0xef, 0x02, 0x5c, 0x2b, 0x68, 0x13, 0x5f, 0x71, 0xae, 0x27, 0x5d, 0xe2, 0xb2, 0x10, 0x01, 0x0e, 0x6e, 0xed, 0x9e, 0x7b, 0x6f, 0xb6, 0xdc, 0x99, 0x62, 0x0b, 0x48, 0x03, 0xa5, 0x8c, 0x6c, 0x82, 0xa1, 0xe3, 0x69, 0x72, 0x90, 0x47, 0xb6, 0x36, 0xe2, 0xfb, 0x9d, 0x14, 0x8a, 0xcd, 0x67, 0x48, 0xb9, 0x01, 0x2d, 0xf0, 0x9d, 0xc3, 0xf1, 0xb3, 0x92, 0x0c, 0x3a, 0xb4, 0xb5, 0x3a, 0x5c, 0x22, 0x0f, 0x31, 0x3c, 0xf9, 0xd1, 0xd8, 0x0c, 0xc9, 0xc9, 0x06, 0xbf, 0x86, 0x4e, 0x5a, 0xe7, 0xd8, 0xd2, 0x6b, 0x7a, 0x2c, 0xb3, 0xb3, 0x40, 0xd3, 0x49, 0xa0, 0xf9, 0xc3, 0x31, 0x18, 0x75, 0x95, 0x34, 0xce, 0x25, 0x3c, 0x48, 0x47, 0xeb, 0x4f, 0xde, 0xa6, 0xd2, 0x5f, 0xf3, 0x4d, 0x09, 0xb1, 0xc0, 0x65, 0xbc, 0xe6, 0x27, 0x3b, 0x8a, 0x08, 0xf6, 0x6e, 0x48, 0x1a, 0x1e, 0xc9, 0x8d, 0x6d, 0x7b, 0x67, 0x6c, 0xdb, 0x67, 0xcc, 0xe2, 0x67, 0x8e, 0x61, 0xf0, 0x3c, 0x0b, 0xac, 0x40, 0x37, 0x57, 0xae, 0x6d, 0x12, 0xfd, 0x2b, 0xec, 0x7e, 0xd3, 0xc0, 0x4e, 0x67, 0x44, 0x5e, 0xa7, 0x88, 0x14, 0x89, 0x44, 0x0e, 0x10, 0x20, 0xf8, 0x01, 0xe2, 0xea, 0xb3, 0xea, 0xd7, 0x04, 0x79, 0x6d, 0x7c, 0xd9, 0x32, 0xc9, 0x6e, 0x0e, 0xb5, 0xa7, 0x16, 0x23, 0x01, 0xdd, 0xb5, 0x6e, 0x51, 0xd8, 0x46, 0x9c, 0x1e, 0x14, 0x1c, 0x48, 0xb6, 0x3b, 0xb7, 0xcd, 0x0f, 0x1c, 0x8a, 0x3a, 0x69, 0xec, 0xb5, 0xa3, 0x31, 0x30, 0x3f, 0x44, 0x45, 0xd1, 0x5b, 0x4f, 0x94, 0xba, 0x01, 0x3f, 0xcd, 0x1f, 0x24, 0x2e, 0xe8, 0x4e, 0x48, 0x59, 0xeb, 0x86, 0xb8, 0x52, 0x1a, 0xcf, 0x1b, 0x02, 0x84, 0x8f, 0x81, 0x52, 0x8c, 0xfc, 0xb7, 0xf0, 0x15, 0xe1, 0xab, 0xa8, 0xc4, 0xd5, 0x61, 0x3c, 0x29, 0xd1, 0x32, 0x40, 0x84, 0xd1, 0xc9, 0x48, 0x03, 0x09, 0x4d, 0x3e, 0xd0, 0x07, 0xaf, 0xc9, 0x90, 0xad, 0xd6, 0x77, 0x27, 0x29, 0x17, 0x51, 0x2d, 0x37, 0x5f, 0xed, 0xe1, 0xef, 0xb1, 0xa0, 0xd5, 0xd6, 0xb6, 0x78, 0x89, 0xb2, 0x98, 0xec, 0x28, 0x05, 0x9e, 0x2b, 0x18, 0xa5, 0x59, 0x00, 0x6d, 0x0c, 0x62, 0x06, 0x85, 0xe4, 0xa7, 0x6f, 0xf9, 0x38, 0x42, 0x59, 0x43, 0xc0, 0xe0, 0xaf, 0xe5, 0x66, 0x7d, 0x70, 0x3c, 0x36, 0x0b, 0x6e, 0x47, 0x8b, 0xcf, 0x19, 0x91, 0xa3, 0xff, 0xe4, 0x98, 0x75, 0x46, 0x45, 0x64, 0x59, 0x9c, 0x9e, 0xf6, 0xe2, 0x47, 0xb0, 0xeb, 0xb6, 0x87, 0x3f, 0xc2, 0xbd, 0xcc, 0x76, 0x49, 0x38, 0xc6, 0x60, 0xb1, 0xc6, 0x57, 0x61, 0x3c, 0xc2, 0xd9, 0x68, 0xde, 0x61, 0x57, 0x0b, 0x7d, 0x80, 0x93, 0xb2, 0xc4, 0xdb, 0x54, 0x2d, 0xa2, 0x9d, 0x30, 0x2e, 0x77, 0x52, 0x64, 0xa0, 0xa5, 0x40, 0x61, 0xa5, 0x17, 0xd0, 0x10, 0x4e, 0x34, 0x1b, 0x15, 0x3b, 0x82, 0xc7, 0xea, 0x9e, 0xf8, 0xdd, 0x6b, 0xc4, 0xa9, 0xc4, 0x69, 0x76, 0xa9, 0x8b, 0x9f, 0x52, 0x06, 0xa3, 0xc4, 0x6b, 0xd9, 0x2e, 0x4a, 0xd6, 0x65, 0xb9, 0x51, 0xde, 0x5c, 0x7b, 0xd1, 0x26, 0x97, 0x80, 0xe1, 0x03, 0xa6, 0x79, 0x30, 0x73, 0xe8, 0x36, 0x91, 0xbe, 0x6b, 0xe1, 0xef, 0x5a, 0xdc, 0x2a, 0x73, 0x03, 0x72, 0x6a, 0x39, 0x60, 0x2a, 0xe3, 0x7f, 0x2f, 0x67, 0x95, 0x19, 0x38, 0x94, 0x27, 0xc0, 0x77, 0xba, 0x9e, 0xe1, 0x98, 0xb4, 0x2f, 0xa9, 0xe2, 0x9c, 0xf3, 0xea, 0x80, 0x5e, 0x6b, 0xee, 0x81, 0x38, 0x80, 0x29, 0xa1, 0x28, 0x84, 0x5f, 0x8e, 0xbb, 0xbe, 0x63, 0xcf, 0x85, 0x7f, 0x9a, 0x22, 0xae, 0x89, 0xfe, 0x87, 0xf5, 0x4f, 0x03, 0x70, 0xc9, 0xeb, 0xf9, 0x90, 0x6e, 0x7c, 0x25, 0xf3, 0xd7, 0xc5, 0xbf, 0x2b, 0x13, 0x8a, 0xbe, 0xbc, 0x50, 0x38, 0xf5, 0x38, 0xd9, 0xf7, 0x3b, 0xa7, 0xb0, 0x57, 0x85, 0x0b, 0xd0, 0x3d, 0x05, 0xfc, 0xe3, 0xf5, 0x3f, 0xc4, 0x23, 0x8c, 0x26, 0x94, 0xe9, 0xf0, 0xb0, 0x84, 0x77, 0xb4, 0x88, 0xa1, 0x5d, 0xd0, 0xb9, 0xb2, 0x9c, 0xf5, 0x18, 0x13, 0x3a, 0x3a, 0x69, 0x90, 0x35, 0x4e, 0x4f, 0xcb, 0xc9, 0xab, 0xb3, 0x1a, 0x5d, 0x8a, 0xff, 0x84, 0xf5, 0x43, 0x45, 0xdd, 0x99, 0x79, 0x48, 0x32, 0x7a, 0x5b, 0xed, 0xc5, 0x9e, 0x8c, 0xef, 0xfd, 0x23, 0x6d, 0x92, 0xf9, 0xef, 0xa2, 0x86, 0xe2, 0x09, 0xdf, 0x06, 0x85, 0x9e, 0xbc, 0x83, 0x88, 0xb3, 0x24, 0x8f, 0xbf, 0x00, 0x84, 0x91, 0x90, 0xc9, 0xc8, 0xaf, 0x4b, 0xbe, 0xa0, 0xa3, 0xff, 0x66, 0xb1, 0x8a, 0x8a, 0x78, 0x37, 0x4e, 0x32, 0xa9, 0x61, 0x9a, 0xbd, 0x13, 0xf5, 0xbc, 0x39, 0x41, 0x8d, 0x4f, 0xfa, 0xe3, 0xdc, 0x76, 0x65, 0x26, 0xf1, 0x23, 0xdb, 0x71, 0xc6, 0x0b, 0x31, 0x4e, 0x05, 0x0c, 0xb4, 0x8d, 0x3c, 0x12, 0x37, 0x86, 0x59, 0x40, 0x1a, 0x40, 0x26, 0xcb, 0x04, 0x29, 0x23, 0x48, 0x76, 0xee, 0x6c, 0x00, 0x22, 0x9d, 0x8e, 0x70, 0x0e, 0x37, 0x9e, 0x78, 0x53, 0x76, 0x91, 0x10, 0x00, 0x23, 0xb0, 0x6c, 0x70, 0x78, 0x1b, 0xeb, 0x3e, 0x26, 0xb0, 0x0b, 0x8b, 0x3b, 0xa2, 0x9c, 0x72, 0x5e, 0xb9, 0x93, 0x17, 0x6b, 0x25, 0x06, 0xd0, 0x87, 0x52, 0x66, 0x0f, 0xe2, 0x28, 0xc9, 0xbb, 0x3a, 0x7f, 0xdb, 0x03, 0x53, 0x58, 0xb0, 0x59, 0x9a, 0xb7, 0x08, 0x57, 0x5a, 0xd9, 0xaa, 0xd9, 0xd5, 0x3b, 0xb1, 0xb2, 0xa7, 0x01, 0xae, 0x5b, 0xb5, 0xef, 0xb7, 0x2a, 0x83, 0x0e, 0x5c, 0x17, 0x70, 0x5f, 0xbf, 0xa5, 0x59, 0xbc, 0xa8, 0xee, 0x8a, 0x88, 0x47, 0x14, 0xfc, 0x59, 0x99, 0x85, 0x4e, 0x52, 0x14, 0x6b, 0x76, 0xd7, 0x23, 0xd2, 0xdf, 0x32, 0x97, 0x70, 0x89, 0x4e, 0xc0, 0xa8, 0x5d, 0x03, 0x64, 0xca, 0x89, 0x63, 0x9b, 0xc8, 0x57, 0x1f, 0xed, 0xf2, 0xbb, 0x87, 0x7c, 0xbf, 0x4c, 0xda, 0xf0, 0x71, 0x62, 0xda, 0x1e, 0xd9, 0x3d, 0x3c, 0xa2, 0xc6, 0xa7, 0x16, 0xdf, 0x6c, 0x8a, 0xd8, 0xbc, 0x7b, 0x8c, 0x23, 0x2e, 0xce, 0x42, 0x48, 0xe7, 0x91, 0xf9, 0x4a, 0xcf, 0xe6, 0xfd, 0xd3, 0xb1, 0x99, 0x86, 0xd9, 0xcc, 0x6f, 0x9d, 0x73, 0x5a, 0x8f, 0x63, 0x5d, 0x4d, 0x07, 0x65, 0x46, 0x7a, 0x1f, 0x60, 0x94, 0x89, 0x53, 0x49, 0x38, 0x1e, 0x3e, 0xf2, 0xeb, 0x55, 0x52, 0x90, 0xa8, 0x76, 0x75, 0x90, 0xd9, 0x16, 0x4a, 0x63, 0x90, 0xe3, 0x02, 0xcf, 0x0f, 0x94, 0xb4, 0xb4, 0xa2, 0x96, 0xb4, 0xc2, 0x6c, 0x8e, 0x87, 0x86, 0x8d, 0x1c, 0x18, 0xbd, 0xc4, 0x1a, 0xd9, 0x8a, 0x0d, 0x87, 0x72, 0xdb, 0x6d, 0xbe, 0x05, 0xb6, 0x79, 0xbe, 0x5d, 0x19, 0x4f, 0x1c, 0x34, 0x89, 0xa5, 0xe2, 0x37, 0x2d, 0x2c, 0xbd, 0x58, 0xf5, 0xb7, 0xb9, 0x8b, 0x2c, 0xf9, 0x0c, 0xa0, 0x4d, 0x10, 0x8d, 0xda, 0x7f, 0x0d, 0x87, 0xcb, 0x6d, 0x59, 0xe9, 0x22, 0xc4, 0x29, 0x8e, 0x4b, 0x40, 0xf1, 0x94, 0xc7, 0xca, 0x37, 0x3d, 0x3f, 0xc9, 0x15, 0xa5, 0x22, 0xaf, 0xec, 0xb9, 0x52, 0xd2, 0x0c, 0xb5, 0x41, 0x33, 0x4f, 0xa1, 0x5b, 0x75, 0x01, 0x40, 0x63, 0x74, 0x52, 0xff, 0x3e, 0x5c, 0x50, 0xab, 0x63, 0x78, 0xad, 0xf5, 0x7c, 0x1e, 0xb1, 0x89, 0x5f, 0xc3, 0xb6, 0x44, 0xc5, 0xd1, 0x1f, 0xb7, 0xa6, 0x32, 0x78, 0x63, 0xc0, 0x68, 0xbe, 0x38, 0x33, 0x6b, 0x81, 0x2f, 0xfa, 0x0e, 0x9f, 0x70, 0x80, 0x6b, 0x0d, 0x29, 0xf9, 0x91, 0x65, 0x36, 0x3f, 0x71, 0x1e, 0x1c, 0xd1, 0xf7, 0xe7, 0xef, 0x82, 0x64, 0x68, 0x1d, 0x8e, 0x9e, 0x04, 0x48, 0x3e, 0xff, 0xc3, 0xff, 0x60, 0x01, 0xda, 0x26, 0x81, 0x42, 0x32, 0x33, 0xf2, 0x66, 0xa5, 0xed, 0xf0, 0x7c, 0x24, 0x54, 0xc7, 0xa6, 0xde, 0x05, 0x3f, 0x89, 0x7c, 0xbc, 0x72, 0x57, 0x23, 0xb4, 0x1e, 0x9b, 0xb0, 0x64, 0x62, 0x4d, 0x59, 0x99, 0x0a, 0xef, 0x7d, 0x69, 0xff, 0x8b, 0xd0, 0x8f, 0xac, 0x38, 0x94, 0xcc, 0xda, 0x15, 0x39, 0x34, 0xd3, 0x0b, 0x91, 0x71, 0x16, 0xf5, 0xf0, 0xa7, 0xd6, 0xe3, 0x1b, 0x02, 0x9d, 0x68, 0x45, 0x70, 0x5c, 0x70, 0x76, 0xdd, 0x0b, 0x3b, 0xcf, 0xbe, 0x81, 0x36, 0x46, 0x5e, 0xd1, 0x23, 0x16, 0xa6, 0x44, 0x71, 0x9f, 0x37, 0x03, 0xa9, 0xf8, 0x44, 0x4c, 0xe9, 0x1c, 0xbd, 0x02, 0xad, 0x66, 0x4f, 0x5c, 0x86, 0xe1, 0xc4, 0xde, 0x4e, 0x8c, 0x23, 0x2b, 0x53, 0x1b, 0xf7, 0x67, 0x2c, 0xb9, 0x2c, 0x32, 0xad, 0x9c, 0x95, 0x97, 0xfa, 0x9e, 0x4d, 0x85, 0xac, 0x46, 0xe0, 0x72, 0x83, 0x56, 0x1d, 0x38, 0x5d, 0x75, 0x3f, 0xb5, 0xf6, 0x23, 0xb2, 0xba, 0x9e, 0xda, 0xe3, 0x3a, 0x3e, 0x02, 0x66, 0x52, 0xd4, 0x9d, 0x3b, 0x52, 0x98, 0x58, 0x89, 0x6f, 0x24, 0xe1, 0x67, 0xd7, 0x1c, 0xea, 0xca, 0xce, 0x9f, 0xe9, 0xa9, 0xca, 0xc6, 0x59, 0x7b, 0x9d, 0xe4, 0x19, 0xeb, 0x86, 0x6f, 0x8a, 0xa0, 0x8a, 0x7a, 0x74, 0x98, 0x71, 0x5d, 0x8b, 0x03, 0xb4, 0xce, 0x13, 0x08, 0x15, 0xa1, 0x38, 0xbb, 0x00, 0xb1, 0xb3, 0x52, 0x27, 0x0f, 0x8c, 0x24, 0x10, 0x9e, 0x18, 0xfd, 0x3e, 0xa7, 0xaa, 0x5d, 0x4f, 0xa4, 0x83, 0x5e, 0xbe, 0x63, 0x9f, 0xc4, 0xf2, 0x0a, 0x95, 0x46, 0xef, 0x84, 0x90, 0x5e, 0xd7, 0xbe, 0x5c, 0xad, 0xc2, 0x85, 0x03, 0xbc, 0xc5, 0xf4, 0x63, 0xb1, 0x9d, 0x4c, 0x9f, 0x2a, 0x6d, 0x4e, 0x1b, 0xf8, 0xf4, 0x24, 0x32, 0xf0, 0x4e, 0xe0, 0x3f, 0xca, 0x5c, 0xc0, 0xb8, 0x71, 0xc3, 0x1c, 0x7a, 0xec, 0xbf, 0x5b, 0xd0, 0xdc, 0xf4, 0x7d, 0x6d, 0x5e, 0x6c, 0xd0, 0x0e, 0xe0, 0x64, 0x22, 0x82, 0x84, 0xb4, 0xeb, 0xc8, 0x79, 0xdf, 0xcc, 0x0b, 0x60, 0x14, 0x9c, 0xa3, 0x7e, 0x9d, 0xb1, 0xb0, 0xf2, 0x1d, 0x7e, 0x3f, 0x28, 0xf3, 0x6a, 0x50, 0x67, 0x14, 0x56, 0xe1, 0x05, 0x89, 0x9b, 0xf2, 0x41, 0x75, 0xc9, 0x59, 0x03, 0xa1, 0xf0, 0x85, 0xa7, 0xca, 0x23, 0x09, 0xaf, 0x3a, 0xe5, 0x92, 0x14, 0xa7, 0xbe, 0x71, 0x7e, 0x99, 0x07, 0x91, 0xef, 0xdf, 0xab, 0x4a, 0x69, 0x97, 0xa5, 0x37, 0xfe, 0xe5, 0x12, 0xf7, 0x3f, 0x82, 0x2a, 0x9d, 0xd2, 0xa5, 0x27, 0xd3, 0xf5, 0xc1, 0x99, 0xc2, 0x78, 0x10, 0x14, 0x8d, 0x2f, 0xf0, 0x5c, 0x0f, 0x15, 0xc8, 0x0c, 0x8c, 0x93, 0x52, 0x1d, 0x3e, 0xb0, 0x2b, 0x35, 0xda, 0xac, 0x00, 0x80, 0x10, 0xb6, 0x56, 0xea, 0x1a, 0x43, 0xdd, 0x14, 0x0e, 0x75, 0x40, 0x96, 0x5f, 0x1d, 0xcb, 0xf6, 0x26, 0x3e, 0x88, 0x9e, 0xf8, 0x1a, 0x1e, 0x74, 0xed, 0x6b, 0xa7, 0xc8, 0x73, 0x83, 0xac, 0xe0, 0xe4, 0x38, 0x02, 0x7c, 0x4b, 0x67, 0x9a, 0xb3, 0xe1, 0xef, 0xc2, 0xb8, 0xc8, 0xc4, 0x19, 0xe0, 0xab, 0x73, 0x55, 0xd4, 0x99, 0x86, 0x22, 0x27, 0xd4, 0x7b, 0x05, 0x4b, 0x43, 0x2c, 0x43, 0x0b, 0xf2, 0x35, 0x37, 0x3c, 0x95, 0x63, 0xcd, 0x08, 0x24, 0x5f, 0x37, 0xce, 0xff, 0x99, 0xbe, 0x98, 0x0e, 0x0b, 0x87, 0x07, 0xe0, 0x70, 0x89, 0x0b, 0x82, 0x53, 0x57, 0x53, 0x62, 0xdb, 0xe7, 0x76, 0xc6, 0x41, 0x0f, 0x0c, 0x9b, 0x52, 0x37, 0xf8, 0x83, 0x40, 0x23, 0x26, 0x55, 0xf9, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x02, 0xe4, 0x61, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbd, 0x07, 0xec, 0x81, 0x00, 0x00, 0x20, 0x91, 0x48, 0x5e, 0xa3, 0x75, 0x85, 0xfa, 0xa0, 0x8b, 0x71, 0x17, 0xb1, 0x83, 0x8f, 0x09, 0x16, 0x15, 0x34, 0x04, 0xa6, 0x6c, 0x2d, 0x5f, 0x2d, 0x6a, 0x6d, 0xf4, 0x63, 0x28, 0x9c, 0xcb, 0x76, 0x85, 0xd6, 0xdc, 0x0b, 0x75, 0x65, 0xa1, 0xcd, 0xcc, 0x10, 0xa9, 0x4a, 0x81, 0xa9, 0x43, 0x0f, 0xf7, 0x7a, 0xb8, 0xa2, 0x25, 0x44, 0xc5, 0x56, 0xbc, 0x22, 0x0b, 0xa6, 0xaf, 0x45, 0xe2, 0xe4, 0x02, 0x61, 0x4d, 0x5d, 0x1e, 0x47, 0x9a, 0xdc, 0x29, 0xc6, 0x80, 0xf5, 0x79, 0x55, 0x74, 0xd0, 0x19, 0x75, 0xa7, 0x89, 0x9a, 0x7d, 0x11, 0x65, 0x0b, 0x7c, 0xcd, 0x41, 0xcc, 0x9e, 0x41, 0x0c, 0x5e, 0x69, 0xd2, 0x16, 0x95, 0x71, 0xfe, 0xa3, 0x05, 0x41, 0xac, 0xaa, 0x63, 0xa3, 0x25, 0x1e, 0x3a, 0xa8, 0xf8, 0x59, 0x62, 0x42, 0x98, 0x0c, 0x42, 0xdc, 0x12, 0xe6, 0xaf, 0xe3, 0x35, 0x58, 0xba, 0x37, 0x02, 0x6d, 0xd0, 0xff, 0xa8, 0xfd, 0x25, 0x31, 0x29, 0x6c, 0xa9, 0x81, 0xa4, 0x24, 0x9c, 0x65, 0x3e, 0x2e, 0x4f, 0xcb, 0x9f, 0x3e, 0x12, 0x13, 0xf6, 0x52, 0x79, 0x38, 0xbf, 0x74, 0xae, 0x13, 0x7f, 0xa1, 0x4b, 0x90, 0xd6, 0x9e, 0x3d, 0x0e, 0xa5, 0x66, 0xea, 0xa7, 0xe8, 0x72, 0xcb, 0xb5, 0x2f, 0x62, 0xc0, 0xa7, 0xb2, 0xe4, 0x83, 0xfd, 0x9d, 0xcc, 0xb7, 0x1d, 0x44, 0x65, 0x78, 0x44, 0x4d, 0x97, 0x83, 0x38, 0xcc, 0xc2, 0x62, 0x8e, 0x4b, 0x4f, 0x98, 0x12, 0x69, 0x53, 0x1e, 0x4d, 0x4c, 0x86, 0xf5, 0x4f, 0x1a, 0x2c, 0x8c, 0x70, 0x9f, 0x4e, 0x75, 0x8e, 0x46, 0x96, 0xcd, 0xe0, 0x90, 0xcc, 0x8e, 0xa4, 0x8a, 0x5a, 0x1f, 0xe3, 0x4b, 0x9e, 0xa0, 0xfc, 0xc8, 0xb8, 0xa3, 0x7e, 0xc8, 0x11, 0xde, 0x62, 0xa9, 0xfe, 0xe0, 0x01, 0x79, 0x92, 0x00, 0x87, 0xef, 0x51, 0xd2, 0x73, 0x50, 0xaa, 0xad, 0xd6, 0x82, 0x50, 0x83, 0xda, 0x93, 0x96, 0xc5, 0x51, 0x21, 0x7e, 0xe3, 0x9d, 0x86, 0x1c, 0xbb, 0xdb, 0xca, 0x6a, 0x38, 0x32, 0xf9, 0x55, 0x63, 0x97, 0x44, 0x4f, 0x2e, 0xf9, 0x07, 0x43, 0x9e, 0x88, 0x25, 0x6a, 0xa5, 0x1f, 0x75, 0xdc, 0x5b, 0xd0, 0xbf, 0x24, 0x6d, 0xd7, 0x02, 0x6c, 0x82, 0x8b, 0x5f, 0x3b, 0xfc, 0x0d, 0xf4, 0x3a, 0xa5, 0x94, 0x36, 0x07, 0xe2, 0x07, 0x9f, 0x7e, 0xed, 0xb7, 0xc7, 0x3c, 0x9c, 0xdc, 0xbb, 0xd6, 0xa7, 0x8b, 0x1c, 0x8f, 0x1f, 0x26, 0x3d, 0x40, 0x87, 0xfe, 0x2b, 0xa8, 0xf4, 0x1e, 0x84, 0x7c, 0x48, 0xd7, 0xb1, 0xdf, 0xdb, 0xda, 0x8c, 0xa5, 0xea, 0xca, 0xa1, 0xe5, 0xc6, 0x54, 0x57, 0x15, 0x3f, 0xc5, 0x7b, 0xea, 0xc4, 0x58, 0x44, 0x81, 0xa1, 0xdc, 0x8d, 0x98, 0x09, 0x1c, 0xb2, 0x4f, 0xdf, 0x0a, 0x14, 0xb5, 0xfd, 0x34, 0x56, 0x8f, 0x33, 0xd7, 0xbb, 0x28, 0xa1, 0x29, 0x81, 0x53, 0xcb, 0xb7, 0x67, 0xd9, 0x78, 0x3e, 0x46, 0xd6, 0x64, 0x0b, 0x0c, 0x84, 0xc4, 0xb5, 0x65, 0xf9, 0x9f, 0x0e, 0x45, 0x2a, 0x2d, 0xbd, 0x92, 0x63, 0x61, 0x8e, 0xab, 0xb9, 0x22, 0x7e, 0x89, 0x77, 0x1a, 0x47, 0x92, 0x87, 0x77, 0xaf, 0xf7, 0x39, 0x2c, 0x52, 0x55, 0xf8, 0xab, 0xa8, 0x29, 0x18, 0xc4, 0xd3, 0xad, 0x9a, 0x1d, 0x2f, 0x8f, 0x0e, 0xdc, 0x1a, 0x06, 0x39, 0xcf, 0xec, 0x1a, 0xca, 0xde, 0x77, 0x43, 0x04, 0xe2, 0x05, 0xac, 0x6a, 0xa0, 0x0c, 0x51, 0x6c, 0x33, 0x4f, 0xa1, 0xdc, 0x7d, 0x28, 0x08, 0x90, 0x2f, 0x7d, 0x7a, 0x46, 0x21, 0x77, 0x7c, 0xcf, 0x19, 0x0e, 0x9e, 0xbb, 0xbf, 0xe6, 0x3b, 0x7c, 0x05, 0xf1, 0x89, 0xb3, 0x93, 0x90, 0x44, 0xa5, 0xe0, 0x39, 0x73, 0x88, 0x16, 0x0f, 0x99, 0xaf, 0x3b, 0x31, 0x81, 0x05, 0x52, 0x09, 0x46, 0x9e, 0x95, 0xe9, 0xf0, 0x86, 0x78, 0xc9, 0x18, 0x54, 0x9d, 0xe8, 0xfc, 0x3d, 0x0f, 0x77, 0x06, 0xc1, 0x6b, 0xf6, 0x8d, 0x67, 0x77, 0x1d, 0xb3, 0xd3, 0x6e, 0x1f, 0x25, 0x9e, 0x27, 0x5f, 0x35, 0x70, 0x52, 0x24, 0xde, 0xed, 0x3c, 0x5a, 0x35, 0xf1, 0x63, 0xe9, 0xc7, 0x58, 0xdb, 0x5f, 0xcc, 0x46, 0x25, 0xe1, 0xb7, 0x89, 0xfe, 0x81, 0xf1, 0x19, 0x65, 0x0d, 0xc7, 0xcf, 0xf0, 0x79, 0x33, 0xcd, 0xbf, 0xd0, 0xdd, 0x2c, 0xdd, 0xdc, 0x7d, 0x68, 0x66, 0x91, 0x51, 0x26, 0x76, 0x6d, 0x8e, 0xe0, 0xe1, 0x3f, 0xdc, 0xc9, 0xc0, 0xe9, 0x75, 0x50, 0x74, 0x23, 0x28, 0xd9, 0x55, 0x16, 0x53, 0xd8, 0x6c, 0xfe, 0xc8, 0xaa, 0x27, 0x0f, 0xd6, 0x46, 0x33, 0xde, 0x0c, 0xa1, 0x49, 0x57, 0xb5, 0xe9, 0x04, 0xc9, 0xc1, 0xfc, 0x4b, 0x10, 0x5b, 0x41, 0x92, 0xa9, 0x66, 0xda, 0x9a, 0x45, 0xf3, 0x57, 0x47, 0x43, 0x32, 0x64, 0xe2, 0xe9, 0x19, 0x2d, 0x53, 0xff, 0xae, 0x3f, 0x69, 0xc3, 0x14, 0x83, 0xdd, 0x2a, 0xdc, 0xc2, 0xeb, 0x2c, 0x9e, 0x2c, 0x26, 0x2b, 0x0b, 0x70, 0x57, 0xe8, 0x47, 0x6a, 0x83, 0xce, 0xf3, 0x3d, 0xda, 0xbf, 0x8c, 0x1f, 0x87, 0x67, 0xfa, 0x38, 0xaf, 0x57, 0xa8, 0x3d, 0x24, 0x1d, 0xf7, 0xf1, 0x82, 0x93, 0x8f, 0x6a, 0xed, 0x97, 0x60, 0xef, 0x10, 0x61, 0x8a, 0x5d, 0x17, 0x58, 0x5e, 0x4d, 0x2d, 0x4a, 0x61, 0x48, 0xc1, 0x1d, 0x17, 0x3e, 0x8c, 0x97, 0x24, 0xb8, 0x8e, 0xfc, 0xba, 0x47, 0x96, 0x52, 0x18, 0xec, 0xf9, 0xec, 0xa9, 0x32, 0x26, 0xe2, 0xe9, 0xb8, 0x59, 0xc7, 0xf2, 0x8b, 0xc7, 0x11, 0xf7, 0x76, 0x64, 0x63, 0x5a, 0x2a, 0x55, 0xef, 0x3b, 0xf2, 0x78, 0x50, 0x44, 0x03, 0xfe, 0xa3, 0xcb, 0x5b, 0xac, 0x9a, 0x2c, 0xef, 0x5f, 0x73, 0x08, 0x4b, 0xac, 0x63, 0x2b, 0xe7, 0x2f, 0x9a, 0x4a, 0x6f, 0xab, 0x1f, 0x53, 0x70, 0xea, 0x58, 0xa3, 0x1f, 0xbe, 0xbb, 0x7e, 0x11, 0xf7, 0x46, 0x0e, 0xfe, 0xe7, 0x7e, 0xd1, 0xfe, 0x88, 0xa1, 0x6e, 0x8a, 0x3e, 0xff, 0x9d, 0xda, 0xf0, 0x57, 0xbb, 0x41, 0xbf, 0xdd, 0x79, 0x0d, 0x47, 0x98, 0x23, 0x11, 0xa3, 0xea, 0x6d, 0x6b, 0x32, 0x70, 0x5f, 0x1a, 0xf5, 0xfc, 0x03, 0x2f, 0xc1, 0x52, 0x2d, 0xab, 0xb4, 0xb4, 0xb9, 0x2f, 0x53, 0x99, 0x3c, 0x93, 0xbe, 0xa3, 0x69, 0x17, 0x91, 0x89, 0x1b, 0xa6, 0x25, 0x9f, 0x84, 0x3e, 0xb5, 0x32, 0x41, 0xaa, 0x2a, 0x7c, 0x09, 0xde, 0xc2, 0xd6, 0xf6, 0x06, 0x99, 0xf2, 0x4e, 0x49, 0x26, 0x0c, 0x75, 0x39, 0x4d, 0x10, 0x41, 0x86, 0x70, 0xc6, 0xa6, 0x92, 0xfc, 0xe1, 0x84, 0xd2, 0xcb, 0xe2, 0x9c, 0x82, 0x62, 0x3c, 0x24, 0xa4, 0x62, 0xc4, 0xbe, 0xfb, 0xc4, 0xdc, 0xde, 0xa3, 0x89, 0x53, 0x26, 0x25, 0xdf, 0x7e, 0x53, 0x6f, 0x57, 0xca, 0x62, 0x22, 0x18, 0xe6, 0xde, 0x87, 0x31, 0x3b, 0x6f, 0x2b, 0x2f, 0xb0, 0x95, 0xc6, 0xa9, 0x36, 0xcf, 0x51, 0x40, 0xd5, 0xe6, 0x9d, 0xeb, 0x9f, 0x5b, 0x9e, 0x82, 0x47, 0xb9, 0x17, 0xdf, 0x94, 0x1e, 0x0c, 0x85, 0x48, 0xd3, 0x00, 0x7d, 0x3a, 0xe0, 0x45, 0xd2, 0xe7, 0x96, 0x27, 0xb6, 0xc5, 0x88, 0x0b, 0x3b, 0x52, 0xcc, 0xa7, 0xbf, 0x0b, 0x20, 0xa5, 0x84, 0x12, 0x29, 0xc9, 0xd9, 0xec, 0xd1, 0xd4, 0x05, 0x4d, 0x38, 0x96, 0x3e, 0x9e, 0xaa, 0x53, 0x85, 0xe2, 0x5f, 0x1c, 0x43, 0xce, 0x88, 0xb1, 0x49, 0x6a, 0x64, 0xc4, 0x11, 0x91, 0x4a, 0x06, 0xac, 0x4c, 0xe7, 0x03, 0x5b, 0x44, 0xf3, 0xbd, 0x9c, 0x7a, 0x56, 0xb5, 0xef, 0x98, 0x18, 0xa9, 0xbf, 0xb9, 0xb9, 0x7d, 0x16, 0xb8, 0x21, 0xe5, 0x2d, 0xfc, 0xb0, 0x16, 0x69, 0x6c, 0x81, 0x59, 0xf0, 0xcd, 0xd3, 0x2b, 0x0c, 0x5a, 0x8b, 0x5b, 0xa7, 0x38, 0x21, 0x85, 0x96, 0xd3, 0x43, 0xdf, 0xb3, 0x81, 0xde, 0xa2, 0x4a, 0x23, 0xb3, 0x95, 0x46, 0x41, 0x9c, 0x24, 0x76, 0x27, 0xe6, 0xc2, 0x8e, 0x52, 0xe9, 0xe5, 0x86, 0x0a, 0x0d, 0x45, 0x2f, 0x70, 0x6e, 0x9d, 0xcb, 0x3a, 0x70, 0xaa, 0xf4, 0xd8, 0xbf, 0xe1, 0x94, 0x95, 0x60, 0x4f, 0x11, 0x04, 0x0f, 0x23, 0x31, 0x1a, 0x35, 0x20, 0xe1, 0x3d, 0x2b, 0xf2, 0x6f, 0xfd, 0x7e, 0x25, 0x88, 0xd7, 0xdf, 0x25, 0x3e, 0x3c, 0x90, 0x09, 0xd3, 0x9b, 0x08, 0xbe, 0x5e, 0x23, 0x9a, 0x8f, 0xdc, 0x0a, 0xda, 0x7f, 0x00, 0xa3, 0xb2, 0x80, 0x86, 0xc4, 0x2d, 0x01, 0xbd, 0x50, 0x13, 0x28, 0xe3, 0xae, 0x87, 0x19, 0x71, 0xcc, 0x31, 0xdd, 0x7a, 0x81, 0x40, 0x55, 0x66, 0x54, 0xa3, 0x9b, 0x30, 0x19, 0x69, 0x91, 0xa0, 0xd6, 0x4c, 0xaa, 0x60, 0xf3, 0x28, 0xce, 0x86, 0xc3, 0xee, 0xff, 0x52, 0xcf, 0x97, 0x2e, 0x41, 0x6f, 0x35, 0xfe, 0x2f, 0x6b, 0x56, 0x51, 0x15, 0x68, 0x53, 0xbc, 0xab, 0xb6, 0xd0, 0x88, 0x80, 0x57, 0x75, 0x4b, 0x87, 0x3e, 0x15, 0x73, 0xba, 0x3c, 0xa8, 0xc7, 0x5b, 0x7a, 0xec, 0x56, 0xf2, 0x56, 0x6d, 0x8d, 0x62, 0x86, 0xeb, 0x9e, 0x8f, 0x50, 0x85, 0xd2, 0x1c, 0xd7, 0xeb, 0x37, 0xeb, 0x96, 0xc1, 0x11, 0xbd, 0xcd, 0xf7, 0xf0, 0xbf, 0x9e, 0xba, 0xaf, 0x66, 0xe1, 0x64, 0x06, 0x4e, 0x6b, 0x48, 0x31, 0xd8, 0x06, 0x8b, 0x5c, 0x14, 0x33, 0x47, 0x78, 0xab, 0xd0, 0x56, 0x52, 0xd2, 0xf1, 0x0f, 0xc0, 0x12, 0xd2, 0x07, 0x8f, 0xe7, 0xe9, 0x85, 0x6f, 0x17, 0x6d, 0xa5, 0x7e, 0xdf, 0xff, 0xd1, 0xb8, 0x12, 0x74, 0x0d, 0xf6, 0xd2, 0xcb, 0xc3, 0xae, 0x8c, 0x3a, 0x5e, 0xcf, 0x46, 0x6f, 0xb3, 0xc1, 0xfb, 0x87, 0xcd, 0x8c, 0x93, 0xf3, 0x10, 0x90, 0x2a, 0xea, 0x9d, 0x92, 0x38, 0x75, 0x07, 0x91, 0x7b, 0x5b, 0x5d, 0x64, 0x32, 0x63, 0x28, 0x58, 0xbf, 0x5c, 0xb4, 0x53, 0x6c, 0x1a, 0xcc, 0x95, 0xbb, 0x54, 0xb0, 0x81, 0x0a, 0xb8, 0x65, 0xf2, 0x71, 0x66, 0xa7, 0x84, 0x71, 0x20, 0x5b, 0x6c, 0x0e, 0x1b, 0xeb, 0x4d, 0xe0, 0xbd, 0x72, 0xa8, 0x9a, 0x6f, 0x6a, 0x44, 0x6d, 0xcc, 0x13, 0xdf, 0x5b, 0x76, 0xd8, 0x54, 0x0d, 0xee, 0xc9, 0xdd, 0x48, 0x1f, 0x80, 0xb2, 0x22, 0x20, 0xb7, 0xc4, 0x3a, 0x91, 0x34, 0x06, 0x97, 0xc2, 0xbb, 0xe8, 0x5f, 0x30, 0x4e, 0x3a, 0x2a, 0xb7, 0x26, 0xe8, 0x7e, 0xb9, 0xfc, 0x84, 0x04, 0x6e, 0xab, 0x93, 0x92, 0xd6, 0x18, 0xfc, 0x51, 0x52, 0x8d, 0x84, 0x45, 0x71, 0x0a, 0x6f, 0x38, 0x37, 0x40, 0x94, 0xc9, 0xbc, 0xa3, 0x87, 0x50, 0xaa, 0x3b, 0x76, 0xab, 0xb4, 0xc3, 0xa4, 0xf4, 0xa6, 0x07, 0xfe, 0x15, 0xac, 0x81, 0x31, 0x4b, 0xfa, 0xcb, 0x5e, 0xa1, 0xb3, 0x3a, 0x77, 0xc9, 0x85, 0xd8, 0xa7, 0x34, 0xf5, 0xf1, 0x06, 0x99, 0x20, 0x05, 0x50, 0xeb, 0x6d, 0x67, 0x2c, 0x51, 0xb8, 0x21, 0xe3, 0x79, 0x40, 0x18, 0x83, 0xbf, 0xa5, 0xe2, 0x9e, 0xb2, 0x9e, 0xc6, 0x58, 0x8d, 0xb6, 0x4b, 0xa8, 0xa6, 0x86, 0x16, 0xcb, 0x8f, 0x67, 0x00, 0xa5, 0x5c, 0x45, 0xdd, 0x46, 0x7b, 0xb3, 0x34, 0xd7, 0x55, 0x63, 0xfc, 0x2a, 0x3f, 0x6d, 0x24, 0xda, 0xd0, 0xf1, 0x5c, 0xe5, 0xbc, 0x80, 0xce, 0x09, 0x4d, 0xcf, 0x96, 0x6e, 0xfb, 0xb1, 0x69, 0xcd, 0xbb, 0x8e, 0x12, 0xfc, 0xb0, 0xe7, 0x39, 0xaf, 0xe8, 0x04, 0xea, 0x2a, 0xbd, 0x11, 0x2e, 0x14, 0xa8, 0x6b, 0x87, 0x4a, 0xe8, 0xda, 0xd2, 0xd2, 0xc1, 0x3b, 0x35, 0x9b, 0x25, 0xb2, 0x18, 0x23, 0xd4, 0xb6, 0xb6, 0x33, 0x53, 0x34, 0xbc, 0xb6, 0x3f, 0x25, 0xc5, 0x68, 0x1f, 0xe7, 0xcb, 0x1e, 0x1e, 0xeb, 0x33, 0x80, 0x7f, 0xa2, 0x29, 0x3e, 0xa7, 0xb6, 0xfb, 0x02, 0xfe, 0x71, 0xbc, 0x9a, 0x4d, 0x22, 0x9c, 0x7e, 0x4f, 0x7d, 0xe3, 0x9e, 0x5e, 0x19, 0x20, 0xf1, 0x59, 0x71, 0xd8, 0x23, 0x58, 0xbb, 0xd1, 0x04, 0x9e, 0xdf, 0x0d, 0x4b, 0x72, 0x94, 0x7c, 0xb4, 0x41, 0xbe, 0x64, 0x2d, 0x88, 0x5d, 0x2e, 0x29, 0x08, 0x96, 0xcf, 0xb8, 0xa9, 0x38, 0x2d, 0x84, 0x7f, 0xec, 0xa8, 0xf3, 0x54, 0x4d, 0x36, 0xc8, 0x3a, 0x3c, 0x3a, 0x3d, 0xdb, 0x60, 0xf7, 0x2e, 0x08, 0x19, 0xd4, 0x6a, 0xe8, 0x12, 0xb5, 0x75, 0x2b, 0xd1, 0xaa, 0xc5, 0xea, 0xd8, 0x75, 0x2e, 0xe0, 0x61, 0x25, 0xc9, 0x86, 0x92, 0x07, 0x6f, 0x7d, 0x4f, 0xd4, 0xda, 0x0c, 0x47, 0xa0, 0xbf, 0xb4, 0x08, 0x97, 0xe5, 0xb1, 0x4c, 0x3a, 0xac, 0xd3, 0xc4, 0xec, 0x5c, 0x2a, 0x6e, 0x3d, 0xb3, 0xf8, 0xf0, 0x7b, 0xdf, 0x02, 0xfa, 0xd9, 0x03, 0x10, 0x96, 0x52, 0x3b, 0xa7, 0x96, 0x51, 0x52, 0x87, 0xb1, 0x28, 0xf8, 0xd6, 0x74, 0x62, 0xa4, 0xfc, 0xa4, 0xd0, 0x5a, 0xbe, 0x9e, 0x9d, 0x72, 0x10, 0x92, 0xac, 0x85, 0x34, 0xfd, 0xcc, 0x1d, 0x1a, 0x37, 0xc7, 0xb0, 0x1e, 0xc2, 0xcc, 0x81, 0x85, 0x7b, 0x21, 0x97, 0xa1, 0x7e, 0x9a, 0xe4, 0x6d, 0x62, 0x93, 0x26, 0xcd, 0x19, 0xfc, 0x81, 0x36, 0xe9, 0x8f, 0x7a, 0x36, 0xd9, 0x22, 0x6e, 0x35, 0x1a, 0xae, 0x5f, 0xfb, 0x9d, 0xf1, 0xf3, 0x19, 0x40, 0x40, 0x4f, 0xab, 0xb7, 0xe2, 0xe7, 0x6e, 0x23, 0xe6, 0x11, 0xa1, 0x87, 0x13, 0x1d, 0x9b, 0xc0, 0x21, 0x9c, 0x7c, 0x6a, 0xfb, 0x5b, 0xc0, 0x53, 0x07, 0x09, 0xd0, 0x57, 0xa6, 0x82, 0xe8, 0x64, 0x61, 0x4b, 0x7c, 0x01, 0xa7, 0x58, 0xfe, 0xd8, 0x7a, 0x0d, 0x05, 0xf1, 0xda, 0xc3, 0x40, 0xf7, 0x3a, 0xd5, 0x8e, 0xba, 0xae, 0xe2, 0x5c, 0xf6, 0x4b, 0x13, 0x09, 0xba, 0x99, 0xb4, 0x97, 0x4d, 0x69, 0xd2, 0x8b, 0x94, 0x5d, 0x2d, 0x15, 0x60, 0xad, 0xb0, 0x4e, 0xfc, 0x07, 0xef, 0x0d, 0xb5, 0x4a, 0x84, 0x59, 0x2d, 0xb9, 0x53, 0x9e, 0x3c, 0x89, 0xbb, 0x24, 0x77, 0x88, 0x63, 0x88, 0xa4, 0x2f, 0x11, 0x5d, 0x7c, 0xd4, 0xd0, 0xf5, 0x89, 0x39, 0xc1, 0x95, 0xde, 0x39, 0x40, 0x53, 0xd6, 0xff, 0x46, 0x17, 0x83, 0x27, 0x94, 0x33, 0xb6, 0xb9, 0x0c, 0xe8, 0x28, 0xb0, 0xc9, 0xc7, 0x96, 0x3e, 0xdd, 0xb9, 0x64, 0x9d, 0xee, 0x99, 0x59, 0x88, 0x59, 0xfe, 0x99, 0x3e, 0xaa, 0xd8, 0xaf, 0x62, 0x6e, 0xb9, 0xc9, 0xb1, 0x86, 0x5a, 0xba, 0xa7, 0x9a, 0xbf, 0xf7, 0x58, 0xff, 0xb1, 0xe2, 0x6d, 0x31, 0x7f, 0x3a, 0xde, 0x51, 0x95, 0x4e, 0x60, 0x9b, 0x53, 0x29, 0x83, 0xd3, 0x8e, 0xf2, 0x47, 0x6f, 0x86, 0x99, 0x89, 0xfb, 0x7d, 0x3b, 0x6d, 0x85, 0xe0, 0xb0, 0x32, 0x0b, 0x26, 0xcb, 0x5f, 0xb8, 0xc7, 0x2d, 0x57, 0xe1, 0xe2, 0x44, 0x81, 0x0a, 0x0b, 0xd4, 0x21, 0x0b, 0x4d, 0x68, 0xfe, 0x31, 0x21, 0x25, 0x8e, 0xfc, 0x38, 0xe2, 0x69, 0x32, 0x67, 0xff, 0x43, 0xbd, 0xc3, 0x7e, 0x3c, 0x0d, 0x7f, 0x6a, 0x70, 0x31, 0x9b, 0x41, 0x45, 0xa9, 0x53, 0x1a, 0x62, 0xa2, 0xaf, 0x03, 0x45, 0xe2, 0xf4, 0x13, 0x04, 0x47, 0xf9, 0x52, 0x05, 0xf5, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x02, 0xe4, 0x61, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbd, 0x07, 0xec, 0x81, 0x00, 0x00, 0x20, 0xa4, 0x0f, 0x2b, 0x24, 0x82, 0x3a, 0x10, 0xf0, 0xcc, 0x73, 0x05, 0x2a, 0x3a, 0x68, 0xdc, 0xd3, 0x1b, 0x96, 0x77, 0x74, 0x51, 0x86, 0x4d, 0xd8, 0x66, 0x59, 0xd5, 0xa6, 0x31, 0x22, 0x48, 0x96, 0x55, 0x98, 0xd0, 0xb6, 0x5b, 0x1a, 0xbd, 0xe4, 0x97, 0x27, 0x3a, 0xc8, 0x39, 0x64, 0x7b, 0x1e, 0x6e, 0x84, 0x92, 0x38, 0xff, 0xb6, 0xcf, 0xc8, 0x4f, 0x4c, 0x47, 0xd3, 0xea, 0x8b, 0xa4, 0xcd, 0xa4, 0x17, 0x8c, 0x14, 0x2e, 0xb2, 0xec, 0x18, 0x3f, 0xa6, 0x6c, 0x8c, 0xae, 0x93, 0x1a, 0x26, 0xd6, 0x5f, 0x7e, 0x1d, 0x88, 0x40, 0x81, 0x85, 0xf9, 0x14, 0x70, 0xf3, 0xbf, 0xd6, 0x4a, 0xdd, 0x90, 0x51, 0x88, 0x0e, 0x90, 0x89, 0x9c, 0x95, 0xec, 0x3c, 0xa1, 0xeb, 0xb6, 0x52, 0x30, 0x3c, 0xd1, 0x0f, 0xb8, 0xf3, 0xbf, 0x42, 0x87, 0x98, 0x0b, 0xad, 0xdf, 0xe7, 0x07, 0x6c, 0x05, 0xf5, 0xd8, 0xb8, 0xce, 0x4e, 0xdc, 0xa9, 0xb2, 0x7d, 0xeb, 0xc1, 0x1d, 0xae, 0x82, 0xbe, 0x15, 0x4a, 0x72, 0xb6, 0x15, 0x0f, 0x75, 0x93, 0xb7, 0x59, 0x4e, 0x22, 0x9e, 0x62, 0xab, 0x81, 0xc7, 0xb0, 0xa9, 0xb7, 0xbb, 0x8c, 0x45, 0x3d, 0x04, 0xcc, 0x1f, 0x15, 0x1a, 0xef, 0x5b, 0x89, 0x77, 0x87, 0xfb, 0x61, 0x91, 0x5d, 0x96, 0x2a, 0x28, 0x39, 0xd4, 0xa2, 0xfc, 0xfa, 0x5b, 0x74, 0x93, 0x30, 0x6c, 0x74, 0x50, 0x2b, 0x26, 0x25, 0xd2, 0xdb, 0xf2, 0xa8, 0xcf, 0xa1, 0x67, 0xe8, 0x63, 0x0e, 0xd8, 0x56, 0xbc, 0x2b, 0xa7, 0x7e, 0x78, 0xa8, 0xaf, 0xe0, 0xf2, 0x04, 0xed, 0xe2, 0xdd, 0xfb, 0xf2, 0x8a, 0x04, 0xf9, 0xdf, 0xba, 0x0e, 0x42, 0x2b, 0xaf, 0xeb, 0xca, 0x17, 0x36, 0x67, 0x5b, 0xf3, 0x93, 0x23, 0x64, 0xeb, 0x9e, 0xd0, 0x3e, 0x51, 0x5d, 0xb7, 0x18, 0x4e, 0x09, 0x2a, 0x91, 0x80, 0xca, 0x73, 0x3b, 0x3f, 0xd6, 0x8e, 0x40, 0xa1, 0x74, 0xd0, 0x03, 0xed, 0xdd, 0x99, 0xe3, 0x87, 0x30, 0x54, 0x65, 0xe8, 0x8b, 0x32, 0x1e, 0xff, 0xa2, 0x1e, 0x25, 0xe7, 0x96, 0xfc, 0xe1, 0xb4, 0x1c, 0xfc, 0x0d, 0x41, 0x48, 0xda, 0x8a, 0x5a, 0x4a, 0x43, 0x50, 0xe6, 0x8b, 0xfb, 0x41, 0xcc, 0xa5, 0xbc, 0x38, 0xc1, 0xc0, 0x8e, 0x11, 0x8d, 0x5f, 0xd9, 0x60, 0x8f, 0x7c, 0xb8, 0x86, 0x51, 0xdc, 0x07, 0x0a, 0xfc, 0x06, 0x48, 0xb4, 0x4b, 0xe2, 0x25, 0x1f, 0x89, 0xd0, 0xcd, 0xcf, 0x92, 0x60, 0xf9, 0x63, 0x31, 0xb1, 0x2b, 0x7c, 0x86, 0x7a, 0xb0, 0x7d, 0x4d, 0x4d, 0x9a, 0xb6, 0x67, 0xa5, 0x48, 0x02, 0x04, 0x53, 0x13, 0x4d, 0x44, 0x86, 0x0d, 0x3d, 0xc0, 0x8b, 0x86, 0x36, 0xfd, 0x50, 0x98, 0x42, 0x18, 0x2f, 0xe3, 0x48, 0x01, 0xed, 0xd8, 0xbf, 0x68, 0x42, 0xde, 0x08, 0xe2, 0xe0, 0xb0, 0x9d, 0x81, 0x05, 0x4b, 0x5b, 0x4d, 0xcc, 0xa4, 0x14, 0xf8, 0x09, 0x73, 0x62, 0xaa, 0x83, 0x27, 0x49, 0x67, 0x75, 0x61, 0xae, 0x6a, 0xa3, 0xf6, 0xa1, 0x87, 0x45, 0x9f, 0x29, 0x99, 0xa5, 0xba, 0x4c, 0x07, 0x5d, 0xb1, 0x42, 0x49, 0x68, 0x94, 0xb8, 0xf9, 0xa0, 0x3c, 0x89, 0xc7, 0x09, 0xa5, 0x0e, 0x62, 0xa6, 0x33, 0xd0, 0x79, 0xf3, 0xd4, 0xc2, 0x72, 0xcb, 0x6b, 0x97, 0xa8, 0x83, 0x92, 0xa1, 0x43, 0xc2, 0x26, 0x50, 0x48, 0xd0, 0x2f, 0x63, 0x5f, 0xff, 0x46, 0xac, 0x7b, 0xe0, 0xe6, 0x4d, 0x8a, 0x2f, 0xb6, 0xf0, 0xfc, 0x58, 0x06, 0xde, 0x5e, 0x42, 0xef, 0x15, 0x74, 0x8b, 0xc4, 0x9e, 0x32, 0x97, 0x19, 0x15, 0x9f, 0x7d, 0x3f, 0xe9, 0xe7, 0x0d, 0x47, 0xd3, 0x6b, 0xad, 0xaf, 0x58, 0x02, 0x5a, 0xd0, 0xb5, 0xa9, 0x94, 0xd8, 0xd4, 0xae, 0xb1, 0xab, 0x93, 0x0f, 0x1b, 0xb4, 0xcb, 0xf7, 0x13, 0x2e, 0x25, 0x80, 0x61, 0x32, 0x47, 0x7c, 0x5a, 0xfa, 0x08, 0x9b, 0x65, 0x42, 0xaf, 0xec, 0x65, 0xaf, 0x7d, 0xb3, 0x87, 0x04, 0xc2, 0x35, 0xb0, 0x23, 0xa4, 0x54, 0xfc, 0xb6, 0x9f, 0x9b, 0xa8, 0xfb, 0x21, 0x6f, 0x51, 0x57, 0x00, 0xb8, 0x9a, 0x48, 0x53, 0x18, 0x69, 0xc1, 0xdc, 0x12, 0x4b, 0xb5, 0x87, 0x3a, 0x5f, 0x48, 0x8f, 0x43, 0xfd, 0x67, 0x51, 0x24, 0x8b, 0xd9, 0xf5, 0xc8, 0xfd, 0xa2, 0x99, 0xac, 0xbd, 0x46, 0x5d, 0x8e, 0xa7, 0xe4, 0x40, 0x2b, 0x27, 0x77, 0x63, 0x3a, 0xbe, 0x03, 0xaf, 0x73, 0x3e, 0xdc, 0xae, 0x6f, 0xea, 0xf0, 0xe2, 0xa0, 0xc5, 0x81, 0xd5, 0x77, 0x72, 0x19, 0x2b, 0x3c, 0x1c, 0xc1, 0xd3, 0xf4, 0xda, 0xf1, 0x6b, 0xbc, 0x3a, 0xd9, 0x0b, 0x8f, 0x28, 0xaa, 0x50, 0x49, 0x0b, 0xda, 0x3f, 0x53, 0x40, 0xf3, 0x73, 0x4e, 0x41, 0x98, 0x96, 0x67, 0x0a, 0xc4, 0x98, 0xd6, 0x1d, 0xae, 0x57, 0xbe, 0x82, 0x77, 0x87, 0x5d, 0xb5, 0xfe, 0x90, 0xe0, 0xd6, 0x85, 0x34, 0x6d, 0x78, 0xf0, 0x7e, 0xba, 0xed, 0x2b, 0xf2, 0xb7, 0xe4, 0x00, 0xee, 0x6e, 0xd2, 0x57, 0x6b, 0xbc, 0xcd, 0x31, 0x20, 0xbd, 0xbe, 0x8f, 0xc4, 0x8a, 0x34, 0x8b, 0x50, 0xfe, 0x7d, 0x3a, 0x57, 0xf1, 0x75, 0x69, 0xa6, 0xdd, 0xf3, 0xae, 0x77, 0x14, 0x98, 0x25, 0x9b, 0xe0, 0x11, 0x68, 0x66, 0xa7, 0xbf, 0xc7, 0x0e, 0xb3, 0x75, 0xd5, 0x2b, 0x44, 0x27, 0xd6, 0x9c, 0x7f, 0x32, 0x9c, 0x54, 0x3e, 0x1c, 0x6b, 0xa6, 0x20, 0x9d, 0xd8, 0xbf, 0x4b, 0xf1, 0x30, 0x48, 0x8b, 0x0a, 0x6d, 0x92, 0x21, 0x5c, 0xd3, 0x21, 0x0a, 0x25, 0x54, 0x3b, 0xa0, 0x15, 0xc8, 0x73, 0xf5, 0x38, 0xce, 0xff, 0x96, 0xf9, 0xbb, 0xbb, 0x3e, 0x9b, 0xba, 0x08, 0x24, 0xcd, 0x14, 0x77, 0x2e, 0xc6, 0x3e, 0x2d, 0x30, 0x19, 0x2c, 0xd5, 0x6a, 0x1e, 0x6d, 0x16, 0x78, 0xa8, 0x9b, 0xca, 0x44, 0x51, 0x74, 0x3b, 0x0e, 0x76, 0x07, 0xf1, 0x81, 0x8f, 0x43, 0x44, 0xf1, 0xf5, 0xab, 0x6e, 0x0a, 0x9b, 0xbb, 0xf7, 0xf6, 0xfb, 0xba, 0x2a, 0x9e, 0xc3, 0xa4, 0xc6, 0x9b, 0x78, 0x6c, 0x01, 0x37, 0x9b, 0x45, 0x2d, 0xee, 0x70, 0x32, 0xd8, 0x29, 0x98, 0xcb, 0x92, 0x42, 0x12, 0x2d, 0x31, 0x1d, 0xd5, 0x39, 0xa3, 0xac, 0x1e, 0x79, 0xb6, 0x54, 0x15, 0x97, 0x8b, 0xa2, 0x82, 0x12, 0xbc, 0xc6, 0x0c, 0x94, 0xcd, 0xcc, 0xe4, 0xb6, 0xda, 0x8d, 0x69, 0xe1, 0xa7, 0x65, 0x66, 0xad, 0x8d, 0xf1, 0x85, 0x6e, 0x1b, 0xd5, 0x9c, 0xf6, 0x45, 0x37, 0xd2, 0x8a, 0xc4, 0x3a, 0x80, 0x23, 0x3d, 0xa7, 0xa5, 0xa5, 0x92, 0x6a, 0xf7, 0x30, 0x06, 0x5f, 0xad, 0x19, 0x0f, 0x64, 0x2c, 0x37, 0xa5, 0xc1, 0xfb, 0xaa, 0x80, 0x6b, 0x71, 0xd8, 0x87, 0xb7, 0x11, 0x03, 0x66, 0x0b, 0x8c, 0xff, 0xc2, 0x16, 0x41, 0xe2, 0x5c, 0x6d, 0xdc, 0x0d, 0x51, 0x09, 0x9f, 0xae, 0xf7, 0x2a, 0xa8, 0x07, 0x91, 0xe4, 0x59, 0x9b, 0x32, 0xd8, 0x68, 0x50, 0x32, 0x99, 0x9f, 0x77, 0xe6, 0x91, 0xd5, 0x80, 0x33, 0xe7, 0xd8, 0x6d, 0xa9, 0xc9, 0xf2, 0xed, 0x7f, 0xd8, 0x15, 0x57, 0xd7, 0x5b, 0x4e, 0xa0, 0x9f, 0xee, 0x81, 0x8a, 0x3d, 0x6e, 0x51, 0x99, 0x3a, 0xdf, 0x33, 0xe3, 0x2b, 0xa2, 0x45, 0xd3, 0xb1, 0x4b, 0x77, 0x69, 0xcb, 0xee, 0x4a, 0xa8, 0x9d, 0x96, 0x8b, 0x97, 0x66, 0xd5, 0xd3, 0x11, 0xad, 0x7a, 0xd5, 0x3a, 0x45, 0x7b, 0x97, 0x00, 0x6f, 0x0f, 0x5b, 0x42, 0x78, 0x0d, 0xd8, 0xa6, 0xb1, 0xc7, 0xc1, 0xc0, 0x94, 0xe5, 0x2b, 0xcb, 0xc8, 0xea, 0x88, 0xa7, 0x9b, 0xf8, 0x6a, 0x6d, 0xfd, 0xf6, 0xf1, 0x05, 0x75, 0x59, 0xd1, 0xdf, 0xd5, 0xfc, 0xa2, 0x40, 0x48, 0x56, 0xba, 0x80, 0xc0, 0xac, 0x11, 0x32, 0x23, 0x4f, 0x36, 0xda, 0x8d, 0x14, 0x65, 0xdd, 0xda, 0x73, 0xcc, 0x04, 0x02, 0x8d, 0xc4, 0x66, 0xf1, 0x0b, 0x91, 0x65, 0xc7, 0xda, 0x5a, 0x42, 0x8a, 0x00, 0xbc, 0xf0, 0x96, 0x7a, 0xd8, 0x05, 0xd3, 0xe7, 0xa1, 0x16, 0xba, 0xbd, 0x2b, 0x38, 0x3d, 0x62, 0x76, 0xbf, 0x6e, 0x82, 0xdb, 0x56, 0xeb, 0x5c, 0x01, 0xd9, 0x58, 0x0d, 0x7e, 0x91, 0x33, 0xdd, 0x4c, 0x0c, 0x50, 0xcc, 0xdf, 0x7f, 0x11, 0x3a, 0x9a, 0x62, 0x21, 0xdb, 0x94, 0xe1, 0xdc, 0xbb, 0x86, 0x3f, 0x6d, 0x34, 0x42, 0x4b, 0xbb, 0x22, 0x4e, 0x1b, 0x7b, 0x6c, 0x75, 0x6f, 0x8c, 0xc0, 0xcf, 0x48, 0xe5, 0xc0, 0x53, 0xd5, 0x77, 0x2e, 0x58, 0x94, 0x36, 0x2c, 0xf0, 0xc8, 0x08, 0x55, 0xb2, 0xae, 0xec, 0x06, 0x8b, 0x1b, 0xa0, 0x51, 0x6f, 0x6b, 0xfa, 0x6f, 0xa0, 0x0a, 0xc5, 0x51, 0xf7, 0xe3, 0x21, 0x6d, 0x2b, 0x8c, 0x9d, 0x94, 0xe4, 0x9a, 0x26, 0xe5, 0x55, 0xdb, 0x35, 0xcf, 0x09, 0x8e, 0x2f, 0x59, 0x50, 0xa9, 0xd7, 0x4d, 0x92, 0xcf, 0x63, 0xfb, 0xc7, 0xe1, 0x41, 0xab, 0x1b, 0x77, 0xfe, 0xdc, 0xaf, 0x2e, 0x2a, 0x90, 0x50, 0x59, 0x73, 0x5b, 0x82, 0x34, 0x6a, 0xcd, 0xcf, 0x3c, 0x67, 0x3f, 0x1e, 0x8c, 0x02, 0xa0, 0x6b, 0xf2, 0xdb, 0x9e, 0xa3, 0xd0, 0xdd, 0xc2, 0x8b, 0x09, 0xf2, 0xb1, 0x17, 0x1c, 0x74, 0x38, 0x1e, 0xc1, 0xcf, 0x36, 0x25, 0x3d, 0x6f, 0x9c, 0x49, 0x79, 0x17, 0x73, 0xb6, 0x6f, 0x81, 0xf6, 0x65, 0xd7, 0xfa, 0xcd, 0x8a, 0x6f, 0x30, 0x42, 0x95, 0xf7, 0xa9, 0xa4, 0xeb, 0x4b, 0xae, 0x22, 0xab, 0x8b, 0x80, 0x38, 0x93, 0x5a, 0x63, 0x44, 0x61, 0x78, 0x54, 0xc6, 0x23, 0xe3, 0x47, 0xe6, 0x63, 0x23, 0x82, 0xb2, 0x53, 0x4b, 0x1b, 0xe2, 0x8f, 0xfe, 0x81, 0x21, 0xb4, 0xfd, 0x12, 0xb9, 0x4a, 0x84, 0x1c, 0xf8, 0x8a, 0xdd, 0x3c, 0xef, 0xef, 0x07, 0x35, 0x80, 0x90, 0x78, 0x03, 0x75, 0x46, 0xfb, 0x09, 0xf4, 0x18, 0x34, 0x70, 0x1c, 0xd8, 0xd7, 0x15, 0x30, 0xaa, 0x6e, 0x66, 0x1c, 0x2b, 0x62, 0x63, 0xd1, 0x28, 0x34, 0x37, 0x93, 0xb9, 0x83, 0x9f, 0x11, 0xae, 0xc5, 0x77, 0xdf, 0xf3, 0xdf, 0x2e, 0x22, 0x24, 0xf4, 0xe7, 0x3e, 0xb6, 0x14, 0x67, 0xc6, 0x4e, 0xae, 0x88, 0x19, 0xcb, 0x3a, 0x64, 0x34, 0xc8, 0xa2, 0xf6, 0xcb, 0x35, 0xc7, 0x93, 0x65, 0x65, 0xd7, 0xd9, 0x98, 0xa6, 0x93, 0xb1, 0xb7, 0xd3, 0xe0, 0xa9, 0x55, 0x02, 0x3f, 0xf9, 0x47, 0x01, 0x09, 0xa0, 0x92, 0xf0, 0x91, 0x98, 0xd4, 0x9b, 0xc8, 0xf1, 0x47, 0xf8, 0x19, 0x6b, 0x4c, 0xa0, 0x23, 0x67, 0xeb, 0xb5, 0xfa, 0x3b, 0xb1, 0x2b, 0xe0, 0xfb, 0x74, 0x7e, 0x3b, 0x58, 0x1a, 0xcf, 0x49, 0x24, 0xb0, 0x52, 0x44, 0x78, 0x8e, 0x06, 0xbf, 0x06, 0x4e, 0x3b, 0x24, 0x9f, 0x4c, 0x5a, 0x68, 0xd4, 0xef, 0x53, 0x4a, 0x4a, 0x85, 0x61, 0x7e, 0x45, 0x2d, 0x3f, 0x69, 0x2f, 0x6b, 0xa3, 0x2f, 0x24, 0x99, 0x9d, 0x45, 0x27, 0x71, 0xce, 0xd3, 0x2d, 0x9c, 0xa6, 0x7f, 0xd7, 0x74, 0x7a, 0x16, 0xd8, 0x07, 0x05, 0x94, 0x93, 0x4c, 0xc5, 0xb9, 0xe8, 0x45, 0xd4, 0x53, 0x65, 0x8b, 0xce, 0x08, 0x98, 0x45, 0xd9, 0x16, 0x0c, 0x45, 0xeb, 0x7a, 0xb3, 0x69, 0x70, 0xbd, 0xef, 0xbc, 0xcb, 0x6f, 0xaf, 0xfd, 0x67, 0x14, 0xcb, 0x34, 0xeb, 0x82, 0x45, 0xb7, 0x7f, 0x13, 0x24, 0xa0, 0xd2, 0x01, 0x86, 0x34, 0xb9, 0xa1, 0x79, 0x45, 0xe9, 0x01, 0x1e, 0x90, 0x01, 0x61, 0x6a, 0x19, 0xce, 0x50, 0xc0, 0xff, 0xc6, 0xb6, 0x83, 0x79, 0xf6, 0x2d, 0x6a, 0x83, 0x8c, 0x2a, 0x6a, 0xe3, 0xe9, 0x7c, 0x6c, 0x69, 0x60, 0xee, 0xb0, 0xaa, 0x14, 0x2a, 0x32, 0x64, 0x08, 0x92, 0x6c, 0x1f, 0x9b, 0xf7, 0xfe, 0xec, 0x46, 0x26, 0x90, 0xe0, 0x23, 0xa3, 0x29, 0xc7, 0x48, 0xde, 0x71, 0x18, 0x69, 0xe9, 0x26, 0x30, 0x01, 0x86, 0x46, 0xe4, 0x6a, 0xac, 0xa8, 0x2f, 0xf7, 0xd1, 0x5a, 0x71, 0xba, 0x6b, 0xa5, 0x20, 0xf1, 0x59, 0xe3, 0x45, 0xc2, 0x85, 0xe7, 0x98, 0xcc, 0x32, 0xef, 0xa8, 0x4b, 0xe9, 0xd3, 0xc6, 0x8e, 0x14, 0x87, 0xee, 0x06, 0xe6, 0xc0, 0x8e, 0x7a, 0xb9, 0x28, 0x71, 0x91, 0xdf, 0xe9, 0xc2, 0x0f, 0x2e, 0xa1, 0xc9, 0xf5, 0x1c, 0x69, 0x1a, 0x9f, 0xfb, 0x9b, 0x31, 0xcf, 0x25, 0xdb, 0xdc, 0x78, 0xb3, 0x12, 0x3a, 0x39, 0x78, 0xa7, 0xc6, 0xb6, 0x6f, 0x9d, 0x4b, 0x65, 0xdc, 0xf8, 0xcd, 0x67, 0x78, 0xee, 0xb0, 0x98, 0xb4, 0x05, 0xd6, 0x8f, 0x8b, 0xba, 0x65, 0x27, 0x07, 0xbf, 0x6a, 0x40, 0x94, 0xcc, 0x29, 0xb4, 0xe2, 0x5c, 0xb6, 0x42, 0x97, 0xb7, 0x0a, 0x98, 0x97, 0x5f, 0x86, 0xe2, 0x38, 0x4a, 0x39, 0xe3, 0x20, 0x00, 0xae, 0xe4, 0x78, 0xe4, 0xf0, 0xa0, 0x37, 0x11, 0xe1, 0x74, 0xad, 0xb4, 0x6e, 0x31, 0xad, 0xb5, 0xe9, 0xb1, 0x48, 0x44, 0x42, 0xbd, 0xc8, 0x25, 0x73, 0xd7, 0x45, 0x83, 0x85, 0x38, 0xfd, 0xcc, 0x69, 0xd4, 0xc7, 0x35, 0x2f, 0xb6, 0xd7, 0xcd, 0x6b, 0x8e, 0x87, 0x2d, 0xe3, 0x81, 0x44, 0x58, 0x16, 0x00, 0x88, 0x8e, 0x41, 0x13, 0xd1, 0xfe, 0x5a, 0xf7, 0xe1, 0x68, 0x5f, 0xeb, 0x0b, 0x04, 0x2e, 0x10, 0xf3, 0x67, 0xc2, 0xe3, 0x1c, 0xea, 0x3c, 0xf6, 0xc5, 0x4d, 0x85, 0x8c, 0x6e, 0x10, 0xa4, 0x52, 0x3f, 0xfd, 0x36, 0x45, 0xd8, 0x03, 0x45, 0xe8, 0xd5, 0x73, 0x1f, 0x00, 0x90, 0x3e, 0x7b, 0x9f, 0x4b, 0x2a, 0x59, 0x4a, 0x01, 0xfa, 0xfc, 0x7d, 0xe6, 0x9b, 0x08, 0x46, 0x0b, 0x20, 0x13, 0xdc, 0xaa, 0x86, 0x47, 0x17, 0x4a, 0xe8, 0xa9, 0xab, 0x16, 0x73, 0x45, 0xc7, 0xb5, 0x84, 0x1c, 0x36, 0x9f, 0x48, 0x89, 0x22, 0xe2, 0xf1, 0xd1, 0x62, 0x7c, 0xb8, 0x79, 0x6d, 0x97, 0x4a, 0x80, 0x6b, 0x69, 0x13, 0xb4, 0x7e, 0x21, 0x34, 0xe7, 0xb3, 0xf1, 0xe2, 0x9b, 0x1f, 0x53, 0x24, 0xcd, 0x07, 0x40, 0x92, 0xed, 0xf1, 0xb3, 0x91, 0x15, 0x76, 0xac, 0xdd, 0x1c, 0x3f, 0xb0, 0xdb, 0x73, 0xfd, 0xb2, 0x98, 0xa1, 0x87, 0x2d, 0xe8, 0x43, 0x19, 0x86, 0x4f, 0xe7, 0x22, 0x77, 0x25, 0x16, 0x10, 0x97, 0xfb, 0x02, 0x0a, 0x57, 0xb4, 0xa1, 0x34, 0x1f, 0x5e, 0x04, 0xea, 0xdc, 0x0b, 0xac, 0x41, 0x9d, 0xe0, 0xd2, 0x9e, 0x5c, 0x3f, 0x25, 0x0a, 0x1d, 0x0a, 0xf6, 0x36, 0x7b, 0xc7, 0x33, 0x16, 0xb0, 0xc3, 0xca, 0x36, 0x1c, 0xd8, 0xd3, 0x09, 0x72, 0xd2, 0xee, 0x00, 0x98, 0xea, 0x30, 0x06, 0x20, 0x5b, 0x15, 0x9a, 0xa0, 0x42, 0x60, 0x5d, 0x41, 0x9b, 0x37, 0xbe, 0x3c, 0x22, 0x2f, 0x15, 0xeb, 0x3e, 0x28, 0x24, 0x1d, 0x54, 0xb0, 0x0f, 0xd3, 0xba, 0xb3, 0x9c, 0xa7, 0x3f, 0x0e, 0x23, 0x35, 0xc3, 0x0e, 0x33, 0x98, 0x98, 0xf7, 0x08, 0xb0, 0x65, 0xd6, 0x3c, 0xdd, 0x58, 0x9c, 0x1c, 0x2c, 0xc2, 0x94, 0x0c, 0x86, 0x87, 0xab, 0x8a, 0x64, 0xd3, 0x88, 0x3b, 0x97, 0xb7, 0x31, 0x38, 0x1a, 0x08, 0xa2, 0x2f, 0xc9, 0xf1 }; +constexpr AccessUnit USER_DATA_LARGE_AU_EXPECTED_AU = { 0x15f90, 0x159b2, false, 0, {}, { 0xe6, 0xce, 0x63, 0xc5, 0xc9, 0x69, 0xbf, 0x14, 0xa4, 0x80, 0x23, 0x67, 0xff, 0x8f, 0x9f, 0x76, 0xf7, 0x10, 0x3e, 0xdb } }; + + +const std::vector ATRACX_SKIP_BYTES_STREAM = { 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xf3, 0x3b, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0x7a, 0x01, 0xe0, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x1a, 0x00, 0x80, 0x20, 0x90, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x00, 0x01, 0xbd, 0x07, 0x5a, 0x81, 0xc1, 0x0d, 0x31, 0x00, 0x05, 0xbf, 0x21, 0x11, 0x00, 0x05, 0xa7, 0xab, 0x1e, 0x73, 0x3b, 0x00, 0x4f, 0x02, 0xa0, 0x0f, 0xd0, 0x00, 0x52, 0x18, 0x4c, 0xe5, 0xfb, 0x25, 0x04, 0x81, 0xb1, 0x90, 0x29, 0x50, 0x65, 0x71, 0xac, 0x47, 0xdb, 0x51, 0x9e, 0x31, 0x43, 0xd2, 0x41, 0xc8, 0x06, 0xd3, 0xd3, 0x41, 0x13, 0x26, 0xef, 0xff, 0xba, 0x03, 0xc3, 0x38, 0x5c, 0xb5, 0x79, 0xb1, 0x88, 0x4e, 0x7c, 0xea, 0x44, 0x40, 0x9d, 0x56, 0x92, 0x3c, 0x21, 0x79, 0x83, 0xa9, 0x45, 0x10, 0x5c, 0x9c, 0xca, 0x93, 0x9c, 0x24, 0x89, 0xb5, 0xf5, 0x41, 0x2a, 0xc1, 0x70, 0xfa, 0x7d, 0xe3, 0x6c, 0x48, 0x0a, 0xc8, 0x16, 0xdf, 0xd9, 0x29, 0x95, 0xfc, 0x91, 0x18, 0x0c, 0xd4, 0x63, 0x3e, 0x1f, 0x3a, 0x60, 0x4b, 0xb2, 0x9b, 0x37, 0x4b, 0xf7, 0x70, 0x78, 0xb4, 0x19, 0xb9, 0xd4, 0x3f, 0x03, 0x28, 0xf7, 0x00, 0x22, 0x0b, 0xff, 0x39, 0x21, 0x23, 0xa0, 0xe5, 0xe9, 0xeb, 0x77, 0xfc, 0x81, 0x06, 0x32, 0xe0, 0x83, 0xde, 0x72, 0x7d, 0x49, 0x94, 0x98, 0x08, 0x0b, 0xde, 0xf1, 0x72, 0x8a, 0x78, 0xdb, 0xe9, 0x03, 0x2a, 0xe2, 0x03, 0x87, 0xa5, 0xf1, 0x77, 0xfb, 0xaa, 0x10, 0x78, 0x49, 0x3e, 0x53, 0x0c, 0x96, 0xe2, 0xe6, 0x08, 0x84, 0x11, 0x69, 0x78, 0xd1, 0x78, 0xff, 0xab, 0xd1, 0xa7, 0xc2, 0x20, 0xa5, 0x42, 0x88, 0x07, 0x2c, 0xd9, 0x1e, 0x2d, 0xf4, 0xf2, 0x72, 0x63, 0xcf, 0x01, 0x48, 0xce, 0xc1, 0x42, 0x74, 0xaf, 0x58, 0xb3, 0xbe, 0x85, 0xc7, 0xb8, 0xdb, 0x9f, 0x3b, 0x09, 0x2c, 0x86, 0x4d, 0x00, 0x2b, 0xcc, 0x88, 0x7d, 0xb5, 0x29, 0x5b, 0xc9, 0x94, 0xf4, 0x03, 0x57, 0x0c, 0x69, 0x32, 0x3a, 0x31, 0x3b, 0x88, 0xa8, 0x5e, 0x71, 0x1e, 0xf7, 0x16, 0x84, 0xc0, 0xd4, 0x0d, 0x3e, 0x90, 0xb4, 0x3b, 0xda, 0x28, 0xaf, 0x35, 0x4f, 0x8c, 0x56, 0x23, 0xe5, 0x65, 0x27, 0x0c, 0x62, 0x69, 0xad, 0x64, 0x76, 0xea, 0x82, 0x05, 0x44, 0xdd, 0xae, 0xf8, 0x18, 0xed, 0x25, 0xcd, 0xb2, 0x58, 0x50, 0x5a, 0xbd, 0xae, 0xf5, 0x15, 0x4a, 0xb7, 0xe7, 0x7d, 0x74, 0x0c, 0x40, 0x2b, 0x84, 0x3b, 0x20, 0x8c, 0x2e, 0x69, 0x36, 0x61, 0xc9, 0xdc, 0x7d, 0x78, 0x99, 0xe1, 0xf9, 0x49, 0x8e, 0xe4, 0x6c, 0x5e, 0x07, 0xce, 0x37, 0xbe, 0x86, 0xde, 0xec, 0xb7, 0x62, 0xa1, 0x51, 0xbf, 0xde, 0xce, 0xbd, 0x58, 0x37, 0x04, 0x20, 0x15, 0x90, 0xc9, 0x26, 0x45, 0xcd, 0x4f, 0x36, 0xd0, 0xc3, 0xc7, 0x46, 0x52, 0x4d, 0x51, 0xc0, 0x8c, 0x35, 0xd8, 0xfa, 0x97, 0xf5, 0x63, 0xf2, 0x92, 0xc2, 0xa1, 0x52, 0xac, 0x68, 0xce, 0xfd, 0xb9, 0xed, 0x25, 0x8f, 0xbf, 0xfb, 0x80, 0xa0, 0x26, 0x84, 0xe6, 0xbb, 0x75, 0x27, 0x14, 0x42, 0xd1, 0x4d, 0x53, 0xca, 0x9a, 0xf9, 0x22, 0x9a, 0xe2, 0xc6, 0x83, 0x51, 0xa2, 0x9b, 0xed, 0xf0, 0xd8, 0xf6, 0x45, 0xc4, 0xfe, 0xef, 0x50, 0xe5, 0x84, 0x4a, 0x7c, 0x50, 0x3a, 0x33, 0x07, 0xd0, 0xd2, 0x87, 0xcc, 0x38, 0xef, 0xba, 0x46, 0xa7, 0x61, 0xc6, 0x98, 0xce, 0x86, 0xb0, 0x9d, 0x7f, 0xf1, 0x88, 0x53, 0xf3, 0xca, 0xfa, 0x2e, 0x93, 0x96, 0xd3, 0x17, 0x2c, 0x46, 0x12, 0x2f, 0xe2, 0xc7, 0x60, 0x96, 0x45, 0x79, 0x0a, 0xc7, 0x5a, 0x36, 0xdf, 0x5a, 0x85, 0xd9, 0x8a, 0x2d, 0x94, 0x77, 0x42, 0x4d, 0x6f, 0xa1, 0xee, 0x1e, 0x1d, 0x7c, 0x1d, 0x9a, 0x1c, 0x75, 0x69, 0xa6, 0x55, 0xdf, 0x1b, 0xda, 0x16, 0xd1, 0x40, 0x34, 0xd9, 0xfa, 0x74, 0x94, 0xd2, 0x4f, 0x0f, 0xfe, 0x7d, 0xd0, 0x86, 0x02, 0xaf, 0xb5, 0x24, 0xb8, 0xdb, 0xc9, 0x6f, 0x3a, 0x8f, 0xd4, 0xe0, 0x98, 0x69, 0x39, 0xbc, 0x93, 0xf3, 0x42, 0x35, 0xaf, 0x2c, 0xbb, 0x2c, 0x66, 0xb7, 0xd2, 0x2b, 0x89, 0xed, 0x59, 0x7e, 0x1a, 0x4d, 0xea, 0x78, 0x28, 0x07, 0x87, 0x4f, 0x83, 0x98, 0xa8, 0x24, 0x47, 0xc2, 0xec, 0x0d, 0x90, 0x4a, 0xcb, 0x48, 0xed, 0x41, 0xfc, 0xf0, 0x45, 0xda, 0x7c, 0xcd, 0x58, 0xfa, 0x60, 0x14, 0x0d, 0x09, 0xdc, 0x49, 0x2e, 0xc1, 0x31, 0x8c, 0x53, 0xf0, 0x66, 0xe7, 0x05, 0x69, 0x00, 0x9b, 0x74, 0xab, 0x20, 0x5a, 0x38, 0xea, 0xb2, 0xf1, 0xfa, 0x86, 0x9f, 0xe7, 0x09, 0x1d, 0x28, 0xf7, 0x28, 0xc4, 0xd6, 0x7d, 0x1e, 0x0d, 0xb6, 0x34, 0xdc, 0xf2, 0xb8, 0xde, 0x3e, 0xc9, 0x72, 0xb8, 0xb7, 0xca, 0xa9, 0xd1, 0x6e, 0xda, 0x49, 0x9e, 0xa0, 0xa6, 0xc1, 0x70, 0x50, 0x36, 0xe8, 0x9b, 0x8d, 0x85, 0xdc, 0x7b, 0xdf, 0xd1, 0x7c, 0x9d, 0xa3, 0x9e, 0x7e, 0xc1, 0x6d, 0xb4, 0x34, 0x7a, 0xa4, 0x81, 0x81, 0x98, 0x01, 0xac, 0x9d, 0xb1, 0xa8, 0xce, 0x98, 0x64, 0xf4, 0x87, 0xcc, 0x38, 0x31, 0x78, 0xa2, 0x2e, 0xed, 0xd8, 0x5b, 0x5f, 0x85, 0x97, 0xca, 0x4d, 0x24, 0x5c, 0x2a, 0xb9, 0x5a, 0xcb, 0x77, 0x1c, 0xf6, 0xdd, 0x00, 0x22, 0xd7, 0x0f, 0xd0, 0x01, 0x00, 0xb5, 0xf3, 0xca, 0xde, 0xeb, 0x93, 0x07, 0x58, 0xd3, 0x9e, 0x57, 0xaf, 0x26, 0xe3, 0x44, 0x06, 0x5a, 0x2e, 0x14, 0xcd, 0xcb, 0x11, 0x4f, 0xe8, 0xce, 0x3a, 0x30, 0x44, 0xae, 0x50, 0x8b, 0xcf, 0xcb, 0x6f, 0x0e, 0x31, 0x51, 0xca, 0xfa, 0xc4, 0x53, 0x05, 0xa4, 0xa3, 0x35, 0x42, 0x6a, 0xce, 0xab, 0x0c, 0xeb, 0xc4, 0xc4, 0x84, 0xa8, 0x05, 0xc4, 0x84, 0x5e, 0x5c, 0xbe, 0xa6, 0xc8, 0xf9, 0x37, 0x48, 0x8a, 0x9b, 0x40, 0x1c, 0x7f, 0x69, 0xd1, 0xc5, 0xac, 0x37, 0x56, 0x98, 0x89, 0x48, 0xaf, 0x86, 0x65, 0xda, 0x20, 0xbd, 0x1f, 0x0d, 0xe8, 0x8d, 0x73, 0xe0, 0x84, 0x9c, 0x83, 0x63, 0xcb, 0x79, 0x84, 0x62, 0x73, 0x0c, 0x91, 0x13, 0xa7, 0x86, 0x18, 0x97, 0xba, 0xc6, 0x6c, 0x54, 0x29, 0x52, 0x6a, 0x7f, 0x6a, 0x5a, 0x34, 0x58, 0x48, 0x75, 0x78, 0xe3, 0xc5, 0xef, 0xcb, 0x37, 0xbe, 0xf1, 0x08, 0x9e, 0xc9, 0xd4, 0xb1, 0x21, 0x15, 0x64, 0xd2, 0x40, 0x3b, 0xe3, 0xe7, 0xe8, 0x43, 0x17, 0xa9, 0xf7, 0x54, 0xb1, 0xe8, 0xcf, 0xd5, 0xd4, 0xbc, 0xce, 0xed, 0x91, 0xb4, 0xb5, 0xa9, 0x93, 0xe5, 0x3e, 0x44, 0x63, 0xe3, 0x88, 0x3e, 0xef, 0x0d, 0x05, 0x54, 0x3a, 0xcc, 0x0c, 0x88, 0x73, 0x92, 0x57, 0xb3, 0xc8, 0xc1, 0xef, 0x64, 0xb3, 0xd2, 0x5e, 0x07, 0xa4, 0x54, 0x2f, 0x8c, 0x36, 0xb0, 0x02, 0x0c, 0x59, 0xae, 0xcf, 0x29, 0x2a, 0x3b, 0x0b, 0x24, 0x49, 0xf5, 0xde, 0xe9, 0xf7, 0x5b, 0x8d, 0x7e, 0x5b, 0xc9, 0xcb, 0xae, 0x91, 0x8f, 0xa3, 0xc6, 0x83, 0xc7, 0x0c, 0xc8, 0xa5, 0xbe, 0x81, 0x6b, 0x0d, 0x1e, 0x11, 0xc1, 0x8f, 0x17, 0xcf, 0x70, 0xc2, 0x40, 0x8d, 0xb9, 0x29, 0xfe, 0x56, 0xd4, 0xda, 0x8f, 0x09, 0x50, 0x60, 0x10, 0x00, 0x80, 0xb9, 0x2a, 0xc7, 0x23, 0x9f, 0x2d, 0x22, 0xcf, 0x88, 0xc5, 0x00, 0xd6, 0x09, 0x9c, 0x1d, 0x9f, 0x8d, 0x8d, 0x60, 0xb2, 0x81, 0x38, 0x47, 0xf4, 0x68, 0x23, 0xe1, 0xcc, 0x85, 0xb1, 0x2f, 0x2f, 0x08, 0xa1, 0xf0, 0xc8, 0xd8, 0xdb, 0x25, 0xcc, 0x86, 0xb4, 0xde, 0x1b, 0xf8, 0x0b, 0x18, 0xbc, 0xc4, 0xc1, 0xaf, 0xee, 0x6c, 0x8b, 0xc7, 0x43, 0xdc, 0x1c, 0x23, 0x88, 0xdc, 0x16, 0x3c, 0x6f, 0x63, 0x54, 0x28, 0x45, 0xf6, 0x6b, 0x99, 0x18, 0x7b, 0x86, 0x84, 0x27, 0x31, 0xe8, 0x36, 0x78, 0xb6, 0xc5, 0xe6, 0xf0, 0x4c, 0x3b, 0x11, 0x4b, 0xc3, 0x94, 0x30, 0xcb, 0xb1, 0x25, 0x87, 0x83, 0xf3, 0x6d, 0x26, 0x8b, 0x95, 0x46, 0x64, 0x8e, 0x8c, 0x54, 0x5e, 0x75, 0xfb, 0xfb, 0x43, 0x26, 0xe5, 0x86, 0x86, 0x99, 0x76, 0x53, 0x35, 0xb7, 0x5c, 0x29, 0xfe, 0xc4, 0xc7, 0x09, 0xc4, 0x51, 0x16, 0x1a, 0xb6, 0xf2, 0x44, 0x96, 0x41, 0x2d, 0x92, 0xc0, 0x6a, 0x64, 0x13, 0x52, 0x5b, 0xbe, 0x07, 0xf5, 0x25, 0x34, 0x33, 0xa0, 0x15, 0x59, 0x9a, 0xfd, 0x16, 0x83, 0x54, 0x2f, 0xfc, 0x62, 0x5b, 0x90, 0xb6, 0x34, 0x85, 0x4c, 0xbb, 0x17, 0x1a, 0xed, 0x3e, 0x39, 0xa8, 0x3d, 0xf2, 0xdc, 0x08, 0x07, 0x6b, 0x6c, 0xbf, 0xb3, 0x69, 0x25, 0x25, 0xb6, 0x97, 0xfe, 0x03, 0x4b, 0x8c, 0xe4, 0x87, 0x05, 0x19, 0x6e, 0xd1, 0x1a, 0x34, 0x93, 0x67, 0x84, 0x00, 0x19, 0x5f, 0x4f, 0xce, 0xbf, 0x06, 0xb5, 0x15, 0x51, 0x4c, 0xe2, 0xbd, 0x33, 0x59, 0x7e, 0x32, 0x0e, 0xf1, 0x52, 0x22, 0xa9, 0x93, 0xb3, 0xe7, 0x23, 0x91, 0x78, 0xe3, 0x0b, 0x6f, 0xb0, 0x6e, 0x10, 0x50, 0x62, 0x09, 0x4b, 0x53, 0xfc, 0xf4, 0x58, 0xff, 0x46, 0x70, 0xc2, 0x46, 0x02, 0x2e, 0x70, 0xb0, 0x80, 0xc5, 0x26, 0xab, 0xdb, 0x39, 0x3a, 0x25, 0xa2, 0xcf, 0x0f, 0xd9, 0x21, 0xd6, 0x0e, 0x08, 0x92, 0x11, 0x08, 0x76, 0xdd, 0xed, 0x59, 0xf1, 0xbd, 0xb5, 0x30, 0xae, 0x75, 0x63, 0xc6, 0x47, 0x53, 0xcc, 0x75, 0x31, 0xbe, 0x3e, 0xfb, 0xe1, 0x97, 0xd7, 0x52, 0x05, 0x0c, 0x1c, 0xe5, 0x85, 0x40, 0xa9, 0x21, 0x2b, 0x5c, 0xf8, 0x8f, 0x30, 0xe9, 0x94, 0x04, 0x0a, 0x8d, 0x40, 0x94, 0x2f, 0x8d, 0xe3, 0x55, 0xb7, 0xa4, 0x3a, 0x17, 0x0a, 0x1a, 0xab, 0xa9, 0x04, 0x28, 0xb9, 0x4d, 0x3c, 0x10, 0xe8, 0x66, 0x5e, 0x84, 0x23, 0x9c, 0xbb, 0x2e, 0xe8, 0xe5, 0x85, 0x84, 0xc8, 0x45, 0x57, 0x35, 0x0b, 0x25, 0x08, 0xd8, 0x84, 0x9e, 0xdd, 0xb4, 0xd2, 0x10, 0x9b, 0xb1, 0xb8, 0xe1, 0x15, 0xea, 0x37, 0x4c, 0x33, 0x60, 0x8e, 0x83, 0x8a, 0xb6, 0x60, 0xa1, 0xfe, 0x17, 0x8e, 0x24, 0x21, 0x94, 0x99, 0xed, 0x20, 0xa9, 0x85, 0x07, 0x89, 0xae, 0xa4, 0xa5, 0x44, 0x67, 0xb9, 0x20, 0x6d, 0xfb, 0x55, 0xe9, 0x01, 0x02, 0x6e, 0xad, 0x83, 0x6f, 0x7f, 0x28, 0x0a, 0x89, 0xbe, 0x64, 0x63, 0x3b, 0x34, 0x56, 0x2f, 0x6a, 0xbe, 0x2d, 0x30, 0x1a, 0x4f, 0xab, 0x2c, 0x8e, 0xef, 0x6d, 0x13, 0xb4, 0x54, 0xf9, 0x52, 0x7f, 0x0c, 0xe6, 0x85, 0x0a, 0x9d, 0x8f, 0xf0, 0x9f, 0x16, 0x19, 0x67, 0xfa, 0xd9, 0xae, 0x99, 0x71, 0xc0, 0x4d, 0xea, 0xca, 0xd3, 0x89, 0x36, 0xee, 0x24, 0x11, 0x4c, 0xc8, 0x9a, 0xdd, 0xe5, 0xef, 0xc4, 0x5d, 0x61, 0xfd, 0xe6, 0x0f, 0xab, 0xa4, 0xe6, 0x3d, 0xea, 0xea, 0xd8, 0xe6, 0xf9, 0x1a, 0x33, 0x09, 0xc1, 0x56, 0x08, 0xca, 0xf7, 0xd3, 0xb2, 0x35, 0xcf, 0x31, 0xe3, 0x97, 0xac, 0x71, 0x09, 0xa8, 0xdc, 0x81, 0x58, 0x04, 0xec, 0x66, 0x15, 0xad, 0x20, 0x63, 0xd5, 0x95, 0x19, 0xc4, 0xd2, 0x69, 0xb5, 0x19, 0x95, 0x1c, 0xb8, 0x0e, 0x89, 0xe9, 0xca, 0x2a, 0x3c, 0xd0, 0xce, 0x23, 0x5d, 0xbf, 0xae, 0x93, 0xc7, 0xef, 0x14, 0x36, 0x1e, 0x2a, 0xaf, 0x05, 0xca, 0xf3, 0xfb, 0xd1, 0x6b, 0xd5, 0xb9, 0x33, 0xf8, 0x51, 0x76, 0xf1, 0x2d, 0x21, 0xda, 0x35, 0x07, 0xd3, 0xa5, 0x2d, 0x5b, 0xfd, 0x86, 0xf6, 0xdb, 0x75, 0x3e, 0xeb, 0x0c, 0x5a, 0xaf, 0xb2, 0x02, 0xdf, 0xd3, 0xa9, 0xe1, 0x1d, 0xb4, 0x87, 0x83, 0x62, 0xe5, 0x55, 0xb7, 0xb3, 0x16, 0x16, 0xfc, 0x90, 0xc0, 0xb6, 0xaf, 0x24, 0x03, 0x2e, 0x0e, 0x5f, 0x33, 0xde, 0x84, 0xc5, 0xb0, 0x90, 0x1d, 0xda, 0x0a, 0xb6, 0x2b, 0x73, 0x81, 0xbd, 0x5a, 0x68, 0x68, 0x97, 0xd1, 0x5a, 0x05, 0xd4, 0x23, 0x9b, 0xe2, 0xeb, 0x1a, 0x56, 0xbc, 0x84, 0xb0, 0x99, 0x73, 0xed, 0xb9, 0xd9, 0xb4, 0x0a, 0x11, 0x0a, 0x3d, 0x68, 0x54, 0x6c, 0xf0, 0x40, 0x78, 0xa1, 0x1b, 0x95, 0xbd, 0xb7, 0xa3, 0xbe, 0xdd, 0x2b, 0x02, 0xfe, 0x71, 0x1d, 0x39, 0x08, 0xe5, 0x33, 0x32, 0x7b, 0x77, 0xe8, 0x30, 0xcf, 0x24, 0x39, 0x3b, 0x31, 0x7b, 0x04, 0xc2, 0x40, 0xa9, 0x72, 0xc9, 0xb4, 0x4c, 0x4c, 0x60, 0x62, 0xda, 0x1c, 0x49, 0x24, 0x9d, 0x64, 0xf7, 0x89, 0xa3, 0x64, 0x59, 0x6d, 0x1b, 0x25, 0x78, 0xd1, 0xf5, 0xd5, 0x0b, 0x89, 0xd3, 0x97, 0xb0, 0xb0, 0x8f, 0x60, 0xf6, 0xdc, 0xe9, 0x81, 0x20, 0x96, 0x21, 0xee, 0x16, 0x95, 0x9a, 0x7d, 0x68, 0x9d, 0xb6, 0x82, 0x81, 0x2d, 0x96, 0xab, 0xaf, 0x45, 0x72, 0xee, 0xe3, 0xeb, 0xa2, 0xea, 0x65, 0x47, 0x9f, 0x17, 0xd6, 0x78, 0x8d, 0xa0, 0x3c, 0x73, 0x0e, 0xc5, 0xfd, 0x8e, 0x7a, 0x1a, 0xf0, 0x9f, 0xbe, 0x0c, 0xfb, 0xaa, 0x70, 0x77, 0xe1, 0xa8, 0xe1, 0x3c, 0x32, 0xd4, 0x43, 0x20, 0x7f, 0x82, 0x23, 0x64, 0x53, 0x7a, 0xca, 0xd8, 0x7f, 0x53, 0x4d, 0x68, 0xc3, 0x51, 0x60, 0x55, 0xe9, 0xaa, 0x2d, 0xa2, 0xca, 0x55, 0xc0, 0x6a, 0xed, 0xb7, 0xd9, 0x17, 0x96, 0xca, 0x25, 0xc6, 0x92, 0x9f, 0x38, 0x3b, 0x0b, 0x54, 0xc2, 0x3e, 0x2a, 0xd9, 0xe2, 0x43, 0x63, 0x22, 0x87, 0xa9, 0x9f, 0xa1, 0x4c, 0x08, 0xa7, 0x24, 0x37, 0x48, 0x8c, 0x75, 0x48, 0x7e, 0xe6, 0x51, 0xcc, 0xc9, 0x24, 0xa2, 0xcf, 0xb3, 0x4f, 0xff, 0x2f, 0xc8, 0xf0, 0xe8, 0x22, 0x65, 0x0d, 0x4b, 0x3b, 0xf7, 0x54, 0x2a, 0x35, 0x28, 0xfc, 0x92, 0x14, 0xbd, 0xec, 0x28, 0x6c, 0x11, 0x29, 0xf6, 0xcd, 0x7b, 0xb1, 0x52, 0xad, 0x05, 0x25, 0xf6, 0x5b, 0x52, 0xfa, 0xaa, 0xb8, 0x84, 0x21, 0x18, 0xdc, 0x82, 0x3d, 0xad, 0xd7, 0x0d, 0xe9, 0x9c, 0x2f, 0x54, 0xaf, 0x5a, 0xdc, 0x18, 0x9d, 0x47, 0xd4, 0x92, 0xa9, 0x3c, 0x6d, 0x92, 0x46, 0x3a, 0x26, 0x9a, 0xe4, 0x89, 0xa3, 0xf5, 0x38, 0xda, 0xe0, 0xf4, 0x83, 0x59, 0xf7, 0xe9, 0x42, 0xc3, 0xf0, 0x7e, 0xec, 0xdb, 0x7e, 0x7b, 0xb1, 0xd7, 0x9f, 0x29, 0x6d, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbd, 0x07, 0xec, 0x79, 0x01, 0x00, 0x00, 0x24, 0xff, 0xdb, 0x8c, 0xe6, 0x0a, 0xfa, 0x51, 0x85, 0xb8, 0xdb, 0x2d, 0x4f, 0x23, 0x96, 0x35, 0xb2, 0x4b, 0x26, 0x29, 0x13, 0x41, 0x05, 0xb5, 0x52, 0x96, 0xed, 0xe2, 0x23, 0x2f, 0xc8, 0x03, 0xd7, 0xf8, 0xc1, 0x9e, 0x30, 0x12, 0xf0, 0x30, 0x52, 0x75, 0x34, 0xcb, 0x09, 0x30, 0x0c, 0xd7, 0xd4, 0xa7, 0x9a, 0x96, 0x86, 0x8e, 0x28, 0x1a, 0x63, 0x7e, 0xc7, 0xd1, 0x04, 0x56, 0xe1, 0xee, 0x7c, 0xd4, 0xeb, 0x28, 0x70, 0x11, 0x7d, 0xbc, 0x2a, 0xcd, 0x7a, 0xa3, 0xe0, 0xb2, 0x22, 0x4e, 0xa5, 0x07, 0x24, 0x82, 0xc4, 0x6d, 0x12, 0x09, 0x88, 0x9f, 0xd7, 0x5d, 0x9d, 0x62, 0xfa, 0x7f, 0x96, 0x02, 0xde, 0x9d, 0x49, 0x19, 0x51, 0x47, 0x08, 0x89, 0x03, 0x3f, 0xe2, 0xc6, 0xcb, 0x32, 0x79, 0xf2, 0xca, 0xea, 0x23, 0x67, 0xd5, 0xc1, 0x50, 0x9e, 0xb6, 0x58, 0x6c, 0xaa, 0x26, 0xf7, 0xcb, 0xa2, 0xa1, 0x05, 0x44, 0xad, 0x60, 0x77, 0x8e, 0xa8, 0x26, 0x3b, 0x7e, 0x7d, 0xba, 0xed, 0xc9, 0xa4, 0x16, 0x62, 0xdd, 0x7a, 0xc6, 0xd0, 0xec, 0x53, 0xfd, 0xa9, 0x53, 0x7a, 0x3e, 0x6d, 0xe5, 0x8a, 0xc1, 0xfd, 0xcc, 0xc4, 0xe2, 0x46, 0xfd, 0x5d, 0x42, 0x48, 0x8a, 0xdd, 0x6a, 0xbf, 0x32, 0x0d, 0x16, 0x0d, 0x0e, 0x19, 0x81, 0x1b, 0x31, 0xca, 0x4d, 0x4b, 0x98, 0x10, 0xdd, 0xc9, 0xd5, 0x44, 0x4e, 0xb3, 0x2f, 0xcd, 0x56, 0x03, 0x3f, 0x0f, 0xb7, 0x2b, 0x3c, 0xdd, 0x17, 0xbc, 0x75, 0xd0, 0x5c, 0xa7, 0xb8, 0x2a, 0xe5, 0xda, 0x9a, 0x44, 0x48, 0x4d, 0xe6, 0x9f, 0x62, 0xc8, 0xac, 0x0e, 0xdb, 0xec, 0xa1, 0xa5, 0x79, 0x50, 0xde, 0x57, 0xea, 0xbd, 0x31, 0x6d, 0xc5, 0xca, 0x76, 0x45, 0xfe, 0x7d, 0xc0, 0x07, 0x12, 0x9a, 0x43, 0x36, 0x95, 0xd2, 0x4b, 0x4e, 0xf1, 0xfd, 0xa1, 0xd8, 0x80, 0xff, 0x39, 0xa2, 0x53, 0x24, 0x0b, 0x05, 0x44, 0xea, 0x6a, 0x6b, 0x37, 0xa6, 0x3e, 0x77, 0x96, 0x71, 0xee, 0x7e, 0x71, 0x3c, 0xf0, 0x49, 0xe0, 0x11, 0x39, 0x3a, 0x72, 0xcb, 0x0f, 0x49, 0xda, 0xd9, 0xf2, 0x8b, 0x29, 0xc8, 0x99, 0x1b, 0x32, 0xb4, 0x4b, 0xaf, 0xf8, 0xde, 0xfa, 0x26, 0x42, 0xf9, 0xf1, 0xd0, 0xab, 0xf3, 0x05, 0x58, 0xd6, 0x53, 0x87, 0x70, 0x8e, 0x6e, 0x75, 0xbb, 0x08, 0xf9, 0xab, 0x9d, 0x8a, 0xdb, 0x00, 0xd0, 0x25, 0x2f, 0x9b, 0x00, 0x55, 0xd6, 0xfa, 0xc5, 0xa3, 0x1e, 0x5a, 0xb5, 0xaf, 0x47, 0x8d, 0x75, 0x2b, 0xf9, 0x6d, 0xf3, 0xb7, 0xf1, 0x75, 0x3a, 0xaf, 0x74, 0x28, 0x87, 0x46, 0x50, 0x5b, 0x8e, 0x92, 0x85, 0x88, 0x1c, 0x5f, 0xc6, 0xb4, 0x7d, 0xe1, 0x7f, 0x9e, 0x56, 0xb0, 0x16, 0x34, 0xe4, 0x96, 0x75, 0x8c, 0xbc, 0x20, 0x37, 0xd6, 0x89, 0xf6, 0xf0, 0x11, 0x6e, 0x71, 0x6d, 0x6b, 0xf4, 0xf3, 0xf1, 0xa1, 0xb4, 0xec, 0xb7, 0xbf, 0x28, 0xa4, 0x4d, 0x15, 0x52, 0x23, 0x8f, 0x4d, 0x1e, 0xd3, 0x4f, 0xe4, 0xb4, 0xc0, 0xf5, 0x83, 0x1d, 0x89, 0xaa, 0xef, 0xea, 0x63, 0xcc, 0x93, 0xd5, 0xc3, 0xc6, 0xda, 0x6d, 0x95, 0x8b, 0xd9, 0x56, 0x1c, 0x4f, 0xfe, 0xb9, 0xc3, 0x37, 0xce, 0xcf, 0x9f, 0x1f, 0xdd, 0xbc, 0x52, 0xb3, 0x8a, 0x1f, 0x99, 0x71, 0x32, 0x07, 0xba, 0x5b, 0xdb, 0x37, 0x83, 0x67, 0x8d, 0xe0, 0xb8, 0xf4, 0xe2, 0x4c, 0xf9, 0xde, 0x79, 0x14, 0x90, 0xe7, 0x50, 0xd8, 0xbe, 0x97, 0x40, 0xa6, 0x56, 0xd0, 0x1f, 0x6e, 0xd9, 0xaa, 0x2f, 0x46, 0x55, 0x5e, 0xee, 0x54, 0xba, 0x4d, 0x74, 0x9a, 0x77, 0x79, 0xe0, 0x00, 0x71, 0xe7, 0x8c, 0x5b, 0xca, 0xc9, 0x10, 0x4e, 0xf6, 0x78, 0x3c, 0x39, 0x10, 0x7d, 0x97, 0x9a, 0x81, 0x4d, 0x1b, 0x99, 0x58, 0x69, 0x1c, 0x9c, 0xf0, 0x06, 0xb1, 0x1d, 0xb6, 0x77, 0xfa, 0x1e, 0x40, 0xed, 0x20, 0xfc, 0xfa, 0x60, 0xf1, 0x79, 0x14, 0x99, 0x62, 0x30, 0x87, 0xbf, 0x6e, 0xea, 0x4d, 0xe4, 0x12, 0x69, 0x2e, 0x68, 0x59, 0xb1, 0xb1, 0x32, 0xc6, 0xdd, 0x1f, 0x1b, 0x7d, 0x06, 0xa2, 0x06, 0x02, 0xdb, 0xe8, 0x7f, 0x79, 0xd5, 0xe5, 0xe5, 0xaa, 0x3b, 0x86, 0x6f, 0x42, 0x56, 0x7e, 0x91, 0x13, 0x93, 0x81, 0x99, 0x3d, 0x69, 0x8f, 0x87, 0x9e, 0x43, 0x20, 0x6a, 0xdb, 0xcb, 0x59, 0xdb, 0xe3, 0x4c, 0xa5, 0x4e, 0xd0, 0x14, 0x3d, 0x5c, 0x6c, 0xfc, 0x9d, 0x3b, 0xd7, 0x8e, 0xd6, 0x06, 0x01, 0x66, 0x43, 0x8e, 0x04, 0xd0, 0x1f, 0xcc, 0x83, 0xad, 0xea, 0x3b, 0xa8, 0x35, 0xad, 0xab, 0x59, 0x1a, 0x81, 0x4b, 0xc5, 0x1a, 0xf3, 0x0f, 0x69, 0x0b, 0x20, 0xa4, 0x12, 0xf1, 0x9f, 0x8c, 0xa5, 0xa7, 0xa7, 0x2e, 0x8c, 0x23, 0xfa, 0xdf, 0x27, 0x6c, 0x73, 0x3a, 0x9c, 0xbf, 0x66, 0x46, 0xdd, 0x84, 0x14, 0x44, 0xca, 0xff, 0xe2, 0x26, 0xc0, 0xf3, 0x25, 0xff, 0xff, 0x96, 0xa3, 0xfe, 0xa8, 0x8e, 0x27, 0xb2, 0x5a, 0xd5, 0xbc, 0xb0, 0x9d, 0xc4, 0x73, 0xe5, 0x95, 0x99, 0xd2, 0x14, 0xcb, 0x3a, 0x38, 0x5f, 0xf4, 0x10, 0xe8, 0xdb, 0xfa, 0x32, 0x88, 0x77, 0xcc, 0x47, 0x34, 0xcd, 0x9a, 0xc6, 0x7f, 0xaa, 0x96, 0x8d, 0x07, 0x45, 0x5d, 0xef, 0x6a, 0x90, 0x93, 0xa7, 0xc4, 0x0d, 0x66, 0x64, 0x0b, 0x14, 0xfc, 0xce, 0xe9, 0x7e, 0x00, 0x3d, 0xea, 0x07, 0xcc, 0x80, 0x25, 0xfc, 0xee, 0x70, 0xaf, 0xf7, 0x0b, 0x26, 0x7f, 0xb7, 0x44, 0x1b, 0x97, 0x62, 0xba, 0x81, 0x91, 0xc0, 0xd2, 0x9b, 0xf1, 0x30, 0x41, 0xed, 0xcb, 0x71, 0x20, 0x79, 0xac, 0x82, 0x75, 0x74, 0xcd, 0x24, 0xfd, 0x20, 0xfc, 0xd1, 0x29, 0xae, 0xce, 0x31, 0x92, 0x67, 0x01, 0x57, 0x54, 0x71, 0x14, 0x4e, 0x19, 0xee, 0x8f, 0xd2, 0xc5, 0x56, 0x7a, 0x2b, 0x0d, 0x42, 0xf8, 0x8d, 0x63, 0x08, 0x0a, 0x6f, 0xff, 0xdd, 0xee, 0xc0, 0x04, 0x67, 0xa1, 0xf6, 0xeb, 0xe9, 0x71, 0x3e, 0xce, 0x78, 0xaa, 0x6e, 0x27, 0xde, 0xd0, 0x6f, 0x2d, 0x26, 0xe5, 0x37, 0xdd, 0xe8, 0xb7, 0xa1, 0x54, 0xd6, 0x3a, 0x9d, 0x16, 0x25, 0x51, 0xa5, 0x53, 0xc9, 0xa8, 0x59, 0x58, 0xab, 0x74, 0xba, 0xb7, 0x48, 0x36, 0x69, 0xcf, 0x61, 0xe2, 0xcf, 0xc2, 0xac, 0xfe, 0x34, 0x0a, 0xad, 0x9a, 0x0b, 0x2b, 0x2c, 0x43, 0x04, 0x44, 0xe7, 0x37, 0xb0, 0x72, 0x7d, 0x99, 0xc4, 0x44, 0x0f, 0xd0, 0x43, 0xc5, 0x4a, 0x1d, 0x1c, 0xc5, 0xe3, 0x38, 0x0f, 0x73, 0x6e, 0xbc, 0xd5, 0x71, 0xc8, 0x15, 0xed, 0xee, 0x0a, 0x8b, 0x8a, 0x70, 0x88, 0xf3, 0x68, 0x61, 0x63, 0x2c, 0xb4, 0x80, 0xd4, 0x3e, 0x24, 0xd0, 0x9a, 0x49, 0xfb, 0xa3, 0x40, 0x89, 0x9f, 0xd1, 0x25, 0x1b, 0xdf, 0x57, 0x65, 0x5e, 0x3d, 0xc9, 0x26, 0xff, 0xab, 0x66, 0xde, 0x1f, 0xa9, 0xc3, 0x8d, 0x1e, 0xb8, 0x41, 0x12, 0xf5, 0x7c, 0xd6, 0x06, 0x29, 0x0b, 0xe5, 0xcb, 0xce, 0x43, 0x12, 0xbc, 0x19, 0x30, 0x60, 0xa2, 0x71, 0xc3, 0x09, 0xeb, 0x0e, 0x77, 0xd5, 0x38, 0x96, 0x9f, 0xe1, 0x42, 0x31, 0x77, 0x1d, 0x3c, 0x1c, 0x3f, 0xf6, 0x13, 0xae, 0xe5, 0xed, 0x4b, 0x47, 0x14, 0x10, 0x55, 0xba, 0xb4, 0x97, 0x93, 0x0d, 0x1d, 0x22, 0x76, 0xae, 0x92, 0x50, 0x53, 0x79, 0xcd, 0xa6, 0xfc, 0x29, 0xaa, 0x12, 0x1e, 0x16, 0x34, 0x76, 0xf7, 0x4e, 0xb7, 0x00, 0xf8, 0x75, 0x7d, 0x47, 0x43, 0x04, 0x6f, 0x6a, 0x3f, 0xb7, 0xbc, 0xab, 0x97, 0x55, 0x34, 0x4e, 0x66, 0x2c, 0x0b, 0xa1, 0x6a, 0xd0, 0x1c, 0x7f, 0x7a, 0x09, 0xf7, 0xbe, 0xa0, 0x03, 0x43, 0x48, 0x81, 0x20, 0x41, 0xdb, 0x11, 0x03, 0x78, 0xab, 0xa1, 0xb5, 0xe6, 0x5e, 0xd6, 0x00, 0x29, 0x2b, 0x17, 0x59, 0x81, 0x07, 0x6e, 0xf2, 0xae, 0x2a, 0x05, 0xdd, 0xf6, 0x5b, 0xab, 0x4c, 0xe0, 0xd2, 0x09, 0x51, 0x72, 0x91, 0x79, 0xc4, 0xfa, 0x91, 0xa7, 0x12, 0xb3, 0x1a, 0x6b, 0x2e, 0xd0, 0x25, 0x83, 0xea, 0xaf, 0xb0, 0x1f, 0x60, 0x57, 0x3a, 0x68, 0x40, 0x76, 0xfe, 0x6d, 0x29, 0x77, 0x8e, 0x25, 0x58, 0x79, 0xd3, 0x6d, 0x5c, 0x33, 0xb5, 0x36, 0xa0, 0x12, 0xe1, 0x44, 0xe5, 0x1d, 0x61, 0x3a, 0x12, 0x66, 0x16, 0xc7, 0xef, 0x1d, 0x3b, 0x40, 0xa5, 0x8c, 0x7b, 0xee, 0x22, 0x85, 0x52, 0xe0, 0xc6, 0x12, 0xad, 0x12, 0xe1, 0x76, 0x17, 0x24, 0xf0, 0xc4, 0xda, 0x03, 0xaa, 0x99, 0xe4, 0x40, 0x44, 0xcd, 0x59, 0xe6, 0x79, 0x1f, 0x1d, 0x1e, 0x3f, 0x26, 0xcc, 0xe8, 0x40, 0x1d, 0xd8, 0xb7, 0x72, 0x4e, 0xd3, 0xc0, 0x6e, 0x2b, 0x18, 0x3b, 0x5a, 0x5d, 0x51, 0xfd, 0x8c, 0x5e, 0x9b, 0x0d, 0x39, 0x5f, 0x3e, 0x2e, 0xda, 0x8d, 0x36, 0x87, 0x08, 0x02, 0x0c, 0xcd, 0x10, 0xe4, 0xbc, 0x9d, 0x77, 0x91, 0x99, 0x03, 0x23, 0xcc, 0x7e, 0x3d, 0xfb, 0x48, 0xb3, 0x3c, 0x18, 0x1e, 0x54, 0x8d, 0xee, 0xea, 0x2c, 0x85, 0xf3, 0xac, 0x3c, 0xf5, 0xbf, 0xb3, 0x7d, 0xbe, 0xa6, 0x15, 0x7f, 0xf8, 0x33, 0x94, 0xf9, 0x9d, 0x21, 0xe7, 0x73, 0xda, 0xb0, 0xc1, 0x94, 0x7e, 0x65, 0x1b, 0xc4, 0x20, 0xa2, 0x90, 0x2e, 0x06, 0xa9, 0xd5, 0x4d, 0xd4, 0xe4, 0xa1, 0x83, 0x94, 0x97, 0x7d, 0x88, 0xa1, 0x48, 0x62, 0x92, 0x81, 0x91, 0x21, 0x87, 0xbb, 0x1e, 0xdb, 0xa9, 0x33, 0x08, 0x2e, 0x80, 0x9b, 0xda, 0xc7, 0xf6, 0x00, 0xe5, 0x75, 0xe8, 0x86, 0xbe, 0x07, 0xa7, 0xda, 0xfd, 0x7d, 0x1f, 0xe8, 0x9e, 0x5d, 0xa5, 0xd8, 0x9d, 0x2f, 0xab, 0x7b, 0xad, 0x7a, 0xcf, 0x82, 0x20, 0xc2, 0x05, 0x46, 0x5f, 0x5a, 0xd5, 0xf4, 0x94, 0x0c, 0xf2, 0x60, 0x54, 0xf5, 0x96, 0xd0, 0x75, 0x0d, 0x71, 0x8d, 0x5d, 0x38, 0x17, 0x00, 0x74, 0xdc, 0x35, 0xa8, 0x87, 0x57, 0x03, 0x45, 0x4a, 0xd8, 0xb1, 0xdc, 0x3d, 0x67, 0xc4, 0x9b, 0xa7, 0x2f, 0xb2, 0xaa, 0x76, 0x4d, 0x20, 0x6a, 0x23, 0xb5, 0x8f, 0xc8, 0xf6, 0xfc, 0x72, 0x88, 0x48, 0x07, 0xdf, 0xc7, 0x9d, 0x00, 0x69, 0x08, 0xac, 0x02, 0xc7, 0x8d, 0xc5, 0x60, 0x5f, 0xde, 0x13, 0x88, 0xd6, 0xa2, 0xb4, 0xc8, 0x3b, 0x4f, 0xab, 0x94, 0x70, 0x41, 0x1a, 0x05, 0xe4, 0x35, 0x52, 0xa4, 0xc8, 0x4d, 0xa1, 0xd7, 0x46, 0x0d, 0xed, 0x6a, 0x70, 0xff, 0x8b, 0x0d, 0xe5, 0xdb, 0xd1, 0xd2, 0x6d, 0x79, 0x64, 0xf0, 0xfe, 0xdb, 0x38, 0x5b, 0xeb, 0x19, 0xc0, 0x03, 0x3f, 0x00, 0xcc, 0xb9, 0x73, 0xa6, 0x0b, 0x11, 0x07, 0x4b, 0x3a, 0xca, 0xb6, 0x48, 0x67, 0x86, 0x3a, 0xe7, 0xde, 0xe0, 0xec, 0x54, 0x9f, 0x25, 0xa7, 0x1d, 0x78, 0x50, 0xbf, 0xdf, 0x22, 0xfb, 0xf8, 0x15, 0xf4, 0x60, 0xc4, 0x31, 0x16, 0xb6, 0x39, 0x6a, 0x42, 0x73, 0x88, 0xf6, 0x77, 0x3b, 0xe6, 0x86, 0x3b, 0x95, 0x2b, 0x4c, 0x43, 0x9a, 0x97, 0xd9, 0x9d, 0x4e, 0x8c, 0x9b, 0xbf, 0x46, 0x2a, 0xd6, 0x0f, 0xc9, 0x07, 0x41, 0xc3, 0xa5, 0x8f, 0xc8, 0x39, 0x48, 0xb9, 0x07, 0x1a, 0xee, 0x15, 0x74, 0xed, 0xea, 0x65, 0x6e, 0xf1, 0x57, 0x51, 0x86, 0x5c, 0xc1, 0xd8, 0xc7, 0x59, 0x8f, 0x91, 0xd5, 0x62, 0x36, 0xe9, 0x1e, 0xd4, 0x8e, 0xe0, 0x78, 0xd7, 0xc2, 0x02, 0xf0, 0xf5, 0xb5, 0x95, 0xa0, 0xfc, 0xed, 0x3c, 0xbb, 0x0f, 0x37, 0x7f, 0x50, 0xf1, 0xac, 0x0c, 0x50, 0xf7, 0xd7, 0x90, 0xdd, 0x39, 0xff, 0x7d, 0x01, 0xd1, 0xf8, 0x26, 0x3d, 0x59, 0xeb, 0xfc, 0x9a, 0xf0, 0xfb, 0xdc, 0x2b, 0x77, 0xbe, 0xb3, 0x29, 0xc6, 0xe9, 0xee, 0x17, 0x17, 0xa5, 0x75, 0x99, 0xe3, 0x72, 0x2d, 0xea, 0xe3, 0x8e, 0x39, 0x1c, 0x06, 0x3b, 0x81, 0x93, 0x7d, 0x65, 0x28, 0x60, 0x39, 0x7e, 0x00, 0x6d, 0x6d, 0x93, 0x33, 0xa1, 0x04, 0xf0, 0x8e, 0x6f, 0x13, 0xd5, 0x44, 0x78, 0xac, 0x08, 0x10, 0x2c, 0xb3, 0x62, 0xf8, 0x8f, 0x81, 0x85, 0x33, 0xa6, 0x89, 0x63, 0xe8, 0x13, 0x3f, 0x4f, 0xbe, 0xf0, 0xf4, 0xb3, 0x87, 0xff, 0x7a, 0xa5, 0x73, 0x9e, 0xa9, 0xfa, 0x8f, 0x37, 0x24, 0x97, 0x88, 0x07, 0xff, 0x0e, 0xf7, 0x74, 0x17, 0xd7, 0xa3, 0x58, 0x44, 0xac, 0x83, 0xf6, 0xb6, 0xd7, 0x75, 0x73, 0x24, 0x7c, 0xe1, 0x14, 0x9e, 0x32, 0xd8, 0xa1, 0x24, 0x66, 0x4e, 0x94, 0x62, 0x6d, 0x86, 0x16, 0x23, 0x38, 0xd8, 0xd4, 0x5f, 0x07, 0x5b, 0x3f, 0xfa, 0x9d, 0x26, 0xc1, 0x98, 0xce, 0x28, 0xe8, 0x1c, 0x5f, 0xd4, 0xa7, 0xa8, 0x96, 0x18, 0x27, 0x51, 0xff, 0x60, 0xc2, 0xbf, 0x31, 0xa1, 0x23, 0x7e, 0x9c, 0xa3, 0xaf, 0xb4, 0xbd, 0x0b, 0xa5, 0x7b, 0x25, 0xdf, 0xa2, 0x21, 0x43, 0x80, 0x75, 0xfa, 0xe0, 0x59, 0x6f, 0x97, 0xa5, 0xb3, 0x93, 0x82, 0x3f, 0x84, 0x65, 0xdc, 0xd9, 0x11, 0x30, 0x72, 0x09, 0xc0, 0xf8, 0x36, 0x77, 0x84, 0x86, 0x1b, 0xc8, 0xa1, 0x37, 0xd1, 0x99, 0xc8, 0x77, 0xe6, 0x98, 0xcb, 0x1a, 0x2d, 0x07, 0x50, 0xfe, 0x8f, 0x34, 0x61, 0x99, 0x99, 0xb2, 0xb5, 0x71, 0x67, 0x60, 0xff, 0x96, 0xc8, 0x87, 0xbe, 0x95, 0xb2, 0x9f, 0x43, 0x95, 0x6d, 0x86, 0xf1, 0x7a, 0x07, 0x35, 0xeb, 0x49, 0xed, 0x36, 0xb6, 0x32, 0xcf, 0x7f, 0x80, 0xeb, 0x1d, 0x5d, 0x0f, 0x4f, 0xc8, 0x9a, 0x92, 0x64, 0x11, 0x12, 0xd4, 0x37, 0x9b, 0x54, 0x81, 0x44, 0xfd, 0x15, 0x8d, 0x42, 0x8b, 0x76, 0xdd, 0x92, 0x23, 0x83, 0xd3, 0xb0, 0x22, 0x57, 0x4e, 0x5e, 0xd4, 0xcf, 0x43, 0x67, 0x03, 0xc1, 0x0e, 0x31, 0x7e, 0x10, 0x03, 0x86, 0xb8, 0x28, 0xfb, 0x40, 0xce, 0xa3, 0xd4, 0xc5, 0xa2, 0x32, 0x2a, 0x7c, 0xdb, 0x0f, 0xb6, 0xab, 0xea, 0x84, 0x1b, 0x68, 0x6b, 0x4e, 0x1c, 0x89, 0x8b, 0xf3, 0x6f, 0xc0, 0x3e, 0x51, 0xaf, 0x4f, 0x6c, 0xef, 0x32, 0xf9, 0x70, 0xe3, 0xa3, 0x2f, 0x81, 0x50, 0xbe, 0x86, 0xe7, 0xd4, 0x95, 0x0b, 0x0b, 0x66, 0x1e, 0xf2, 0xd5, 0x78, 0x08, 0xb9, 0xd8, 0x64, 0x11, 0xc9, 0x43, 0x74, 0x5f, 0x14, 0x9e, 0x10, 0x8f, 0x54, 0xb7, 0xdb, 0x78, 0xdc, 0x63, 0xcd, 0xe8, 0x21, 0xdc, 0x9b, 0xc9, 0x6a, 0xf1, 0xed, 0x70, 0x5b, 0x48, 0x3d, 0x18, 0x30, 0x64, 0x5a, 0xb8, 0xf6, 0x47, 0xef, 0xbe, 0x0a, 0xbb, 0x87, 0x5c, 0xa8, 0xbd, 0xe6, 0x78, 0x61, 0x82, 0xbb, 0x5d, 0xb1, 0x14, 0x05, 0xcd, 0x1a, 0x8a, 0xa1, 0x0d, 0x75, 0x3f, 0xe1, 0x02, 0x5c, 0xaf, 0x31, 0x8a, 0xe7, 0xc3, 0x0c, 0x99, 0x1c, 0xb3, 0xe5, 0xca, 0xc1, 0xdd, 0xb2, 0x6a, 0x83, 0x21, 0x3e, 0x36, 0x8f, 0xad, 0x84, 0x44, 0x1d, 0x46, 0x99, 0xd7, 0x86, 0x78, 0xfd, 0x1f, 0xdb, 0x3c, 0x57, 0x10, 0x2e, 0xf8, 0xe8, 0xe3, 0xe6, 0xfa, 0x4c, 0xea, 0xe0, 0xb8, 0x41 }; +constexpr AccessUnit ATRACX_SKIP_BYTES_EXPECTED_AU = { 0x15f90, 0x153d5, false, 0, {}, { 0x8a, 0x7b, 0xc9, 0x69, 0xee, 0xca, 0xcb, 0xab, 0xc6, 0x61, 0xa1, 0xf4, 0x75, 0x2e, 0x59, 0xb5, 0xf2, 0x90, 0x9d, 0x29 } }; + +const std::vector AC3_SKIP_BYTES_STREAM = { 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xf3, 0x3b, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0x7a, 0x01, 0xe0, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x1a, 0x00, 0x80, 0x20, 0x90, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x00, 0x01, 0xbd, 0x07, 0x5a, 0x81, 0xc1, 0x0d, 0x31, 0x00, 0x05, 0xbf, 0x21, 0x11, 0x00, 0x05, 0xa7, 0xab, 0x1e, 0x73, 0x3b, 0x30, 0x05, 0x05, 0x00, 0x0b, 0x77, 0xf4, 0x4b, 0x1b, 0x17, 0x5a, 0xaf, 0x1a, 0x24, 0x2c, 0x25, 0xa4, 0x37, 0x51, 0x53, 0xb0, 0x42, 0x4c, 0x69, 0x01, 0x21, 0x3f, 0x19, 0xf9, 0xfe, 0x1f, 0x8c, 0x15, 0x45, 0x98, 0xc8, 0x74, 0xa5, 0x58, 0x15, 0xba, 0xfd, 0xc4, 0x76, 0xf0, 0x2d, 0x4c, 0x44, 0x42, 0x21, 0xe0, 0x5a, 0xa7, 0xab, 0x3c, 0x92, 0xdf, 0xdf, 0x11, 0x67, 0x62, 0x1a, 0x35, 0xf5, 0x0b, 0xea, 0x6d, 0xc4, 0xb5, 0x70, 0x78, 0xfd, 0x0b, 0xfc, 0x67, 0x0b, 0x41, 0x02, 0x74, 0xba, 0x7d, 0x9c, 0xd8, 0x5a, 0x13, 0x3c, 0x59, 0x7a, 0xf9, 0x42, 0x91, 0x37, 0x02, 0xa3, 0x29, 0x4c, 0xc0, 0xc1, 0x7c, 0x3e, 0x2f, 0x2e, 0x6c, 0x62, 0x7b, 0x04, 0x54, 0xa4, 0x88, 0xeb, 0x67, 0x33, 0x0b, 0x1e, 0xe5, 0x8a, 0x60, 0xf1, 0xec, 0x79, 0x67, 0xa7, 0xe1, 0x1d, 0x17, 0xaa, 0xad, 0xf7, 0x8e, 0x68, 0x42, 0x86, 0xd2, 0x66, 0x31, 0x17, 0x86, 0x59, 0x41, 0xb0, 0x43, 0x42, 0x4b, 0x4e, 0x68, 0xef, 0xd5, 0xd3, 0x7d, 0x5a, 0x24, 0x5c, 0x85, 0xba, 0xc9, 0xde, 0xe1, 0x54, 0xda, 0x4e, 0x93, 0x52, 0x60, 0xa0, 0x0f, 0x32, 0xaa, 0x60, 0xe8, 0x93, 0x88, 0xcd, 0xf5, 0x76, 0xaa, 0x9d, 0xd4, 0x2d, 0x9a, 0xd3, 0xdf, 0x9c, 0x16, 0x62, 0xf5, 0x7f, 0xb6, 0x76, 0xa5, 0xdb, 0x2d, 0x9f, 0xaf, 0xc8, 0x9b, 0x42, 0xdd, 0x3f, 0x9b, 0xf8, 0xa6, 0xa0, 0x26, 0xd2, 0x26, 0x0a, 0x71, 0xa8, 0x52, 0xc9, 0x4c, 0xdb, 0x7f, 0x6d, 0xb8, 0x40, 0x9a, 0x4c, 0xb6, 0x12, 0xad, 0x8a, 0x86, 0x2b, 0x88, 0xe4, 0xdb, 0xd9, 0xb4, 0xcf, 0xad, 0x0d, 0x04, 0xbf, 0xbd, 0xc7, 0x60, 0x95, 0xf4, 0xea, 0xa9, 0x89, 0x25, 0xf1, 0xd6, 0x19, 0xe6, 0x1d, 0x9d, 0xca, 0x7d, 0x16, 0x45, 0xc4, 0x29, 0x27, 0x88, 0x96, 0x2d, 0x85, 0x94, 0xb8, 0x6e, 0x42, 0x8f, 0x85, 0x93, 0xe7, 0x32, 0xc1, 0xe9, 0xd2, 0x65, 0x06, 0x84, 0xcf, 0xe7, 0x82, 0x5e, 0x97, 0x6a, 0xf9, 0x64, 0x17, 0xbe, 0xfb, 0xbe, 0xbb, 0xdc, 0xa1, 0xc1, 0x18, 0xfe, 0x65, 0x4e, 0xac, 0x13, 0xda, 0x91, 0xa5, 0x2f, 0x4f, 0x69, 0xc3, 0xd5, 0xad, 0xec, 0xe2, 0x34, 0x19, 0xc4, 0xbc, 0xb2, 0x2b, 0x65, 0xe2, 0x6d, 0xba, 0x51, 0x06, 0x76, 0x9c, 0xed, 0x1a, 0xf8, 0xd2, 0xa4, 0xd6, 0xa4, 0xfa, 0x46, 0xa4, 0xef, 0x0f, 0xf3, 0x14, 0x0e, 0xbf, 0x03, 0x4b, 0xc5, 0xe8, 0xa0, 0x12, 0x6a, 0x06, 0x21, 0x73, 0xac, 0x9e, 0x53, 0x18, 0x0a, 0xf3, 0x2a, 0xc8, 0x0c, 0x91, 0xa8, 0xbd, 0x98, 0x76, 0xe2, 0xbc, 0x0c, 0xea, 0x69, 0x10, 0xe5, 0x53, 0x93, 0xe0, 0x27, 0x8a, 0x5b, 0x8f, 0xc9, 0x84, 0xdc, 0xfe, 0xd7, 0x56, 0x97, 0xf6, 0x14, 0xe5, 0x13, 0x10, 0x48, 0xc9, 0x77, 0xd4, 0x8a, 0x32, 0x3c, 0xfc, 0x25, 0xd9, 0x12, 0xf6, 0xf8, 0x51, 0x8d, 0x2c, 0x6a, 0x2f, 0x47, 0xa1, 0x4d, 0xf4, 0x7c, 0xea, 0x4f, 0xa9, 0x57, 0x9a, 0xcf, 0x86, 0x69, 0x96, 0x3e, 0x34, 0x13, 0x01, 0x58, 0x66, 0xce, 0xa2, 0xdd, 0xed, 0x98, 0xfa, 0xa5, 0x76, 0x02, 0x6a, 0x21, 0x9a, 0x95, 0x27, 0xb6, 0xf8, 0x8e, 0xd1, 0x79, 0x6e, 0x2e, 0xf0, 0x3e, 0xbd, 0x12, 0xb2, 0x05, 0x1e, 0x61, 0x9d, 0x24, 0x9f, 0xb4, 0x25, 0xdb, 0x47, 0x08, 0x42, 0x0f, 0x54, 0x29, 0x8e, 0x65, 0x24, 0x5d, 0x75, 0x07, 0x87, 0x42, 0x81, 0xbe, 0x93, 0x1c, 0xd9, 0x26, 0x44, 0x16, 0x6f, 0x35, 0x6b, 0x2a, 0x78, 0x56, 0xbe, 0xb2, 0x2b, 0xcb, 0x1f, 0xd5, 0xea, 0x1f, 0x51, 0x5d, 0x3d, 0xd1, 0xb9, 0x9a, 0x54, 0x8b, 0xea, 0x6b, 0xfd, 0x8b, 0x19, 0x86, 0x2b, 0x11, 0xad, 0xa2, 0x8d, 0xed, 0x8f, 0x1c, 0xd2, 0x96, 0xf6, 0x2c, 0x93, 0x5a, 0xbf, 0xd6, 0x01, 0x7f, 0xa6, 0x1c, 0xcf, 0x85, 0xd7, 0x2c, 0x00, 0xcc, 0xc0, 0x80, 0x7c, 0x51, 0x13, 0x34, 0xaf, 0x4b, 0x59, 0x06, 0x80, 0xce, 0x95, 0xc7, 0x63, 0xd5, 0xcf, 0x2c, 0x6c, 0x3c, 0x87, 0x44, 0x89, 0xa0, 0x5f, 0x0a, 0x54, 0x26, 0x94, 0xd6, 0x28, 0x9d, 0xfc, 0x9f, 0x69, 0x86, 0xac, 0x52, 0x22, 0xe7, 0x80, 0xb7, 0x6e, 0x00, 0x1a, 0xa1, 0x53, 0x44, 0x27, 0x61, 0xfb, 0x29, 0xe8, 0xbe, 0x7b, 0xb4, 0x5f, 0xed, 0x8c, 0xdb, 0x96, 0x3e, 0xf1, 0x10, 0xe4, 0x85, 0x61, 0xa1, 0x20, 0x70, 0x35, 0xb9, 0x2e, 0x4e, 0x35, 0x2c, 0x51, 0x03, 0x43, 0x5a, 0x2d, 0x1b, 0xba, 0xda, 0x6b, 0x46, 0xc0, 0xb3, 0x5a, 0xb0, 0xed, 0x50, 0x1b, 0xf1, 0xf3, 0x7f, 0x12, 0x98, 0x38, 0x20, 0xc0, 0x83, 0x8c, 0x5c, 0x41, 0x88, 0x63, 0x7f, 0xff, 0x2a, 0x42, 0xd1, 0x66, 0x50, 0x53, 0x0f, 0xa9, 0x42, 0x38, 0x59, 0xdb, 0x61, 0xa0, 0xb6, 0xf1, 0x5d, 0x39, 0x86, 0x74, 0xdf, 0xf4, 0x84, 0xf0, 0xe3, 0xc2, 0x2d, 0x6e, 0x45, 0x3b, 0xac, 0x7e, 0x38, 0xd8, 0xa8, 0xaa, 0x9b, 0xa8, 0x8b, 0x52, 0x7c, 0xb7, 0x25, 0x3e, 0x33, 0x84, 0xc0, 0x7c, 0xd6, 0x45, 0x05, 0x4d, 0x05, 0xd0, 0x52, 0x2b, 0x4b, 0x63, 0x4d, 0x3b, 0x8a, 0xb7, 0xe9, 0xbc, 0x31, 0xff, 0x21, 0x26, 0x38, 0xce, 0x15, 0x28, 0x23, 0x02, 0x5b, 0xb5, 0x7d, 0x2a, 0xa6, 0xb5, 0x92, 0x0a, 0x22, 0x34, 0x5a, 0x3a, 0x12, 0xfb, 0xdd, 0xf0, 0xa1, 0x05, 0x80, 0x80, 0xef, 0x3b, 0xff, 0x24, 0xc3, 0x5a, 0x0a, 0x0d, 0x78, 0x03, 0xc9, 0xd6, 0x01, 0x44, 0xba, 0xd7, 0x24, 0x27, 0xad, 0xf0, 0x44, 0x12, 0xd2, 0xd5, 0x53, 0x03, 0x1c, 0xdf, 0xd4, 0xf9, 0x74, 0xf7, 0xfd, 0x10, 0x6f, 0x2a, 0x58, 0x1a, 0x96, 0xe2, 0x82, 0xcd, 0x64, 0xe2, 0xe4, 0xc6, 0x88, 0x84, 0x7b, 0xf2, 0x27, 0xd4, 0x18, 0x25, 0x05, 0x77, 0xa4, 0xf6, 0xf1, 0x98, 0x53, 0x1c, 0xd5, 0x2f, 0xd5, 0xe5, 0x33, 0x67, 0xef, 0x8e, 0x06, 0xfd, 0x07, 0x85, 0x4e, 0xc8, 0x92, 0xe8, 0xab, 0xe1, 0x6d, 0xca, 0xe2, 0x05, 0x8e, 0x01, 0x2e, 0x2c, 0x9b, 0x9f, 0xa8, 0x79, 0x4f, 0x45, 0x3a, 0xf0, 0xbd, 0xf9, 0xdf, 0xa5, 0xda, 0x33, 0x28, 0x43, 0xde, 0x3d, 0x45, 0x20, 0x60, 0x2b, 0x08, 0x4e, 0x44, 0xf6, 0xa5, 0x48, 0xdb, 0x8c, 0x2d, 0x31, 0xd1, 0xda, 0xf1, 0xd2, 0xbd, 0x20, 0x5a, 0xb6, 0x7e, 0x1d, 0xed, 0x22, 0xaf, 0xda, 0x6e, 0xcc, 0xe2, 0x1e, 0x6c, 0x74, 0x65, 0xe5, 0xaa, 0xe0, 0xcb, 0x53, 0x1d, 0xd4, 0x78, 0x00, 0x86, 0xfa, 0xe2, 0x97, 0xe0, 0xe9, 0x57, 0x2b, 0x13, 0xaf, 0x66, 0xb7, 0xba, 0x91, 0x4a, 0xa6, 0xec, 0xe5, 0xf1, 0x61, 0x4a, 0x44, 0x7c, 0x3e, 0xc1, 0x62, 0x52, 0x51, 0xd7, 0x56, 0x20, 0xea, 0x61, 0x2c, 0x70, 0xdb, 0xee, 0xf7, 0x9b, 0xba, 0x64, 0xc1, 0x48, 0xc1, 0x87, 0x16, 0xc8, 0x10, 0x5e, 0x10, 0xef, 0x55, 0xc7, 0x03, 0x45, 0x35, 0x9f, 0x51, 0xac, 0xf2, 0x48, 0xed, 0xd5, 0x2f, 0x89, 0xa3, 0x20, 0xc0, 0xf6, 0x29, 0xca, 0xf4, 0x74, 0x81, 0x7a, 0xc8, 0x79, 0x4d, 0x8c, 0xe4, 0x20, 0xff, 0xc3, 0x5e, 0x32, 0x18, 0x24, 0x99, 0xba, 0xde, 0x33, 0xd0, 0xc6, 0x2f, 0xda, 0x03, 0x6d, 0x6d, 0x9a, 0x72, 0x39, 0xa0, 0xe9, 0xd5, 0x8a, 0x3d, 0xd4, 0xef, 0x9a, 0x43, 0x3d, 0x43, 0x34, 0x9c, 0x57, 0xf1, 0x3f, 0xdf, 0x3f, 0x12, 0xae, 0xef, 0xc2, 0x15, 0x8e, 0x22, 0xb8, 0xf2, 0x23, 0xcd, 0x8c, 0x32, 0x5c, 0x71, 0xc3, 0x2c, 0x13, 0xf2, 0xb7, 0xeb, 0xd7, 0x7b, 0xc4, 0xa1, 0x41, 0x04, 0x9a, 0x9b, 0x02, 0xa5, 0x82, 0x18, 0x38, 0x1e, 0xb8, 0x83, 0xbd, 0x44, 0x3d, 0xd9, 0x61, 0x39, 0xa6, 0x55, 0x66, 0xa6, 0xe4, 0x9c, 0xa0, 0x56, 0x03, 0x07, 0x01, 0xea, 0x51, 0xc6, 0x8f, 0x87, 0x80, 0xf9, 0xf6, 0xaf, 0x9c, 0xf8, 0x3d, 0xb9, 0xfb, 0x6c, 0x57, 0x84, 0x77, 0xeb, 0x83, 0x5c, 0x9d, 0x43, 0xc4, 0x3a, 0x9d, 0x9d, 0xe6, 0xd0, 0x1e, 0x1f, 0xce, 0xfc, 0x56, 0xcf, 0x0d, 0xa9, 0x00, 0xbf, 0xf9, 0x33, 0x02, 0xd5, 0xc2, 0xc0, 0xf1, 0xb8, 0x44, 0x46, 0xbc, 0xaf, 0x89, 0x14, 0x2c, 0x7a, 0x45, 0x20, 0x05, 0x7a, 0xbd, 0x7a, 0xf2, 0xa6, 0xd6, 0x8d, 0x89, 0x2c, 0x4c, 0x24, 0x14, 0xb3, 0x4e, 0x5c, 0xeb, 0xa2, 0xf3, 0xea, 0x87, 0xe3, 0x4e, 0x62, 0xa4, 0xfe, 0x16, 0x74, 0x0d, 0x8a, 0x1e, 0x3d, 0xf5, 0x52, 0x22, 0x26, 0xee, 0xa2, 0x96, 0xf0, 0xe5, 0xa1, 0x81, 0xe3, 0xbb, 0xb1, 0x9a, 0x4a, 0x51, 0x2a, 0x1d, 0xa0, 0x2d, 0xfe, 0x25, 0x25, 0x0b, 0x07, 0x73, 0xc3, 0x03, 0x19, 0xe8, 0x69, 0x0a, 0x19, 0x37, 0x56, 0x03, 0xac, 0x71, 0xea, 0xa9, 0x47, 0x88, 0x08, 0xf9, 0xa6, 0xe8, 0x10, 0xf5, 0x0a, 0xb4, 0x00, 0xd6, 0xac, 0x5d, 0x4f, 0x13, 0x4d, 0x8a, 0x7b, 0xd3, 0xde, 0x9e, 0x72, 0xa6, 0x96, 0x3e, 0x42, 0xa7, 0xf3, 0xab, 0xb7, 0x56, 0x8a, 0xdd, 0xe7, 0xd4, 0x97, 0xa6, 0xb4, 0x5b, 0xb3, 0x4f, 0xdb, 0xfc, 0x24, 0x6b, 0x13, 0x1f, 0xa5, 0xed, 0x4b, 0x44, 0xa8, 0xa1, 0x19, 0xee, 0x65, 0xa2, 0xd5, 0xd4, 0x38, 0x6d, 0x05, 0xb3, 0x2a, 0xa2, 0x08, 0x58, 0x9a, 0xa7, 0x33, 0xc8, 0x6b, 0xa7, 0xb6, 0x99, 0x33, 0xac, 0x1a, 0xd8, 0x3a, 0xcd, 0x15, 0x25, 0x56, 0xb5, 0x13, 0xcc, 0xf4, 0xef, 0xb0, 0x0b, 0x77, 0xc4, 0xf4, 0x1b, 0x3c, 0x9c, 0x29, 0x93, 0xd9, 0x20, 0x7a, 0x4a, 0x4a, 0x9d, 0xcd, 0x2d, 0x39, 0x5f, 0x7f, 0x2b, 0x8b, 0x04, 0xf0, 0x46, 0xde, 0x02, 0x08, 0xed, 0x87, 0xd6, 0x25, 0x46, 0xa8, 0xa3, 0x1c, 0xec, 0x28, 0x36, 0x3a, 0x98, 0x93, 0xac, 0x6d, 0xae, 0x3f, 0x32, 0x0b, 0xbd, 0x29, 0xa6, 0xd4, 0x47, 0x69, 0x0d, 0x27, 0x7d, 0x48, 0x15, 0x97, 0xc3, 0x36, 0x2b, 0x3d, 0x13, 0x3b, 0xde, 0x86, 0xa9, 0xaa, 0x7e, 0x5f, 0x7e, 0x1c, 0x49, 0xe4, 0x8a, 0x0b, 0x8d, 0x13, 0xd1, 0x8b, 0x8a, 0x1b, 0xa2, 0xfb, 0x08, 0x38, 0xa2, 0xb1, 0xdd, 0x50, 0x82, 0xeb, 0xe7, 0xb3, 0x79, 0x9c, 0x2d, 0xb1, 0xd7, 0xd3, 0x24, 0xf1, 0x60, 0xda, 0x59, 0xa8, 0x34, 0x42, 0xf9, 0x3b, 0x75, 0x7b, 0xf5, 0xce, 0xf3, 0xbc, 0xb7, 0xd6, 0x91, 0x4b, 0xae, 0xb8, 0x26, 0x67, 0x27, 0xf6, 0x06, 0x6f, 0x30, 0x8f, 0x93, 0x07, 0x7f, 0x7c, 0x5e, 0x49, 0xa3, 0x7a, 0xc8, 0x4f, 0xe6, 0x8b, 0x37, 0xa9, 0xb7, 0xd8, 0x38, 0x7a, 0x84, 0xe7, 0x2d, 0x5a, 0x42, 0x49, 0x6a, 0x3c, 0x2c, 0x2a, 0xcc, 0xf1, 0x66, 0x85, 0x39, 0xff, 0x89, 0xc2, 0x99, 0xf6, 0x50, 0x0c, 0x25, 0x6e, 0xe4, 0xc2, 0x2e, 0x59, 0x83, 0x99, 0xb1, 0x57, 0x7a, 0x87, 0x5a, 0x36, 0xb4, 0x6e, 0xd1, 0xd2, 0x5a, 0x28, 0x61, 0xed, 0x35, 0x6f, 0x6d, 0xc6, 0xde, 0xb6, 0x3a, 0x85, 0xef, 0x06, 0xef, 0xb2, 0xac, 0x50, 0xf0, 0x62, 0xf0, 0xe6, 0xe2, 0xc9, 0x48, 0x03, 0x02, 0x4d, 0x85, 0x8b, 0xa0, 0x64, 0x3a, 0x79, 0xde, 0xc6, 0xe6, 0x99, 0x15, 0xbe, 0xc1, 0x82, 0x6b, 0xac, 0x72, 0x03, 0x8d, 0xfe, 0x17, 0x5d, 0x99, 0x31, 0x78, 0x06, 0x93, 0x9b, 0x42, 0xdd, 0x10, 0x1f, 0x98, 0xf3, 0xe0, 0x02, 0x79, 0x5f, 0xe3, 0x72, 0xa6, 0xc6, 0x5b, 0x9a, 0x18, 0x82, 0x5b, 0x37, 0x2f, 0x91, 0x2b, 0x0e, 0x25, 0xc0, 0xca, 0xc4, 0x7d, 0xb6, 0xd2, 0xeb, 0x60, 0xce, 0x76, 0x42, 0x36, 0xf0, 0x5f, 0x8e, 0xe7, 0xcc, 0x91, 0x7b, 0x87, 0x2c, 0xaf, 0x63, 0x6c, 0x46, 0x3d, 0x04, 0xe1, 0x34, 0xb8, 0x6d, 0xf9, 0x08, 0xa6, 0xb1, 0x40, 0x25, 0xee, 0x2b, 0x3d, 0xbf, 0x29, 0x5e, 0x0b, 0xbf, 0xaf, 0xc1, 0x79, 0x68, 0x8d, 0xfe, 0x7e, 0x76, 0xc1, 0x74, 0xec, 0x93, 0x47, 0x06, 0xa5, 0x62, 0xe8, 0x7e, 0xd8, 0x77, 0xd5, 0x1f, 0xe9, 0xf9, 0x7d, 0x23, 0x1a, 0xcf, 0x22, 0x30, 0x27, 0x90, 0x24, 0x25, 0x48, 0x8f, 0x03, 0xae, 0x64, 0xc1, 0x8a, 0x80, 0x67, 0x63, 0xb6, 0x44, 0xff, 0x88, 0x31, 0x75, 0x2e, 0x02, 0x84, 0xca, 0x83, 0x48, 0x56, 0xeb, 0xda, 0x51, 0x5f, 0x89, 0x00, 0x8a, 0xd9, 0x1a, 0x91, 0x50, 0x9f, 0xcf, 0xf6, 0x9f, 0x43, 0x89, 0x56, 0xe0, 0xc8, 0xd9, 0xd4, 0x04, 0xd1, 0x5d, 0x8a, 0x52, 0x62, 0x01, 0xfd, 0x9f, 0x96, 0xf3, 0x05, 0xca, 0xdf, 0x4d, 0x6b, 0xc5, 0xaa, 0xd3, 0xb4, 0x6f, 0x93, 0x3d, 0xd6, 0x17, 0x6a, 0xe9, 0xd0, 0x6d, 0xbf, 0xf3, 0x6e, 0x29, 0xc5, 0x11, 0x9e, 0xc6, 0xa3, 0xa9, 0x2b, 0xfe, 0x9e, 0xfd, 0xc7, 0xf7, 0xa7, 0x77, 0xa7, 0x4e, 0x3a, 0x58, 0x37, 0x64, 0x97, 0x65, 0x88, 0xa2, 0xc3, 0x4a, 0x94, 0x9c, 0xe4, 0xd6, 0x7b, 0x3e, 0xd2, 0x45, 0x41, 0x6e, 0xff, 0x39, 0xc4, 0xd9, 0x11, 0x1f, 0xee, 0xc4, 0xc2, 0x11, 0x53, 0x26, 0xee, 0x84, 0xc1, 0x59, 0xe3, 0x48, 0x76, 0x2f, 0x54, 0xaf, 0x04, 0x39, 0x80, 0xd8, 0x0f, 0x7f, 0x7e, 0x7d, 0x6d, 0x11, 0xb3, 0xbe, 0x63, 0x18, 0xd9, 0xc4, 0xef, 0x56, 0x3c, 0x3e, 0x74, 0x42, 0xef, 0x06, 0x1f, 0x2f, 0x36, 0x7d, 0xed, 0x20, 0x66, 0x6b, 0x25, 0x3d, 0xe3, 0x65, 0x9e, 0x1a, 0x17, 0x12, 0x42, 0x28, 0x7e, 0xd6, 0x87, 0x18, 0x22, 0xa9, 0xe3, 0x02, 0x25, 0x32, 0x71, 0x8d, 0x2a, 0x61, 0x43, 0x7a, 0xd2, 0x2e, 0x1f, 0x4b, 0x8a, 0x27, 0xa1, 0xdb, 0x60, 0xfa, 0x04, 0x32, 0xaa, 0x32, 0x02, 0xe0, 0xa3, 0xb6, 0x93, 0xa8, 0x5d, 0xe2, 0x83, 0x53, 0x93, 0x35, 0x17, 0xe1, 0x52, 0xee, 0x40, 0x81, 0x7c, 0x17, 0x20, 0xf9, 0x90, 0xde, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbd, 0x07, 0xec, 0x79, 0x01, 0x00, 0x30, 0x40, 0x7b, 0x72, 0x2a, 0xee, 0x84, 0xd7, 0xa4, 0x09, 0x4a, 0x05, 0xac, 0x4a, 0xac, 0x61, 0xf7, 0xf9, 0x62, 0xd3, 0x8d, 0x35, 0xe0, 0x7d, 0x1e, 0x7c, 0x57, 0xe5, 0xe0, 0x7c, 0x5a, 0x5d, 0x7e, 0xa1, 0xf1, 0xa4, 0x26, 0xe4, 0x34, 0xf2, 0xc7, 0xc8, 0x9d, 0xfc, 0xfe, 0x9e, 0xc3, 0x98, 0x51, 0x60, 0x29, 0x10, 0xab, 0xd4, 0x3b, 0x52, 0x44, 0xb9, 0xd0, 0x7e, 0x60, 0x3b, 0xa1, 0x93, 0x91, 0xe2, 0x9d, 0x2f, 0x66, 0xbf, 0x15, 0x9e, 0xbc, 0x97, 0x12, 0xbf, 0x0b, 0x37, 0x64, 0x6d, 0x74, 0x45, 0x29, 0x6f, 0x64, 0x2f, 0xf0, 0x2f, 0x02, 0x14, 0xa2, 0xa8, 0xde, 0xbe, 0xe4, 0x53, 0x7a, 0x0d, 0x9d, 0x0c, 0xa3, 0x6f, 0xbc, 0x23, 0xcb, 0x42, 0x8c, 0x20, 0xc5, 0x36, 0x16, 0xf0, 0x97, 0x14, 0x6d, 0x7a, 0x47, 0x7a, 0xdc, 0xcf, 0xda, 0x7d, 0x5a, 0x85, 0xe7, 0x2b, 0xb6, 0xdf, 0x68, 0x74, 0x63, 0xd7, 0xc5, 0xeb, 0xd3, 0x2d, 0x32, 0x5c, 0xc2, 0x13, 0xd5, 0x43, 0xfa, 0x18, 0x62, 0x80, 0x50, 0x5d, 0x19, 0xed, 0xf4, 0x4f, 0x44, 0xa5, 0x59, 0x5c, 0xbc, 0x2a, 0x3f, 0x60, 0x00, 0xac, 0xb7, 0xcf, 0xed, 0x2b, 0x15, 0xcc, 0x22, 0x3a, 0x3f, 0xb1, 0x95, 0x86, 0xbf, 0xbc, 0xf5, 0x80, 0x82, 0xeb, 0xd3, 0xc1, 0x3d, 0x33, 0xac, 0x06, 0xd4, 0x98, 0x53, 0xe6, 0x3b, 0xdf, 0x5a, 0x8b, 0xb1, 0xd8, 0x6c, 0x2b, 0x55, 0x75, 0xc0, 0xf5, 0x64, 0x36, 0x15, 0xae, 0xad, 0x9a, 0xe1, 0x4f, 0x08, 0x99, 0xa1, 0x36, 0xd4, 0x5f, 0x6f, 0xdb, 0xd6, 0xc7, 0x55, 0x0f, 0xf9, 0x4d, 0x02, 0x30, 0xc1, 0x7a, 0xca, 0xee, 0x76, 0x00, 0x25, 0x6b, 0x62, 0x04, 0x19, 0xed, 0x9d, 0x54, 0x2d, 0x6a, 0x3a, 0x82, 0xe4, 0x8f, 0xe6, 0x1f, 0xe1, 0x22, 0x3b, 0x9c, 0x21, 0xd9, 0x5e, 0x7c, 0xf8, 0xfb, 0xa8, 0xe1, 0xc0, 0x77, 0x71, 0xa9, 0x5f, 0x3d, 0x42, 0x9f, 0x19, 0xf9, 0xfd, 0x6f, 0x52, 0x95, 0xc5, 0x62, 0x31, 0x13, 0xb6, 0x21, 0x4a, 0xa0, 0xb5, 0xef, 0xc8, 0xfc, 0xe2, 0x24, 0xb0, 0x8f, 0x7e, 0xdb, 0x3d, 0xd0, 0x54, 0x10, 0x6d, 0xd1, 0xdf, 0xb0, 0x40, 0x0b, 0xce, 0x53, 0x3f, 0xd5, 0xa9, 0x9c, 0x4f, 0x0d, 0x9c, 0x76, 0xe4, 0xdc, 0xc9, 0xb9, 0x0f, 0xb5, 0x8f, 0xe1, 0x13, 0xd6, 0xad, 0xde, 0x65, 0x06, 0x40, 0x39, 0x47, 0x50, 0xe9, 0x03, 0x6d, 0xe2, 0xa7, 0x4f, 0x56, 0x76, 0x39, 0x35, 0x3d, 0xcb, 0x02, 0x95, 0xde, 0x22, 0xd1, 0x19, 0x70, 0xc2, 0x06, 0x30, 0x7c, 0xfc, 0xf2, 0x00, 0x8c, 0x2a, 0x68, 0x8d, 0xd3, 0xa7, 0xe1, 0x89, 0x35, 0xbf, 0xb2, 0x93, 0x6d, 0x05, 0x20, 0xd7, 0x2a, 0xa2, 0x67, 0x59, 0x5c, 0x80, 0xf9, 0x53, 0x18, 0x69, 0x7b, 0x76, 0xbb, 0x71, 0x61, 0xfe, 0x3f, 0x51, 0x16, 0xd8, 0xf0, 0x89, 0x21, 0x58, 0xdf, 0x6a, 0xac, 0x34, 0xcd, 0x55, 0x58, 0xd0, 0x7a, 0xe7, 0x5e, 0xff, 0x75, 0xcb, 0x43, 0xcc, 0xea, 0x71, 0xb6, 0xf9, 0x14, 0xea, 0x5f, 0x36, 0x3c, 0x93, 0xa8, 0x4a, 0x6f, 0x6b, 0xd3, 0xa6, 0x66, 0x2a, 0xe7, 0x2d, 0x36, 0x7d, 0x33, 0x12, 0xc8, 0xf5, 0x8e, 0x2a, 0x33, 0x99, 0x85, 0x10, 0x7a, 0x26, 0x12, 0xe5, 0x41, 0x5f, 0xa7, 0xae, 0x75, 0x0e, 0x8c, 0x77, 0x15, 0x85, 0xf7, 0xd3, 0x7a, 0xd0, 0x48, 0x59, 0xd9, 0xd7, 0x54, 0x31, 0xde, 0x2c, 0xb1, 0xe0, 0x96, 0x47, 0x67, 0xcd, 0x13, 0x58, 0x80, 0x4a, 0x6c, 0x0e, 0x47, 0x0c, 0x10, 0xe2, 0x49, 0x58, 0x9a, 0xd6, 0x60, 0x5d, 0x7f, 0xab, 0x4b, 0x7a, 0x5c, 0x01, 0xb4, 0x69, 0xbe, 0xef, 0x96, 0x8b, 0x91, 0xf4, 0x68, 0xd6, 0xb2, 0x5b, 0x83, 0x1a, 0x36, 0x75, 0xa2, 0x9c, 0x6a, 0x35, 0x78, 0x48, 0xac, 0x1f, 0xb5, 0xea, 0x8c, 0x94, 0xfc, 0x36, 0xda, 0xdf, 0x9f, 0x96, 0x9c, 0xa5, 0x21, 0xf9, 0x0b, 0x83, 0xd8, 0x21, 0x08, 0x07, 0x33, 0x2c, 0xb2, 0x5a, 0x6e, 0x4e, 0x0f, 0x30, 0xc4, 0x09, 0xed, 0xe6, 0x71, 0x43, 0x6d, 0xe2, 0xfe, 0x15, 0xe0, 0x96, 0xb6, 0x3a, 0xe1, 0xb8, 0x47, 0x5d, 0xdf, 0x9b, 0xdd, 0xca, 0x7c, 0xb8, 0x3c, 0x3c, 0x6a, 0xc6, 0xb5, 0xb6, 0xc3, 0xff, 0xf0, 0xbe, 0xf0, 0x73, 0xe5, 0x54, 0xa1, 0x75, 0x86, 0x86, 0x70, 0x91, 0xed, 0x7c, 0x29, 0x98, 0x15, 0x4c, 0xdd, 0xa9, 0x70, 0x0f, 0x26, 0x4e, 0xde, 0xe9, 0x59, 0x04, 0xd5, 0x0c, 0x7c, 0xd4, 0xcf, 0xef, 0x40, 0xd5, 0x33, 0x2e, 0x5d, 0xaf, 0x5e, 0xd8, 0x01, 0x7e, 0x8c, 0x24, 0x46, 0xb7, 0xa8, 0xc2, 0xc6, 0xdc, 0x5f, 0x53, 0xd4, 0x2d, 0xec, 0xb6, 0xef, 0xa5, 0x82, 0x2a, 0x65, 0xe3, 0x4b, 0x88, 0x59, 0xdd, 0x53, 0x05, 0x87, 0x75, 0xe4, 0x42, 0x7d, 0x50, 0x30, 0xa0, 0x3b, 0x8c, 0x34, 0x1c, 0x53, 0x26, 0x4a, 0x1c, 0x09, 0x3c, 0xce, 0x0a, 0x10, 0x7e, 0xc1, 0x92, 0xdd, 0x66, 0x61, 0xdb, 0xad, 0x20, 0x0f, 0x33, 0xbb, 0x31, 0x0a, 0xdc, 0x42, 0x3e, 0xc9, 0x03, 0x42, 0x93, 0x00, 0x1c, 0x2f, 0x40, 0xa8, 0x16, 0xf9, 0xe9, 0x0b, 0x77, 0x15, 0xa7, 0x8d, 0x65, 0x75, 0x99, 0x21, 0x9a, 0xa0, 0xf8, 0x08, 0x34, 0x49, 0xd1, 0x56, 0xa4, 0x21, 0xc1, 0x9b, 0x02, 0xc6, 0x4b, 0x65, 0xe9, 0xf8, 0xa5, 0xc1, 0x0f, 0x8e, 0x22, 0x94, 0x5b, 0xc9, 0x7c, 0xb4, 0x6d, 0xf5, 0xbd, 0xb0, 0xdf, 0x8c, 0x82, 0xb1, 0xa9, 0x35, 0xc8, 0xe1, 0x7b, 0x62, 0x99, 0x3e, 0xf6, 0x69, 0x36, 0xd4, 0x0c, 0x41, 0x95, 0xb3, 0xf9, 0x66, 0x5c, 0x2b, 0x99, 0x6c, 0x9f, 0x18, 0x16, 0x58, 0x18, 0x47, 0x25, 0xbd, 0xa0, 0x51, 0x56, 0x35, 0x0b, 0x5a, 0x26, 0xbe, 0xc8, 0xa0, 0xde, 0xfe, 0xdb, 0xcf, 0x75, 0x93, 0x13, 0x70, 0xec, 0xd2, 0x8e, 0xfe, 0xe3, 0xb4, 0xf3, 0x6f, 0x6d, 0xcb, 0xf3, 0x33, 0x4d, 0x75, 0xf8, 0x03, 0x25, 0xb6, 0x14, 0x02, 0x4e, 0x63, 0x93, 0x01, 0x5b, 0x90, 0xc5, 0xed, 0x76, 0x67, 0xe6, 0xbc, 0x21, 0xd8, 0x35, 0x59, 0x15, 0xc7, 0xa1, 0x65, 0x29, 0xb2, 0x99, 0xd5, 0x9b, 0xe9, 0xf2, 0xb7, 0x22, 0xd7, 0xe2, 0xaf, 0x81, 0xf3, 0x87, 0xf3, 0xb3, 0x59, 0x84, 0xd8, 0xc3, 0x2d, 0x9a, 0x31, 0xf9, 0x31, 0x51, 0x1b, 0xed, 0x42, 0x15, 0xf7, 0x9f, 0xa2, 0x5d, 0xa1, 0xb8, 0x42, 0xbc, 0x30, 0x7d, 0x6c, 0xf5, 0xcb, 0x30, 0x84, 0x70, 0x61, 0xcf, 0xcb, 0xaa, 0x50, 0x79, 0x48, 0x7f, 0x3c, 0xf5, 0x4b, 0x66, 0xb8, 0x10, 0x34, 0x00, 0x78, 0xcc, 0x67, 0x93, 0x21, 0xae, 0x9e, 0x48, 0x06, 0x8c, 0xfc, 0x55, 0x54, 0xb0, 0xa1, 0x62, 0x87, 0x3d, 0x8b, 0xce, 0x27, 0x14, 0x10, 0xa7, 0x1e, 0xbd, 0x49, 0x7b, 0x38, 0x04, 0x23, 0x57, 0x8e, 0x50, 0x00, 0x94, 0xf1, 0xef, 0x0c, 0x4a, 0xa3, 0xc7, 0xc4, 0x8a, 0xdb, 0x3a, 0x48, 0xb3, 0xf4, 0x2f, 0x71, 0x8c, 0x44, 0x78, 0xce, 0xeb, 0xee, 0x1a, 0xfe, 0x1c, 0x38, 0x34, 0x06, 0x51, 0x33, 0x6e, 0x9e, 0xbd, 0xc3, 0x4f, 0x92, 0x3e, 0x47, 0xcb, 0xb2, 0xa4, 0x86, 0xec, 0xea, 0xfe, 0x8d, 0x7b, 0x89, 0x81, 0xa2, 0xea, 0xc3, 0xe5, 0x94, 0xfd, 0xf5, 0x5b, 0xe6, 0xef, 0x49, 0x6c, 0xb6, 0x0f, 0xa8, 0x70, 0x5a, 0x06, 0x2a, 0x5f, 0x06, 0x58, 0x6a, 0x33, 0x10, 0xc6, 0x6e, 0x21, 0x8b, 0x9b, 0x15, 0x52, 0x51, 0x15, 0x21, 0xf6, 0xce, 0x76, 0x6c, 0xc9, 0x07, 0x6a, 0xcd, 0x68, 0xba, 0xbd, 0xba, 0x10, 0x90, 0xb0, 0xc1, 0xb0, 0xc7, 0x54, 0x43, 0x4f, 0xc7, 0xaf, 0x2e, 0x3e, 0x79, 0xab, 0x88, 0xa5, 0x71, 0x06, 0x10, 0x41, 0x2c, 0xbe, 0x54, 0x80, 0xf3, 0xba, 0xe4, 0x48, 0x33, 0xa8, 0xa1, 0x08, 0x51, 0x4d, 0x37, 0xf6, 0x45, 0xc6, 0x4b, 0x91, 0x8b, 0x6e, 0xf8, 0xbd, 0x38, 0x6e, 0x8c, 0x25, 0x3c, 0x31, 0xaa, 0xad, 0x15, 0x2f, 0x52, 0x1c, 0x95, 0xdc, 0x59, 0x57, 0x6e, 0xa5, 0x60, 0xc4, 0x9f, 0x43, 0x61, 0xbb, 0x0f, 0xdd, 0x3f, 0x16, 0xd3, 0xb2, 0x0e, 0x46, 0xfd, 0x4a, 0xfc, 0x80, 0xfb, 0x6b, 0xff, 0xe5, 0xc2, 0x47, 0xc1, 0xbc, 0x6d, 0xae, 0x66, 0x1f, 0x07, 0x2a, 0x2e, 0xb5, 0x8f, 0x58, 0x09, 0x4b, 0x89, 0xe8, 0x93, 0x82, 0xa8, 0x0b, 0x26, 0xca, 0x50, 0x48, 0xea, 0x6b, 0x0d, 0xee, 0x12, 0x5a, 0x3f, 0xaa, 0xad, 0x04, 0x90, 0xf4, 0xbb, 0x73, 0xf2, 0x54, 0x76, 0x4f, 0x48, 0xb9, 0xed, 0xb9, 0xeb, 0x5c, 0x70, 0xf9, 0xa9, 0xf0, 0x6a, 0x7a, 0x0d, 0x16, 0x9a, 0x9c, 0xe5, 0x59, 0xda, 0x3e, 0x6f, 0x1e, 0xd9, 0x1d, 0xa4, 0x55, 0x7e, 0x65, 0x75, 0xe3, 0xd5, 0x0d, 0x09, 0xf7, 0xbc, 0xd9, 0x3f, 0xd2, 0xb0, 0x26, 0x08, 0xb8, 0x79, 0xcd, 0x64, 0x06, 0x85, 0xce, 0x0a, 0xaf, 0x42, 0x89, 0x07, 0x8d, 0xba, 0xb2, 0xe6, 0x5c, 0x45, 0x4f, 0x2a, 0x39, 0x1f, 0x6b, 0x21, 0x05, 0x1c, 0x46, 0x64, 0x06, 0xe4, 0x37, 0x89, 0xa1, 0x64, 0x7d, 0xdb, 0x0d, 0x58, 0xc0, 0x17, 0x54, 0x28, 0xf7, 0x90, 0x07, 0x79, 0xf3, 0x26, 0x78, 0x1d, 0xcd, 0x00, 0x5f, 0x5a, 0xe9, 0xf7, 0x3c, 0xa6, 0x5d, 0x0f, 0xda, 0x4f, 0xdd, 0x88, 0xcd, 0xb1, 0x89, 0x48, 0xc6, 0xf2, 0x34, 0xbb, 0x13, 0x61, 0x07, 0x67, 0xbe, 0xf5, 0x94, 0xc7, 0xfd, 0x86, 0xc0, 0x38, 0x01, 0xc0, 0x0e, 0x01, 0x58, 0xe7, 0x3f, 0xc7, 0x52, 0xe8, 0x50, 0xf2, 0x41, 0x5b, 0x33, 0xd9, 0x6d, 0x69, 0xf3, 0xb8, 0x1c, 0xb3, 0xfc, 0xbe, 0x09, 0xbe, 0xce, 0xc1, 0x21, 0x75, 0x4b, 0x6a, 0x6e, 0xc1, 0x61, 0xce, 0x79, 0x61, 0xd2, 0xe6, 0x97, 0x5b, 0x48, 0x48, 0xe5, 0xd0, 0x02, 0x0e, 0xe5, 0x05, 0xc6, 0xe5, 0xff, 0xda, 0xdf, 0x99, 0x63, 0x1b, 0x5c, 0xa1, 0x01, 0x50, 0xd8, 0x7f, 0x9a, 0xff, 0x70, 0xff, 0x23, 0x88, 0xbf, 0x9d, 0xf5, 0x08, 0x03, 0xa1, 0x88, 0xf1, 0xc0, 0xbb, 0xb3, 0x42, 0x7d, 0x2e, 0xb3, 0x84, 0x7a, 0xd4, 0x6a, 0x05, 0x7e, 0x86, 0x9b, 0xf5, 0x13, 0xb6, 0x1d, 0x51, 0xcc, 0x47, 0x40, 0xc5, 0x73, 0xee, 0xde, 0x02, 0x45, 0xa6, 0xd9, 0x16, 0x7c, 0x08, 0x01, 0xd2, 0xeb, 0x90, 0x92, 0x54, 0x5c, 0x1a, 0xe1, 0x29, 0xf8, 0x23, 0xd2, 0xb4, 0xec, 0xa1, 0x32, 0xc0, 0x09, 0x70, 0x1a, 0x77, 0x21, 0xb1, 0xe5, 0x11, 0x52, 0x96, 0x70, 0x07, 0x88, 0x73, 0x9c, 0x99, 0xe6, 0x20, 0x5b, 0xe2, 0xda, 0xed, 0xae, 0xea, 0x12, 0xc1, 0x6e, 0x50, 0x99, 0x27, 0xb9, 0x8c, 0xc1, 0x58, 0x62, 0xec, 0xbd, 0x92, 0xc4, 0xb0, 0xf4, 0x41, 0xc4, 0x04, 0x7b, 0xca, 0xf8, 0xaf, 0x4a, 0x03, 0x2f, 0xb9, 0x0b, 0xa3, 0xde, 0x5c, 0x99, 0x3c, 0x19, 0x01, 0x90, 0x81, 0x35, 0x28, 0x91, 0xed, 0x2c, 0x6c, 0x02, 0x0f, 0x57, 0x10, 0x7a, 0x0f, 0x33, 0xbd, 0x2e, 0x34, 0x28, 0x61, 0xf6, 0x74, 0x96, 0x58, 0xca, 0x64, 0x9d, 0x4a, 0xdb, 0x03, 0x64, 0x74, 0x8f, 0x3f, 0xd0, 0x39, 0x1a, 0x36, 0xf1, 0x2e, 0x6c, 0x7c, 0xa0, 0x13, 0xb6, 0xf8, 0xfe, 0x5a, 0xc2, 0x27, 0xe7, 0x30, 0xcc, 0xc3, 0x78, 0x31, 0xb7, 0x2f, 0x40, 0x31, 0xad, 0x1a, 0xc1, 0xca, 0x97, 0x43, 0x53, 0x9b, 0x00, 0x4c, 0x8d, 0x61, 0x3d, 0x00, 0xc2, 0x52, 0xfd, 0x8b, 0x4b, 0x74, 0x97, 0x70, 0x93, 0xd1, 0xb5, 0x52, 0x25, 0xad, 0x36, 0xd4, 0x3c, 0x42, 0x67, 0x19, 0x88, 0x94, 0xeb, 0xc2, 0x30, 0x5c, 0xec, 0x5b, 0x3f, 0x24, 0x7a, 0x98, 0x07, 0x17, 0x29, 0xea, 0x23, 0x1a, 0x54, 0x30, 0x2d, 0x2b, 0x99, 0x99, 0x4f, 0x25, 0x6d, 0xf9, 0x2c, 0x63, 0xe6, 0x2c, 0xf4, 0xdd, 0x15, 0x48, 0x79, 0xbf, 0x8d, 0xa3, 0xad, 0x8e, 0xed, 0x11, 0xdb, 0x63, 0x99, 0xca, 0x72, 0xcd, 0xe5, 0xdb, 0x5c, 0x5c, 0x69, 0x21, 0x0b, 0xea, 0x48, 0x17, 0xd0, 0x2e, 0x88, 0x13, 0x23, 0x20, 0xe0, 0xb2, 0xe7, 0x39, 0x91, 0x7b, 0xdf, 0xa6, 0x24, 0x0f, 0xce, 0xe8, 0x2e, 0x75, 0x0a, 0x84, 0x77, 0x3a, 0x68, 0xb3, 0x18, 0x8a, 0xd4, 0x3e, 0x77, 0x7b, 0x09, 0xf0, 0x32, 0x22, 0x1a, 0x4e, 0x5d, 0x34, 0xd5, 0x77, 0xb0, 0x4a, 0x3f, 0x6c, 0x70, 0x0a, 0x97, 0x10, 0x4f, 0xc9, 0xa1, 0xa9, 0x7d, 0x68, 0x3f, 0xb6, 0x9c, 0x86, 0x89, 0x59, 0x6d, 0x48, 0xdf, 0xac, 0x4b, 0x40, 0xbf, 0xc9, 0xe1, 0x52, 0x42, 0x56, 0xa0, 0x8d, 0xa0, 0xce, 0xe6, 0x4d, 0x0d, 0xf4, 0xe5, 0x37, 0xcf, 0x19, 0xad, 0xd6, 0x74, 0x1e, 0xf1, 0xdd, 0x6b, 0x64, 0x61, 0x71, 0x7d, 0x15, 0xc1, 0xe9, 0xdd, 0x6b, 0x04, 0xe9, 0xd3, 0xe9, 0x20, 0xd6, 0x35, 0xb3, 0x60, 0xf8, 0x2d, 0x66, 0x5e, 0xc7, 0x12, 0x28, 0x02, 0x48, 0x3b, 0xd6, 0x14, 0x69, 0x20, 0x81, 0x50, 0xc1, 0x30, 0x97, 0x02, 0x2d, 0x25, 0x7f, 0xa3, 0x25, 0xd0, 0x77, 0xf1, 0xc9, 0x96, 0xf4, 0x7b, 0xfd, 0x18, 0xe8, 0xac, 0x11, 0xcb, 0x9a, 0xba, 0xd7, 0x70, 0x00, 0x0b, 0x1a, 0xb4, 0xc1, 0xf8, 0xd5, 0x6c, 0x4f, 0x03, 0xb1, 0x28, 0xc6, 0xde, 0x8a, 0x23, 0x7a, 0xd7, 0x20, 0xbf, 0x5d, 0x99, 0x24, 0x13, 0xb1, 0x46, 0x44, 0x3f, 0xaa, 0x58, 0xef, 0x8e, 0xf0, 0xda, 0xf1, 0x93, 0x2c, 0xdd, 0x1f, 0xc7, 0x0e, 0x3c, 0xab, 0x5f, 0x74, 0x19, 0xed, 0x5e, 0xa1, 0x9b, 0xa6, 0x12, 0xb0, 0xdf, 0x09, 0x85, 0xaf, 0x25, 0x20, 0x97, 0x07, 0xa3, 0x50, 0xb9, 0x2e, 0x8e, 0x06, 0x91, 0xbd, 0x46, 0xe2, 0xfc, 0x5a, 0xa9, 0xe7, 0x24, 0x30, 0xfd, 0x7a, 0xb2, 0xce, 0x0b, 0x3d, 0x51, 0xa2, 0x37, 0x1a, 0xfd, 0x7f, 0xc7, 0xfd, 0xe1, 0xd2, 0xa4, 0x0f, 0xb5, 0x78, 0x36, 0x84, 0xe4, 0x62, 0x40, 0x3a, 0xeb, 0x6c, 0xc9, 0xc7, 0xb7, 0x17, 0x76, 0xad, 0xf9, 0x18, 0xf6, 0xd9, 0xa5, 0xdc, 0x4e, 0x9c, 0x2b, 0x77, 0x2e, 0xc4, 0x0e, 0xa1, 0xaa, 0x95, 0xed, 0xbd, 0xe3, 0xa9, 0x25, 0x00, 0x99, 0x13, 0x94, 0x32, 0xa1, 0x3c, 0x3b, 0xb9, 0xb6, 0x5b, 0xad, 0xca, 0x33, 0x84, 0x9b, 0xfb, 0x96, 0xa4, 0xe2, 0x9c, 0xe1, 0xf2, 0xf3, 0x7f, 0x47, 0x9c, 0x6e, 0x23, 0xae, 0xc9, 0x53, 0x6d, 0xe5, 0x2f, 0x21, 0x4e, 0xb8, 0xd0, 0xb7, 0x1a, 0x30, 0xa9, 0xf0, 0x62, 0x9a, 0x5a, 0x22, 0x91, 0x43, 0x20, 0x1d, 0xac, 0xe8, 0x9a, 0x49, 0xe9, 0x53, 0x36, 0xeb, 0x02, 0xb1, 0x4a, 0xd1, 0x74, 0x7b, 0x23, 0xda, 0x15, 0x1b, 0x9e, 0x17, 0xb2, 0x9c, 0x11, 0x83, 0x93, 0x09, 0x8c, 0x8f, 0x21, 0x51, 0xce, 0xf8, 0x15, 0xd2, 0x62, 0xae, 0xd2, 0xe8, 0xc8, 0xb7, 0xe6, 0x0b, 0xa7, 0x63, 0xd4, 0x77, 0x57, 0x2f, 0x91, 0x59, 0x55, 0x29, 0x6e, 0xf8, 0x61, 0xd0, 0x43, 0x5f, 0x5f, 0x9a, 0x26 }; +constexpr AccessUnit AC3_SKIP_BYTES_EXPECTED_AU = { 0x15f90, 0x153d5, false, 0, {}, { 0x8e, 0x59, 0x01, 0x62, 0x21, 0xbd, 0x77, 0x65, 0x7b, 0xfe, 0x1e, 0xb1, 0x20, 0x49, 0xce, 0x3f, 0xed, 0x98, 0xe4, 0x99 } }; + +const std::vector LPCM_SKIP_BYTES_STREAM = { 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xf3, 0x3b, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0x7a, 0x01, 0xe0, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x1a, 0x00, 0x80, 0x20, 0x90, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x00, 0x01, 0xbd, 0x07, 0x5a, 0x81, 0xc1, 0x0d, 0x31, 0x00, 0x05, 0xbf, 0x21, 0x11, 0x00, 0x05, 0xa7, 0xab, 0x1e, 0x73, 0x3b, 0x40, 0xe6, 0xa3, 0x12, 0x99, 0xcf, 0x16, 0x2e, 0x6d, 0x67, 0x2a, 0xa2, 0xb4, 0xf7, 0xa2, 0x3c, 0xdf, 0x11, 0xe7, 0x98, 0x98, 0xef, 0x5c, 0x93, 0xbf, 0x51, 0x56, 0xaa, 0x5c, 0x26, 0x2d, 0x8e, 0xc3, 0x34, 0x23, 0x45, 0x68, 0x25, 0x5c, 0x60, 0x1a, 0xa9, 0x35, 0x12, 0xa7, 0x95, 0x8f, 0x35, 0x23, 0x2e, 0x00, 0x85, 0x49, 0x0c, 0xe8, 0xa6, 0xbc, 0x42, 0xe5, 0xb8, 0x18, 0xb0, 0x29, 0x86, 0x1c, 0xb6, 0x9d, 0xa0, 0x5c, 0xa9, 0xea, 0xee, 0x40, 0xc2, 0xbc, 0x80, 0x4c, 0x63, 0xe7, 0xab, 0xe4, 0xf1, 0x41, 0xc0, 0x15, 0x9e, 0x52, 0xeb, 0x12, 0xd9, 0x34, 0x02, 0x6b, 0x50, 0x3c, 0x4c, 0x38, 0xa5, 0x53, 0x99, 0xac, 0x57, 0x0b, 0x29, 0xd9, 0x6f, 0xd8, 0x3c, 0x96, 0xfa, 0x05, 0x45, 0xc7, 0x66, 0x43, 0x1e, 0x88, 0x3b, 0xe5, 0xbe, 0xed, 0xd0, 0x3b, 0x42, 0x59, 0xf8, 0x84, 0x52, 0xab, 0xc8, 0x7e, 0x2f, 0xb5, 0xdd, 0x8c, 0xf7, 0xc2, 0xe1, 0xe1, 0xeb, 0x1a, 0x25, 0x47, 0xbf, 0xd1, 0x8c, 0x5f, 0x49, 0x51, 0x2c, 0x71, 0x0e, 0x5c, 0x51, 0x36, 0x86, 0x89, 0xcf, 0x21, 0x1c, 0x6d, 0xd6, 0x1c, 0x36, 0xf9, 0xa1, 0xc0, 0xd2, 0xbc, 0xc0, 0x77, 0x85, 0x11, 0xe7, 0x11, 0xe8, 0x6b, 0x56, 0xb6, 0xbe, 0x41, 0x6f, 0x4b, 0x5f, 0x52, 0xfc, 0xa7, 0x30, 0x48, 0x30, 0x39, 0x44, 0xdc, 0x7d, 0xed, 0x56, 0x1b, 0xb8, 0x7c, 0xc7, 0x6d, 0x26, 0x7c, 0x56, 0x5b, 0x72, 0xca, 0xa2, 0x65, 0xab, 0x2b, 0xcf, 0x50, 0xb6, 0x49, 0xc9, 0xa8, 0xe7, 0x52, 0xf8, 0x84, 0xa9, 0xf5, 0x76, 0xb6, 0x5f, 0x78, 0x09, 0xe5, 0xef, 0x1b, 0x79, 0x5d, 0xa0, 0x17, 0xfe, 0x77, 0x31, 0xdc, 0xe4, 0xf1, 0x66, 0x67, 0xa1, 0x98, 0x66, 0xc8, 0xf8, 0x16, 0x99, 0x3f, 0xe7, 0xd2, 0xfc, 0x81, 0x72, 0x20, 0x0f, 0x06, 0xa0, 0x44, 0xc6, 0x7a, 0x1d, 0xfa, 0x30, 0xb1, 0x73, 0x8d, 0xbf, 0xb7, 0xb8, 0xa4, 0x57, 0xd3, 0x2d, 0x58, 0x98, 0xa7, 0x2c, 0x3e, 0x0d, 0xba, 0x5b, 0x6a, 0x21, 0x0f, 0x0f, 0xa3, 0x18, 0xa5, 0x3c, 0x47, 0x70, 0xfc, 0x7e, 0x95, 0x4d, 0xfa, 0xfc, 0x65, 0xed, 0xcd, 0x3f, 0x7a, 0x3f, 0xa0, 0x40, 0xf3, 0x1b, 0x4c, 0x38, 0xa2, 0xb5, 0x55, 0x07, 0x27, 0x41, 0xd3, 0x34, 0x2a, 0xf6, 0x25, 0xd6, 0x24, 0xd4, 0x86, 0xf8, 0x64, 0xe1, 0xe4, 0x35, 0x6e, 0xbf, 0x96, 0xaa, 0xcf, 0xd7, 0xc1, 0x7c, 0xf0, 0x70, 0x9e, 0x85, 0xa9, 0x74, 0xe4, 0xf2, 0x88, 0xbc, 0x07, 0xdf, 0x07, 0x1b, 0x1d, 0x3a, 0x33, 0x8f, 0x82, 0x7e, 0x7f, 0x4a, 0xa5, 0x10, 0xba, 0x6f, 0x8c, 0x41, 0x67, 0xc9, 0xee, 0x56, 0xf9, 0xcd, 0x08, 0x0e, 0x9f, 0xa3, 0x7e, 0x75, 0xb2, 0x24, 0xe7, 0x20, 0xec, 0xea, 0xe5, 0x06, 0xf1, 0xef, 0xde, 0x96, 0xe4, 0x59, 0xb8, 0xcf, 0xfd, 0x69, 0x2e, 0x5e, 0x68, 0xb5, 0xa1, 0x18, 0xdd, 0x1a, 0x7b, 0x63, 0xb3, 0x0d, 0x81, 0x40, 0x6d, 0x3f, 0xb5, 0x1c, 0xf3, 0xbf, 0x9c, 0xad, 0xff, 0xf9, 0x0d, 0x5a, 0x73, 0x56, 0xdb, 0x0d, 0x91, 0x4d, 0x00, 0x6f, 0x5b, 0x2e, 0x1c, 0xdf, 0x8e, 0xf6, 0x6b, 0xa8, 0xf8, 0xf2, 0x8d, 0x53, 0x23, 0x09, 0xb5, 0x0d, 0x97, 0xe5, 0x23, 0x77, 0x22, 0x64, 0x04, 0x77, 0xf3, 0xf9, 0x11, 0xb4, 0x75, 0xf0, 0x88, 0xf9, 0x30, 0xba, 0x60, 0x9c, 0x24, 0xb3, 0xd0, 0x95, 0x65, 0x07, 0x87, 0x07, 0xe5, 0xb0, 0x30, 0x3e, 0xb9, 0x9e, 0x1e, 0x80, 0x42, 0x9c, 0x3d, 0x2f, 0x0c, 0x72, 0xa0, 0x06, 0x4a, 0x5b, 0x52, 0x92, 0x38, 0xd5, 0x36, 0x15, 0xd9, 0x55, 0x25, 0x76, 0xd6, 0x74, 0x96, 0x04, 0x67, 0x96, 0x73, 0x11, 0x9c, 0x1f, 0xf9, 0xb7, 0x6c, 0xbf, 0xb7, 0x58, 0x4c, 0x62, 0x13, 0x97, 0x56, 0xca, 0xeb, 0xe5, 0x2a, 0xee, 0x28, 0xe2, 0x0c, 0x97, 0x6b, 0x2a, 0x09, 0xd5, 0x28, 0x4a, 0xff, 0x52, 0xd0, 0xfa, 0xea, 0x91, 0xe0, 0xdf, 0xd0, 0xa3, 0xf2, 0x5c, 0x24, 0xe0, 0x38, 0x4e, 0x83, 0xad, 0xe8, 0xaf, 0x1f, 0x68, 0x87, 0x72, 0x40, 0xe6, 0x25, 0x26, 0xa2, 0x3a, 0xed, 0x2a, 0xab, 0xae, 0x9b, 0x83, 0xae, 0x11, 0xc4, 0x8f, 0xc5, 0xcd, 0xf6, 0x39, 0xe9, 0x74, 0x22, 0x69, 0x5d, 0xab, 0xe0, 0xc6, 0x96, 0x9b, 0x66, 0x05, 0x1b, 0x63, 0x5c, 0x70, 0x29, 0x27, 0xd9, 0x4c, 0x09, 0xaa, 0x2d, 0x48, 0x59, 0xb1, 0x5b, 0x33, 0xc1, 0x7b, 0x4b, 0x80, 0xd3, 0x1f, 0x27, 0x78, 0x18, 0x9a, 0x6c, 0x0e, 0x72, 0xd0, 0x9c, 0xb2, 0x68, 0xe5, 0x9c, 0xa6, 0x08, 0x93, 0x25, 0xa9, 0x5e, 0x78, 0xe4, 0xfb, 0xbf, 0x74, 0x1f, 0x0a, 0x62, 0x9b, 0x01, 0x58, 0x02, 0x51, 0xe1, 0x5f, 0x88, 0x87, 0x2d, 0x84, 0xf7, 0x48, 0xc5, 0x60, 0x15, 0xf5, 0xf4, 0xf6, 0x8e, 0xec, 0x4d, 0x90, 0x90, 0x7e, 0x1f, 0x5f, 0x18, 0x55, 0x4d, 0x27, 0x69, 0xd2, 0xa9, 0x7a, 0x75, 0xf1, 0x2f, 0x56, 0x28, 0xb4, 0xc4, 0x35, 0xd2, 0x35, 0x41, 0xcf, 0x36, 0xd0, 0xf9, 0x26, 0xef, 0x12, 0x12, 0xa3, 0x2c, 0x57, 0x45, 0x4e, 0xff, 0x40, 0xe7, 0x73, 0xba, 0x76, 0x58, 0x34, 0x12, 0x59, 0x34, 0xea, 0x15, 0x95, 0xda, 0x45, 0x0f, 0xbf, 0x32, 0x8e, 0x01, 0x68, 0xc2, 0x8b, 0x42, 0x58, 0x78, 0xd8, 0x62, 0xd1, 0xbe, 0xb5, 0x77, 0x17, 0xb1, 0xa7, 0x5d, 0x93, 0xaa, 0x69, 0xa2, 0x57, 0x56, 0xfb, 0x10, 0xd2, 0x19, 0xeb, 0x22, 0x00, 0x80, 0x03, 0xd1, 0x63, 0xec, 0x14, 0x83, 0x86, 0xc8, 0x7a, 0x05, 0xf0, 0xf6, 0x94, 0xe2, 0xae, 0x36, 0x54, 0x81, 0xea, 0xbb, 0x8d, 0xd3, 0x2c, 0x3f, 0xbe, 0x80, 0x48, 0x30, 0x71, 0xdf, 0x08, 0xd7, 0x69, 0x25, 0x1a, 0x96, 0x3e, 0x90, 0xd9, 0x8f, 0x27, 0x8d, 0xe9, 0x60, 0x01, 0x09, 0xd0, 0xc3, 0xdd, 0x75, 0xed, 0x2f, 0xaa, 0x35, 0x90, 0xdf, 0xba, 0x6f, 0x07, 0xd2, 0x36, 0x83, 0xda, 0xa6, 0xcb, 0x9f, 0x9a, 0x64, 0x1e, 0x2d, 0x00, 0x9b, 0xd2, 0x15, 0x28, 0x70, 0x24, 0x18, 0x38, 0x69, 0x79, 0xaf, 0xc4, 0x2a, 0x60, 0x3e, 0xac, 0x66, 0xcd, 0x89, 0x55, 0xb6, 0xad, 0xa9, 0x6c, 0x21, 0x0c, 0x06, 0xa7, 0x7f, 0x5d, 0x00, 0x20, 0x03, 0xc0, 0x5e, 0x4b, 0x9f, 0x39, 0x9f, 0x98, 0xff, 0x34, 0xc6, 0x4b, 0x57, 0xde, 0x47, 0x1f, 0x4d, 0x26, 0x21, 0xa9, 0x97, 0x5e, 0x56, 0xab, 0x3f, 0xe0, 0x44, 0xb4, 0x92, 0x35, 0x96, 0xd2, 0x1f, 0x8d, 0xcb, 0x24, 0x69, 0x93, 0x93, 0x95, 0x1c, 0xec, 0x78, 0x11, 0xe4, 0xec, 0x8d, 0xfa, 0x4c, 0x4a, 0x2d, 0xb1, 0x33, 0xe2, 0xef, 0x74, 0xbb, 0xd1, 0x6a, 0xec, 0xcd, 0x77, 0x5d, 0x20, 0x8a, 0x26, 0x63, 0xba, 0x51, 0x95, 0x4c, 0xc8, 0x1f, 0x56, 0xa5, 0x5a, 0x83, 0xe3, 0x32, 0xc3, 0x64, 0x11, 0x45, 0x4d, 0x4f, 0xe9, 0x3f, 0x9c, 0x16, 0x3d, 0xa8, 0x2c, 0xe4, 0x86, 0xa8, 0x8b, 0x27, 0xce, 0xd3, 0x48, 0xda, 0xb9, 0x85, 0xbe, 0x2a, 0xf8, 0x52, 0x1d, 0x69, 0xb1, 0x3a, 0x75, 0xd6, 0xa8, 0xa9, 0x91, 0xb0, 0x35, 0x73, 0xe9, 0x92, 0x54, 0x56, 0x06, 0x10, 0x5b, 0xb0, 0x07, 0x18, 0x1c, 0x6b, 0x3d, 0x8f, 0x8b, 0x60, 0xf9, 0x21, 0x2e, 0xa8, 0x07, 0x51, 0xd7, 0x8f, 0x7e, 0x28, 0x8e, 0x39, 0xc6, 0x23, 0x9d, 0x1e, 0x17, 0x37, 0x1d, 0xef, 0xbf, 0x0c, 0x81, 0x8e, 0xfd, 0xc6, 0xf8, 0x1d, 0x3a, 0xfb, 0xad, 0x61, 0xed, 0xae, 0x27, 0xf4, 0x76, 0x79, 0x6c, 0xff, 0xbf, 0x26, 0x99, 0x7b, 0x69, 0x75, 0x0d, 0x36, 0xd3, 0xd0, 0x70, 0x11, 0x51, 0x18, 0x17, 0x43, 0x48, 0xdf, 0xa3, 0x82, 0x17, 0xaf, 0xd2, 0x6f, 0x03, 0x40, 0xe7, 0xa5, 0x7f, 0xa2, 0x1a, 0x39, 0x8f, 0xdd, 0xf0, 0x99, 0x2a, 0x79, 0x83, 0x15, 0xc3, 0xed, 0xfb, 0x80, 0x6a, 0xf8, 0xd3, 0xb1, 0x38, 0x51, 0xae, 0xd5, 0xde, 0x42, 0xc5, 0xd7, 0x99, 0x06, 0x45, 0x52, 0xe8, 0x13, 0x1d, 0xd5, 0xb9, 0xa1, 0x10, 0x61, 0xef, 0x08, 0x11, 0x79, 0x7c, 0xe2, 0x3e, 0x21, 0x6b, 0xf4, 0xfb, 0x9f, 0x92, 0x53, 0xff, 0xf6, 0xce, 0x4b, 0x61, 0x48, 0x00, 0xf7, 0xec, 0xb2, 0x2e, 0x96, 0x49, 0x49, 0x79, 0x07, 0xc9, 0x45, 0xce, 0xfb, 0xdf, 0x86, 0x89, 0xc5, 0x91, 0xff, 0x6a, 0xd9, 0x6c, 0xba, 0x8d, 0x5c, 0xd1, 0x69, 0x58, 0x68, 0x98, 0xd9, 0x7c, 0xcc, 0x5c, 0xa3, 0x80, 0x78, 0x03, 0xf5, 0x83, 0xea, 0x40, 0x59, 0x16, 0x32, 0x28, 0xc0, 0x6b, 0x73, 0x1b, 0x4a, 0x30, 0xf5, 0x95, 0x8f, 0xd6, 0x29, 0xb3, 0x56, 0x25, 0x3a, 0x6e, 0xff, 0x47, 0x02, 0xe8, 0x25, 0xc2, 0x8b, 0x44, 0x1a, 0xfb, 0x68, 0xed, 0x59, 0x47, 0x90, 0x3a, 0x12, 0x93, 0x8b, 0xda, 0x54, 0x3b, 0x1d, 0x7b, 0x93, 0x8d, 0xba, 0x86, 0x88, 0x0e, 0x65, 0xfd, 0x99, 0x8f, 0xdb, 0xb7, 0x5c, 0x8b, 0x26, 0x9c, 0xdb, 0x7e, 0xe5, 0x9c, 0xa1, 0x14, 0xfb, 0x79, 0xcb, 0x6a, 0x6f, 0xa0, 0x93, 0xbc, 0xaa, 0xb4, 0x1d, 0x46, 0x54, 0x81, 0x6f, 0x23, 0x92, 0x71, 0xe5, 0x73, 0x5d, 0xc4, 0x92, 0x26, 0x23, 0x2a, 0x43, 0x17, 0x06, 0x6e, 0x34, 0x68, 0x5e, 0x5a, 0x9c, 0x49, 0x49, 0x11, 0xa3, 0x9a, 0x76, 0x6d, 0x67, 0x09, 0x7f, 0x2f, 0x1e, 0xa5, 0x70, 0x0a, 0x89, 0x09, 0x51, 0xe0, 0x33, 0x94, 0xdf, 0xa6, 0x3f, 0x4a, 0xb6, 0xd7, 0xb6, 0x5e, 0xa9, 0x69, 0x9c, 0x81, 0x03, 0xa8, 0x42, 0x6e, 0xe2, 0x66, 0x91, 0x52, 0x08, 0x6d, 0x4e, 0x0b, 0xae, 0x1f, 0x8c, 0x5b, 0x45, 0xad, 0xd1, 0x89, 0x3c, 0x59, 0xa0, 0x0d, 0x24, 0x9f, 0x72, 0x47, 0xcf, 0x45, 0x45, 0x54, 0x4c, 0xb1, 0x53, 0x84, 0xd2, 0xf3, 0x9f, 0x11, 0xff, 0x6e, 0x5a, 0x00, 0x01, 0x17, 0x5b, 0x65, 0x89, 0xa3, 0x1e, 0x6a, 0xa1, 0x21, 0x1c, 0xca, 0xc1, 0xe2, 0x56, 0xa8, 0xc6, 0xa1, 0x75, 0xf9, 0x98, 0x4e, 0xdc, 0xe0, 0xae, 0xfb, 0x76, 0xaa, 0xb8, 0xb8, 0x42, 0x62, 0x23, 0x70, 0xc5, 0x19, 0x33, 0x0d, 0xf6, 0x55, 0xf7, 0x70, 0x4b, 0x5e, 0x45, 0x12, 0xf3, 0x38, 0x8a, 0x43, 0x6f, 0x9c, 0x1f, 0x75, 0x08, 0x36, 0x61, 0xfb, 0xe4, 0xf6, 0xcd, 0x26, 0xa9, 0x45, 0xd0, 0xba, 0x00, 0x5b, 0x1e, 0x0a, 0x53, 0x19, 0xac, 0x4c, 0xaa, 0x1c, 0xaa, 0xf2, 0x7f, 0xe6, 0x19, 0x07, 0xd9, 0x5b, 0xdd, 0xed, 0x27, 0xf0, 0x5d, 0x01, 0x96, 0x40, 0x19, 0xe6, 0xd8, 0xee, 0xc9, 0x9b, 0xa2, 0x04, 0xe6, 0x8e, 0x57, 0x39, 0xb2, 0x4e, 0x9c, 0xca, 0x2d, 0x9a, 0xd4, 0xd1, 0x76, 0xda, 0xbc, 0x4a, 0x8f, 0x56, 0xaa, 0x2c, 0x94, 0xb3, 0x20, 0x49, 0xbd, 0x7b, 0xba, 0xd9, 0xd4, 0xca, 0xaa, 0xe2, 0xec, 0x60, 0x47, 0xee, 0x80, 0xa5, 0x65, 0xa3, 0x53, 0x78, 0x6e, 0x4f, 0xa9, 0xc1, 0x87, 0x70, 0xbb, 0x20, 0x29, 0xbc, 0x7f, 0x47, 0xfa, 0x44, 0x1e, 0xba, 0xde, 0xb3, 0xb9, 0x15, 0x76, 0xb6, 0x57, 0x1b, 0x8b, 0x21, 0x0f, 0x12, 0x2e, 0x53, 0xe1, 0x4b, 0x71, 0xe7, 0xbc, 0xd1, 0x0d, 0xc8, 0xa7, 0x91, 0x5d, 0x24, 0x19, 0x8a, 0x7e, 0xdb, 0xe3, 0xce, 0x79, 0x5f, 0x46, 0x5d, 0xcb, 0x35, 0x0f, 0x2f, 0xb0, 0x74, 0xdd, 0xeb, 0x05, 0xfe, 0xe1, 0x28, 0xa2, 0x56, 0xbe, 0x36, 0x83, 0x40, 0x5f, 0xc1, 0x27, 0x9f, 0xe3, 0xdb, 0xec, 0x28, 0xfa, 0x35, 0x62, 0xf5, 0x4b, 0x97, 0xd1, 0x08, 0xc3, 0xdf, 0x67, 0x3a, 0xec, 0x1a, 0xda, 0x39, 0xa3, 0x77, 0x6a, 0x8c, 0xc3, 0x2e, 0x84, 0xbd, 0xb2, 0x9f, 0x88, 0x19, 0xe1, 0x2f, 0x67, 0xbc, 0x93, 0xc2, 0x15, 0xbe, 0x9d, 0xcb, 0x14, 0xcc, 0xe3, 0x43, 0x84, 0x7a, 0xc3, 0x1c, 0x84, 0x0f, 0xb8, 0xf4, 0xd8, 0xb0, 0xe0, 0x0d, 0x0e, 0x15, 0x35, 0xeb, 0xa7, 0x36, 0x9a, 0x0d, 0xf5, 0x9b, 0x23, 0x9c, 0xb2, 0x3a, 0x15, 0x16, 0x85, 0x13, 0xa5, 0x45, 0x00, 0xf0, 0x6a, 0x04, 0xbb, 0xfd, 0xf8, 0xb0, 0x9c, 0x18, 0x32, 0x39, 0x83, 0x13, 0x3d, 0x3b, 0xd0, 0x49, 0x1b, 0x91, 0x84, 0x3d, 0x61, 0x3b, 0xfb, 0x1a, 0x90, 0xaa, 0x78, 0x60, 0x03, 0xa5, 0xf8, 0x0c, 0x71, 0x78, 0x1c, 0xf6, 0x7c, 0x0f, 0x0d, 0x52, 0xd7, 0x2d, 0xaa, 0x76, 0xe8, 0xf9, 0x70, 0x5e, 0xf4, 0x6a, 0xe1, 0x8e, 0x4a, 0x70, 0x5a, 0x45, 0xf0, 0xca, 0xa5, 0x2e, 0xba, 0xf7, 0xad, 0xf1, 0xe8, 0xb1, 0x2a, 0x60, 0xa3, 0xc9, 0x25, 0x1e, 0xf3, 0x78, 0xac, 0xf1, 0x14, 0x61, 0x1a, 0x31, 0x38, 0xde, 0xbf, 0xee, 0x1f, 0x5b, 0xda, 0xd7, 0x19, 0xd0, 0x28, 0xe9, 0x4b, 0xa2, 0x83, 0x76, 0x66, 0x7d, 0x48, 0x14, 0x0f, 0xeb, 0x80, 0x70, 0xab, 0xbc, 0x18, 0x2d, 0x64, 0x85, 0x86, 0x34, 0x7f, 0xc3, 0xb7, 0x32, 0x65, 0x74, 0x2a, 0x1d, 0xf3, 0x29, 0x81, 0xf3, 0xfd, 0xe1, 0x03, 0x28, 0x06, 0x3e, 0xc0, 0x62, 0xa8, 0xd6, 0x62, 0x72, 0x2b, 0xb2, 0xe0, 0xc2, 0x41, 0x4b, 0x8e, 0x8c, 0xe6, 0x86, 0x43, 0xa2, 0xe3, 0x85, 0x9e, 0x9a, 0x6d, 0x55, 0x96, 0xa0, 0xd8, 0xc3, 0xda, 0x46, 0x64, 0xea, 0xbf, 0x0a, 0x96, 0x3c, 0xaf, 0x81, 0xa3, 0x22, 0x5a, 0x42, 0xd5, 0x6b, 0x30, 0x14, 0x0c, 0x25, 0xc2, 0xf9, 0xa6, 0xac, 0x2e, 0x05, 0x77, 0xea, 0xad, 0x3a, 0xa9, 0x2d, 0xd8, 0xc3, 0xa3, 0x0b, 0x57, 0x44, 0x4a, 0x28, 0xf1, 0x2b, 0x44, 0xed, 0x41, 0x2e, 0x11, 0x73, 0x8f, 0x59, 0x16, 0x36, 0x78, 0x68, 0xff, 0x5b, 0x76, 0x49, 0x06, 0x8f, 0x73, 0xfe, 0x03, 0xd4, 0xf3, 0x48, 0x69, 0xbe, 0x7d, 0xb9, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbd, 0x07, 0xec, 0x79, 0x01, 0x00, 0x40, 0xbf, 0x45, 0x1f, 0x31, 0x39, 0xc2, 0x40, 0x77, 0xfb, 0x6a, 0x24, 0xa5, 0xcb, 0x6c, 0xd8, 0x05, 0xaa, 0x6f, 0x6b, 0xa1, 0x51, 0x5c, 0xbf, 0x4c, 0xc1, 0x76, 0xed, 0x59, 0x4e, 0xa6, 0xc4, 0x9e, 0x1f, 0x40, 0x72, 0xa2, 0x7b, 0xaf, 0xe7, 0x0b, 0x6c, 0xcc, 0x79, 0xb2, 0x80, 0xe2, 0xd8, 0xea, 0xbe, 0x8d, 0x61, 0xec, 0x07, 0xf7, 0x4d, 0x6d, 0x8f, 0x38, 0x63, 0xc7, 0x14, 0xc2, 0x1c, 0x4e, 0x01, 0x22, 0x5b, 0xb4, 0xb4, 0x97, 0x33, 0x82, 0x77, 0x27, 0x5f, 0x24, 0xfe, 0x41, 0x57, 0x01, 0x75, 0x26, 0x2f, 0x97, 0x5d, 0x82, 0xb5, 0xa1, 0xda, 0x10, 0x68, 0xb9, 0x2c, 0x27, 0x45, 0xfa, 0x65, 0x81, 0x8f, 0x93, 0xa9, 0xac, 0xfa, 0x5d, 0x87, 0xeb, 0xed, 0xca, 0x2d, 0x73, 0xc4, 0xde, 0x8e, 0x54, 0x38, 0xf0, 0xbe, 0x7f, 0x64, 0x6c, 0x17, 0x9f, 0x09, 0xe0, 0xe9, 0xd0, 0x08, 0xf6, 0xd1, 0x67, 0x2a, 0x32, 0xf0, 0x43, 0xc1, 0xa1, 0x9a, 0x6f, 0xac, 0xb8, 0x4a, 0x04, 0xc5, 0x17, 0xdd, 0x97, 0xd3, 0x0b, 0x6e, 0x95, 0x7b, 0xd6, 0x4c, 0x6d, 0xce, 0x31, 0xf1, 0x5f, 0x64, 0x9b, 0xe4, 0x46, 0x3f, 0x47, 0xf5, 0xd4, 0xc6, 0xda, 0x42, 0xeb, 0x9b, 0x42, 0xe4, 0x28, 0x32, 0x47, 0x48, 0xd0, 0x4b, 0xbf, 0x80, 0x90, 0xd1, 0x6a, 0x17, 0xe6, 0xac, 0xe3, 0x3e, 0x15, 0x8c, 0x46, 0x4e, 0xf2, 0xd3, 0x4a, 0xf7, 0xfc, 0xf7, 0x15, 0xa4, 0x7c, 0x2c, 0x04, 0xe0, 0xb4, 0x17, 0x0e, 0xcb, 0x45, 0xe0, 0xa8, 0xdf, 0x5d, 0xef, 0x38, 0xa7, 0x58, 0x10, 0x74, 0x20, 0xdc, 0xe7, 0x58, 0xd4, 0xa3, 0xdd, 0x79, 0x09, 0x7b, 0xf9, 0xe4, 0x7a, 0x24, 0x44, 0xdb, 0x77, 0x20, 0xb5, 0x0d, 0x73, 0xa1, 0xc4, 0x26, 0x47, 0x0f, 0x12, 0xd5, 0xbf, 0xf7, 0xdb, 0xa4, 0x37, 0x3e, 0x0e, 0x36, 0x4f, 0xf6, 0x4c, 0xd5, 0x14, 0x37, 0x22, 0x5d, 0x13, 0xc8, 0x3e, 0xec, 0x34, 0x8c, 0x81, 0xed, 0x63, 0xf1, 0x1e, 0x5b, 0x4a, 0xde, 0x2c, 0x58, 0xb8, 0xda, 0x60, 0x77, 0x7b, 0x6c, 0xd1, 0x4a, 0xab, 0xe9, 0x01, 0x25, 0xd1, 0x37, 0x7f, 0x1a, 0x4f, 0x31, 0xe8, 0x9b, 0xf9, 0xb9, 0x24, 0x57, 0xd4, 0xa9, 0x0a, 0x2f, 0x4d, 0x24, 0xe3, 0x5e, 0x7e, 0xfd, 0x67, 0x35, 0x35, 0x39, 0x33, 0xff, 0xea, 0xe3, 0xd0, 0xf1, 0xd1, 0xa9, 0xce, 0x39, 0xa5, 0x0c, 0x84, 0x94, 0xf9, 0x0c, 0x79, 0xfc, 0x0e, 0x9e, 0x97, 0x4e, 0x8b, 0x5f, 0x90, 0x06, 0x8f, 0x3d, 0x2d, 0x6c, 0x05, 0x1d, 0x69, 0xc8, 0x21, 0xaa, 0x83, 0x87, 0x77, 0xde, 0x84, 0x5b, 0x1f, 0xeb, 0xc8, 0xc5, 0xbd, 0x90, 0x93, 0x8e, 0x72, 0x0b, 0xc8, 0x27, 0x0f, 0x33, 0x41, 0xf5, 0x01, 0x60, 0x62, 0xeb, 0xdc, 0x33, 0xde, 0x18, 0x77, 0x6b, 0xd7, 0xf8, 0xfa, 0x4a, 0xc8, 0xa8, 0x5b, 0x43, 0xdf, 0x60, 0x21, 0xf1, 0xb4, 0xc3, 0x72, 0x8d, 0x93, 0xee, 0xbb, 0x65, 0xb7, 0x52, 0x7b, 0x0b, 0x2a, 0xc7, 0x01, 0x3c, 0x31, 0x6a, 0x2a, 0xb7, 0x7d, 0x1a, 0x65, 0x86, 0x76, 0xc8, 0x89, 0x6d, 0x66, 0xdc, 0x55, 0x82, 0x56, 0x58, 0x95, 0x27, 0xe4, 0x9a, 0x46, 0xe1, 0x69, 0xc9, 0x38, 0xcb, 0x1c, 0x59, 0x0e, 0x9b, 0x35, 0x39, 0x8c, 0x81, 0x1a, 0x86, 0x98, 0x4e, 0x1d, 0xea, 0x71, 0xa6, 0x6f, 0xf3, 0xdf, 0x39, 0x25, 0x0a, 0x76, 0x40, 0x9b, 0xe6, 0x37, 0xb6, 0x7f, 0x8a, 0x09, 0x0e, 0x46, 0x3d, 0xf1, 0x58, 0xf0, 0x07, 0x00, 0x22, 0x46, 0x9b, 0x47, 0x84, 0x02, 0xc0, 0x6c, 0x0f, 0x80, 0xa4, 0x95, 0xae, 0x02, 0x9e, 0xc4, 0xa0, 0x8a, 0x53, 0xec, 0x16, 0xd7, 0x4a, 0x52, 0x27, 0x26, 0x54, 0xee, 0x1e, 0x9c, 0x5a, 0xff, 0x57, 0x91, 0x78, 0xf8, 0x2c, 0x1a, 0x80, 0x68, 0xaf, 0x95, 0x31, 0xa5, 0x21, 0x02, 0xd9, 0x40, 0x78, 0x77, 0x22, 0x98, 0x58, 0x03, 0x40, 0x09, 0x4e, 0xb2, 0xc2, 0x9a, 0x3d, 0xa9, 0xb9, 0x17, 0x3e, 0x79, 0x04, 0x07, 0x6f, 0x13, 0xe3, 0xe7, 0x6d, 0x1a, 0x21, 0x8f, 0x72, 0x6d, 0x87, 0xc4, 0x58, 0x20, 0x5d, 0x3e, 0xf7, 0x48, 0x28, 0xbc, 0x9f, 0x50, 0xef, 0xdf, 0xa9, 0xb9, 0xb1, 0xe8, 0x5c, 0x75, 0xe9, 0xa3, 0x99, 0x4b, 0x28, 0xfe, 0x17, 0xf1, 0x3e, 0x27, 0x28, 0xbf, 0x76, 0x38, 0x37, 0x31, 0xcf, 0xb9, 0x91, 0xa0, 0x43, 0x8a, 0x17, 0xdf, 0x88, 0xfc, 0xfa, 0xa3, 0xd5, 0x27, 0x9b, 0xed, 0x93, 0xd0, 0x1b, 0xd7, 0x11, 0x58, 0x5e, 0x72, 0x97, 0x96, 0x6b, 0xaa, 0x7b, 0x9c, 0x70, 0x4f, 0x06, 0xb6, 0xe8, 0xb9, 0x53, 0x27, 0x9b, 0xac, 0x7d, 0x83, 0x6c, 0x70, 0xb8, 0x9e, 0x45, 0x3f, 0x34, 0x65, 0x8a, 0x7d, 0xe3, 0x32, 0xd8, 0x66, 0x7e, 0x57, 0x0a, 0x12, 0x6b, 0x04, 0xc0, 0x11, 0x56, 0xb6, 0xe5, 0xf4, 0xa1, 0xda, 0xf1, 0x7d, 0x03, 0x5b, 0xdd, 0x60, 0xf4, 0x28, 0x0b, 0xbb, 0xc2, 0x0d, 0x9f, 0xba, 0x68, 0x5e, 0xfe, 0x0a, 0x8a, 0x3c, 0x77, 0x0f, 0x22, 0x94, 0x49, 0x02, 0xd8, 0x0e, 0x91, 0x67, 0xfa, 0x80, 0xc6, 0x8a, 0x93, 0xbe, 0xd2, 0xe6, 0x26, 0xb6, 0x02, 0xa7, 0xf6, 0x48, 0x36, 0xbd, 0xf0, 0x41, 0x2d, 0x12, 0x94, 0x68, 0xc6, 0xee, 0x7f, 0x8a, 0x93, 0xa0, 0x66, 0xe8, 0x1c, 0xdb, 0xac, 0x89, 0xa7, 0x7f, 0xe8, 0x3a, 0x73, 0xa7, 0xee, 0x4e, 0xa1, 0x3d, 0x4d, 0x68, 0x51, 0x6a, 0x4b, 0xd7, 0xa6, 0xa3, 0xbc, 0x55, 0xb3, 0x30, 0x64, 0x33, 0x87, 0x5f, 0x9f, 0x41, 0xd7, 0xce, 0x8d, 0xf7, 0x09, 0x7b, 0x04, 0xb1, 0x8b, 0x7f, 0xf2, 0x08, 0xc5, 0xa8, 0x0a, 0x96, 0x13, 0x58, 0xcf, 0xac, 0x8e, 0x58, 0x64, 0xcd, 0x9a, 0x8a, 0xb9, 0xf2, 0x73, 0xa6, 0xe8, 0xeb, 0x3a, 0x72, 0xf4, 0x64, 0x42, 0x13, 0x2a, 0x5b, 0x8a, 0x7c, 0xda, 0x12, 0xae, 0x0a, 0x31, 0xcd, 0xc5, 0xd2, 0x57, 0xe3, 0xef, 0x3d, 0x33, 0xf2, 0x7e, 0xe3, 0x68, 0x3e, 0x09, 0xd1, 0x67, 0x8a, 0xe0, 0xab, 0xbc, 0xfa, 0x8e, 0x4f, 0xe3, 0xc1, 0x84, 0xe0, 0x54, 0xab, 0x00, 0x78, 0x8c, 0xdc, 0xd5, 0xda, 0x40, 0x31, 0xb6, 0xd7, 0x13, 0x38, 0x04, 0x58, 0x61, 0xa2, 0x61, 0x2d, 0x09, 0x99, 0x86, 0x15, 0x46, 0x7b, 0x0d, 0xab, 0xfd, 0xc1, 0x30, 0x23, 0x11, 0x2a, 0xc3, 0xfc, 0xa8, 0x66, 0xd3, 0x21, 0x6c, 0xe1, 0xb4, 0x1a, 0x32, 0x68, 0x75, 0x3b, 0x96, 0xbc, 0xf3, 0xff, 0x7c, 0x64, 0x10, 0xfc, 0x77, 0x38, 0xc0, 0x18, 0x86, 0x8f, 0xea, 0xee, 0xc5, 0xf5, 0x64, 0x91, 0xd7, 0xe2, 0x74, 0x10, 0x42, 0xcf, 0x9f, 0x71, 0x03, 0x9d, 0xc0, 0x0f, 0xff, 0x41, 0x9f, 0x7d, 0x35, 0x0d, 0x85, 0x61, 0xb5, 0x1c, 0x8f, 0xf8, 0xd4, 0xaf, 0xb2, 0x21, 0x29, 0x8c, 0xb3, 0x2b, 0x2f, 0x9d, 0x90, 0xc2, 0xab, 0x6e, 0x0e, 0xb9, 0x3c, 0x48, 0x76, 0x8e, 0x97, 0xf6, 0xa6, 0xd3, 0x6a, 0x89, 0x0f, 0xfc, 0xec, 0xa0, 0x47, 0x25, 0x7f, 0xfe, 0x2c, 0xcf, 0xfb, 0x7e, 0xe4, 0xac, 0x88, 0xb5, 0x24, 0x06, 0x16, 0xc4, 0x81, 0x46, 0xd8, 0x2d, 0xcd, 0xa3, 0x5b, 0xb6, 0xaf, 0x1f, 0x17, 0xa2, 0xfd, 0x34, 0x8e, 0xd6, 0x95, 0xeb, 0x64, 0xa8, 0x9e, 0x3c, 0xfb, 0x70, 0x8f, 0xf0, 0x81, 0x1e, 0x50, 0x62, 0x74, 0x6b, 0x57, 0xdc, 0x15, 0x65, 0x9f, 0x70, 0x50, 0x70, 0xc3, 0x75, 0xfc, 0xf4, 0xc2, 0x28, 0x8d, 0x61, 0x0d, 0x09, 0xa2, 0x31, 0xf6, 0xe5, 0xef, 0x1b, 0xb1, 0xc2, 0x7a, 0x9f, 0x5b, 0x0b, 0x3b, 0x8f, 0xd7, 0xb7, 0x76, 0x5c, 0x69, 0x48, 0x7d, 0x27, 0x52, 0xdb, 0x9b, 0xf2, 0xf4, 0xa9, 0x62, 0x78, 0x26, 0xb4, 0x9f, 0x6e, 0xc3, 0x78, 0x9f, 0x4c, 0xa9, 0xe4, 0x9a, 0xd3, 0xab, 0xee, 0x65, 0xf4, 0x29, 0x84, 0xc1, 0xd3, 0x4d, 0xb6, 0xec, 0xf2, 0x2d, 0x4d, 0x3d, 0xe1, 0x4f, 0x3e, 0x09, 0xe8, 0x3c, 0x93, 0x04, 0x8b, 0x38, 0xd7, 0xd8, 0xe3, 0x3c, 0x0a, 0xc9, 0x2a, 0xcf, 0xaa, 0x70, 0xef, 0x5b, 0x65, 0x01, 0xdd, 0x10, 0x74, 0xac, 0xfc, 0x8b, 0xbb, 0xed, 0xd9, 0xb0, 0x1e, 0x02, 0x11, 0x8e, 0xc3, 0xbb, 0x05, 0x2d, 0x19, 0x6c, 0xd7, 0x93, 0xdf, 0xb6, 0xe7, 0x76, 0x93, 0x5f, 0x6a, 0x5d, 0xf0, 0x85, 0xe3, 0x1e, 0x75, 0xd0, 0x83, 0x05, 0x06, 0x7b, 0xc9, 0x1a, 0x39, 0x50, 0xe5, 0x3f, 0xd5, 0xf6, 0xae, 0x1e, 0x89, 0x2f, 0x2e, 0x38, 0xff, 0xd1, 0x21, 0x76, 0xb0, 0xb6, 0xe3, 0x06, 0x30, 0xdd, 0xa2, 0x82, 0xdc, 0x6f, 0xda, 0x9a, 0x07, 0x79, 0x71, 0xb5, 0x30, 0x7b, 0xef, 0x55, 0xcb, 0x2a, 0xae, 0x2a, 0xa5, 0xfa, 0x07, 0x1e, 0xfb, 0x50, 0xc5, 0xc7, 0xbd, 0x81, 0x6c, 0x0e, 0xa3, 0xe2, 0x29, 0xf0, 0x01, 0xa5, 0x69, 0xad, 0x87, 0x40, 0x67, 0xcb, 0x57, 0x90, 0x48, 0xbd, 0x1e, 0x0f, 0x7e, 0x16, 0x20, 0xaa, 0x92, 0x97, 0x58, 0x2d, 0x90, 0x86, 0x29, 0x4c, 0xa9, 0x12, 0x3a, 0xae, 0xde, 0xbc, 0x73, 0x90, 0xa9, 0x03, 0x47, 0xea, 0x14, 0xcb, 0xba, 0x1f, 0xa1, 0x46, 0xbb, 0xa1, 0xed, 0x49, 0xe0, 0x20, 0x14, 0x5c, 0x90, 0x25, 0x17, 0xf3, 0x19, 0x2b, 0xd7, 0x94, 0x5c, 0x9e, 0x77, 0xe1, 0xf0, 0x53, 0x2b, 0xc6, 0xfa, 0x58, 0xb7, 0x47, 0x15, 0x3b, 0x3d, 0xa3, 0x01, 0x20, 0x1d, 0xcf, 0x00, 0x41, 0xe6, 0x8a, 0x0f, 0xb9, 0xc1, 0x74, 0x64, 0xb3, 0xc1, 0xf9, 0xe3, 0x56, 0x03, 0xfb, 0x6e, 0x15, 0x90, 0x86, 0x46, 0x2c, 0x5f, 0xf7, 0xda, 0x7d, 0xf6, 0x6a, 0xc4, 0x12, 0x84, 0x57, 0xcf, 0xf7, 0x75, 0xa0, 0x36, 0x30, 0xc8, 0x90, 0x95, 0xfd, 0xca, 0x8a, 0x1d, 0xbc, 0xe1, 0x4e, 0x16, 0x01, 0x90, 0x33, 0xc6, 0xcf, 0xf2, 0xb4, 0x2e, 0x00, 0x35, 0x18, 0x4d, 0x3f, 0xed, 0x35, 0xce, 0x2d, 0x41, 0x82, 0x5c, 0x92, 0x3e, 0xf6, 0xec, 0xa9, 0xe8, 0x74, 0xcb, 0xfa, 0xc5, 0xbe, 0x44, 0x46, 0xf5, 0x25, 0x0b, 0x6b, 0x2a, 0x7e, 0xec, 0x64, 0xfc, 0x0b, 0x57, 0xb3, 0x77, 0x62, 0xb6, 0xd6, 0xdf, 0x7a, 0xc8, 0xac, 0x04, 0x75, 0x5c, 0xd7, 0xa5, 0xc9, 0x25, 0x80, 0xb8, 0xd5, 0x88, 0x17, 0x9f, 0x15, 0x96, 0xf1, 0x94, 0x77, 0xa1, 0xce, 0xde, 0x87, 0x13, 0xbe, 0x93, 0x77, 0x70, 0xe5, 0xf8, 0x32, 0xb7, 0x11, 0xd2, 0x02, 0x8e, 0x2f, 0x1e, 0x7e, 0xd4, 0xfe, 0x16, 0xc1, 0xa7, 0xab, 0x7f, 0x22, 0xdf, 0x13, 0x92, 0xe6, 0x8e, 0xe5, 0x03, 0xb3, 0x25, 0xf6, 0x07, 0xb6, 0x1b, 0x55, 0x4a, 0xbc, 0x5c, 0x16, 0x34, 0xb6, 0xdc, 0xd9, 0x06, 0x6c, 0xf7, 0x6d, 0x90, 0x54, 0x9a, 0x3d, 0x9e, 0xce, 0x50, 0x49, 0x58, 0x36, 0xa9, 0xd6, 0x27, 0x9a, 0xa5, 0x32, 0xef, 0x03, 0x09, 0x21, 0xa4, 0x8c, 0xdb, 0xd5, 0x89, 0xcd, 0x56, 0x83, 0xa1, 0x50, 0x1f, 0x06, 0x29, 0x04, 0x8e, 0x0c, 0x15, 0xff, 0x4a, 0xcf, 0xf0, 0xf5, 0x9c, 0x50, 0x99, 0x2b, 0x1e, 0x8f, 0xb8, 0xe4, 0xc2, 0x4c, 0xec, 0x79, 0x4d, 0x2a, 0x04, 0xa9, 0xc1, 0x61, 0xcb, 0xcb, 0x52, 0x48, 0x3b, 0xe9, 0xe2, 0x5b, 0x14, 0x00, 0x1f, 0xa4, 0x38, 0xd7, 0xc4, 0x87, 0x3e, 0x3a, 0x92, 0x6e, 0x25, 0x85, 0xff, 0xd9, 0x1b, 0xc0, 0xbf, 0xb7, 0xac, 0xce, 0x93, 0x27, 0xf1, 0x63, 0x0b, 0xf4, 0x71, 0xc3, 0x2c, 0x71, 0xde, 0x7e, 0x17, 0x8b, 0xe0, 0xb1, 0x33, 0x33, 0x8d, 0x7e, 0x74, 0x72, 0x4d, 0xb7, 0xaf, 0xd2, 0x3d, 0x02, 0x32, 0xe2, 0x5e, 0xe5, 0xf8, 0x10, 0x14, 0x81, 0x38, 0x13, 0xcc, 0xf2, 0x34, 0x98, 0xc8, 0x8c, 0x6b, 0x0c, 0x6e, 0x7f, 0xae, 0x90, 0x92, 0x92, 0xac, 0x86, 0x98, 0xed, 0xf6, 0x43, 0x73, 0x41, 0x9c, 0xd5, 0xc7, 0xba, 0xcf, 0xda, 0xcb, 0x72, 0x3a, 0xee, 0xa0, 0x7c, 0xf6, 0x21, 0x3f, 0x9f, 0x4c, 0x73, 0x3c, 0x60, 0xaf, 0x5f, 0xed, 0xf4, 0x96, 0xd4, 0xc7, 0x3e, 0x29, 0x3f, 0xf2, 0xe8, 0xe5, 0x7c, 0x6d, 0x3e, 0xad, 0xc7, 0x40, 0x68, 0xe9, 0x13, 0x96, 0x0b, 0xa4, 0x5d, 0xc1, 0x94, 0xdd, 0xcf, 0x77, 0x95, 0x64, 0xe2, 0xd2, 0x0a, 0x03, 0xcd, 0xeb, 0x66, 0xd3, 0xd9, 0x03, 0xc1, 0xeb, 0x89, 0xa5, 0x86, 0xd9, 0x9b, 0x2f, 0x77, 0x8d, 0x56, 0xaa, 0xed, 0xa2, 0xa4, 0xe1, 0xa6, 0x34, 0xf3, 0x1f, 0x86, 0xae, 0xe3, 0x09, 0x19, 0x36, 0x26, 0x6b, 0xc6, 0xb3, 0x2b, 0x03, 0xfe, 0x7e, 0x71, 0x9b, 0xcb, 0x4e, 0xa3, 0xec, 0x98, 0xe5, 0xcc, 0x2c, 0x13, 0x88, 0x50, 0x45, 0x7a, 0x5d, 0x76, 0x0b, 0xbe, 0x22, 0xad, 0xed, 0x4d, 0xe8, 0xd8, 0x00, 0x61, 0xbb, 0x52, 0x63, 0x32, 0x65, 0x6f, 0x4f, 0x6a, 0xbd, 0xab, 0x5c, 0xaa, 0x24, 0xd0, 0xc0, 0x14, 0x24, 0xc1, 0xa9, 0x14, 0x57, 0xb6, 0xe4, 0xeb, 0x0b, 0x10, 0x6f, 0xb4, 0x45, 0x1f, 0xba, 0xde, 0x11, 0x6e, 0xa7, 0x55, 0x57, 0x80, 0x95, 0xe2, 0x88, 0x06, 0xf8, 0x6d, 0xef, 0x01, 0x5f, 0x29, 0x75, 0x5a, 0xdc, 0xdf, 0x15, 0xcf, 0x27, 0xe0, 0x66, 0x60, 0x12, 0x44, 0xec, 0x7a, 0xfa, 0x89, 0x12, 0xa5, 0x68, 0xc4, 0x02, 0x64, 0x12, 0xd9, 0xc7, 0x89, 0xcf, 0x86, 0x60, 0x41, 0x56, 0x2f, 0xb0, 0x81, 0xbf, 0xaa, 0x7d, 0xa8, 0x26, 0x94, 0xe5, 0x74, 0xee, 0xd2, 0xf3, 0xb0, 0x77, 0x52, 0x4a, 0x1f, 0x54, 0x3f, 0x07, 0xa2, 0x43, 0x18, 0x46, 0x8e, 0x83, 0x7f, 0x06, 0xb6, 0x45, 0xa8, 0x3e, 0xa2, 0x4b, 0xa6, 0x6c, 0xe6, 0x05, 0x21, 0xec, 0xaa, 0xaf, 0x19, 0xe0, 0xc7, 0x3c, 0xcd, 0x7d, 0x0b, 0x2a, 0xea, 0xfb, 0x83, 0x77, 0x8b, 0x85, 0xf4, 0x49, 0xc5, 0xe2, 0xcb, 0x1f, 0xba, 0xbc, 0x2b, 0x89, 0x6a, 0xb0, 0xf5, 0xbf, 0xc6, 0x97, 0xe1, 0x94, 0xba, 0xb1, 0x0e, 0xa6, 0x32, 0xa2, 0x97, 0xc1, 0x4e, 0x67, 0x14, 0xd1, 0x43, 0xb6, 0x1c, 0xeb, 0xa9, 0x6b, 0x2f, 0x2d, 0x30, 0xfa, 0x90, 0x9a, 0xf1, 0x0c, 0x04, 0x20, 0xe6, 0xb1, 0x7c, 0x72, 0x36, 0xd4, 0x13, 0x68, 0x5b, 0xe2, 0xfa, 0x00, 0x56, 0xc9, 0x27, 0x49, 0x74, 0xc2, 0xed, 0xc7, 0x60, 0x8a, 0xd4, 0x0d, 0x75, 0xfc, 0x48, 0xae, 0x97, 0x38, 0x08, 0xca, 0x07, 0xbe, 0x64, 0xb1, 0xf6, 0x2f, 0xac, 0x88, 0xca, 0x9d, 0x6d, 0xe4, 0x53, 0x91, 0x51, 0xab, 0x78, 0x45, 0xd0, 0xcf, 0x04, 0x9e, 0xef, 0xad, 0x9d, 0xfc, 0xcc, 0x0f, 0x20, 0xde, 0xb8, 0x32, 0xd5, 0xf2, 0x05, 0x4c, 0x45, 0x1a, 0xf2, 0x61, 0xa0, 0x64, 0x2b, 0x7f, 0xf9, 0x25, 0xec, 0x94, 0xcb, 0x8d, 0xb3, 0x89, 0x92, 0x7a, 0xfd, 0x52, 0x5d, 0x65, 0x9e, 0x15, 0xb1, 0x9e, 0x8e, 0xa2, 0x1d, 0x37, 0x4f, 0xd3, 0x52, 0x5f, 0x3f, 0xa1, 0xa8, 0x00, 0x78, 0xf5, 0x60, 0xdd, 0x16, 0x79, 0x0e, 0x9e, 0x09 }; +constexpr AccessUnit LPCM_SKIP_BYTES_EXPECTED_AU = { 0x15f90, 0x153d5, false, 3, { 0xe6, 0xa3, 0x12, 0x99, 0xcf, 0x16, 0x2e, 0x6d, 0x67, 0x2a, 0xa2, 0xb4, 0xf7, 0xa2, 0x3c, 0xdf }, { 0x97, 0xf7, 0x18, 0x4f, 0xfc, 0x6b, 0x28, 0x74, 0x44, 0x69, 0x80, 0xc1, 0x76, 0x96, 0x50, 0xe6, 0x23, 0x0d, 0xdf, 0xf2 } }; + + +const std::vector AVC_BEGIN_OF_AU_SPLIT_STREAM = { 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xe0, 0x06, 0xe6, 0x81, 0xc1, 0x0d, 0x31, 0x00, 0x05, 0xbf, 0x21, 0x11, 0x00, 0x05, 0xb3, 0x65, 0x1e, 0x69, 0xb2, 0x5c, 0xe5, 0xaf, 0x00, 0xfd, 0x0f, 0x1d, 0x27, 0x61, 0x90, 0xd4, 0x77, 0x92, 0x34, 0x4a, 0x7a, 0xdc, 0x96, 0x0d, 0x27, 0x58, 0x2f, 0xfa, 0x88, 0x0d, 0xb6, 0x88, 0xcb, 0x5f, 0xd7, 0x79, 0xc8, 0xe5, 0x46, 0xe3, 0x99, 0xc7, 0x10, 0x1d, 0xfa, 0x50, 0xd7, 0x07, 0xcf, 0xcf, 0x21, 0x1c, 0xaf, 0x1c, 0x74, 0x86, 0x02, 0x33, 0x71, 0xc2, 0x81, 0x7f, 0xd6, 0xea, 0xe0, 0xab, 0xa5, 0xf2, 0x66, 0xb1, 0x69, 0x10, 0x40, 0x36, 0x55, 0x95, 0x09, 0xba, 0x8d, 0x65, 0xc8, 0x33, 0x21, 0xa0, 0xcf, 0x1c, 0xfc, 0xa4, 0x2b, 0x3e, 0x8f, 0x92, 0x74, 0xbe, 0x8a, 0x75, 0xed, 0x8a, 0x33, 0x85, 0x42, 0xcf, 0xf2, 0x0e, 0xaa, 0xe2, 0x8f, 0x51, 0xee, 0xd9, 0x67, 0x8c, 0x24, 0x75, 0x18, 0xf5, 0x90, 0x3e, 0x74, 0xf8, 0x43, 0x4e, 0xc5, 0x5d, 0xe1, 0xd5, 0x6f, 0x97, 0x6d, 0xef, 0xd5, 0x5f, 0x12, 0xb0, 0x83, 0xcb, 0x07, 0x02, 0x8c, 0x1d, 0x91, 0x2e, 0x04, 0x2c, 0x34, 0xff, 0xa0, 0xdc, 0x27, 0xe9, 0x53, 0x9e, 0x6f, 0xe2, 0x75, 0xd6, 0x2a, 0x73, 0x17, 0x71, 0xe7, 0x5e, 0x93, 0x98, 0x9f, 0xca, 0x01, 0xd9, 0x03, 0x60, 0x6d, 0x49, 0xed, 0x54, 0x79, 0x90, 0x09, 0x1a, 0x52, 0xfa, 0x36, 0x06, 0x5f, 0x7a, 0x0a, 0xd7, 0x9e, 0xbc, 0x97, 0xbb, 0xa1, 0xc5, 0xfd, 0xaa, 0xb8, 0x62, 0x82, 0x72, 0x73, 0xfb, 0x29, 0x86, 0x35, 0x25, 0x8c, 0x2b, 0x9b, 0xdd, 0xf2, 0x73, 0xd6, 0xc0, 0x34, 0x32, 0x14, 0x43, 0x3d, 0x48, 0xe0, 0x58, 0x2e, 0x7d, 0x81, 0x6f, 0xb0, 0x05, 0xde, 0x7c, 0xff, 0xb6, 0xa2, 0xc6, 0x3d, 0x57, 0xea, 0x84, 0xa8, 0x28, 0x32, 0x51, 0x67, 0xf5, 0xa8, 0x0d, 0x58, 0x34, 0x1e, 0x59, 0x05, 0x4a, 0xff, 0x3b, 0x44, 0x0e, 0xe1, 0x21, 0x49, 0xe5, 0x4f, 0x6c, 0x6e, 0xe0, 0x52, 0xc1, 0x86, 0xec, 0x17, 0x61, 0xdd, 0xc5, 0x6a, 0x15, 0x6e, 0x76, 0x9d, 0xe0, 0x51, 0x55, 0x0c, 0x63, 0x12, 0xe4, 0x9c, 0x3c, 0xa5, 0x7c, 0xb5, 0xc1, 0xd7, 0xbf, 0xc2, 0x3c, 0x2f, 0xb9, 0xca, 0x69, 0x15, 0xfd, 0x02, 0x06, 0xb9, 0xc9, 0xa2, 0x1f, 0x25, 0xc1, 0x18, 0x54, 0x76, 0x8c, 0x7b, 0x8c, 0x12, 0x55, 0xb6, 0xa2, 0xbb, 0x08, 0xa2, 0x9b, 0xab, 0xa1, 0xfd, 0xb2, 0x1d, 0x42, 0x38, 0x71, 0x5a, 0xba, 0xc4, 0x09, 0x3b, 0x06, 0x51, 0x38, 0x16, 0xb8, 0x94, 0xab, 0x41, 0x24, 0x9e, 0x93, 0x3f, 0x82, 0x85, 0x0c, 0x97, 0xf0, 0x78, 0x21, 0xeb, 0x4f, 0xe9, 0xf3, 0xf1, 0x3a, 0x53, 0x90, 0x91, 0xe6, 0xdb, 0x5f, 0x56, 0x22, 0x1d, 0x33, 0x61, 0x83, 0xf5, 0xf2, 0xac, 0x0b, 0x9b, 0xb4, 0xda, 0x58, 0xc4, 0xac, 0xf2, 0xa6, 0xd6, 0xfb, 0x37, 0x7a, 0x97, 0x70, 0x22, 0x4c, 0x6c, 0x1d, 0x4d, 0x52, 0x29, 0x07, 0xdf, 0xc9, 0x79, 0x30, 0xd4, 0x63, 0x92, 0x15, 0xc8, 0x3c, 0xd9, 0x51, 0x56, 0xb9, 0xc9, 0x41, 0x8c, 0x45, 0xe1, 0x18, 0x99, 0xa7, 0xbf, 0xb8, 0x3b, 0x45, 0x84, 0x48, 0xdd, 0x39, 0x36, 0xb3, 0x21, 0x48, 0xf1, 0x69, 0x51, 0x62, 0x45, 0x6b, 0xf4, 0xf6, 0xed, 0x41, 0xda, 0x8f, 0x64, 0xb8, 0x39, 0xa5, 0x36, 0x58, 0x8a, 0xc1, 0xd6, 0x6c, 0x3a, 0xc6, 0xf5, 0x41, 0x9f, 0xe5, 0x7b, 0x68, 0x9e, 0xbf, 0x39, 0x55, 0x9d, 0xda, 0x14, 0xa3, 0x2e, 0x4a, 0xa8, 0x25, 0x31, 0x4c, 0x9f, 0xb6, 0xf2, 0x1d, 0x67, 0x20, 0x2a, 0x49, 0x0e, 0x65, 0x04, 0xa5, 0x3d, 0x6e, 0xb7, 0x95, 0x4d, 0x90, 0x63, 0xec, 0xa0, 0xc7, 0xd4, 0x16, 0x5e, 0xe7, 0x33, 0x77, 0xbf, 0x03, 0x09, 0xfc, 0x5e, 0xe9, 0x21, 0x3f, 0x58, 0x76, 0xdc, 0x4a, 0x19, 0x89, 0x8e, 0x05, 0x90, 0x45, 0xb1, 0x55, 0xfc, 0x79, 0x44, 0x88, 0xcc, 0xc3, 0x24, 0x1d, 0xf4, 0xc5, 0x07, 0x65, 0xcf, 0x39, 0x2e, 0xeb, 0x43, 0x70, 0x41, 0xb3, 0x56, 0x8c, 0x51, 0x64, 0xc1, 0xcd, 0x42, 0x1b, 0xfa, 0x05, 0x80, 0x6c, 0xa6, 0x15, 0xe5, 0xa2, 0x2d, 0xd3, 0x34, 0x5f, 0x9e, 0xab, 0x7b, 0xd4, 0x0f, 0x14, 0x67, 0x3e, 0x28, 0x4f, 0xab, 0x30, 0xa7, 0x02, 0xb5, 0x59, 0xcd, 0x35, 0xfa, 0x43, 0xe4, 0x77, 0xe6, 0xa5, 0x04, 0xba, 0x91, 0xf8, 0x0a, 0xc5, 0xb0, 0xef, 0x48, 0xf3, 0x8a, 0x97, 0x9f, 0x9a, 0x01, 0xd3, 0x28, 0x99, 0x70, 0xf6, 0xa2, 0x50, 0xe5, 0x75, 0xcc, 0xd4, 0x22, 0x50, 0x95, 0x6b, 0xc2, 0x95, 0xcd, 0xeb, 0x8e, 0x01, 0xa9, 0x70, 0x25, 0x9f, 0x62, 0xf4, 0x3a, 0xfe, 0xec, 0x41, 0xb3, 0x49, 0xce, 0x68, 0xfe, 0xc3, 0xe5, 0x1f, 0x7d, 0xfd, 0x7d, 0x78, 0x4c, 0xa4, 0x55, 0x8b, 0x19, 0xf0, 0x4c, 0xce, 0xb8, 0xa4, 0xb1, 0xe1, 0x86, 0x03, 0xb0, 0x46, 0xc5, 0xa4, 0xdc, 0xcb, 0x20, 0xc5, 0x55, 0xbb, 0xf4, 0xc6, 0xba, 0x70, 0x27, 0xa2, 0xd5, 0xd8, 0x05, 0x25, 0x60, 0xb6, 0x6e, 0xe0, 0xda, 0x03, 0x6c, 0x98, 0x0c, 0xa4, 0xf1, 0xe7, 0x33, 0x6d, 0xf2, 0x1d, 0xf6, 0x99, 0x4b, 0xd6, 0x84, 0x4c, 0x2e, 0xf1, 0x54, 0x42, 0x78, 0xa2, 0x2f, 0x08, 0x9e, 0x95, 0xf7, 0x1f, 0xfa, 0xe1, 0x50, 0x1a, 0x1c, 0x69, 0x98, 0x1d, 0x2b, 0x1d, 0xe0, 0xec, 0xe6, 0x28, 0xda, 0xc8, 0x76, 0xf3, 0xaa, 0x91, 0xf8, 0x63, 0x04, 0x6b, 0xa6, 0x3b, 0x8e, 0xbb, 0x45, 0x8c, 0x7b, 0x5a, 0x75, 0xe7, 0x26, 0xe0, 0x07, 0xd7, 0xb7, 0x6d, 0x6f, 0x4c, 0xc5, 0xda, 0xde, 0xc7, 0xcf, 0xf2, 0x07, 0xd8, 0xad, 0x23, 0x0e, 0xa2, 0xc2, 0xcf, 0xe7, 0xbd, 0x9e, 0x41, 0x09, 0xb2, 0x9b, 0x6b, 0xcc, 0x4d, 0xe9, 0xe1, 0x88, 0xbb, 0x12, 0x76, 0x20, 0xe9, 0x60, 0x73, 0x08, 0x87, 0x7e, 0xb8, 0x71, 0x7b, 0x7c, 0x75, 0xb1, 0x5a, 0xfb, 0x9e, 0xd1, 0xb4, 0x2b, 0x94, 0xa8, 0x5f, 0x88, 0xf2, 0xec, 0x9a, 0x21, 0x42, 0x9f, 0x70, 0xd9, 0xf5, 0x6a, 0xad, 0xbd, 0x88, 0x75, 0x86, 0xc2, 0x1e, 0xcb, 0x45, 0xe7, 0x27, 0xa2, 0xe8, 0x48, 0xd7, 0xaf, 0x22, 0x30, 0xe6, 0x47, 0x36, 0x9e, 0x5d, 0x0d, 0xa3, 0x5c, 0x84, 0xcd, 0x14, 0x63, 0xae, 0x12, 0x28, 0x6a, 0xcf, 0x75, 0xfb, 0x62, 0x84, 0x25, 0x8c, 0xda, 0x10, 0xaa, 0xf8, 0xa7, 0xfa, 0xee, 0xa5, 0x9e, 0x54, 0x62, 0xe7, 0xdd, 0x11, 0xb3, 0x3e, 0x1f, 0x9e, 0x00, 0x0a, 0x89, 0x55, 0x7c, 0x28, 0x56, 0xb9, 0xb2, 0x0a, 0xc9, 0x83, 0xc4, 0x51, 0x6b, 0x6d, 0x9f, 0xec, 0xd0, 0x49, 0x41, 0xd2, 0xcb, 0xf7, 0xc9, 0x38, 0x85, 0x2f, 0x0b, 0xd4, 0x84, 0x6c, 0xd9, 0xd3, 0x35, 0x44, 0x4d, 0x9a, 0x80, 0xee, 0xca, 0xf5, 0x77, 0x2e, 0xf5, 0xd8, 0xc0, 0xd9, 0x05, 0xfc, 0xfe, 0xaf, 0x0b, 0x62, 0x90, 0x21, 0x73, 0x2f, 0x3f, 0x39, 0x44, 0x74, 0x7f, 0x18, 0x20, 0xa1, 0x34, 0x49, 0xeb, 0x1f, 0x69, 0x50, 0xa5, 0x1c, 0x51, 0x3b, 0x4c, 0xeb, 0x1e, 0xc9, 0x5f, 0xe9, 0xe4, 0xed, 0x6e, 0x37, 0x3d, 0x44, 0xd9, 0x86, 0x8e, 0x5c, 0x05, 0x48, 0x4a, 0x64, 0x9d, 0x9e, 0x6c, 0x26, 0x03, 0x1d, 0xa3, 0x2d, 0xa0, 0x7c, 0x51, 0xf6, 0xaf, 0xe1, 0xaf, 0xeb, 0x05, 0xdc, 0x6a, 0x05, 0xc7, 0x15, 0x0e, 0xc8, 0xd6, 0x99, 0x9b, 0xdf, 0x7f, 0x9b, 0x25, 0x40, 0x17, 0x96, 0x97, 0xa7, 0x15, 0x6a, 0xbd, 0x70, 0x11, 0x64, 0x26, 0x90, 0x55, 0x80, 0x7d, 0xed, 0xd5, 0xb5, 0xc3, 0x86, 0x9a, 0x5b, 0xb5, 0x31, 0x83, 0x35, 0x69, 0x81, 0x59, 0x32, 0x1a, 0x72, 0xf8, 0xae, 0xe0, 0xfa, 0x1e, 0x34, 0xa1, 0xc3, 0xfd, 0x88, 0xa1, 0xa8, 0x27, 0xa9, 0x95, 0x61, 0x09, 0xfb, 0xc5, 0xd5, 0x48, 0x97, 0x19, 0x1e, 0xfb, 0xd5, 0x03, 0xdf, 0xa4, 0x59, 0x82, 0x12, 0x5e, 0x63, 0x93, 0xe3, 0x8b, 0xd2, 0x3c, 0x13, 0x4d, 0x14, 0x90, 0xe0, 0x28, 0x95, 0xb3, 0x79, 0xcb, 0x62, 0x7d, 0x80, 0xfd, 0xa8, 0xbd, 0xdc, 0x69, 0x07, 0x0e, 0x59, 0xc3, 0x57, 0xca, 0xbe, 0xd9, 0xfb, 0xd0, 0x34, 0x26, 0x98, 0x7c, 0x6a, 0xa7, 0x3f, 0x4f, 0x70, 0x8f, 0x9c, 0x63, 0x3e, 0xa0, 0x84, 0x14, 0x95, 0x59, 0xe6, 0xb3, 0x38, 0x99, 0xf7, 0xb4, 0x9d, 0x34, 0x50, 0x35, 0xe2, 0x74, 0x90, 0xa4, 0x1a, 0x93, 0xe1, 0xd1, 0x46, 0x68, 0xa7, 0x4d, 0x02, 0x48, 0x32, 0x49, 0x39, 0xd8, 0xd1, 0x57, 0x85, 0xc5, 0x36, 0xd7, 0x87, 0x08, 0x7a, 0xca, 0xb8, 0xb5, 0x4a, 0x02, 0x1a, 0x98, 0x5e, 0x5b, 0x57, 0xb5, 0x14, 0x8f, 0x10, 0x33, 0xbe, 0xbd, 0x43, 0x17, 0xf3, 0x0e, 0x15, 0x49, 0x84, 0xc9, 0xcd, 0xbb, 0xe6, 0x19, 0x0b, 0x2e, 0xf4, 0xfc, 0xdf, 0x48, 0x3e, 0xe4, 0x5f, 0x72, 0x8a, 0x8d, 0x08, 0x90, 0x93, 0x0d, 0x64, 0xd6, 0xa2, 0xf6, 0x28, 0x63, 0x73, 0x56, 0x8a, 0xfb, 0xd5, 0x6f, 0xf9, 0x80, 0x88, 0xeb, 0xe4, 0x42, 0x7c, 0x62, 0x7e, 0xd7, 0xe2, 0x8c, 0x1f, 0x68, 0x5b, 0xae, 0x6c, 0xba, 0x3a, 0x43, 0xc5, 0x52, 0x55, 0xe0, 0x3c, 0x7d, 0x52, 0x75, 0xd5, 0x6a, 0x0f, 0xd8, 0xdd, 0x53, 0x1d, 0xcb, 0x61, 0xa7, 0x80, 0x2a, 0x82, 0x70, 0x25, 0x8e, 0xb5, 0xdf, 0xea, 0xb1, 0x2a, 0xab, 0x1f, 0x6b, 0xad, 0x86, 0x78, 0xba, 0x98, 0x9b, 0x3a, 0x64, 0xf2, 0xdd, 0x5b, 0x65, 0x89, 0x20, 0xc4, 0xa6, 0x98, 0x67, 0x67, 0x3c, 0xe6, 0xaf, 0x1c, 0x3a, 0xd9, 0xf0, 0x1e, 0x14, 0x96, 0xbe, 0x08, 0x21, 0xad, 0xa1, 0x44, 0xa1, 0xed, 0xdf, 0x52, 0xad, 0x3d, 0x84, 0x4d, 0x2c, 0x7d, 0xd9, 0xe5, 0xed, 0x80, 0xda, 0x3f, 0x22, 0xd7, 0xe6, 0xb3, 0xa5, 0xc6, 0xe9, 0x50, 0x3b, 0xbc, 0xf8, 0xc5, 0xc6, 0x7e, 0x7f, 0xce, 0x40, 0x69, 0x91, 0xe9, 0xc1, 0x8b, 0xfb, 0xa7, 0xca, 0xae, 0xab, 0xee, 0x14, 0x2b, 0x3c, 0x35, 0x01, 0xfa, 0x91, 0x2f, 0xea, 0xcf, 0x8c, 0xc7, 0x01, 0xed, 0x9b, 0x86, 0xff, 0xea, 0x7d, 0xb6, 0xf2, 0x43, 0x46, 0xf7, 0x3f, 0xf1, 0x96, 0x02, 0x00, 0xde, 0xfc, 0x3b, 0xc5, 0x0a, 0x6e, 0xe8, 0xd6, 0x47, 0x4e, 0xb9, 0x65, 0xcb, 0x59, 0xe9, 0x05, 0x08, 0xb6, 0x67, 0x13, 0x02, 0x8a, 0x61, 0xbe, 0x20, 0x15, 0x87, 0x7a, 0x8e, 0x56, 0xc4, 0x04, 0x18, 0xd4, 0xa0, 0x48, 0x24, 0x73, 0x90, 0xe0, 0x0f, 0xbb, 0xca, 0x98, 0xeb, 0x77, 0xc9, 0x70, 0x7a, 0x8e, 0x1a, 0xd1, 0x57, 0xc8, 0x09, 0xe7, 0x6f, 0x54, 0xd9, 0xe5, 0xf9, 0xc3, 0x79, 0xb8, 0xb7, 0xa3, 0x11, 0x3b, 0x08, 0xc7, 0x7e, 0xe2, 0xcb, 0xc8, 0x5e, 0x87, 0x68, 0x3a, 0xee, 0x78, 0x45, 0x67, 0x8b, 0xed, 0x22, 0xde, 0x7f, 0x4b, 0xad, 0xc3, 0xc8, 0x88, 0xa8, 0x54, 0x86, 0xbe, 0x82, 0x08, 0xaa, 0xee, 0x81, 0xd0, 0xa6, 0x29, 0xf0, 0x66, 0x91, 0xa5, 0xa7, 0xc4, 0x2f, 0x26, 0x72, 0x10, 0xea, 0x92, 0x9c, 0xde, 0x23, 0x90, 0x9e, 0x4e, 0x01, 0x7f, 0x93, 0x13, 0x7f, 0x95, 0x89, 0x22, 0x8e, 0x53, 0xcd, 0xa7, 0x68, 0x7f, 0xa4, 0x78, 0xef, 0xaf, 0x30, 0x3e, 0xfe, 0xbe, 0x62, 0x22, 0x10, 0x8e, 0x52, 0xbd, 0xbe, 0x30, 0x5c, 0x5d, 0x84, 0xbe, 0x1d, 0xeb, 0x27, 0x4a, 0x8c, 0x17, 0xd8, 0x91, 0x97, 0x85, 0x7b, 0xb8, 0x65, 0x11, 0x84, 0xe2, 0x6f, 0x4f, 0x61, 0x3e, 0x05, 0x5d, 0x53, 0x60, 0x8b, 0xe8, 0x35, 0x4d, 0x58, 0x12, 0x60, 0x3a, 0xaf, 0x7a, 0x2a, 0xe4, 0xb3, 0x82, 0x33, 0x02, 0x15, 0x1b, 0xc9, 0x37, 0xd9, 0xa5, 0x81, 0xe3, 0x91, 0xf3, 0x08, 0xb4, 0x8d, 0xad, 0x90, 0x96, 0xb5, 0xb0, 0xe9, 0x23, 0xba, 0xb7, 0x25, 0x38, 0xb9, 0x07, 0x0f, 0xc1, 0x4c, 0xdc, 0x6d, 0x3c, 0x85, 0x6b, 0xea, 0x96, 0x04, 0xf0, 0xca, 0xfb, 0xb7, 0xdc, 0x45, 0xcb, 0x11, 0x5b, 0x7e, 0x14, 0xcc, 0x2d, 0xc4, 0x23, 0xcb, 0x68, 0xeb, 0x56, 0xe9, 0xaa, 0x7a, 0x44, 0x5b, 0x92, 0xc1, 0x3b, 0xff, 0xfd, 0x16, 0x5a, 0xf3, 0x4c, 0xbc, 0x38, 0x1e, 0x36, 0x68, 0xd4, 0xa2, 0x4d, 0xcb, 0xc7, 0xee, 0x3a, 0x1d, 0xa5, 0x69, 0x67, 0xd8, 0xd7, 0x34, 0x7a, 0xe9, 0x2b, 0x6d, 0xb0, 0xe4, 0x47, 0x81, 0x1f, 0xef, 0xf6, 0xd4, 0x60, 0x07, 0x92, 0x1d, 0xd1, 0x61, 0xbb, 0x8f, 0x3f, 0x4a, 0x0b, 0xbd, 0xae, 0x6f, 0x77, 0xf2, 0x46, 0x64, 0x77, 0x34, 0xf1, 0x93, 0xa5, 0x3a, 0x2b, 0x98, 0x79, 0x93, 0x54, 0xc2, 0x7b, 0x63, 0xad, 0xdb, 0xb8, 0x9e, 0xa2, 0x9c, 0xba, 0xe6, 0x7c, 0xf1, 0x0f, 0x0e, 0x68, 0x04, 0xba, 0x63, 0xf2, 0xe5, 0xbd, 0x85, 0xf3, 0x6c, 0x96, 0x40, 0xb0, 0xf2, 0x71, 0x2f, 0x50, 0xe8, 0x20, 0x38, 0xac, 0xe6, 0xc9, 0x26, 0x7a, 0xca, 0xeb, 0xec, 0xd0, 0x40, 0x65, 0x34, 0x4b, 0x70, 0x07, 0x23, 0xee, 0x65, 0x00, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xe0, 0x06, 0xe6, 0x81, 0xc1, 0x0d, 0x3e, 0x95, 0xcd, 0x33, 0x75, 0xc9, 0xd6, 0x9d, 0x2c, 0xad, 0x4c, 0x70, 0xfc, 0x00, 0x01, 0x09, 0x40, 0x7f, 0x53, 0xed, 0xb3, 0xc2, 0xfd, 0xff, 0x4c, 0x6a, 0x04, 0x34, 0xc8, 0x0f, 0xc1, 0xcf, 0x3b, 0xdf, 0xb1, 0x07, 0xa8, 0x0e, 0x59, 0xb2, 0xc9, 0x3c, 0x27, 0x51, 0x67, 0xb2, 0x07, 0x0b, 0x30, 0xd3, 0xa0, 0x73, 0x14, 0xda, 0x1b, 0xd1, 0xbc, 0xf8, 0x42, 0xca, 0xe5, 0xab, 0x6b, 0x49, 0x7a, 0xe7, 0xe5, 0x3a, 0xf1, 0x9d, 0x4a, 0x8b, 0x34, 0x18, 0x12, 0xcb, 0x1c, 0x10, 0x5e, 0x2c, 0x53, 0x16, 0xfc, 0x65, 0x00, 0x49, 0x27, 0x30, 0xb2, 0x5e, 0xc8, 0x35, 0x44, 0xab, 0x9e, 0x18, 0xc8, 0x0c, 0xda, 0x5b, 0xc2, 0xb8, 0xf3, 0x2b, 0xcc, 0xc8, 0x5c, 0x0c, 0x14, 0x79, 0x58, 0x4d, 0x69, 0xd2, 0xff, 0x06, 0x58, 0x20, 0xca, 0xe4, 0xac, 0x1a, 0x3f, 0x5a, 0x53, 0x82, 0x3b, 0x5b, 0xd3, 0x8f, 0x6c, 0x63, 0xc0, 0xf0, 0x84, 0x9e, 0x4b, 0x61, 0x67, 0xd6, 0xc3, 0xd3, 0x61, 0xb2, 0xec, 0xd5, 0xb0, 0xdf, 0x41, 0x13, 0xcb, 0x66, 0x4c, 0x13, 0x69, 0x69, 0x8d, 0x27, 0xa7, 0x06, 0x1b, 0xca, 0x00, 0xf6, 0x82, 0xfb, 0xeb, 0x1b, 0xc1, 0x36, 0x95, 0x9d, 0x44, 0x98, 0x33, 0x8f, 0x26, 0x7a, 0x41, 0x9c, 0x00, 0x2c, 0xeb, 0xcc, 0xc0, 0x05, 0x5a, 0xf5, 0x58, 0xec, 0x23, 0x4f, 0x44, 0x79, 0x97, 0x8d, 0x0c, 0xe0, 0xa5, 0xc9, 0x14, 0xcf, 0x2b, 0xe3, 0xa1, 0x3f, 0x12, 0x8d, 0xde, 0xbf, 0x46, 0x4e, 0xca, 0x9c, 0xe4, 0xa5, 0x1c, 0x61, 0x35, 0x57, 0xae, 0xa8, 0xfa, 0x3a, 0x55, 0x11, 0x05, 0x7b, 0x55, 0xb7, 0x90, 0x5c, 0x03, 0xb3, 0x00, 0x31, 0xfa, 0xa0, 0x16, 0xa7, 0x03, 0x99, 0xc1, 0x5d, 0xfe, 0x7e, 0xc7, 0x61, 0x7e, 0xb1, 0x4b, 0x4d, 0x05, 0x65, 0xdf, 0x14, 0x47, 0x81, 0xd1, 0xe7, 0xd9, 0x5e, 0x8a, 0xbd, 0xa5, 0xfb, 0x48, 0x2f, 0x7f, 0x33, 0x90, 0x26, 0x1e, 0x28, 0xbb, 0x45, 0xd0, 0x8d, 0x98, 0x83, 0x5f, 0x4c, 0xe4, 0xa6, 0x20, 0x2b, 0xc2, 0x7b, 0x11, 0xf9, 0x6a, 0x9c, 0x46, 0x21, 0x5b, 0x32, 0x8c, 0x51, 0x11, 0x06, 0x00, 0xb6, 0xf6, 0xc2, 0xcf, 0x26, 0x50, 0x2c, 0xd6, 0x39, 0xa8, 0xe4, 0xf6, 0xc9, 0x97, 0x3d, 0xe2, 0x54, 0x88, 0x4b, 0x0c, 0x93, 0xbe, 0xd5, 0x17, 0xa6, 0xfc, 0x65, 0x1f, 0xa6, 0x0f, 0xe9, 0xa5, 0xcb, 0xdf, 0x61, 0xc4, 0xea, 0x87, 0x83, 0xc8, 0x50, 0xe7, 0x51, 0x96, 0x96, 0x7e, 0x2b, 0x5b, 0x58, 0x3e, 0x87, 0x3b, 0x8f, 0x92, 0x23, 0x7f, 0xb3, 0x10, 0xe8, 0xd9, 0xdd, 0x74, 0x21, 0x37, 0x7d, 0x0f, 0x91, 0x7c, 0xef, 0xaa, 0x9c, 0x1f, 0x18, 0xee, 0xe8, 0x20, 0xfe, 0xb4, 0x7e, 0x7a, 0xe6, 0x1a, 0xa3, 0x04, 0x6a, 0xfa, 0x82, 0x4c, 0xe1, 0xdd, 0xf5, 0xb0, 0x45, 0x52, 0x32, 0x71, 0x87, 0x7a, 0xd2, 0xc6, 0x38, 0xcb, 0xff, 0xce, 0x22, 0x01, 0xb5, 0x28, 0x69, 0x8d, 0xef, 0x37, 0xd2, 0xb3, 0xc4, 0x53, 0x9f, 0x49, 0x10, 0xda, 0xa4, 0x10, 0x13, 0x8d, 0x76, 0x2f, 0x0d, 0xc0, 0x24, 0x96, 0x96, 0x6d, 0xe5, 0xe9, 0x97, 0xf2, 0xce, 0x10, 0x9e, 0x53, 0xab, 0x3a, 0x46, 0xdf, 0xed, 0xab, 0x6b, 0xf3, 0xd6, 0x92, 0xba, 0x92, 0xb0, 0xb3, 0xbb, 0x2b, 0xd9, 0xd5, 0xc3, 0xbd, 0xb1, 0xeb, 0x8b, 0x86, 0x3d, 0xf9, 0xfb, 0x08, 0x64, 0x62, 0x24, 0xa5, 0x0e, 0x46, 0x27, 0x32, 0x67, 0x8d, 0x19, 0x5e, 0xe7, 0x95, 0x1d, 0x42, 0x92, 0xde, 0xaf, 0x15, 0xd3, 0x98, 0x7f, 0x08, 0xd2, 0xd5, 0xcb, 0xd6, 0x20, 0xb4, 0x3d, 0x96, 0xff, 0x3a, 0x0c, 0x1a, 0x77, 0xe0, 0x2f, 0xe1, 0x09, 0x99, 0x82, 0x00, 0x11, 0x7c, 0xe3, 0xb7, 0xc4, 0x1f, 0x97, 0xa1, 0xd9, 0xff, 0x6b, 0x1c, 0x6a, 0xd9, 0xf4, 0x28, 0x30, 0xa7, 0x06, 0xef, 0x22, 0xab, 0x6e, 0x3a, 0xc0, 0x40, 0xc0, 0x1e, 0x47, 0xb8, 0x01, 0x25, 0xfd, 0x44, 0xf6, 0x3b, 0xf1, 0xe3, 0xd5, 0x5f, 0x35, 0x4b, 0x0f, 0xe8, 0x32, 0xca, 0x7b, 0xe7, 0x73, 0xb0, 0x2a, 0xe8, 0xe5, 0x5e, 0xd5, 0x19, 0xfd, 0x7c, 0x7a, 0x3c, 0x33, 0xdb, 0x50, 0xa4, 0xec, 0x09, 0x94, 0xaa, 0xbc, 0x6f, 0xf1, 0x43, 0xa3, 0x36, 0x6f, 0xcd, 0x0b, 0x34, 0xfc, 0x5a, 0x2c, 0xee, 0x2a, 0x69, 0x98, 0x06, 0x41, 0xa7, 0x9d, 0xe1, 0x97, 0x80, 0x6e, 0x2f, 0x4b, 0x17, 0xd9, 0x39, 0xf9, 0xbd, 0x8b, 0x64, 0x1c, 0x0b, 0x51, 0xde, 0x2d, 0x73, 0x39, 0x9d, 0xed, 0x5d, 0x9f, 0x3e, 0xb9, 0xa8, 0x0d, 0xf1, 0xf7, 0x21, 0xd4, 0xf8, 0x05, 0x1c, 0x95, 0x9e, 0x5e, 0xb1, 0xc3, 0xc4, 0x45, 0x2c, 0xcc, 0x55, 0x15, 0xba, 0x4b, 0xae, 0x84, 0x7f, 0x2f, 0x23, 0xf1, 0x47, 0x46, 0x9b, 0x3a, 0xed, 0x06, 0xe1, 0xff, 0x3e, 0x55, 0x44, 0xfe, 0xdc, 0xb3, 0x8f, 0xde, 0xa6, 0x3e, 0x33, 0xf8, 0x8c, 0x52, 0x0c, 0x77, 0xa8, 0x12, 0xeb, 0xfa, 0x0d, 0x05, 0x6c, 0x5c, 0x86, 0x4f, 0x46, 0x2f, 0x9c, 0xa7, 0x58, 0x4f, 0x50, 0xa1, 0x21, 0xde, 0xda, 0x54, 0xd2, 0x51, 0x84, 0x5e, 0xa3, 0x7c, 0x55, 0xd0, 0xc7, 0x73, 0x80, 0xfe, 0x99, 0x26, 0xb2, 0x6f, 0xd8, 0x4f, 0x75, 0x09, 0xe0, 0xb7, 0xde, 0xec, 0x04, 0xc9, 0x8c, 0xc9, 0xaf, 0xb0, 0x9a, 0x41, 0x52, 0xff, 0xf9, 0x29, 0x64, 0xe8, 0xa2, 0x7f, 0x7c, 0x65, 0x81, 0xf6, 0x0d, 0x16, 0x71, 0x2f, 0xca, 0xf7, 0xac, 0xe3, 0x3e, 0x91, 0xf9, 0xdb, 0xb4, 0x0f, 0x87, 0xa6, 0x74, 0x9b, 0x5e, 0xbf, 0x6a, 0x74, 0x78, 0x75, 0x76, 0x9f, 0x5f, 0xc7, 0x75, 0x36, 0x60, 0xe5, 0xe5, 0x86, 0x2c, 0xbf, 0xf1, 0xa2, 0x68, 0x14, 0xc9, 0x44, 0x80, 0x08, 0xe6, 0x55, 0x06, 0x5e, 0xd6, 0xbf, 0x70, 0x8b, 0x2a, 0x9a, 0xa6, 0xe2, 0x79, 0xe2, 0xa7, 0x54, 0x7d, 0x59, 0xe0, 0x82, 0xc9, 0xd8, 0x72, 0x88, 0x5e, 0xe1, 0x11, 0x59, 0xa4, 0x6d, 0xaf, 0x6e, 0x97, 0xa3, 0xe3, 0xa2, 0x60, 0xe1, 0x8e, 0x02, 0x72, 0xe6, 0xcc, 0x46, 0x12, 0x15, 0x28, 0x37, 0xfc, 0x5c, 0x2b, 0x65, 0x63, 0x6a, 0x90, 0x46, 0x20, 0x6a, 0xa1, 0xca, 0xb5, 0x6d, 0x9a, 0xba, 0xb5, 0x8c, 0x77, 0x03, 0xdf, 0x28, 0x08, 0x03, 0xb1, 0x21, 0x42, 0x79, 0xbb, 0x55, 0xf1, 0x14, 0x76, 0x00, 0x04, 0xb2, 0x1c, 0x4d, 0x31, 0x5c, 0x74, 0x7a, 0xdf, 0x4a, 0xd6, 0x82, 0x7d, 0x1d, 0xe3, 0x05, 0x04, 0x9c, 0xdc, 0xe3, 0x39, 0xeb, 0x3a, 0xe9, 0xa0, 0x9a, 0x95, 0x54, 0x8f, 0x3b, 0x28, 0x98, 0x7e, 0xd3, 0x44, 0xcf, 0xf5, 0x9e, 0x98, 0xdd, 0xa9, 0x53, 0xe4, 0x2a, 0xfb, 0xb7, 0x25, 0x0a, 0x39, 0x76, 0x4b, 0x5f, 0xaa, 0x86, 0xad, 0xf2, 0x65, 0xce, 0x31, 0x90, 0xd1, 0xc7, 0x2c, 0x3b, 0x3c, 0x13, 0x91, 0x49, 0xe6, 0xb8, 0x93, 0xd9, 0x98, 0x70, 0x2b, 0x6c, 0xe2, 0xd0, 0x6a, 0xd4, 0xd8, 0x13, 0x73, 0xae, 0x77, 0x9d, 0xda, 0xe1, 0xbc, 0x23, 0x52, 0x4b, 0x43, 0x62, 0xb5, 0x46, 0xb9, 0x75, 0x40, 0x75, 0xef, 0x1e, 0x1a, 0x2b, 0xa5, 0x13, 0x9e, 0x16, 0xdb, 0x7e, 0x08, 0x35, 0xe8, 0x83, 0xc4, 0x6b, 0xfe, 0x92, 0x74, 0x9f, 0xf0, 0xfc, 0xf4, 0x0b, 0xd6, 0x98, 0x24, 0xc1, 0x4a, 0xeb, 0x91, 0xc4, 0x21, 0x71, 0x4b, 0x36, 0x2c, 0xe8, 0xb2, 0xc5, 0xd9, 0xd0, 0x59, 0xbe, 0x1d, 0xcc, 0x23, 0x52, 0xc8, 0x27, 0x36, 0x95, 0x53, 0xf9, 0x2a, 0xb9, 0x17, 0x03, 0xa8, 0xbc, 0x22, 0x03, 0x62, 0x0d, 0x98, 0xec, 0xd2, 0x4e, 0x2f, 0x42, 0x52, 0x52, 0x47, 0xc6, 0x68, 0x8b, 0xa6, 0x5d, 0x58, 0x53, 0x1a, 0xf3, 0x82, 0x7c, 0xea, 0xdd, 0xda, 0x4f, 0x88, 0x66, 0x62, 0x58, 0x05, 0xf8, 0x82, 0x95, 0xa5, 0x6f, 0x15, 0x1b, 0xcf, 0xaa, 0x7c, 0x64, 0xd4, 0xd0, 0xf3, 0x5d, 0x8a, 0xce, 0xf9, 0x53, 0x87, 0x03, 0xf9, 0xc9, 0x8c, 0x16, 0x43, 0xd6, 0x92, 0x83, 0x7f, 0xb3, 0x03, 0x8f, 0x7e, 0xc7, 0xec, 0x90, 0x2f, 0xc6, 0xf3, 0x1d, 0xd8, 0x55, 0xf6, 0x65, 0x7e, 0xfe, 0xa1, 0x95, 0x90, 0x0d, 0xd9, 0xca, 0xd5, 0xb6, 0x3d, 0x32, 0x75, 0x47, 0xd6, 0xc4, 0x8a, 0x29, 0x34, 0x3d, 0xd8, 0xdc, 0x2e, 0xe7, 0x8b, 0xc6, 0x25, 0x0f, 0xa7, 0xd0, 0xf9, 0x86, 0x60, 0x2d, 0xa5, 0xdb, 0x90, 0xc6, 0x99, 0x63, 0xc8, 0xcd, 0xe4, 0xa0, 0x42, 0x52, 0x2a, 0xad, 0x88, 0x62, 0x9a, 0x41, 0xc8, 0x7f, 0xf3, 0x35, 0x10, 0xc5, 0xe5, 0x48, 0x6b, 0x91, 0x41, 0x58, 0x9b, 0x0e, 0x54, 0x34, 0xef, 0x09, 0x4b, 0x11, 0xf9, 0x83, 0xed, 0xd2, 0x0d, 0x7e, 0xc8, 0x03, 0xf1, 0x26, 0x04, 0xc1, 0x46, 0x18, 0xc7, 0x6e, 0xb4, 0xeb, 0x27, 0x33, 0x64, 0x23, 0x1b, 0xa1, 0xb5, 0x5d, 0xec, 0x56, 0xc0, 0x98, 0x0c, 0xde, 0x08, 0x1b, 0x2e, 0x7d, 0xad, 0xc0, 0x6c, 0x7a, 0x76, 0x48, 0xd9, 0x59, 0xca, 0x93, 0x44, 0x95, 0x74, 0x5c, 0x9d, 0x66, 0x7c, 0x3a, 0x26, 0xc0, 0x9e, 0xee, 0x49, 0xae, 0x6e, 0x28, 0x13, 0xb3, 0xb0, 0xd5, 0x1f, 0xad, 0x33, 0x00, 0xba, 0xc6, 0x1b, 0x92, 0x6b, 0xda, 0x70, 0xef, 0x61, 0x13, 0x71, 0x37, 0xe3, 0xe3, 0x1d, 0x7a, 0x10, 0xb4, 0x22, 0xed, 0xc4, 0xd0, 0x31, 0x1f, 0xc2, 0x45, 0x2c, 0xa5, 0x7d, 0x3e, 0x1f, 0xd8, 0xd0, 0xa8, 0x52, 0x5a, 0x0d, 0x6c, 0xb4, 0x0a, 0xfc, 0x3f, 0x5e, 0x4d, 0xe1, 0x5d, 0xc2, 0x2d, 0x10, 0x18, 0x9c, 0xd6, 0x3e, 0xc3, 0x48, 0x68, 0x3e, 0xd3, 0xcd, 0x87, 0x91, 0xdb, 0x9c, 0x3e, 0x86, 0x87, 0xf7, 0x28, 0xa9, 0xb5, 0xd1, 0x2c, 0x71, 0x12, 0x3e, 0x0a, 0x8d, 0x0b, 0xe9, 0x7c, 0x92, 0x1e, 0xd8, 0xbf, 0xd4, 0x9f, 0x0a, 0x1a, 0x0e, 0x5f, 0xac, 0xcd, 0x23, 0xc0, 0xa2, 0x6c, 0x43, 0xa2, 0x00, 0x1c, 0x7e, 0x6a, 0x7b, 0xf5, 0x46, 0x47, 0xd4, 0x4e, 0x3c, 0x37, 0x36, 0x79, 0x52, 0xfb, 0xa0, 0x7d, 0x13, 0x73, 0x7f, 0xe2, 0xff, 0xbf, 0x0b, 0x68, 0xdd, 0x81, 0xcf, 0x48, 0x40, 0x1e, 0x16, 0x06, 0x26, 0x87, 0xd1, 0xa6, 0x2c, 0xec, 0x10, 0x6d, 0x2c, 0xcc, 0x95, 0x79, 0x1f, 0xb7, 0x41, 0x30, 0x01, 0x34, 0x30, 0x00, 0x31, 0x90, 0xce, 0x59, 0x4d, 0x85, 0xda, 0x51, 0x1e, 0x08, 0x81, 0x06, 0x1c, 0x71, 0x41, 0x5d, 0xac, 0xf2, 0x75, 0x27, 0x81, 0xe7, 0xa6, 0x8b, 0x6d, 0x84, 0x44, 0x32, 0xb1, 0xfb, 0xf2, 0x45, 0xfd, 0x9e, 0xb5, 0xa7, 0x9e, 0xf9, 0x3f, 0xa0, 0x0b, 0x03, 0x21, 0x90, 0xa0, 0x4a, 0x83, 0x39, 0x81, 0xa7, 0x90, 0xe0, 0xfd, 0xd1, 0x1a, 0xea, 0xaf, 0xea, 0x72, 0x5a, 0xfc, 0xe4, 0xfe, 0xbb, 0xf2, 0x3a, 0xbb, 0x75, 0x3c, 0x9f, 0xed, 0xcb, 0xbe, 0x2c, 0x8e, 0xd8, 0x18, 0x0c, 0x58, 0x39, 0x98, 0x9c, 0x9e, 0x92, 0x1f, 0x3f, 0x80, 0xe0, 0xda, 0x61, 0x54, 0x07, 0xe0, 0x65, 0x66, 0x12, 0x29, 0x09, 0x4d, 0x47, 0x8f, 0x8d, 0x26, 0x6c, 0xbe, 0x30, 0x71, 0x51, 0x0a, 0x65, 0x94, 0x74, 0x87, 0x32, 0xf8, 0x4d, 0xc0, 0x57, 0x4d, 0x31, 0x42, 0xc2, 0xc0, 0xf2, 0x2c, 0x29, 0x15, 0xc1, 0xa0, 0x93, 0xf2, 0x36, 0xd2, 0x9b, 0x4c, 0xf3, 0xb5, 0x40, 0xff, 0xad, 0x9e, 0xd5, 0x28, 0x63, 0xfd, 0xfc, 0x1f, 0x40, 0xdb, 0x6d, 0x91, 0x90, 0x39, 0xc5, 0x98, 0x00, 0xb9, 0x29, 0x74, 0x68, 0xba, 0xbb, 0x8b, 0x5d, 0x27, 0x8c, 0x75, 0x2d, 0xa6, 0x27, 0xed, 0xd5, 0x62, 0x48, 0x65, 0x70, 0xb3, 0xef, 0xd8, 0x19, 0x23, 0x49, 0x33, 0x94, 0x9c, 0xb2, 0x08, 0xcf, 0x51, 0x72, 0x47, 0x44, 0x07, 0x9a, 0x14, 0x40, 0x8f, 0xbd, 0x36, 0x90, 0xc5, 0x9a, 0xcb, 0x8d, 0xcd, 0xae, 0xe4, 0xb5, 0x4b, 0x63, 0x81, 0xbb, 0x27, 0x55, 0xb5, 0x17, 0xf0, 0x66, 0xb6, 0x87, 0xc6, 0xc1, 0xc7, 0x1c, 0x73, 0xa0, 0xb4, 0xcb, 0xb8, 0xd4, 0xf9, 0xf4, 0xbb, 0x1b, 0x1b, 0x4e, 0x59, 0xf6, 0x99, 0x8d, 0xa2, 0xb7, 0x5b, 0x34, 0x58, 0x7d, 0x09, 0x99, 0xa0, 0x44, 0x7d, 0xa6, 0xf6, 0xc9, 0xe8, 0x8a, 0x74, 0xfe, 0xd1, 0xcd, 0xa4, 0xad, 0xa0, 0x3e, 0x8b, 0xde, 0x25, 0x92, 0xc9, 0x92, 0x34, 0xee, 0x01, 0x3d, 0xe9, 0xe2, 0x4d, 0x8a, 0xcb, 0xc6, 0x88, 0xe7, 0x09, 0xb7, 0x7d, 0x9f, 0xf6, 0x6e, 0xd9, 0x20, 0x62, 0x0b, 0x06, 0x7b, 0xa3, 0x94, 0xfb, 0x26, 0x8b, 0x3f, 0x13, 0x71, 0x77, 0xeb, 0x0e, 0x19, 0xd5, 0xb0, 0x71, 0x22, 0xec, 0xf5, 0x92, 0xda, 0x16, 0x14, 0x88, 0xa6, 0xc5, 0x88, 0xd7, 0x0f, 0x1f, 0x73, 0xbd, 0xec, 0x5c, 0xc4, 0x64, 0xf6, 0x82, 0x31, 0x00, 0x8b, 0x96, 0xee, 0x4a, 0x38, 0x88, 0x85, 0x2d, 0x3b, 0x0b, 0xaa, 0x0e, 0x75, 0xc6, 0xff, 0x94, 0xaf, 0x7c, 0xce, 0x4c, 0x5b, 0xdd, 0x00, 0x00, 0x01, 0x09 }; +constexpr AccessUnit AVC_BEGIN_OF_AU_SPLIT_EXPECTED_AU = { std::numeric_limits::max(), std::numeric_limits::max(), false, 0, {}, { 0x8d, 0x36, 0x09, 0x27, 0xb3, 0xab, 0x69, 0x2f, 0x0f, 0x43, 0xb5, 0x3e, 0x2d, 0x6d, 0x54, 0x1a, 0x9f, 0x91, 0x90, 0xbd } }; + +const std::vector M2V_BEGIN_OF_AU_SPLIT_STREAM = { 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xe0, 0x06, 0xe6, 0x81, 0xc1, 0x0d, 0x31, 0x00, 0x05, 0xbf, 0x21, 0x11, 0x00, 0x05, 0xb3, 0x65, 0x1e, 0x69, 0xb2, 0x5c, 0xe5, 0xaf, 0x00, 0xfd, 0x0f, 0x1d, 0x27, 0x61, 0x90, 0xd4, 0x77, 0x92, 0x34, 0x4a, 0x7a, 0xdc, 0x96, 0x0d, 0x89, 0x63, 0xef, 0x89, 0xa1, 0x9a, 0x65, 0xc3, 0x28, 0xba, 0x93, 0x62, 0x56, 0x1b, 0xfc, 0x5e, 0xac, 0xaf, 0x7d, 0x30, 0xaa, 0x20, 0x5f, 0x98, 0xf7, 0x81, 0x50, 0xa1, 0x73, 0xa2, 0xd1, 0x35, 0x49, 0x93, 0xed, 0xdf, 0xc4, 0x4b, 0xb7, 0xc3, 0x26, 0x8d, 0xaa, 0x93, 0xb6, 0x62, 0x9a, 0xd4, 0xc8, 0x2c, 0x35, 0x7b, 0x38, 0x78, 0x5c, 0x8c, 0xb8, 0x93, 0x40, 0x3c, 0x0a, 0x11, 0x77, 0x63, 0x33, 0x4b, 0xe0, 0xfd, 0x79, 0x75, 0x87, 0x30, 0x65, 0xbd, 0x20, 0x28, 0x8c, 0x98, 0x4a, 0x60, 0x44, 0xfa, 0xfc, 0x13, 0x31, 0xa5, 0x6f, 0x0b, 0xea, 0x2d, 0x4b, 0xf6, 0x21, 0xd8, 0xa2, 0x0f, 0x19, 0x82, 0x2f, 0x39, 0x45, 0x86, 0xea, 0x54, 0x21, 0xcf, 0xcb, 0xce, 0x75, 0x05, 0x75, 0x96, 0xe8, 0x40, 0x3f, 0x0b, 0x28, 0x96, 0xe2, 0x2a, 0x4a, 0x21, 0xb7, 0xb5, 0xaf, 0x16, 0xce, 0xfe, 0xdd, 0xf4, 0x67, 0x26, 0xcc, 0x95, 0xd3, 0xc3, 0x19, 0x73, 0xeb, 0xce, 0x67, 0x4e, 0x1e, 0x0c, 0xf6, 0x68, 0xbe, 0xde, 0x22, 0x61, 0xf8, 0x87, 0x3e, 0xdf, 0x9b, 0xbf, 0x57, 0x36, 0x19, 0x18, 0x02, 0x49, 0xb4, 0xcc, 0x17, 0xe8, 0x64, 0x03, 0x01, 0x8d, 0xbd, 0x18, 0x60, 0xcc, 0x3f, 0x8f, 0xe8, 0x89, 0xe3, 0x40, 0x4b, 0x3e, 0xf5, 0x0c, 0xa3, 0xd1, 0x32, 0x9f, 0x6c, 0x2e, 0xbd, 0xd4, 0xb7, 0x38, 0x09, 0x40, 0x43, 0x0d, 0xd5, 0x7a, 0x85, 0xf5, 0x30, 0xd7, 0x22, 0xe2, 0x17, 0x7c, 0x7e, 0x26, 0xa0, 0x4b, 0xc4, 0xcf, 0x95, 0xe9, 0x99, 0xbe, 0xc8, 0x1a, 0xda, 0x14, 0x61, 0x4e, 0x49, 0x89, 0x54, 0x8d, 0x0b, 0x0a, 0x27, 0x67, 0x45, 0xd0, 0xb6, 0x18, 0x70, 0x47, 0x11, 0x13, 0x77, 0x46, 0x4b, 0xc4, 0x87, 0x7e, 0x7e, 0x5c, 0x05, 0x4a, 0x2d, 0x2e, 0xf4, 0xbf, 0x0b, 0xf4, 0xd2, 0x7c, 0xa7, 0x9b, 0x29, 0x50, 0x60, 0xc5, 0x3b, 0xa2, 0x72, 0x45, 0x3d, 0xe7, 0x0e, 0x83, 0x68, 0x17, 0x92, 0xc8, 0x80, 0xf4, 0x04, 0x74, 0x5c, 0x61, 0xfc, 0x17, 0x77, 0x32, 0x72, 0xd7, 0xde, 0xcb, 0x3e, 0x00, 0x2c, 0x0b, 0x6b, 0x7c, 0xf1, 0xf6, 0x57, 0x4a, 0xe7, 0x84, 0x38, 0x3c, 0x0e, 0xcd, 0x47, 0xc1, 0x29, 0xa4, 0xab, 0x0f, 0x1a, 0x77, 0x15, 0x5b, 0x90, 0xe4, 0x14, 0xee, 0x03, 0xf2, 0xda, 0x1f, 0x08, 0xd4, 0x2b, 0x1b, 0xa5, 0x35, 0x76, 0x2b, 0x13, 0x8a, 0xe8, 0x70, 0x43, 0x96, 0x86, 0x1d, 0xeb, 0x85, 0x7c, 0x52, 0x8f, 0x22, 0x6b, 0xaf, 0x2d, 0xab, 0xd9, 0x0f, 0xdb, 0x2d, 0xed, 0xd1, 0xd0, 0x2c, 0xa9, 0x7c, 0xcd, 0x66, 0x1d, 0x45, 0x6d, 0x0e, 0x60, 0xd7, 0xa7, 0xca, 0xcd, 0xf5, 0x46, 0x07, 0xcb, 0x60, 0xbb, 0x45, 0x75, 0xe3, 0x61, 0xa2, 0x11, 0x97, 0x05, 0x80, 0xc6, 0x95, 0x76, 0xff, 0x4c, 0x62, 0x86, 0x58, 0xa4, 0x20, 0x14, 0x24, 0x57, 0xa3, 0x10, 0x21, 0x16, 0x42, 0xd6, 0x96, 0x00, 0x0a, 0x15, 0x2e, 0x69, 0x6a, 0x7e, 0x1a, 0x3b, 0x4e, 0x23, 0xc3, 0xb5, 0x41, 0x1b, 0x0b, 0xa3, 0x11, 0xfb, 0xd2, 0x22, 0x79, 0x38, 0xb8, 0xa9, 0x90, 0x31, 0x9e, 0x2d, 0x94, 0xdd, 0x45, 0x1b, 0x3e, 0x2c, 0xbc, 0x43, 0x42, 0x39, 0x00, 0x17, 0xce, 0x9d, 0xb5, 0x25, 0x02, 0x03, 0x9f, 0xb8, 0xdc, 0x18, 0x5d, 0xdc, 0x68, 0xa2, 0xd1, 0xf8, 0xca, 0xdd, 0xce, 0xf8, 0xe1, 0xa5, 0xe9, 0xec, 0xf1, 0x1a, 0xcd, 0xa0, 0x6d, 0xd7, 0xcc, 0xc9, 0xd5, 0x60, 0x59, 0xe6, 0xc7, 0x5b, 0x56, 0x31, 0x83, 0x58, 0x30, 0x7d, 0x54, 0x66, 0x7b, 0x34, 0xc9, 0x4c, 0xda, 0xab, 0xcf, 0x5c, 0xae, 0x82, 0x75, 0x28, 0xa1, 0xed, 0x4a, 0x55, 0xca, 0x8d, 0x2c, 0xd3, 0x52, 0x58, 0xb6, 0xf8, 0x2d, 0x1d, 0x00, 0x82, 0x0f, 0xff, 0x7f, 0x6d, 0x80, 0xe0, 0xa1, 0x77, 0x23, 0x77, 0x3e, 0x67, 0xff, 0x82, 0x18, 0xff, 0x17, 0x00, 0xeb, 0xa9, 0x92, 0x3c, 0x2e, 0x16, 0x27, 0x36, 0xde, 0xef, 0x72, 0x42, 0xb8, 0x9a, 0xbb, 0xa7, 0x46, 0x9b, 0xa6, 0x75, 0xce, 0x8b, 0x71, 0x1c, 0x76, 0x4e, 0x84, 0xaa, 0x15, 0x24, 0xe4, 0xf5, 0x93, 0x4f, 0x19, 0xf3, 0x7b, 0x57, 0xd7, 0x3f, 0x70, 0xfe, 0xb4, 0x75, 0x52, 0x4e, 0x52, 0x88, 0x75, 0xfe, 0x4a, 0x16, 0x22, 0x00, 0xe8, 0xa7, 0x41, 0x7a, 0x8a, 0xb4, 0x15, 0x30, 0xda, 0x3f, 0x5c, 0x54, 0xc3, 0x00, 0xef, 0x4e, 0x65, 0x14, 0xa2, 0xca, 0x8d, 0x4c, 0x3a, 0x4c, 0xba, 0x07, 0xaf, 0xdc, 0x7b, 0x2c, 0x5b, 0x95, 0x79, 0x6e, 0x0b, 0xc4, 0xf3, 0x09, 0x80, 0x5e, 0xc1, 0x18, 0x23, 0x49, 0xe6, 0x81, 0xcd, 0x8b, 0x5d, 0xfc, 0xa2, 0xed, 0xd2, 0x46, 0x30, 0x6d, 0x21, 0x77, 0xde, 0xa3, 0x1f, 0xeb, 0x29, 0x51, 0xd0, 0xae, 0x06, 0x92, 0x1c, 0xd3, 0x80, 0x4f, 0x85, 0x3e, 0xbc, 0xf1, 0xb9, 0x59, 0x1a, 0x25, 0xe2, 0xdb, 0x0a, 0x51, 0xad, 0x2f, 0x62, 0xbd, 0xf6, 0x1a, 0x59, 0xd7, 0x84, 0x48, 0xc7, 0xd3, 0x82, 0xd8, 0xb8, 0x63, 0x02, 0xf4, 0x77, 0x0b, 0x7e, 0xe9, 0x54, 0xc7, 0x5f, 0x04, 0xcd, 0x38, 0xf9, 0xb3, 0xc1, 0x29, 0x7e, 0x69, 0x01, 0x7b, 0xa7, 0x03, 0x4d, 0xd0, 0x2a, 0x3e, 0x5f, 0x06, 0xf2, 0xcb, 0x15, 0x5a, 0x91, 0xe8, 0x02, 0xbc, 0x9c, 0xfb, 0x54, 0x26, 0xb3, 0xec, 0xe1, 0xb7, 0x8b, 0x14, 0x71, 0xc2, 0xc7, 0x8b, 0x61, 0x91, 0x25, 0xcd, 0x51, 0x79, 0x90, 0xcf, 0x26, 0x34, 0x1b, 0x1b, 0xc9, 0x8d, 0xc7, 0x60, 0x15, 0x41, 0x06, 0x48, 0x08, 0xbd, 0x30, 0x28, 0xfc, 0x5e, 0x06, 0x5a, 0x58, 0x89, 0xd1, 0x0c, 0xb6, 0x4c, 0x23, 0x6a, 0xe5, 0x10, 0x97, 0xba, 0x97, 0x01, 0xee, 0x9d, 0x3e, 0x2e, 0x2a, 0x88, 0xa6, 0x86, 0xdc, 0xb1, 0xd8, 0x6a, 0xc0, 0x1c, 0xa8, 0x64, 0xb6, 0x7f, 0x65, 0x7c, 0x5d, 0x91, 0xdf, 0x64, 0x93, 0x93, 0xcf, 0xa7, 0xc6, 0xf9, 0xd3, 0x76, 0xc1, 0x89, 0x90, 0x48, 0xd2, 0x24, 0xa2, 0x68, 0x2f, 0xa8, 0x32, 0xd6, 0x28, 0x27, 0x74, 0x44, 0xdf, 0x56, 0x0d, 0x6a, 0x85, 0xf7, 0xe7, 0x5c, 0x33, 0xcc, 0x2c, 0xa1, 0x55, 0x93, 0xe8, 0x9e, 0x18, 0x08, 0xd3, 0x11, 0x69, 0xb8, 0xb6, 0x03, 0x50, 0x80, 0x2b, 0xce, 0x66, 0x67, 0x13, 0xd8, 0x88, 0x67, 0xcd, 0xb8, 0x51, 0x48, 0xd3, 0xd7, 0x8e, 0x0f, 0x11, 0x5f, 0x89, 0xdd, 0x84, 0xe2, 0xb0, 0x5b, 0x1e, 0xb9, 0x0f, 0x41, 0x6e, 0xfb, 0x3c, 0x13, 0x56, 0xcd, 0x4b, 0x06, 0x05, 0x4d, 0x82, 0xed, 0xa3, 0xa5, 0x37, 0xfb, 0x4f, 0x14, 0x3b, 0x20, 0xdf, 0x13, 0xf1, 0x34, 0x14, 0x31, 0xea, 0xd3, 0x17, 0x4c, 0xa3, 0x7f, 0xf6, 0x9b, 0x13, 0x08, 0x3c, 0x31, 0x85, 0xb2, 0xae, 0xf3, 0x3f, 0x46, 0x70, 0x75, 0x26, 0x77, 0x58, 0xb8, 0x4c, 0x33, 0xad, 0x4c, 0xb1, 0x1b, 0xc7, 0x93, 0xde, 0xd1, 0xaf, 0xfe, 0xc6, 0x96, 0x82, 0x58, 0x0a, 0xfb, 0x70, 0xfd, 0xa4, 0x8f, 0x7d, 0x4b, 0x9b, 0xbf, 0x1f, 0xc4, 0x50, 0x7d, 0x4a, 0x11, 0x10, 0x69, 0x68, 0x23, 0xa4, 0xfe, 0xbe, 0x39, 0x3b, 0xc2, 0x4c, 0x66, 0x4d, 0xed, 0x71, 0x66, 0x96, 0x9c, 0xc0, 0x0b, 0xc5, 0x02, 0x75, 0x79, 0xf6, 0x24, 0xc7, 0x2e, 0x5c, 0x7f, 0x17, 0x16, 0x78, 0x8d, 0x9f, 0xcc, 0xe2, 0x58, 0x62, 0x74, 0x0d, 0xbf, 0xea, 0x9b, 0xc8, 0x65, 0x8a, 0x44, 0x24, 0xcf, 0x8e, 0x79, 0x20, 0x4a, 0x4e, 0x74, 0xc2, 0xef, 0x31, 0x31, 0xe7, 0x73, 0xeb, 0xbe, 0x28, 0x5b, 0x58, 0xb5, 0x4b, 0xd7, 0x36, 0xf5, 0xda, 0x4b, 0x75, 0xb4, 0xbd, 0x81, 0xd0, 0x52, 0x7d, 0xd7, 0xfa, 0x6c, 0x59, 0xbd, 0x02, 0x8d, 0x28, 0x41, 0x21, 0xe9, 0xdb, 0x45, 0x7d, 0xf3, 0x23, 0xc8, 0x9f, 0xf2, 0xed, 0x2e, 0xfa, 0x6f, 0x22, 0x0e, 0x58, 0x6c, 0x96, 0x94, 0xde, 0xa3, 0xce, 0x14, 0x6c, 0xb9, 0x21, 0x43, 0xd1, 0x6d, 0x26, 0x11, 0x80, 0xb2, 0xdf, 0xc9, 0x64, 0xb7, 0xd5, 0xf7, 0x4b, 0xb8, 0x04, 0x29, 0x23, 0x4c, 0xb3, 0x4b, 0x0a, 0x03, 0xc9, 0x22, 0xfc, 0x05, 0xa6, 0x2d, 0x99, 0xf3, 0xc1, 0x19, 0xb4, 0xf6, 0x1c, 0xeb, 0x9b, 0xa0, 0xb6, 0x98, 0x28, 0x04, 0x54, 0x12, 0x8d, 0x4d, 0xc7, 0xa7, 0x2a, 0x55, 0x28, 0xe6, 0x6b, 0xd7, 0xaa, 0x00, 0x31, 0x5e, 0x9b, 0xa1, 0xfc, 0xcd, 0x86, 0xe7, 0xd1, 0x4e, 0xea, 0x93, 0x5a, 0x02, 0x2c, 0xa7, 0x3a, 0x48, 0xde, 0xb0, 0xe3, 0x35, 0x2c, 0x53, 0x9e, 0x65, 0xe2, 0xaf, 0x2f, 0xb7, 0xe4, 0x62, 0xb8, 0x26, 0xb9, 0x2f, 0x2f, 0x4c, 0xd7, 0xda, 0xaf, 0x3d, 0xbe, 0x1c, 0x0a, 0xcb, 0x64, 0xb3, 0xcb, 0xc9, 0xd1, 0xf1, 0xdf, 0x8f, 0xa1, 0xd7, 0xba, 0x1d, 0xf8, 0xdd, 0x68, 0xf6, 0x54, 0x9c, 0x59, 0x90, 0x93, 0x7a, 0x10, 0x88, 0x97, 0x0a, 0xc8, 0x34, 0xfc, 0xd0, 0x30, 0xea, 0xd2, 0x2d, 0x39, 0x3a, 0xe0, 0x5c, 0x05, 0xc1, 0x35, 0x1e, 0xfb, 0x77, 0x38, 0xb7, 0xb3, 0xf8, 0x84, 0x75, 0xfd, 0x11, 0xec, 0x6a, 0xef, 0xc6, 0xd6, 0x8b, 0x5f, 0xb3, 0xf7, 0x05, 0x05, 0x36, 0x94, 0x02, 0x7a, 0xf2, 0xc1, 0x40, 0x46, 0xf9, 0x38, 0xb6, 0x37, 0xc5, 0xec, 0x00, 0xe3, 0xd0, 0x6f, 0xfb, 0xa5, 0x0a, 0x05, 0xc7, 0x97, 0x20, 0xe5, 0xd7, 0x8f, 0x33, 0x05, 0x18, 0xc3, 0x14, 0xed, 0x72, 0x00, 0x1d, 0x7a, 0x5e, 0xa1, 0xb4, 0x32, 0x2d, 0xe4, 0xf1, 0xd7, 0x43, 0xb2, 0x27, 0xf8, 0x43, 0x41, 0x9d, 0x02, 0xf8, 0xc4, 0xb8, 0x7d, 0x84, 0x1f, 0xc3, 0xb6, 0xcf, 0x73, 0xdf, 0x6b, 0xad, 0xda, 0x7b, 0xe6, 0xa0, 0x55, 0xa4, 0x5a, 0x48, 0x8a, 0xd0, 0xe3, 0xe1, 0x62, 0x86, 0xe3, 0x7d, 0xab, 0x23, 0x2b, 0x1e, 0x57, 0x64, 0x25, 0xf7, 0x67, 0x71, 0x07, 0x90, 0x7f, 0xf5, 0x59, 0xc1, 0x89, 0x3e, 0x9f, 0xfe, 0x16, 0xbc, 0x5e, 0xc9, 0xcd, 0x6d, 0x60, 0x97, 0x00, 0x33, 0x4c, 0x10, 0x9f, 0x24, 0xcc, 0x7f, 0x9f, 0x43, 0x4c, 0x80, 0x7e, 0x94, 0x0d, 0x5d, 0xb4, 0x00, 0x6b, 0xbf, 0x3a, 0xb4, 0xee, 0x9a, 0x75, 0xa4, 0x2a, 0x20, 0xa0, 0x1a, 0x04, 0x5d, 0xf5, 0x06, 0x19, 0x9a, 0x1a, 0xd8, 0xb4, 0xca, 0xd7, 0xbb, 0xe5, 0x8b, 0x0d, 0x34, 0x30, 0x9e, 0xf4, 0x45, 0xa5, 0xd5, 0x2d, 0x0d, 0x68, 0x3a, 0xb9, 0xef, 0x86, 0x47, 0x38, 0xda, 0xc7, 0x05, 0xd4, 0x60, 0xc8, 0x99, 0x2f, 0xb7, 0x34, 0x44, 0x1c, 0x5b, 0xa2, 0x97, 0x2a, 0xb2, 0xa5, 0xe1, 0x24, 0x44, 0x01, 0x79, 0x60, 0x0f, 0x12, 0xe3, 0x9b, 0x01, 0xe1, 0x23, 0x94, 0x0d, 0x46, 0x59, 0x78, 0x53, 0xe1, 0x39, 0x7e, 0x3e, 0xe3, 0x80, 0xe3, 0xe9, 0xf1, 0xa9, 0x29, 0xf0, 0xc4, 0x96, 0xd5, 0x8d, 0xe6, 0x40, 0xc5, 0x40, 0x22, 0x8f, 0x96, 0xa0, 0xc5, 0x90, 0xa9, 0x8b, 0xba, 0xb4, 0xcc, 0x77, 0x07, 0x95, 0xb7, 0x37, 0xe3, 0x84, 0xc5, 0xb0, 0xc8, 0x8d, 0x53, 0xa9, 0x57, 0xa5, 0x73, 0xbb, 0xea, 0x5a, 0xcc, 0x79, 0x22, 0x6e, 0x65, 0x63, 0x5c, 0xd5, 0xb4, 0x35, 0xf9, 0xed, 0x95, 0xfa, 0xad, 0x73, 0x7c, 0x20, 0x53, 0x45, 0xac, 0x76, 0x36, 0x50, 0x65, 0xe0, 0x63, 0x14, 0x1e, 0xa2, 0x82, 0x73, 0x43, 0x22, 0xe4, 0xce, 0xbb, 0x6f, 0xb5, 0xa3, 0x99, 0xd8, 0x0a, 0x8d, 0xc2, 0x0d, 0xb7, 0xa6, 0x56, 0xbf, 0x13, 0x84, 0x63, 0x18, 0x8f, 0xaf, 0x15, 0xc9, 0x21, 0xe3, 0xf6, 0x08, 0x48, 0x90, 0xe2, 0x95, 0xf9, 0x69, 0x7f, 0xce, 0xa7, 0x83, 0xdb, 0x5c, 0x35, 0x24, 0x3e, 0x8c, 0x98, 0x3d, 0xd7, 0xe6, 0xc2, 0xe8, 0x23, 0xde, 0xf5, 0x35, 0xa5, 0x98, 0x2a, 0x96, 0x9c, 0xe3, 0xf7, 0x97, 0x17, 0x16, 0x24, 0x46, 0xd2, 0x30, 0x5f, 0x38, 0xd4, 0x63, 0x7c, 0x9e, 0xa1, 0x92, 0xa8, 0xbb, 0x20, 0x79, 0x25, 0xe6, 0x79, 0x6a, 0x73, 0x2a, 0xb9, 0xe8, 0x8b, 0x4d, 0xd4, 0x97, 0x37, 0x5f, 0x05, 0x86, 0xb5, 0x91, 0x0e, 0xc9, 0xd5, 0x75, 0xa0, 0xb4, 0xb4, 0xe7, 0x6f, 0x9a, 0xf5, 0xb9, 0x24, 0x22, 0x21, 0x15, 0x0c, 0x18, 0x4a, 0x65, 0x18, 0x80, 0xa6, 0x11, 0x67, 0x8f, 0x97, 0x6a, 0x68, 0x5a, 0x4d, 0xca, 0xae, 0x2a, 0x05, 0x40, 0xe7, 0x01, 0xef, 0xa5, 0xdb, 0xa3, 0x96, 0x19, 0x59, 0xa7, 0x7c, 0x0f, 0xae, 0xc3, 0xd1, 0xf5, 0x8e, 0x4a, 0xa3, 0xc7, 0x8c, 0x54, 0x85, 0x01, 0x14, 0x3b, 0x44, 0x16, 0xe0, 0xa0, 0xdb, 0x0b, 0x66, 0xe8, 0x9d, 0x2c, 0xea, 0xc3, 0xf5, 0x43, 0xaf, 0xfd, 0xec, 0x3d, 0x1a, 0x83, 0x96, 0x4a, 0xfb, 0x5a, 0x7c, 0x00, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xe0, 0x06, 0xe6, 0x81, 0xc1, 0x0d, 0xc3, 0xa9, 0xb9, 0x73, 0x50, 0xe3, 0x6a, 0x08, 0xb4, 0x2e, 0x64, 0x6d, 0x05, 0x00, 0x01, 0xb3, 0xd5, 0x92, 0x5f, 0xdd, 0xe1, 0xe6, 0xd0, 0x9d, 0xc5, 0x1c, 0xa6, 0xe6, 0x19, 0xb0, 0x16, 0x15, 0xa1, 0xc3, 0xa6, 0xdb, 0xdb, 0x47, 0x92, 0xa0, 0x40, 0x59, 0x85, 0x23, 0xde, 0x43, 0x26, 0x81, 0x72, 0xab, 0xd9, 0x0b, 0x02, 0xc4, 0x4e, 0x6d, 0xc8, 0x02, 0x67, 0x4a, 0x2f, 0x79, 0x49, 0x22, 0x44, 0xbf, 0x58, 0xec, 0xef, 0x55, 0x29, 0xc6, 0x17, 0xba, 0xf0, 0xcf, 0x1b, 0x94, 0x1d, 0x83, 0x10, 0x85, 0x07, 0x90, 0xda, 0xb9, 0x45, 0xa5, 0x1f, 0xc0, 0x79, 0x00, 0x6d, 0x0b, 0x14, 0xbc, 0xed, 0xde, 0x1f, 0xd4, 0x4a, 0x0c, 0x6e, 0x82, 0x26, 0xeb, 0x37, 0xb8, 0x0b, 0xd0, 0xa5, 0xb3, 0x5f, 0xc1, 0x8e, 0xb8, 0x3d, 0x6d, 0x39, 0x17, 0x64, 0x86, 0x7b, 0x56, 0x01, 0x8d, 0x54, 0x17, 0x5a, 0x16, 0xec, 0x64, 0x3b, 0x4a, 0xce, 0x4a, 0x1d, 0xd7, 0x57, 0xbe, 0x0e, 0x8b, 0x2e, 0xad, 0xd4, 0xbd, 0xab, 0x6b, 0x58, 0xa3, 0xee, 0xd3, 0x2e, 0x38, 0x3c, 0x34, 0x68, 0xe5, 0x37, 0x3b, 0x1d, 0xff, 0xb6, 0x08, 0x3a, 0xed, 0x46, 0x70, 0xc4, 0x85, 0xcd, 0x1e, 0xce, 0xcd, 0x90, 0xa5, 0x7e, 0x42, 0x21, 0xe4, 0x1b, 0x0a, 0xe9, 0xda, 0x9f, 0x42, 0x12, 0xec, 0x89, 0xb8, 0xd3, 0x3e, 0x3e, 0x5e, 0xa0, 0x5e, 0xae, 0x9e, 0x13, 0xa4, 0x7f, 0x89, 0x52, 0x92, 0x36, 0x87, 0x2e, 0x34, 0xaf, 0x3b, 0x0d, 0xaa, 0xe2, 0xfe, 0x85, 0xe5, 0x96, 0x49, 0x2f, 0xf3, 0x28, 0x8a, 0x00, 0xe4, 0x67, 0x9e, 0xf8, 0xc9, 0x70, 0xbd, 0x7c, 0x05, 0x6a, 0x57, 0x81, 0x6f, 0xbc, 0x59, 0x59, 0xc0, 0xce, 0x04, 0xe5, 0x67, 0xc4, 0xac, 0xba, 0xda, 0xd3, 0xe1, 0xbc, 0xf0, 0x79, 0xbb, 0x53, 0x4b, 0xc7, 0x85, 0x63, 0xbf, 0xf0, 0x4f, 0x2f, 0xfa, 0x8d, 0xcf, 0xd7, 0x75, 0x7b, 0x1d, 0x05, 0xea, 0x00, 0x00, 0x01, 0x00, 0x19, 0x48, 0xbb, 0x1d, 0x3e, 0xd9, 0x98, 0x87, 0x8e, 0x14, 0x43, 0x97, 0xd5, 0xae, 0x1f, 0xcc, 0x45, 0x84, 0x6b, 0x27, 0xad, 0x5d, 0x2f, 0x93, 0x5f, 0xac, 0xca, 0x18, 0x34, 0x36, 0x1e, 0x99, 0xf7, 0x9c, 0xf2, 0x93, 0x6a, 0x9c, 0x39, 0xe8, 0x70, 0x87, 0xce, 0x64, 0xf2, 0xa4, 0x70, 0x40, 0x50, 0x49, 0xc2, 0xa7, 0xa9, 0xe9, 0x78, 0xe7, 0xec, 0x6b, 0x33, 0xca, 0x7a, 0xfa, 0x49, 0x4c, 0x39, 0xe4, 0x8d, 0xe5, 0x3d, 0x3f, 0x63, 0xd4, 0xf6, 0xc2, 0x45, 0xc8, 0x93, 0xb6, 0xf9, 0xaa, 0x4d, 0xd2, 0xbc, 0x7e, 0x56, 0x99, 0x6f, 0x43, 0x98, 0x4f, 0xfa, 0xdc, 0x4f, 0x15, 0x30, 0xcf, 0x70, 0x9d, 0x47, 0x0b, 0xb7, 0x42, 0xf8, 0xa6, 0xd3, 0x00, 0x75, 0xff, 0x3a, 0xe4, 0x2f, 0x13, 0xa1, 0xc9, 0xc6, 0x11, 0xa1, 0x51, 0xbb, 0xd4, 0x3d, 0x69, 0x7e, 0xfc, 0xec, 0xa5, 0x77, 0xa4, 0x04, 0x5b, 0xd0, 0x6c, 0x78, 0xe7, 0xbe, 0x10, 0x4c, 0xfc, 0xa2, 0x1f, 0x03, 0x5c, 0x28, 0x57, 0x2f, 0x95, 0xff, 0xdd, 0x65, 0x0b, 0x38, 0xcd, 0x2e, 0x72, 0xcc, 0xcd, 0x2d, 0x80, 0x80, 0x5a, 0xa3, 0x09, 0xaa, 0xd8, 0x9e, 0xe3, 0x96, 0xc2, 0x86, 0xed, 0xe7, 0x55, 0xd6, 0x9e, 0xce, 0xfc, 0x3c, 0x28, 0x40, 0xc8, 0x21, 0xbf, 0x9b, 0x51, 0x64, 0xce, 0x21, 0xe8, 0xc4, 0xab, 0x72, 0xc2, 0x07, 0x5d, 0xa5, 0x26, 0x0e, 0xdc, 0xfb, 0xa4, 0xec, 0x63, 0x00, 0x08, 0x50, 0x4e, 0x27, 0xd6, 0xf7, 0x7f, 0x92, 0xe9, 0xe0, 0x11, 0x50, 0xea, 0xbe, 0xf8, 0x53, 0x5d, 0x02, 0xec, 0x8f, 0x0a, 0xb0, 0xbd, 0x33, 0x22, 0x37, 0x0f, 0x80, 0xff, 0x45, 0xcf, 0x71, 0xdc, 0x00, 0xad, 0x25, 0x1b, 0xee, 0x88, 0x71, 0x69, 0xa5, 0x06, 0x07, 0x21, 0x55, 0x10, 0x43, 0xe0, 0xdb, 0x1a, 0x99, 0xdd, 0xa6, 0xdf, 0xd4, 0x63, 0x2c, 0x1b, 0x0c, 0x17, 0x61, 0xd5, 0x97, 0x2c, 0x71, 0xcf, 0xd7, 0x15, 0x5a, 0x49, 0x83, 0x2a, 0x32, 0x29, 0x19, 0x75, 0x65, 0xc3, 0x6f, 0x17, 0xbb, 0xd2, 0x94, 0x76, 0x2f, 0x7a, 0x96, 0xb5, 0x1f, 0xa1, 0xce, 0xa1, 0x63, 0x0b, 0x29, 0x1c, 0x84, 0x73, 0x37, 0x5f, 0x00, 0x22, 0x41, 0x24, 0x78, 0xb0, 0x34, 0x6e, 0xcf, 0xe7, 0x26, 0x49, 0x61, 0x5b, 0x04, 0x81, 0xe6, 0x15, 0x18, 0x81, 0xc9, 0xd7, 0x2f, 0x28, 0x64, 0xea, 0x30, 0x08, 0x8e, 0x7b, 0x7c, 0x09, 0x79, 0x43, 0x27, 0xa8, 0x9d, 0x38, 0x01, 0xbe, 0xbd, 0xe5, 0xeb, 0xea, 0x83, 0xbd, 0x37, 0x77, 0x71, 0xf2, 0x1d, 0x24, 0x1b, 0x64, 0x57, 0xd7, 0x30, 0x20, 0xa6, 0xa9, 0x3d, 0xe7, 0xd1, 0x34, 0x53, 0x72, 0x3a, 0xb8, 0xe1, 0x39, 0x3e, 0xef, 0x46, 0x94, 0x97, 0xb4, 0x2c, 0xf6, 0x5f, 0xd6, 0x8d, 0xb5, 0x77, 0xf4, 0x38, 0x25, 0x90, 0xc7, 0x21, 0x9d, 0xa7, 0x4a, 0xd2, 0x09, 0xf1, 0xb9, 0x64, 0xed, 0x88, 0xb5, 0xfa, 0xce, 0x60, 0x44, 0x46, 0xf5, 0xb1, 0x02, 0x8e, 0x0f, 0x44, 0xe9, 0x2d, 0x93, 0x4c, 0xd7, 0xa5, 0x03, 0xb1, 0xff, 0x3d, 0xad, 0xf3, 0x7f, 0x00, 0xbb, 0x70, 0x34, 0x74, 0xd7, 0x89, 0x19, 0xb7, 0x17, 0x6a, 0xf1, 0xdb, 0x6c, 0x7a, 0xb1, 0x9f, 0x34, 0xff, 0x51, 0x68, 0x41, 0x9c, 0xea, 0x2b, 0x69, 0x7e, 0x73, 0xf0, 0xb6, 0xa9, 0x3e, 0x65, 0x00, 0xd9, 0xf1, 0xb4, 0x95, 0xdc, 0xdf, 0x89, 0xbc, 0x97, 0xf2, 0x56, 0xf0, 0xa6, 0x01, 0xfa, 0x67, 0x16, 0x0f, 0x38, 0xb1, 0x28, 0x23, 0x0b, 0xef, 0xaa, 0x5f, 0x43, 0xd3, 0x3b, 0xad, 0xe7, 0xf7, 0xe3, 0xa6, 0xdb, 0x84, 0x78, 0x12, 0xda, 0x7d, 0xcb, 0x59, 0xda, 0x76, 0x7f, 0x23, 0x88, 0xe4, 0x9b, 0x7b, 0x4d, 0xb4, 0x29, 0xce, 0xd7, 0x81, 0xa7, 0x0a, 0x12, 0xbb, 0x4f, 0x31, 0x2a, 0x45, 0x6f, 0xbb, 0x68, 0x0a, 0x8b, 0xe2, 0xba, 0xe4, 0x49, 0xa0, 0x13, 0x45, 0x7b, 0xd4, 0x65, 0x01, 0xc8, 0x68, 0x8c, 0xe4, 0x00, 0x4f, 0x15, 0xdf, 0x0a, 0x08, 0x0f, 0x2c, 0x2d, 0x8a, 0x2b, 0xfc, 0xa2, 0x37, 0x96, 0xfb, 0xaf, 0x92, 0x7d, 0xcf, 0x2a, 0x71, 0xec, 0x47, 0x9d, 0x44, 0x49, 0x23, 0x84, 0x3e, 0x4d, 0x97, 0x36, 0x1a, 0xf8, 0xc6, 0x0c, 0x6e, 0x52, 0x29, 0xeb, 0xc1, 0xbd, 0x74, 0xf1, 0x9e, 0x02, 0xf6, 0x21, 0xd0, 0x87, 0x67, 0x29, 0x2a, 0xcd, 0xfc, 0xfb, 0xd5, 0x6e, 0xe1, 0xe3, 0xec, 0xdd, 0x0b, 0x64, 0x16, 0xe8, 0xf6, 0x4b, 0x0f, 0x1e, 0x49, 0x92, 0xd4, 0x5d, 0x0c, 0xcb, 0x1b, 0x41, 0x85, 0x30, 0x42, 0x91, 0xe8, 0x4a, 0x31, 0xbc, 0x0d, 0x4f, 0x3e, 0xd4, 0x9f, 0x9b, 0x51, 0xaa, 0x84, 0x9a, 0x25, 0x85, 0x5e, 0x87, 0x4b, 0x95, 0x12, 0x52, 0x69, 0x54, 0x31, 0x45, 0xde, 0xe2, 0x58, 0xf6, 0xde, 0x8f, 0xce, 0xa1, 0x66, 0x0e, 0x35, 0xd6, 0xc5, 0x7c, 0x70, 0x83, 0x71, 0xe7, 0x96, 0x06, 0x06, 0x75, 0xcd, 0x0b, 0xeb, 0x9b, 0x98, 0x8d, 0x79, 0xc2, 0x33, 0xad, 0x4b, 0x1c, 0x08, 0x67, 0x63, 0x65, 0xd0, 0xbd, 0x67, 0x56, 0x7a, 0x0a, 0x46, 0x9c, 0xe8, 0x10, 0x25, 0x9d, 0xb1, 0x97, 0x4c, 0x20, 0xe8, 0x5a, 0x07, 0xc7, 0x82, 0x36, 0x9b, 0xfd, 0x32, 0x15, 0xf2, 0xe6, 0x86, 0x20, 0x61, 0xb8, 0xc9, 0xc5, 0x86, 0xcb, 0x84, 0x35, 0x86, 0x96, 0xb2, 0x5e, 0xcc, 0x00, 0x2e, 0x14, 0x1c, 0x64, 0xd0, 0xdb, 0x59, 0x0e, 0x5e, 0x53, 0x07, 0x94, 0x05, 0xa8, 0xa8, 0x5e, 0x9f, 0xb6, 0x44, 0xbd, 0x7d, 0x03, 0x47, 0xf7, 0xb2, 0xbf, 0x21, 0xf6, 0xc6, 0xe5, 0xe3, 0xaa, 0x1a, 0xab, 0xca, 0x79, 0x0d, 0x72, 0xa7, 0xc4, 0x48, 0x97, 0x1e, 0xbc, 0x8c, 0xf9, 0xbf, 0xe5, 0xc2, 0xfa, 0x64, 0x0f, 0xa6, 0x1c, 0x98, 0xa8, 0x74, 0x47, 0x51, 0x55, 0xc3, 0x53, 0x64, 0xc6, 0x17, 0xed, 0x44, 0x02, 0x25, 0x33, 0xcd, 0x13, 0xa8, 0x1e, 0x9c, 0x3f, 0x49, 0xf1, 0xac, 0x6a, 0xd5, 0xfb, 0xb3, 0xde, 0xcc, 0xf5, 0x3e, 0xb7, 0x73, 0x2e, 0xb2, 0x0e, 0x0c, 0x03, 0x5c, 0xbb, 0xf6, 0x0e, 0x57, 0x0a, 0x15, 0xd5, 0x84, 0xdb, 0x3c, 0x6c, 0x64, 0xca, 0xe7, 0x41, 0x52, 0xb3, 0x62, 0xb8, 0xf5, 0xd0, 0xdd, 0xc5, 0xba, 0x1a, 0x26, 0x6b, 0xb7, 0xe5, 0xb5, 0x9d, 0xdb, 0x21, 0x4a, 0x28, 0x1a, 0xe4, 0x6a, 0xd0, 0x32, 0x71, 0xf0, 0x7d, 0x02, 0x67, 0x75, 0x9d, 0xe0, 0x0f, 0x61, 0x2b, 0x60, 0xb2, 0xc0, 0x1f, 0x73, 0x72, 0x10, 0x43, 0x7e, 0xcc, 0x28, 0x52, 0xb0, 0xa9, 0x75, 0x20, 0x79, 0xf8, 0xd6, 0x20, 0x6e, 0x3d, 0x38, 0x0e, 0x5d, 0x61, 0xe6, 0x32, 0xfc, 0x34, 0xa6, 0x6d, 0xd9, 0xd0, 0x59, 0x7b, 0xc7, 0xdb, 0xb7, 0x23, 0x7c, 0x4a, 0x66, 0x2d, 0xae, 0x6c, 0xde, 0x6d, 0x50, 0x14, 0x83, 0xb3, 0x28, 0xa3, 0x4c, 0x7e, 0xde, 0x3b, 0x24, 0x6b, 0xb7, 0x5f, 0x08, 0xa2, 0x06, 0x0f, 0x31, 0x13, 0x66, 0x1e, 0xf9, 0x8e, 0x85, 0x61, 0xb9, 0xbb, 0x67, 0x28, 0x2a, 0xe7, 0xd9, 0xb4, 0x7e, 0xab, 0x1b, 0xb2, 0xdb, 0x2d, 0x7e, 0xb9, 0x96, 0x10, 0x82, 0x20, 0xa9, 0xa2, 0x44, 0x72, 0xb3, 0xe7, 0x97, 0x63, 0x3e, 0xdc, 0x81, 0x2a, 0xbf, 0x2b, 0xf5, 0x02, 0x37, 0xe8, 0x77, 0x3b, 0x8b, 0xe1, 0x11, 0xcf, 0xab, 0x26, 0xbd, 0x07, 0x62, 0x45, 0x0a, 0x5f, 0x55, 0x10, 0x7a, 0x52, 0xa0, 0xea, 0x1c, 0x84, 0xdf, 0xa2, 0x31, 0xaf, 0x2a, 0xe5, 0x50, 0x39, 0x58, 0xc0, 0x65, 0x3f, 0xad, 0x3b, 0x27, 0xa1, 0x3b, 0x26, 0x91, 0x02, 0x82, 0xaf, 0xfc, 0x36, 0xc3, 0x42, 0xc7, 0x2b, 0x40, 0xd1, 0xf1, 0xde, 0x6d, 0x0c, 0x35, 0x28, 0xa1, 0x7d, 0x62, 0x51, 0xeb, 0x04, 0xca, 0xdb, 0x81, 0x8e, 0x4e, 0x2a, 0x41, 0xb9, 0x6e, 0x2f, 0x58, 0x53, 0x1b, 0xa6, 0x34, 0x06, 0x50, 0x56, 0xa2, 0x66, 0x8e, 0xc5, 0xfb, 0xe1, 0x38, 0x54, 0x10, 0x98, 0x56, 0xda, 0xda, 0x24, 0xb9, 0xc9, 0xba, 0x3e, 0xcf, 0xa9, 0x89, 0x52, 0xcb, 0x6c, 0x21, 0x37, 0xdc, 0xdb, 0xdc, 0x86, 0x0e, 0xa3, 0x6e, 0xe4, 0x56, 0x03, 0xbc, 0x7c, 0x61, 0xd8, 0x12, 0xeb, 0x7e, 0x92, 0xe4, 0xfc, 0xc9, 0xbc, 0x3b, 0x18, 0x5b, 0x09, 0xdb, 0x97, 0xd6, 0xd6, 0x6f, 0xa1, 0xbd, 0x17, 0xfb, 0x18, 0xc1, 0x8e, 0xf2, 0x03, 0x32, 0x4d, 0x18, 0x38, 0x31, 0x50, 0xe7, 0x56, 0xc6, 0xaa, 0x1c, 0x27, 0xb9, 0xb6, 0x0f, 0x5c, 0x11, 0x0d, 0x7d, 0xd2, 0xdd, 0x72, 0xe4, 0x30, 0xbb, 0xa9, 0x7a, 0xa4, 0x17, 0xeb, 0x0e, 0x8d, 0xe4, 0xfd, 0x3c, 0xd5, 0x81, 0xea, 0x53, 0x05, 0xbb, 0xa5, 0x5a, 0xdc, 0xfe, 0x58, 0x40, 0x4d, 0xf0, 0xdb, 0xc8, 0x48, 0x05, 0x2e, 0x06, 0xb4, 0x21, 0x43, 0x10, 0x3d, 0x3d, 0x66, 0xfe, 0x47, 0x91, 0x5b, 0x93, 0xde, 0x27, 0x60, 0x9e, 0x15, 0x23, 0xc7, 0x24, 0xeb, 0xa3, 0x1b, 0x4c, 0xff, 0x32, 0x95, 0xb5, 0xd2, 0x96, 0x1c, 0x1d, 0xa9, 0x02, 0x57, 0xbe, 0x93, 0xd0, 0x35, 0x3d, 0xc9, 0xeb, 0xd9, 0x6a, 0x3e, 0x9b, 0x0d, 0x33, 0x20, 0xa2, 0x44, 0x5f, 0x81, 0x75, 0x8c, 0xd7, 0x92, 0xbc, 0xb6, 0x57, 0x84, 0xce, 0xe8, 0xe4, 0x7e, 0x6b, 0xed, 0x95, 0x69, 0x25, 0x96, 0xae, 0x78, 0x67, 0x90, 0x02, 0xee, 0xe5, 0x11, 0x2d, 0x6c, 0x68, 0x02, 0x49, 0xb1, 0x00, 0xda, 0x84, 0x07, 0x7a, 0x53, 0x24, 0x9d, 0xb4, 0xfc, 0xf3, 0x38, 0x3b, 0xc2, 0xed, 0x36, 0x66, 0x62, 0x84, 0xee, 0x53, 0x37, 0x48, 0xb2, 0xb8, 0xfa, 0x1a, 0x40, 0xf7, 0xa1, 0x10, 0x49, 0x32, 0x97, 0xf8, 0xee, 0x64, 0x94, 0x20, 0x82, 0xac, 0x19, 0x34, 0x6a, 0x33, 0xce, 0x1a, 0x14, 0xb3, 0x9e, 0x62, 0x83, 0xea, 0xc5, 0x29, 0xf1, 0xed, 0xa4, 0xae, 0xb8, 0x54, 0x72, 0xd1, 0xce, 0x94, 0xfc, 0x94, 0xf6, 0x52, 0x6b, 0xbb, 0xde, 0x34, 0x37, 0xec, 0xdd, 0x82, 0x94, 0xae, 0xae, 0x20, 0x0b, 0x4a, 0xa2, 0xc5, 0x89, 0x96, 0xbd, 0x07, 0xf1, 0x02, 0xf5, 0x45, 0x9c, 0xb3, 0xa4, 0x91, 0xcd, 0xf5, 0xb3, 0x7c, 0xaf, 0x82, 0xe8, 0xeb, 0xd7, 0xc9, 0xd8, 0x72, 0x46, 0x2e, 0xd5, 0x4e, 0x89, 0x96, 0x3f, 0x67, 0xe4, 0xba, 0x6c, 0x7f, 0xef, 0x49, 0x39, 0xef, 0x17, 0x33, 0x4b, 0x24, 0xf6, 0xb2, 0x5d, 0x01, 0x58, 0x91, 0x95, 0x80, 0xfe, 0xd8, 0x99, 0xc6, 0x0c, 0xfa, 0x85, 0x77, 0xc8, 0x18, 0x44, 0x2e, 0xa6, 0xbb, 0x2b, 0xfb, 0xa4, 0x23, 0x8e, 0xbe, 0xde, 0x19, 0xff, 0x71, 0x83, 0x72, 0x4e, 0xbb, 0x84, 0xae, 0x8a, 0x0a, 0x52, 0xa4, 0x0a, 0x90, 0x7b, 0xb3, 0x11, 0xf3, 0xe8, 0xb3, 0x6f, 0x91, 0xf3, 0xca, 0xd0, 0x9e, 0xf8, 0xfb, 0x7a, 0x1f, 0x4a, 0x9a, 0x26, 0x3c, 0x5f, 0x96, 0xf4, 0x58, 0x2a, 0x27, 0x8c, 0x00, 0x00, 0x01, 0xb7 }; +constexpr AccessUnit M2V_BEGIN_OF_AU_SPLIT_EXPECTED_AU = { std::numeric_limits::max(), std::numeric_limits::max(), false, 0, {}, { 0x82, 0x81, 0xd3, 0x81, 0x99, 0x42, 0xa6, 0x9c, 0xe1, 0x8b, 0xab, 0x3e, 0xdb, 0x1c, 0x00, 0x03, 0xae, 0x8a, 0x24, 0x51 } }; + +const std::vector ATRACX_BEGIN_OF_AU_SPLIT_STREAM = { 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xbd, 0x06, 0xe6, 0x81, 0xc1, 0x0d, 0x31, 0x00, 0x05, 0xbf, 0x21, 0x11, 0x00, 0x05, 0xb3, 0x65, 0x1e, 0x69, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x6c, 0xa7, 0x0b, 0x60, 0xfe, 0xb5, 0x2e, 0x3b, 0x4e, 0x6b, 0xaf, 0x90, 0x57, 0xc4, 0x99, 0xd0, 0x4e, 0xfa, 0x04, 0x29, 0x4c, 0x23, 0xcd, 0x8a, 0x9a, 0xac, 0x64, 0x27, 0x65, 0x27, 0xa2, 0x5c, 0xe2, 0xfd, 0x1d, 0x15, 0xcf, 0x72, 0x70, 0x1e, 0xb5, 0x08, 0x9f, 0x6f, 0x3d, 0x0b, 0x22, 0x22, 0x99, 0xbe, 0xcc, 0xb6, 0xdd, 0x99, 0xb9, 0x2b, 0xba, 0xa6, 0x32, 0xf0, 0x11, 0xc3, 0x4f, 0xc9, 0x06, 0xb1, 0x27, 0xee, 0x0b, 0xc6, 0xa6, 0x26, 0xf8, 0x02, 0x35, 0x7f, 0x64, 0x4a, 0x5d, 0x87, 0x1e, 0x20, 0xc9, 0x2a, 0x48, 0x0a, 0x57, 0x90, 0x65, 0x5a, 0x14, 0x62, 0x31, 0xbd, 0x5c, 0x28, 0xc6, 0x17, 0xcc, 0x3f, 0xde, 0x22, 0x35, 0xcf, 0xe2, 0xdc, 0xbe, 0x9b, 0xcb, 0x22, 0x96, 0xf1, 0xe1, 0xe9, 0x74, 0x7f, 0xc4, 0x79, 0xca, 0xe4, 0xeb, 0x68, 0x16, 0xeb, 0x39, 0x57, 0x65, 0xed, 0xd1, 0xc3, 0x6b, 0x21, 0x3a, 0xca, 0x94, 0xa2, 0xf7, 0x5f, 0x8e, 0x02, 0x47, 0x02, 0x35, 0xe4, 0x65, 0x3a, 0x34, 0x09, 0x15, 0x63, 0x8d, 0x0b, 0x1f, 0xdc, 0x1e, 0x8d, 0x6b, 0xfd, 0x16, 0xe7, 0xf6, 0x12, 0x2f, 0x75, 0x30, 0x31, 0x72, 0xd1, 0x8e, 0x68, 0x15, 0x5a, 0xbc, 0xf7, 0x0e, 0x89, 0x07, 0x20, 0xa0, 0x9b, 0xae, 0x14, 0x2a, 0xe7, 0x74, 0xa5, 0xf0, 0x15, 0xec, 0xda, 0x9a, 0x6e, 0xe2, 0x80, 0xc6, 0x98, 0xac, 0x8e, 0xc4, 0xfb, 0xdc, 0x73, 0x5b, 0x97, 0xcd, 0xa4, 0x99, 0xea, 0x92, 0x39, 0x50, 0xcc, 0xdc, 0x09, 0x89, 0x09, 0xed, 0x61, 0x44, 0x7a, 0xa3, 0x9b, 0x70, 0x86, 0x36, 0x0e, 0x81, 0x1d, 0xc5, 0x7a, 0x6a, 0xcf, 0x2e, 0x3f, 0x17, 0xbb, 0xf3, 0xe1, 0x4b, 0x44, 0xe9, 0xdb, 0x1b, 0x69, 0x59, 0x4e, 0xd2, 0x37, 0x1f, 0xe1, 0x22, 0x9a, 0x10, 0xdd, 0x72, 0xc7, 0x56, 0x7c, 0x6f, 0xc4, 0xb3, 0x36, 0xa7, 0xce, 0x69, 0xad, 0x7c, 0xc4, 0x1c, 0xed, 0xa0, 0x55, 0x8d, 0x44, 0x37, 0x96, 0x41, 0x3c, 0x06, 0xe1, 0xbb, 0x58, 0x35, 0x43, 0x5b, 0x0b, 0x10, 0xed, 0x13, 0x02, 0xe2, 0xb2, 0xeb, 0x2f, 0x7d, 0x89, 0x63, 0x2e, 0x52, 0x51, 0xc5, 0x05, 0x06, 0xbd, 0x64, 0xc0, 0x16, 0xfe, 0x41, 0xc9, 0x36, 0xb1, 0xe6, 0xf3, 0x14, 0x06, 0x6e, 0x05, 0x04, 0x02, 0x70, 0x1f, 0xa7, 0xed, 0x2b, 0x80, 0x94, 0x7f, 0x73, 0xb6, 0xf8, 0xa6, 0x16, 0x10, 0x6d, 0x1d, 0xe2, 0xf4, 0x9e, 0x5c, 0x48, 0x1f, 0x00, 0x9d, 0xb4, 0xc1, 0x9f, 0xd4, 0x1a, 0x69, 0x3d, 0xbc, 0x1c, 0x2b, 0x07, 0xeb, 0xe4, 0xe4, 0xdc, 0xf1, 0x82, 0x5b, 0xba, 0xab, 0x9f, 0xf2, 0xdc, 0x21, 0x0c, 0xcd, 0xef, 0x70, 0x1b, 0xf4, 0xbd, 0x9a, 0x7d, 0xde, 0xad, 0x0e, 0x58, 0x68, 0xd2, 0x1b, 0x9b, 0x23, 0x4d, 0xe6, 0x94, 0x6c, 0xe3, 0x75, 0x4f, 0x7e, 0x0e, 0x89, 0x14, 0x79, 0x54, 0x2c, 0x93, 0x4f, 0x05, 0x52, 0x1d, 0x92, 0x15, 0x80, 0x58, 0x8d, 0x42, 0xb6, 0xf4, 0x14, 0x9c, 0x46, 0x45, 0x69, 0x9f, 0xbd, 0x74, 0xd8, 0xe4, 0x30, 0x31, 0x23, 0x78, 0xce, 0x4b, 0xb7, 0x2c, 0x51, 0x2d, 0x76, 0x21, 0x83, 0x41, 0x64, 0x29, 0xce, 0x29, 0x09, 0x4c, 0xe8, 0x0a, 0xbe, 0x12, 0x77, 0xaf, 0x31, 0x0e, 0x6c, 0xc8, 0x4f, 0x29, 0xe4, 0x84, 0xfa, 0x05, 0xe2, 0x1c, 0xdb, 0x56, 0x64, 0xe2, 0xb4, 0x28, 0x6e, 0x51, 0x4b, 0xc4, 0x90, 0xad, 0x5d, 0x8f, 0x90, 0x64, 0x78, 0xf9, 0x7b, 0x3e, 0xd4, 0xf7, 0x2a, 0xdc, 0x40, 0xc0, 0xee, 0x48, 0x69, 0x61, 0x53, 0xe7, 0x76, 0x2e, 0xcb, 0x73, 0x4b, 0xad, 0xe5, 0x93, 0x45, 0x3f, 0x4a, 0x8c, 0x1d, 0x02, 0x2f, 0x02, 0xb7, 0xb3, 0xf7, 0xbe, 0x95, 0x6e, 0x48, 0x63, 0x55, 0x1d, 0xe2, 0xdb, 0xf0, 0x17, 0x22, 0x5f, 0xda, 0xb3, 0xf2, 0x54, 0x08, 0xbc, 0x8b, 0x08, 0x7b, 0x99, 0x37, 0xef, 0xfb, 0x10, 0xc6, 0x7b, 0xdd, 0x43, 0x98, 0xa2, 0x67, 0x55, 0x41, 0xd6, 0x43, 0x5b, 0xfe, 0x59, 0xfa, 0xd1, 0x1c, 0xb5, 0x18, 0x1b, 0x50, 0x68, 0xbd, 0x8f, 0x4a, 0x6f, 0x81, 0xfd, 0x6e, 0x85, 0x76, 0xe3, 0x43, 0x8d, 0x18, 0x2a, 0x1f, 0x8d, 0x75, 0x78, 0xa5, 0xaa, 0xb1, 0x6a, 0xa1, 0x59, 0xa1, 0x7e, 0x40, 0x62, 0x2c, 0x8d, 0x5b, 0xda, 0xa7, 0x32, 0x1c, 0xe2, 0xb9, 0xdd, 0x8d, 0x77, 0x6d, 0xcc, 0x13, 0x5f, 0x0a, 0x40, 0x74, 0xf6, 0xe1, 0x66, 0xda, 0xc3, 0x9c, 0x5c, 0x60, 0x61, 0xed, 0x2f, 0x2c, 0x89, 0x72, 0x7a, 0x11, 0xc6, 0x3a, 0x5d, 0x45, 0x55, 0xd8, 0xa8, 0x03, 0xc6, 0x6d, 0x78, 0xe7, 0xb9, 0x54, 0xb3, 0x6b, 0xc9, 0xcb, 0xc1, 0xac, 0x41, 0x1c, 0x4a, 0x10, 0x21, 0x56, 0x17, 0xa3, 0x1d, 0x1e, 0x78, 0x40, 0x6f, 0x0c, 0x3b, 0x9e, 0xcc, 0x7b, 0xc4, 0xa3, 0x07, 0x90, 0xa3, 0x6c, 0xa4, 0x63, 0xdf, 0xc3, 0xea, 0xf0, 0x85, 0xbc, 0x14, 0xda, 0x31, 0xd8, 0x49, 0x2f, 0x70, 0x85, 0x5c, 0x7b, 0x6d, 0x92, 0x3c, 0x0d, 0x35, 0x61, 0xe7, 0x8d, 0x65, 0xee, 0x37, 0xa3, 0x9a, 0xdb, 0x9c, 0x44, 0x18, 0x7c, 0x01, 0x90, 0xc2, 0xae, 0x37, 0x34, 0x07, 0x9e, 0xb9, 0xf2, 0x53, 0x86, 0x09, 0x9b, 0xc4, 0xda, 0xf8, 0xe2, 0x0e, 0x52, 0x8d, 0xb5, 0xe8, 0xd5, 0x0c, 0x75, 0xe9, 0x1d, 0x9e, 0x52, 0xa3, 0x60, 0x15, 0x50, 0x94, 0xcd, 0x1c, 0x7d, 0xfe, 0x75, 0x61, 0x30, 0x6b, 0xc9, 0x4f, 0xcd, 0xe1, 0x97, 0xa0, 0x9d, 0xaf, 0xfc, 0x57, 0xdf, 0xca, 0xff, 0xd6, 0x23, 0x8d, 0x0a, 0x38, 0x89, 0xdd, 0x9c, 0x60, 0x1e, 0xaf, 0xed, 0x83, 0xac, 0x84, 0x6b, 0xd8, 0xc2, 0x06, 0x5f, 0xc0, 0xef, 0xac, 0x59, 0x96, 0xcc, 0xc4, 0x2f, 0xb7, 0x57, 0x73, 0x9f, 0xee, 0x70, 0x82, 0xe9, 0x3c, 0x54, 0xdf, 0x2c, 0x35, 0xfe, 0xa4, 0x78, 0x0c, 0x75, 0xb4, 0x90, 0x12, 0xd3, 0x1f, 0xbf, 0x92, 0x7b, 0xd7, 0x10, 0xa6, 0x98, 0xb2, 0x0e, 0x9f, 0xfd, 0x3d, 0xd5, 0x4e, 0x4d, 0x55, 0xa8, 0xf0, 0xa8, 0xa4, 0x74, 0x74, 0xf7, 0x8b, 0x7f, 0xda, 0xfe, 0xe3, 0xc2, 0xf7, 0x31, 0xe4, 0x0a, 0x20, 0xf2, 0x2e, 0x0b, 0x47, 0x5c, 0x29, 0x2c, 0x33, 0xd7, 0xf7, 0x7d, 0x02, 0x0b, 0x17, 0x01, 0xf4, 0x0b, 0x1e, 0xa2, 0x63, 0xaa, 0x80, 0xbc, 0xb9, 0x21, 0xd7, 0xfa, 0x7c, 0x2a, 0xa1, 0xa6, 0x90, 0x30, 0x8e, 0xd1, 0x94, 0x75, 0x78, 0xc1, 0x6e, 0x78, 0xdc, 0x8a, 0xd8, 0x65, 0x00, 0x2e, 0xf7, 0x99, 0x67, 0xfe, 0x5e, 0x49, 0x3e, 0x87, 0xd5, 0x92, 0x7b, 0x2d, 0x23, 0xfe, 0xcc, 0xce, 0x44, 0xe4, 0x94, 0x1b, 0xa6, 0xd3, 0x48, 0x88, 0x17, 0x71, 0x2b, 0x94, 0xd8, 0x47, 0xc6, 0x68, 0xc2, 0x89, 0xa7, 0xab, 0x65, 0x9a, 0xa0, 0x9a, 0xcd, 0xee, 0x36, 0x8c, 0x1d, 0xba, 0xcb, 0x75, 0x8d, 0xbe, 0x09, 0x1e, 0x48, 0xad, 0xd4, 0xc6, 0x16, 0xf3, 0xfe, 0x6a, 0x77, 0xa9, 0xed, 0x2c, 0xd3, 0x7e, 0xc0, 0x16, 0xa9, 0x11, 0x57, 0xfc, 0x36, 0xa8, 0x68, 0xb1, 0xb0, 0x57, 0x59, 0x1b, 0xea, 0x4c, 0xe9, 0x47, 0xf7, 0xa9, 0xa1, 0x88, 0xfc, 0x47, 0x84, 0x28, 0xd6, 0xca, 0x39, 0xc4, 0xde, 0x88, 0xad, 0x8c, 0xff, 0x68, 0xe1, 0x81, 0x83, 0x8b, 0x71, 0x0e, 0xda, 0x98, 0xf8, 0x63, 0xd7, 0x25, 0x81, 0x57, 0x12, 0x19, 0x8e, 0x03, 0xf3, 0x3a, 0x58, 0xfb, 0xf5, 0x34, 0x93, 0xc0, 0x1f, 0xd5, 0x43, 0xac, 0x92, 0x13, 0x48, 0x7e, 0x9a, 0x66, 0x69, 0x2e, 0x0c, 0x77, 0x00, 0xa3, 0xe1, 0x16, 0x76, 0x51, 0x7a, 0xc7, 0x5f, 0xf4, 0x66, 0x3f, 0xe6, 0x2f, 0x90, 0x6a, 0xfd, 0xba, 0x0b, 0x87, 0x29, 0x3e, 0xa4, 0xc4, 0xde, 0x6b, 0x25, 0xce, 0x45, 0x16, 0x9f, 0x54, 0x10, 0x20, 0xea, 0xb5, 0xd7, 0x9b, 0xc0, 0x79, 0xef, 0x90, 0x0e, 0xca, 0x5e, 0x4c, 0x1a, 0x73, 0x5a, 0xc2, 0xfb, 0x7a, 0x1a, 0x6b, 0x6b, 0x51, 0x55, 0x85, 0x0b, 0xf3, 0x60, 0x6c, 0x92, 0x94, 0x37, 0x45, 0x89, 0x48, 0xb8, 0x17, 0xa3, 0xa4, 0x70, 0x33, 0xdb, 0x12, 0x39, 0x48, 0x6e, 0x8f, 0x83, 0x9c, 0xea, 0x24, 0x46, 0x50, 0x15, 0xa4, 0xe5, 0x57, 0x5f, 0x73, 0xdc, 0xbb, 0xad, 0xc9, 0x08, 0x03, 0x8d, 0x7a, 0x89, 0x17, 0x91, 0x9e, 0x7e, 0x1c, 0x9f, 0xdc, 0xb3, 0x61, 0x0a, 0x0b, 0x16, 0x2c, 0x5a, 0xbf, 0xab, 0x25, 0x66, 0xdc, 0x21, 0x4a, 0xd6, 0xb9, 0x22, 0xa1, 0x0b, 0xed, 0x54, 0xf9, 0xf3, 0xc6, 0xe9, 0xf5, 0xd8, 0x39, 0x90, 0xa2, 0xad, 0xd8, 0xa4, 0xdf, 0x6e, 0xe0, 0x07, 0x3b, 0xe2, 0x6c, 0x04, 0x92, 0x03, 0x05, 0x6a, 0x54, 0x2c, 0xfb, 0xb3, 0xcb, 0xe8, 0xd0, 0x19, 0x0a, 0x4d, 0xdd, 0xf6, 0xf8, 0x84, 0xb6, 0xe8, 0xae, 0xd9, 0x73, 0xbe, 0xca, 0x44, 0x59, 0x2c, 0x7a, 0x83, 0xf4, 0xd3, 0x45, 0x72, 0x78, 0x50, 0xd8, 0xc7, 0xcd, 0xb6, 0x93, 0x1f, 0x87, 0x56, 0xc3, 0xf8, 0xb1, 0xb7, 0x6f, 0xd5, 0xda, 0x98, 0xa4, 0x84, 0x59, 0x69, 0x6d, 0xa0, 0xcc, 0xcf, 0x29, 0xac, 0x6a, 0x1a, 0xd8, 0x08, 0x73, 0x2a, 0x70, 0x2e, 0x76, 0xc0, 0x87, 0xc5, 0xb7, 0x06, 0xec, 0x9d, 0x1d, 0xce, 0xbe, 0x99, 0x1c, 0xcf, 0x45, 0x2d, 0xdf, 0x35, 0x14, 0xad, 0xa6, 0x9e, 0xcb, 0x86, 0xe8, 0x24, 0xaa, 0x79, 0x36, 0x84, 0xe1, 0x78, 0x1e, 0xdd, 0x41, 0x67, 0x74, 0x45, 0x24, 0x41, 0x62, 0x59, 0x77, 0xf1, 0xaf, 0xbf, 0xca, 0x21, 0x85, 0xf9, 0xc8, 0xb2, 0xf6, 0x07, 0x91, 0x54, 0x98, 0x25, 0xc8, 0x66, 0x3b, 0xb7, 0x1b, 0xcf, 0x3e, 0xe7, 0xb0, 0x53, 0x6b, 0x11, 0x6f, 0xb1, 0x79, 0xd5, 0xdb, 0xbd, 0x72, 0x0a, 0xdb, 0x79, 0x86, 0x4a, 0x22, 0x55, 0x09, 0xf2, 0x0d, 0x19, 0x90, 0xc9, 0x0a, 0x20, 0x7a, 0x67, 0x7e, 0x8b, 0x26, 0x47, 0x04, 0x60, 0xd7, 0x04, 0x6b, 0x9b, 0x85, 0x32, 0x12, 0xc6, 0x3e, 0xbb, 0x2d, 0xd3, 0x0f, 0x1a, 0x33, 0x6d, 0x4d, 0x88, 0xda, 0xd8, 0xb5, 0xe3, 0x0c, 0xc6, 0x12, 0x4d, 0x7b, 0x77, 0x55, 0x5c, 0xf6, 0xfd, 0xaa, 0xed, 0xa5, 0x13, 0x3e, 0x8b, 0xce, 0x37, 0xc3, 0x21, 0xe2, 0x80, 0x25, 0x35, 0x55, 0xae, 0x03, 0x38, 0x60, 0x8f, 0x57, 0x05, 0x65, 0xd8, 0x35, 0x5c, 0x8a, 0xd7, 0x9b, 0x6b, 0x7c, 0x31, 0xe0, 0x82, 0xbf, 0xf5, 0x21, 0x41, 0x6c, 0xab, 0xe3, 0x44, 0xd0, 0x64, 0x80, 0xce, 0x9a, 0x28, 0x50, 0x5d, 0x71, 0x28, 0xab, 0x2a, 0x1f, 0x5b, 0xca, 0x16, 0xc4, 0x81, 0x52, 0xa1, 0x39, 0xa6, 0x08, 0xb4, 0x31, 0x38, 0x0d, 0xe6, 0xc6, 0x2a, 0xaf, 0x1f, 0xd9, 0x52, 0x43, 0xd8, 0xb5, 0xb9, 0xc9, 0x84, 0x08, 0x53, 0x91, 0xd9, 0x5d, 0xa8, 0x78, 0x21, 0x2c, 0x2c, 0xa5, 0x49, 0x8c, 0xf5, 0x0d, 0xee, 0xdc, 0xb7, 0xdf, 0xf3, 0x66, 0x40, 0x68, 0xc9, 0xa4, 0x94, 0xbc, 0x37, 0x16, 0x2d, 0x61, 0xb5, 0x58, 0x47, 0x09, 0x95, 0xc5, 0xf0, 0xbb, 0x43, 0xee, 0x60, 0x32, 0xa4, 0xd1, 0xbf, 0xe1, 0xf1, 0xd5, 0x54, 0xbc, 0xd3, 0x81, 0xc5, 0x26, 0xbb, 0xb4, 0xd8, 0xd6, 0x3d, 0x4a, 0x86, 0x50, 0x90, 0xbd, 0x8b, 0x36, 0xfb, 0xe3, 0x78, 0x94, 0xb2, 0x3a, 0x76, 0x1b, 0x72, 0x5a, 0x29, 0x20, 0x31, 0x12, 0xf3, 0xaa, 0x03, 0xcb, 0x2c, 0xdf, 0x59, 0x78, 0x8e, 0x99, 0x1f, 0x23, 0x9d, 0x13, 0xd1, 0xac, 0xef, 0x2e, 0xfb, 0x0b, 0x86, 0xfa, 0x28, 0xc6, 0x62, 0x82, 0x9b, 0xf2, 0x75, 0x13, 0x24, 0xfe, 0x2f, 0x06, 0x0c, 0xf1, 0x4f, 0x92, 0xda, 0xda, 0x67, 0x58, 0x5e, 0x52, 0x85, 0xbf, 0xa0, 0x6d, 0xdb, 0xb2, 0x2f, 0xf0, 0xe9, 0x98, 0x97, 0xd1, 0x4c, 0x53, 0x93, 0xf9, 0x44, 0xc6, 0x84, 0x0e, 0x8a, 0xcd, 0xfb, 0x60, 0xf3, 0xfe, 0x75, 0xbc, 0x46, 0xef, 0x00, 0x5c, 0xfa, 0xbc, 0xf7, 0x60, 0x30, 0xc3, 0xe7, 0xc0, 0x10, 0xa4, 0xd4, 0x69, 0xf3, 0xea, 0x10, 0x54, 0x9e, 0xd1, 0x1d, 0xd7, 0x09, 0xcc, 0x0f, 0x7b, 0x28, 0xec, 0x75, 0x82, 0x3c, 0x18, 0xb4, 0x5d, 0x1b, 0xbb, 0x90, 0xe0, 0xd3, 0xed, 0x99, 0x67, 0x72, 0x2d, 0xa6, 0x35, 0xf4, 0x92, 0x2d, 0x77, 0x62, 0x67, 0x32, 0x1d, 0xba, 0xd6, 0xb2, 0x97, 0xe9, 0xd7, 0x83, 0x0d, 0x37, 0xe9, 0xad, 0x3a, 0xd8, 0x7b, 0xfb, 0xd3, 0xc8, 0xeb, 0xd2, 0xb1, 0x3a, 0xab, 0xc9, 0xd6, 0x61, 0x8f, 0x90, 0xbc, 0xa5, 0x1b, 0xa9, 0xc6, 0x47, 0x8d, 0x75, 0xb7, 0x59, 0x84, 0xb7, 0xb4, 0x07, 0x22, 0x66, 0xac, 0x7f, 0xbf, 0xbb, 0xe2, 0x13, 0x6d, 0x41, 0x74, 0xcf, 0x1e, 0x67, 0xd3, 0x01, 0x9a, 0xd8, 0xe9, 0x3c, 0xcc, 0xde, 0x08, 0x5b, 0x32, 0xa5, 0xf2, 0x8b, 0x0f, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xbd, 0x06, 0xe6, 0x81, 0xc1, 0x0d, 0xc3, 0xa9, 0xb9, 0x73, 0x50, 0xe3, 0x6a, 0x08, 0xb4, 0x2e, 0x64, 0x6d, 0x05, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x00, 0xd8, 0x1d, 0xe7, 0x46, 0x25, 0x7e, 0x8c, 0x8e, 0xd0, 0xf5, 0xbe, 0x16, 0xfa, 0x95, 0x4f, 0xf2, 0x70, 0xa3, 0xbb, 0x44, 0x58, 0x07, 0x72, 0xef, 0x92, 0xaf, 0x0e, 0x5b, 0xcb, 0x5f, 0x84, 0x33, 0x71, 0xad, 0x81, 0x00, 0x39, 0xab, 0x5c, 0xfa, 0x36, 0xfd, 0xcd, 0x41, 0xdb, 0x64, 0xfc, 0xba, 0x97, 0x46, 0x3f, 0x10, 0x92, 0xe6, 0xa1, 0xb4, 0xc4, 0x2d, 0x53, 0x2c, 0x11, 0xea, 0x7a, 0x8b, 0x82, 0x44, 0x7d, 0xdf, 0xf6, 0x7c, 0x8b, 0xf4, 0xd5, 0x1e, 0xcf, 0xb7, 0x49, 0xdd, 0x14, 0x81, 0x08, 0x6d, 0x2b, 0x90, 0x99, 0x57, 0x44, 0xfe, 0xb2, 0xf2, 0xaa, 0x3e, 0x9a, 0xac, 0x55, 0x30, 0x73, 0x3e, 0x97, 0xcd, 0x99, 0x08, 0x37, 0x65, 0x14, 0x55, 0xf2, 0xaf, 0xfd, 0x2f, 0x02, 0xbc, 0x80, 0x52, 0x16, 0x46, 0xd2, 0xae, 0xcc, 0x8c, 0xd1, 0x1a, 0x3d, 0xd6, 0x6a, 0x53, 0xdb, 0xcf, 0x75, 0x55, 0x39, 0x97, 0x1b, 0x21, 0x38, 0x04, 0xbe, 0xb2, 0xfb, 0xb2, 0x5b, 0x4d, 0x50, 0x41, 0xf4, 0x8a, 0xc4, 0xb2, 0xcd, 0xba, 0x98, 0xf3, 0x87, 0x58, 0xdc, 0xc7, 0xdf, 0x70, 0xc6, 0x91, 0xa2, 0x67, 0x0f, 0xe4, 0xe0, 0x61, 0xfa, 0xa8, 0xc6, 0x0c, 0xf9, 0xfe, 0x3d, 0xee, 0xb7, 0xdc, 0x94, 0x02, 0xd1, 0x62, 0x76, 0x7f, 0xa2, 0xf5, 0xca, 0xfb, 0x7d, 0x00, 0x92, 0xf0, 0x50, 0xc9, 0xac, 0x39, 0x53, 0x59, 0x67, 0x2f, 0x55, 0x00, 0x8d, 0x07, 0xdb, 0x6d, 0x0b, 0x32, 0xe3, 0x18, 0x55, 0xc4, 0x8d, 0xb7, 0x1b, 0x28, 0xf3, 0x65, 0xb7, 0x1c, 0x8c, 0xf5, 0x39, 0x7e, 0xa4, 0x29, 0x31, 0x28, 0x4f, 0x23, 0x44, 0xd6, 0xbd, 0x46, 0x00, 0x18, 0x0d, 0x2a, 0x2c, 0xcc, 0x4f, 0xb3, 0x1b, 0x78, 0x43, 0x36, 0x41, 0x4a, 0x9c, 0xd7, 0x02, 0xfc, 0x80, 0xfb, 0x2b, 0xcc, 0x0f, 0x51, 0x78, 0x1e, 0x82, 0xf5, 0x75, 0xb8, 0x1c, 0xf6, 0x43, 0xd0, 0x50, 0x27, 0x66, 0x18, 0x2d, 0x99, 0x4e, 0x16, 0x52, 0x1e, 0x62, 0x17, 0x87, 0x3e, 0xeb, 0xa6, 0x02, 0xa8, 0xc3, 0x3e, 0x03, 0x3b, 0x1a, 0x59, 0xe4, 0xe3, 0xfa, 0xb2, 0x9b, 0xae, 0x91, 0x0d, 0x45, 0x18, 0xac, 0x25, 0x52, 0x07, 0xf4, 0x15, 0xcc, 0x8b, 0xe3, 0xc2, 0xce, 0x63, 0xc6, 0x2c, 0xc9, 0xa0, 0x7c, 0xa1, 0x98, 0x31, 0x97, 0xc5, 0x5e, 0x48, 0xbb, 0x0e, 0x52, 0x14, 0xf3, 0x36, 0xcf, 0x2c, 0x4d, 0x6d, 0xaa, 0x73, 0x67, 0x63, 0x0a, 0xcb, 0x11, 0xe1, 0x6d, 0xf9, 0x78, 0x1c, 0x46, 0x38, 0xd3, 0xea, 0x1e, 0xe0, 0x92, 0xfa, 0xc1, 0x9e, 0x6c, 0x8f, 0x30, 0x96, 0x50, 0xd6, 0x3c, 0x19, 0x04, 0xdb, 0x72, 0x1b, 0x52, 0xd0, 0x6c, 0x59, 0x59, 0x29, 0x92, 0xdb, 0x75, 0x9c, 0xbf, 0x84, 0x60, 0x02, 0x31, 0x4f, 0x67, 0x6a, 0x1e, 0x2d, 0x6a, 0x2c, 0x0e, 0xc3, 0x7f, 0xa3, 0x34, 0xaa, 0x58, 0x08, 0xd7, 0xc2, 0xf5, 0xef, 0x9a, 0xd0, 0x72, 0xda, 0xb1, 0xb8, 0xd4, 0xd0, 0x69, 0x13, 0x81, 0x48, 0x7e, 0x99, 0x65, 0x39, 0x63, 0x4b, 0x66, 0x69, 0x34, 0x26, 0xb4, 0x52, 0xc0, 0xce, 0x47, 0x9a, 0x2c, 0xdf, 0x17, 0x7f, 0x78, 0xbf, 0x69, 0x8e, 0x54, 0x70, 0x9d, 0xb1, 0x87, 0x2a, 0xa7, 0x7c, 0x32, 0x84, 0xc5, 0xf7, 0x91, 0x5b, 0xd3, 0x8f, 0xf9, 0x3a, 0x03, 0xfa, 0xf0, 0x20, 0x9e, 0xe0, 0xc9, 0x0d, 0xb1, 0x03, 0x07, 0x62, 0xd8, 0xbc, 0x48, 0x42, 0x42, 0x81, 0x29, 0x14, 0x84, 0x44, 0x0a, 0x66, 0x8e, 0xc5, 0xb6, 0xea, 0x0d, 0xdc, 0x7c, 0xde, 0xd3, 0xfc, 0xcb, 0x9b, 0xc2, 0xcc, 0x1d, 0xe4, 0x65, 0xe8, 0xae, 0xe6, 0x82, 0x50, 0xfe, 0x8c, 0x7a, 0x34, 0xdb, 0x0f, 0xa7, 0x6e, 0x02, 0x9b, 0x85, 0xc1, 0xed, 0xa0, 0x4c, 0x68, 0x91, 0x5d, 0xd5, 0xae, 0x7c, 0x18, 0xbd, 0xb1, 0x04, 0x5f, 0x28, 0xe6, 0x75, 0x25, 0x22, 0xe0, 0x6e, 0xb1, 0xe7, 0xc5, 0xfb, 0x69, 0x91, 0x39, 0x59, 0x4f, 0x5f, 0xda, 0xc9, 0x39, 0x30, 0xad, 0x5d, 0x2d, 0x4c, 0x88, 0xc5, 0xff, 0x17, 0xc9, 0x76, 0x30, 0x25, 0xda, 0x86, 0x37, 0x1c, 0x7e, 0x97, 0xc3, 0xf1, 0xea, 0xcc, 0xef, 0x20, 0xc0, 0xf3, 0xbd, 0xdf, 0xbf, 0x92, 0x28, 0xba, 0x93, 0x5f, 0x4a, 0xae, 0xc0, 0xa3, 0xbb, 0xbb, 0xaf, 0xa0, 0x8e, 0x3e, 0x5a, 0xb5, 0x44, 0x7a, 0x08, 0x33, 0x60, 0x3a, 0xf1, 0xcd, 0x52, 0x05, 0xb8, 0x16, 0x3b, 0xab, 0xde, 0xd1, 0x3d, 0x7b, 0x3d, 0xc5, 0x44, 0xda, 0xdc, 0xa5, 0xe2, 0x80, 0x0b, 0x7f, 0xfa, 0xb9, 0xc9, 0xa9, 0x32, 0x46, 0xf3, 0x89, 0x0f, 0xe3, 0xeb, 0x68, 0xac, 0x96, 0x13, 0xff, 0xef, 0x76, 0xec, 0x19, 0xca, 0x09, 0x1a, 0x9a, 0x49, 0x4d, 0xa8, 0x54, 0xfa, 0x74, 0x85, 0x80, 0x3d, 0xb8, 0x61, 0x75, 0x13, 0xc2, 0x2e, 0xe9, 0x4c, 0x9a, 0x69, 0x41, 0xcb, 0x72, 0xce, 0x9e, 0x30, 0x4b, 0x1d, 0x3f, 0x8d, 0xc6, 0xfe, 0xe4, 0x87, 0xb9, 0x29, 0x1a, 0xdc, 0xb8, 0x57, 0xd0, 0xe8, 0xbf, 0x04, 0xb7, 0x06, 0x97, 0x38, 0x21, 0xb7, 0xd8, 0x17, 0xb1, 0xef, 0xb6, 0xfc, 0x09, 0x74, 0xdf, 0x73, 0x4a, 0x42, 0x1f, 0x13, 0x49, 0x48, 0x7b, 0x28, 0x0d, 0x3e, 0x55, 0x02, 0x93, 0x39, 0x1c, 0x87, 0x66, 0x7b, 0x2e, 0x10, 0x75, 0x1e, 0x85, 0x64, 0xf9, 0xd6, 0x2f, 0x40, 0x18, 0x86, 0xf3, 0xa7, 0x81, 0xb7, 0xb0, 0x1e, 0x95, 0x57, 0x02, 0x3e, 0x0f, 0xe5, 0x87, 0x9f, 0x72, 0x30, 0x80, 0xaa, 0x63, 0xf1, 0xdd, 0xb0, 0xd5, 0x83, 0x3b, 0x58, 0x19, 0x42, 0xc6, 0x27, 0xdf, 0x6b, 0x26, 0x07, 0x15, 0x4d, 0xc1, 0x83, 0x40, 0xa0, 0x36, 0xbb, 0xaf, 0xf7, 0x7a, 0xcf, 0x9e, 0x37, 0x9d, 0x32, 0xec, 0x64, 0x49, 0xd5, 0xe0, 0x17, 0x2d, 0x25, 0x67, 0xce, 0x31, 0xb7, 0x1e, 0x09, 0x2f, 0x2a, 0x6e, 0x7c, 0xcd, 0xf4, 0x1c, 0xc4, 0x74, 0x63, 0x89, 0xc1, 0xd8, 0xda, 0x33, 0x6c, 0x46, 0x44, 0x74, 0x7c, 0xa4, 0xf0, 0x4f, 0x03, 0x16, 0xd5, 0x27, 0x38, 0xda, 0x36, 0x08, 0x62, 0xd0, 0xbc, 0xa2, 0x00, 0x7a, 0x58, 0x2e, 0x1a, 0x7b, 0x2d, 0xf6, 0x02, 0xf1, 0x41, 0xce, 0x60, 0x32, 0xdd, 0x11, 0xd9, 0x7f, 0x2b, 0xbe, 0x40, 0x1b, 0xdb, 0xe5, 0x65, 0xc4, 0xa2, 0x7f, 0xc6, 0x78, 0x38, 0x16, 0xe2, 0x13, 0x29, 0x34, 0x1c, 0xda, 0x36, 0xae, 0xc3, 0x05, 0xc9, 0xf2, 0x5c, 0xa5, 0xa2, 0x5b, 0xae, 0xb6, 0xe3, 0x5d, 0x6e, 0xa6, 0x36, 0x9e, 0x5b, 0x11, 0x1f, 0x0a, 0xa4, 0xf0, 0x35, 0x70, 0x3d, 0x82, 0xee, 0xa2, 0x9f, 0xd9, 0x7b, 0xec, 0xe8, 0xaa, 0xee, 0xb9, 0x05, 0x2f, 0xca, 0xdd, 0x80, 0x19, 0x0f, 0x81, 0x6e, 0xdd, 0x8f, 0x71, 0xc1, 0x0b, 0x36, 0x2d, 0xcf, 0x8e, 0xfa, 0xb9, 0x8a, 0x70, 0xf5, 0x20, 0x61, 0x9f, 0x20, 0xde, 0xe7, 0xed, 0xd6, 0x24, 0x4a, 0xd7, 0x29, 0xb7, 0x3a, 0xe1, 0x88, 0x64, 0x20, 0x0c, 0x43, 0x57, 0xa5, 0x18, 0x85, 0x52, 0x92, 0xb1, 0xc5, 0x98, 0xf6, 0x6e, 0x4c, 0x3d, 0x60, 0x03, 0xb7, 0x82, 0x01, 0xec, 0x7d, 0xcf, 0xe3, 0x4e, 0xcb, 0x58, 0x49, 0xdb, 0xb1, 0xb3, 0xd3, 0xfc, 0x31, 0x9d, 0x1d, 0xb1, 0xcd, 0x50, 0x64, 0x2b, 0x2c, 0x30, 0x0f, 0xd7, 0x11, 0x42, 0xa5, 0x1f, 0x45, 0x33, 0xf8, 0xc6, 0x97, 0x9f, 0xc7, 0xce, 0x96, 0xb0, 0x0c, 0xf2, 0xcd, 0x5f, 0x65, 0x9e, 0x81, 0x58, 0x41, 0xfa, 0xf8, 0xe2, 0x79, 0xa6, 0x73, 0x65, 0xf6, 0xbe, 0x15, 0x98, 0x20, 0xe5, 0xda, 0xd3, 0x31, 0x9d, 0x97, 0x13, 0x47, 0x14, 0xf6, 0x2c, 0xd8, 0xbc, 0xea, 0xbb, 0x80, 0x60, 0x9d, 0x1f, 0x50, 0x59, 0x9f, 0x82, 0x4f, 0x6f, 0x18, 0x4d, 0x79, 0x48, 0x99, 0x6b, 0x55, 0xcb, 0x1a, 0xac, 0x4c, 0x8c, 0x38, 0xbf, 0x80, 0xad, 0x0b, 0x7c, 0xc5, 0x72, 0xe7, 0x60, 0x0e, 0xbf, 0xc3, 0x78, 0x73, 0xd7, 0x98, 0x96, 0xc1, 0x31, 0x16, 0xd5, 0x92, 0x06, 0x09, 0xd6, 0x92, 0x85, 0x1a, 0xa6, 0xd1, 0x77, 0x8e, 0x0f, 0xbe, 0x82, 0x40, 0x25, 0x97, 0x7b, 0x10, 0xfc, 0x1f, 0x65, 0x40, 0x58, 0x19, 0x7d, 0x08, 0x28, 0xfa, 0x8a, 0x85, 0xfa, 0x4b, 0x9b, 0xe6, 0xa0, 0xea, 0x62, 0xa9, 0x64, 0xd5, 0x3c, 0x60, 0x6b, 0x33, 0x33, 0x95, 0x97, 0xc2, 0x6f, 0x9e, 0x9d, 0xe2, 0x85, 0x83, 0x10, 0x7d, 0x56, 0x69, 0x68, 0x07, 0x2e, 0xb6, 0x84, 0x79, 0x1a, 0xc6, 0x7e, 0x75, 0x89, 0x42, 0xc7, 0xdf, 0x46, 0x35, 0x82, 0x3d, 0x42, 0x35, 0x95, 0x41, 0x33, 0x8b, 0xdd, 0xf7, 0xc2, 0x27, 0xbd, 0x3a, 0xc4, 0xb2, 0x5d, 0xc5, 0xc6, 0xa9, 0xea, 0x05, 0x33, 0x3c, 0x3a, 0xe0, 0xe5, 0x0e, 0x44, 0xfd, 0xc8, 0xb0, 0x90, 0x29, 0x70, 0xae, 0x3a, 0x55, 0x42, 0xd0, 0x08, 0x7e, 0xc2, 0xc8, 0xf2, 0x1e, 0xd9, 0x2e, 0x9d, 0xc8, 0xa0, 0x8a, 0x77, 0x3e, 0xf4, 0xa0, 0xfb, 0x0a, 0xbd, 0xaf, 0x12, 0xde, 0xc9, 0x5a, 0xa8, 0xcd, 0xa8, 0x3c, 0xb0, 0x6d, 0x27, 0x9c, 0xed, 0xb5, 0x41, 0x84, 0x55, 0x4e, 0x61, 0x30, 0x15, 0x71, 0x7a, 0x19, 0xd9, 0x79, 0x78, 0x9a, 0x9e, 0xd8, 0xed, 0x9e, 0x24, 0x2c, 0x6b, 0x7d, 0x8c, 0x2c, 0x3c, 0x70, 0x5d, 0x16, 0x56, 0x19, 0x0c, 0xac, 0xde, 0x76, 0xef, 0xb3, 0xaa, 0xe7, 0xac, 0xac, 0x27, 0x75, 0xd9, 0xb9, 0x47, 0x4d, 0x86, 0x8d, 0xdd, 0xc5, 0xd6, 0x70, 0xd1, 0xd3, 0x00, 0xfa, 0xf6, 0x84, 0x60, 0x16, 0x53, 0x4b, 0x35, 0x74, 0xd9, 0x0d, 0xd5, 0xa1, 0x13, 0x1a, 0x08, 0xdd, 0x73, 0x9b, 0xf0, 0x44, 0xf3, 0xdd, 0x0a, 0x5b, 0xbb, 0x01, 0xf1, 0x74, 0x81, 0x79, 0x4d, 0x80, 0x5f, 0xfd, 0x0d, 0x7a, 0x1b, 0x7b, 0x78, 0xde, 0x1a, 0x95, 0x53, 0xf1, 0xf7, 0x91, 0x5d, 0xac, 0xa2, 0x53, 0x10, 0xe8, 0xd0, 0x86, 0x77, 0x83, 0x6f, 0x92, 0x0b, 0x84, 0x6c, 0xb3, 0x1a, 0xfa, 0x14, 0x25, 0xbb, 0x72, 0xbc, 0xd1, 0xa9, 0xae, 0xc0, 0xb8, 0x1b, 0x42, 0x32, 0x25, 0x30, 0xc2, 0xfa, 0xb1, 0x63, 0xbf, 0x7e, 0x81, 0xb8, 0xa9, 0x0a, 0x8c, 0x18, 0x1b, 0x44, 0x02, 0xa8, 0xe3, 0xc0, 0xff, 0xbf, 0x62, 0xf0, 0x18, 0x08, 0xdc, 0xfa, 0x0a, 0xe6, 0x1c, 0x04, 0xff, 0xd8, 0x08, 0x0c, 0x08, 0x62, 0xaf, 0x3c, 0x0e, 0xde, 0x24, 0x54, 0x47, 0x3e, 0x2c, 0x8c, 0xec, 0xe7, 0xcd, 0x5a, 0x04, 0x90, 0x7a, 0x70, 0x6f, 0x66, 0x44, 0xab, 0x57, 0x08, 0x70, 0x17, 0xb8, 0xf0, 0xc2, 0xff, 0x2f, 0xa2, 0x2d, 0x6e, 0x5f, 0xbd, 0x8c, 0x8a, 0xf0, 0x28, 0x37, 0xff, 0x04, 0x01, 0x5f, 0xac, 0x11, 0x53, 0x25, 0xc1, 0x52, 0xf3, 0x27, 0xed, 0xac, 0x60, 0x99, 0xd8, 0x25, 0x8e, 0x54, 0x7f, 0x9c, 0xf1, 0x3f, 0x4e, 0xc8, 0x57, 0xf6, 0x2b, 0x2d, 0x6d, 0xe9, 0xa4, 0xd8, 0x4b, 0x2e, 0x7a, 0xc3, 0x63, 0xcd, 0xe1, 0xf0, 0xf0, 0x39, 0xf0, 0x0a, 0xbb, 0x0c, 0x82, 0xd3, 0x0e, 0x49, 0x9e, 0x22, 0xcb, 0x5c, 0xd7, 0x3d, 0xd3, 0x58, 0x76, 0x84, 0x2d, 0x8a, 0x5a, 0x02, 0xee, 0x2a, 0xbc, 0xc1, 0xc4, 0x57, 0x5d, 0x06, 0x04, 0x6c, 0x93, 0x70, 0x26, 0x2b, 0x5c, 0xc9, 0xff, 0x22, 0x51, 0x25, 0xa2, 0xec, 0xdc, 0x29, 0xf2, 0x72, 0x41, 0x8c, 0x47, 0x70, 0xa9, 0xe3, 0x4c, 0xf5, 0xef, 0x16, 0xbf, 0x6d, 0x7d, 0xc1, 0xad, 0x1f, 0x14, 0x9e, 0x86, 0x43, 0xd1, 0x7e, 0xac, 0x67, 0x6f, 0x4c, 0x84, 0xdc, 0x68, 0x25, 0xd3, 0xfc, 0x5f, 0x5e, 0x01, 0xb4, 0xe6, 0x6b, 0xf0, 0x19, 0x54, 0x5a, 0xc7, 0x1c, 0xff, 0x0b, 0x4a, 0x73, 0xda, 0xc4, 0xb5, 0xd4, 0x79, 0xc4, 0x79, 0x7c, 0x13, 0x61, 0xd4, 0x77, 0x86, 0x57, 0x90, 0x91, 0x4b, 0x27, 0x81, 0x2a, 0xd6, 0x52, 0x33, 0x04, 0x2e, 0xc5, 0xa9, 0x56, 0xbf, 0xbc, 0x44, 0x40, 0x0f, 0x6b, 0x92, 0xda, 0xb0, 0x39, 0xe5, 0x45, 0x51, 0x21, 0x5d, 0x26, 0xb4, 0x4e, 0xe5, 0x2f, 0x4e, 0x7a, 0x02, 0x7c, 0x20, 0xa0, 0xe3, 0x74, 0x8c, 0xdb, 0x76, 0xf2, 0xcd, 0xdc, 0x29, 0x13, 0x63, 0x84, 0x54, 0xe7, 0x3e, 0xb2, 0x14, 0xf4, 0x90, 0x98, 0x51, 0x67, 0x66, 0xbd, 0x36, 0xc7, 0x5f, 0x00, 0x61, 0x93, 0x30, 0xe5, 0x9f, 0xe9, 0xb1, 0x15, 0x4e, 0xf3, 0x55, 0x7b, 0x34, 0x41, 0xa4, 0xc0, 0xc1, 0xa7, 0xe3, 0x58, 0xb3, 0x6b, 0x13, 0x4e, 0xca, 0x54, 0xca, 0x31, 0xe7, 0xc3, 0x5b, 0xfa, 0x58, 0x83, 0x5e, 0xf5, 0x82, 0xe8, 0x67, 0xb8, 0x33, 0xe1, 0x71, 0x5d, 0x6c, 0xa9, 0xc1, 0x3a, 0x4a, 0x7f, 0xa7, 0x02, 0xac, 0x96, 0xc2, 0x06, 0x89, 0x0f, 0xd0, 0x13, 0x34, 0xd9, 0x12, 0x6c, 0xf7, 0x0f, 0xd0, 0x46, 0x29, 0x4a }; +constexpr AccessUnit ATRACX_BEGIN_OF_AU_SPLIT_EXPECTED_AU = { std::numeric_limits::max(), std::numeric_limits::max(), false, 0, {}, { 0x35, 0x1b, 0x6a, 0x2a, 0x8e, 0x4d, 0xf1, 0x87, 0x92, 0xa9, 0xff, 0x8c, 0x7f, 0xcc, 0x5c, 0x1c, 0x5a, 0x7a, 0x05, 0xdd } }; + +const std::vector AC3_BEGIN_OF_AU_SPLIT_STREAM = { 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xbd, 0x06, 0xe6, 0x81, 0xc1, 0x0d, 0x31, 0x00, 0x05, 0xbf, 0x21, 0x11, 0x00, 0x05, 0xb3, 0x65, 0x1e, 0x69, 0xb2, 0x30, 0x00, 0x00, 0x00, 0x6e, 0xc9, 0xfb, 0xc5, 0x67, 0xe9, 0x8d, 0x68, 0x46, 0x00, 0x0d, 0x37, 0x95, 0xba, 0x1f, 0xda, 0x13, 0x05, 0xa0, 0x64, 0xd4, 0x9f, 0x4f, 0xdb, 0x14, 0x4d, 0x18, 0x4e, 0xb1, 0x3c, 0x2c, 0x9e, 0xca, 0x40, 0x57, 0xbd, 0x5e, 0xce, 0xf5, 0xd7, 0xae, 0x0d, 0xce, 0x9f, 0x77, 0xc5, 0xbf, 0xff, 0x00, 0x19, 0xbf, 0xe2, 0x98, 0x6a, 0x77, 0xd7, 0x78, 0x6a, 0xe4, 0x97, 0x5a, 0x98, 0xd1, 0xe2, 0x55, 0x64, 0xff, 0x08, 0x0b, 0xe5, 0xab, 0x41, 0xb5, 0x30, 0x25, 0xa9, 0x10, 0xd4, 0x4c, 0xd6, 0x33, 0xb0, 0x14, 0x2d, 0x2e, 0xb4, 0xc8, 0x9b, 0x5b, 0x9b, 0xd8, 0x1a, 0x88, 0xab, 0xf2, 0xdb, 0x6f, 0xc1, 0x99, 0xd6, 0x5c, 0x3a, 0xc5, 0xcf, 0xf7, 0x30, 0x90, 0x76, 0x26, 0x8f, 0x22, 0x20, 0xc7, 0xdb, 0xec, 0xad, 0xee, 0x45, 0x12, 0x52, 0x01, 0x8e, 0x1c, 0xa7, 0xb5, 0x71, 0x76, 0x33, 0x44, 0xf8, 0x54, 0xf6, 0x5c, 0x92, 0x38, 0xfc, 0xf3, 0x2d, 0x53, 0x73, 0xbe, 0x7a, 0x7d, 0x26, 0xb1, 0x93, 0xda, 0x46, 0xae, 0xae, 0xf2, 0xc7, 0x1c, 0xc2, 0x57, 0xfd, 0x5d, 0xaf, 0xdd, 0xf0, 0x4d, 0xad, 0xb6, 0x70, 0x8c, 0x09, 0xd7, 0xbd, 0x53, 0x9e, 0xbc, 0x64, 0x78, 0x0d, 0xe0, 0x7d, 0xf9, 0xd7, 0x6f, 0xf9, 0x31, 0x71, 0xc5, 0xef, 0xfe, 0xaf, 0x50, 0x74, 0x3a, 0x62, 0x82, 0x4f, 0x72, 0x9d, 0x68, 0xf7, 0x12, 0xd9, 0x3a, 0x0e, 0xc9, 0x77, 0x86, 0x9d, 0xe8, 0x86, 0x78, 0x03, 0xc2, 0x1a, 0x97, 0xa8, 0xfc, 0xac, 0x41, 0x9f, 0x58, 0x5c, 0x33, 0xf0, 0x04, 0x11, 0xd6, 0x8d, 0x09, 0x5e, 0xb3, 0xee, 0x99, 0x89, 0x33, 0xdc, 0x76, 0x4a, 0xf5, 0x4a, 0xb7, 0x14, 0x95, 0x31, 0x7e, 0x0f, 0xf4, 0xac, 0x89, 0xdb, 0x24, 0x9b, 0x92, 0x08, 0x3b, 0xca, 0xd4, 0x87, 0x84, 0x65, 0xad, 0x8b, 0x77, 0xb7, 0x81, 0xec, 0x1b, 0xcd, 0x9f, 0x8f, 0x38, 0x65, 0xbe, 0xda, 0x7a, 0x78, 0x9a, 0xbf, 0x9a, 0xc7, 0x24, 0x97, 0x37, 0x6b, 0x56, 0x30, 0xc4, 0xa9, 0xe7, 0xd1, 0x15, 0x47, 0xe6, 0x8d, 0xce, 0x25, 0xc6, 0xc3, 0x2c, 0xb9, 0xa1, 0x65, 0xda, 0x26, 0x25, 0x5c, 0x66, 0x22, 0x95, 0x5d, 0xa4, 0xcb, 0x9c, 0x72, 0xd5, 0xd6, 0xd6, 0x02, 0xe9, 0xa2, 0x10, 0xe7, 0xf6, 0xbe, 0x10, 0x03, 0x1a, 0xee, 0xdb, 0x60, 0xc2, 0x0f, 0x09, 0x1c, 0x56, 0x48, 0x04, 0x72, 0x95, 0x5d, 0x88, 0x7d, 0x77, 0xe0, 0x22, 0x3d, 0xc9, 0x15, 0x3f, 0x9c, 0x12, 0x9f, 0xf2, 0xcc, 0xc7, 0xc5, 0xb8, 0x1c, 0x76, 0x26, 0x87, 0x61, 0x3b, 0xe2, 0x31, 0x22, 0x33, 0x4e, 0x3f, 0xb1, 0x7f, 0x2d, 0x31, 0xd7, 0x0f, 0x93, 0x1d, 0x91, 0xc2, 0x3a, 0xb1, 0xdb, 0xbe, 0xf3, 0x16, 0x5a, 0x64, 0x52, 0x3d, 0x33, 0x7b, 0x6c, 0xa9, 0xf2, 0x26, 0x69, 0xb7, 0xb8, 0xcd, 0x1d, 0xde, 0x8b, 0x88, 0xc5, 0xdc, 0x55, 0x05, 0x6f, 0x17, 0x61, 0x60, 0x44, 0xf8, 0x87, 0xba, 0xd2, 0xa3, 0x66, 0x00, 0xf5, 0x4d, 0xc1, 0x74, 0x6d, 0x51, 0x5b, 0x3d, 0x95, 0xbb, 0x89, 0xb5, 0xf5, 0x05, 0xf5, 0x67, 0x65, 0x2a, 0xc8, 0x86, 0xe6, 0x45, 0x10, 0x09, 0x81, 0xce, 0x19, 0x94, 0x57, 0xe1, 0xeb, 0xde, 0xa9, 0xda, 0x44, 0xd6, 0x33, 0xd5, 0xaf, 0x2c, 0x77, 0xa5, 0x2d, 0xe9, 0xa7, 0xce, 0xe5, 0xc2, 0x49, 0x30, 0x53, 0x04, 0x1d, 0xa9, 0xa3, 0xf4, 0x8e, 0x05, 0xf1, 0x8a, 0x7f, 0x0d, 0xc4, 0x0f, 0x80, 0x0f, 0x67, 0x29, 0x44, 0x17, 0x7d, 0x4d, 0x28, 0x20, 0xf2, 0x05, 0xcd, 0x33, 0x05, 0xac, 0x5d, 0x65, 0xbd, 0xe3, 0x5e, 0xdc, 0x08, 0xf4, 0x80, 0x11, 0x73, 0x39, 0x31, 0x15, 0xe1, 0x24, 0xd0, 0x4d, 0xd5, 0xf5, 0xa4, 0x02, 0x84, 0x34, 0x74, 0x25, 0x7c, 0x4e, 0x4a, 0x93, 0xa6, 0x84, 0x38, 0x88, 0x0a, 0x07, 0x68, 0xab, 0xa2, 0xe9, 0x06, 0x86, 0xfc, 0x17, 0x3b, 0x2d, 0xf6, 0xef, 0x99, 0x41, 0xdc, 0x35, 0xb2, 0xb2, 0x0a, 0x00, 0x11, 0xcb, 0x26, 0x8a, 0xa1, 0xab, 0xe1, 0xea, 0x40, 0xb2, 0xa6, 0xf2, 0x6d, 0x19, 0x8a, 0xb1, 0x57, 0xe4, 0x27, 0xb5, 0x4e, 0x11, 0xa8, 0xc5, 0x39, 0x44, 0xca, 0x6b, 0x8c, 0xfa, 0x35, 0x19, 0xfa, 0x91, 0xfe, 0xb5, 0xc8, 0x5b, 0xc4, 0x42, 0x39, 0x8a, 0xfe, 0x4e, 0xd3, 0x8b, 0xcc, 0x80, 0xf0, 0x15, 0xa1, 0xa8, 0x61, 0x2a, 0xb2, 0x4a, 0x7c, 0xf3, 0x0e, 0xda, 0x91, 0xfa, 0x30, 0xdf, 0x21, 0xda, 0x43, 0x42, 0x21, 0xf4, 0x5a, 0x89, 0xcc, 0xef, 0xda, 0xb3, 0xae, 0x16, 0xc8, 0x98, 0xc9, 0x47, 0xc5, 0xf0, 0x6a, 0xac, 0xaf, 0x16, 0x6b, 0x44, 0x77, 0xa6, 0x89, 0x87, 0x3d, 0x21, 0xb8, 0x2e, 0x4a, 0xc2, 0x53, 0xe7, 0xdc, 0x2f, 0x93, 0x35, 0x37, 0xf7, 0xf3, 0x83, 0xdf, 0xa2, 0x56, 0x14, 0x43, 0x4e, 0x0e, 0x8d, 0x09, 0x5c, 0x6c, 0x5b, 0x63, 0xbc, 0xe8, 0xa1, 0x55, 0x0b, 0x66, 0xdd, 0x44, 0x2e, 0x16, 0x08, 0xf2, 0x96, 0x28, 0x71, 0x28, 0xa3, 0xe8, 0xb8, 0x4a, 0xfb, 0x22, 0x00, 0xbe, 0x01, 0x79, 0x2d, 0x82, 0x88, 0xb7, 0xfa, 0xcb, 0xe0, 0xdf, 0x22, 0xe0, 0x8b, 0xe1, 0x78, 0xcb, 0x08, 0xd1, 0x2e, 0x93, 0xf7, 0x28, 0xbc, 0x43, 0x27, 0x57, 0x55, 0x2c, 0x11, 0x81, 0xe0, 0xc6, 0xd6, 0x28, 0x60, 0x80, 0x66, 0x01, 0x68, 0x47, 0x7b, 0x7b, 0x83, 0xa3, 0x0c, 0x34, 0x9b, 0x3b, 0x54, 0xc6, 0x59, 0x38, 0x56, 0x22, 0xc9, 0xa1, 0xc6, 0x7f, 0xc5, 0x1a, 0x77, 0xec, 0x13, 0x90, 0x2d, 0x56, 0x16, 0x59, 0x6a, 0x26, 0x48, 0x81, 0x3a, 0x25, 0xfe, 0xd2, 0x08, 0x7f, 0x04, 0x10, 0xd1, 0x48, 0xa1, 0x08, 0x26, 0xb8, 0x6f, 0x5a, 0xbe, 0x93, 0x77, 0x6f, 0x9e, 0x8c, 0x2d, 0x5f, 0xf6, 0xf0, 0xa0, 0x72, 0xa3, 0xad, 0x5e, 0x8b, 0x7a, 0x84, 0x47, 0x49, 0xcc, 0x72, 0xf8, 0x5e, 0x5a, 0xdf, 0x62, 0x11, 0x5c, 0x25, 0x8d, 0xde, 0x32, 0x00, 0x3b, 0x0f, 0xe1, 0x26, 0x7b, 0x93, 0xa9, 0xf1, 0x4c, 0x1b, 0x7e, 0x98, 0x14, 0xc8, 0xbf, 0x79, 0x34, 0x93, 0x6c, 0x9f, 0x8c, 0x9d, 0x98, 0x17, 0x40, 0x14, 0x9f, 0x9d, 0x09, 0x07, 0xd2, 0x3f, 0x9f, 0x25, 0xa9, 0x4c, 0x3b, 0x3f, 0x5c, 0x94, 0x7b, 0xa8, 0x49, 0x29, 0x6c, 0xd9, 0xc2, 0x26, 0xe7, 0xce, 0x90, 0x20, 0x96, 0x5e, 0xd8, 0x87, 0x2e, 0x02, 0xf8, 0xc4, 0xf2, 0xf2, 0x3e, 0x0b, 0x9f, 0x1c, 0xcc, 0x4b, 0x3f, 0x7d, 0x56, 0x41, 0xb3, 0x47, 0xbb, 0xd7, 0x52, 0xc4, 0xdd, 0x0f, 0xeb, 0x4c, 0xd8, 0x84, 0x3e, 0xdd, 0xd9, 0xad, 0xc3, 0xf2, 0xdc, 0xaa, 0xd9, 0xfd, 0x19, 0xdc, 0xf1, 0x02, 0xb4, 0x6e, 0xdd, 0xe5, 0x99, 0xc2, 0x09, 0xbc, 0x98, 0x6a, 0x48, 0xcb, 0x49, 0x89, 0x8c, 0xd2, 0x59, 0x4e, 0x55, 0xbc, 0x6b, 0xee, 0x1d, 0xf4, 0x30, 0x91, 0x67, 0x27, 0x05, 0x55, 0x97, 0xb9, 0x68, 0x52, 0x82, 0xc3, 0x57, 0xd1, 0xf7, 0xee, 0xd4, 0x80, 0x12, 0xd1, 0x6c, 0xa7, 0x03, 0xc9, 0x10, 0x63, 0xce, 0x20, 0x63, 0x05, 0x03, 0x77, 0xdc, 0xe2, 0xe3, 0x37, 0x6d, 0x43, 0x47, 0xd6, 0x83, 0xea, 0x09, 0xdf, 0xd3, 0x57, 0x86, 0x86, 0xee, 0x86, 0x01, 0x6b, 0x5e, 0xe9, 0x24, 0x5e, 0x6f, 0x8a, 0xba, 0xda, 0x79, 0x44, 0x0d, 0x42, 0xe6, 0x69, 0x43, 0xb3, 0x5d, 0xc4, 0x9a, 0x2d, 0x87, 0x5e, 0xb2, 0x4c, 0xb4, 0xe8, 0x06, 0x02, 0x73, 0x3f, 0x8e, 0x15, 0x37, 0x68, 0x8c, 0x97, 0x14, 0xb2, 0xbc, 0x28, 0x4c, 0xb9, 0x09, 0x4b, 0x7b, 0xae, 0xf6, 0x08, 0xd1, 0xf2, 0x2f, 0x0b, 0x98, 0x2a, 0xb0, 0xeb, 0xed, 0xf8, 0x71, 0xd9, 0x5b, 0xdf, 0xdd, 0x87, 0x9b, 0xdf, 0x2a, 0x62, 0x8a, 0x00, 0x4b, 0x03, 0xae, 0x37, 0x38, 0xf1, 0x94, 0x59, 0x1b, 0x2e, 0x79, 0x56, 0x8d, 0xcc, 0x36, 0xe5, 0xcc, 0xec, 0x50, 0x38, 0x37, 0x15, 0xb8, 0x84, 0x07, 0x5a, 0x6e, 0xb1, 0xda, 0xa1, 0x52, 0xe6, 0x32, 0x08, 0x4a, 0x91, 0xce, 0x0e, 0x2e, 0x78, 0xe2, 0xcc, 0xac, 0xb3, 0xc1, 0xeb, 0xce, 0x3e, 0x51, 0x21, 0x18, 0x5d, 0x96, 0xf9, 0x31, 0x18, 0xab, 0x54, 0x67, 0x61, 0xa5, 0x5c, 0x5b, 0x4b, 0x27, 0xa4, 0x61, 0xe1, 0x82, 0x58, 0xfd, 0xa7, 0x18, 0x1c, 0x8e, 0xdc, 0xbe, 0xd3, 0xdf, 0x3f, 0xdf, 0x2e, 0xbf, 0xe5, 0x5c, 0xb1, 0x5a, 0xcf, 0x49, 0xac, 0x66, 0x3b, 0x90, 0xf0, 0xba, 0x41, 0x3f, 0x6d, 0x4f, 0x1c, 0x60, 0x27, 0x76, 0xfe, 0x1a, 0xbf, 0x32, 0x8c, 0x81, 0xec, 0xe0, 0x56, 0xd3, 0x8b, 0xac, 0x17, 0x67, 0x7e, 0x8b, 0x22, 0x4a, 0x61, 0x38, 0xf8, 0xa6, 0x37, 0xcb, 0x1f, 0x29, 0x80, 0x0b, 0x48, 0x19, 0xff, 0x9f, 0x83, 0x48, 0x83, 0x62, 0x33, 0xa6, 0xd8, 0xac, 0xf7, 0xe8, 0x10, 0x01, 0xea, 0x6d, 0x0b, 0x2f, 0x2d, 0x57, 0x02, 0x89, 0xcc, 0x07, 0x2a, 0x79, 0x6d, 0x22, 0x1f, 0x1c, 0xb8, 0xe8, 0x89, 0xcb, 0x24, 0x3a, 0x90, 0x30, 0xd2, 0xc1, 0xf1, 0x6f, 0x26, 0xea, 0x91, 0xfb, 0xcb, 0xa1, 0xb1, 0x0f, 0xd9, 0x22, 0xd9, 0x53, 0x14, 0xa2, 0x12, 0x8c, 0x0f, 0x9a, 0x38, 0x53, 0x34, 0x43, 0x54, 0x77, 0x6c, 0x60, 0xc0, 0xca, 0xf2, 0x88, 0xc0, 0xba, 0x96, 0x15, 0xf7, 0xd9, 0x11, 0x44, 0x5b, 0x57, 0x9b, 0xc9, 0x72, 0x6d, 0x93, 0xda, 0xc6, 0xaa, 0xb2, 0x01, 0x0b, 0x0e, 0x44, 0x0d, 0xb4, 0x1e, 0xff, 0xf4, 0x7e, 0x3e, 0xe3, 0x1a, 0xa1, 0xae, 0x5c, 0x02, 0xe4, 0x89, 0x29, 0x56, 0x4d, 0xc8, 0x13, 0x43, 0x56, 0x72, 0x65, 0xda, 0x4f, 0x2a, 0xb4, 0xb9, 0x7a, 0x6a, 0x93, 0x1c, 0x23, 0x6d, 0x77, 0x19, 0x82, 0x26, 0x2e, 0xc0, 0x5c, 0x9c, 0x5c, 0x2f, 0xeb, 0x19, 0x19, 0x7a, 0x62, 0x3b, 0x0f, 0xa5, 0xde, 0xb6, 0x56, 0x68, 0xb3, 0x06, 0x01, 0x81, 0x1d, 0x89, 0x23, 0xd5, 0xa4, 0xa1, 0xd6, 0xd2, 0x81, 0x0d, 0x0e, 0xcf, 0xb7, 0x5d, 0xe8, 0x57, 0x78, 0xbc, 0x09, 0x5d, 0xd4, 0x0f, 0x91, 0x66, 0xad, 0x4f, 0xc3, 0x0b, 0x37, 0x9d, 0x7d, 0xb5, 0x3d, 0xc5, 0x66, 0x63, 0x49, 0x40, 0xa8, 0x85, 0xcb, 0x4b, 0x74, 0xec, 0x4d, 0xc9, 0xee, 0x0f, 0xc4, 0xf8, 0x73, 0x29, 0xf2, 0x5e, 0xa0, 0x84, 0x95, 0x7f, 0x98, 0x65, 0x9f, 0x20, 0x1d, 0x12, 0x60, 0x9a, 0xec, 0x33, 0xf5, 0x66, 0x33, 0x32, 0xa8, 0x98, 0x7c, 0x91, 0xf5, 0x9f, 0x63, 0xeb, 0xf1, 0x77, 0x1c, 0xc6, 0x0f, 0x15, 0xc7, 0x18, 0xf8, 0x38, 0xe1, 0x87, 0x2b, 0xaf, 0x89, 0x1d, 0xb4, 0xe2, 0x76, 0x35, 0x51, 0x02, 0xf6, 0x4e, 0xd5, 0xd3, 0xda, 0xbe, 0x03, 0x3a, 0x0d, 0xaa, 0xf0, 0xe9, 0x0e, 0x3a, 0xaa, 0x5f, 0x8f, 0x56, 0x2e, 0x08, 0x10, 0x3c, 0x37, 0x81, 0xae, 0xfc, 0xae, 0x21, 0x44, 0x92, 0x88, 0x4f, 0xd8, 0x98, 0xf7, 0x08, 0x1c, 0x37, 0x62, 0xb5, 0xad, 0x4b, 0x03, 0x63, 0x4a, 0x05, 0x65, 0x31, 0xf8, 0xd6, 0x3c, 0x26, 0x6c, 0xf4, 0x26, 0x08, 0xaa, 0xfe, 0x5c, 0xb7, 0x62, 0x73, 0x1e, 0xc8, 0x48, 0xcf, 0x04, 0xb8, 0x16, 0x7c, 0x27, 0x91, 0x45, 0x7a, 0x88, 0xb8, 0x0f, 0xa3, 0x7f, 0x00, 0x4f, 0xf3, 0xc7, 0x09, 0xef, 0x99, 0xae, 0x05, 0x93, 0x6a, 0xd5, 0xd7, 0x2f, 0x94, 0xc8, 0xb5, 0x5a, 0x87, 0x7b, 0xaf, 0x7c, 0x62, 0xe5, 0x85, 0x3a, 0x95, 0x58, 0xeb, 0xf0, 0x77, 0x6b, 0x97, 0x4a, 0xc7, 0xb8, 0xc8, 0x36, 0x0e, 0x8f, 0xf5, 0x61, 0x82, 0xcf, 0x91, 0x4b, 0xd5, 0x76, 0xab, 0xb6, 0x00, 0x92, 0xcd, 0x6c, 0x71, 0x69, 0x7a, 0x10, 0x9d, 0x0b, 0xa8, 0xff, 0x34, 0x4c, 0x7f, 0xab, 0x4e, 0xc2, 0x4f, 0xba, 0x4b, 0xe9, 0xe2, 0xc5, 0x8e, 0x18, 0xa1, 0x8f, 0x91, 0x3e, 0x38, 0x8b, 0x9a, 0xac, 0xe1, 0x4f, 0x67, 0xf7, 0x23, 0xab, 0x4f, 0xa7, 0x47, 0x72, 0xed, 0xfc, 0x90, 0xa0, 0x3a, 0x67, 0x69, 0x7d, 0xea, 0xa5, 0x70, 0x3b, 0x65, 0xc5, 0xb7, 0xa4, 0x30, 0x19, 0x8e, 0x10, 0x70, 0xe3, 0x8a, 0x79, 0xf6, 0xae, 0xa0, 0x51, 0x17, 0xfa, 0xdc, 0x93, 0xe7, 0x38, 0x81, 0xd0, 0xe2, 0xed, 0xf6, 0x23, 0x5e, 0xb4, 0x73, 0x09, 0x89, 0xf7, 0x9e, 0x18, 0x0e, 0x42, 0xdf, 0x74, 0x36, 0x9d, 0x28, 0xd6, 0xea, 0x8f, 0x6a, 0xfa, 0x03, 0x44, 0x1d, 0x0b, 0x70, 0x72, 0xea, 0x2c, 0x50, 0x8f, 0xcb, 0x58, 0x14, 0x7e, 0x3d, 0x4a, 0x2a, 0xbf, 0x1e, 0xf8, 0x94, 0xa8, 0x8b, 0xd9, 0xcd, 0x92, 0x19, 0xe0, 0x01, 0x49, 0xa2, 0x55, 0x4e, 0x28, 0xb0, 0x64, 0xf0, 0x7f, 0x4b, 0x2f, 0x5d, 0x96, 0xa7, 0x40, 0x54, 0x56, 0x1b, 0xe1, 0x13, 0x30, 0xa0, 0x48, 0x2c, 0xb6, 0x30, 0xe9, 0xc8, 0x0b, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xbd, 0x06, 0xe6, 0x81, 0xc1, 0x0d, 0xc3, 0xa9, 0xb9, 0x73, 0x50, 0xe3, 0x6a, 0x08, 0xb4, 0x2e, 0x64, 0x6d, 0x05, 0x30, 0x00, 0x00, 0x00, 0x77, 0x82, 0x23, 0x5c, 0x1a, 0x92, 0xad, 0x54, 0xb4, 0x09, 0xb7, 0x88, 0x9e, 0x52, 0x6e, 0x19, 0xc5, 0xfa, 0xfe, 0x28, 0x20, 0x5a, 0x4d, 0xcf, 0xd3, 0xbc, 0x46, 0xbe, 0x0e, 0x52, 0xef, 0x4d, 0xad, 0x71, 0xdb, 0x51, 0x79, 0x70, 0x29, 0xd9, 0x13, 0x91, 0x58, 0x41, 0x68, 0x62, 0x25, 0x52, 0xf9, 0x8e, 0xc9, 0xca, 0x46, 0x94, 0x70, 0xc4, 0xa4, 0x78, 0xad, 0xc5, 0xd4, 0x07, 0x07, 0x0f, 0xd5, 0x15, 0x7b, 0x4e, 0x8d, 0x13, 0x9f, 0x26, 0x02, 0xb1, 0x1a, 0x95, 0xc9, 0x89, 0xbc, 0x38, 0xbb, 0x3f, 0xb3, 0x41, 0x8e, 0xc9, 0x76, 0x7e, 0x97, 0xeb, 0xb3, 0xcc, 0x4a, 0x3b, 0xf9, 0x97, 0xbc, 0x7e, 0xd3, 0x9e, 0x6e, 0x0c, 0x76, 0x85, 0x6f, 0xff, 0x4a, 0x56, 0x67, 0xe7, 0x51, 0xc0, 0x91, 0xa0, 0xc9, 0xa8, 0xef, 0xe0, 0x98, 0x69, 0x41, 0x6b, 0x86, 0x16, 0x94, 0x2a, 0x37, 0x31, 0xfa, 0x54, 0x7d, 0x73, 0x6f, 0x81, 0xff, 0xdd, 0xc3, 0x8c, 0x89, 0xa6, 0xb7, 0x8f, 0xbf, 0x1d, 0x7c, 0xab, 0x18, 0xef, 0x49, 0x0b, 0xa1, 0x59, 0x42, 0x2d, 0x51, 0xec, 0x36, 0xdd, 0xb9, 0x24, 0x48, 0xee, 0xa4, 0xbb, 0x42, 0xfd, 0x5a, 0x27, 0x41, 0x70, 0xb7, 0xe5, 0x2c, 0xb7, 0x68, 0x62, 0x6c, 0x9c, 0xe0, 0x1c, 0xf0, 0x59, 0x1b, 0xd7, 0x8f, 0x0e, 0xc4, 0x9f, 0x55, 0x23, 0x3c, 0x8d, 0x4d, 0x6a, 0xbe, 0x10, 0xb4, 0xa9, 0x18, 0x9c, 0xd1, 0x23, 0x5f, 0xb8, 0x8f, 0xc0, 0x8e, 0x65, 0xec, 0x2c, 0x39, 0x10, 0x31, 0x0e, 0xb9, 0x5a, 0xad, 0xeb, 0x26, 0x1a, 0x62, 0xc1, 0xd4, 0xa2, 0xdf, 0x09, 0x2b, 0xc6, 0x8b, 0x0c, 0xa3, 0xf8, 0x0f, 0x21, 0xc3, 0x9a, 0x7f, 0x4d, 0xc3, 0xe8, 0xc9, 0xa5, 0x46, 0x67, 0xfc, 0x2d, 0x76, 0x85, 0xa4, 0x8a, 0xa7, 0x49, 0xed, 0xf8, 0x45, 0xb4, 0xab, 0xbe, 0x48, 0xff, 0xe1, 0x4c, 0x25, 0x0a, 0x2d, 0x85, 0x8b, 0x75, 0x1a, 0x7e, 0x21, 0xf6, 0xf5, 0x91, 0x12, 0xae, 0xc9, 0x9c, 0x27, 0x4e, 0x8f, 0x29, 0xd7, 0x01, 0xa1, 0x3c, 0x32, 0xf4, 0xda, 0xf7, 0x25, 0x24, 0xfa, 0xfb, 0x9c, 0xa5, 0x96, 0xd2, 0x99, 0x9c, 0xcf, 0xba, 0x12, 0x40, 0x93, 0x9b, 0xf3, 0x40, 0xf6, 0x86, 0xaf, 0xcd, 0xe7, 0x53, 0xa4, 0x7d, 0x02, 0xeb, 0x91, 0x1b, 0x8c, 0xbc, 0xe4, 0xfb, 0x7e, 0x3e, 0x40, 0x14, 0x0d, 0xe2, 0x79, 0x97, 0x18, 0x1c, 0x7d, 0x58, 0x9d, 0xe2, 0x9e, 0x83, 0x81, 0xf7, 0x23, 0x68, 0xae, 0xcd, 0x2f, 0x1f, 0x54, 0x8e, 0xbb, 0x4a, 0x41, 0xc9, 0x19, 0xfd, 0x93, 0xe9, 0x65, 0x4f, 0x2d, 0xaa, 0x1e, 0x04, 0x67, 0x99, 0xfa, 0xe4, 0x58, 0xe2, 0x03, 0x9d, 0xd0, 0x76, 0x2b, 0x69, 0x15, 0x23, 0x19, 0x13, 0x8d, 0xa5, 0x61, 0x08, 0x3b, 0x91, 0xe5, 0x64, 0xd1, 0xa8, 0xb7, 0xfb, 0xa5, 0xc6, 0xac, 0xd8, 0x2a, 0xf1, 0xbb, 0xb2, 0x40, 0x5a, 0x40, 0xab, 0x57, 0xcb, 0x96, 0x55, 0x41, 0x04, 0x90, 0x1f, 0x40, 0xe8, 0xc6, 0x05, 0xd0, 0x78, 0x16, 0x81, 0x6b, 0xe3, 0xbb, 0x8a, 0xc8, 0xd4, 0x61, 0x7b, 0x16, 0xef, 0x09, 0xf5, 0x38, 0x2f, 0xf4, 0xa0, 0x6f, 0x4d, 0x0b, 0x04, 0x47, 0xdd, 0xf9, 0x7f, 0x24, 0x6a, 0x21, 0x18, 0x2f, 0xcf, 0xc9, 0xba, 0x22, 0x11, 0xdb, 0x45, 0xbd, 0xe3, 0x20, 0x48, 0xac, 0xa2, 0x83, 0x5c, 0xa4, 0xbd, 0xb7, 0xc3, 0x08, 0xd0, 0x90, 0xb1, 0x6e, 0xce, 0x1c, 0x7f, 0xc1, 0xff, 0xed, 0x5d, 0xbd, 0x38, 0x26, 0x39, 0x97, 0x22, 0x26, 0xf4, 0x71, 0x80, 0xd6, 0xae, 0xf3, 0x17, 0x98, 0x30, 0x36, 0xf8, 0x53, 0xf3, 0x66, 0x93, 0xf3, 0x7c, 0x3d, 0x4b, 0x6d, 0x8b, 0xb0, 0xa1, 0x52, 0xb5, 0x33, 0x4f, 0x71, 0x93, 0xfa, 0x11, 0xd2, 0xb1, 0x70, 0x92, 0x20, 0x19, 0x83, 0x8f, 0xb5, 0xc0, 0xa0, 0x94, 0x5c, 0xcf, 0x85, 0xcd, 0x46, 0xef, 0x79, 0xb9, 0xd1, 0xdf, 0xaa, 0x87, 0x71, 0x8e, 0x8c, 0x0b, 0x50, 0x0f, 0x8f, 0x1d, 0x78, 0x1f, 0x89, 0x44, 0x37, 0x67, 0xe1, 0x9d, 0xb5, 0x88, 0xee, 0x07, 0xe6, 0x59, 0x87, 0xcf, 0x49, 0xce, 0xab, 0x3f, 0x59, 0x83, 0x4e, 0xe1, 0x49, 0x97, 0x05, 0x67, 0x03, 0xff, 0x1e, 0x4a, 0x00, 0xcc, 0x1d, 0x3c, 0x6f, 0x14, 0x70, 0xa7, 0x1d, 0xc0, 0x0c, 0x02, 0x49, 0x62, 0xb6, 0x18, 0xaf, 0x08, 0xb4, 0xf7, 0xe8, 0xfe, 0x1c, 0x1c, 0x07, 0x1e, 0x13, 0x4d, 0xbd, 0x5d, 0x98, 0x02, 0x31, 0xb0, 0x88, 0x69, 0x14, 0x0e, 0x75, 0xa0, 0xc0, 0xb8, 0x0e, 0xe2, 0xe7, 0x43, 0x43, 0x80, 0x9b, 0x3a, 0x6e, 0xde, 0x33, 0xd7, 0xca, 0xba, 0x6e, 0x11, 0x56, 0x87, 0x71, 0x86, 0xa6, 0xf4, 0xf7, 0x43, 0xfe, 0x88, 0x76, 0xed, 0x65, 0x62, 0x2c, 0xc0, 0x93, 0xe5, 0x67, 0xf9, 0x03, 0xf3, 0x47, 0x14, 0xa3, 0xd6, 0xe5, 0x3e, 0x4d, 0xc4, 0x17, 0x4f, 0x20, 0xaf, 0x3e, 0x4a, 0x40, 0x4c, 0x1b, 0x77, 0x5b, 0x02, 0xac, 0x9e, 0xd6, 0x95, 0xf0, 0xf7, 0x49, 0xc8, 0x6e, 0x9b, 0x6d, 0x0f, 0x30, 0x48, 0x8a, 0x56, 0xcd, 0xd1, 0x73, 0x04, 0x97, 0x5a, 0x89, 0x17, 0x80, 0x0f, 0x60, 0x1a, 0x34, 0x77, 0x83, 0x57, 0x95, 0xda, 0x35, 0xda, 0x69, 0xef, 0xb8, 0x01, 0x31, 0x47, 0x4f, 0x19, 0x6f, 0x46, 0x0c, 0x3b, 0x8c, 0xe1, 0xb0, 0x47, 0x38, 0xe8, 0x72, 0x7d, 0x87, 0x14, 0x48, 0x46, 0x39, 0x35, 0x22, 0xc5, 0x53, 0x3f, 0x4e, 0x98, 0x81, 0xb5, 0x0c, 0x29, 0x5e, 0x0e, 0x28, 0x4e, 0xe1, 0x33, 0xb1, 0x8d, 0x22, 0x65, 0x24, 0x38, 0x2d, 0xac, 0xdf, 0xbc, 0x76, 0x67, 0xfe, 0x91, 0xae, 0x6f, 0x45, 0x1c, 0xce, 0xa8, 0xdc, 0xde, 0x96, 0x53, 0x49, 0xf9, 0x2b, 0x1a, 0xf9, 0x89, 0xe3, 0xff, 0xcc, 0x83, 0xbf, 0x09, 0xa5, 0x88, 0x26, 0xb4, 0x96, 0xd5, 0x1f, 0x12, 0x26, 0x5a, 0x5a, 0xd3, 0x82, 0xf1, 0xe0, 0xe3, 0x97, 0xf7, 0xc7, 0x5c, 0x1f, 0x80, 0x8b, 0x8e, 0x03, 0x7c, 0x51, 0x15, 0x10, 0x79, 0x36, 0x84, 0x3e, 0x58, 0xc7, 0xb5, 0x37, 0xa9, 0x8d, 0xb3, 0x1a, 0x32, 0xac, 0xc4, 0x49, 0xe1, 0xaa, 0xec, 0xd2, 0xe5, 0x8d, 0x26, 0x5b, 0x07, 0x4a, 0xb0, 0x09, 0xb8, 0x7a, 0x1b, 0x0e, 0xaf, 0x4f, 0x41, 0x4f, 0x8f, 0xf8, 0x70, 0x77, 0x36, 0x0c, 0x4f, 0x8c, 0xeb, 0xda, 0x67, 0x6a, 0xa8, 0x31, 0x01, 0x00, 0x08, 0x31, 0x72, 0x9b, 0xde, 0x2b, 0x4b, 0x2d, 0xad, 0x3c, 0x53, 0x55, 0x12, 0xb8, 0x24, 0xd8, 0xb4, 0xc1, 0xed, 0xad, 0x56, 0x5e, 0x93, 0x69, 0x3e, 0xf3, 0x4d, 0xf6, 0x60, 0xa0, 0x8e, 0x3f, 0xb7, 0x43, 0x30, 0x2a, 0xbd, 0x80, 0xf4, 0x5d, 0x2d, 0xb6, 0xa2, 0xab, 0x10, 0x06, 0xd5, 0xa7, 0xac, 0xb0, 0x7e, 0x41, 0xb9, 0x4b, 0xa5, 0x94, 0x5f, 0x90, 0xa1, 0x08, 0xd6, 0x38, 0x0a, 0x2d, 0xf9, 0xed, 0xa0, 0x94, 0x7f, 0xbe, 0xd4, 0xce, 0x04, 0xaf, 0xfa, 0xdb, 0x91, 0xb0, 0xc0, 0xa9, 0xf0, 0x6f, 0x30, 0x10, 0xab, 0x6c, 0xed, 0xa5, 0x50, 0x26, 0x12, 0x1f, 0x53, 0x0c, 0xc0, 0x0c, 0x29, 0x40, 0x4b, 0xff, 0x7e, 0x26, 0x42, 0x62, 0xfb, 0xe8, 0x9c, 0xf2, 0x27, 0xbb, 0xf8, 0xf3, 0xb2, 0x93, 0x37, 0x02, 0x32, 0x88, 0x24, 0x3d, 0x5f, 0x8a, 0x04, 0x8d, 0x9b, 0x08, 0x53, 0x3e, 0x30, 0xba, 0x32, 0x25, 0x0a, 0x3f, 0x81, 0x1e, 0xf2, 0x16, 0x74, 0xf0, 0x37, 0x4d, 0x69, 0x49, 0x87, 0xa0, 0x77, 0xb5, 0x87, 0xbf, 0x5d, 0x72, 0x7b, 0xf0, 0x61, 0x73, 0xa8, 0xb3, 0x18, 0x09, 0xce, 0x29, 0x78, 0x8e, 0x48, 0xdf, 0x2a, 0xd7, 0x23, 0xa9, 0xaf, 0x46, 0x43, 0xbb, 0x9b, 0xdb, 0x06, 0x2d, 0xaf, 0x6a, 0x16, 0x15, 0x74, 0x24, 0xe5, 0xa6, 0xc8, 0x39, 0x47, 0xb3, 0x43, 0x62, 0xc9, 0xdb, 0x75, 0xc1, 0x06, 0xad, 0xee, 0x08, 0x47, 0xf5, 0x77, 0xae, 0x3d, 0x50, 0x96, 0x4f, 0x24, 0x20, 0x6b, 0x52, 0x03, 0x80, 0x72, 0x2b, 0xed, 0xdc, 0x9f, 0x24, 0xda, 0xe2, 0xba, 0x81, 0x87, 0xa9, 0x7d, 0xfc, 0x06, 0xd4, 0x23, 0xb5, 0x0a, 0x52, 0x94, 0xc7, 0x63, 0xe7, 0x51, 0xad, 0x1e, 0xac, 0xa6, 0xbe, 0x8f, 0xd2, 0x9d, 0xe5, 0xb8, 0xa3, 0xdf, 0x99, 0x7a, 0xe7, 0x5e, 0x06, 0x38, 0x70, 0x5b, 0x4d, 0x27, 0x03, 0x2c, 0xa8, 0x0a, 0x3f, 0x93, 0xbb, 0x38, 0x7e, 0xae, 0xab, 0x9a, 0x7b, 0xd2, 0xc9, 0x8b, 0x53, 0xee, 0xcb, 0x80, 0x6f, 0x1d, 0x83, 0xdd, 0x81, 0xb8, 0xa0, 0xb9, 0xb6, 0xdc, 0x5e, 0xf1, 0x6b, 0x54, 0x0d, 0x32, 0xd7, 0xb0, 0xd5, 0x2b, 0xa2, 0xe5, 0xf7, 0x18, 0xa5, 0x28, 0x54, 0xb6, 0x7c, 0xea, 0x47, 0x8c, 0x7a, 0xb5, 0xce, 0x9d, 0x0f, 0xd8, 0x89, 0xfa, 0xd7, 0x21, 0xd8, 0x4b, 0x14, 0x5a, 0x86, 0x32, 0xd1, 0x40, 0x21, 0x75, 0x4b, 0xbf, 0x1c, 0x66, 0x54, 0x84, 0xb2, 0x1f, 0xd4, 0x32, 0x06, 0x7a, 0x52, 0x1f, 0x7d, 0xd8, 0x59, 0x99, 0x86, 0xb9, 0x6c, 0x26, 0xec, 0x5e, 0x74, 0x38, 0x5d, 0xb9, 0x38, 0xdd, 0xf6, 0x9c, 0x28, 0xbe, 0xb6, 0x87, 0xb7, 0xaf, 0x5b, 0x47, 0x7a, 0xbb, 0x79, 0x55, 0x53, 0x9c, 0xc1, 0x74, 0x73, 0x01, 0xde, 0xdf, 0xae, 0x0f, 0x63, 0xb2, 0xab, 0xc6, 0x01, 0x63, 0xea, 0xf2, 0xb5, 0x9a, 0x57, 0x2b, 0x62, 0x8b, 0x35, 0x21, 0x4d, 0xbc, 0x06, 0xb8, 0x7c, 0x31, 0x98, 0xc4, 0xbb, 0xd5, 0x83, 0x45, 0xd8, 0xc3, 0xa9, 0x2b, 0xab, 0x3e, 0x10, 0xfc, 0x60, 0x63, 0x6f, 0xbb, 0xbf, 0x90, 0x54, 0xe8, 0x63, 0x3f, 0x78, 0xf8, 0x8b, 0xa2, 0xa0, 0x75, 0x26, 0x21, 0x8d, 0xa4, 0xb2, 0xde, 0xa8, 0xaf, 0xb3, 0x3b, 0x65, 0x90, 0xac, 0xba, 0xad, 0x37, 0xac, 0xaf, 0x6a, 0xc1, 0x0a, 0x36, 0x5d, 0x95, 0x86, 0x13, 0x15, 0xbc, 0xf9, 0x7b, 0xc6, 0x62, 0x27, 0x88, 0xdb, 0x50, 0x16, 0x1a, 0x16, 0xe0, 0x5c, 0x3c, 0x0a, 0xf7, 0x5c, 0x69, 0xb8, 0xfe, 0x2a, 0x3c, 0x54, 0x3c, 0x57, 0x7e, 0xb5, 0xbb, 0x30, 0x32, 0x23, 0x59, 0x98, 0x0f, 0x83, 0x81, 0x3c, 0x2c, 0xaa, 0xdf, 0x28, 0xf3, 0xa0, 0x97, 0x28, 0xee, 0xad, 0x9a, 0xb5, 0x22, 0x2a, 0x43, 0x99, 0x51, 0x08, 0x82, 0x04, 0x9d, 0x9f, 0x56, 0x77, 0xfd, 0x8f, 0xaa, 0xb9, 0x17, 0xfb, 0xd0, 0x3b, 0x20, 0xc6, 0x31, 0xf4, 0x4f, 0x8b, 0x5d, 0x4b, 0x7c, 0x5e, 0x87, 0x9b, 0x75, 0x21, 0x31, 0x98, 0x05, 0xa8, 0x4c, 0xac, 0xde, 0x2b, 0x10, 0x4a, 0xc9, 0x79, 0x75, 0xd2, 0xb1, 0xf4, 0x23, 0x10, 0x80, 0x99, 0x52, 0xa6, 0x9c, 0xcb, 0x70, 0x75, 0xa2, 0x7a, 0x8b, 0x12, 0x50, 0xa4, 0x2c, 0x00, 0xe0, 0x86, 0x39, 0xda, 0x57, 0x10, 0x80, 0xe6, 0x4a, 0xc7, 0x0a, 0x9e, 0x40, 0x53, 0x22, 0xf3, 0xca, 0x19, 0x7c, 0xa2, 0xb2, 0xab, 0xa8, 0x2c, 0x32, 0xd5, 0x5e, 0xce, 0x54, 0x67, 0x02, 0x66, 0xe1, 0x00, 0x01, 0x60, 0xf8, 0xa5, 0x58, 0xd9, 0x44, 0x9d, 0xa2, 0x26, 0x2b, 0xd0, 0x9c, 0x99, 0xf3, 0x0c, 0x33, 0x57, 0xc0, 0xcf, 0x83, 0x02, 0xdb, 0x8f, 0x06, 0xa9, 0x12, 0x4b, 0xa9, 0x35, 0x00, 0x14, 0xab, 0xd5, 0x9f, 0x66, 0x4c, 0x57, 0xb8, 0xfc, 0xa9, 0x47, 0xb4, 0xae, 0xd3, 0xaa, 0xc8, 0x39, 0x70, 0x82, 0x93, 0x7d, 0xfb, 0xa3, 0x67, 0x33, 0x44, 0x2b, 0xf1, 0x09, 0xa7, 0x24, 0x5a, 0x66, 0x64, 0x72, 0xa3, 0xb8, 0x29, 0x65, 0xfc, 0xbe, 0xfa, 0xc9, 0x6b, 0x8e, 0x3d, 0xcf, 0x0f, 0x6f, 0x75, 0x30, 0xcf, 0xa7, 0x92, 0x7c, 0x5a, 0xcd, 0x0f, 0xd1, 0xcb, 0xa2, 0x9f, 0x75, 0xb9, 0x59, 0x67, 0x54, 0x24, 0xc0, 0xc1, 0x64, 0x14, 0xfa, 0xee, 0x14, 0xb8, 0x80, 0x56, 0x66, 0x18, 0xc3, 0xb4, 0xd2, 0x74, 0x83, 0x28, 0x8d, 0xe8, 0x1a, 0xb7, 0x5f, 0x6a, 0xb6, 0x9e, 0x2e, 0x27, 0xdd, 0xa1, 0xfb, 0xac, 0xeb, 0x9a, 0x76, 0xc3, 0x61, 0xf2, 0x2b, 0x70, 0x26, 0xf5, 0x35, 0x6b, 0x68, 0x12, 0x20, 0x1c, 0xa5, 0x6b, 0x51, 0x8a, 0xcc, 0xb4, 0xf8, 0x33, 0xbf, 0x00, 0x01, 0x46, 0x2d, 0x31, 0xc3, 0xd5, 0x98, 0x8f, 0xc5, 0x05, 0x39, 0x77, 0xde, 0x18, 0x8d, 0x0b, 0x77, 0x5a, 0x6a, 0x68, 0xe0, 0x27, 0x99, 0xdd, 0x6f, 0x79, 0x2c, 0xcb, 0x00, 0x9b, 0x1b, 0xf3, 0xf5, 0x76, 0x7b, 0x7c, 0xc2, 0xea, 0xb9, 0x60, 0xcc, 0x03, 0xbb, 0x9c, 0xa7, 0xc6, 0xad, 0x78, 0x26, 0xac, 0xa8, 0xfb, 0xdf, 0xaa, 0x1e, 0xab, 0x6f, 0x6c, 0xe3, 0xd6, 0x8f, 0x94, 0x5c, 0x30, 0x82, 0xba, 0xc9, 0xe5, 0xd2, 0x80, 0xe1, 0x30, 0xb4, 0x30, 0x24, 0xae, 0xb4, 0x6b, 0xcd, 0xf7, 0x17, 0x68, 0x65, 0x26, 0x0c, 0xa2, 0x8b, 0x9d, 0x7c, 0x03, 0xf2, 0xcd, 0xec, 0xee }; +constexpr AccessUnit AC3_BEGIN_OF_AU_SPLIT_EXPECTED_AU = { std::numeric_limits::max(), std::numeric_limits::max(), false, 0, {}, { 0xa6, 0x64, 0x73, 0xed, 0x20, 0xed, 0x51, 0x95, 0x8a, 0xc7, 0xee, 0xd3, 0x6f, 0x52, 0x8c, 0x0b, 0xcd, 0xe2, 0x4f, 0x51 } }; + + +const std::vector ATRACX_SIZE_MISMATCH_STREAM = { 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xbd, 0x06, 0xe6, 0x81, 0xc1, 0x0d, 0x31, 0x00, 0x05, 0xbf, 0x21, 0x11, 0x00, 0x05, 0xb3, 0x65, 0x1e, 0x69, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xd0, 0x00, 0xbf, 0xa6, 0x85, 0x42, 0x98, 0xc5, 0x19, 0x4a, 0xdc, 0xcf, 0x38, 0x32, 0x5d, 0x7d, 0x6f, 0x99, 0xb2, 0x66, 0x6a, 0x9c, 0xe6, 0x6d, 0xaa, 0x5a, 0xbc, 0xcb, 0x31, 0x5c, 0xc9, 0x53, 0x87, 0x6c, 0x69, 0x2d, 0x3e, 0x35, 0xe6, 0xba, 0x7b, 0x05, 0x66, 0xfe, 0xea, 0xfe, 0x76, 0x9e, 0x0e, 0x53, 0xfe, 0xdc, 0x52, 0x31, 0x7a, 0xea, 0x93, 0xab, 0x90, 0xba, 0x50, 0x17, 0xc9, 0xe8, 0xa4, 0xdc, 0x3a, 0x10, 0xdc, 0x91, 0xed, 0x0d, 0x95, 0xdd, 0x15, 0x21, 0x8e, 0xf3, 0xd3, 0xfc, 0x6b, 0xb5, 0xc6, 0xac, 0x63, 0x72, 0x78, 0x72, 0xfe, 0x04, 0xc3, 0x55, 0xa3, 0x65, 0x7e, 0x50, 0x83, 0xfe, 0x92, 0xdd, 0x47, 0xa0, 0x5b, 0x10, 0x8f, 0xb6, 0x30, 0xb6, 0xac, 0x5e, 0x9a, 0x0b, 0xb0, 0xea, 0x43, 0xcf, 0x4c, 0xc5, 0x64, 0xe1, 0x14, 0x58, 0x5e, 0x4a, 0x4b, 0xc5, 0x14, 0xf0, 0xe7, 0xbc, 0xeb, 0x10, 0xc5, 0xf1, 0x98, 0x25, 0xab, 0x77, 0x04, 0xb2, 0xaf, 0x2c, 0xa1, 0x7e, 0x3f, 0x59, 0x9d, 0x6d, 0xc0, 0x64, 0xea, 0x1d, 0x98, 0x8f, 0x00, 0xfd, 0xc5, 0x8e, 0x57, 0x38, 0x71, 0x64, 0x9f, 0xd7, 0x57, 0x7d, 0xc4, 0x6c, 0x0f, 0x15, 0x8d, 0x84, 0xaa, 0xf3, 0xef, 0xd2, 0x66, 0x5b, 0xc4, 0xf0, 0xcf, 0x6b, 0x89, 0xd5, 0x9b, 0x55, 0x87, 0x5d, 0x63, 0xf6, 0x24, 0x17, 0x28, 0x33, 0xb8, 0xcd, 0x78, 0x9f, 0x2c, 0x00, 0x91, 0xe1, 0x79, 0x45, 0xe6, 0x8b, 0x3e, 0xab, 0xf5, 0xc4, 0x98, 0x00, 0xb7, 0xc7, 0x2a, 0x34, 0x47, 0xd6, 0xd3, 0x29, 0xd2, 0x2b, 0x4c, 0x3f, 0x6e, 0x06, 0x43, 0x60, 0x60, 0x69, 0xf1, 0x1b, 0xd4, 0x3f, 0xb8, 0x47, 0x7f, 0x2f, 0xc9, 0x4b, 0x23, 0xdd, 0x83, 0x6e, 0x4f, 0x69, 0x21, 0xc4, 0x48, 0x98, 0x53, 0x81, 0xd9, 0xfa, 0xba, 0xb6, 0xf9, 0x38, 0x64, 0x27, 0x24, 0xc9, 0xcb, 0x5f, 0xd8, 0x4f, 0x97, 0x06, 0x8e, 0xce, 0xa2, 0x88, 0xe2, 0x8b, 0x4c, 0xb6, 0x76, 0x49, 0xf6, 0x0c, 0x2a, 0xab, 0x06, 0x59, 0xde, 0x51, 0x73, 0xd6, 0x33, 0xe7, 0x4a, 0x85, 0x4a, 0x46, 0x83, 0x4e, 0xe4, 0x73, 0x19, 0xc4, 0x6d, 0x3c, 0xea, 0x36, 0xb8, 0xdb, 0x0d, 0xc7, 0x67, 0xe3, 0x72, 0x52, 0x08, 0x9d, 0x88, 0xd4, 0xb2, 0xec, 0x24, 0x0b, 0x9f, 0x2a, 0x9c, 0x34, 0xf2, 0x20, 0x6d, 0x7a, 0xbd, 0x2e, 0x9c, 0x22, 0x52, 0x34, 0xc6, 0xa6, 0x7a, 0x88, 0x76, 0xe4, 0x7a, 0x6d, 0x23, 0xba, 0xd7, 0x12, 0x3f, 0xf3, 0x31, 0x8b, 0x6d, 0xd8, 0xdc, 0x23, 0xf1, 0x21, 0x45, 0xdb, 0x2b, 0x92, 0x3f, 0x52, 0xbc, 0xf6, 0x1f, 0x57, 0x91, 0x5c, 0xef, 0xde, 0x64, 0x60, 0xcb, 0xfc, 0x27, 0x54, 0x9b, 0xf3, 0x94, 0x6a, 0x88, 0xed, 0x7c, 0xaf, 0x0c, 0x01, 0xc6, 0xb6, 0xe1, 0x98, 0x61, 0xbd, 0x17, 0xd8, 0x41, 0xc3, 0x89, 0x81, 0x55, 0x01, 0x80, 0xb7, 0x39, 0x0e, 0x18, 0x46, 0xea, 0xdb, 0x41, 0x59, 0xc0, 0x89, 0x11, 0x49, 0x99, 0x37, 0xcb, 0x1f, 0xe5, 0x21, 0xbf, 0xa0, 0x4d, 0xf9, 0x48, 0x8d, 0xef, 0xb3, 0x48, 0x90, 0xa5, 0xa1, 0x6a, 0xd6, 0x2b, 0xf2, 0x7e, 0x55, 0x34, 0xa9, 0xe6, 0x44, 0x8d, 0x26, 0xf3, 0x4c, 0xe4, 0x2c, 0xe5, 0x95, 0xc4, 0x63, 0x1c, 0x8d, 0x44, 0x81, 0x6a, 0x11, 0x16, 0xa9, 0xe3, 0x26, 0x49, 0xe3, 0x24, 0x04, 0x5d, 0x2d, 0xe0, 0x50, 0xfd, 0x47, 0x4c, 0x47, 0xfa, 0x8a, 0xa8, 0xf5, 0x82, 0x45, 0xff, 0x13, 0xda, 0x71, 0x93, 0x3b, 0x1c, 0xcc, 0x04, 0x75, 0x17, 0x2f, 0x2e, 0x5d, 0x0f, 0xdd, 0x33, 0xfa, 0x9c, 0xfa, 0x50, 0x9e, 0xa8, 0x29, 0x84, 0xee, 0x9c, 0xb2, 0xb2, 0xc4, 0xa9, 0xc0, 0x85, 0xb1, 0x42, 0x54, 0x4c, 0xd2, 0x62, 0x0d, 0xa4, 0xdf, 0xb3, 0xb7, 0x70, 0xe4, 0x9e, 0x8e, 0xa1, 0x9d, 0x4c, 0x1d, 0xdd, 0xc5, 0xfa, 0x8e, 0x67, 0x06, 0x17, 0x7d, 0xc6, 0xef, 0xb4, 0x5c, 0x1b, 0xac, 0xfd, 0xf7, 0x89, 0x36, 0xd0, 0x45, 0xf5, 0x95, 0xaa, 0xad, 0x23, 0x61, 0x4f, 0xd5, 0xdb, 0x52, 0x83, 0xa0, 0xb3, 0xba, 0xd1, 0x66, 0x0d, 0xe0, 0xa2, 0xb9, 0xd6, 0x73, 0xfa, 0xed, 0xe6, 0x96, 0xaf, 0x8b, 0x27, 0xf9, 0xe9, 0x24, 0xcb, 0x18, 0xc2, 0xa3, 0x41, 0x70, 0x89, 0xe9, 0x99, 0xb4, 0x58, 0x53, 0x80, 0x79, 0x55, 0x60, 0x88, 0x1e, 0xd7, 0x5d, 0x06, 0x5d, 0x67, 0x16, 0x48, 0xef, 0x25, 0xff, 0x76, 0x1d, 0x76, 0x94, 0x73, 0xf4, 0x48, 0xcd, 0x88, 0x58, 0xda, 0x46, 0x26, 0xf2, 0x0a, 0x0e, 0xc5, 0x59, 0x1c, 0xc4, 0xbd, 0xae, 0x00, 0x90, 0xe2, 0xed, 0xc8, 0xe7, 0xc4, 0x36, 0x5c, 0x5f, 0x1a, 0x72, 0xce, 0xbe, 0x7f, 0x9a, 0x25, 0xf1, 0x7d, 0x62, 0x78, 0x21, 0xe9, 0x8a, 0xca, 0x6f, 0x08, 0x91, 0x26, 0x9c, 0xa8, 0xeb, 0xf4, 0x56, 0xc9, 0x4d, 0x04, 0xaa, 0x36, 0x05, 0x4f, 0x67, 0x03, 0xf0, 0x7d, 0xd5, 0x60, 0x19, 0xd9, 0x5d, 0xf7, 0x05, 0xa1, 0x7c, 0xe9, 0xa2, 0x5b, 0xc7, 0x9b, 0x8e, 0x3d, 0xae, 0xc5, 0x89, 0x06, 0x4a, 0x4e, 0x66, 0x7d, 0x22, 0xbc, 0x98, 0x54, 0x7e, 0x95, 0xa5, 0x6d, 0xce, 0x09, 0xbc, 0x8e, 0x59, 0xda, 0x34, 0x7d, 0x9e, 0x83, 0x99, 0xf6, 0x0b, 0xa3, 0x69, 0xc3, 0xf1, 0xc7, 0x50, 0x1a, 0xde, 0xe3, 0xe3, 0x85, 0xf2, 0xc5, 0x7f, 0x01, 0x96, 0xb9, 0x68, 0x83, 0xd8, 0xb6, 0x62, 0x12, 0x52, 0x09, 0xf0, 0xf6, 0x73, 0xad, 0xe4, 0x40, 0xaa, 0x21, 0x7b, 0x5c, 0xf7, 0x1a, 0x39, 0x7d, 0x41, 0xed, 0x9b, 0x42, 0x3a, 0x48, 0xa9, 0xac, 0x5c, 0x16, 0x9c, 0x52, 0x7b, 0xcb, 0x5b, 0x48, 0xf0, 0x3c, 0x30, 0xeb, 0xae, 0x9e, 0xc0, 0xc9, 0xa7, 0xb7, 0x18, 0x84, 0x4e, 0x55, 0x44, 0xe1, 0xf1, 0x2b, 0x80, 0xfd, 0x4f, 0x63, 0xa7, 0x57, 0x35, 0x39, 0xba, 0xaa, 0xb4, 0xc7, 0x22, 0x08, 0xed, 0x0e, 0x2a, 0x24, 0x83, 0x62, 0xc9, 0x59, 0x19, 0xec, 0xa5, 0xb7, 0x36, 0xff, 0x10, 0xe9, 0x67, 0x82, 0x27, 0x38, 0xdc, 0x66, 0x66, 0x4f, 0xb9, 0x03, 0xb3, 0xd8, 0x6f, 0xc4, 0x7f, 0x61, 0xac, 0x72, 0x29, 0x71, 0x4b, 0x49, 0x99, 0xbc, 0x01, 0x6c, 0x30, 0x78, 0x94, 0x06, 0x7d, 0xd6, 0x75, 0xbb, 0xa4, 0x1b, 0x4a, 0xc9, 0xd4, 0x6c, 0x41, 0x65, 0xac, 0x7f, 0x47, 0xf6, 0x59, 0x75, 0xda, 0xfe, 0x0c, 0xf6, 0xa9, 0xb2, 0xf3, 0xfb, 0xac, 0xdd, 0x77, 0x02, 0x3b, 0x28, 0xd4, 0x0b, 0xa1, 0x1e, 0x2c, 0xef, 0xf9, 0x0d, 0x5b, 0x31, 0x8c, 0xeb, 0xbe, 0x07, 0x19, 0x2b, 0x67, 0xb1, 0x78, 0xe9, 0x0e, 0x08, 0x20, 0x51, 0xf1, 0xc2, 0x55, 0xa1, 0x33, 0xfe, 0x28, 0xc2, 0x75, 0xc0, 0xeb, 0x41, 0x0b, 0xaa, 0x98, 0x98, 0x92, 0x1d, 0xd6, 0xbf, 0xbd, 0xa9, 0x9e, 0xc8, 0x34, 0xd8, 0xeb, 0x3b, 0x9a, 0x65, 0x8f, 0x5f, 0xdd, 0x0d, 0x8b, 0xc5, 0x77, 0x31, 0x1b, 0x04, 0x42, 0x97, 0x16, 0x96, 0x89, 0x39, 0xac, 0xc3, 0x06, 0xe8, 0x9d, 0x36, 0x83, 0xf9, 0x8d, 0x71, 0x83, 0xe2, 0x5c, 0x0e, 0xc1, 0xc0, 0x12, 0x21, 0x0e, 0xae, 0x40, 0x67, 0xbd, 0x0c, 0xe0, 0xf6, 0x8b, 0x18, 0x77, 0x1a, 0x19, 0x8f, 0x1b, 0x9f, 0x6e, 0x5b, 0xfa, 0xf7, 0xf5, 0x93, 0xaf, 0xe6, 0xd2, 0x80, 0x4d, 0x11, 0x33, 0xc6, 0xff, 0x0c, 0x1b, 0x92, 0x99, 0x2e, 0xc3, 0x33, 0xc1, 0x89, 0x51, 0x36, 0x35, 0xda, 0x52, 0x60, 0x7c, 0x94, 0x33, 0xff, 0xd8, 0x46, 0x70, 0xd5, 0x6d, 0x0f, 0x17, 0x42, 0x20, 0x50, 0xc7, 0xb6, 0xa4, 0xa9, 0x35, 0x91, 0x8b, 0x4c, 0xdf, 0xe4, 0xd1, 0x5d, 0xfc, 0x45, 0x27, 0x5a, 0x66, 0x99, 0x63, 0xa2, 0x6b, 0x01, 0x84, 0x7a, 0x28, 0x34, 0x74, 0x29, 0xa6, 0x1e, 0xbf, 0x47, 0x3a, 0x90, 0x93, 0x62, 0xc1, 0xf1, 0xbc, 0xd3, 0x8b, 0x16, 0x45, 0xd5, 0xd0, 0xf9, 0xab, 0x58, 0x75, 0x0e, 0xa2, 0x10, 0xfe, 0xa3, 0xcc, 0x56, 0x8b, 0x2a, 0x9d, 0x62, 0x9e, 0x80, 0x68, 0xd4, 0x35, 0xd8, 0xd5, 0x0d, 0x73, 0x2b, 0xac, 0x90, 0x0c, 0xbe, 0xd3, 0x36, 0xd7, 0x0b, 0xfc, 0x10, 0x0e, 0x3d, 0x49, 0x7b, 0xa8, 0x64, 0xad, 0xa5, 0x2f, 0x04, 0x8d, 0x9d, 0x42, 0xee, 0x7e, 0x24, 0xb6, 0xd8, 0x8a, 0x47, 0x23, 0x87, 0xf9, 0xee, 0x6d, 0x39, 0x5c, 0x4a, 0x7e, 0xdc, 0xfa, 0x03, 0x5f, 0xe9, 0x18, 0xbe, 0x0b, 0x12, 0x10, 0x64, 0xae, 0x5a, 0x17, 0x20, 0x41, 0xaf, 0x82, 0xb1, 0x6c, 0x14, 0xa8, 0x9b, 0x1e, 0x43, 0x7c, 0x45, 0x24, 0xe0, 0x81, 0xf5, 0x13, 0xe0, 0x92, 0xc1, 0x77, 0xb2, 0x7c, 0xd6, 0x54, 0xad, 0x8f, 0x69, 0x32, 0xcf, 0x87, 0x8e, 0x72, 0xa5, 0xac, 0x8c, 0x89, 0xec, 0x22, 0x99, 0x84, 0x08, 0x70, 0x9e, 0xcb, 0x48, 0x0d, 0xe3, 0x2e, 0x06, 0x16, 0xe3, 0x4a, 0x08, 0x24, 0xf7, 0xfb, 0xda, 0x91, 0x7b, 0xd5, 0x95, 0xf0, 0x8a, 0x2f, 0x23, 0x40, 0xaf, 0x64, 0x7b, 0xab, 0x46, 0x41, 0x49, 0x01, 0xd1, 0xd3, 0x08, 0xf9, 0x07, 0x69, 0x4d, 0x78, 0x69, 0xbf, 0x4c, 0x6c, 0x12, 0x7c, 0xb1, 0xc2, 0xaf, 0x7c, 0x23, 0x30, 0x29, 0x70, 0xc4, 0x79, 0xcc, 0x97, 0xe1, 0x23, 0x01, 0xeb, 0x02, 0xe8, 0x01, 0x53, 0xbb, 0x37, 0x3b, 0xf5, 0x46, 0x9e, 0x00, 0xba, 0xf6, 0x5d, 0xae, 0xeb, 0x02, 0xae, 0xf6, 0x45, 0x22, 0x00, 0xac, 0x7a, 0x3b, 0x53, 0xbd, 0x6a, 0x6c, 0x59, 0xd5, 0x24, 0x4a, 0xb3, 0x41, 0xf1, 0x27, 0x0f, 0x5e, 0x12, 0x33, 0x91, 0xad, 0xc8, 0xac, 0x2a, 0x06, 0x73, 0x5a, 0x94, 0x19, 0x7a, 0x8b, 0x0f, 0x8a, 0xd6, 0x86, 0x9d, 0x18, 0x22, 0x5f, 0x7d, 0x7d, 0xd9, 0x8e, 0x0f, 0x36, 0xcc, 0x6d, 0x39, 0xe9, 0x9d, 0xd7, 0xfd, 0xe3, 0xdc, 0xbe, 0xff, 0x72, 0x67, 0xa8, 0x27, 0xb8, 0x56, 0xcd, 0xde, 0x79, 0x11, 0x0d, 0xf7, 0x8e, 0xaf, 0xad, 0xd3, 0x32, 0x57, 0x2a, 0xb0, 0xaa, 0xe5, 0xf3, 0x9a, 0xc4, 0xa6, 0x62, 0x89, 0x53, 0x5a, 0x89, 0xd7, 0x04, 0x96, 0xfd, 0x3d, 0x78, 0x61, 0x44, 0xfe, 0x43, 0x8d, 0xda, 0x00, 0xc2, 0x95, 0xcf, 0x4d, 0x6b, 0xd4, 0x17, 0x0d, 0xec, 0x4a, 0x84, 0x1c, 0xc1, 0x6f, 0x29, 0xe5, 0xf8, 0x40, 0x1a, 0x5f, 0x29, 0x97, 0x7a, 0xa3, 0x1c, 0x2d, 0x7a, 0x31, 0x9b, 0xd1, 0x7f, 0x44, 0x0b, 0x7d, 0xa9, 0xbf, 0xb8, 0xf8, 0xdb, 0x2b, 0x94, 0x32, 0x21, 0xa5, 0x8f, 0xb8, 0x13, 0x13, 0x43, 0x84, 0x18, 0x90, 0xc9, 0x0c, 0x5a, 0x6d, 0x07, 0x8b, 0xff, 0xe1, 0x67, 0xec, 0x10, 0x51, 0x25, 0xe3, 0x2a, 0xd9, 0x7a, 0xaa, 0x82, 0x17, 0xb8, 0x4d, 0xa5, 0xd9, 0xb8, 0x3f, 0x55, 0x88, 0xa1, 0x1c, 0x7f, 0x07, 0x06, 0x43, 0xce, 0xf5, 0x1e, 0x5d, 0x31, 0x02, 0x12, 0xfc, 0x5d, 0xd6, 0x9b, 0xfb, 0xb7, 0xf7, 0x0c, 0xd5, 0x57, 0xac, 0xbe, 0x28, 0x62, 0xc3, 0xfa, 0xa0, 0x4c, 0x39, 0xaf, 0xfa, 0x65, 0xe2, 0x12, 0x11, 0x7a, 0x42, 0x11, 0x07, 0xb6, 0x66, 0x23, 0xb5, 0xa5, 0xbc, 0xbc, 0xa5, 0x04, 0x97, 0x6d, 0xc7, 0x25, 0x36, 0xa8, 0x44, 0xaa, 0x84, 0x38, 0xec, 0xe4, 0x54, 0xd2, 0x2b, 0xaa, 0x8c, 0x06, 0x21, 0xed, 0x40, 0x3b, 0x02, 0x02, 0x38, 0xa8, 0xbf, 0x41, 0x74, 0xbe, 0x78, 0x76, 0x2f, 0xb9, 0x85, 0x32, 0xf6, 0xca, 0x93, 0x1f, 0x2e, 0xfd, 0xe9, 0x4c, 0xcc, 0x09, 0x9d, 0x32, 0x9c, 0xec, 0xb5, 0x1c, 0x96, 0xe9, 0x09, 0xea, 0x6d, 0x64, 0x12, 0xd6, 0x45, 0x3a, 0x57, 0x19, 0x51, 0x5f, 0x27, 0x30, 0x0a, 0x28, 0xbd, 0x65, 0x25, 0xbb, 0xc8, 0x28, 0x9d, 0x95, 0x7c, 0xd6, 0x03, 0x2c, 0xaf, 0x01, 0x3d, 0x68, 0x38, 0x3f, 0x92, 0xee, 0x7e, 0xe8, 0x39, 0xfc, 0x39, 0x4f, 0xb8, 0x3b, 0x1e, 0x00, 0xef, 0x00, 0x5a, 0x0e, 0x2d, 0xf9, 0x3e, 0x74, 0x57, 0x91, 0x03, 0xa0, 0x33, 0x4a, 0xea, 0x07, 0x3b, 0x1e, 0x3d, 0x48, 0x7d, 0xb1, 0x01, 0xd1, 0xf7, 0xbf, 0x89, 0x3f, 0x2d, 0x3e, 0x81, 0x41, 0xd8, 0xc0, 0xf6, 0x2d, 0x4a, 0x26, 0xe0, 0x2b, 0x0f, 0xee, 0x42, 0xc5, 0x47, 0x88, 0xa9, 0x81, 0x6b, 0xbc, 0xb3, 0x13, 0x66, 0xc5, 0x9f, 0x18, 0x41, 0xdb, 0xd4, 0xff, 0x1c, 0x9a, 0x4a, 0xb9, 0x3e, 0x29, 0xd0, 0xaf, 0xd1, 0xf6, 0xce, 0x64, 0x46, 0xc4, 0xcb, 0x95, 0xeb, 0x90, 0x31, 0xb1, 0xd9, 0xf2, 0x2c, 0x6c, 0xee, 0x96, 0x9b, 0xee, 0x0c, 0x46, 0x18, 0xa7, 0xa8, 0xaa, 0x0b, 0xfe, 0x30, 0x94, 0x00, 0x51, 0x48, 0xd8, 0x6b, 0xe5, 0x4d, 0x87, 0x46, 0x10, 0x8f, 0x50, 0x1c, 0xec, 0xe0, 0xc7, 0xf7, 0x24, 0x16, 0xf5, 0xa8, 0xa2, 0xd4, 0x71, 0xd7, 0x1f, 0x26, 0xa6, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xbd, 0x06, 0xe6, 0x81, 0xc1, 0x0d, 0x31, 0x00, 0x05, 0xbf, 0x21, 0x11, 0x00, 0x05, 0xb3, 0x65, 0x1e, 0x69, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xbc, 0xc5, 0x39, 0x13, 0xe5, 0x6a, 0x03, 0x84, 0xdc, 0x27, 0x67, 0xc2, 0x48, 0xe4, 0xb1, 0xab, 0x7b, 0x3f, 0x94, 0xdd, 0x91, 0x15, 0x9e, 0xd7, 0xdb, 0x7a, 0x60, 0xc4, 0x79, 0xa0, 0x79, 0x4f, 0x93, 0x16, 0xb0, 0x48, 0x25, 0x38, 0x29, 0x1e, 0x45, 0x14, 0x77, 0x05, 0x1d, 0x29, 0x39, 0x03, 0xdd, 0xcd, 0xff, 0x2d, 0x6a, 0x02, 0xf1, 0x26, 0x6a, 0xd4, 0x7e, 0x3c, 0x19, 0xae, 0x69, 0xf7, 0xc4, 0xc6, 0xa5, 0xe6, 0x21, 0x31, 0x08, 0xc8, 0x05, 0x0e, 0xf2, 0x7a, 0x53, 0x86, 0x3e, 0xe7, 0xf4, 0x57, 0x6b, 0x44, 0x1d, 0x10, 0xdf, 0xfb, 0x77, 0x15, 0x5d, 0x65, 0xf8, 0x59, 0x95, 0xbd, 0x66, 0xbc, 0x00, 0xec, 0xbf, 0xf8, 0xa3, 0x15, 0x99, 0x7b, 0x7f, 0xea, 0x11, 0x8d, 0x0b, 0x77, 0xee, 0x8e, 0x0b, 0x34, 0xb9, 0x39, 0x70, 0xb7, 0x2d, 0x2d, 0x58, 0x54, 0x34, 0x7b, 0x4c, 0x5f, 0x8d, 0x23, 0xe0, 0xa6, 0xc6, 0xb9, 0xc4, 0x77, 0x0f, 0xfc, 0x55, 0xb7, 0x3f, 0xd8, 0x39, 0x61, 0x37, 0xa4, 0xb8, 0xf2, 0x8a, 0xc8, 0x17, 0x82, 0x42, 0x08, 0xee, 0x26, 0x1b, 0x75, 0xb7, 0xdc, 0x44, 0x60, 0x57, 0x85, 0x8e, 0x3b, 0xaa, 0x71, 0xb5, 0x73, 0xb9, 0x1f, 0x59, 0x35, 0x35, 0xe6, 0x3d, 0x56, 0x61, 0x20, 0xc5, 0x4e, 0xf0, 0xc2, 0x4b, 0xa9, 0x01, 0xfb, 0xd0, 0xba, 0xa1, 0x7e, 0xf7, 0x00, 0x4b, 0xe1, 0x56, 0x22, 0x16, 0xd3, 0xbf, 0x1d, 0x17, 0xb6, 0x8d, 0xac, 0xdb, 0xba, 0x5a, 0x09, 0x15, 0x06, 0x2f, 0x77, 0x8a, 0xd5, 0xbd, 0xc4, 0x3c, 0x2d, 0xe3, 0xcc, 0x4e, 0x42, 0x68, 0xad, 0x44, 0xf9, 0x05, 0x13, 0xf2, 0x4d, 0x70, 0x50, 0x74, 0x62, 0xcd, 0xfa, 0xc8, 0xba, 0x19, 0x51, 0x38, 0xcc, 0x37, 0x63, 0x27, 0x94, 0xbc, 0x8f, 0x3d, 0x64, 0xba, 0xfd, 0x3f, 0x11, 0xcd, 0x6c, 0x45, 0x28, 0xf3, 0xf9, 0x65, 0x92, 0xd3, 0x05, 0xdb, 0xc5, 0xc4, 0x2a, 0xe0, 0x99, 0xbe, 0x26, 0x9e, 0xf5, 0xc3, 0x0b, 0xd1, 0x03, 0x45, 0xaf, 0xc6, 0x8f, 0x37, 0x25, 0x6b, 0xf0, 0x1a, 0x04, 0x6e, 0x8e, 0x4c, 0x82, 0x8a, 0x9b, 0x02, 0x10, 0x4a, 0x02, 0xf5, 0x25, 0x56, 0xbb, 0x5e, 0x24, 0x95, 0x94, 0x69, 0x8a, 0x98, 0xd3, 0x62, 0x9c, 0x5f, 0x5e, 0xe1, 0x3c, 0xc7, 0x20, 0x7c, 0xd9, 0xcd, 0x17, 0x90, 0x53, 0xa0, 0xb7, 0x8b, 0x87, 0x8c, 0x14, 0x54, 0xdd, 0x46, 0x70, 0xfc, 0x43, 0x9d, 0xb3, 0xb1, 0xe9, 0x58, 0xcd, 0x7b, 0x72, 0x4c, 0xf1, 0x6e, 0x56, 0x61, 0x1b, 0xaf, 0xda, 0x58, 0xee, 0xaa, 0x81, 0x72, 0xe6, 0xa5, 0x9e, 0xee, 0xde, 0x76, 0x2d, 0x71, 0x23, 0x7c, 0x54, 0x03, 0x46, 0x19, 0x5b, 0x3d, 0x08, 0x5e, 0x87, 0x30, 0x89, 0xb2, 0xdb, 0x79, 0x52, 0x80, 0xd9, 0x58, 0xb4, 0x74, 0x2b, 0x83, 0xa1, 0x8d, 0x41, 0x59, 0xd4, 0x75, 0xbe, 0xe6, 0xf5, 0x9e, 0x65, 0x82, 0x38, 0x4c, 0x5a, 0xae, 0x3b, 0x37, 0x5e, 0xe1, 0xcc, 0xac, 0x69, 0xf0, 0x38, 0x64, 0x1f, 0xfe, 0xdf, 0xff, 0xf6, 0x6f, 0x07, 0x55, 0x18, 0x8f, 0xab, 0x52, 0x4a, 0x5d, 0xbd, 0x4f, 0x31, 0xa5, 0x87, 0xda, 0x25, 0xf3, 0xbf, 0xcf, 0x70, 0xae, 0xa3, 0x97, 0xb9, 0x33, 0x2c, 0xb7, 0xc9, 0x7f, 0x1b, 0x82, 0xe2, 0x19, 0x97, 0x0b, 0xab, 0xf8, 0xbc, 0x53, 0x75, 0xcd, 0x7e, 0x07, 0x4b, 0xea, 0x60, 0x05, 0xfb, 0x0a, 0xde, 0xcc, 0xe2, 0x18, 0xf7, 0xb6, 0x92, 0x75, 0x4b, 0x10, 0x6f, 0x04, 0x33, 0x08, 0xfb, 0x03, 0x0a, 0x02, 0x28, 0xb2, 0xe8, 0xcd, 0x03, 0xf0, 0x9c, 0x22, 0xa3, 0x2e, 0x5c, 0x99, 0x7d, 0xa5, 0xd2, 0xf2, 0xf4, 0x00, 0x60, 0xf0, 0xe0, 0x67, 0x1b, 0xe4, 0x1a, 0x79, 0xea, 0xa0, 0x68, 0xe8, 0x6e, 0xd5, 0x75, 0xa2, 0xbb, 0xca, 0x5d, 0x66, 0xe8, 0x0f, 0x1e, 0x1a, 0xd5, 0x16, 0xe7, 0x99, 0x13, 0x69, 0x0a, 0xec, 0x43, 0x9e, 0x66, 0x44, 0xc4, 0x89, 0xfe, 0x87, 0x9c, 0x34, 0x7e, 0x3c, 0x5b, 0x9c, 0x95, 0x9c, 0x88, 0x56, 0xd2, 0x16, 0xa3, 0x49, 0x0e, 0x30, 0x50, 0x2e, 0x84, 0x79, 0xe0, 0xdb, 0x82, 0x68, 0x37, 0x96, 0x0d, 0x85, 0x0c, 0x47, 0x85, 0xbd, 0xb5, 0x27, 0xb7, 0x70, 0x91, 0xad, 0x7f, 0x81, 0xb4, 0x04, 0xd3, 0x78, 0x0b, 0xab, 0xd4, 0xf0, 0xe4, 0x6d, 0xcd, 0xa4, 0x1a, 0xd2, 0xdb, 0x58, 0x10, 0x36, 0x92, 0xe2, 0xdd, 0xc8, 0xb1, 0xda, 0xc4, 0x00, 0xe5, 0x0c, 0xdc, 0x25, 0xdc, 0xac, 0x95, 0xff, 0x0a, 0xaa, 0x2b, 0xa3, 0x28, 0x34, 0xbd, 0x66, 0xd4, 0xaa, 0x76, 0x31, 0x05, 0x04, 0x70, 0xc1, 0x3a, 0x46, 0x6c, 0x98, 0x24, 0x74, 0x02, 0xd4, 0xd3, 0xb0, 0x0c, 0x5b, 0x4f, 0x8d, 0x83, 0x74, 0xa2, 0x72, 0x58, 0xc2, 0xa2, 0x43, 0x11, 0x13, 0x45, 0xe6, 0x50, 0xc7, 0x3e, 0x80, 0x45, 0x43, 0xf8, 0x8a, 0x03, 0xa3, 0x29, 0x6c, 0x9a, 0x03, 0x64, 0x05, 0xf9, 0xd9, 0x59, 0xfc, 0xbc, 0x29, 0xd5, 0x6d, 0xb2, 0x94, 0xeb, 0xbc, 0x23, 0xc1, 0x4f, 0xba, 0xaa, 0x08, 0x7b, 0x73, 0x0c, 0x51, 0x36, 0xef, 0xaf, 0xb4, 0x06, 0xf1, 0x9f, 0xbd, 0x03, 0x95, 0xcb, 0x16, 0xf0, 0xc1, 0xab, 0x94, 0xc6, 0xd2, 0xc9, 0xf9, 0xe4, 0x84, 0x49, 0xd3, 0x9a, 0x58, 0x11, 0x98, 0x69, 0x48, 0xcb, 0xc2, 0xfb, 0x73, 0x5b, 0xc6, 0x9d, 0xdc, 0x27, 0x81, 0xca, 0x8c, 0xf2, 0x00, 0x6a, 0x19, 0xc3, 0xc2, 0x89, 0xbe, 0x01, 0x2f, 0xda, 0x6a, 0xad, 0x6f, 0x93, 0x4c, 0x0e, 0xc9, 0x0b, 0x99, 0xc0, 0xaf, 0xc0, 0xa9, 0x7a, 0xc9, 0x68, 0x2c, 0xca, 0x94, 0xae, 0xfa, 0xcc, 0xbe, 0x59, 0x5f, 0xe7, 0xc3, 0x41, 0xa4, 0x13, 0xf0, 0x64, 0xa5, 0x7c, 0xd1, 0x96, 0x22, 0x1a, 0x79, 0x81, 0x3d, 0x28, 0x22, 0xfe, 0xa1, 0x4f, 0x87, 0x17, 0x0b, 0xa3, 0x75, 0x91, 0xae, 0x9d, 0xa7, 0xfc, 0xfc, 0xba, 0x02, 0xe1, 0xcb, 0x0d, 0x20, 0xae, 0x53, 0xa3, 0x93, 0x10, 0xc5, 0x58, 0xd8, 0x01, 0xc1, 0xc9, 0x62, 0x5a, 0xc4, 0x5a, 0x77, 0xd8, 0x67, 0x3f, 0x2c, 0xd3, 0x2d, 0x0d, 0x16, 0x2f, 0xbe, 0x14, 0x66, 0x63, 0xd6, 0x7a, 0x52, 0xb6, 0xbf, 0x22, 0x69, 0xc4, 0xad, 0x20, 0x66, 0x0e, 0x65, 0x4a, 0x33, 0x8a, 0x74, 0x0b, 0x67, 0xe9, 0x72, 0x1d, 0x67, 0x48, 0xcb, 0xde, 0x02, 0xb0, 0xd3, 0xc3, 0x5e, 0x3c, 0xe8, 0xd2, 0x9d, 0x36, 0x9c, 0x66, 0x1c, 0xa9, 0x54, 0x3e, 0x3c, 0x7d, 0x77, 0x2e, 0x63, 0x8c, 0x07, 0x77, 0x69, 0xf4, 0x0a, 0x24, 0x9a, 0x06, 0x04, 0x9a, 0xa9, 0xcc, 0x4b, 0x3d, 0x23, 0x4a, 0x34, 0x14, 0x67, 0x16, 0xb0, 0x9b, 0x77, 0xa2, 0x59, 0xa2, 0x31, 0xda, 0xd6, 0xa9, 0x68, 0x2f, 0xa3, 0xea, 0x29, 0xd0, 0xab, 0x2c, 0x10, 0xde, 0x65, 0x57, 0x15, 0x70, 0xdc, 0xa9, 0x3c, 0x87, 0x07, 0x13, 0x1a, 0x10, 0xfb, 0x57, 0xac, 0xb3, 0x03, 0x76, 0x5a, 0xc7, 0x8e, 0x38, 0xf3, 0xce, 0x00, 0xf1, 0x68, 0x5a, 0xc6, 0x92, 0x74, 0x21, 0x81, 0xa9, 0x0f, 0x98, 0x22, 0x2b, 0xa5, 0x00, 0x5d, 0x63, 0x6a, 0x89, 0xc6, 0xfa, 0x6c, 0x87, 0x2c, 0xe6, 0x07, 0x1e, 0x6e, 0x99, 0xa2, 0x44, 0xa8, 0x8b, 0xef, 0xdb, 0x03, 0x02, 0x7e, 0x44, 0x4b, 0xdc, 0xeb, 0xe7, 0x90, 0xc7, 0x11, 0x91, 0xd3, 0x80, 0xd3, 0x4e, 0x46, 0x20, 0x67, 0xbe, 0xbb, 0x30, 0x0f, 0x4c, 0x2a, 0xdc, 0x58, 0x4a, 0xf8, 0xed, 0x56, 0x6d, 0x4e, 0xe2, 0x1b, 0xea, 0x2c, 0x09, 0x72, 0x83, 0x95, 0xb3, 0xe5, 0x53, 0x15, 0x66, 0x31, 0xcb, 0x32, 0x10, 0xac, 0xe2, 0xab, 0xa7, 0x33, 0xeb, 0xcc, 0xeb, 0xb5, 0xd4, 0xbf, 0x1d, 0x47, 0xd3, 0x61, 0x08, 0x87, 0x48, 0xa9, 0x5e, 0xa7, 0xa6, 0x06, 0xfd, 0xc5, 0xb4, 0xe6, 0x60, 0xcc, 0xf0, 0xcf, 0x35, 0xaf, 0x41, 0xee, 0xa2, 0x1e, 0x72, 0xd5, 0xda, 0x16, 0x33, 0xd6, 0xd5, 0x03, 0x05, 0xec, 0x6e, 0x3d, 0x51, 0x7d, 0x22, 0xf3, 0x9d, 0x2a, 0xef, 0x45, 0xb9, 0x61, 0x5f, 0x53, 0xcf, 0x9c, 0xd3, 0xeb, 0x46, 0x36, 0xf3, 0xf5, 0xe8, 0xcc, 0xec, 0xcf, 0x9b, 0xf6, 0x83, 0x52, 0xd4, 0x12, 0x88, 0x0d, 0xbd, 0x65, 0x41, 0x5a, 0x11, 0x37, 0x64, 0xad, 0xbc, 0x15, 0xb1, 0xd6, 0x37, 0x3d, 0xcd, 0xca, 0x07, 0xa1, 0x0d, 0x65, 0x42, 0x56, 0xae, 0x86, 0x0d, 0xec, 0xc1, 0x6c, 0x4b, 0x52, 0x7b, 0x42, 0x3d, 0x4b, 0xf9, 0x04, 0x86, 0xb1, 0xdf, 0x34, 0x24, 0xd7, 0x8e, 0xc4, 0x51, 0x0e, 0x37, 0x7b, 0xfc, 0x5d, 0xf8, 0x3c, 0x18, 0x69, 0xaa, 0xce, 0xca, 0x3c, 0xce, 0x76, 0xbf, 0x98, 0x91, 0x9b, 0xcc, 0x07, 0x9c, 0x0a, 0x9a, 0xa4, 0x21, 0x95, 0x91, 0xee, 0x73, 0xc3, 0xc9, 0x4a, 0xf2, 0x4e, 0x46, 0x32, 0x51, 0xd2, 0xd9, 0x5f, 0xb5, 0x31, 0x4f, 0x33, 0xc7, 0x14, 0xe2, 0x23, 0xe3, 0x22, 0xbe, 0xe0, 0xe2, 0xa5, 0x95, 0x2f, 0x2a, 0xf8, 0x7f, 0x6e, 0x96, 0x88, 0x36, 0x9b, 0xca, 0x66, 0x6b, 0xac, 0xd3, 0x93, 0x5f, 0x93, 0xfb, 0x5c, 0xf3, 0xb7, 0xb2, 0x16, 0xfb, 0x95, 0x21, 0xcc, 0xdc, 0xdb, 0xe9, 0xbf, 0x87, 0x9b, 0x23, 0xf9, 0x50, 0x8f, 0x58, 0xfa, 0x4e, 0xe5, 0x8c, 0xcd, 0xda, 0x0e, 0x3a, 0xca, 0x8a, 0x5e, 0x12, 0xc5, 0xdb, 0x08, 0xec, 0x36, 0x4a, 0xac, 0x5b, 0xf0, 0x53, 0x30, 0x47, 0xbf, 0xa7, 0x45, 0xb3, 0x37, 0x7b, 0x1b, 0xad, 0x47, 0x85, 0x4d, 0xdd, 0xcb, 0x11, 0x08, 0x26, 0x31, 0x5d, 0x33, 0xa1, 0x02, 0xba, 0xe1, 0x9c, 0x53, 0x0e, 0xee, 0xaa, 0xc0, 0x96, 0x37, 0xc0, 0xf5, 0xec, 0xa4, 0x89, 0xd9, 0xaf, 0x18, 0x2a, 0x24, 0x36, 0x07, 0xff, 0x1c, 0x56, 0x08, 0x06, 0x8f, 0xb5, 0xb0, 0x04, 0x49, 0x36, 0xa4, 0xcb, 0x66, 0x69, 0xae, 0x48, 0xd1, 0xc6, 0x60, 0x7b, 0x51, 0x06, 0x34, 0xe9, 0x25, 0x5e, 0x41, 0xfc, 0x8a, 0xf3, 0xbb, 0xe3, 0xa4, 0xc0, 0x45, 0xed, 0x12, 0x8e, 0x47, 0xdb, 0x94, 0x4f, 0x1d, 0x23, 0xfe, 0x97, 0x7d, 0x05, 0x11, 0x78, 0x67, 0x46, 0xcd, 0x01, 0x2e, 0x22, 0x3b, 0x48, 0x87, 0x08, 0xb1, 0x2d, 0x5d, 0xe4, 0xd8, 0x3d, 0xe2, 0x10, 0xab, 0xf1, 0xcd, 0xd6, 0x5f, 0x5c, 0xde, 0x11, 0x5f, 0xd3, 0xf4, 0x8d, 0xcd, 0xb7, 0xd1, 0x44, 0xd5, 0xf7, 0x10, 0x64, 0x00, 0x7c, 0xf7, 0xcd, 0xfb, 0x24, 0x03, 0x7a, 0xd4, 0x70, 0x16, 0x2f, 0x02, 0x0b, 0xca, 0x81, 0x9f, 0x6e, 0x9e, 0x9e, 0x22, 0x29, 0x24, 0x23, 0xdf, 0xe5, 0x8f, 0xba, 0x82, 0x7b, 0x50, 0xfe, 0x91, 0x3c, 0x22, 0x4d, 0xbc, 0xd8, 0xec, 0x4a, 0x66, 0xa8, 0xf0, 0x0e, 0xbb, 0x13, 0x12, 0x82, 0x38, 0x82, 0x9f, 0xa0, 0x99, 0x20, 0x9f, 0x4d, 0x3b, 0x69, 0x50, 0xeb, 0x78, 0x51, 0x6d, 0xaf, 0x09, 0xdb, 0x72, 0xb3, 0x16, 0x80, 0x61, 0xc4, 0x1b, 0x2f, 0x46, 0x0a, 0xbf, 0xda, 0x67, 0x44, 0xd2, 0xd8, 0xbf, 0xca, 0x1a, 0x50, 0x01, 0x47, 0x78, 0x05, 0x2f, 0x8a, 0x88, 0x11, 0xd0, 0xe3, 0x93, 0xd5, 0x3f, 0xe7, 0xe9, 0xc3, 0x3b, 0xe0, 0x6e, 0x63, 0xf6, 0x77, 0x1f, 0x90, 0xa7, 0x62, 0xe6, 0x33, 0x98, 0x16, 0xdd, 0x3c, 0x8a, 0xa6, 0x35, 0x43, 0x0a, 0x16, 0xb9, 0x08, 0x4d, 0x24, 0x60, 0xe8, 0x1c, 0x47, 0x21, 0x38, 0x6e, 0xd1, 0x74, 0x7c, 0x40, 0x07, 0x92, 0xc4, 0x0b, 0x07, 0x91, 0x74, 0xc2, 0x10, 0xe9, 0x50, 0xf9, 0xe7, 0x68, 0x44, 0x16, 0x99, 0x96, 0x67, 0x2b, 0xa3, 0x8b, 0x60, 0x90, 0xdc, 0x63, 0xcc, 0x8c, 0xf5, 0x29, 0xdc, 0x19, 0xe5, 0xda, 0x95, 0x9a, 0x35, 0x2a, 0xa8, 0x3c, 0x36, 0xb1, 0x47, 0xff, 0xcd, 0xeb, 0xc5, 0x01, 0xa6, 0x41, 0x79, 0x2d, 0x9e, 0x4b, 0x22, 0xa0, 0x4f, 0x37, 0x62, 0x10, 0xc5, 0x70, 0x1b, 0x8a, 0xa0, 0xd9, 0x81, 0xdf, 0xf7, 0x33, 0x4d, 0xa1, 0x88, 0x92, 0x07, 0xee, 0xcb, 0xa1, 0x23, 0x1d, 0x8c, 0xd7, 0xbb, 0x1f, 0xbb, 0xa7, 0xa8, 0xe1, 0xbc, 0xcf, 0x7d, 0x8e, 0x79, 0xf6, 0x7b, 0x60, 0x76, 0x86, 0xba, 0x23, 0x7a, 0x4b, 0x18, 0x4c, 0xac, 0xc5, 0xdf, 0xc8, 0xab, 0x98, 0xab, 0x17, 0x1a, 0x5c, 0x76, 0x06, 0x14, 0xc3, 0x69, 0xde, 0x66, 0x95, 0x5b, 0x3a, 0x03, 0xb0, 0x83, 0x9e, 0x5d, 0x4d, 0x8f, 0x4e, 0x60, 0x77, 0x2e, 0x79, 0xbe, 0x05, 0x2a, 0x2e, 0x24, 0xe2, 0x9f, 0x62, 0x93, 0x28, 0x97, 0x3f, 0x82, 0x5a, 0x1a, 0x15, 0xa6, 0x74, 0x1d, 0x38, 0x9d, 0xab, 0x48, 0x93, 0x44, 0x0e, 0xc3, 0x58, 0xb9, 0x22, 0xa1, 0x9a, 0x75, 0x95, 0x32, 0x82, 0xd4, 0x61, 0x1f, 0xc5, 0x06, 0x8f, 0x89, 0xb6, 0x17, 0xfd, 0x01, 0x27, 0xff, 0x92, 0x0f, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xbd, 0x06, 0xe6, 0x81, 0xc1, 0x0d, 0x31, 0x00, 0x05, 0xbf, 0x21, 0x11, 0x00, 0x05, 0xb3, 0x65, 0x1e, 0x69, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x9f, 0xb4, 0x80, 0x33, 0x18, 0xed, 0x17, 0xb5, 0xc4, 0xac, 0xb0, 0xba, 0xa8, 0x13, 0xe4, 0x96, 0x6f, 0x61, 0xe8, 0xce, 0xdf, 0x72, 0xb2, 0x56, 0xaa, 0xa4, 0xe7, 0xd1, 0x0b, 0x8c, 0xa4, 0x7e, 0x94, 0x28, 0x2c, 0xba, 0x69, 0x66, 0xdc, 0x96, 0x79, 0xab, 0x7f, 0xcc, 0x41, 0xf6, 0xd7, 0x48, 0x8a, 0x15, 0x40, 0xf3, 0x4f, 0x31, 0x90, 0x1e, 0xb6, 0xfd, 0xda, 0x34, 0xe5, 0xbb, 0x69, 0x1c, 0xf4, 0x17, 0x18, 0xd0, 0x89, 0x17, 0xe6, 0x83, 0xfa, 0x3d, 0xd6, 0x28, 0x3c, 0x92, 0x2d, 0x58, 0x46, 0xcb, 0x4f, 0x4c, 0x29, 0xa5, 0xdb, 0x56, 0xfb, 0xce, 0xf9, 0x0a, 0xe3, 0x4e, 0x3d, 0x2e, 0xdc, 0x42, 0x47, 0x15, 0x3a, 0xea, 0x66, 0xc8, 0x79, 0xc3, 0xd5, 0x93, 0x8d, 0xc9, 0xa1, 0xae, 0x8c, 0xed, 0x35, 0xd6, 0xcb, 0xea, 0x15, 0x72, 0xb5, 0x54, 0xf2, 0x10, 0xbb, 0x01, 0x5e, 0x68, 0x3b, 0xdb, 0x17, 0xf3, 0x18, 0x49, 0x72, 0xbc, 0x24, 0xba, 0xc3, 0x2f, 0x30, 0xf6, 0x79, 0x7f, 0x38, 0x6a, 0x36, 0x36, 0x04, 0xdb, 0xd3, 0x17, 0xd1, 0x34, 0x81, 0x4d, 0xcf, 0x67, 0x74, 0xb3, 0x21, 0x94, 0xd9, 0xb1, 0x1d, 0x3a, 0x1c, 0x22, 0x24, 0xd2, 0xe3, 0x3b, 0xf5, 0x60, 0x97, 0xaa, 0xdf, 0xba, 0x16, 0xf8, 0x27, 0xf4, 0xcd, 0xc1, 0x3b, 0xc1, 0xe6, 0x0a, 0x6a, 0x59, 0xa7, 0xff, 0xef, 0x5d, 0xc8, 0xd3, 0x4c, 0xb4, 0xa8, 0x86, 0x00, 0x53, 0x50, 0x6b, 0x1c, 0x7b, 0xa5, 0x61, 0x20, 0xe3, 0x01, 0x1b, 0x66, 0x1a, 0x4e, 0xf4, 0x80, 0xdc, 0x46, 0xb6, 0x94, 0x77, 0x43, 0xc1, 0x37, 0xf0, 0xe9, 0x7c, 0x27, 0xae, 0x30, 0x70, 0x67, 0x84, 0x3f, 0x33, 0x1c, 0x27, 0xc9, 0xda, 0xc2, 0x7d, 0xc6, 0x5d, 0x9f, 0x7a, 0xb9, 0x71, 0xbc, 0xb6, 0x3c, 0xfe, 0x4a, 0x28, 0xd3, 0x24, 0x94, 0x43, 0x7d, 0xee, 0x84, 0xb1, 0xc5, 0xe6, 0x27, 0x54, 0xb9, 0xef, 0x0a, 0xf8, 0xdb, 0xb5, 0xa8, 0x5c, 0xb8, 0x42, 0x11, 0x12, 0x94, 0xd5, 0xa6, 0xba, 0x5e, 0x54, 0xe2, 0x6f, 0x79, 0x48, 0xd2, 0xf0, 0xd7, 0x1f, 0x23, 0x90, 0x95, 0x3e, 0x8f, 0xed, 0x2b, 0xf7, 0xe6, 0x65, 0xfe, 0x1d, 0x68, 0x4a, 0xb8, 0xef, 0x9f, 0xce, 0x74, 0x92, 0xa9, 0xb0, 0xa4, 0x83, 0x91, 0x2b, 0xa8, 0x90, 0xa3, 0x23, 0x09, 0x58, 0x7a, 0x51, 0x36, 0x6b, 0xaa, 0x06, 0x73, 0x46, 0xd2, 0x38, 0x6e, 0x2c, 0x87, 0x2c, 0x20, 0x6f, 0xf3, 0x13, 0xf3, 0x49, 0x2b, 0xc8, 0x0c, 0x1d, 0xfe, 0x0d, 0xa1, 0x20, 0x13, 0x0b, 0x5a, 0xac, 0x16, 0xac, 0x0e, 0xb1, 0x1f, 0xc9, 0x14, 0xf7, 0xbc, 0xda, 0x48, 0xd3, 0x5d, 0xf5, 0x4b, 0x3d, 0x9c, 0xc8, 0x56, 0xd8, 0x9e, 0x88, 0xbc, 0x60, 0xae, 0xe6, 0xfc, 0xaa, 0xba, 0x3d, 0xb1, 0xe1, 0x07, 0x8c, 0xc8, 0x05, 0xae, 0x2d, 0x4c, 0x1b, 0x2a, 0xec, 0xad, 0xe6, 0x2b, 0x34, 0xb2, 0x29, 0xf2, 0x19, 0x51, 0x5e, 0xb6, 0x55, 0x8e, 0xa5, 0x4d, 0x74, 0x1c, 0x5f, 0xa0, 0xc8, 0xae, 0x21, 0x2d, 0x48, 0x15, 0x04, 0x78, 0x0e, 0xd0, 0xce, 0xfd, 0x6b, 0x80, 0xcf, 0xc5, 0xa2, 0x32, 0x15, 0xfb, 0x8c, 0xa8, 0x38, 0xc3, 0xab, 0x70, 0x04, 0x04, 0xcc, 0x75, 0x40, 0x2c, 0x5b, 0x78, 0x2e, 0x1d, 0xfc, 0x71, 0xff, 0x38, 0x63, 0x1b, 0x77, 0x3b, 0x0c, 0x65, 0x8f, 0xc9, 0x21, 0xdd, 0x28, 0x40, 0x5c, 0xaa, 0xf2, 0x9e, 0x5a, 0x24, 0x7b, 0x44, 0xc0, 0xdb, 0x7c, 0x82, 0x1e, 0x1d, 0xe8, 0xb7, 0x99, 0xe2, 0x7d, 0xfa, 0x75, 0xc9, 0x74, 0x43, 0xcf, 0x95, 0x23, 0xe2, 0xe8, 0x08, 0x49, 0x5e, 0x45, 0x2d, 0xb5, 0x5a, 0x2a, 0x57, 0xf3, 0xe0, 0x01, 0xf7, 0xd8, 0x41, 0x83, 0xae, 0xac, 0xd3, 0x1d, 0xe4, 0x3b, 0x89, 0x2f, 0x2d, 0xdc, 0x2f, 0x3c, 0xd2, 0x3b, 0x9b, 0xd5, 0x0b, 0x8c, 0x68, 0xee, 0xee, 0x72, 0x7e, 0x0e, 0x97, 0x9e, 0xd6, 0x8b, 0x57, 0xaa, 0xd8, 0x61, 0xb1, 0x10, 0xf1, 0xc1, 0x5c, 0x29, 0x72, 0x48, 0xc0, 0xaf, 0x8c, 0x58, 0x1b, 0x3d, 0xad, 0xe5, 0xe8, 0x10, 0x90, 0x35, 0x0f, 0xa6, 0xfe, 0x7b, 0xc9, 0xbf, 0x2f, 0x3d, 0x60, 0xc5, 0x1f, 0xc2, 0x27, 0x14, 0xff, 0x14, 0xd3, 0x10, 0x1d, 0xa0, 0x96, 0xa6, 0xb4, 0x5f, 0x93, 0xd5, 0xc5, 0xd9, 0x5f, 0xea, 0x99, 0xac, 0x4b, 0xa7, 0x89, 0x09, 0x59, 0x94, 0xb2, 0x77, 0x37, 0xa9, 0x85, 0xc6, 0xa5, 0xb9, 0x2c, 0x1d, 0xe8, 0x7e, 0x16, 0xa1, 0xb5, 0xbe, 0xfa, 0x12, 0x54, 0x32, 0xb9, 0x55, 0xf8, 0x0b, 0x77, 0x89, 0xf6, 0xc5, 0xd7, 0x8f, 0x8f, 0x0b, 0xa1, 0x3c, 0x08, 0x08, 0x90, 0xe9, 0xdd, 0x97, 0xc4, 0xb0, 0xdd, 0x23, 0x55, 0x69, 0x8a, 0x80, 0x8e, 0x7f, 0x7c, 0xe1, 0x38, 0xe7, 0xff, 0xe1, 0xfd, 0x79, 0x55, 0x11, 0xbf, 0x1d, 0x94, 0x87, 0xa1, 0x38, 0x66, 0x82, 0xc6, 0x9d, 0x4d, 0x46, 0x3b, 0x64, 0x99, 0x28, 0x0c, 0x2f, 0xe1, 0x63, 0x2b, 0xdb, 0x2f, 0x08, 0xcb, 0x42, 0xa8, 0xd7, 0xcd, 0x48, 0x58, 0x64, 0xa0, 0xa4, 0x08, 0x98, 0x55, 0x9c, 0x4f, 0xcf, 0x1a, 0x83, 0xf6, 0xfa, 0x59, 0x61, 0x7c, 0x34, 0x8c, 0xb6, 0x20, 0x2e, 0xea, 0x5d, 0x3a, 0x0c, 0xc0, 0x33, 0xbd, 0xf5, 0x64, 0x26, 0x67, 0xba, 0xc5, 0x6e, 0xa5, 0x09, 0xe4, 0x95, 0x3e, 0x9b, 0x8e, 0x52, 0x0b, 0xdc, 0x31, 0x06, 0xe4, 0xc5, 0x61, 0x89, 0xa1, 0x89, 0x16, 0x47, 0x23, 0xa9, 0x51, 0x2d, 0x93, 0xd5, 0x34, 0xbd, 0x77, 0x3d, 0x02, 0x7b, 0x86, 0x42, 0xe4, 0xfc, 0xab, 0xa7, 0x20, 0xa7, 0x3e, 0xc3, 0x89, 0x35, 0xf5, 0xd8, 0x18, 0x1c, 0xa6, 0x03, 0x39, 0x6d, 0xdd, 0x82, 0xfa, 0x35, 0xaa, 0x9b, 0xfa, 0x05, 0xc5, 0x56, 0x7c, 0x09, 0xd7, 0xa9, 0x7d, 0xbf, 0xf1, 0x3d, 0xed, 0xec, 0xa3, 0x3b, 0x4c, 0x28, 0x23, 0x96, 0x8a, 0x76, 0xf5, 0x29, 0xda, 0x72, 0x01, 0x7b, 0xb7, 0x20, 0x11, 0x1d, 0xd0, 0xea, 0xdc, 0x8d, 0x96, 0x6e, 0x2f, 0x53, 0x9e, 0xb5, 0x4c, 0x8e, 0x45, 0xbf, 0xf0, 0x0d, 0x88, 0xad, 0x0b, 0x4c, 0xd3, 0x9d, 0x90, 0xef, 0x53, 0x65, 0x8d, 0xc0, 0xee, 0x3e, 0x7d, 0x8b, 0xbd, 0xc8, 0x15, 0xdf, 0x51, 0x83, 0xbe, 0x61, 0x76, 0xac, 0xfc, 0x34, 0x07, 0xc0, 0x26, 0xd1, 0x6a, 0xe4, 0xd0, 0x20, 0xfb, 0x15, 0x07, 0x5d, 0xea, 0x40, 0xca, 0x4e, 0xff, 0x8d, 0xf7, 0x44, 0xd5, 0x6f, 0x1e, 0x26, 0x1d, 0x87, 0xce, 0xdc, 0xbe, 0xc9, 0x04, 0x3f, 0x45, 0xd3, 0x36, 0x7d, 0x04, 0xa2, 0x46, 0xcd, 0xb1, 0x62, 0x82, 0x07, 0xc3, 0x76, 0x63, 0xc6, 0x2b, 0x83, 0x5a, 0xe3, 0x27, 0xb6, 0xad, 0x67, 0x3d, 0x82, 0x6f, 0x5c, 0xae, 0x09, 0xcf, 0xca, 0xc2, 0x48, 0xc8, 0x35, 0xe1, 0x2a, 0x4a, 0xf2, 0xbd, 0xa0, 0x4e, 0xe1, 0xf9, 0xb3, 0x23, 0x1f, 0x1f, 0x01, 0xd7, 0x64, 0x20, 0x1c, 0xdb, 0xfe, 0x92, 0xd2, 0x99, 0x8c, 0x26, 0x1f, 0x8e, 0x40, 0x77, 0x03, 0x72, 0x78, 0x18, 0x6f, 0xe2, 0x0a, 0x77, 0x4c, 0x55, 0x6e, 0x98, 0x08, 0x20, 0xe9, 0x44, 0x79, 0x9c, 0xbc, 0x33, 0x72, 0x6e, 0x69, 0x84, 0x6e, 0xb7, 0x2f, 0x63, 0x29, 0xe0, 0x6a, 0xd2, 0x66, 0xd3, 0x19, 0x7f, 0x03, 0x39, 0x4d, 0xee, 0x66, 0xcb, 0xca, 0xcb, 0x8f, 0xb3, 0xf8, 0x98, 0x6d, 0x37, 0xca, 0xf3, 0x5b, 0xc6, 0x5a, 0xe8, 0x6f, 0xe4, 0x7a, 0x8d, 0xb9, 0xe2, 0x28, 0x25, 0x56, 0xd1, 0x56, 0xc9, 0xb3, 0x8e, 0x12, 0xb9, 0x55, 0x9b, 0x7b, 0x19, 0xc8, 0xf5, 0x7a, 0x9c, 0x53, 0xac, 0xe9, 0xac, 0xe1, 0xce, 0xb9, 0x29, 0xca, 0x2d, 0x4e, 0xfc, 0x81, 0xfb, 0xfe, 0x0d, 0x7c, 0xec, 0x0c, 0x83, 0x6f, 0x4d, 0xba, 0xf9, 0xde, 0xc9, 0xa0, 0xf1, 0x37, 0xbc, 0x12, 0xeb, 0xcb, 0xa7, 0x95, 0x47, 0x5c, 0x78, 0x3a, 0xdd, 0x4f, 0xfa, 0xdf, 0x2b, 0x36, 0x82, 0xf8, 0x7d, 0x97, 0x8e, 0x74, 0x73, 0xc3, 0x8e, 0x43, 0xcf, 0x63, 0x40, 0xc0, 0x01, 0x99, 0x9a, 0xe8, 0x11, 0xef, 0x69, 0xd2, 0x95, 0x30, 0xee, 0x5d, 0x52, 0x94, 0x04, 0xf5, 0x53, 0xbc, 0x8f, 0x46, 0xde, 0xbd, 0x31, 0x35, 0x18, 0x74, 0x67, 0x16, 0x9e, 0x67, 0xd3, 0x47, 0x41, 0x6e, 0xb5, 0x79, 0x06, 0x6d, 0x73, 0xd1, 0xdb, 0x4a, 0x58, 0x7c, 0x1e, 0xb7, 0xb0, 0xab, 0x76, 0x81, 0x5e, 0xee, 0x3d, 0x38, 0x2c, 0xb1, 0x06, 0x25, 0xbc, 0xd6, 0x69, 0xa6, 0x41, 0xea, 0x7d, 0xfa, 0x89, 0x27, 0xd6, 0x75, 0x55, 0x08, 0x4a, 0x93, 0xe1, 0x2a, 0x2b, 0xac, 0x10, 0x86, 0xf6, 0xc8, 0x7a, 0xa4, 0xc4, 0x2c, 0x49, 0xc1, 0x80, 0x94, 0x3d, 0xc5, 0xb9, 0x9b, 0x7b, 0xee, 0xfe, 0x1d, 0x79, 0x81, 0x5a, 0x69, 0xa3, 0x02, 0x5b, 0x26, 0xbd, 0xeb, 0x28, 0xa0, 0x3e, 0x6c, 0xc7, 0xe3, 0x23, 0xb9, 0x8c, 0xd4, 0x3c, 0x61, 0x66, 0xf6, 0xb7, 0xf4, 0x3b, 0x60, 0x1f, 0xb8, 0x66, 0xcb, 0x97, 0xd8, 0x58, 0x26, 0x2f, 0x2e, 0xb2, 0xfb, 0xe0, 0xf5, 0x3e, 0xd2, 0x49, 0x87, 0xc0, 0xb6, 0xa4, 0x84, 0x38, 0xa7, 0xc6, 0x14, 0xf3, 0x98, 0x8a, 0x01, 0x70, 0xd8, 0x7c, 0x14, 0x6b, 0x5a, 0x56, 0x06, 0x39, 0xa5, 0x4c, 0x2d, 0x00, 0x91, 0x6a, 0x6b, 0x92, 0x56, 0x21, 0x18, 0x59, 0xe6, 0x2d, 0xb9, 0x78, 0xdd, 0x8e, 0xe6, 0x07, 0xfe, 0x81, 0x7f, 0x0e, 0x7c, 0xf4, 0x1b, 0x78, 0x78, 0x86, 0xbb, 0x9d, 0xb1, 0x43, 0xad, 0x78, 0x04, 0x00, 0x88, 0x8e, 0xcd, 0x7b, 0x33, 0xdc, 0x1c, 0x8b, 0x7b, 0x7e, 0x33, 0x1f, 0x03, 0xdc, 0xc7, 0x84, 0xd9, 0x9e, 0xdd, 0x41, 0x8d, 0xe1, 0xe4, 0x4d, 0x04, 0xc1, 0xd5, 0x51, 0x08, 0x5f, 0x3e, 0xf8, 0x55, 0x8c, 0x9b, 0xae, 0xe4, 0x5a, 0x6a, 0x3f, 0x42, 0xb9, 0x01, 0x6b, 0x83, 0xb7, 0x3e, 0x82, 0x0a, 0xde, 0xfd, 0x67, 0x9a, 0x76, 0xfe, 0x16, 0x38, 0x0f, 0xc3, 0x6e, 0x24, 0xe5, 0xbf, 0x25, 0xfb, 0x41, 0x00, 0x0b, 0xfb, 0xd2, 0x5d, 0x37, 0x39, 0xaa, 0xb3, 0xb8, 0x8b, 0xee, 0x74, 0xb3, 0xfb, 0x0e, 0xe3, 0xed, 0xc2, 0x00, 0x7f, 0xd9, 0xd9, 0xd1, 0x2c, 0x9e, 0x30, 0xda, 0x7a, 0x71, 0x0d, 0x28, 0x38, 0x14, 0xe7, 0x64, 0xae, 0x88, 0x28, 0x15, 0x24, 0x0f, 0x46, 0x78, 0x23, 0xdd, 0x98, 0x4a, 0xdb, 0x39, 0xd6, 0x2d, 0x2c, 0x6a, 0x34, 0xd5, 0xe7, 0xce, 0x81, 0xdb, 0x0f, 0x77, 0x5f, 0xa1, 0xcc, 0x50, 0x1f, 0xe3, 0x2a, 0x3e, 0x1b, 0xf5, 0xb8, 0x72, 0x8a, 0x73, 0xf8, 0x80, 0x64, 0x41, 0xd2, 0x35, 0xa8, 0x59, 0xa3, 0x4f, 0x46, 0xd4, 0xac, 0x9f, 0x72, 0xe2, 0x62, 0x65, 0x04, 0xfb, 0x7e, 0x4a, 0x21, 0x33, 0xcf, 0x91, 0x2e, 0x5d, 0xa9, 0xfa, 0xee, 0xb8, 0x0e, 0xe2, 0xf0, 0x57, 0x2c, 0xa9, 0x45, 0xb7, 0x6d, 0xc3, 0x96, 0x6d, 0x52, 0xae, 0x69, 0xd8, 0x1a, 0x15, 0x54, 0x3c, 0x6b, 0xa3, 0x1e, 0x51, 0x24, 0x25, 0x83, 0xb6, 0x89, 0x98, 0xc4, 0xc7, 0xa3, 0x6e, 0x50, 0xda, 0x3d, 0xaf, 0xd5, 0x32, 0x7c, 0xb8, 0xd1, 0xf4, 0x08, 0x15, 0x7f, 0x95, 0xfe, 0x8d, 0x37, 0x25, 0xe9, 0x8b, 0x0c, 0x2a, 0xd4, 0x03, 0x57, 0xec, 0xee, 0x53, 0x38, 0x29, 0xe6, 0x60, 0xa7, 0x82, 0x8b, 0xa6, 0x33, 0xee, 0xb7, 0xbc, 0x0c, 0x30, 0x5e, 0xc1, 0x92, 0x4b, 0x21, 0xa6, 0xcb, 0xf7, 0xa6, 0x77, 0xc2, 0xac, 0xc6, 0x0a, 0x1d, 0x05, 0xae, 0xee, 0xe9, 0x7d, 0x91, 0xe6, 0xce, 0xed, 0x3d, 0xcc, 0xf5, 0x67, 0xa4, 0x08, 0x49, 0xf0, 0xd8, 0x28, 0x4c, 0xb4, 0x57, 0x36, 0x79, 0xc4, 0xdf, 0xc4, 0x40, 0x10, 0xc5, 0x96, 0xb5, 0xc1, 0x43, 0xc9, 0x14, 0x3d, 0x86, 0x65, 0x5d, 0xc4, 0xb4, 0xbf, 0x69, 0x10, 0x76, 0xb5, 0xe5, 0x98, 0xe1, 0xe7, 0x19, 0x47, 0xcf, 0x9d, 0x77, 0x0e, 0xcb, 0xd1, 0x20, 0x1d, 0xee, 0x2e, 0x6e, 0x5b, 0xa5, 0xd3, 0x59, 0x28, 0x3b, 0x1b, 0xa3, 0xf4, 0xcc, 0x55, 0xfa, 0x27, 0x9e, 0xf8, 0x00, 0xe8, 0x3f, 0xa0, 0xa5, 0x14, 0x9b, 0x31, 0x13, 0x6c, 0xa5, 0xfb, 0x05, 0x04, 0xa1, 0xba, 0x1c, 0xf4, 0xfd, 0xf4, 0x30, 0x16, 0x55, 0x61, 0x4a, 0x0f, 0xda, 0x7f, 0xa1, 0x1d, 0xf6, 0xa9, 0x2d, 0x4c, 0x2d, 0xec, 0x1e, 0xac, 0xba, 0x31, 0xae, 0x28, 0xaa, 0xc9, 0xb0, 0xc8, 0x39, 0x8c, 0x4f, 0xa1, 0xb8, 0xb4, 0x92, 0x4b, 0xe7, 0xf7, 0x6c, 0xf0, 0x07, 0x5b, 0xd1, 0x70, 0x40, 0xef, 0x67, 0x7b, 0x9e, 0xde, 0x54, 0x0a, 0xb9, 0x04, 0xfd, 0xb3, 0xc4, 0xdb, 0x90, 0x9b, 0xab, 0xa9, 0xc5, 0xdd, 0xaf, 0x9b, 0x9f, 0x46, 0x1f, 0x9c, 0xe8, 0x01, 0xa3, 0x92, 0xe7, 0x3b, 0xea, 0x31, 0xef, 0xba, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xbd, 0x06, 0xe6, 0x81, 0xc1, 0x0d, 0x31, 0x00, 0x05, 0xbf, 0x21, 0x11, 0x00, 0x05, 0xb3, 0x65, 0x1e, 0x69, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x58, 0xd0, 0xfa, 0x1b, 0xf4, 0x76, 0x32, 0x3a, 0xc8, 0xd3, 0x5d, 0x75, 0x65, 0x33, 0x3a, 0x8d, 0x35, 0xc3, 0x0b, 0x5c, 0xba, 0xb8, 0xb1, 0xe5, 0x97, 0x00, 0x66, 0x7f, 0x98, 0xd3, 0xa0, 0x41, 0xb7, 0x4b, 0xd5, 0xe6, 0x54, 0x49, 0x8d, 0x21, 0x29, 0xd8, 0xbf, 0x41, 0x56, 0x2f, 0xb5, 0xe6, 0x78, 0x3c, 0x91, 0xdf, 0x78, 0x9f, 0xf3, 0x87, 0xcc, 0xce, 0x27, 0x87, 0xa3, 0x9f, 0x32, 0x62, 0x70, 0x5a, 0x9a, 0x50, 0x4e, 0xeb, 0x74, 0x4f, 0xae, 0x35, 0x19, 0x7f, 0xf8, 0x49, 0xdc, 0xbc, 0x95, 0x7d, 0x7e, 0x21, 0xdb, 0x69, 0x11, 0x4f, 0xb1, 0xd5, 0x12, 0x7b, 0x69, 0xe0, 0x60, 0x8a, 0xeb, 0x82, 0x6b, 0x92, 0xbd, 0xa4, 0x6f, 0x78, 0xb9, 0x93, 0xdd, 0x7e, 0x6c, 0x63, 0xfb, 0x91, 0xfc, 0xb1, 0x65, 0xf7, 0xbd, 0xd5, 0x7c, 0xcc, 0xb0, 0xb3, 0x95, 0x96, 0xd6, 0x90, 0x4b, 0x39, 0xd0, 0x8a, 0xf0, 0xfb, 0xae, 0x00, 0x20, 0x07, 0x81, 0x79, 0xc6, 0x03, 0x23, 0x11, 0x68, 0x97, 0x3a, 0x3a, 0x8c, 0x84, 0xa4, 0x97, 0xcf, 0x71, 0x2b, 0x2a, 0x67, 0x5b, 0x19, 0x40, 0x3e, 0xf3, 0x72, 0x68, 0x8b, 0x0f, 0x7f, 0xd7, 0x72, 0xe0, 0x61, 0x13, 0x8a, 0xfd, 0x81, 0xbb, 0x88, 0x32, 0x83, 0x70, 0xb2, 0x21, 0xf7, 0xf2, 0xf9, 0x62, 0xb6, 0x95, 0xd7, 0x86, 0xec, 0x0e, 0xdc, 0x45, 0x2b, 0x82, 0x03, 0x7e, 0x96, 0x64, 0xb8, 0x60, 0xa2, 0x34, 0xa9, 0x43, 0x1b, 0xb4, 0x1e, 0xbe, 0x50, 0x8c, 0x47, 0x15, 0x29, 0xc1, 0xa1, 0x0d, 0x0f, 0x11, 0xde, 0xa1, 0xbb, 0x79, 0x60, 0x4b, 0x3b, 0xc1, 0xf5, 0xd1, 0x32, 0x21, 0x02, 0xf3, 0x94, 0x1f, 0xa1, 0xbb, 0x10, 0x05, 0x3e, 0xcf, 0x37, 0xef, 0x16, 0x63, 0x0f, 0x5d, 0x89, 0x2b, 0x1c, 0xe9, 0x95, 0x48, 0xab, 0x1f, 0xa3, 0xfb, 0x12, 0xe6, 0xd3, 0xd8, 0xa7, 0x48, 0xa4, 0xd0, 0xc9, 0x91, 0xe4, 0xfb, 0x1a, 0xe7, 0xf2, 0x2c, 0xaf, 0x0e, 0xa4, 0x9d, 0x2e, 0xac, 0x0f, 0x6c, 0x33, 0xdb, 0xdd, 0x8b, 0x14, 0x1c, 0x98, 0x06, 0x93, 0x1f, 0x27, 0x7a, 0x35, 0xea, 0xcb, 0x89, 0x05, 0x76, 0x09, 0x23, 0x5a, 0x1a, 0x75, 0x8c, 0x1d, 0xea, 0x10, 0x91, 0xcc, 0x56, 0x29, 0x7d, 0x71, 0x38, 0x29, 0x44, 0x68, 0x8a, 0xdb, 0xf1, 0x24, 0x36, 0xb1, 0x85, 0x78, 0x6e, 0x46, 0x1e, 0xb7, 0x92, 0x99, 0x1d, 0xf3, 0x02, 0x03, 0x80, 0x84, 0x67, 0x23, 0x7c, 0xe1, 0xe0, 0x3b, 0xbf, 0x21, 0x26, 0x4f, 0xad, 0xfb, 0x1c, 0xc1, 0xc7, 0x68, 0x2b, 0xde, 0x47, 0xf6, 0x41, 0xd8, 0xc6, 0xd6, 0x39, 0x41, 0x58, 0xce, 0x60, 0x1c, 0xb6, 0x49, 0x41, 0xb8, 0x66, 0x41, 0x02, 0x0e, 0xed, 0x62, 0x44, 0x8e, 0x19, 0x2f, 0xe9, 0x19, 0x85, 0x9c, 0x17, 0xc9, 0xdf, 0xa3, 0xf5, 0xc8, 0x45, 0x7c, 0x05, 0x7f, 0x74, 0xfd, 0x77, 0x7b, 0xab, 0xc4, 0xfc, 0x36, 0xb9, 0xa6, 0xbc, 0x70, 0xbc, 0x0d, 0x88, 0x32, 0xfa, 0xeb, 0x9c, 0x98, 0x7d, 0x50, 0x09, 0x80, 0xfa, 0xfc, 0xa1, 0x16, 0xf1, 0x84, 0x4e, 0xf9, 0xca, 0x5f, 0xdc, 0x18, 0x6b, 0x2b, 0xce, 0xf6, 0xfe, 0x37, 0xa9, 0x6b, 0xf2, 0x6d, 0xa3, 0xa2, 0x37, 0xfa, 0x8d, 0xd8, 0x7d, 0xa6, 0x82, 0xe0, 0xb8, 0x2e, 0x1e, 0x3c, 0xa3, 0x9d, 0x8f, 0x5d, 0xe3, 0x45, 0xec, 0x80, 0x3d, 0x9d, 0x61, 0x43, 0xbd, 0x93, 0xca, 0x27, 0xfd, 0x6d, 0x29, 0x2d, 0xff, 0x7a, 0xe2, 0x13, 0xc1, 0xc1, 0x16, 0x62, 0x80, 0x7c, 0xa1, 0x38, 0x2b, 0x41, 0x2e, 0x3c, 0x4f, 0xf8, 0xc0, 0xd9, 0xd8, 0x96, 0x17, 0xbb, 0x42, 0x89, 0x74, 0x8c, 0x4b, 0x4c, 0x4b, 0xeb, 0x58, 0xfc, 0x12, 0x97, 0x1b, 0xc0, 0x98, 0xbe, 0x82, 0x33, 0x40, 0x92, 0x7b, 0xb2, 0x87, 0xf8, 0xca, 0x9e, 0xa8, 0x8a, 0x44, 0x49, 0xe5, 0x9d, 0x59, 0x37, 0x8d, 0xe9, 0x30, 0xaf, 0x46, 0x4f, 0xb0, 0xe3, 0xc7, 0xff, 0x89, 0x81, 0x33, 0xa7, 0x9e, 0xe2, 0x73, 0x1d, 0x97, 0x4d, 0x54, 0x62, 0xf9, 0xf6, 0x5d, 0x27, 0x56, 0xef, 0x72, 0xd5, 0x30, 0xfc, 0x5e, 0x9a, 0xc8, 0xb9, 0x32, 0x7b, 0xbd, 0x2f, 0x54, 0x2d, 0xa5, 0x40, 0x9f, 0xf8, 0xe4, 0xc8, 0x7a, 0x11, 0x6c, 0xdf, 0x39, 0xcb, 0xc1, 0x9d, 0xef, 0x40, 0x13, 0xac, 0x26, 0xb8, 0xa4, 0x21, 0xf8, 0x1d, 0x66, 0x46, 0xa7, 0xee, 0x2f, 0xa2, 0x4a, 0xf3, 0x9f, 0x0d, 0x63, 0x87, 0x6d, 0xe0, 0x4f, 0x41, 0x62, 0xad, 0xbb, 0x6a, 0x27, 0x70, 0x10, 0xd3, 0x8a, 0x84, 0x12, 0xb5, 0x17, 0xef, 0x72, 0x64, 0x87, 0xdd, 0xda, 0xca, 0x21, 0x52, 0x17, 0x83, 0x53, 0x70, 0x41, 0x7d, 0x93, 0x17, 0x9d, 0x30, 0x8a, 0x99, 0x79, 0xd1, 0xf2, 0x6a, 0x2d, 0x04, 0x65, 0x97, 0x07, 0x37, 0xc0, 0x7a, 0x16, 0xbf, 0x2a, 0x31, 0x52, 0xe2, 0x8c, 0x91, 0x70, 0xf5, 0x1c, 0xe1, 0xa3, 0xe4, 0x8d, 0x48, 0xbb, 0x41, 0xf1, 0x2f, 0x2a, 0x46, 0x9f, 0xa1, 0x20, 0x0b, 0x9e, 0xe9, 0xc5, 0x14, 0x37, 0x0e, 0x4f, 0x99, 0x3d, 0x3e, 0x6d, 0x33, 0x47, 0x02, 0x5e, 0xae, 0x29, 0x61, 0x16, 0x46, 0xe2, 0x37, 0x62, 0x44, 0xcc, 0x3d, 0xfe, 0x5e, 0xcf, 0xb6, 0x92, 0x09, 0x6a, 0x55, 0xa5, 0x20, 0x48, 0xd1, 0x37, 0x80, 0xa8, 0xf5, 0x37, 0x17, 0x36, 0x99, 0x1b, 0x49, 0x30, 0x99, 0x11, 0x6b, 0x29, 0x6b, 0x16, 0x5b, 0x63, 0x81, 0x74, 0xbc, 0xcb, 0xc8, 0x37, 0xff, 0xff, 0x61, 0x85, 0x3a, 0x50, 0xb7, 0xaf, 0x88, 0x38, 0x2f, 0xc1, 0x0b, 0xa6, 0xa8, 0xcc, 0x27, 0x19, 0x2e, 0xb0, 0x0c, 0xfb, 0x8e, 0xfa, 0xa4, 0x4f, 0xb2, 0x1c, 0x16, 0x8c, 0xc6, 0xae, 0x7b, 0x4e, 0xf4, 0x19, 0x27, 0x7e, 0xdb, 0xa6, 0x4b, 0xb0, 0x93, 0xa8, 0x46, 0x1c, 0x5b, 0xcc, 0x89, 0x37, 0x64, 0x04, 0x3c, 0x96, 0x74, 0xba, 0x60, 0x55, 0x74, 0x33, 0xbf, 0xbc, 0xad, 0x07, 0x35, 0xef, 0xbc, 0x6e, 0x49, 0x94, 0x47, 0xc3, 0xdb, 0x70, 0x53, 0x80, 0x08, 0xd1, 0x7d, 0x0e, 0xbc, 0x2c, 0x3c, 0xb1, 0x5d, 0x77, 0xae, 0x76, 0xb5, 0x5c, 0x5f, 0xf3, 0x3a, 0x5a, 0xfc, 0xad, 0x2d, 0x7b, 0x8e, 0xf5, 0x33, 0x60, 0x04, 0x6b, 0x9c, 0xec, 0x89, 0x5c, 0xa6, 0x5c, 0xb7, 0xfa, 0x2d, 0x09, 0xa7, 0x96, 0x7f, 0x84, 0xc6, 0x26, 0xae, 0x75, 0x46, 0x39, 0x2b, 0x4b, 0xd5, 0x26, 0x0c, 0x4e, 0x57, 0x30, 0xf8, 0x57, 0x3b, 0xb7, 0x2b, 0xfa, 0x7b, 0x45, 0x4e, 0xb8, 0xf0, 0x05, 0x76, 0x9d, 0xc1, 0xbe, 0x64, 0x59, 0xce, 0xc7, 0xbb, 0x55, 0xd2, 0x05, 0x15, 0x34, 0xc8, 0x52, 0x31, 0xdf, 0x43, 0x92, 0xe3, 0x3a, 0x09, 0x50, 0xe4, 0x18, 0x43, 0x0c, 0x42, 0xc0, 0x56, 0x80, 0x5c, 0xeb, 0xc0, 0x58, 0xec, 0x3e, 0x58, 0xc7, 0x0a, 0xd2, 0xb8, 0x06, 0x6a, 0xeb, 0xec, 0x30, 0xf8, 0x0a, 0xa5, 0xde, 0xa4, 0x4d, 0x87, 0xde, 0xc7, 0x36, 0x41, 0xb0, 0xea, 0xad, 0x5e, 0x00, 0x2a, 0x73, 0x9d, 0x92, 0x34, 0xae, 0x96, 0xfb, 0xb5, 0xb8, 0x05, 0xa6, 0x62, 0x33, 0xb6, 0xb5, 0xad, 0xa2, 0x0a, 0x06, 0x69, 0x5d, 0xcb, 0x47, 0xe8, 0x6a, 0xbc, 0x5f, 0x6c, 0xc8, 0xea, 0x60, 0x53, 0x9e, 0x42, 0x80, 0x37, 0x45, 0xc7, 0x3e, 0xfd, 0xa8, 0xb2, 0x3c, 0x4e, 0x77, 0xd0, 0x25, 0xb4, 0x5a, 0x24, 0xce, 0x55, 0xc9, 0xa7, 0x88, 0x83, 0x71, 0x8e, 0x67, 0xda, 0x3b, 0xd3, 0x4a, 0x45, 0xae, 0x57, 0xbe, 0x9b, 0x64, 0xf8, 0x98, 0x11, 0xbe, 0x17, 0xa9, 0xac, 0xbe, 0x79, 0x98, 0x38, 0xc7, 0x5d, 0x19, 0x9e, 0x96, 0x41, 0xa4, 0x5d, 0xc7, 0x97, 0xa6, 0x0b, 0x4d, 0xdf, 0x0a, 0xf3, 0x85, 0xb9, 0x57, 0x34, 0x4d, 0xd3, 0xb3, 0xdd, 0x69, 0x6f, 0x42, 0x5c, 0xf7, 0xb7, 0x36, 0xff, 0x1e, 0x2c, 0x7f, 0xe9, 0x6b, 0xb8, 0x44, 0x5e, 0xbe, 0xd3, 0xed, 0x1f, 0xed, 0x1d, 0x81, 0xf1, 0x5b, 0xb4, 0x10, 0xc9, 0x7f, 0x03, 0x7a, 0xaa, 0x03, 0x7f, 0x0e, 0x4e, 0xba, 0x8a, 0x6e, 0x76, 0x60, 0xd7, 0xb7, 0x9a, 0xc2, 0xbf, 0x72, 0x54, 0x39, 0x23, 0x67, 0x55, 0x31, 0x27, 0xf7, 0xb1, 0x96, 0xd9, 0x6e, 0x55, 0xeb, 0x4f, 0xd9, 0xca, 0xe6, 0x12, 0xa9, 0x12, 0xd8, 0x12, 0xba, 0x71, 0x5d, 0xff, 0x69, 0xf3, 0xc2, 0x54, 0x1e, 0xd6, 0xb8, 0x7f, 0x72, 0x0c, 0x7c, 0xa5, 0xaf, 0x74, 0xff, 0xcb, 0x35, 0x77, 0x33, 0x14, 0xc3, 0xdc, 0x4e, 0xe8, 0xd8, 0xf0, 0x95, 0x05, 0xef, 0x8c, 0xf1, 0xf3, 0x5f, 0x5a, 0xed, 0xbd, 0x1d, 0x3e, 0x8c, 0xf9, 0x51, 0xad, 0xef, 0x97, 0x57, 0xaf, 0x82, 0x3f, 0x96, 0x96, 0x4b, 0x8e, 0xe2, 0x3c, 0x80, 0x71, 0x24, 0xd7, 0x68, 0x6d, 0xda, 0x0c, 0x1f, 0xa8, 0x0c, 0x5c, 0x6c, 0x7d, 0x83, 0xab, 0x6f, 0x9f, 0x23, 0xee, 0xbb, 0xc1, 0xca, 0x4c, 0xb4, 0x04, 0xcc, 0xb6, 0x9b, 0x5b, 0x9f, 0x61, 0x57, 0xf8, 0x25, 0x10, 0xa9, 0x18, 0x9d, 0x2f, 0x77, 0xdd, 0xc4, 0xe7, 0xa7, 0x7e, 0x0b, 0x97, 0x28, 0xc3, 0x31, 0xd4, 0xd9, 0xf9, 0x18, 0x07, 0x43, 0x19, 0xdd, 0x81, 0x08, 0x43, 0x73, 0xe4, 0x69, 0x0e, 0x91, 0x0a, 0xf1, 0x88, 0xbb, 0x9b, 0xa2, 0x90, 0x9d, 0xd1, 0x95, 0xc8, 0x0f, 0xdf, 0x70, 0x36, 0x60, 0xcb, 0xb4, 0x2e, 0xca, 0x02, 0x95, 0x52, 0x64, 0x64, 0x62, 0x60, 0x3d, 0xb1, 0xaa, 0x1f, 0xbc, 0xd5, 0x56, 0x6c, 0x42, 0x92, 0xdd, 0xfc, 0xb6, 0x4c, 0x91, 0x6c, 0x33, 0x04, 0xad, 0x74, 0x89, 0x46, 0x5a, 0xef, 0xa7, 0xe8, 0x30, 0xd8, 0x63, 0x9d, 0x4f, 0xe5, 0x8e, 0xa3, 0x14, 0x31, 0x65, 0x4b, 0x37, 0xde, 0x88, 0x29, 0xa6, 0x3b, 0x6a, 0x87, 0x2b, 0x1c, 0xa3, 0x0e, 0xef, 0x6f, 0x2f, 0xa3, 0x6d, 0xad, 0x32, 0x5e, 0x69, 0xed, 0x00, 0x1b, 0x8b, 0x90, 0xc3, 0xfa, 0x52, 0xfe, 0xea, 0xb5, 0x9f, 0xc4, 0xc5, 0x46, 0x31, 0x61, 0xf7, 0xa1, 0x33, 0xf0, 0x7c, 0xbf, 0xb4, 0xa4, 0x58, 0x16, 0xd8, 0x88, 0xba, 0xef, 0xc1, 0x9b, 0x6d, 0x3c, 0x6d, 0x1a, 0x48, 0x3c, 0x4f, 0x0b, 0x2b, 0x5e, 0x67, 0xb6, 0x62, 0x17, 0x50, 0xe4, 0x69, 0xfb, 0x0c, 0x5c, 0xe7, 0x3f, 0xfa, 0x4f, 0x68, 0x6b, 0x27, 0x52, 0x7e, 0xdc, 0xa1, 0xf3, 0x8e, 0xeb, 0x67, 0x06, 0xe0, 0xee, 0xe8, 0x13, 0xab, 0xa1, 0x6c, 0xe1, 0x3b, 0x19, 0x2f, 0xed, 0xa8, 0xe0, 0x57, 0x4f, 0x28, 0xd6, 0x67, 0xd2, 0x33, 0x7d, 0xb5, 0x54, 0x41, 0x79, 0x5a, 0x8e, 0xbd, 0x74, 0xeb, 0x50, 0x01, 0xf2, 0x59, 0x0b, 0xa0, 0x84, 0xbd, 0x9c, 0xcb, 0x18, 0xf0, 0x89, 0x17, 0xef, 0x54, 0x33, 0x7b, 0x08, 0xda, 0x59, 0xaa, 0x60, 0x83, 0xa2, 0x5c, 0xdc, 0x3d, 0xae, 0x38, 0xf8, 0x2f, 0x73, 0xfb, 0x25, 0x4b, 0x97, 0xee, 0xfd, 0xc6, 0x50, 0x4a, 0x50, 0xc8, 0x40, 0x0e, 0x49, 0xd1, 0x29, 0x0a, 0xc9, 0xf3, 0x87, 0x6d, 0x0b, 0x0f, 0x90, 0x7b, 0x77, 0xeb, 0x1f, 0x31, 0x23, 0x9b, 0x7d, 0xfd, 0xa8, 0x83, 0xe8, 0x93, 0x01, 0x29, 0x52, 0x10, 0xb0, 0x9e, 0x74, 0x52, 0x87, 0x92, 0x96, 0x1a, 0xf5, 0xf2, 0x99, 0xf0, 0x96, 0xe8, 0x08, 0xd2, 0xcc, 0x54, 0x5a, 0xe1, 0xd8, 0xf6, 0x42, 0xc2, 0xb6, 0x20, 0x7e, 0x41, 0x33, 0xb5, 0xdf, 0xde, 0x20, 0x0a, 0x94, 0x8b, 0x7f, 0xec, 0x23, 0x29, 0x77, 0xfb, 0xda, 0xc9, 0x53, 0x28, 0x5e, 0x45, 0x0a, 0xd6, 0xa3, 0x13, 0x45, 0x17, 0x24, 0x22, 0xa3, 0x7e, 0x2a, 0xf2, 0x78, 0xce, 0x9b, 0x78, 0xc9, 0xe5, 0x22, 0xad, 0x6b, 0xcd, 0xcb, 0xc6, 0x7b, 0x41, 0xce, 0x38, 0x38, 0x46, 0x6a, 0xe0, 0xff, 0xc7, 0x42, 0x06, 0x1a, 0x38, 0xe0, 0xa1, 0x92, 0xab, 0x4b, 0x79, 0xf2, 0x22, 0x1b, 0x86, 0xeb, 0x9c, 0x2c, 0xcd, 0x75, 0x3d, 0xc3, 0xe8, 0x6c, 0x2f, 0xb0, 0x51, 0x70, 0x9f, 0x5f, 0x08, 0x9c, 0xb1, 0x15, 0x12, 0x75, 0x60, 0xfc, 0x15, 0x15, 0x95, 0x90, 0x55, 0x42, 0x3a, 0xc4, 0x2a, 0x25, 0x98, 0x89, 0x74, 0xbe, 0x5c, 0x4b, 0xd7, 0xcb, 0xa8, 0xed, 0x36, 0xe3, 0x82, 0x41, 0xd3, 0x7e, 0x57, 0xb7, 0x06, 0x36, 0x6e, 0xcf, 0xbb, 0x04, 0xbc, 0xa0, 0xfa, 0x61, 0xcb, 0x29, 0x8a, 0x49, 0xbb, 0x70, 0xc1, 0x9e, 0xc7, 0xea, 0xe3, 0xd5, 0xfb, 0x8c, 0xff, 0xee, 0xc4, 0x7e, 0x0f, 0xe0, 0x7a, 0xd9, 0xc3, 0x81, 0x2d, 0x97, 0x4a, 0x1f, 0x6a, 0xd2, 0x1f, 0xa3, 0x36, 0x05, 0x84, 0xda, 0xa8, 0x24, 0x8b, 0x73, 0x64, 0x18, 0xa2, 0x05, 0x5a, 0x6c, 0x87, 0xfc, 0x94, 0x4a, 0x41, 0x6e, 0x13, 0xbd, 0x5c, 0x4b, 0xa6, 0x17, 0x08, 0xaa, 0x8d, 0x99, 0xe1, 0xb2, 0x2b, 0x77, 0x37, 0x0f, 0xd0, 0x72, 0x24 }; +constexpr AccessUnit ATRACX_SIZE_MISMATCH_EXPECTED_AU = { 0x15f90, 0x159b2, false, 0, {}, { 0x71, 0x4c, 0x99, 0x14, 0x4a, 0x0d, 0x1d, 0xe6, 0x05, 0x5c, 0x64, 0xa7, 0xa0, 0xd6, 0x4b, 0x56, 0x87, 0xe4, 0x5d, 0x61 } }; + +const std::vector AC3_SIZE_MISMATCH_STREAM = { 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xbd, 0x06, 0xe6, 0x81, 0xc1, 0x0d, 0x31, 0x00, 0x05, 0xbf, 0x21, 0x11, 0x00, 0x05, 0xb3, 0x65, 0x1e, 0x69, 0xb2, 0x30, 0x00, 0x00, 0x00, 0x0b, 0x77, 0x31, 0xfd, 0x1c, 0x4b, 0x30, 0xa2, 0xe6, 0x40, 0x35, 0x38, 0xe1, 0xea, 0xc9, 0xcb, 0x6d, 0x24, 0x95, 0x8e, 0x57, 0xe6, 0xfc, 0x72, 0xf4, 0x35, 0xca, 0x6d, 0x13, 0x5a, 0x24, 0xa4, 0x03, 0x6e, 0x1d, 0x22, 0x04, 0xc8, 0xdc, 0xa5, 0x99, 0x12, 0x6d, 0xc6, 0x69, 0x0e, 0x5e, 0x59, 0x09, 0x64, 0x9d, 0xa7, 0x5e, 0xc2, 0x7f, 0xe8, 0x0f, 0xe9, 0x09, 0xc5, 0x5f, 0xe7, 0x52, 0x84, 0x3a, 0xdf, 0xf7, 0x73, 0x53, 0x36, 0x46, 0xc9, 0x02, 0xf5, 0x33, 0xc9, 0x73, 0x46, 0xe2, 0x68, 0xbd, 0xf5, 0x51, 0x86, 0xd9, 0x16, 0x54, 0x38, 0x35, 0xf5, 0xf6, 0xe5, 0x0b, 0xa4, 0xe3, 0xcb, 0xea, 0x2d, 0x55, 0x22, 0xcb, 0xf8, 0xbc, 0x8f, 0x53, 0xa4, 0xf9, 0xaa, 0x85, 0x4f, 0x7e, 0xab, 0xec, 0x25, 0xca, 0x27, 0x9c, 0xc6, 0x99, 0xbf, 0xb0, 0x68, 0x5d, 0x57, 0xb8, 0x60, 0x0a, 0xa6, 0x95, 0xeb, 0xdf, 0x64, 0x11, 0x73, 0x18, 0x6e, 0x64, 0x19, 0xd3, 0x7b, 0x52, 0xc9, 0x05, 0x18, 0x39, 0x20, 0xb2, 0x07, 0xf0, 0x87, 0xe7, 0xff, 0xa3, 0x3a, 0x4b, 0xa4, 0xf2, 0xce, 0xcf, 0xf5, 0xcc, 0x0f, 0xdf, 0x67, 0x31, 0x8c, 0x77, 0x99, 0x81, 0x28, 0xa9, 0x58, 0xd3, 0x55, 0x8e, 0xdc, 0xb6, 0xae, 0x9f, 0x1f, 0x3b, 0xb8, 0x45, 0x97, 0xfb, 0x7b, 0xc1, 0x27, 0x4e, 0x65, 0xcc, 0xc7, 0xa5, 0xea, 0xd2, 0x0e, 0xbf, 0x68, 0x9a, 0xb5, 0x4e, 0xee, 0x2e, 0xc7, 0x18, 0x5a, 0x89, 0x3d, 0x54, 0x0d, 0x62, 0x6d, 0x68, 0x71, 0x91, 0xc4, 0x05, 0x4e, 0xd5, 0x11, 0x8e, 0x16, 0xe3, 0x54, 0xd2, 0xa4, 0x30, 0xf4, 0xde, 0xfc, 0xdc, 0x85, 0xf0, 0xf4, 0x0a, 0xb4, 0xd5, 0xfb, 0xc7, 0xff, 0x65, 0xfe, 0x1c, 0x4f, 0xda, 0xfc, 0x38, 0x77, 0xc4, 0xfc, 0xfe, 0xe4, 0x78, 0x25, 0xe6, 0xd4, 0x0c, 0x43, 0x51, 0xea, 0x9d, 0x46, 0xb2, 0xd6, 0x9e, 0xc2, 0x82, 0x5f, 0xbb, 0x0e, 0xfb, 0xb6, 0xf4, 0x7a, 0x54, 0x92, 0x08, 0x8d, 0xcf, 0xae, 0x37, 0x63, 0x18, 0xc1, 0xf3, 0xa9, 0xa2, 0x8f, 0x7c, 0xd1, 0x06, 0xfe, 0xfc, 0x4d, 0xdc, 0xb1, 0x6b, 0x42, 0xa1, 0xaf, 0xc6, 0x4a, 0xd4, 0x3b, 0x4a, 0xad, 0xb4, 0x16, 0x9b, 0x39, 0x85, 0x29, 0x97, 0xd0, 0x94, 0xc6, 0x48, 0x6c, 0x2f, 0xa9, 0x19, 0x48, 0x62, 0x8d, 0x3b, 0x8b, 0xec, 0x0b, 0xa7, 0xca, 0xd0, 0x11, 0x93, 0xe3, 0xb8, 0x50, 0x93, 0x16, 0x42, 0xe9, 0x4f, 0x8c, 0x43, 0xfe, 0x6b, 0xcc, 0x17, 0x06, 0x18, 0x3b, 0xd3, 0xd1, 0xb0, 0xb4, 0xa5, 0x4c, 0xb3, 0xaa, 0x04, 0xbf, 0xc3, 0x08, 0xe1, 0x7d, 0xae, 0xa4, 0x5f, 0x95, 0xf3, 0x17, 0x62, 0x9c, 0x64, 0x5f, 0x26, 0x4f, 0x06, 0xed, 0x4e, 0x79, 0x18, 0x03, 0x4b, 0xb8, 0x61, 0xbb, 0x5a, 0xae, 0x51, 0xc3, 0x32, 0x67, 0xe5, 0xc2, 0x5a, 0x03, 0x2e, 0xee, 0xf8, 0x07, 0x4b, 0x06, 0x47, 0xe2, 0x6b, 0x0e, 0x08, 0xa7, 0xab, 0x1e, 0xa0, 0xf4, 0x85, 0x87, 0xb9, 0xec, 0xf7, 0x53, 0x8b, 0xbf, 0xf3, 0x4e, 0xb6, 0x5f, 0x00, 0x32, 0x5c, 0x07, 0xce, 0xc6, 0x9a, 0x24, 0xb7, 0x9e, 0x31, 0x20, 0xb5, 0x54, 0x79, 0x0e, 0x53, 0xca, 0x95, 0x09, 0xc9, 0x12, 0x8a, 0xb5, 0xed, 0xab, 0xc8, 0xb4, 0xdb, 0x76, 0x13, 0xb5, 0x10, 0x0a, 0x45, 0x78, 0xd4, 0xc5, 0x81, 0x3a, 0x11, 0x99, 0x14, 0x44, 0x43, 0x19, 0x6f, 0x16, 0x77, 0xd7, 0x14, 0xeb, 0x59, 0xb3, 0x55, 0xae, 0x69, 0xc9, 0x72, 0xd7, 0xb6, 0x50, 0x2a, 0xc2, 0xe0, 0x27, 0x72, 0xc7, 0xcf, 0xc5, 0x42, 0x32, 0x38, 0x92, 0xf3, 0x1a, 0x46, 0x90, 0x90, 0xa5, 0x5d, 0xf6, 0x46, 0xf7, 0x3e, 0x0c, 0x1a, 0x6e, 0x71, 0x2b, 0x30, 0xe0, 0x46, 0x6b, 0x9a, 0xc6, 0x2b, 0xb2, 0x89, 0xdb, 0x52, 0xe9, 0x5a, 0x58, 0x9b, 0x50, 0xb5, 0x75, 0xe1, 0xfa, 0x66, 0xf3, 0x69, 0x1e, 0x78, 0x90, 0x8e, 0x4c, 0x0c, 0xd4, 0xe7, 0x9d, 0xbc, 0x02, 0x8b, 0x2a, 0xfb, 0xca, 0x6d, 0x68, 0x28, 0x1e, 0x47, 0x08, 0x24, 0xe3, 0xce, 0x05, 0x60, 0x0e, 0xe1, 0xf7, 0x17, 0x13, 0xbd, 0xd3, 0x97, 0x78, 0x9b, 0xd5, 0x5a, 0x61, 0x4a, 0x16, 0x41, 0xb9, 0x37, 0xa4, 0x92, 0xe5, 0xc5, 0x99, 0x73, 0xf6, 0x14, 0xcd, 0xfd, 0x7a, 0x9e, 0x6c, 0x39, 0x00, 0x9a, 0xb1, 0x77, 0x7e, 0x78, 0x11, 0xef, 0x63, 0xec, 0xcc, 0x47, 0x71, 0xed, 0xd5, 0x64, 0xa5, 0xe6, 0xc7, 0xf9, 0x6c, 0xf0, 0x6d, 0x7b, 0x3a, 0x78, 0x4e, 0x8e, 0x8e, 0x9c, 0xbd, 0x69, 0x62, 0xdc, 0xec, 0xd1, 0xe0, 0xe1, 0x8f, 0x7f, 0x4e, 0x57, 0x7a, 0x7e, 0xa6, 0x25, 0x7d, 0xfa, 0xee, 0x6a, 0x7c, 0x67, 0x79, 0x80, 0x83, 0xb7, 0x7e, 0xb0, 0x4b, 0xba, 0x2f, 0x97, 0xba, 0x90, 0xae, 0x1a, 0xe5, 0x28, 0xea, 0xf6, 0x18, 0xe8, 0xc7, 0xfb, 0xb8, 0xa9, 0xa0, 0x0f, 0x15, 0x34, 0x14, 0x92, 0xfe, 0x84, 0x9b, 0x76, 0x83, 0xba, 0xe4, 0x07, 0xd6, 0x4e, 0x7f, 0xa7, 0xfc, 0x42, 0xd2, 0x50, 0x37, 0x96, 0x25, 0xe3, 0x2e, 0xfd, 0x4c, 0xdc, 0xbe, 0x6b, 0x09, 0x49, 0xa5, 0x46, 0xa9, 0xdd, 0x96, 0x70, 0x5c, 0x30, 0x6d, 0xbf, 0x5a, 0x3c, 0xda, 0x39, 0x56, 0xe4, 0x42, 0x73, 0x99, 0xcf, 0x1c, 0x0b, 0x2d, 0x22, 0x8d, 0x6e, 0xd0, 0x1e, 0xb9, 0x6c, 0x90, 0xc8, 0xfd, 0xe2, 0xe8, 0xdc, 0x81, 0x14, 0x34, 0xdd, 0x59, 0xdf, 0xce, 0xc0, 0x05, 0x43, 0xb6, 0x49, 0xbd, 0x15, 0xd0, 0xe9, 0xea, 0x3b, 0x46, 0xe3, 0x88, 0xe8, 0xa2, 0x0a, 0xf4, 0x28, 0xf1, 0xc5, 0xa4, 0xdd, 0x8b, 0x06, 0xe2, 0x84, 0x93, 0xa2, 0xc1, 0x87, 0xdd, 0x3f, 0x49, 0x4b, 0x88, 0x58, 0x2c, 0x93, 0x3c, 0x89, 0xb9, 0x30, 0xda, 0x8b, 0x22, 0x23, 0x35, 0x57, 0x3e, 0x2c, 0xe9, 0x09, 0x2c, 0xd0, 0x3a, 0x12, 0xe7, 0x9b, 0xb0, 0xd5, 0x3c, 0x12, 0xc3, 0x7c, 0x41, 0x51, 0x5b, 0x58, 0x3e, 0xf0, 0x0c, 0x90, 0x26, 0xa5, 0xab, 0xe9, 0x50, 0x6b, 0x50, 0x89, 0x0d, 0x66, 0xc0, 0x82, 0x5e, 0x49, 0xd2, 0x55, 0xea, 0xbc, 0x8f, 0x98, 0x21, 0x91, 0xad, 0xed, 0x23, 0x58, 0xda, 0xa9, 0x7f, 0xa6, 0xd5, 0xca, 0x63, 0x37, 0x72, 0x95, 0x6e, 0x76, 0xc7, 0x0c, 0x6e, 0xe1, 0xa9, 0x5e, 0x91, 0x66, 0xab, 0xa3, 0x63, 0xa1, 0xc0, 0xd9, 0x6a, 0x28, 0x79, 0xdd, 0xf1, 0xb1, 0x8a, 0x8f, 0x3c, 0xee, 0x62, 0x22, 0x73, 0x72, 0xb4, 0xfa, 0x2d, 0x1a, 0x2e, 0x72, 0x97, 0xb0, 0x8f, 0x78, 0x8c, 0x8e, 0xd8, 0xa7, 0xfb, 0xb4, 0xfa, 0x78, 0xee, 0x16, 0x6c, 0x8c, 0x7e, 0x64, 0xc3, 0xe6, 0xef, 0x3b, 0xbb, 0x95, 0xbb, 0xc4, 0x92, 0xaf, 0x9d, 0x0a, 0xca, 0xd5, 0x29, 0xf8, 0x51, 0x2f, 0xbf, 0x53, 0xc3, 0x6f, 0x0d, 0x90, 0x7e, 0x82, 0x05, 0x01, 0xfb, 0xee, 0x15, 0x8b, 0x04, 0xcc, 0xae, 0xb6, 0x7c, 0x57, 0x58, 0xba, 0x6a, 0xfc, 0x17, 0x40, 0x3b, 0x1c, 0x08, 0xed, 0xb9, 0xdf, 0x70, 0x4f, 0x3b, 0x02, 0xbf, 0x2d, 0x5f, 0x06, 0x74, 0x34, 0x45, 0x41, 0x4f, 0xef, 0x40, 0x79, 0x02, 0x57, 0x0d, 0x74, 0xd7, 0x2a, 0x03, 0x92, 0xa1, 0xa8, 0x03, 0xc2, 0x4e, 0x34, 0x82, 0xf5, 0x70, 0x6d, 0x00, 0x6b, 0x3a, 0xc3, 0x87, 0x73, 0x74, 0xec, 0xa4, 0xf6, 0xd7, 0xda, 0x8f, 0x4d, 0xef, 0x73, 0x79, 0x3e, 0x1b, 0x45, 0xcb, 0x27, 0x10, 0x5b, 0xc8, 0xe7, 0xd4, 0x88, 0x7d, 0x45, 0xdd, 0x12, 0x26, 0xf1, 0x66, 0x7e, 0xfd, 0xa9, 0xb7, 0x71, 0xd8, 0xbd, 0x43, 0x69, 0x51, 0xe4, 0x37, 0xcd, 0x27, 0x21, 0x9a, 0x73, 0xef, 0xf0, 0x7f, 0x76, 0xbf, 0xfe, 0x15, 0xbd, 0x68, 0x6e, 0x6e, 0xbc, 0xf8, 0xad, 0x76, 0xd5, 0x19, 0xd0, 0x01, 0x0c, 0xa1, 0xe1, 0x9e, 0xdd, 0x61, 0x37, 0xe8, 0x80, 0x08, 0xcb, 0x21, 0x4a, 0xf9, 0x2c, 0x32, 0xf4, 0x30, 0x9e, 0x51, 0x2a, 0x7f, 0xda, 0x74, 0x72, 0x23, 0x7f, 0x33, 0xa7, 0xe8, 0xa6, 0x18, 0xe5, 0x3c, 0xa6, 0x11, 0x1c, 0x43, 0x1f, 0x4f, 0xb0, 0xb6, 0x15, 0x8b, 0x89, 0x6e, 0xb8, 0xc3, 0x97, 0xe3, 0xe5, 0x65, 0x32, 0x0a, 0xe4, 0xae, 0x28, 0x4d, 0x76, 0x33, 0x66, 0x8a, 0x58, 0x36, 0xce, 0xa3, 0xab, 0x36, 0x3f, 0x42, 0x21, 0xa8, 0xa9, 0x8f, 0xe5, 0x6b, 0x75, 0x36, 0x4e, 0x60, 0x8f, 0x06, 0x1d, 0x19, 0x9d, 0x99, 0xba, 0x34, 0xe7, 0xe9, 0x6c, 0xd7, 0x90, 0xc7, 0x3d, 0x12, 0x9b, 0xc8, 0x6b, 0x11, 0xb5, 0x46, 0xf0, 0x1b, 0x1d, 0xdb, 0xe3, 0xc0, 0x3d, 0x2f, 0x85, 0xa9, 0x64, 0xe2, 0x74, 0xa7, 0x2d, 0xe1, 0x81, 0x6b, 0x96, 0xa2, 0x81, 0xba, 0xd4, 0x5c, 0x95, 0xc8, 0xa3, 0xc1, 0x95, 0x65, 0x5d, 0x91, 0xca, 0xa6, 0x9e, 0x1d, 0x1b, 0x41, 0x3a, 0x9a, 0x68, 0x9f, 0x51, 0x59, 0x1a, 0x81, 0xe0, 0x46, 0x02, 0x46, 0xfd, 0x11, 0xe5, 0x48, 0x86, 0xde, 0x7d, 0xed, 0x3c, 0xb1, 0x0d, 0x81, 0x1d, 0x13, 0x47, 0x0c, 0xda, 0xd8, 0xe0, 0xac, 0x42, 0xb8, 0x0b, 0x29, 0x73, 0x36, 0xe8, 0xaf, 0x95, 0xf3, 0xce, 0xdf, 0xe1, 0xd7, 0x62, 0xe3, 0xac, 0x53, 0x8d, 0x7b, 0x63, 0x13, 0x3b, 0xdc, 0xd3, 0x9a, 0xc9, 0x3f, 0x71, 0x2d, 0x3e, 0xef, 0x48, 0x82, 0x15, 0xe6, 0xb7, 0xbb, 0x56, 0xd6, 0x7d, 0xda, 0xb3, 0x97, 0x39, 0x96, 0xc5, 0xa6, 0x66, 0x8b, 0xb1, 0x94, 0x93, 0x40, 0xa5, 0xc2, 0x52, 0x34, 0x04, 0xce, 0xeb, 0xf4, 0x93, 0x37, 0xa5, 0xa6, 0xd0, 0xef, 0x38, 0x74, 0x19, 0x82, 0x7d, 0x77, 0x47, 0x8c, 0xac, 0x33, 0x82, 0x2b, 0x23, 0x71, 0x28, 0xb0, 0xa5, 0x93, 0xc2, 0x30, 0x5b, 0x6e, 0x30, 0xa8, 0xcc, 0x42, 0x59, 0x10, 0xb9, 0x91, 0x1f, 0xe0, 0x2c, 0x5d, 0x54, 0x1e, 0xef, 0x03, 0x3d, 0x76, 0xb4, 0x6e, 0xc3, 0x0a, 0x6a, 0x35, 0xac, 0xda, 0x96, 0xfa, 0xb5, 0x33, 0x48, 0xe1, 0x2f, 0x2d, 0x7d, 0xec, 0x53, 0x6e, 0xfe, 0xa5, 0x50, 0x2f, 0x9b, 0x00, 0x22, 0xed, 0x02, 0x90, 0xe1, 0xa1, 0xb8, 0x5d, 0x86, 0x28, 0xac, 0x45, 0xee, 0xfa, 0x84, 0x72, 0x30, 0xe8, 0xe7, 0x21, 0x65, 0xe6, 0xcc, 0x3c, 0x99, 0x35, 0x97, 0x25, 0xd8, 0x86, 0x49, 0x14, 0xde, 0x2e, 0x5e, 0x1c, 0xf7, 0x8f, 0x2c, 0xd1, 0x5d, 0x83, 0x9a, 0x43, 0xf8, 0x6c, 0x93, 0xdd, 0x8a, 0x51, 0xab, 0xd4, 0x3b, 0x28, 0xa8, 0x02, 0x40, 0x94, 0x67, 0x23, 0x83, 0x7b, 0xff, 0xc2, 0xcd, 0x2a, 0x06, 0x05, 0x9e, 0xae, 0x0f, 0x5f, 0xfa, 0x80, 0x2a, 0xa9, 0x25, 0xab, 0x32, 0x38, 0x4a, 0x19, 0x2b, 0x51, 0x57, 0xb1, 0x15, 0xba, 0x1b, 0x1d, 0x0b, 0xee, 0xfb, 0xe5, 0xe1, 0x31, 0x10, 0x63, 0x36, 0x56, 0x0a, 0xd9, 0x13, 0xfe, 0x85, 0x0a, 0xf0, 0x8e, 0x2b, 0xc0, 0x9e, 0xf8, 0x90, 0xc5, 0x9d, 0xf3, 0x8c, 0x2f, 0xb8, 0x3f, 0x67, 0x46, 0x8c, 0xec, 0xab, 0xac, 0x29, 0xcf, 0x5d, 0x6b, 0x26, 0x94, 0x9a, 0x90, 0x65, 0x6a, 0x7f, 0x76, 0xad, 0xc2, 0x88, 0x31, 0xcc, 0x10, 0xaa, 0xf2, 0x26, 0xc8, 0x0c, 0x30, 0xf0, 0x9d, 0xcd, 0xf0, 0x9c, 0xfe, 0xb3, 0x34, 0x4f, 0x7f, 0x9d, 0x8d, 0xdb, 0x46, 0x04, 0x2c, 0x8a, 0xa3, 0x1a, 0xab, 0x9a, 0xa6, 0x7f, 0xad, 0xec, 0x05, 0x76, 0x43, 0xd5, 0x42, 0x94, 0x2c, 0xea, 0x4e, 0x2a, 0x89, 0x11, 0x4a, 0x0b, 0x3c, 0x80, 0xde, 0x86, 0x61, 0x90, 0x9d, 0x2a, 0x44, 0xe7, 0xcf, 0x8c, 0xae, 0xce, 0xf0, 0xa8, 0xeb, 0xaf, 0x8d, 0xd9, 0xd0, 0x09, 0xb8, 0xce, 0x28, 0x0e, 0x28, 0xe0, 0xeb, 0x7b, 0x7c, 0x44, 0xc4, 0x91, 0x02, 0x34, 0xdc, 0x27, 0xbf, 0xd4, 0x75, 0x7a, 0xa5, 0x4f, 0x6b, 0x70, 0xf5, 0x96, 0x80, 0x43, 0xe0, 0xb3, 0x93, 0x06, 0xc0, 0xdc, 0x29, 0x14, 0x3e, 0x80, 0x82, 0x95, 0x03, 0xf8, 0xe5, 0xbf, 0x95, 0xe9, 0x9c, 0xdc, 0xbf, 0xc6, 0xac, 0xb6, 0x0f, 0xb7, 0x95, 0xc9, 0x8e, 0x15, 0xc7, 0x9c, 0x1f, 0xd4, 0xae, 0xfe, 0xa1, 0xe8, 0x19, 0x72, 0xb4, 0xd1, 0x14, 0x49, 0xe3, 0x53, 0x9a, 0x3a, 0x30, 0x45, 0x2c, 0xa0, 0xf0, 0x21, 0xc8, 0xee, 0x61, 0x8e, 0x2a, 0xa3, 0x1b, 0xfd, 0xd7, 0xf4, 0x04, 0xd6, 0xa6, 0xa4, 0xb7, 0x1e, 0x13, 0x5c, 0x5a, 0x0e, 0xf8, 0x7b, 0xb6, 0x10, 0x07, 0x35, 0xc4, 0x1b, 0x50, 0xa9, 0xd9, 0x9b, 0xdb, 0xa8, 0xf0, 0x67, 0xa8, 0x3e, 0x50, 0x71, 0x32, 0xfb, 0x37, 0xfe, 0x51, 0xff, 0x18, 0x57, 0x3a, 0xce, 0x7f, 0x50, 0x5c, 0xb2, 0xd6, 0xd8, 0xc1, 0xb4, 0x71, 0xe6, 0x49, 0xf1, 0x39, 0xad, 0x9b, 0xea, 0x2e, 0x8f, 0x68, 0x6d, 0x05, 0x34, 0x30, 0x9d, 0x72, 0x7c, 0x50, 0x98, 0xcc, 0x55, 0x18, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xbd, 0x06, 0xe6, 0x81, 0xc1, 0x0d, 0x31, 0x00, 0x05, 0xbf, 0x21, 0x11, 0x00, 0x05, 0xb3, 0x65, 0x1e, 0x69, 0xb2, 0x30, 0x00, 0x00, 0x00, 0x1d, 0x0b, 0x3f, 0xee, 0x73, 0x16, 0x75, 0x44, 0x00, 0x0f, 0x64, 0xd1, 0x17, 0xe7, 0x11, 0xdc, 0x36, 0x45, 0xe8, 0x21, 0x49, 0x4b, 0x34, 0x34, 0xc7, 0x5a, 0x5d, 0x6e, 0xbd, 0x78, 0xae, 0xcd, 0x9d, 0xe4, 0xe3, 0xfc, 0x3c, 0x3c, 0x75, 0x39, 0x2e, 0xb3, 0x7b, 0xea, 0x8f, 0xd8, 0x26, 0xca, 0x15, 0x60, 0xd2, 0x25, 0x61, 0xf9, 0x0b, 0x6a, 0x6b, 0x98, 0xc3, 0x6b, 0x8c, 0xeb, 0x17, 0xa5, 0x44, 0x7a, 0xe0, 0x82, 0xc5, 0xc8, 0xc2, 0xb5, 0xdd, 0x62, 0x10, 0xce, 0x4c, 0xa8, 0x1f, 0x5d, 0xe1, 0x84, 0xdd, 0xa4, 0x45, 0xdf, 0x0c, 0xb1, 0xb8, 0x93, 0x2b, 0x4d, 0x72, 0x4d, 0x1c, 0x4b, 0xbe, 0x9c, 0x89, 0xfa, 0xdf, 0xb4, 0x10, 0x9b, 0x67, 0x40, 0xa2, 0xaf, 0x44, 0xd2, 0x3f, 0xe1, 0x8d, 0xbb, 0xa0, 0x3f, 0x04, 0xf5, 0xd2, 0x29, 0x7d, 0x2e, 0xfa, 0x10, 0x0f, 0x1d, 0x94, 0xa1, 0x69, 0x0f, 0x42, 0x69, 0x21, 0xb0, 0xf3, 0x7a, 0x0a, 0xb3, 0xee, 0xc6, 0x31, 0x48, 0xb8, 0xda, 0xb7, 0x1a, 0xcf, 0xdb, 0x7f, 0x77, 0x5e, 0x10, 0xa3, 0x7b, 0xfa, 0x4e, 0x51, 0x9d, 0x20, 0x92, 0x11, 0x15, 0x2e, 0xed, 0x22, 0x77, 0x17, 0x3d, 0xf9, 0x98, 0x3f, 0x86, 0x9f, 0x96, 0x62, 0xbf, 0xdf, 0x1c, 0xb9, 0x46, 0xfa, 0xa0, 0xf5, 0x6c, 0x08, 0x9f, 0x61, 0x9a, 0x79, 0x6b, 0xc2, 0x4b, 0x47, 0xfc, 0x8d, 0xfd, 0x49, 0x10, 0x63, 0x32, 0x5b, 0x78, 0xd7, 0x36, 0x75, 0x42, 0x86, 0xba, 0xf4, 0x23, 0x12, 0xe1, 0xa2, 0x4d, 0x8f, 0x33, 0x0d, 0xb6, 0xe6, 0x87, 0x93, 0x8b, 0xdd, 0x01, 0x60, 0x80, 0xb3, 0xe9, 0xa5, 0x8f, 0xd4, 0x91, 0x5d, 0x8f, 0xd5, 0x52, 0x75, 0x11, 0xae, 0xb1, 0xd1, 0x3b, 0x18, 0x01, 0x6b, 0x83, 0xba, 0xa9, 0x9d, 0xa5, 0x8d, 0x4d, 0xe9, 0x7c, 0x11, 0x19, 0x45, 0x30, 0xb7, 0xbb, 0xd2, 0x07, 0x60, 0x92, 0x54, 0x2f, 0xb4, 0xe3, 0xa1, 0xb2, 0xa6, 0xf9, 0x14, 0xb5, 0xc4, 0x30, 0x7a, 0x4d, 0x27, 0x1c, 0x2f, 0xfc, 0xbf, 0x34, 0xa6, 0xa8, 0xf4, 0x78, 0x0f, 0x16, 0x27, 0xeb, 0xac, 0xd7, 0x0f, 0x6a, 0xac, 0xf4, 0x4a, 0x73, 0xff, 0x30, 0x2b, 0xeb, 0x6a, 0x92, 0xd3, 0x09, 0xc4, 0xcd, 0x8a, 0x74, 0x3c, 0x6d, 0x61, 0x18, 0xd2, 0xcb, 0x61, 0xfb, 0x0c, 0x61, 0x6d, 0xb2, 0xe9, 0x1e, 0xfb, 0x8b, 0x15, 0xc3, 0x84, 0xdd, 0x7b, 0x34, 0xd7, 0x81, 0x99, 0xae, 0x1f, 0xce, 0xc3, 0x61, 0x95, 0x27, 0x5d, 0x25, 0xb2, 0x41, 0x7f, 0x9e, 0x21, 0xc7, 0xb9, 0x56, 0x6b, 0x41, 0xcd, 0x19, 0xef, 0xaa, 0x85, 0x14, 0x62, 0x53, 0xde, 0x13, 0x52, 0x8d, 0x25, 0x4b, 0xf8, 0xad, 0x8d, 0x09, 0xfb, 0x86, 0x30, 0xcf, 0xb5, 0xb9, 0xc8, 0x4e, 0x2b, 0x45, 0x74, 0x03, 0x87, 0xde, 0x51, 0x28, 0x65, 0x20, 0xfc, 0xf1, 0x27, 0x73, 0x7a, 0xfb, 0xff, 0xa6, 0x2f, 0x82, 0xb1, 0xe1, 0xca, 0xb7, 0x92, 0x60, 0x4e, 0xfd, 0xf6, 0x4f, 0x48, 0x4e, 0xfe, 0xd8, 0x80, 0xaf, 0xc7, 0xb2, 0xc4, 0xa1, 0x82, 0x86, 0x7d, 0x4b, 0x1e, 0x3c, 0xac, 0x76, 0xc5, 0x9b, 0x9b, 0x46, 0x5f, 0xdc, 0x67, 0xde, 0xa1, 0x04, 0x2a, 0x1e, 0x6e, 0x7f, 0xf8, 0x92, 0x60, 0x4d, 0xa4, 0x09, 0x1b, 0xeb, 0x38, 0x70, 0x5a, 0xd5, 0xa0, 0x61, 0xae, 0xf7, 0x7b, 0xcd, 0xa6, 0xe8, 0x75, 0x81, 0xb4, 0x11, 0x8b, 0xa0, 0x1e, 0x3a, 0xeb, 0x3a, 0xa8, 0x57, 0xcb, 0x61, 0xa2, 0x7a, 0x59, 0x91, 0xc1, 0x4e, 0x1a, 0x17, 0x22, 0x68, 0xd9, 0x9e, 0xa1, 0x82, 0xb4, 0xf9, 0xd4, 0x22, 0x32, 0xc5, 0x2f, 0x5f, 0xd5, 0xee, 0x73, 0xef, 0x81, 0xf1, 0x86, 0x3d, 0x73, 0xc2, 0xd0, 0x39, 0x2f, 0xe8, 0x1c, 0xb4, 0xbf, 0x28, 0xdb, 0xe6, 0xc0, 0xd2, 0xff, 0x03, 0xdb, 0xa2, 0xe6, 0x68, 0x2e, 0xfa, 0x67, 0xd4, 0x21, 0x25, 0xa6, 0xce, 0x5c, 0x97, 0xb8, 0x7d, 0x5b, 0x3d, 0x68, 0x2a, 0x35, 0x47, 0xf8, 0x7d, 0x26, 0x6f, 0x1d, 0x8a, 0x34, 0x6a, 0x3f, 0x0c, 0x58, 0x93, 0xa2, 0x4b, 0x8b, 0xa2, 0xd7, 0x4f, 0x14, 0x8b, 0xac, 0x4a, 0x0e, 0xbc, 0xee, 0x97, 0x14, 0xb7, 0x43, 0x41, 0xee, 0xda, 0xb3, 0xbf, 0x30, 0x1d, 0xba, 0xdf, 0x44, 0x50, 0x17, 0x80, 0x9b, 0x63, 0x6a, 0xf5, 0x3b, 0x9c, 0x34, 0x67, 0x8d, 0x99, 0x89, 0x61, 0x41, 0xf4, 0x6a, 0x0f, 0x5e, 0x4a, 0x0a, 0x29, 0x0f, 0x35, 0x5c, 0xa1, 0x17, 0xae, 0x6e, 0xdd, 0x78, 0x0a, 0xbc, 0xfd, 0x96, 0x5c, 0x4f, 0x89, 0xdc, 0x33, 0x59, 0x38, 0xfb, 0x29, 0xd5, 0xcc, 0xa7, 0x3c, 0x3c, 0xeb, 0xfc, 0xc8, 0x11, 0xfc, 0xbe, 0xe1, 0x61, 0x97, 0xad, 0x12, 0x98, 0xed, 0xc5, 0x45, 0x6f, 0xbc, 0x49, 0xd8, 0x45, 0x32, 0xe4, 0x2a, 0xa5, 0x4d, 0x86, 0xae, 0xb4, 0xfd, 0x4a, 0xf5, 0xa0, 0x0d, 0x01, 0x61, 0x52, 0x8c, 0x43, 0x6f, 0x8a, 0xb6, 0x43, 0xd3, 0x0c, 0x53, 0x2b, 0xf1, 0x66, 0xb5, 0x3c, 0xc8, 0xde, 0xe7, 0x93, 0x08, 0x61, 0x74, 0xb4, 0x4e, 0x42, 0xfb, 0x37, 0x65, 0xa6, 0x30, 0x43, 0x59, 0x26, 0x7a, 0x9d, 0x22, 0x36, 0x1a, 0xee, 0x3f, 0x77, 0x79, 0xc6, 0xcd, 0xb6, 0xd3, 0x2c, 0x57, 0xea, 0xad, 0x14, 0x57, 0x77, 0x60, 0xae, 0x05, 0xee, 0x61, 0xa3, 0xad, 0x9c, 0x85, 0xe2, 0xe5, 0xf7, 0x6a, 0x8f, 0xf2, 0x8b, 0xed, 0xde, 0xb8, 0x2a, 0xbe, 0xaa, 0x67, 0x7f, 0xf9, 0x2a, 0x40, 0xc9, 0x8c, 0x19, 0x8d, 0x35, 0x7d, 0x15, 0x39, 0x64, 0x92, 0x02, 0x0d, 0x93, 0x48, 0x9f, 0x4a, 0xda, 0x91, 0xc7, 0x5b, 0x51, 0xba, 0xf0, 0x2e, 0x0a, 0xc0, 0xa4, 0x37, 0xd7, 0x66, 0x03, 0x43, 0xc7, 0x03, 0x40, 0x8b, 0xd1, 0x90, 0x0b, 0x96, 0x84, 0x5d, 0x25, 0x64, 0xda, 0x8c, 0xbf, 0x4d, 0x3e, 0x21, 0x2a, 0x53, 0xef, 0x33, 0xd1, 0xb5, 0xe2, 0x39, 0xbf, 0x91, 0xbf, 0x53, 0xd7, 0xef, 0xcf, 0x5d, 0xd9, 0xd7, 0x28, 0x5f, 0x8c, 0xde, 0x3e, 0x9e, 0x74, 0x64, 0x39, 0xb5, 0x3f, 0xd6, 0xaa, 0x76, 0xe8, 0x0d, 0x0c, 0xc2, 0x96, 0x74, 0x09, 0xc6, 0xc4, 0x4e, 0x15, 0x9b, 0x7b, 0x27, 0xb5, 0xcd, 0x8c, 0x12, 0x49, 0xc2, 0x3c, 0xbb, 0x40, 0x04, 0x0f, 0x02, 0x85, 0xe7, 0x48, 0x7b, 0xb8, 0xac, 0x4c, 0xf0, 0x25, 0x9a, 0xd1, 0x97, 0x41, 0x71, 0xb6, 0x53, 0xd5, 0xe7, 0xfe, 0x23, 0x97, 0x91, 0xff, 0x98, 0x7a, 0x3c, 0xfb, 0x34, 0x25, 0xef, 0x21, 0xe9, 0x46, 0x3d, 0x18, 0x84, 0x20, 0xab, 0x85, 0x1d, 0x4e, 0x0c, 0x80, 0x19, 0xf2, 0x88, 0xb5, 0xae, 0x10, 0x8f, 0x6e, 0xaf, 0x52, 0xe4, 0x42, 0x4c, 0xa5, 0xe3, 0x62, 0x73, 0x87, 0xa6, 0x46, 0x83, 0xbc, 0xba, 0x42, 0x9f, 0x9f, 0xd3, 0x04, 0xc0, 0x09, 0x21, 0xfe, 0x1d, 0x42, 0xdf, 0x01, 0xb8, 0x93, 0x11, 0x9f, 0x67, 0x4b, 0xf4, 0x0a, 0x9b, 0xf9, 0x40, 0x2c, 0x6f, 0x6f, 0x28, 0x9d, 0xb2, 0x23, 0xd1, 0x3c, 0x34, 0x86, 0x99, 0xab, 0xd1, 0x92, 0xc1, 0x18, 0xbb, 0x10, 0xef, 0xda, 0xbe, 0x66, 0xe8, 0x86, 0xdf, 0xd9, 0xff, 0x2f, 0xf6, 0x67, 0xe1, 0x91, 0xfc, 0x59, 0x11, 0xdb, 0xfb, 0x05, 0x89, 0x36, 0x25, 0x55, 0xfd, 0x98, 0xb8, 0xaa, 0x06, 0xaa, 0x39, 0x18, 0x1f, 0xcf, 0x36, 0xd3, 0x18, 0xc3, 0xd7, 0x46, 0x90, 0x6a, 0x12, 0x19, 0x10, 0xef, 0x50, 0x80, 0x7d, 0xe4, 0xcd, 0xf1, 0x91, 0xc7, 0x61, 0xfd, 0x50, 0x9b, 0xc4, 0x34, 0x47, 0x80, 0x23, 0x76, 0x05, 0x95, 0x9a, 0xff, 0xbb, 0x6d, 0xb7, 0xa1, 0xa7, 0x07, 0x42, 0x42, 0x60, 0x24, 0x5f, 0x2f, 0xbc, 0xd6, 0x77, 0x88, 0x35, 0x19, 0x50, 0x12, 0x11, 0xbc, 0xf0, 0x48, 0xd4, 0xee, 0x85, 0x26, 0xb1, 0xfb, 0x22, 0xef, 0xe0, 0x7f, 0x82, 0x7c, 0x49, 0xca, 0x9b, 0xfc, 0x30, 0x44, 0xa7, 0x10, 0xee, 0xbb, 0x5e, 0x36, 0x61, 0x65, 0xb5, 0x4a, 0xdf, 0xb2, 0x94, 0x7c, 0x87, 0x39, 0xc4, 0x46, 0x4a, 0xa4, 0x2d, 0x31, 0xe7, 0x58, 0xb9, 0xb8, 0x30, 0x6f, 0x87, 0x12, 0xc0, 0x02, 0xca, 0x5e, 0xbf, 0xae, 0xff, 0xf0, 0xd6, 0xde, 0x64, 0x4a, 0xa5, 0x75, 0x47, 0xfd, 0xd5, 0xfb, 0x6e, 0xa7, 0xce, 0x45, 0xfb, 0xf2, 0xc4, 0xe2, 0x24, 0xf9, 0x05, 0xc4, 0xbc, 0xd0, 0x79, 0xb2, 0xec, 0x8f, 0x8d, 0x29, 0x9d, 0xca, 0x68, 0xe4, 0x3a, 0x92, 0xd8, 0x9c, 0xad, 0x66, 0x2c, 0x80, 0x65, 0x93, 0x78, 0x7f, 0xd1, 0x86, 0x2d, 0xc7, 0xf9, 0x2a, 0xe1, 0x8a, 0xd1, 0xba, 0xd0, 0xf7, 0xef, 0xaf, 0x70, 0x85, 0x1a, 0xb1, 0xda, 0x78, 0x77, 0x9e, 0xa5, 0x04, 0x9a, 0xd7, 0x1d, 0x56, 0x49, 0x5d, 0xa2, 0x66, 0x0f, 0xbc, 0x6d, 0x34, 0x0c, 0x1f, 0xf3, 0xd7, 0x91, 0x58, 0xeb, 0x49, 0x1b, 0xf3, 0xf1, 0xde, 0xb1, 0xd9, 0x70, 0xf5, 0x10, 0x10, 0xf9, 0xcc, 0x80, 0x1b, 0x4e, 0xac, 0x01, 0xde, 0x54, 0x0e, 0x8b, 0xe0, 0xd2, 0xa3, 0xbe, 0x99, 0x65, 0x8f, 0x68, 0x0a, 0x97, 0x32, 0xc1, 0xeb, 0xdb, 0x8d, 0xb8, 0x7d, 0xcc, 0xe7, 0x65, 0x94, 0xf6, 0x9a, 0xc2, 0x8f, 0x93, 0xfc, 0xe5, 0xf6, 0x16, 0x0c, 0xb9, 0x5f, 0xec, 0x59, 0xae, 0x81, 0x6f, 0x83, 0x16, 0x83, 0xb7, 0xd5, 0xa4, 0x18, 0xaa, 0xff, 0x22, 0xed, 0x77, 0x6e, 0xf3, 0x47, 0x82, 0xe9, 0xd3, 0x12, 0x59, 0x6f, 0x62, 0xd3, 0xd6, 0x61, 0x24, 0x61, 0x85, 0xdb, 0x4b, 0xe0, 0x41, 0xd4, 0x87, 0x68, 0x1c, 0x22, 0xb9, 0x0a, 0x70, 0xda, 0xba, 0xe0, 0x80, 0xb4, 0x38, 0x8f, 0x68, 0x7b, 0x58, 0x5c, 0x5e, 0x45, 0xf4, 0xae, 0x6f, 0x39, 0xed, 0xbd, 0xdb, 0x16, 0xe9, 0x35, 0x05, 0xfb, 0xe4, 0x0b, 0x72, 0x89, 0xa6, 0xd1, 0x6e, 0x29, 0x54, 0xb9, 0x78, 0x94, 0x4c, 0xaa, 0xb8, 0x9f, 0x3d, 0xd6, 0x3e, 0x60, 0x4a, 0xdf, 0x14, 0xfb, 0x4f, 0x7b, 0xfb, 0xd0, 0x39, 0xbb, 0xb9, 0x85, 0x26, 0xc5, 0xae, 0xc7, 0x99, 0x43, 0xbd, 0x5a, 0x89, 0x82, 0x5b, 0x5c, 0x8a, 0xb7, 0x90, 0xe5, 0x49, 0xa4, 0xdd, 0x87, 0x16, 0x0c, 0x60, 0xe3, 0xb9, 0x1b, 0x42, 0x62, 0x9d, 0x2c, 0x2d, 0xba, 0x60, 0x13, 0x34, 0x09, 0xe2, 0x30, 0xdd, 0xf0, 0xe9, 0xbe, 0x02, 0x1f, 0xdf, 0x17, 0x18, 0x06, 0x1f, 0x66, 0xa5, 0x92, 0x0c, 0x6f, 0xee, 0xef, 0x64, 0x82, 0x4e, 0x3e, 0x98, 0xb6, 0xaa, 0xf7, 0x2f, 0xdd, 0xe8, 0xc3, 0x3e, 0xd6, 0x43, 0x8a, 0x54, 0x2f, 0xd3, 0xc9, 0x04, 0xf8, 0xa0, 0x2c, 0x0b, 0x44, 0x67, 0x0c, 0xb7, 0xe2, 0xa9, 0x7a, 0x48, 0x5d, 0x8a, 0x50, 0x67, 0xc1, 0x25, 0xde, 0x32, 0x43, 0x94, 0x37, 0xd3, 0xe2, 0x47, 0xa2, 0xe9, 0x7f, 0x99, 0x5d, 0x04, 0x9b, 0x79, 0xe2, 0x29, 0x6d, 0x21, 0x27, 0x28, 0x67, 0x75, 0xd3, 0x98, 0xbd, 0x61, 0x4f, 0xcd, 0x20, 0x5a, 0x1d, 0x17, 0xca, 0x65, 0x37, 0xb1, 0x7d, 0xb7, 0xc0, 0xc8, 0x80, 0x6c, 0x3b, 0xe7, 0xc1, 0xdf, 0xdc, 0x97, 0xe6, 0xf3, 0x20, 0xdc, 0xd9, 0x4b, 0xd9, 0xe3, 0x1f, 0x6d, 0xba, 0xf5, 0x68, 0x2d, 0x74, 0xbd, 0xb9, 0x49, 0x23, 0x2b, 0x36, 0x89, 0x10, 0x1d, 0xe2, 0x30, 0xe6, 0x3e, 0xb1, 0x6f, 0x6e, 0x50, 0x6b, 0x1b, 0x23, 0x5b, 0xcb, 0xf0, 0x3f, 0x32, 0x03, 0xf5, 0x0d, 0x37, 0x78, 0x60, 0x49, 0x86, 0x52, 0x84, 0x5a, 0xf0, 0x80, 0xf9, 0x8f, 0xfa, 0x61, 0x0d, 0x50, 0x67, 0x62, 0x5b, 0x7e, 0x41, 0x2b, 0xf3, 0x2a, 0xc4, 0xe2, 0xbc, 0x25, 0x5a, 0xb0, 0x3c, 0xe5, 0x56, 0x5c, 0x8d, 0x00, 0x5f, 0x67, 0x41, 0x35, 0x16, 0x1d, 0x12, 0x4d, 0xa1, 0x6c, 0x99, 0xe7, 0x09, 0x45, 0xd9, 0x65, 0x7d, 0x05, 0x13, 0x61, 0x84, 0xc8, 0x3b, 0x23, 0x5e, 0x72, 0xe7, 0x04, 0x4d, 0xf9, 0xf6, 0x58, 0x8d, 0x2f, 0x9f, 0x32, 0xc0, 0x1b, 0x90, 0x9e, 0xc2, 0x6f, 0x71, 0xf3, 0xe1, 0x74, 0x94, 0x9b, 0x18, 0xa7, 0xdd, 0x6b, 0xb5, 0xf4, 0xa8, 0x00, 0x2b, 0x90, 0x8f, 0x21, 0xd2, 0xd3, 0xb8, 0x09, 0xf0, 0x68, 0x61, 0x9a, 0xb2, 0x12, 0x3c, 0x52, 0x30, 0xae, 0x77, 0x25, 0x97, 0xbb, 0xa0, 0x23, 0x81, 0x41, 0x09, 0x0b, 0x91, 0x21, 0x95, 0x34, 0x55, 0x5e, 0xb2, 0x1d, 0x6f, 0xb7, 0x07, 0x5d, 0xe5, 0xd8, 0xea, 0xf9, 0xa1, 0x6f, 0x81, 0x98, 0x8c, 0x8b, 0x95, 0x15, 0x26, 0xaa, 0xf6, 0xd1, 0x27, 0xb7, 0x9c, 0x34, 0xbb, 0xe8, 0x1f, 0xa1, 0xd1, 0x92, 0xcc, 0x01, 0x77, 0xad, 0x9d, 0xba, 0x35, 0x71, 0x58, 0xdd, 0xb8, 0x8f, 0xe5, 0x34, 0xfc, 0x6b, 0x26, 0x70, 0xeb, 0x17, 0x50, 0xec, 0x66, 0x4a, 0xde, 0xdb, 0x5b, 0x3b, 0xcc, 0xae, 0x2e, 0x53, 0x66, 0xbd, 0x1e, 0xdd, 0xe5, 0xed, 0x0b, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xbd, 0x06, 0xe6, 0x81, 0xc1, 0x0d, 0x31, 0x00, 0x05, 0xbf, 0x21, 0x11, 0x00, 0x05, 0xb3, 0x65, 0x1e, 0x69, 0xb2, 0x30, 0x00, 0x00, 0x00, 0x77, 0xd0, 0x5d, 0x32, 0xfd, 0x25, 0x3e, 0x44, 0x23, 0x3c, 0xe7, 0x13, 0xca, 0xd0, 0xef, 0x0b, 0x0c, 0xc8, 0xc4, 0xd7, 0x20, 0x45, 0x2b, 0x66, 0x0e, 0x64, 0x5d, 0x30, 0x85, 0x34, 0x31, 0x64, 0x76, 0x7a, 0x23, 0xa1, 0x02, 0xda, 0x0e, 0xf9, 0x2a, 0xa2, 0x4a, 0xc1, 0xa5, 0xfb, 0xa3, 0xb8, 0x07, 0x0d, 0x03, 0xb0, 0x33, 0xa4, 0x09, 0x49, 0xe3, 0x15, 0x4c, 0x98, 0x56, 0xef, 0xac, 0x71, 0xa0, 0xa1, 0x22, 0x1c, 0xc1, 0x26, 0xdc, 0xd8, 0xee, 0xeb, 0x71, 0xb8, 0xd7, 0x9e, 0x7a, 0xb9, 0x3e, 0x55, 0x7f, 0x9a, 0xf7, 0x4a, 0xfe, 0x75, 0x1a, 0x3a, 0x16, 0xf7, 0x69, 0xfb, 0x63, 0x5a, 0x90, 0xfa, 0xf3, 0xb4, 0x82, 0x60, 0x78, 0x96, 0x88, 0x1c, 0x3a, 0x3f, 0xb5, 0x8c, 0xda, 0x10, 0x56, 0x9c, 0x82, 0x10, 0x36, 0x9c, 0x44, 0x3a, 0xab, 0xe8, 0xfb, 0x47, 0xd9, 0xd2, 0x80, 0xfe, 0xc9, 0x2c, 0x27, 0xb4, 0xe0, 0xfc, 0xf6, 0xa4, 0x92, 0x3a, 0x4f, 0x70, 0x60, 0xe6, 0x16, 0x31, 0x71, 0x5b, 0x06, 0x6d, 0xa3, 0xc3, 0xfb, 0xe8, 0xcc, 0xfe, 0x08, 0x10, 0x22, 0x1d, 0xc4, 0x73, 0xe1, 0x79, 0xf4, 0xbf, 0x07, 0xa1, 0x8d, 0x37, 0xe2, 0x10, 0xfb, 0x89, 0x7b, 0x47, 0x3e, 0xac, 0xc8, 0x7e, 0xa0, 0xf8, 0x0a, 0x16, 0xaa, 0x4a, 0x60, 0x20, 0x4f, 0x2e, 0x1f, 0xaf, 0xd3, 0xe1, 0x97, 0xb4, 0xea, 0x60, 0x82, 0x76, 0x17, 0x77, 0x0a, 0x59, 0xb7, 0x7a, 0x41, 0x4a, 0x34, 0xd2, 0x3a, 0x4d, 0x03, 0xab, 0x4f, 0x11, 0x0a, 0x1a, 0x23, 0xc5, 0x17, 0x13, 0x5a, 0x4c, 0xca, 0x90, 0xbf, 0xa1, 0x31, 0x9c, 0xed, 0x66, 0xc3, 0x2f, 0x30, 0x9e, 0xdb, 0x3f, 0xfe, 0x0b, 0x46, 0xfa, 0xc8, 0x20, 0x61, 0x87, 0xa2, 0xb0, 0xa9, 0x41, 0x70, 0x2b, 0x6e, 0x67, 0x0c, 0x7f, 0x35, 0xbd, 0xe8, 0xa9, 0x44, 0xd3, 0xa2, 0x73, 0xa7, 0x9f, 0x15, 0xa6, 0xda, 0xba, 0x27, 0xe0, 0x43, 0x6e, 0x61, 0xd9, 0x16, 0x2a, 0x7f, 0x31, 0xad, 0xb7, 0x80, 0xad, 0x03, 0x0a, 0x34, 0x54, 0xf4, 0x85, 0x45, 0xd1, 0x9c, 0x8b, 0x87, 0xf7, 0x0c, 0xa8, 0x47, 0x07, 0x64, 0xb2, 0x18, 0x07, 0x25, 0x70, 0x14, 0xc3, 0xf7, 0xc3, 0xd6, 0xab, 0x00, 0x94, 0x17, 0x74, 0x9b, 0xa3, 0x46, 0xb3, 0x5e, 0x52, 0xf5, 0x9b, 0x04, 0xea, 0x33, 0xc8, 0xe9, 0xc9, 0xe7, 0xf9, 0x77, 0x2a, 0x15, 0xda, 0xee, 0x44, 0x70, 0xc7, 0xc4, 0xce, 0x3f, 0xea, 0x69, 0xb2, 0xab, 0xd8, 0xb0, 0xc5, 0xfc, 0x7a, 0x75, 0x12, 0x53, 0xf1, 0x95, 0xfe, 0x70, 0xfa, 0xed, 0x4f, 0xc4, 0xfd, 0xdc, 0x35, 0xea, 0x8e, 0x6e, 0x1e, 0xef, 0xe3, 0x89, 0x52, 0x7b, 0xba, 0x35, 0x85, 0x37, 0x54, 0x52, 0x0e, 0x29, 0x3e, 0xff, 0xc4, 0xb9, 0x36, 0x91, 0x8d, 0x8a, 0xdb, 0xa7, 0x3f, 0xaa, 0x47, 0x2b, 0x40, 0x35, 0xfc, 0x1c, 0xdb, 0xfa, 0x4d, 0x8a, 0x60, 0x7b, 0xba, 0xf3, 0x22, 0x3e, 0xeb, 0xfd, 0x79, 0x7b, 0x43, 0xb2, 0x91, 0x95, 0xce, 0x22, 0x49, 0xa7, 0x50, 0x12, 0xd5, 0xfe, 0x55, 0x78, 0xa8, 0xc8, 0x4a, 0x66, 0xaa, 0x5e, 0xa7, 0xc6, 0x20, 0x02, 0xab, 0x82, 0x23, 0xf2, 0xee, 0xd0, 0x6c, 0xf5, 0xa3, 0x90, 0x3f, 0x50, 0x02, 0xc8, 0xbe, 0x97, 0xac, 0x70, 0x83, 0xa5, 0xb3, 0xa0, 0x58, 0x29, 0xc7, 0x20, 0x27, 0x35, 0x3a, 0xaf, 0xa5, 0x1a, 0xaa, 0xaa, 0x87, 0x7c, 0x10, 0x2d, 0xd9, 0x04, 0xa9, 0x29, 0x8e, 0x02, 0x73, 0x70, 0x21, 0xe1, 0x71, 0xe7, 0x9d, 0xaf, 0x3d, 0xf7, 0xc1, 0x10, 0x27, 0x1a, 0x97, 0x7c, 0x68, 0xc5, 0x7e, 0xeb, 0x80, 0xbf, 0x19, 0x1d, 0x2b, 0x33, 0xd1, 0xfb, 0x90, 0xac, 0xb3, 0xf7, 0xe1, 0x7d, 0x96, 0x94, 0xea, 0xd9, 0xc6, 0x45, 0x3b, 0xaf, 0x6e, 0x70, 0xf4, 0x03, 0x00, 0x80, 0x76, 0x64, 0x1c, 0xef, 0x6e, 0x71, 0xda, 0x92, 0x59, 0x0d, 0x47, 0xbb, 0x73, 0x38, 0xec, 0x27, 0xec, 0x8a, 0x28, 0xf2, 0x42, 0xb7, 0x6d, 0xf9, 0x0c, 0xdd, 0x3e, 0xbe, 0xfe, 0x4b, 0x12, 0xeb, 0x86, 0xdb, 0x11, 0x1a, 0xf1, 0xb7, 0x41, 0x8a, 0xff, 0x30, 0x5f, 0xed, 0x2c, 0x03, 0xa4, 0xca, 0xac, 0xd8, 0xec, 0xe2, 0x3f, 0x19, 0x57, 0x91, 0x72, 0x7a, 0xf4, 0x5f, 0x37, 0x8d, 0x8c, 0x0e, 0xd1, 0x80, 0xd6, 0x6a, 0x65, 0x6c, 0x42, 0x0f, 0x3a, 0x81, 0x7a, 0x83, 0xf9, 0xf3, 0xdc, 0x52, 0x44, 0x34, 0x3a, 0xed, 0xc0, 0xb2, 0x56, 0x27, 0x4f, 0x31, 0xb1, 0x05, 0x73, 0xb0, 0x86, 0x3c, 0x3f, 0x6b, 0xe4, 0xaf, 0x83, 0x4f, 0x19, 0xae, 0x5c, 0xdf, 0xcf, 0x1d, 0x5b, 0x7e, 0x88, 0xbb, 0xa4, 0x44, 0x05, 0xcf, 0xb3, 0x4e, 0xe3, 0x42, 0xa8, 0x45, 0x44, 0x58, 0x24, 0xb9, 0xd8, 0x62, 0x12, 0x34, 0x27, 0x47, 0xc4, 0x0b, 0x30, 0x05, 0x2f, 0x2e, 0x38, 0x81, 0x9d, 0xcd, 0xd0, 0x27, 0x79, 0x3a, 0xbc, 0x27, 0x29, 0x19, 0xd6, 0xe8, 0x69, 0x2e, 0x1b, 0x4d, 0xc0, 0xf6, 0x47, 0x2a, 0x70, 0xad, 0x36, 0x37, 0xf9, 0x31, 0x0c, 0xe2, 0x95, 0x97, 0x36, 0xad, 0xd3, 0xd1, 0x46, 0x3f, 0x3c, 0x3e, 0xd0, 0xef, 0xb5, 0x1a, 0x7a, 0xf8, 0x33, 0xcb, 0xb8, 0x46, 0x23, 0x3e, 0x9d, 0x2d, 0x53, 0x65, 0x99, 0x67, 0x8f, 0x2e, 0x37, 0x6a, 0xbe, 0x22, 0x94, 0x1c, 0xc9, 0xbd, 0x87, 0x0b, 0xea, 0xfe, 0xf0, 0xe2, 0xd4, 0xf5, 0xd5, 0xcc, 0x1a, 0xbb, 0x19, 0x17, 0x73, 0x24, 0x8e, 0xa5, 0xfa, 0x07, 0x12, 0x61, 0x48, 0x32, 0x7b, 0x5b, 0x06, 0x6c, 0xf0, 0x11, 0xbb, 0xd1, 0xed, 0x4e, 0x5e, 0x4e, 0x18, 0xc3, 0x5a, 0x64, 0x00, 0xba, 0x3d, 0x0b, 0x80, 0x5c, 0x50, 0x02, 0x20, 0xcc, 0xa3, 0x05, 0x9f, 0xab, 0x4a, 0x28, 0x26, 0x78, 0xc0, 0xd0, 0x5f, 0xc3, 0x32, 0x86, 0xaa, 0x00, 0xfa, 0xfb, 0x52, 0xe0, 0x62, 0x4a, 0xa9, 0xcd, 0x49, 0x4e, 0x24, 0x64, 0xf0, 0x3f, 0x67, 0xd8, 0x96, 0xcd, 0xe4, 0xaf, 0xb4, 0xcc, 0x15, 0x1a, 0x96, 0x67, 0x3b, 0xc1, 0xd3, 0x97, 0xe4, 0x8e, 0x2e, 0xa2, 0x86, 0xd0, 0x82, 0x68, 0x3a, 0x9e, 0xf7, 0x89, 0x5c, 0x79, 0xb9, 0x92, 0x90, 0xe3, 0x28, 0x39, 0x0e, 0xc2, 0xc3, 0xd6, 0xb8, 0x39, 0x31, 0x54, 0x9a, 0x9c, 0x6c, 0x46, 0x40, 0xb1, 0xa2, 0xc1, 0x53, 0xe7, 0x12, 0x92, 0x18, 0xd4, 0x61, 0x63, 0x36, 0xd8, 0xda, 0xb3, 0xef, 0x64, 0x54, 0x5b, 0xa7, 0xce, 0x08, 0xff, 0xc6, 0xe7, 0x65, 0x1f, 0x15, 0xc3, 0xc8, 0x93, 0x56, 0xc9, 0xe0, 0x2e, 0xdb, 0x9e, 0x3c, 0x30, 0x28, 0x41, 0x15, 0x41, 0x46, 0xda, 0xb9, 0xda, 0x98, 0x6e, 0x62, 0x30, 0xc3, 0x9a, 0x87, 0x3f, 0x5f, 0x71, 0x65, 0x27, 0x80, 0x8b, 0xe5, 0xd3, 0xc3, 0x67, 0xd1, 0xab, 0x8b, 0xa7, 0xcc, 0x63, 0x75, 0xe7, 0x8e, 0x4a, 0x70, 0x1a, 0xfc, 0x5f, 0xc5, 0x25, 0x52, 0xa5, 0xaa, 0x35, 0x82, 0x03, 0xfd, 0x74, 0xb4, 0x42, 0x55, 0x6a, 0xf6, 0xc3, 0x89, 0x0f, 0x09, 0x2a, 0x1a, 0x82, 0xb3, 0xa4, 0x9e, 0x50, 0xff, 0x3c, 0x99, 0xbf, 0x98, 0x91, 0xce, 0xbf, 0x63, 0x54, 0x65, 0x07, 0xd8, 0xfe, 0x71, 0xe6, 0xb4, 0xf9, 0x45, 0x68, 0xbb, 0x08, 0xe6, 0xa7, 0x0f, 0x58, 0x9c, 0x2b, 0x01, 0xe8, 0x41, 0xe9, 0xe0, 0xb8, 0xc2, 0x96, 0xe6, 0x76, 0x9b, 0xd5, 0x3f, 0x87, 0xbb, 0x5d, 0xf4, 0x90, 0xdb, 0xa9, 0x62, 0xe6, 0x3f, 0xb6, 0xdb, 0x9a, 0xf7, 0x2c, 0xfb, 0xf5, 0xcf, 0x72, 0xbe, 0xdd, 0xd9, 0xa0, 0xde, 0xe4, 0x31, 0x12, 0x4f, 0x8c, 0x3c, 0x13, 0xfb, 0xcb, 0x77, 0x53, 0x6a, 0xdf, 0x77, 0x87, 0x6e, 0x0b, 0x2b, 0x9a, 0x0d, 0x6f, 0xe3, 0xa9, 0x20, 0x6b, 0x75, 0x57, 0x31, 0xad, 0x84, 0x2f, 0xa9, 0x51, 0xc7, 0x1f, 0xd2, 0x03, 0xc2, 0xca, 0xf9, 0xdc, 0xab, 0xf2, 0x23, 0xd6, 0x9c, 0x83, 0xce, 0x9a, 0x63, 0x92, 0x04, 0xe0, 0xc4, 0x91, 0x24, 0xb5, 0x78, 0xdb, 0x4a, 0xb6, 0x8b, 0xa5, 0x0f, 0xbd, 0x7d, 0x01, 0x6f, 0xb5, 0x79, 0x18, 0x83, 0x78, 0x65, 0x0b, 0x88, 0xd0, 0xbe, 0x8e, 0x77, 0xe0, 0x10, 0xd2, 0x2c, 0xa1, 0x7d, 0x47, 0x09, 0x63, 0x99, 0xfc, 0xec, 0x92, 0x9a, 0xee, 0x3e, 0xf0, 0x6b, 0x4f, 0xda, 0x54, 0x03, 0x5d, 0x87, 0x77, 0x13, 0x7c, 0x72, 0xf6, 0xa3, 0x45, 0x6f, 0x27, 0x74, 0xdb, 0xc9, 0x8f, 0x5e, 0xb2, 0xd9, 0x60, 0xe8, 0xf3, 0x89, 0x9d, 0x7d, 0x68, 0x23, 0xf3, 0x60, 0x7e, 0xc7, 0x96, 0x90, 0x60, 0xad, 0x2d, 0x40, 0x61, 0x4f, 0x8d, 0x1b, 0x03, 0xbf, 0x0e, 0x1f, 0x7c, 0xf8, 0x89, 0xfc, 0xa3, 0xf6, 0xff, 0x80, 0x3a, 0x5d, 0x5d, 0x79, 0x39, 0x4e, 0xad, 0xa7, 0x8a, 0xb7, 0x04, 0x68, 0x8d, 0x80, 0x51, 0xa6, 0x99, 0x06, 0xda, 0x23, 0xae, 0x31, 0xcf, 0x95, 0x4b, 0xb9, 0x5b, 0x45, 0x0c, 0x96, 0x80, 0x0e, 0x93, 0xdc, 0x0c, 0x65, 0xe2, 0x19, 0x88, 0x69, 0x18, 0x1c, 0x46, 0x8f, 0xba, 0xd5, 0xdb, 0xb2, 0xc3, 0xd2, 0xb3, 0x8a, 0xd0, 0xb2, 0x71, 0x95, 0xeb, 0x48, 0x0d, 0x70, 0x39, 0x93, 0x1e, 0x05, 0xcd, 0xc7, 0x54, 0xa3, 0xb4, 0xad, 0x88, 0xce, 0x6f, 0x53, 0x35, 0xeb, 0x5e, 0xe7, 0x83, 0xad, 0xb2, 0x9a, 0xb8, 0x17, 0x23, 0x69, 0x87, 0x77, 0xb5, 0x99, 0xb3, 0x78, 0x7b, 0x03, 0xb3, 0xfa, 0x5a, 0xa1, 0xc5, 0x6c, 0x36, 0xf5, 0x67, 0x77, 0xbf, 0x4b, 0xe7, 0x02, 0x34, 0xc5, 0xfd, 0x5e, 0xa4, 0x3e, 0x3d, 0xc9, 0x50, 0xcc, 0x15, 0x0e, 0xef, 0x09, 0x69, 0xf5, 0x4f, 0x18, 0x52, 0x21, 0xb0, 0x84, 0x59, 0x4b, 0xc3, 0x30, 0xc7, 0x7a, 0xe3, 0xfa, 0xfa, 0xfa, 0x53, 0xa4, 0x08, 0x5e, 0xd0, 0x58, 0xef, 0x93, 0x08, 0xac, 0x8a, 0x5b, 0xfa, 0x0d, 0x02, 0x4a, 0x7b, 0x23, 0x7f, 0x08, 0x72, 0xb9, 0x39, 0x1a, 0x52, 0x3d, 0x64, 0x7b, 0x49, 0x22, 0x0d, 0xb0, 0xb2, 0x81, 0x07, 0xe1, 0xce, 0x8a, 0x46, 0x18, 0x99, 0xeb, 0x9a, 0xd7, 0x0e, 0x0f, 0x58, 0x02, 0x36, 0xed, 0x43, 0x3e, 0x6d, 0xef, 0xcc, 0x24, 0x11, 0x4e, 0x9d, 0xd5, 0x08, 0x99, 0x37, 0x28, 0x8e, 0x2e, 0x67, 0x2b, 0xad, 0x4e, 0x5c, 0x27, 0x0f, 0x7a, 0xc3, 0x99, 0xa0, 0xa0, 0x7f, 0x74, 0xb8, 0x17, 0x59, 0x7c, 0x5e, 0x5e, 0x70, 0xc9, 0x5a, 0x81, 0x93, 0xb0, 0xeb, 0x6d, 0xfb, 0x1a, 0x4b, 0x18, 0x0d, 0x63, 0x0c, 0xff, 0x90, 0xff, 0x9e, 0xd5, 0x26, 0x75, 0x1f, 0x04, 0x1e, 0x65, 0xbe, 0xb8, 0x82, 0xc4, 0x71, 0xc3, 0x97, 0xc5, 0x98, 0x74, 0x98, 0xa9, 0xeb, 0x93, 0x46, 0xfa, 0xdd, 0x95, 0x72, 0x30, 0x71, 0xf9, 0xb6, 0xd1, 0x9f, 0x96, 0x30, 0xc6, 0x6d, 0x42, 0xf9, 0x24, 0x24, 0xf8, 0x58, 0xca, 0xd8, 0x72, 0x1b, 0x26, 0x08, 0xac, 0x77, 0x3c, 0xd2, 0x5d, 0x4b, 0xbd, 0xb7, 0xfd, 0xa7, 0x71, 0x2f, 0xed, 0x3d, 0x59, 0x87, 0x18, 0xb3, 0x36, 0x88, 0xf6, 0xe9, 0x4d, 0xb6, 0x62, 0xa7, 0x87, 0xc1, 0x6b, 0x83, 0x6c, 0x7c, 0x82, 0xa3, 0x7a, 0x5c, 0x1e, 0x81, 0xb5, 0xd6, 0x36, 0x91, 0x11, 0x5e, 0xbd, 0xf4, 0x3e, 0xdd, 0xe8, 0xfc, 0x89, 0x25, 0x12, 0x00, 0x26, 0x46, 0x58, 0xf7, 0xb3, 0x03, 0x4c, 0x5b, 0x37, 0x8b, 0x9c, 0xd1, 0x02, 0x80, 0x1a, 0xb3, 0x48, 0xf9, 0xb2, 0x10, 0x98, 0x67, 0x3f, 0x99, 0x59, 0xf3, 0xd9, 0x00, 0xb1, 0x83, 0xe1, 0xb2, 0x1c, 0xd9, 0x4d, 0x2f, 0xf5, 0x56, 0x1b, 0xc6, 0x80, 0x36, 0xa0, 0x5d, 0x41, 0x67, 0xf8, 0xbf, 0xfe, 0x00, 0x18, 0xdb, 0x52, 0xf2, 0xac, 0x7c, 0xd6, 0x42, 0x70, 0xe2, 0x14, 0xc2, 0x33, 0xac, 0x14, 0x1f, 0xfa, 0xd0, 0x28, 0x30, 0x22, 0xba, 0xbe, 0xac, 0x53, 0xf7, 0xc5, 0x42, 0xb0, 0x64, 0xc7, 0xe5, 0xf7, 0xc4, 0x2a, 0x4d, 0xc5, 0x83, 0xa0, 0x6b, 0x4f, 0x49, 0x8d, 0xd7, 0x9a, 0x23, 0xdf, 0xbd, 0x07, 0x75, 0x34, 0xc0, 0xde, 0x66, 0x34, 0x7e, 0x94, 0xb7, 0x17, 0x02, 0xd1, 0x39, 0x5a, 0x42, 0xe9, 0x52, 0x54, 0xbf, 0x9d, 0xb6, 0xfe, 0xe2, 0x8e, 0x7d, 0x19, 0xa9, 0x85, 0xdb, 0x67, 0xee, 0xdd, 0x74, 0xa8, 0xba, 0x16, 0x81, 0x01, 0x37, 0x40, 0x30, 0x32, 0x88, 0x66, 0xa4, 0x85, 0x60, 0x0f, 0x5b, 0x4a, 0x0d, 0xd5, 0x81, 0x02, 0xb5, 0xf4, 0xd3, 0xda, 0x6e, 0x03, 0x63, 0xa5, 0x0e, 0xdc, 0x81, 0xfe, 0x9b, 0xf7, 0x59, 0xc1, 0x38, 0xeb, 0x2c, 0xed, 0x12, 0xf9, 0x15, 0x45, 0x7d, 0x90, 0x0f, 0xea, 0x7d, 0x41, 0xd7, 0x7e, 0xf3, 0x68, 0x78, 0xe5, 0x4c, 0x77, 0xa7, 0x83, 0x4b, 0xe4, 0xed, 0xd6, 0x6f, 0xb9, 0x98, 0x04, 0x76, 0x82, 0x1e, 0xb2, 0xc9, 0x8f, 0xc6, 0x5b, 0xdc, 0x1e, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xbd, 0x06, 0xe6, 0x81, 0xc1, 0x0d, 0x31, 0x00, 0x05, 0xbf, 0x21, 0x11, 0x00, 0x05, 0xb3, 0x65, 0x1e, 0x69, 0xb2, 0x30, 0x00, 0x00, 0x00, 0x9b, 0x7b, 0xdc, 0x1c, 0xac, 0x09, 0x71, 0x73, 0x18, 0x64, 0x92, 0xcc, 0x53, 0x4f, 0x46, 0xe1, 0x19, 0xe2, 0x23, 0x65, 0x1b, 0x3b, 0xb1, 0xd7, 0xc0, 0xb3, 0x61, 0x3b, 0x42, 0x1f, 0xb1, 0xec, 0x08, 0x2b, 0x15, 0x32, 0xa1, 0xe7, 0xf1, 0x02, 0x9e, 0x60, 0x44, 0x1b, 0x7d, 0x6b, 0x87, 0xe9, 0xcf, 0xdc, 0x0c, 0x54, 0x1e, 0x96, 0xf7, 0xb6, 0x7b, 0x6a, 0x47, 0x37, 0xb1, 0xa6, 0xf7, 0x60, 0x73, 0xe2, 0x4b, 0x9e, 0xc6, 0x8d, 0xfe, 0x12, 0xfc, 0xee, 0x1d, 0x40, 0xb4, 0x91, 0x5d, 0x37, 0x0b, 0xfd, 0x13, 0x17, 0xdb, 0x75, 0x52, 0x68, 0x3b, 0x02, 0x56, 0x42, 0x6b, 0x75, 0x6c, 0x1f, 0xcc, 0x5d, 0xfc, 0x3e, 0x6d, 0xc2, 0xb5, 0x8f, 0x08, 0x66, 0x58, 0x93, 0x74, 0x3a, 0x28, 0xc1, 0x9d, 0x57, 0x13, 0x0c, 0xad, 0x1a, 0xb5, 0x2f, 0xc8, 0x2b, 0x0d, 0x4a, 0x20, 0x5a, 0x49, 0xb1, 0x8c, 0x1e, 0x34, 0x93, 0x7c, 0xe8, 0x15, 0x04, 0xa2, 0xf6, 0x15, 0x00, 0x9c, 0xd4, 0x5a, 0x63, 0xa2, 0x1a, 0xef, 0x92, 0x6e, 0x39, 0xf3, 0xe1, 0x6e, 0x55, 0x7b, 0xfe, 0xbc, 0x45, 0x1f, 0x4e, 0x42, 0xa2, 0xdf, 0x08, 0xd6, 0x67, 0x0b, 0x47, 0x27, 0x4b, 0x40, 0x31, 0xef, 0x0f, 0xc7, 0xbd, 0x20, 0xe9, 0x4e, 0x95, 0xa7, 0x5f, 0xe3, 0x04, 0x70, 0xb7, 0x02, 0x76, 0x6b, 0xe7, 0x13, 0xc4, 0x18, 0x9e, 0xf7, 0xad, 0x38, 0xdf, 0x9b, 0x65, 0xcd, 0x69, 0xf4, 0xc0, 0xb4, 0x88, 0x59, 0x28, 0x14, 0xfe, 0x68, 0x84, 0x30, 0x80, 0xae, 0x2d, 0x11, 0xb0, 0xd6, 0x02, 0xdd, 0x48, 0xbf, 0x25, 0x48, 0xa5, 0x05, 0xa3, 0xbc, 0x02, 0xef, 0xad, 0xa0, 0xb1, 0xc3, 0xbb, 0xe1, 0xc8, 0xc3, 0x42, 0x4c, 0x37, 0x29, 0x10, 0x91, 0x7a, 0x11, 0x1b, 0x19, 0x24, 0x5b, 0xb5, 0x81, 0xa2, 0xdc, 0x51, 0xa0, 0x85, 0x15, 0x5a, 0x7c, 0xb3, 0xfa, 0x56, 0x0a, 0xc3, 0x16, 0xfa, 0x7d, 0x51, 0xdc, 0x4a, 0x87, 0xad, 0x97, 0x2e, 0xb6, 0x1c, 0xca, 0x6d, 0x12, 0x3b, 0xc9, 0x27, 0x41, 0x02, 0xe4, 0x8c, 0x40, 0x28, 0xf0, 0xff, 0x83, 0x6c, 0x85, 0x27, 0xad, 0xf4, 0xaf, 0x53, 0x28, 0x8b, 0x3e, 0xbd, 0x45, 0x1c, 0x2c, 0xe5, 0x5c, 0xbd, 0x51, 0xa7, 0xa0, 0x1b, 0xe7, 0x72, 0x77, 0xea, 0x08, 0xb2, 0xad, 0x0d, 0x38, 0x3f, 0x4f, 0x4e, 0xfa, 0x68, 0x0d, 0x74, 0xaa, 0x70, 0x2c, 0x1b, 0x96, 0x04, 0x73, 0x63, 0x20, 0x4a, 0x84, 0xad, 0xfd, 0x5b, 0xd2, 0xee, 0x43, 0x2a, 0xad, 0xbb, 0x77, 0x46, 0x59, 0x7c, 0x82, 0x51, 0xf3, 0x5b, 0xaf, 0x39, 0xe5, 0xdf, 0xed, 0x7c, 0xff, 0x9e, 0xf7, 0x9a, 0xd3, 0x2d, 0x5c, 0x58, 0x44, 0x99, 0x2d, 0xed, 0x89, 0xac, 0x99, 0x72, 0x73, 0x06, 0x0e, 0x33, 0xd3, 0x43, 0xe6, 0x68, 0x47, 0x51, 0xcc, 0x52, 0xb6, 0x76, 0x06, 0xa2, 0xa2, 0x79, 0x57, 0x92, 0x01, 0xc8, 0xfd, 0x0d, 0x8e, 0xb1, 0x84, 0x0f, 0x66, 0x6c, 0x3f, 0xb5, 0x1c, 0xef, 0x15, 0x8e, 0x70, 0xfa, 0x55, 0x86, 0x4a, 0x61, 0x56, 0x9b, 0xad, 0x2a, 0xa2, 0xfa, 0x83, 0x6c, 0xc3, 0x42, 0xee, 0x1b, 0x84, 0x13, 0xa3, 0xed, 0x47, 0xde, 0x99, 0x50, 0x06, 0xfa, 0xf4, 0x39, 0x6c, 0xc0, 0x99, 0xe9, 0xf9, 0x3d, 0xb4, 0x31, 0x40, 0xdf, 0xde, 0x57, 0xf4, 0x49, 0x3f, 0xfd, 0xd7, 0x46, 0xad, 0x57, 0xb3, 0x25, 0x2c, 0xef, 0x5a, 0x7c, 0xe8, 0x7e, 0x03, 0xaf, 0x8e, 0x2c, 0xa6, 0xce, 0xe9, 0x35, 0xb4, 0x9e, 0x0d, 0xa8, 0x7e, 0x47, 0xcb, 0x3c, 0xe0, 0xd6, 0x5e, 0xeb, 0xb8, 0xcf, 0x74, 0xc2, 0xea, 0x09, 0xba, 0x4b, 0x51, 0x48, 0x0f, 0xef, 0x6a, 0xb7, 0xc1, 0x30, 0xf6, 0x65, 0xdc, 0x0f, 0x9c, 0xe6, 0x15, 0xff, 0xcc, 0x0a, 0x3f, 0x8f, 0xde, 0x86, 0x14, 0x66, 0xdd, 0xbe, 0xbf, 0x1e, 0xb4, 0x68, 0x92, 0xda, 0x12, 0xab, 0x88, 0xb9, 0x2f, 0x94, 0x8b, 0xf1, 0x9a, 0x5c, 0xee, 0x38, 0x5a, 0x30, 0xb3, 0x94, 0x52, 0x50, 0x0b, 0x2a, 0x76, 0xc3, 0x90, 0x81, 0xf5, 0xe9, 0xc7, 0x2b, 0xfa, 0x2d, 0x91, 0xf8, 0xfc, 0x6b, 0x13, 0x75, 0x71, 0x4c, 0xb4, 0x54, 0xa5, 0xd7, 0xe6, 0xc9, 0x7b, 0xd0, 0xb8, 0xf4, 0x2f, 0x61, 0xcf, 0x49, 0xb6, 0x57, 0x1a, 0xd4, 0xdb, 0x5e, 0x4d, 0x4f, 0x18, 0x53, 0xe0, 0xf4, 0x27, 0x03, 0xd8, 0x08, 0xcb, 0x9e, 0xee, 0xdc, 0x72, 0x5a, 0x6c, 0x3b, 0x13, 0x78, 0x28, 0xf5, 0xf8, 0x6e, 0x1a, 0x7a, 0xda, 0xc5, 0xf0, 0x4f, 0xbd, 0x0e, 0xcd, 0xc7, 0x22, 0x44, 0x0c, 0x85, 0x4b, 0xe0, 0x96, 0x80, 0xbb, 0x96, 0x26, 0xd2, 0x5d, 0x5f, 0x69, 0x8b, 0x3a, 0x29, 0xaa, 0x04, 0xdd, 0x95, 0xd2, 0x71, 0xf2, 0x62, 0x32, 0x11, 0x3b, 0xe1, 0x00, 0x94, 0x8d, 0x94, 0xf7, 0x9d, 0x5f, 0x57, 0xc3, 0xca, 0x82, 0xc4, 0x70, 0x9f, 0x47, 0x4c, 0x2a, 0xdc, 0x3a, 0x2b, 0xc6, 0x86, 0xc1, 0x9e, 0xf6, 0x04, 0x39, 0x8c, 0x1f, 0x67, 0xd4, 0xc2, 0x5c, 0x8d, 0xf4, 0x80, 0xc7, 0x6b, 0x71, 0xcb, 0x2a, 0x8d, 0x5a, 0x17, 0xae, 0x48, 0x2e, 0x9e, 0x90, 0xd2, 0xdb, 0x6e, 0x8b, 0xd3, 0x8c, 0xe1, 0x06, 0xd4, 0xef, 0x43, 0xf0, 0x3f, 0x53, 0x4c, 0xfb, 0x38, 0x0d, 0xc9, 0xa5, 0x0c, 0xc5, 0x37, 0x92, 0x50, 0x5b, 0x10, 0x39, 0xa5, 0x9e, 0x01, 0x18, 0x62, 0x6c, 0xd6, 0x48, 0xdc, 0xec, 0x68, 0x3a, 0x60, 0xb2, 0x0d, 0x7a, 0x0b, 0x07, 0x93, 0x4b, 0xa3, 0x2d, 0xfb, 0x8b, 0x8b, 0x14, 0x14, 0x4f, 0x3a, 0x47, 0xff, 0xdd, 0x5a, 0x8f, 0x07, 0x7b, 0x01, 0x16, 0x06, 0xe3, 0xe9, 0x02, 0xdc, 0xa8, 0x28, 0x34, 0x0b, 0xcb, 0x7a, 0x6d, 0xe6, 0xce, 0x41, 0xac, 0x13, 0xfa, 0x22, 0x54, 0x03, 0x46, 0x7a, 0x66, 0x75, 0x25, 0x7d, 0xfc, 0x74, 0x67, 0xa4, 0x4d, 0x3e, 0x0c, 0x4a, 0x19, 0xa3, 0xd9, 0x1d, 0x08, 0xc2, 0xe0, 0x4e, 0x90, 0xfd, 0x74, 0x4b, 0x8a, 0x07, 0xcd, 0x49, 0x23, 0x58, 0xe9, 0xa7, 0x1e, 0xbc, 0x64, 0x6d, 0xcb, 0xe0, 0xd3, 0x06, 0x7e, 0x39, 0x57, 0x03, 0x50, 0x76, 0x81, 0x25, 0xe4, 0x7e, 0xc6, 0xf9, 0x8c, 0xce, 0x05, 0x53, 0xaa, 0x7f, 0x0d, 0xe5, 0xef, 0x5f, 0xdb, 0xec, 0x91, 0xd9, 0x34, 0x34, 0xef, 0x27, 0xc1, 0x82, 0x56, 0x16, 0x02, 0x20, 0x23, 0xfc, 0x36, 0xa7, 0x62, 0x57, 0x9e, 0xe6, 0x62, 0x9f, 0xc6, 0x52, 0x2c, 0x2f, 0x33, 0x22, 0xd4, 0x94, 0x87, 0x17, 0xd8, 0x0d, 0x3d, 0x72, 0x2e, 0x8f, 0x04, 0x3b, 0x1e, 0xf4, 0xac, 0x90, 0x5d, 0x27, 0x63, 0x7b, 0xdb, 0xa5, 0x0a, 0x10, 0x9e, 0x79, 0xbd, 0x21, 0x2a, 0xa3, 0x7e, 0xf6, 0x72, 0x34, 0xa6, 0x64, 0x09, 0x0f, 0x82, 0x6e, 0xe7, 0x71, 0xca, 0x21, 0x2f, 0x29, 0x0c, 0xe2, 0x9d, 0x28, 0x6b, 0x5f, 0x9a, 0xd9, 0x68, 0x6f, 0xbe, 0xd8, 0x3b, 0xd3, 0x75, 0x52, 0x58, 0x7c, 0x51, 0x35, 0xfc, 0x6e, 0xe7, 0x7d, 0xab, 0xa9, 0x8b, 0x0d, 0x47, 0x42, 0x00, 0x73, 0x4c, 0xae, 0x02, 0xef, 0xd4, 0xa0, 0x6f, 0x6f, 0xa6, 0x56, 0xf9, 0x0d, 0xb2, 0x8a, 0xa3, 0x09, 0xe2, 0x7f, 0xc3, 0x22, 0x0f, 0x9a, 0xf5, 0x0f, 0x6e, 0x66, 0xe6, 0x85, 0x99, 0x67, 0x13, 0x94, 0xe8, 0x15, 0x55, 0x0f, 0x37, 0x8f, 0x43, 0x8e, 0x32, 0x88, 0x35, 0x8d, 0xb8, 0x19, 0xbd, 0xe4, 0x3f, 0x1d, 0x44, 0x65, 0xd3, 0xbe, 0xbb, 0x7f, 0xdf, 0x21, 0x4e, 0xe6, 0x87, 0x81, 0x86, 0xc0, 0x66, 0xad, 0x52, 0x98, 0x56, 0x02, 0xe0, 0x09, 0xe9, 0xa1, 0x96, 0x0a, 0xfb, 0x75, 0xbd, 0x9c, 0xeb, 0x23, 0x99, 0x9e, 0x93, 0x5c, 0x65, 0xde, 0xc4, 0x68, 0xa4, 0xac, 0x1d, 0xbb, 0xa7, 0x7f, 0x7c, 0x7f, 0xe8, 0xc7, 0x41, 0xd6, 0xd5, 0x1f, 0x1f, 0x66, 0x59, 0xb2, 0xe0, 0xab, 0xa0, 0x52, 0x9a, 0x07, 0x8c, 0xb6, 0x6d, 0x9f, 0x61, 0xfe, 0x06, 0x55, 0x19, 0x22, 0x38, 0x25, 0xc6, 0x20, 0x99, 0xd5, 0xac, 0x8e, 0xfb, 0x43, 0x3d, 0xa6, 0x23, 0xb4, 0xa0, 0x6d, 0x83, 0x4e, 0xd5, 0xd6, 0x14, 0xfd, 0xb6, 0xe2, 0xf2, 0xe2, 0xae, 0x15, 0x39, 0x66, 0x12, 0x5c, 0x0c, 0xa5, 0xc2, 0xa3, 0x5c, 0x4e, 0x55, 0x9a, 0x71, 0xcf, 0xfc, 0x26, 0x54, 0x44, 0x72, 0x2f, 0xed, 0x2a, 0x93, 0x94, 0xce, 0x04, 0x66, 0x66, 0x51, 0x37, 0x02, 0x11, 0xee, 0xbc, 0xe9, 0x6c, 0x4e, 0xba, 0x2c, 0x54, 0x15, 0x25, 0x40, 0x19, 0x2c, 0x6e, 0x2b, 0x1b, 0x7e, 0x8d, 0x29, 0x45, 0x1e, 0x12, 0xbb, 0xe3, 0x44, 0xc8, 0x8b, 0xe6, 0xd3, 0x6b, 0xc8, 0x27, 0x22, 0x40, 0x33, 0xa5, 0x2e, 0x87, 0x59, 0xa9, 0xac, 0x78, 0x23, 0x98, 0x84, 0x75, 0xfc, 0xa4, 0x4e, 0x6f, 0x1b, 0x76, 0x45, 0xd9, 0x91, 0x58, 0xf7, 0x1a, 0x95, 0xad, 0xdd, 0x33, 0x20, 0xfb, 0x25, 0x5d, 0x3d, 0xfb, 0xdf, 0xc2, 0x35, 0x27, 0x38, 0xf0, 0x2f, 0x0f, 0xb6, 0x82, 0x3e, 0x61, 0x64, 0x4b, 0xa4, 0xc2, 0x9d, 0x9e, 0x86, 0xa7, 0xd9, 0xfe, 0xea, 0x0d, 0x87, 0x7a, 0xad, 0x9e, 0x8d, 0x13, 0xd1, 0x0b, 0x53, 0x0c, 0x17, 0x29, 0x40, 0x17, 0xe7, 0x07, 0x75, 0x75, 0x66, 0xfb, 0x94, 0x9d, 0xa7, 0x2c, 0xc2, 0x65, 0x6b, 0xc9, 0xd9, 0xc0, 0xe6, 0x87, 0x31, 0x54, 0x29, 0x64, 0x28, 0x45, 0x63, 0x6c, 0x22, 0xed, 0xaa, 0x3b, 0xcf, 0x97, 0xd5, 0x7a, 0x16, 0xec, 0x06, 0x1d, 0xbf, 0x8a, 0x92, 0x68, 0xa9, 0xdd, 0x6d, 0xe2, 0x2a, 0x4b, 0xca, 0x49, 0xa9, 0x3d, 0x37, 0x2b, 0xdc, 0x00, 0xd9, 0xe4, 0x5e, 0x3c, 0x2c, 0xfd, 0x5f, 0x01, 0xcf, 0xd4, 0x08, 0x38, 0x1b, 0x2a, 0xa5, 0x56, 0xea, 0xfe, 0x53, 0xc9, 0xbd, 0x39, 0xcb, 0x93, 0x5f, 0x06, 0xf0, 0x14, 0x82, 0xfb, 0xe6, 0xe1, 0x24, 0x93, 0xeb, 0xdc, 0x71, 0xc1, 0xac, 0xd9, 0x0a, 0xda, 0x94, 0x1e, 0xcf, 0xf4, 0x27, 0x36, 0x91, 0x8a, 0x47, 0x8c, 0xda, 0xe2, 0x7c, 0x31, 0xbf, 0x70, 0x04, 0x98, 0xfb, 0x3b, 0xf3, 0x70, 0x78, 0xa3, 0x0b, 0x67, 0x69, 0x2b, 0x82, 0x5d, 0xb1, 0xcc, 0x1a, 0x0d, 0x82, 0xf2, 0xe3, 0x6f, 0x0e, 0x54, 0x5b, 0x2a, 0xb9, 0x6a, 0x1d, 0x11, 0x10, 0x20, 0x35, 0x76, 0x7b, 0xa1, 0x64, 0x2b, 0x96, 0x12, 0x5c, 0x62, 0xab, 0x42, 0xc8, 0x30, 0xb7, 0xba, 0x51, 0xb3, 0xe7, 0xe1, 0xa5, 0x21, 0xdc, 0xe5, 0xad, 0x7c, 0xf8, 0x83, 0x7a, 0xa3, 0xec, 0xd4, 0xd1, 0x0d, 0x8b, 0x2e, 0xbf, 0xc4, 0x1f, 0x47, 0x07, 0x5a, 0xa6, 0x4d, 0x5b, 0xc9, 0x21, 0xa2, 0x31, 0x7b, 0xcd, 0x61, 0xcd, 0x1b, 0x51, 0xfc, 0xea, 0xff, 0xb0, 0x86, 0xce, 0x10, 0x51, 0xcb, 0x77, 0xcd, 0x74, 0x4b, 0x3e, 0x6b, 0x0b, 0x9d, 0x42, 0x9f, 0x0f, 0xfa, 0x7c, 0x1e, 0x30, 0x11, 0xc1, 0x02, 0x96, 0x85, 0xd3, 0x8b, 0xdd, 0xc2, 0xc7, 0xf8, 0x09, 0x77, 0x8b, 0x8d, 0xef, 0x3a, 0xfc, 0x21, 0xd6, 0x0b, 0x62, 0x8a, 0x16, 0xd8, 0x5a, 0x75, 0x32, 0x23, 0xd3, 0x5f, 0xa8, 0x9b, 0xba, 0xac, 0x78, 0x64, 0xbf, 0xc4, 0x41, 0x01, 0x5e, 0x95, 0x17, 0x52, 0xf1, 0x53, 0x77, 0xdc, 0x68, 0x62, 0x64, 0xd0, 0x62, 0x9b, 0x73, 0xd0, 0xec, 0xd6, 0x1e, 0x9a, 0xef, 0xea, 0xc6, 0xb7, 0x17, 0x83, 0x74, 0x70, 0xb4, 0x0b, 0x77, 0x7b, 0xab, 0xb5, 0x00, 0x9f, 0xe9, 0x20, 0xc6, 0xf3, 0x3e, 0xc3, 0x1b, 0x5f, 0x53, 0x08, 0x46, 0x5c, 0x4e, 0x03, 0x8f, 0x4f, 0xdc, 0xdc, 0x9d, 0x02, 0xba, 0x9c, 0xd9, 0xca, 0x0d, 0x6d, 0xe7, 0x33, 0xb0, 0xf5, 0x37, 0x8d, 0x04, 0xb0, 0x95, 0x1e, 0x39, 0x8b, 0x15, 0xcc, 0xc6, 0x15, 0x86, 0x41, 0x41, 0x71, 0xb4, 0x48, 0x29, 0x67, 0x97, 0x3f, 0x96, 0x52, 0x1f, 0x75, 0x8a, 0xd7, 0x68, 0xae, 0xa1, 0x66, 0xc5, 0x18, 0xaa, 0x59, 0xbd, 0x8e, 0xa5, 0xa2, 0x89, 0x73, 0x36, 0xa5, 0x01, 0xdd, 0x4a, 0x29, 0xea, 0x1f, 0x03, 0x9a, 0xbc, 0x30, 0x80, 0xa5, 0xa8, 0x44, 0xc1, 0xa3, 0xc5, 0x32, 0xd7, 0x6b, 0xdf, 0x6e, 0xba, 0xd2, 0x02, 0x61, 0x7a, 0x48, 0xb4, 0x8a, 0xa3, 0x7b, 0x26, 0x4d, 0x1b, 0x76, 0x52, 0xd7, 0x4b, 0x18, 0xe7, 0xa0, 0x5a, 0xf3, 0x5e, 0x05, 0x4a, 0x16, 0x65, 0xe3, 0xa2, 0x52, 0x06, 0xa2, 0x68, 0x52, 0x14, 0x00, 0xd3, 0x76, 0xb4, 0xdc, 0x9c, 0xe1, 0x7d, 0xaf, 0xb3, 0x78, 0xe1, 0x1a, 0xf0, 0xa6, 0xbb, 0x72, 0x8b, 0x4c, 0xc7, 0x44, 0xc7, 0xa0, 0xcf, 0x96, 0xf1, 0xfc, 0x1b, 0x6d, 0x92, 0x96, 0x37, 0x21, 0x2b, 0xfa, 0x00, 0xa5, 0x92, 0xd2, 0x38, 0xe9, 0x22, 0xf9, 0x7c, 0xf6, 0x6e, 0x7d, 0xad, 0xd0, 0xd6, 0x46, 0xa7, 0x4a, 0x38, 0x85, 0xe8, 0xce, 0x6a, 0xc8 }; +constexpr AccessUnit AC3_SIZE_MISMATCH_EXPECTED_AU = { 0x15f90, 0x159b2, false, 0, {}, { 0x3d, 0x29, 0x18, 0x6e, 0x61, 0xd9, 0x34, 0x8e, 0x10, 0xc9, 0x57, 0xdd, 0x59, 0x03, 0xca, 0x97, 0x43, 0xdf, 0x1f, 0xd3 } }; + + +const std::vector M2V_SEQUENCE_END_SPLIT_STREAM = { 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xe0, 0x06, 0xe6, 0x81, 0xc1, 0x0d, 0x31, 0x00, 0x05, 0xbf, 0x21, 0x11, 0x00, 0x05, 0xb3, 0x65, 0x1e, 0x69, 0xb2, 0xf2, 0x26, 0xae, 0xd3, 0xf0, 0x56, 0xd2, 0xd9, 0x26, 0xf4, 0x15, 0xd1, 0x9e, 0xbd, 0x68, 0x9d, 0x99, 0x4a, 0x77, 0xcf, 0x6c, 0xea, 0x0a, 0xbe, 0x4b, 0x6c, 0x0f, 0x35, 0x82, 0xf6, 0xef, 0x3d, 0xce, 0x01, 0x6c, 0x79, 0x05, 0x4e, 0xff, 0xb3, 0xca, 0x99, 0xd2, 0x78, 0xdd, 0xf0, 0x68, 0xea, 0x2c, 0x8f, 0x8f, 0xcd, 0x9e, 0x33, 0x8e, 0x0d, 0xe4, 0xf7, 0x67, 0x03, 0x2c, 0x75, 0x5c, 0x05, 0xbf, 0x6a, 0x5d, 0x78, 0x35, 0x68, 0x9d, 0x40, 0xaa, 0xde, 0x5e, 0xde, 0x1c, 0xcb, 0x4a, 0x61, 0x54, 0x61, 0x3a, 0x88, 0xee, 0x47, 0x71, 0xe1, 0xaa, 0xca, 0x47, 0x21, 0xeb, 0x9d, 0x5b, 0xf5, 0x51, 0xc1, 0x08, 0xdb, 0xd1, 0x75, 0x1b, 0x7f, 0x41, 0x7c, 0x99, 0xd1, 0xaa, 0x55, 0x84, 0xf7, 0xac, 0x85, 0xdc, 0x38, 0xf2, 0x26, 0x70, 0xe1, 0x73, 0x49, 0x19, 0x19, 0x1d, 0xbd, 0x77, 0x7a, 0xc5, 0xc5, 0xeb, 0xb9, 0x12, 0x07, 0x4b, 0x06, 0x6b, 0x83, 0x27, 0x8b, 0x66, 0x5a, 0xf5, 0x81, 0x38, 0x77, 0x75, 0x59, 0xda, 0xac, 0x22, 0x41, 0xe6, 0xcf, 0x49, 0xaf, 0xd1, 0x9e, 0x1d, 0xf3, 0x3d, 0x98, 0x05, 0x11, 0x64, 0x8c, 0x86, 0x36, 0x75, 0xc5, 0xd4, 0x7a, 0xda, 0x76, 0x11, 0x6f, 0x5f, 0x60, 0x6f, 0x36, 0xd5, 0x8f, 0x0a, 0xa4, 0x1c, 0x51, 0x9e, 0x10, 0x9c, 0x66, 0xe9, 0xac, 0xdf, 0xde, 0x6f, 0xcc, 0xb8, 0xd6, 0x24, 0xee, 0xe2, 0xaf, 0x5e, 0x75, 0xe0, 0x34, 0x0f, 0x6f, 0xa3, 0x85, 0xbe, 0x61, 0x7b, 0xcf, 0xca, 0x06, 0xf6, 0xf5, 0x02, 0x3b, 0xdb, 0x4f, 0x17, 0x0f, 0x72, 0xdf, 0x97, 0x88, 0xe5, 0xb1, 0x89, 0x9e, 0xec, 0xca, 0x65, 0xb2, 0x40, 0x1f, 0xb4, 0x94, 0x15, 0x34, 0xfe, 0xa6, 0xb4, 0x0f, 0xa7, 0x7f, 0x0b, 0xf7, 0x59, 0x1d, 0x39, 0xef, 0x70, 0xcc, 0x5d, 0x70, 0x01, 0x0e, 0xee, 0xb5, 0x85, 0x56, 0xe8, 0x04, 0xe3, 0x10, 0xae, 0x6e, 0x70, 0xad, 0xf5, 0x56, 0xbe, 0xc8, 0x01, 0xbc, 0x42, 0xd0, 0x50, 0x05, 0xb7, 0xfd, 0x0f, 0x5a, 0x73, 0xec, 0x0c, 0xef, 0x18, 0xd0, 0xb5, 0xbb, 0x9f, 0x62, 0xac, 0x8e, 0xfc, 0x53, 0xac, 0xec, 0x4f, 0x81, 0x98, 0xef, 0x24, 0x46, 0xb5, 0x71, 0x8d, 0xd2, 0xf4, 0xec, 0x60, 0x34, 0x2c, 0x5f, 0xd3, 0x33, 0xfb, 0xcb, 0x20, 0xe1, 0xb2, 0x66, 0x66, 0x4d, 0x39, 0xb0, 0xa2, 0xfc, 0x0f, 0x5f, 0x52, 0xfc, 0x69, 0xe7, 0xf7, 0xc0, 0xd7, 0xc6, 0x36, 0xe0, 0x23, 0x1d, 0x62, 0xe3, 0x3f, 0xb2, 0x66, 0x6b, 0x1f, 0x88, 0x39, 0x21, 0xf0, 0x81, 0xf7, 0x73, 0x41, 0x07, 0xb7, 0x04, 0xb6, 0x22, 0xd3, 0xbb, 0x19, 0xd9, 0xfb, 0xd0, 0xb9, 0xa7, 0xfc, 0x58, 0x88, 0x4d, 0xa9, 0xaa, 0x19, 0xaf, 0xfb, 0x1d, 0x1a, 0xec, 0x50, 0x3f, 0xb2, 0x02, 0x63, 0x30, 0xba, 0x50, 0x42, 0xa0, 0x5e, 0x55, 0xc9, 0xb4, 0x92, 0xb6, 0x31, 0x0d, 0x21, 0xa3, 0x8f, 0xd1, 0x76, 0x48, 0x26, 0xa5, 0xf5, 0xa8, 0x86, 0x26, 0xc3, 0x52, 0x66, 0x92, 0x38, 0x0d, 0x0e, 0xf5, 0xd7, 0xee, 0x53, 0x3c, 0x34, 0xa4, 0xf0, 0xdf, 0xda, 0x98, 0x33, 0x28, 0x3e, 0x66, 0xea, 0x5e, 0xec, 0xd1, 0xf1, 0xca, 0x0b, 0x1e, 0x6d, 0x93, 0x59, 0xf8, 0xb6, 0xec, 0x75, 0x1f, 0xe0, 0xa9, 0xd9, 0x47, 0x34, 0xfc, 0x40, 0x10, 0x72, 0xc7, 0xd3, 0x9c, 0x35, 0x58, 0x02, 0x1d, 0x2b, 0x5f, 0x2c, 0xa1, 0xcc, 0xbf, 0x3a, 0x4d, 0xde, 0x03, 0xc8, 0x51, 0x1e, 0x6a, 0xd3, 0xe8, 0x71, 0x50, 0x63, 0x9f, 0x1b, 0x42, 0xd0, 0x0a, 0xca, 0xc5, 0x19, 0xc8, 0x7f, 0xf0, 0xd1, 0x65, 0x6e, 0x49, 0xb1, 0x55, 0xbf, 0x14, 0x12, 0x07, 0xfe, 0xb1, 0xda, 0x1b, 0xc0, 0xd0, 0xf8, 0x5f, 0x03, 0xf0, 0x92, 0x8e, 0x45, 0xd8, 0xe7, 0xaa, 0x46, 0x4b, 0x10, 0xfa, 0xc2, 0xdd, 0x67, 0xdd, 0x9b, 0x67, 0x3d, 0xbd, 0xa9, 0xd7, 0x63, 0x08, 0x74, 0xd9, 0xc3, 0x64, 0x2c, 0x5f, 0xc8, 0x1c, 0x70, 0x8e, 0x01, 0x4f, 0x72, 0x83, 0xe3, 0x80, 0x21, 0x9e, 0xb6, 0x3f, 0x31, 0xe4, 0x07, 0xb0, 0xfa, 0xf6, 0xd3, 0x4b, 0xc7, 0xb8, 0xf0, 0xf9, 0xcd, 0xe3, 0x81, 0x30, 0xfd, 0x29, 0xdd, 0xc5, 0xc7, 0x01, 0xc3, 0xef, 0xd2, 0xff, 0x45, 0x1c, 0xff, 0x16, 0x72, 0x5a, 0x65, 0x4a, 0x61, 0x97, 0xf1, 0xc1, 0xa6, 0xee, 0x69, 0xa5, 0xc8, 0x74, 0x79, 0x9e, 0xf0, 0x27, 0xc4, 0x2d, 0x45, 0xb3, 0x91, 0x41, 0x41, 0xd9, 0x7b, 0x6f, 0x12, 0x55, 0xe9, 0x01, 0x6c, 0xeb, 0x3c, 0x90, 0x2f, 0xee, 0x9d, 0xa0, 0x5c, 0x7a, 0x5b, 0xa7, 0x01, 0xca, 0x31, 0xd3, 0xfc, 0xb4, 0xd7, 0x25, 0xbe, 0xc3, 0xa0, 0xde, 0xa9, 0x74, 0x7c, 0x6d, 0x0b, 0xd2, 0x47, 0x76, 0x4a, 0x3f, 0x8e, 0xbd, 0xe3, 0x38, 0xfb, 0xf6, 0x4d, 0xaf, 0x9b, 0xb8, 0xba, 0x50, 0xaa, 0x60, 0x81, 0xd4, 0x0e, 0x8d, 0x6b, 0xd2, 0x9b, 0xdd, 0x22, 0xf0, 0x38, 0x4b, 0xef, 0xd0, 0x34, 0x76, 0x65, 0x53, 0xd5, 0xcf, 0x41, 0xe3, 0xaa, 0x1d, 0xa1, 0xd7, 0xa7, 0xdb, 0x75, 0xc6, 0x69, 0xf0, 0x71, 0xbe, 0x98, 0x06, 0xe6, 0x8e, 0x04, 0x6e, 0x7d, 0x89, 0x24, 0xc6, 0xa4, 0x53, 0xa6, 0x68, 0x6a, 0xdf, 0xb3, 0xa3, 0xbe, 0x9f, 0x76, 0x17, 0xa1, 0x5f, 0x18, 0x60, 0xf0, 0x85, 0x23, 0x67, 0x04, 0x0e, 0x48, 0x93, 0x49, 0x84, 0xc3, 0x11, 0x30, 0x0a, 0x8c, 0x86, 0x00, 0x42, 0x0b, 0x71, 0xc0, 0x6c, 0xb9, 0xd2, 0x7f, 0x75, 0x30, 0x17, 0x37, 0x2c, 0x48, 0x96, 0xe0, 0xc0, 0x1d, 0xdf, 0x45, 0xcd, 0xc5, 0x69, 0xcb, 0xcf, 0x2d, 0x55, 0x7b, 0x0a, 0x14, 0x44, 0x68, 0xd2, 0x55, 0x6a, 0xa4, 0xe7, 0x62, 0x87, 0x43, 0x9d, 0x04, 0x26, 0x7e, 0x2e, 0x6a, 0x25, 0x8c, 0x45, 0x20, 0x26, 0xfc, 0x6a, 0x10, 0xfc, 0x41, 0x04, 0x1e, 0x1c, 0x0e, 0xf4, 0x0c, 0xdb, 0x82, 0x60, 0xc5, 0x1c, 0x11, 0xdc, 0x17, 0x07, 0x01, 0xa5, 0x83, 0x24, 0xa8, 0x7b, 0x4c, 0x7f, 0xf2, 0x92, 0x3e, 0x5f, 0xce, 0x2a, 0xf5, 0xa9, 0x73, 0x17, 0xe2, 0x0a, 0x11, 0x8b, 0x10, 0x18, 0x1e, 0x0a, 0x97, 0xcd, 0xdb, 0x51, 0x6a, 0x5a, 0x69, 0x69, 0x61, 0x06, 0x9c, 0xd3, 0x80, 0xfa, 0xe3, 0xac, 0x8b, 0x9e, 0xbf, 0xbe, 0x1d, 0x35, 0x95, 0xda, 0xd8, 0x42, 0xcf, 0x01, 0xca, 0x88, 0x02, 0x2a, 0x93, 0x1e, 0xa8, 0xd7, 0xe6, 0x60, 0x4c, 0xac, 0x14, 0x16, 0x4b, 0x50, 0xda, 0x7a, 0x72, 0x3b, 0x1a, 0xeb, 0x52, 0x2e, 0xc9, 0xa1, 0x96, 0x2a, 0xc9, 0x73, 0x4d, 0xe2, 0x06, 0xff, 0xe4, 0xa7, 0xf1, 0xf4, 0x32, 0x4e, 0x5f, 0xd8, 0x37, 0x9a, 0x51, 0x48, 0x6c, 0xf3, 0x31, 0xb5, 0x3c, 0x10, 0xb6, 0xc1, 0x74, 0xa8, 0xad, 0x53, 0x64, 0x7d, 0xc5, 0xa2, 0x21, 0xf8, 0x00, 0xd6, 0x48, 0x05, 0xd7, 0x59, 0x65, 0xa2, 0xaa, 0x61, 0xd1, 0x69, 0xd6, 0xf7, 0xe2, 0xf3, 0x03, 0xd3, 0x1a, 0xeb, 0xaa, 0x99, 0x5f, 0xc6, 0x9f, 0x97, 0x3b, 0x80, 0x7c, 0x98, 0xdd, 0xf0, 0x87, 0xde, 0x03, 0xec, 0x82, 0xe4, 0xce, 0x55, 0xb3, 0xda, 0x42, 0x8b, 0xbf, 0xc6, 0x51, 0xfd, 0x20, 0x21, 0xff, 0xb6, 0x0b, 0xe6, 0x80, 0x74, 0x6d, 0x45, 0x9a, 0xe5, 0x63, 0x6d, 0x30, 0xe9, 0x1a, 0x0c, 0x42, 0x48, 0x08, 0xa5, 0xd5, 0xa3, 0x91, 0x38, 0x7d, 0xc7, 0x73, 0x4c, 0xef, 0x26, 0xad, 0x46, 0x61, 0xed, 0x38, 0x73, 0xa5, 0x1e, 0x0d, 0x7b, 0x1e, 0xe6, 0x62, 0xa4, 0x96, 0x7b, 0x6d, 0x52, 0x7b, 0x3d, 0x56, 0xb5, 0x41, 0xab, 0xe4, 0xa8, 0xd0, 0x94, 0x1a, 0x15, 0x7e, 0x34, 0x23, 0xab, 0x77, 0xcb, 0xee, 0x85, 0x0e, 0x2f, 0x1b, 0xf7, 0x74, 0x49, 0x31, 0xd8, 0xfa, 0xf2, 0xd5, 0xbf, 0xa6, 0xe3, 0x65, 0x46, 0x77, 0x9c, 0x69, 0x67, 0x13, 0x20, 0xd9, 0xfc, 0xed, 0xc7, 0x12, 0x2b, 0xf1, 0x98, 0x40, 0xbb, 0x8e, 0x87, 0xe2, 0x1a, 0xa2, 0x4a, 0xe7, 0x7f, 0x3a, 0xda, 0xbe, 0x21, 0xcd, 0x9e, 0xb2, 0x75, 0x52, 0xb2, 0x97, 0x48, 0x08, 0xe2, 0x9a, 0x84, 0x2b, 0x47, 0x00, 0x94, 0xe0, 0x81, 0x4e, 0xef, 0x6c, 0xca, 0x21, 0x7c, 0x65, 0xe9, 0x0a, 0x41, 0x16, 0xc3, 0x8e, 0x59, 0xd2, 0xf1, 0x18, 0x31, 0xde, 0xef, 0xfb, 0x2b, 0xcc, 0x42, 0x8d, 0x51, 0xcd, 0x07, 0x98, 0x76, 0x90, 0x3c, 0x75, 0xb7, 0x68, 0x77, 0xec, 0x41, 0xd5, 0xca, 0x38, 0x8e, 0x10, 0xf8, 0xe3, 0xa5, 0x05, 0x14, 0xac, 0xc7, 0x78, 0x61, 0xde, 0xc6, 0xe0, 0x14, 0x2e, 0x04, 0x4f, 0xe6, 0x3b, 0x76, 0x9c, 0xa5, 0x43, 0xbf, 0xdb, 0x7e, 0x24, 0xae, 0x62, 0x28, 0x7d, 0xbb, 0x98, 0x98, 0x30, 0x29, 0x56, 0x9f, 0x9d, 0xb5, 0x8a, 0xa5, 0x3d, 0x75, 0xb8, 0x35, 0xea, 0x34, 0xa9, 0x4c, 0xdb, 0xf3, 0x4d, 0x62, 0x19, 0x52, 0x4b, 0xfa, 0x3d, 0xee, 0x93, 0xb6, 0xff, 0x4f, 0x56, 0x0e, 0x84, 0x36, 0x4a, 0xb3, 0x58, 0x36, 0x30, 0x23, 0x72, 0xc8, 0x7c, 0xd2, 0x01, 0x5d, 0xbc, 0xb0, 0xc5, 0x4b, 0x78, 0xf9, 0x7c, 0x66, 0x17, 0x5e, 0x10, 0x80, 0xef, 0x7c, 0xa5, 0x2a, 0xe8, 0x67, 0x01, 0xfa, 0xe3, 0xf0, 0x6d, 0x50, 0x80, 0x6b, 0x88, 0x74, 0x6e, 0x46, 0xd3, 0xad, 0x04, 0xc1, 0x43, 0xb3, 0xe5, 0x17, 0x87, 0x24, 0xfe, 0x6d, 0x46, 0x58, 0x4b, 0xec, 0xf3, 0x62, 0x66, 0x39, 0x2d, 0xbb, 0xfe, 0x8b, 0x5c, 0xf0, 0x81, 0x4f, 0xe4, 0x82, 0xdd, 0x9d, 0xac, 0x6d, 0x7e, 0xb1, 0x77, 0x16, 0x49, 0xbe, 0xd3, 0x28, 0x10, 0xc7, 0xb3, 0xbf, 0xc6, 0x0b, 0x5e, 0x8a, 0xd9, 0x5c, 0xf6, 0xd7, 0x5d, 0xde, 0x27, 0xba, 0x04, 0xd9, 0xdc, 0xbb, 0x01, 0xd4, 0x10, 0x46, 0xdd, 0x60, 0x75, 0xea, 0xf1, 0x8e, 0xbc, 0xf1, 0xf8, 0x67, 0xee, 0x1c, 0x51, 0x3e, 0xe9, 0xd5, 0xfa, 0x25, 0xa1, 0x0f, 0x0f, 0x8c, 0x8e, 0x89, 0x77, 0xe5, 0xe6, 0x1a, 0x28, 0x34, 0x16, 0x85, 0x94, 0x5b, 0x83, 0xe3, 0xde, 0xfe, 0x91, 0x29, 0xdc, 0xe1, 0xe6, 0x75, 0xa8, 0x0a, 0xf6, 0x08, 0xe7, 0x4d, 0xad, 0xb5, 0x0e, 0x63, 0xf3, 0x7d, 0xbf, 0xf0, 0xeb, 0xd1, 0x71, 0xe7, 0x76, 0xf5, 0x87, 0xb6, 0x95, 0x44, 0xae, 0x2f, 0x6b, 0x72, 0xbd, 0xd6, 0x69, 0xa3, 0x42, 0xf4, 0x2f, 0x3b, 0xaf, 0x03, 0x6b, 0x56, 0x86, 0x50, 0xa1, 0xfd, 0xcc, 0x93, 0xb3, 0xff, 0xc3, 0x72, 0xfe, 0x7c, 0x56, 0x94, 0x74, 0x70, 0xeb, 0xea, 0x83, 0x9c, 0xcc, 0xed, 0xcf, 0xf9, 0xae, 0xce, 0xfe, 0xa7, 0x3f, 0xf8, 0xb0, 0xba, 0xdf, 0x7a, 0x85, 0x13, 0xb4, 0xe5, 0xf7, 0x6b, 0x24, 0xc6, 0x2c, 0x01, 0x8e, 0x32, 0xb9, 0x29, 0xa6, 0xf1, 0xb7, 0x2e, 0xc6, 0x94, 0xbd, 0xd4, 0x3e, 0x07, 0x57, 0x3a, 0x32, 0xaf, 0x27, 0xbe, 0x66, 0x90, 0x20, 0x8a, 0x45, 0xc9, 0xc5, 0x4f, 0x21, 0x42, 0x95, 0x4a, 0xbc, 0x3c, 0x0d, 0x8d, 0x4e, 0x22, 0xaa, 0x1c, 0xba, 0x2a, 0xb3, 0x69, 0xd9, 0xf4, 0x33, 0x89, 0xde, 0x8f, 0xc5, 0xf0, 0x65, 0x90, 0xb3, 0x62, 0x74, 0x4c, 0x7f, 0xb3, 0xa5, 0x1e, 0x67, 0x62, 0x1e, 0x29, 0x88, 0x6d, 0x2e, 0x65, 0x5c, 0x57, 0xbe, 0x3b, 0xed, 0x77, 0xd0, 0x55, 0xe9, 0xcc, 0x6b, 0xe6, 0x0a, 0xcb, 0xa6, 0x7a, 0x6e, 0x9d, 0xbe, 0x6f, 0xba, 0x87, 0xc8, 0x0d, 0x5d, 0x03, 0xaf, 0xeb, 0xa9, 0x24, 0xb8, 0x51, 0x17, 0x17, 0x1b, 0x73, 0xd8, 0x26, 0xbf, 0x89, 0xeb, 0x27, 0x68, 0xff, 0x18, 0x9e, 0xc6, 0x70, 0xb5, 0x15, 0x17, 0xc0, 0x5b, 0x7b, 0x93, 0xd2, 0x0f, 0x26, 0x8f, 0x36, 0x2a, 0x1b, 0x6c, 0x97, 0x77, 0x69, 0xaf, 0x17, 0xeb, 0xf2, 0x3e, 0x96, 0xc4, 0xf9, 0xba, 0xce, 0xb8, 0x57, 0xb7, 0x46, 0x79, 0xe8, 0x5c, 0xfd, 0x75, 0xdd, 0x03, 0xbe, 0x37, 0x5a, 0x51, 0x63, 0xc1, 0xa7, 0xb9, 0x92, 0x68, 0x23, 0xb1, 0x74, 0x84, 0x49, 0xe2, 0x8e, 0xc1, 0x94, 0x6f, 0x3d, 0x89, 0xdf, 0x11, 0xc0, 0xfc, 0x00, 0x0c, 0x17, 0xdc, 0x6e, 0x92, 0x37, 0xde, 0x91, 0xf5, 0x18, 0x41, 0x90, 0x58, 0xc4, 0x8b, 0xe8, 0x58, 0xd7, 0x87, 0xe6, 0x27, 0xc9, 0xce, 0x7b, 0xc0, 0x2e, 0xf8, 0xd6, 0x1c, 0x7c, 0xe3, 0x79, 0x95, 0x92, 0x1f, 0x71, 0xd8, 0x9f, 0x7f, 0x0f, 0x25, 0x99, 0x03, 0x0f, 0x81, 0xc7, 0x25, 0x5d, 0x49, 0x51, 0xad, 0xc8, 0x9b, 0x62, 0x87, 0x32, 0x62, 0x18, 0xef, 0xb0, 0x72, 0x56, 0xb4, 0x99, 0xa9, 0xff, 0xb0, 0xa0, 0x6a, 0xb6, 0xf7, 0xad, 0x53, 0xd4, 0xd8, 0xc4, 0xc5, 0xa6, 0x9a, 0x94, 0x37, 0x8d, 0x0d, 0xc6, 0x56, 0x90, 0x00, 0x4a, 0x35, 0x70, 0x60, 0x5a, 0x47, 0x58, 0x1d, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x11, 0x81, 0xc1, 0x0d, 0x31, 0x00, 0x05, 0xbf, 0x21, 0x11, 0x00, 0x05, 0xb3, 0x65, 0x1e, 0x69, 0xb2, 0xb7, 0xde, 0xad, 0xbe, 0xef, 0x92, 0x8a, 0xad, 0x4b, 0x8e, 0x21, 0x89, 0xdc, 0xf8, 0x7d, 0x5b, 0x89, 0xa1, 0x2a, 0x4b, 0xb2, 0xff, 0xa4, 0x5e, 0x1c, 0x1f, 0x0f, 0x4c, 0x68, 0x16, 0x18, 0x5e, 0x99, 0xbd, 0x17, 0x33, 0x71, 0x7c, 0x20, 0x20, 0xf1, 0xab, 0x29, 0x8f, 0x99, 0xd3, 0x63, 0xd7, 0x9d, 0x6e, 0xac, 0x4e, 0x23, 0x68, 0xb2, 0x51, 0x45, 0x5e, 0xe4, 0x57, 0x53, 0x49, 0x2c, 0x78, 0x20, 0xba, 0xd2, 0xb6, 0xf8, 0xef, 0x3e, 0xb8, 0xea, 0x7f, 0x79, 0xc8, 0x57, 0xbc, 0x72, 0xdf, 0x31, 0x38, 0x38, 0x33, 0xd8, 0xe4, 0x9c, 0x00, 0x0f, 0x94, 0xb3, 0x63, 0xbd, 0x27, 0xde, 0x73, 0x58, 0x24, 0xaf, 0x73, 0xd1, 0x63, 0xc8, 0xb3, 0x28, 0x0d, 0x12, 0x88, 0x20, 0xbe, 0x3c, 0x67, 0x72, 0x1c, 0x71, 0x92, 0x8a, 0xc8, 0x64, 0x53, 0xaf, 0x30, 0xd3, 0xd3, 0xe8, 0xa1, 0x36, 0x39, 0xba, 0xe6, 0x63, 0xe7, 0x72, 0x8d, 0x78, 0xc0, 0xf3, 0xf4, 0xaf, 0x5a, 0xc8, 0xc1, 0x08, 0x20, 0xe4, 0xf9, 0x49, 0xdb, 0xcf, 0x85, 0x4e, 0x5d, 0x63, 0x7f, 0xcf, 0x8e, 0xdf, 0xaf, 0xa3, 0x3a, 0xfd, 0x6e, 0x05, 0xc7, 0xe7, 0x34, 0xd6, 0x78, 0x05, 0x0c, 0x8a, 0xe3, 0xd6, 0x4c, 0x55, 0x2a, 0xfa, 0xa4, 0xd0, 0x27, 0x0a, 0xde, 0x36, 0xa1, 0x92, 0xd2, 0xb2, 0xf0, 0x09, 0xd5, 0xf6, 0xf2, 0x8b, 0x2c, 0x13, 0x7c, 0xe9, 0xfc, 0xe5, 0x3f, 0xd3, 0x74, 0x5d, 0xd4, 0x99, 0x3c, 0xd4, 0xc9, 0x64, 0x7a, 0x65, 0xf8, 0x13, 0x34, 0x50, 0x0b, 0xab, 0x08, 0x77, 0x1a, 0x94, 0x0d, 0xcd, 0xb2, 0xef, 0x20, 0x15, 0xf9, 0x5b, 0x33, 0x21, 0x95, 0xf5, 0x70, 0x19, 0x3d, 0x1c, 0x26, 0xe9, 0x54, 0x8c, 0x46, 0x32, 0x13, 0x36, 0x64, 0x4f, 0x19, 0x7f, 0xd9, 0xa4, 0xc8, 0xd7, 0x1a, 0x8d, 0x20, 0xb0, 0x30, 0xba, 0xcf, 0x2b, 0xd5, 0x7e, 0x30, 0x67, 0x83, 0x88, 0xf0, 0x3b, 0x5d, 0x9d, 0x6b, 0x59, 0x51, 0xd4, 0xdc, 0x5d, 0xa4, 0x65, 0xa2, 0x81, 0x4b, 0x19, 0xcd, 0xab, 0x37, 0x76, 0x67, 0x44, 0xaf, 0x3f, 0xdd, 0x74, 0xd6, 0x01, 0x61, 0xf2, 0x8f, 0xf7, 0x9e, 0x55, 0x3f, 0xe7, 0xb0, 0x2f, 0x65, 0x1f, 0x64, 0xf2, 0x47, 0x61, 0x48, 0xa3, 0x12, 0xad, 0x4e, 0x0d, 0x11, 0x31, 0x08, 0xba, 0x4a, 0x76, 0x32, 0x3f, 0x90, 0x69, 0x80, 0x3e, 0x42, 0x8e, 0xea, 0x18, 0xac, 0x25, 0x6f, 0x7e, 0x95, 0xff, 0x41, 0xd7, 0x84, 0xf3, 0x5e, 0xea, 0x7f, 0x40, 0x2d, 0xbf, 0x63, 0xf7, 0xe3, 0xe7, 0xbf, 0x6b, 0xdb, 0xdb, 0x44, 0x40, 0x78, 0x9c, 0x6c, 0xa1, 0x17, 0x1a, 0xf4, 0x8f, 0x55, 0xe7, 0x41, 0xf2, 0x1b, 0x52, 0xe9, 0x6e, 0x3b, 0x66, 0x63, 0x3a, 0x89, 0x81, 0x40, 0x02, 0xea, 0x6b, 0x2e, 0x81, 0xd5, 0xbe, 0x4b, 0x73, 0x8a, 0x7f, 0xd7, 0x9e, 0x8b, 0xf7, 0xc8, 0x05, 0xb7, 0x48, 0xbb, 0xb0, 0x5d, 0xe8, 0x92, 0xbf, 0x5f, 0xdd, 0xcc, 0x32, 0x42, 0xb7, 0x6b, 0xff, 0x1d, 0x8a, 0x45, 0xe3, 0x9e, 0xaa, 0x57, 0x3a, 0x2d, 0x54, 0xbf, 0x98, 0x04, 0x5b, 0x29, 0xb3, 0x10, 0xcc, 0x4c, 0x4b, 0xec, 0x5f, 0x94, 0xfe, 0xba, 0x04, 0x77, 0x4d, 0x1c, 0x84, 0x2e, 0x44, 0xe5, 0x4a, 0xcb, 0x11, 0x89, 0x30, 0x46, 0xda, 0x8a, 0xb9, 0x1a, 0xda, 0x6f, 0xc5, 0x24, 0xc9, 0xff, 0xa1, 0xf8, 0x00, 0x6c, 0x44, 0xaa, 0x48, 0x5d, 0x9e, 0xa8, 0xe5, 0x74, 0xda, 0xe3, 0x11, 0x0a, 0x67, 0xca, 0xb9, 0x5c, 0x68, 0xed, 0x21, 0x5b, 0x09, 0x65, 0x3c, 0x4a, 0xe9, 0x72, 0xbb, 0xad, 0x27, 0xb7, 0xe5, 0x5f, 0x0c, 0xfd, 0x04, 0xba, 0xcf, 0x71, 0x6b, 0x71, 0x62, 0x9e, 0xec, 0x40, 0x2c, 0x29, 0x87, 0x5a, 0xef, 0x1d, 0x18, 0xee, 0xd1, 0x67, 0x9b, 0xea, 0x35, 0x9c, 0xc5, 0xb3, 0x7a, 0xcd, 0x80, 0xbc, 0xd4, 0xf7, 0x38, 0x56, 0x9b, 0x02, 0xca, 0x61, 0xa1, 0x8d, 0x15, 0x96, 0x8d, 0xe8, 0xb6, 0xb1, 0xb9, 0x74, 0xc8, 0x9b, 0x73, 0xa9, 0xe6, 0x16, 0x81, 0x9e, 0xb2, 0xf8, 0x5a, 0x56, 0xf2, 0x9e, 0x8c, 0x26, 0xe7, 0xc5, 0x40, 0xbf, 0xd8, 0x94, 0x91, 0x04, 0x21, 0x0c, 0x00, 0x04, 0x7e, 0x78, 0x12, 0x5a, 0x6e, 0x69, 0x57, 0xb6, 0x27, 0xa6, 0x39, 0xe5, 0xe5, 0x00, 0x0e, 0xe0, 0xe2, 0xe1, 0x4b, 0x83, 0x9d, 0x51, 0x00, 0xfc, 0xa9, 0xb7, 0x46, 0xf5, 0x99, 0x1a, 0x1f, 0xfe, 0x54, 0x81, 0x2e, 0xe3, 0x63, 0xcb, 0x73, 0xc4, 0x5b, 0x8f, 0x2d, 0x0d, 0x76, 0x83, 0x3c, 0xe1, 0x80, 0x5b, 0xdc, 0x71, 0x8d, 0x6a, 0x3b, 0xdc, 0xae, 0x31, 0x4a, 0xc6, 0xfb, 0x6e, 0x1c, 0xc3, 0xdb, 0xb5, 0xa0, 0x83, 0x7a, 0x34, 0xfb, 0x89, 0x57, 0xa4, 0xd5, 0x7c, 0x46, 0x5e, 0xa7, 0x79, 0xf7, 0x75, 0x01, 0x72, 0x43, 0x4e, 0x7a, 0x1f, 0xed, 0x39, 0x09, 0xd2, 0x80, 0xf9, 0x6a, 0x7a, 0x41, 0x6f, 0x0b, 0x5f, 0x97, 0x35, 0xe1, 0xa0, 0x35, 0xaf, 0xba, 0x36, 0x45, 0xad, 0xf4, 0x49, 0xbe, 0x74, 0x42, 0x02, 0xea, 0x3b, 0xf1, 0xd5, 0x7d, 0x67, 0x7e, 0x66, 0x98, 0xb8, 0x76, 0x00, 0xbd, 0x9a, 0xd7, 0x17, 0x2d, 0xd7, 0x8e, 0xe6, 0xed, 0xe6, 0xf0, 0x3e, 0x67, 0x94, 0xde, 0xf3, 0x39, 0x78, 0xb6, 0x0e, 0x60, 0xe2, 0xd6, 0xeb, 0xfe, 0x98, 0x84, 0xcc, 0xb1, 0xa2, 0xa2, 0x8f, 0x28, 0x10, 0x60, 0xd8, 0xbd, 0x6d, 0x00, 0x8d, 0xb8, 0x9d, 0x11, 0x2f, 0x73, 0xf9, 0x79, 0xbf, 0xf2, 0x18, 0xa2, 0x27, 0x5d, 0x0c, 0xef, 0x29, 0x40, 0x3f, 0x0d, 0x45, 0xb4, 0x96, 0xb9, 0xc6, 0x44, 0xa3, 0x4b, 0x09, 0x9b, 0xa9, 0x93, 0x16, 0xf0, 0x3d, 0xa1, 0x24, 0x13, 0xcd, 0x39, 0x13, 0xe6, 0x4b, 0x48, 0x1b, 0xc7, 0x3a, 0x4a, 0xcf, 0x9e, 0xbd, 0x5c, 0x18, 0x1f, 0x36, 0xbc, 0x83, 0xbe, 0x79, 0xb6, 0x96, 0xe0, 0x55, 0x76, 0x9f, 0x29, 0x7b, 0xac, 0x6e, 0x5a, 0x7b, 0xb2, 0x83, 0x5a, 0xbe, 0xe4, 0x41, 0xe1, 0xfb, 0x1c, 0x3f, 0x32, 0x42, 0x79, 0x57, 0x93, 0xdd, 0x8a, 0xd6, 0x65, 0x8d, 0x60, 0x46, 0xda, 0xc8, 0x84, 0x60, 0xdb, 0x78, 0x69, 0xef, 0xe5, 0xa6, 0x7c, 0xa5, 0x22, 0xef, 0x23, 0x51, 0xd6, 0xe6, 0x04, 0x66, 0xf4, 0x62, 0xd8, 0x0b, 0x59, 0x94, 0x16, 0xd8, 0xf6, 0xce, 0x9f, 0xa1, 0x0e, 0x81, 0x8a, 0x54, 0xab, 0x78, 0x1e, 0xff, 0xb9, 0x59, 0x25, 0x7a, 0x43, 0x52, 0xa3, 0xc2, 0x74, 0xb8, 0xa0, 0x29, 0x27, 0x98, 0xf3, 0x18, 0xe2, 0x6e, 0x7b, 0x8b, 0x48, 0x73, 0xc5, 0x3b, 0x1c, 0xb1, 0x16, 0x40, 0x68, 0x9a, 0xbe, 0x16, 0x48, 0xaa, 0x07, 0xef, 0x40, 0xc1, 0xec, 0xdb, 0x4e, 0x94, 0x8c, 0x54, 0x41, 0xa2, 0x66, 0x33, 0x53, 0xf9, 0x6e, 0x4d, 0xcc, 0x62, 0x24, 0x33, 0x02, 0xeb, 0x91, 0xbe, 0xeb, 0x95, 0x34, 0xa7, 0x0e, 0x88, 0xfb, 0x1f, 0x6b, 0x15, 0xe0, 0x17, 0xc0, 0x6d, 0x6b, 0x4f, 0x78, 0x5a, 0x7c, 0x36, 0xae, 0xe6, 0x7e, 0xff, 0x00, 0x7c, 0x27, 0x94, 0xc6, 0xd4, 0xa1, 0x22, 0x2a, 0x83, 0x64, 0x34, 0x6e, 0x71, 0x0f, 0x4e, 0x98, 0xb7, 0xc9, 0x78, 0xfb, 0x6d, 0xaa, 0x35, 0x56, 0x16, 0x20, 0x1b, 0x9f, 0x66, 0xec, 0x80, 0x3e, 0xc5, 0x5a, 0x61, 0x69, 0x7c, 0x0c, 0x70, 0x03, 0x23, 0xe8, 0xa5, 0x97, 0x22, 0x62, 0xe6, 0x47, 0xb3, 0x61, 0xe3, 0x1e, 0xd7, 0x77, 0xc8, 0xea, 0x12, 0xf6, 0x0c, 0xf5, 0xca, 0xde, 0xc3, 0x33, 0x97, 0x93, 0xcc, 0x7b, 0xca, 0x75, 0xda, 0x71, 0x10, 0x3e, 0xf5, 0xd3, 0xa7, 0x61, 0xd9, 0xa0, 0x3e, 0xe3, 0x2f, 0x78, 0x5f, 0xef, 0xcb, 0x89, 0xa8, 0x8d, 0xb6, 0xb6, 0x9c, 0xe9, 0x55, 0x45, 0x12, 0xf9, 0x46, 0x55, 0x94, 0xd3, 0x96, 0x0f, 0x12, 0xb6, 0xdc, 0x25, 0x86, 0xbe, 0xca, 0x13, 0x04, 0xbe, 0xda, 0x39, 0xab, 0x9a, 0x1e, 0xa3, 0x0d, 0x13, 0xa6, 0x19, 0x7b, 0xe5, 0x17, 0xcd, 0x63, 0x4a, 0x6a, 0xab, 0xd7, 0xde, 0xbc, 0x0f, 0x70, 0xa6, 0xb2, 0x60, 0xae, 0xcd, 0xdb, 0x52, 0x59, 0x17, 0x28, 0x15, 0x5c, 0xa9, 0xec, 0x89, 0x29, 0xb4, 0x39, 0x7d, 0x71, 0x2b, 0x47, 0x75, 0x29, 0x43, 0x66, 0xa8, 0x8f, 0x15, 0xb9, 0xb5, 0xc5, 0x69, 0x03, 0xc1, 0x12, 0xf5, 0x3c, 0xeb, 0x22, 0x76, 0x2a, 0x36, 0xc1, 0x5b, 0x5b, 0x4a, 0x21, 0xa7, 0xdd, 0xb5, 0xed, 0x53, 0x93, 0x9f, 0xd1, 0xac, 0xb2, 0x51, 0x08, 0x68, 0x03, 0x73, 0xd3, 0x36, 0x40, 0xca, 0xe1, 0x7b, 0xb8, 0x0b, 0xca, 0xc0, 0x3d, 0xa6, 0x12, 0xf2, 0x55, 0x30, 0xe5, 0xba, 0x2c, 0x26, 0x43, 0xbf, 0x2b, 0x0a, 0x94, 0xcc, 0xb1, 0xd9, 0x3a, 0x2a, 0xa0, 0xb4, 0xeb, 0xaf, 0x7e, 0xb5, 0xad, 0xb9, 0x0b, 0xda, 0xd3, 0xa1, 0x91, 0x25, 0x11, 0x2e, 0x52, 0xc8, 0xf1, 0xd1, 0xba, 0x1a, 0xef, 0xd5, 0x5d, 0x7b, 0x02, 0x1b, 0x8d, 0x34, 0x0f, 0x48, 0x5b, 0x66, 0x68, 0xd2, 0xab, 0xda, 0x16, 0x76, 0x63, 0x13, 0x17, 0x83, 0x60, 0xe4, 0xb0, 0x8f, 0x19, 0x33, 0x2d, 0x38, 0x6a, 0x28, 0x85, 0x5c, 0xbc, 0xea, 0xb1, 0xfb, 0xf8, 0xf2, 0xc6, 0x59, 0x21, 0xb6, 0xf2, 0xc7, 0x7a, 0x7c, 0x9b, 0xd4, 0x58, 0x82, 0xed, 0xac, 0x6a, 0xc4, 0x71, 0xfc, 0x2e, 0xeb, 0x9c, 0xe4, 0xcc, 0x8b, 0x66, 0x5d, 0xd5, 0x1c, 0x12, 0x16, 0x5d, 0x98, 0xa6, 0x2d, 0x6b, 0x75, 0x4e, 0x00, 0x59, 0x36, 0xfe, 0x6c, 0x87, 0x48, 0x47, 0xa9, 0xec, 0x8f, 0xc8, 0x88, 0x66, 0x00, 0xb3, 0x5a, 0xe7, 0xe1, 0xc5, 0x13, 0x3b, 0x57, 0xe7, 0x81, 0xa1, 0xfb, 0x6a, 0x7e, 0xc4, 0xf4, 0xf4, 0xc7, 0xbe, 0x90, 0x3c, 0x6a, 0xcc, 0xed, 0xe9, 0x35, 0xf2, 0x19, 0xc8, 0x6e, 0xa2, 0xbe, 0xae, 0xa0, 0x46, 0x3d, 0x76, 0xcd, 0xcf, 0xae, 0xd6, 0x8c, 0x0c, 0xdf, 0x05, 0x1a, 0x2b, 0xde, 0xbf, 0xc4, 0x0d, 0xe6, 0x74, 0x88, 0xad, 0xc7, 0x39, 0x8c, 0x33, 0x9b, 0x31, 0xaa, 0xc4, 0xc0, 0xab, 0x8d, 0x4b, 0xad, 0x88, 0x87, 0x4a, 0x1b, 0x59, 0xaa, 0xac, 0xfe, 0x11, 0x19, 0xa4, 0xd5, 0x40, 0xb1, 0x18, 0x7c, 0x05, 0xa8, 0x7e, 0x89, 0xda, 0x57, 0x0e, 0xfd, 0x70, 0x59, 0xa5, 0xa0, 0x8c, 0x85, 0x3f, 0xaf, 0x05, 0x8a, 0xe5, 0xd3, 0x98, 0x0a, 0x30, 0x8b, 0x47, 0x44, 0x32, 0x13, 0x97, 0x61, 0xef, 0x11, 0xca, 0x96, 0x8f, 0x78, 0x9c, 0x64, 0x4f, 0x56, 0xb1, 0x5c, 0xdc, 0x3f, 0x24, 0x6c, 0xf2, 0xb6, 0x5b, 0x8b, 0x59, 0x8b, 0xab, 0xa6, 0xb8, 0xfc, 0x41, 0xf5, 0xc1, 0xa4, 0xcc, 0x98, 0xdf, 0x72, 0xe7, 0x8a, 0x3a, 0x9a, 0xe6, 0xd7, 0xbf, 0xf7, 0xa0, 0xc7, 0xf9, 0xe1, 0x51, 0xc0, 0xce, 0x7f, 0x8f, 0x07, 0x36, 0xfa, 0x9d, 0xe6, 0x9f, 0xe6, 0x44, 0xe1, 0xf8, 0xe7, 0x0b, 0xe9, 0xde, 0xe9, 0x6a, 0x7f, 0x08, 0x9e, 0xe9, 0x08, 0xfa, 0x28, 0x87, 0xc5, 0xc7, 0x6d, 0x08, 0xd2, 0xf2, 0x59, 0x20, 0x81, 0xdf, 0xe6, 0x0c, 0x85, 0xb5, 0x10, 0xcd, 0x39, 0x24, 0x0d, 0x67, 0x5c, 0x49, 0x2d, 0x84, 0xc8, 0x2c, 0x81, 0x11, 0xfa, 0x49, 0x27, 0x25, 0xd4, 0x40, 0x7d, 0xee, 0xb1, 0x83, 0x72, 0xd6, 0x53, 0xf2, 0xb6, 0x3c, 0x08, 0x58, 0xf8, 0xe3, 0x5a, 0x9e, 0xa7, 0x9d, 0x8d, 0x26, 0xf2, 0xfd, 0xe0, 0x4e, 0xb8, 0x4a, 0x49, 0x99, 0x97, 0x38, 0xe8, 0xc8, 0xc6, 0x6f, 0x54, 0xe7, 0xa7, 0x64, 0xdd, 0x34, 0x2b, 0x71, 0x60, 0xc9, 0x80, 0xbb, 0x42, 0xbe, 0xfb, 0x57, 0x4f, 0x6c, 0xc4, 0x4d, 0x9b, 0x53, 0x07, 0x58, 0x5b, 0xec, 0x02, 0x00, 0x83, 0xec, 0x5b, 0x6d, 0x9f, 0x03, 0xe2, 0x75, 0x60, 0x18, 0x10, 0xa2, 0xa1, 0xc0, 0xad, 0xe2, 0xad, 0xd1, 0x27, 0x7f, 0x45, 0xdf, 0xa6, 0x9c, 0xb7, 0x9b, 0x62, 0xc7, 0x9c, 0x78, 0xc0, 0x5a, 0x63, 0x7b, 0xda, 0x57, 0x89, 0x32, 0x4c, 0x10, 0x25, 0x38, 0xa8, 0x0a, 0x45, 0x37, 0x3e, 0x10, 0x73, 0xe5, 0x12, 0x65, 0x12, 0x21, 0x9f, 0x1a, 0x74, 0x03, 0x8c, 0xf7, 0x6e, 0xdd, 0x14, 0x32, 0x58, 0xea, 0x80, 0xe0, 0xa7, 0xa1, 0xb5, 0xa8, 0x16, 0xab, 0x62, 0x6f, 0x7d, 0xf1, 0xf2, 0x8f, 0xb0, 0x9d, 0xd6, 0x32, 0x31, 0x15, 0x2e, 0xfe, 0xec, 0xcd, 0xb8, 0x5c, 0xe6, 0x9e, 0x64, 0x04, 0x29, 0xe8, 0xe2, 0xcb, 0x48, 0x11, 0x02, 0x68, 0x56, 0xce, 0xad, 0xf6, 0x5d, 0xd3, 0x90, 0x65, 0x32, 0x75, 0x4d, 0x85, 0xce, 0x15, 0x47, 0x77, 0x90, 0x00, 0xbc, 0x08, 0x38, 0x30, 0xb3, 0x71, 0x49, 0x61, 0xcd, 0x1f, 0xea, 0x12, 0xbe, 0x87, 0x77, 0x32, 0x4c, 0x31, 0xe6, 0xc8, 0x7e, 0x22, 0x37, 0x9b, 0x44, 0x2f, 0xb9, 0x73, 0x46, 0x7a, 0x40, 0x24, 0x07, 0x54, 0x0c, 0xc2, 0x31, 0x9d, 0xa4, 0x2b, 0xc5, 0x7f, 0x4f, 0x6d, 0x23, 0x8a, 0xf9, 0x3e, 0xc0, 0x71, 0xab, 0x32, 0xa9, 0xb9, 0x99, 0x40, 0xbd, 0x06, 0x7b, 0xa4, 0xf6, 0x92, 0xec, 0xab, 0x51, 0xec, 0x46, 0x79, 0x6e, 0x40, 0xbf, 0x69, 0x33, 0xad, 0xe6, 0x37, 0x2b, 0x2d, 0xf9, 0xf5, 0x8b, 0x03, 0xeb, 0x72, 0x80, 0x15, 0xb2, 0x0e, 0xb7, 0x60, 0x51, 0xad, 0xdf, 0x6b, 0x5f, 0xf2, 0x2f, 0xe9, 0x48, 0x86, 0x17, 0xe9, 0x21, 0x9d, 0x00, 0x9c, 0x72, 0x14, 0xa3, 0x6c, 0x08, 0xdb, 0x78, 0x3d, 0x3c, 0xce, 0x60, 0x55, 0x5c, 0x12, 0x17, 0x09, 0x7e, 0xaf, 0x0e, 0x5c, 0x2e, 0xc0, 0x5d, 0xf7, 0xec, 0xb1, 0xa7, 0x84, 0xa7, 0x7c, 0x78, 0x52, 0x9c, 0x75, 0xf6, 0x8d, 0x3b, 0x65, 0x18, 0xc5, 0x06, 0x15, 0x95, 0xdb, 0x35, 0x36, 0x16, 0xc4, 0xd3, 0x78, 0xe9, 0x6c, 0x2c, 0x9a, 0x01, 0x90, 0x80, 0x8c, 0xd4, 0x76, 0xf7, 0x19, 0x84, 0x08, 0xfa, 0x62, 0x6d, 0x97, 0xce, 0x60, 0xd9, 0xdf, 0x2b, 0xb5, 0x72, 0xb0, 0x85, 0x69, 0x76, 0x50, 0x08, 0x84, 0xd2, 0xf2, 0xf1, 0xe0, 0x5e, 0x42, 0x97, 0xac, 0x03, 0x76, 0x9a, 0x1a, 0x88, 0xaa, 0x3a, 0x51, 0xb8, 0x49, 0xa0, 0x0c, 0xf4, 0xd2, 0xca, 0x43, 0x7c, 0xa2, 0xf5, 0xb2, 0x2d, 0x78, 0x19, 0x31, 0x7c, 0xe7, 0x4f, 0xdd, 0x67, 0x57, 0x7c, 0x8e, 0x4b, 0x00, 0x54, 0x17, 0xa0, 0xe5, 0xfc, 0x39, 0x9c, 0x37, 0x91, 0x4e, 0xae, 0xe3, 0xb3, 0x78, 0xa4, 0xcd, 0xc6, 0x7d, 0xe5, 0xa9, 0x63, 0x5e, 0xfd, 0x77, 0x78, 0x98, 0x81, 0x53, 0x5e, 0x25, 0x53, 0x79, 0x9b, 0x21, 0x74, 0xc7, 0x66, 0x63, 0x2c, 0x7c, 0x1e, 0x75, 0x3e, 0x86, 0x98, 0x6b, 0xf1, 0xaa, 0xe6, 0x6f, 0xea, 0x62, 0x84, 0xa4, 0xc1, 0x6e, 0x42, 0x93, 0x06, 0x18, 0x4c, 0xdf, 0x9a, 0xd8, 0x8e, 0x03, 0x08, 0xdb }; +constexpr AccessUnit M2V_SEQUENCE_END_SPLIT_EXPECTED_AU = { 0x15f90, 0x159b2, true, 0, {}, { 0x6f, 0x00, 0x25, 0xed, 0x88, 0xfb, 0x17, 0x95, 0x83, 0x1c, 0xb6, 0x9b, 0xbc, 0x41, 0xd8, 0x1f, 0xf1, 0xb0, 0xd5, 0xa3 } }; + + +constexpr std::array AVC_MULTIPLE_PACK_STREAM = { 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xe0, 0x06, 0xe6, 0x81, 0xc1, 0x0d, 0x31, 0x00, 0x05, 0xbf, 0x21, 0x11, 0x00, 0x05, 0xb3, 0x65, 0x1e, 0x69, 0xb2, 0x00, 0x00, 0x00, 0x01, 0x09, 0x9a, 0xc4, 0xa0, 0x2d, 0x49, 0x55, 0xcd, 0xbe, 0x15, 0xf7, 0x93, 0xa4, 0xa7, 0x61, 0x41, 0x82, 0xa8, 0x30, 0xe6, 0xd2, 0x14, 0xe8, 0xa4, 0xa4, 0xdd, 0xf1, 0x6b, 0x6a, 0x44, 0x31, 0xfe, 0x64, 0x2c, 0x95, 0x3a, 0x7a, 0x71, 0x21, 0xc7, 0x11, 0x98, 0x91, 0x63, 0x6d, 0x79, 0xec, 0x89, 0x63, 0x3d, 0xe8, 0x95, 0x7e, 0x4e, 0xfc, 0xe3, 0x7e, 0x8b, 0xd8, 0xe7, 0xe8, 0xaa, 0x15, 0x68, 0x28, 0x35, 0x8e, 0x0a, 0x1c, 0xc3, 0x99, 0xeb, 0x1a, 0x76, 0xae, 0x86, 0x8a, 0x33, 0xb3, 0x11, 0xd7, 0x96, 0x2b, 0x32, 0xaf, 0x6b, 0x07, 0xb0, 0x9d, 0x53, 0xb0, 0x5a, 0x87, 0x2f, 0xe8, 0xa0, 0x30, 0xc2, 0x06, 0x69, 0xfa, 0x07, 0x49, 0xf5, 0x6f, 0xca, 0x0a, 0x3d, 0xcc, 0x72, 0x79, 0x9f, 0x66, 0x1f, 0x8f, 0x75, 0x24, 0x79, 0x2a, 0x43, 0x38, 0x07, 0xd4, 0x6e, 0xcc, 0x2b, 0xf1, 0x81, 0xff, 0x73, 0x99, 0x1e, 0x1a, 0x74, 0xfe, 0xc7, 0xad, 0x01, 0x10, 0x40, 0xb7, 0x48, 0x48, 0x1f, 0x00, 0xd3, 0x02, 0xec, 0x3c, 0x60, 0x1e, 0xf0, 0x4f, 0xa3, 0x97, 0xfb, 0x45, 0x49, 0xc8, 0x4a, 0x6a, 0x9b, 0x6f, 0xbc, 0x82, 0xda, 0x6b, 0xfb, 0x40, 0x5b, 0x04, 0x02, 0x6e, 0x19, 0x1d, 0xc7, 0x90, 0x68, 0xa9, 0xde, 0xae, 0x17, 0xf8, 0xed, 0x64, 0x2c, 0xef, 0x7e, 0x4c, 0x83, 0x1f, 0x28, 0xe9, 0x60, 0x09, 0x80, 0xa4, 0x22, 0x38, 0xd6, 0x0c, 0x2b, 0xb0, 0xc8, 0x46, 0x51, 0x0c, 0x56, 0xe9, 0xc3, 0x94, 0x66, 0x35, 0xc0, 0x13, 0x26, 0xda, 0x02, 0x45, 0x07, 0x89, 0x11, 0xcf, 0xdc, 0x4d, 0x31, 0x95, 0x29, 0xbf, 0x31, 0xe1, 0xfc, 0x44, 0x90, 0x1d, 0x56, 0xbe, 0x33, 0x75, 0x9a, 0xc8, 0xc9, 0xe4, 0xb6, 0x74, 0x89, 0x25, 0xd8, 0x55, 0xa2, 0xa4, 0x66, 0xd2, 0x09, 0xbd, 0x88, 0xfa, 0x89, 0x8a, 0x38, 0x8c, 0x20, 0x8c, 0xd2, 0x32, 0xf5, 0x99, 0x26, 0xb9, 0x90, 0x12, 0xe2, 0x40, 0xd9, 0xce, 0xda, 0x39, 0x8d, 0xb7, 0x14, 0xe3, 0x0b, 0x7f, 0xf7, 0x3f, 0xf7, 0x5c, 0x9a, 0xd2, 0xd6, 0x79, 0xe2, 0xc7, 0x5a, 0xd9, 0x8b, 0xd7, 0x37, 0x63, 0x27, 0x5e, 0x8f, 0x41, 0xc5, 0xff, 0x24, 0x28, 0xcc, 0x27, 0x88, 0xc2, 0x87, 0xd0, 0xf2, 0xd6, 0x21, 0x0e, 0x91, 0x3a, 0x40, 0xc5, 0x3c, 0x44, 0x63, 0x6c, 0xa1, 0x20, 0x13, 0x86, 0x86, 0x03, 0x72, 0x91, 0x37, 0x08, 0x35, 0xfb, 0xb8, 0xf0, 0xdb, 0x23, 0x69, 0x33, 0xe0, 0xde, 0x3d, 0x5b, 0x20, 0xc2, 0xf6, 0x35, 0x0f, 0x32, 0xc9, 0x98, 0xdc, 0x7e, 0xf8, 0xd8, 0x7a, 0xd1, 0x54, 0x34, 0xa2, 0x10, 0x0c, 0xf6, 0x2d, 0xab, 0x24, 0x95, 0x50, 0xbf, 0xd9, 0xb4, 0x42, 0xc3, 0x55, 0xb0, 0x97, 0xec, 0x74, 0x72, 0x6e, 0x61, 0xf6, 0x03, 0x97, 0x47, 0x51, 0xf1, 0x64, 0xb2, 0x90, 0x05, 0xa4, 0x6f, 0xda, 0xeb, 0xf8, 0xa2, 0x77, 0x02, 0x5b, 0xb9, 0xbc, 0xe7, 0x5b, 0xfd, 0x34, 0xb5, 0xf4, 0x8c, 0xd1, 0xe0, 0xa0, 0xd6, 0x06, 0xa8, 0x44, 0x85, 0x8c, 0xfb, 0x9b, 0x73, 0x87, 0xfa, 0x25, 0xeb, 0x17, 0x0c, 0xf3, 0x41, 0xe4, 0x2c, 0xe8, 0xfb, 0x7d, 0x6b, 0x1a, 0x16, 0xe4, 0x5c, 0x20, 0xf6, 0x80, 0x2d, 0x4f, 0x19, 0x61, 0x98, 0x48, 0x22, 0xc2, 0x32, 0xfc, 0xb8, 0x96, 0x92, 0xa1, 0xcd, 0x1d, 0x71, 0x2e, 0xb5, 0x2d, 0xe9, 0xe4, 0xc3, 0x0b, 0x5b, 0xe9, 0xee, 0x85, 0xb2, 0xaf, 0x8d, 0x25, 0xe0, 0x43, 0xb0, 0x1d, 0x82, 0x78, 0xa4, 0xd0, 0x66, 0x61, 0x96, 0x2f, 0xd6, 0x3d, 0x10, 0xe6, 0xda, 0xab, 0xcf, 0xa5, 0x59, 0x95, 0x07, 0x88, 0x7d, 0xae, 0xd7, 0x1d, 0x64, 0x76, 0xdc, 0x60, 0x8e, 0x38, 0x4f, 0xe6, 0x6d, 0xb5, 0xc2, 0x72, 0xd1, 0xe1, 0xa0, 0x84, 0x1f, 0x98, 0x9b, 0x11, 0x31, 0xd3, 0x93, 0x0f, 0x23, 0xff, 0xa8, 0xb0, 0x2b, 0x90, 0xe0, 0x60, 0x40, 0xeb, 0x0c, 0x98, 0xd5, 0x98, 0xe6, 0x3a, 0x42, 0x95, 0xb3, 0x76, 0x90, 0x4c, 0x4a, 0x8d, 0x46, 0x42, 0x0e, 0x39, 0x4c, 0x54, 0x52, 0xa6, 0x2b, 0x87, 0x72, 0x6f, 0xee, 0x41, 0xaf, 0xe0, 0xc3, 0xfe, 0x0d, 0xd1, 0xa2, 0xd4, 0xc6, 0x9d, 0xa9, 0x89, 0x78, 0xcd, 0x8a, 0x33, 0x50, 0x89, 0xe7, 0x4c, 0x85, 0x7a, 0xc2, 0x91, 0x0b, 0x88, 0xd2, 0xe0, 0x0d, 0xfe, 0x21, 0x82, 0x81, 0xc7, 0x4c, 0xfc, 0x00, 0xcb, 0x86, 0x03, 0x38, 0xa5, 0xa4, 0xcf, 0xb0, 0xbd, 0x77, 0x38, 0x4a, 0xd5, 0x92, 0x45, 0x07, 0x96, 0x23, 0xe7, 0x3e, 0x43, 0x50, 0x48, 0xe6, 0x1d, 0x3f, 0x79, 0x67, 0x61, 0xe1, 0xae, 0x5f, 0x57, 0xe4, 0xbd, 0x79, 0x67, 0x0d, 0x11, 0x81, 0xb9, 0xa5, 0xc5, 0xb8, 0x11, 0x0c, 0x02, 0x78, 0x0f, 0x93, 0x51, 0xd6, 0x6a, 0x07, 0xd8, 0xcd, 0x50, 0x60, 0xf6, 0x59, 0x97, 0x0f, 0x25, 0xb6, 0xc7, 0x1f, 0x94, 0xbb, 0xd4, 0xe0, 0x05, 0x44, 0x88, 0x03, 0x44, 0xa4, 0x93, 0x07, 0x80, 0x23, 0x7c, 0x3f, 0xf7, 0xf9, 0x7a, 0x60, 0x39, 0xf6, 0x37, 0xbc, 0x67, 0x56, 0xa1, 0x58, 0x79, 0xd8, 0xb6, 0x05, 0x53, 0xb4, 0xa1, 0x77, 0x57, 0x94, 0xb0, 0xfd, 0xbc, 0xaf, 0x25, 0x52, 0x2c, 0x73, 0xcb, 0x4a, 0x87, 0xcd, 0xda, 0xb4, 0x51, 0x57, 0xaa, 0x1e, 0xc9, 0x2d, 0x6c, 0x51, 0x9d, 0xc6, 0x67, 0x7a, 0x82, 0x76, 0xf2, 0x8b, 0xef, 0xc4, 0xd9, 0xad, 0x96, 0xc4, 0x1c, 0x78, 0x0a, 0x98, 0xb0, 0x16, 0x43, 0x1d, 0xea, 0x3a, 0xe6, 0x77, 0xe8, 0xc7, 0x86, 0x28, 0x1e, 0x24, 0xe3, 0xd4, 0xa8, 0x4a, 0x6f, 0xe1, 0xde, 0x3b, 0x38, 0xd6, 0xa4, 0x3b, 0x4f, 0xaa, 0x6e, 0xe6, 0x80, 0x00, 0xa9, 0xbd, 0xd1, 0xca, 0x35, 0x41, 0x97, 0xca, 0x94, 0x28, 0xd1, 0x0f, 0x52, 0x62, 0x29, 0x23, 0xa3, 0xfd, 0x35, 0x34, 0x57, 0xd3, 0x22, 0x69, 0xf1, 0x17, 0xf5, 0x29, 0x0d, 0xf1, 0xa7, 0xee, 0xe2, 0x2d, 0xe5, 0x19, 0x8c, 0x6b, 0xe7, 0x93, 0x3e, 0xb4, 0xb7, 0xee, 0x65, 0x70, 0x45, 0x4c, 0xd6, 0xe8, 0xe9, 0x9f, 0x33, 0x9a, 0xf8, 0xf9, 0xbd, 0x21, 0xe6, 0x3c, 0x93, 0x5f, 0xa4, 0x5e, 0x6d, 0xab, 0x26, 0xf3, 0xab, 0x07, 0x01, 0x81, 0xa7, 0xea, 0x11, 0xb1, 0x58, 0x5e, 0x49, 0xc2, 0xab, 0x1b, 0xaf, 0xba, 0xe5, 0xae, 0xb4, 0x2d, 0x98, 0x00, 0x40, 0x89, 0x76, 0x18, 0x03, 0x6f, 0x43, 0xe9, 0x48, 0x39, 0x91, 0xa3, 0x6d, 0x61, 0xe7, 0xea, 0x6a, 0xd9, 0x3d, 0x43, 0xf1, 0xd5, 0xcc, 0xb1, 0x2e, 0xe6, 0xbb, 0x10, 0xd9, 0x6a, 0xd2, 0x34, 0x4e, 0xd1, 0x83, 0xef, 0x8a, 0x26, 0x15, 0x04, 0xbf, 0x74, 0xce, 0xbb, 0x25, 0x80, 0xea, 0xc1, 0xc7, 0x25, 0xee, 0x99, 0x9a, 0x25, 0x73, 0x2c, 0xe7, 0x99, 0x33, 0xad, 0x89, 0x69, 0x9e, 0x58, 0xf5, 0x0f, 0x26, 0xba, 0x3e, 0x33, 0x06, 0x0b, 0xb7, 0x8d, 0xbd, 0xc1, 0x38, 0x04, 0x66, 0xa0, 0x94, 0xf6, 0xe2, 0x87, 0x56, 0xde, 0x3f, 0x60, 0x48, 0x1a, 0xbb, 0xc2, 0x05, 0x20, 0xc5, 0xfb, 0x27, 0xcf, 0xc8, 0x2e, 0xb9, 0x6a, 0x8b, 0x37, 0x6f, 0x1e, 0x0f, 0xa5, 0xd1, 0x34, 0xaf, 0x3b, 0xea, 0xfe, 0xc6, 0xaa, 0x76, 0x13, 0x16, 0x1b, 0xb3, 0x33, 0xd2, 0x4b, 0x1e, 0x4d, 0x9c, 0xe6, 0xa7, 0x76, 0x49, 0xe7, 0x6d, 0xf1, 0xb5, 0x9f, 0x6f, 0xbb, 0xaf, 0x49, 0x38, 0xb9, 0xdd, 0x4e, 0xb3, 0x05, 0x00, 0x7d, 0x5a, 0xb8, 0xe0, 0x5c, 0xb7, 0x61, 0xf0, 0x72, 0x7c, 0x71, 0xf8, 0x7d, 0x46, 0xf0, 0x15, 0x30, 0xd7, 0x0a, 0x19, 0x71, 0x1c, 0x68, 0x5e, 0xa9, 0xcf, 0x16, 0xbe, 0x94, 0xa5, 0x95, 0xc9, 0xd7, 0x78, 0x95, 0x29, 0x43, 0x0d, 0xb7, 0xa2, 0xce, 0x7c, 0xa3, 0x1a, 0xc6, 0x2d, 0x55, 0x6f, 0x4c, 0x2f, 0xee, 0x48, 0x20, 0x32, 0x60, 0x60, 0xa7, 0xe3, 0x1c, 0xdf, 0xad, 0x53, 0xb1, 0x88, 0x0d, 0x55, 0x25, 0xd5, 0xf2, 0xb6, 0x80, 0x37, 0xe5, 0x3a, 0x64, 0xfd, 0x02, 0xae, 0xf3, 0x57, 0xfa, 0x6c, 0xbd, 0x69, 0xa3, 0x6e, 0x32, 0x6e, 0xc2, 0x0f, 0x6e, 0x9b, 0xb9, 0x3a, 0xa6, 0x39, 0x27, 0xb4, 0xa0, 0x0f, 0xe0, 0x51, 0xdf, 0xf5, 0x8d, 0xaf, 0x35, 0xc6, 0x55, 0x86, 0x54, 0xcc, 0x28, 0xa0, 0xf8, 0xd2, 0x32, 0x03, 0x6c, 0x09, 0xd3, 0xfb, 0x3b, 0x74, 0x69, 0x44, 0x71, 0x49, 0xf8, 0x87, 0xb6, 0xd9, 0xdc, 0xfc, 0xc4, 0x7f, 0x45, 0xdc, 0x73, 0x99, 0x79, 0xf0, 0x95, 0x78, 0xce, 0x4e, 0x99, 0xc8, 0x35, 0xca, 0xea, 0xba, 0x92, 0xab, 0xe3, 0xba, 0xed, 0x4d, 0xec, 0x32, 0x99, 0x65, 0x48, 0x12, 0x24, 0x3a, 0xaa, 0xbe, 0x54, 0xf0, 0x63, 0xbb, 0x3c, 0x06, 0x38, 0x35, 0x2c, 0xbc, 0x05, 0xe6, 0x1c, 0xc6, 0xe1, 0x9f, 0x77, 0x2c, 0xfa, 0xd5, 0x8d, 0xec, 0x7e, 0x19, 0x8c, 0x7c, 0x29, 0x26, 0xb9, 0x61, 0xba, 0x7c, 0xfa, 0xc4, 0x10, 0x8f, 0x48, 0xf0, 0xed, 0x11, 0xbd, 0xd0, 0xc8, 0x46, 0x9d, 0x06, 0x67, 0xbe, 0xd5, 0x3e, 0x7c, 0xbe, 0x37, 0x7c, 0xf5, 0x4e, 0x77, 0x63, 0xb4, 0x12, 0xb9, 0x37, 0xe3, 0x8d, 0xdc, 0x2f, 0xa4, 0xb8, 0x92, 0xec, 0x06, 0xd7, 0x56, 0x77, 0x02, 0xa2, 0x55, 0xbc, 0x1b, 0x9a, 0x12, 0x05, 0x89, 0x40, 0x59, 0x27, 0x80, 0x74, 0x01, 0xb9, 0xa2, 0x12, 0xb8, 0xcb, 0xd5, 0xd5, 0xe0, 0xd6, 0x78, 0xc1, 0x23, 0x24, 0x23, 0x77, 0x84, 0x60, 0xb3, 0xe5, 0x9c, 0x35, 0x3f, 0xb1, 0x7b, 0x38, 0xe2, 0x35, 0x68, 0xbc, 0x14, 0x8b, 0x89, 0xc2, 0xae, 0x41, 0x48, 0x2e, 0x3a, 0xad, 0x28, 0x3c, 0xc2, 0x7b, 0x8c, 0x20, 0x63, 0xfe, 0x74, 0x6d, 0xf9, 0xd8, 0x57, 0xe0, 0xdb, 0x6e, 0xba, 0xd0, 0x06, 0x4a, 0x50, 0x2f, 0x05, 0x5f, 0x0f, 0x64, 0x7c, 0x6a, 0xe2, 0x10, 0x1f, 0xd7, 0x18, 0xe0, 0x40, 0xcd, 0x06, 0x2c, 0x7c, 0xe9, 0x1a, 0x7c, 0x2c, 0x93, 0x9a, 0x6a, 0x9d, 0x92, 0x26, 0xb6, 0x7e, 0xb6, 0xb7, 0xdf, 0x51, 0xc4, 0x48, 0x0d, 0x37, 0x15, 0xba, 0x02, 0x58, 0xda, 0x07, 0x64, 0x4b, 0x59, 0xf7, 0x0a, 0x1f, 0x2c, 0xe3, 0xce, 0x74, 0x3f, 0x84, 0xb8, 0xd1, 0x96, 0x4a, 0x9f, 0x93, 0x3a, 0x1d, 0x7b, 0x0b, 0x53, 0x5b, 0xc8, 0x6a, 0xc0, 0x60, 0x37, 0xa6, 0xd5, 0x5f, 0x96, 0x12, 0x08, 0xd1, 0x41, 0x3b, 0xc0, 0xde, 0x51, 0x4a, 0x0a, 0x4d, 0xdc, 0xcf, 0x3f, 0xe5, 0x58, 0x76, 0x99, 0x2d, 0x41, 0x16, 0xbf, 0xc7, 0x08, 0x11, 0x80, 0x88, 0x12, 0xd7, 0xba, 0x85, 0x2b, 0xe7, 0x55, 0x23, 0x74, 0x69, 0x62, 0xfe, 0xb4, 0x1b, 0x47, 0xe3, 0xc3, 0xac, 0x74, 0xa6, 0xcd, 0x96, 0xa9, 0x84, 0x60, 0xb6, 0x4d, 0xdc, 0xcb, 0xa1, 0x18, 0xd2, 0xce, 0xb2, 0xa6, 0x37, 0x49, 0x1e, 0x99, 0xbd, 0xdc, 0xcf, 0x69, 0xd0, 0x3f, 0x90, 0xee, 0x52, 0x33, 0x45, 0xd3, 0x9a, 0x3f, 0x64, 0x0d, 0x00, 0x0b, 0xff, 0x5d, 0xbf, 0x1b, 0x43, 0xd3, 0xf5, 0x53, 0xe8, 0x37, 0x63, 0xba, 0xad, 0x01, 0xd6, 0x01, 0x86, 0x48, 0x2d, 0xee, 0x07, 0x0d, 0x0b, 0x85, 0xb2, 0xf9, 0x7e, 0x6c, 0xb9, 0x79, 0x77, 0x1d, 0xff, 0x68, 0xfa, 0xb6, 0xad, 0x0a, 0x0f, 0x43, 0xf6, 0x65, 0x6f, 0x7d, 0x79, 0x5d, 0x70, 0x55, 0x29, 0xc7, 0x41, 0x67, 0xfb, 0x3e, 0xc5, 0xcd, 0x0f, 0x7d, 0x69, 0x5b, 0x64, 0x47, 0x5a, 0x2e, 0x6a, 0xfb, 0xe9, 0x8e, 0x66, 0x80, 0x38, 0x3d, 0x4c, 0xdd, 0x64, 0xc0, 0xfc, 0x07, 0x86, 0xae, 0x90, 0x30, 0xa9, 0x81, 0x18, 0x35, 0xd3, 0x65, 0xf6, 0x7b, 0xe8, 0x1c, 0x92, 0x4b, 0xcb, 0x7a, 0x9d, 0x96, 0x8a, 0x42, 0x2c, 0x72, 0x6f, 0x24, 0xce, 0x7f, 0x5d, 0x6b, 0xf2, 0x50, 0x6c, 0x6a, 0x8d, 0x63, 0x4b, 0x64, 0x23, 0x31, 0x21, 0x60, 0xe2, 0xdb, 0xb9, 0xe6, 0x4e, 0x8e, 0x95, 0x91, 0x59, 0xc1, 0xb3, 0x49, 0x6c, 0x81, 0x1a, 0x08, 0xc0, 0xf3, 0xf4, 0x99, 0x5a, 0x2f, 0x53, 0xfd, 0x6e, 0xf7, 0x58, 0x0e, 0x50, 0xc7, 0x1d, 0xc9, 0xe0, 0xcb, 0x49, 0x07, 0x3b, 0x70, 0xa0, 0x43, 0xc8, 0xb1, 0x88, 0xd2, 0x7d, 0x98, 0xd7, 0xf7, 0xff, 0xdd, 0xdf, 0x6d, 0x06, 0x79, 0x80, 0xcf, 0xfa, 0xa2, 0x39, 0xd0, 0xe9, 0xe1, 0xee, 0x70, 0xc9, 0xb5, 0x03, 0xd3, 0x4a, 0xec, 0x3f, 0x1c, 0xa6, 0xe5, 0x73, 0x35, 0xe7, 0x01, 0xe3, 0xea, 0xd5, 0xab, 0xc1, 0xa7, 0x3d, 0x4c, 0xbd, 0x2f, 0xce, 0x49, 0x0c, 0x48, 0x34, 0xc5, 0xd3, 0x17, 0x62, 0xeb, 0x5f, 0x3c, 0xf8, 0x33, 0x7a, 0x60, 0x71, 0x87, 0x12, 0xb2, 0x46, 0x50, 0x85, 0xad, 0x0e, 0x0b, 0xa3, 0x29, 0xa4, 0xd3, 0x9b, 0xd1, 0xcb, 0x1a, 0x00, 0x30, 0xbc, 0xaa, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xe0, 0x06, 0xe6, 0x81, 0xc1, 0x0d, 0x33, 0x91, 0x85, 0xbf, 0x29, 0x11, 0xf0, 0x05, 0xb3, 0x65, 0x1e, 0x69, 0xb2, 0x09, 0xc2, 0x61, 0x4a, 0x53, 0xd7, 0x45, 0xd1, 0xb4, 0x87, 0x33, 0x02, 0x7c, 0xce, 0x58, 0xc3, 0x62, 0x61, 0xb1, 0x48, 0x93, 0x12, 0x99, 0x43, 0x51, 0x04, 0x23, 0xaf, 0x35, 0x48, 0x29, 0xe1, 0x71, 0x0d, 0x4b, 0x12, 0x0e, 0x9a, 0xf5, 0x1a, 0x64, 0xc1, 0xa6, 0xf5, 0x7d, 0x99, 0x0a, 0x1b, 0x9f, 0xa1, 0xf5, 0xa4, 0xc1, 0xa9, 0x7b, 0xe7, 0x7f, 0xd1, 0x0a, 0x25, 0xc8, 0x04, 0x30, 0xf8, 0x89, 0x9e, 0xa9, 0x58, 0xff, 0xb0, 0x9c, 0x72, 0x25, 0x10, 0xe6, 0xb1, 0xdd, 0xf1, 0x62, 0xde, 0x8f, 0x4c, 0x36, 0x9b, 0xdd, 0xa1, 0xd2, 0x4f, 0x82, 0x65, 0xa8, 0xb6, 0xd3, 0x69, 0x30, 0x4f, 0x53, 0x17, 0xc6, 0x34, 0x6e, 0x99, 0x6c, 0xf3, 0x2d, 0x43, 0x24, 0x27, 0xc8, 0x3f, 0xda, 0x62, 0x8e, 0xa0, 0xbe, 0x8d, 0xa6, 0x4f, 0x72, 0x2b, 0x21, 0x62, 0x45, 0x69, 0x3f, 0x00, 0x97, 0xf3, 0xee, 0x7f, 0x5a, 0xb2, 0xf8, 0x99, 0x69, 0x28, 0xa0, 0x94, 0x52, 0x0b, 0x98, 0x9e, 0xb1, 0xfa, 0x6a, 0x0f, 0x22, 0x23, 0x63, 0xb5, 0xbf, 0x64, 0x05, 0xb6, 0xcc, 0x2d, 0x69, 0x99, 0x12, 0x8f, 0xa8, 0xbb, 0xc4, 0x8a, 0x61, 0xb2, 0x6b, 0x94, 0x66, 0x7f, 0x61, 0xab, 0xc5, 0xc5, 0x9b, 0x75, 0x31, 0x73, 0x58, 0xaa, 0x3b, 0x37, 0xd1, 0x28, 0xbc, 0x45, 0x3b, 0xb2, 0x75, 0x95, 0xb5, 0x42, 0xd0, 0xd6, 0xe3, 0x13, 0xbd, 0xfd, 0x69, 0xde, 0xe6, 0xb3, 0x61, 0x44, 0x93, 0xa0, 0xb0, 0x95, 0xa5, 0x90, 0x1e, 0x05, 0xcd, 0x4e, 0xf3, 0x83, 0x64, 0xd3, 0x51, 0xf6, 0x58, 0x6c, 0x12, 0x2d, 0xe5, 0x3c, 0x79, 0x60, 0xf8, 0x5c, 0xab, 0x41, 0x47, 0x3d, 0xb7, 0xb5, 0x65, 0xd0, 0xd8, 0x23, 0xf4, 0xb5, 0xcd, 0x2e, 0xbb, 0x5b, 0x73, 0xf7, 0xdd, 0xa9, 0x1d, 0xe1, 0xea, 0x9c, 0x43, 0xef, 0x86, 0x05, 0x7d, 0x0a, 0x8a, 0x82, 0xc0, 0xc4, 0x27, 0xc2, 0xa9, 0xc8, 0x8e, 0x0a, 0xeb, 0x42, 0xd9, 0x83, 0x7c, 0xd5, 0x95, 0x71, 0x9c, 0x61, 0x5e, 0xb7, 0x22, 0xe6, 0xa7, 0xa9, 0x7c, 0x18, 0x29, 0x7c, 0x10, 0xcd, 0x6d, 0x2e, 0xfc, 0xc6, 0x3e, 0xc1, 0xfe, 0x32, 0x60, 0x1f, 0xa5, 0xfa, 0x01, 0x29, 0xf1, 0x25, 0xa2, 0xad, 0x80, 0xc4, 0xfe, 0x2d, 0xf8, 0x94, 0x43, 0x01, 0xe3, 0xe9, 0x8e, 0x4f, 0x57, 0xfa, 0xca, 0xc5, 0xb2, 0x4d, 0xb5, 0x36, 0xf6, 0xda, 0x5a, 0xaa, 0x5f, 0xd5, 0xff, 0x1e, 0xc0, 0x7f, 0xea, 0x36, 0xfe, 0xc8, 0xdf, 0x83, 0x83, 0xa2, 0xca, 0xb8, 0xcd, 0x36, 0x78, 0x24, 0xbd, 0xb6, 0x58, 0x66, 0x0a, 0x3e, 0x08, 0x5a, 0x18, 0x73, 0x18, 0xaf, 0x11, 0x4d, 0x3e, 0xd8, 0x29, 0xd1, 0x48, 0x11, 0xad, 0x36, 0x98, 0x8a, 0xe5, 0xb4, 0xcd, 0x53, 0x56, 0xd2, 0xfc, 0x89, 0x00, 0x14, 0x8e, 0x2c, 0xde, 0xbc, 0x05, 0x97, 0x72, 0xe2, 0xad, 0x40, 0xae, 0x8f, 0x3d, 0x7f, 0xb6, 0x4a, 0x55, 0x55, 0x03, 0x8a, 0xa3, 0x08, 0x0b, 0xbd, 0xcb, 0x76, 0x0a, 0xf8, 0x6d, 0x3d, 0x32, 0xb2, 0xe5, 0x50, 0xa4, 0x3c, 0x2d, 0xdf, 0x42, 0x70, 0x9f, 0x64, 0xdb, 0x5c, 0x8e, 0xd9, 0xfe, 0x48, 0xd5, 0x43, 0x3e, 0x97, 0x25, 0x52, 0x0a, 0xef, 0x60, 0x38, 0xba, 0x6c, 0x51, 0xed, 0xbc, 0xbc, 0x8b, 0xe9, 0x59, 0x8f, 0xe7, 0xdf, 0xa2, 0x18, 0xcb, 0x11, 0x0e, 0x90, 0x6d, 0x30, 0xcd, 0x24, 0xff, 0x62, 0x62, 0x2c, 0x0d, 0x9c, 0x9a, 0x12, 0x65, 0x37, 0x2c, 0xdf, 0x64, 0x76, 0xf6, 0x60, 0x8d, 0x9a, 0x2d, 0xdd, 0x94, 0xec, 0xee, 0x87, 0x9c, 0x01, 0xcc, 0x34, 0x68, 0x6d, 0xe6, 0xb6, 0x42, 0x33, 0x3c, 0xef, 0x7a, 0x0f, 0xb7, 0xbf, 0x69, 0x7e, 0x72, 0x71, 0x74, 0xd8, 0xc1, 0xd8, 0x1a, 0x7a, 0x9f, 0x4d, 0x47, 0xd7, 0x63, 0x00, 0x0d, 0xdb, 0x1b, 0x20, 0x06, 0x91, 0x0a, 0xf1, 0x20, 0x8c, 0x96, 0x1c, 0x13, 0x7b, 0xd2, 0x3d, 0x0f, 0x01, 0x27, 0x60, 0xbc, 0xd6, 0xa7, 0x8d, 0x7c, 0x05, 0x30, 0x92, 0x35, 0xfc, 0xa8, 0x06, 0x52, 0x2b, 0xda, 0xd4, 0x2c, 0x42, 0x4a, 0xb3, 0x0d, 0x6d, 0x66, 0xec, 0x28, 0xb6, 0x8f, 0xc7, 0x0b, 0xcd, 0x9d, 0xae, 0xcb, 0xad, 0xd8, 0x9d, 0xec, 0x08, 0x4e, 0xab, 0x25, 0x09, 0x3a, 0xd8, 0xc7, 0x01, 0x49, 0x5e, 0xa9, 0x83, 0x65, 0x34, 0x87, 0x67, 0x38, 0x1e, 0x40, 0x91, 0xf2, 0x54, 0x18, 0x92, 0xa7, 0x17, 0xf3, 0x6c, 0xa1, 0x8a, 0x28, 0xe0, 0x56, 0xb3, 0xbf, 0x6c, 0xe2, 0xb7, 0xb8, 0xa3, 0x72, 0x6c, 0x3c, 0x81, 0x16, 0xdc, 0x7b, 0xd3, 0xa7, 0xfa, 0xb3, 0x0b, 0x24, 0xfa, 0x4c, 0xdb, 0xa2, 0x14, 0xd1, 0xb1, 0xab, 0x68, 0x20, 0x2e, 0x7b, 0xc2, 0x9d, 0x85, 0x12, 0xf6, 0xc8, 0x09, 0xf0, 0xec, 0x10, 0x0a, 0x69, 0x97, 0x11, 0x55, 0x19, 0xad, 0x3b, 0x93, 0xb5, 0xf1, 0x75, 0x2e, 0x7c, 0x16, 0xc6, 0xd4, 0xfc, 0xff, 0xc6, 0x8b, 0x7a, 0x38, 0x5a, 0x6c, 0x8b, 0xe7, 0x61, 0x15, 0x6e, 0x70, 0xd1, 0x44, 0xa3, 0x39, 0xae, 0x09, 0xe2, 0x52, 0x1c, 0xbb, 0xa0, 0xcc, 0x55, 0x3b, 0x4c, 0x11, 0x9e, 0x2f, 0x59, 0x9a, 0x57, 0x72, 0xce, 0xf7, 0xcd, 0x50, 0x37, 0x5d, 0xea, 0x83, 0xfd, 0x67, 0x7e, 0x64, 0x8b, 0x7e, 0x88, 0xd2, 0x31, 0xf3, 0xae, 0xcd, 0xfd, 0x65, 0x6a, 0x07, 0x92, 0x63, 0xc2, 0xaf, 0x4e, 0x8a, 0x54, 0x87, 0x77, 0xb9, 0x0e, 0x8c, 0x21, 0x16, 0x5f, 0xa7, 0xf2, 0xd6, 0x50, 0xfa, 0xe0, 0x5d, 0x3e, 0x63, 0x9c, 0x67, 0x0b, 0xde, 0x91, 0xe6, 0xe1, 0x09, 0x87, 0x4f, 0xcb, 0xf2, 0xa8, 0x24, 0xa7, 0x92, 0xc5, 0x1b, 0xec, 0x44, 0x74, 0xf4, 0xe7, 0x53, 0xaf, 0x6d, 0xc2, 0x46, 0x38, 0xd5, 0x6f, 0x9e, 0x93, 0x7f, 0x46, 0xfb, 0x41, 0x3f, 0x83, 0x74, 0x7b, 0xbb, 0x39, 0xe3, 0x2d, 0x5d, 0x85, 0x7c, 0xb3, 0xce, 0xdb, 0xa6, 0x39, 0x5d, 0xea, 0xd2, 0xe2, 0x9d, 0x4e, 0xfa, 0x70, 0xcc, 0x77, 0x37, 0xf0, 0x58, 0xa9, 0xef, 0x56, 0x12, 0x59, 0xd9, 0x4a, 0xbf, 0xba, 0xa5, 0x30, 0x15, 0xa3, 0xa1, 0x85, 0x4a, 0x7b, 0xf4, 0x5f, 0x84, 0x92, 0x54, 0xce, 0x4a, 0x68, 0x9c, 0x9c, 0x6d, 0x0a, 0x95, 0x9a, 0xfc, 0xe6, 0x1c, 0xa4, 0x6f, 0x2c, 0x8e, 0x5a, 0xd8, 0x4b, 0x3c, 0xbc, 0x62, 0x6b, 0x18, 0x5a, 0x1e, 0x3d, 0xb6, 0xac, 0x29, 0x69, 0x22, 0xda, 0xca, 0xd6, 0xdf, 0x48, 0x36, 0xeb, 0x7f, 0x15, 0x98, 0xb1, 0xcd, 0x92, 0xce, 0x14, 0x32, 0x93, 0x5c, 0x44, 0xe9, 0x17, 0x05, 0x22, 0xb0, 0xc6, 0x16, 0xf2, 0x22, 0x9c, 0x80, 0x48, 0xbf, 0x29, 0x98, 0x48, 0x85, 0xa8, 0xdd, 0xc2, 0x40, 0x22, 0x3f, 0x5c, 0xde, 0x52, 0x7e, 0xf1, 0xf2, 0x8b, 0xbe, 0xfe, 0x6f, 0xfa, 0xb0, 0xa2, 0x42, 0x22, 0xc4, 0x0b, 0x87, 0xdd, 0xc8, 0x69, 0x0c, 0x92, 0xaa, 0x37, 0xe6, 0x59, 0xe9, 0x8d, 0xa9, 0xed, 0xeb, 0xb8, 0xb8, 0x80, 0x33, 0xa7, 0xf5, 0xde, 0x33, 0xd2, 0xfc, 0x1c, 0x00, 0x6c, 0x18, 0x82, 0xb5, 0xc8, 0x11, 0x65, 0xfe, 0x7c, 0x9a, 0x0d, 0x43, 0xba, 0x16, 0x5c, 0xb1, 0xa0, 0xf6, 0xec, 0x4f, 0x24, 0x56, 0xfb, 0x70, 0x01, 0x21, 0x42, 0xd0, 0x5f, 0xbb, 0xbc, 0x8d, 0xad, 0x5c, 0x83, 0x70, 0x58, 0x23, 0xb5, 0x91, 0xa7, 0x1a, 0x1d, 0xc6, 0x00, 0x25, 0xd3, 0x7a, 0x7b, 0xc3, 0xbf, 0xbd, 0x57, 0xe6, 0xab, 0xf9, 0x91, 0x4d, 0xb4, 0x91, 0x92, 0x64, 0x2e, 0x02, 0xd8, 0x6e, 0x37, 0x6b, 0x19, 0x8d, 0xbb, 0xf1, 0x8e, 0xfe, 0x58, 0xd7, 0xe7, 0xac, 0x33, 0x46, 0x01, 0xd5, 0x15, 0x51, 0x7a, 0xae, 0x07, 0x9f, 0x6e, 0xca, 0x22, 0x94, 0x87, 0xfd, 0xc9, 0xad, 0x13, 0x85, 0xd5, 0xca, 0x97, 0xcc, 0x0a, 0x07, 0x7b, 0x33, 0xd1, 0x7a, 0x5e, 0x0d, 0xff, 0xa6, 0x44, 0xfe, 0x20, 0xbf, 0xfa, 0x7e, 0xc7, 0x46, 0x0d, 0x15, 0x5c, 0xaa, 0xaa, 0xe2, 0x41, 0x9f, 0x42, 0x03, 0xfe, 0x60, 0x79, 0xdf, 0x5e, 0xdf, 0x60, 0x94, 0xa1, 0x01, 0x8a, 0xf7, 0xc3, 0xf4, 0x02, 0x8a, 0xf0, 0xb4, 0x27, 0xf4, 0x19, 0x45, 0x00, 0x71, 0xe4, 0x44, 0xd0, 0xd3, 0xec, 0x39, 0x0c, 0xa7, 0xe7, 0xf7, 0x5a, 0xeb, 0x43, 0xfb, 0x2c, 0x4f, 0x38, 0xe7, 0x0f, 0xd6, 0x08, 0x44, 0x2e, 0xd2, 0x88, 0xcb, 0xa6, 0x0f, 0x28, 0x84, 0xf0, 0x78, 0xee, 0x5a, 0x60, 0xea, 0x49, 0x3a, 0x09, 0xff, 0xf0, 0x25, 0xbf, 0x50, 0x62, 0xcf, 0x4e, 0x43, 0x5b, 0xd7, 0xbb, 0x44, 0xe5, 0x3d, 0x1e, 0xf5, 0x88, 0x38, 0xe0, 0x3f, 0xe2, 0x07, 0xaa, 0x8a, 0x42, 0x40, 0x1a, 0x9e, 0x32, 0x14, 0x37, 0x40, 0x1a, 0x7b, 0xe1, 0x6b, 0x07, 0x63, 0xb0, 0xbb, 0x92, 0x6c, 0x94, 0xe4, 0x13, 0x88, 0x4d, 0x5e, 0x00, 0xbf, 0xb4, 0xc3, 0xc2, 0x10, 0xdd, 0x2f, 0x1c, 0xdf, 0xc8, 0xdb, 0xab, 0x61, 0xa7, 0x6a, 0x67, 0x19, 0x4f, 0xa2, 0xfc, 0x3e, 0x11, 0xa0, 0xf4, 0x83, 0x58, 0xb8, 0x88, 0x29, 0xe4, 0xc4, 0x7c, 0x85, 0x74, 0x26, 0xb8, 0x76, 0xe4, 0xce, 0xcc, 0x19, 0xf6, 0xaa, 0x64, 0x4e, 0xfa, 0xe0, 0x2f, 0xa1, 0xca, 0x5b, 0x67, 0x92, 0x76, 0x15, 0x2b, 0x03, 0x8e, 0x97, 0x8c, 0x4c, 0xb0, 0x4b, 0xc0, 0x99, 0xc1, 0xf8, 0xa3, 0x0c, 0xa9, 0xfe, 0x96, 0x9f, 0x09, 0xfd, 0xe9, 0xa2, 0x2b, 0x7e, 0xe2, 0xe2, 0xb8, 0x21, 0xb6, 0x35, 0xde, 0x72, 0xdf, 0xbb, 0x2b, 0xdc, 0x90, 0xee, 0x66, 0x64, 0xe6, 0xd4, 0x2b, 0x93, 0xf3, 0xb9, 0xc7, 0xd9, 0x77, 0xdf, 0x47, 0x21, 0xbe, 0x53, 0x9d, 0xe9, 0xc9, 0x69, 0xcd, 0xa0, 0x7b, 0x4b, 0xd6, 0x00, 0x2b, 0x80, 0x50, 0x4c, 0x38, 0x03, 0x77, 0xac, 0xa1, 0x43, 0xcb, 0xb7, 0xdb, 0x12, 0x23, 0x45, 0x14, 0x8c, 0x36, 0x60, 0x84, 0xbd, 0x5e, 0x53, 0xa4, 0x94, 0xbc, 0x40, 0x0f, 0x9c, 0x3e, 0x4a, 0x8b, 0x98, 0xb4, 0xc7, 0xe6, 0xc9, 0xbf, 0x45, 0x42, 0x3c, 0xf8, 0xea, 0x54, 0x8c, 0xdf, 0x3f, 0x75, 0x39, 0x82, 0xd8, 0xc4, 0x72, 0x40, 0x8a, 0xd8, 0x5b, 0x8c, 0x27, 0x2a, 0x37, 0xdc, 0x17, 0xec, 0x1e, 0xff, 0x15, 0x98, 0xeb, 0xf9, 0xd0, 0x46, 0x38, 0x5a, 0x58, 0xb9, 0x0a, 0xba, 0xb1, 0x56, 0x10, 0x3d, 0xcb, 0x25, 0x13, 0x02, 0x8b, 0x50, 0x5e, 0xb4, 0x93, 0x14, 0xd9, 0x2e, 0x4c, 0x35, 0xf0, 0xa2, 0xf0, 0xf9, 0xbc, 0x17, 0xe2, 0x53, 0xb1, 0x56, 0xe4, 0x7c, 0x87, 0x06, 0xbe, 0xe2, 0xdd, 0x08, 0x17, 0xbe, 0x04, 0xdb, 0xb5, 0x30, 0x0c, 0xdf, 0x2d, 0x18, 0x5f, 0x85, 0x3d, 0x99, 0xe2, 0xe4, 0xd0, 0xe5, 0x38, 0x04, 0x56, 0x01, 0xc3, 0x05, 0xdc, 0x68, 0xc1, 0xf3, 0x39, 0x67, 0x60, 0xea, 0x94, 0x8f, 0xd8, 0xd7, 0xa6, 0x23, 0x45, 0x80, 0x5f, 0xc9, 0x97, 0x57, 0xf0, 0x92, 0xb7, 0x4b, 0xa3, 0x05, 0x84, 0x06, 0x15, 0xcd, 0x2a, 0xc9, 0xf8, 0xd6, 0x15, 0x37, 0xcd, 0x74, 0xc0, 0x63, 0x4b, 0xf2, 0xa3, 0x10, 0x64, 0x0f, 0xf9, 0xdb, 0xb6, 0xe6, 0x54, 0x1e, 0xde, 0x01, 0x94, 0x81, 0x26, 0x45, 0xb8, 0x5b, 0x93, 0x7a, 0x3b, 0xea, 0xf4, 0x98, 0x48, 0x09, 0x15, 0xc0, 0x16, 0x4a, 0xba, 0x19, 0x91, 0x6e, 0xe5, 0xcf, 0x02, 0xbb, 0xe5, 0xa2, 0x84, 0x3a, 0xc8, 0x25, 0x0d, 0x11, 0x25, 0x21, 0x76, 0x02, 0x5a, 0xa6, 0x8a, 0xb5, 0x7e, 0xd5, 0xda, 0x00, 0x61, 0xb3, 0x30, 0x4d, 0x48, 0x53, 0x78, 0xf3, 0x0c, 0x6d, 0xd0, 0x81, 0xf9, 0x89, 0x04, 0x1a, 0x9e, 0xac, 0xb7, 0x3e, 0x7f, 0x95, 0x92, 0x67, 0xb4, 0x63, 0x66, 0xe6, 0x9d, 0x34, 0x98, 0xa4, 0x17, 0xdc, 0xc9, 0xbc, 0x47, 0xc9, 0xf4, 0xa6, 0xa5, 0x9e, 0x9f, 0x18, 0x91, 0xe5, 0xc8, 0xf2, 0x76, 0x88, 0xc4, 0xec, 0x10, 0x06, 0x0a, 0x70, 0x58, 0xed, 0x9a, 0xa8, 0x68, 0x57, 0xfb, 0xf6, 0x2d, 0x1c, 0x78, 0xb3, 0xdd, 0x3f, 0x26, 0xc2, 0x5b, 0x88, 0xb1, 0x3b, 0x55, 0x26, 0x2b, 0x74, 0xba, 0xc3, 0x4c, 0xa0, 0xec, 0x25, 0x85, 0x18, 0x18, 0xd5, 0x50, 0xd5, 0xb4, 0x46, 0x77, 0x3e, 0x01, 0x6b, 0x56, 0xe6, 0xb0, 0x83, 0x8e, 0x5b, 0x36, 0x82, 0x4b, 0xe9, 0x6a, 0x5a, 0x40, 0xe1, 0xd2, 0xe5, 0xb9, 0x27, 0xc3, 0xce, 0x67, 0x86, 0x46, 0x25, 0xa7, 0x53, 0x1b, 0x63, 0x92, 0x9c, 0x5a, 0xd9, 0x82, 0x4b, 0x4f, 0x71, 0x90, 0x7b, 0xf4, 0x6b, 0x7d, 0x13, 0x6a, 0xe6, 0xb7, 0x5c, 0x11, 0x9e, 0x2e, 0x1c, 0x17, 0x7f, 0x6f, 0x90, 0x4f, 0x20, 0xc7, 0xe0, 0x75, 0x68, 0x40, 0x59, 0xa0, 0x8e, 0xea, 0x91, 0xb6, 0xc2, 0x8e, 0xfa, 0xb2, 0x16, 0xe8, 0xe2, 0x02, 0xdb, 0xac, 0x7c, 0x0b, 0x9d, 0xa2, 0x4a, 0x89, 0xc2, 0xeb, 0x00, 0x00, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xe0, 0x06, 0xe6, 0x81, 0xc1, 0x0d, 0x31, 0x00, 0x05, 0xbf, 0x21, 0x11, 0x00, 0x05, 0xb3, 0x65, 0x1e, 0x69, 0xb2, 0x01, 0x09, 0x2d, 0x0f, 0xf6, 0x4d, 0x95, 0x3e, 0x3a, 0x22, 0xe0, 0x6b, 0xf4, 0xc7, 0x1f, 0x61, 0x19, 0x68, 0x7d, 0xa1, 0x25, 0xe0, 0x51, 0xca, 0x80, 0x6f, 0x30, 0x0e, 0xdb, 0x46, 0x51, 0xe6, 0x18, 0x8a, 0x85, 0x40, 0x01, 0xef, 0xca, 0x74, 0xd7, 0xc1, 0xb9, 0x01, 0x17, 0x45, 0xda, 0x3f, 0x12, 0x94, 0xd8, 0x72, 0xb8, 0xdd, 0x39, 0x4c, 0x3f, 0x60, 0x8b, 0x42, 0xae, 0x7d, 0x0f, 0x89, 0xc1, 0xc7, 0xae, 0x86, 0x0e, 0xd5, 0x3d, 0xd1, 0x95, 0x7b, 0xd7, 0x0a, 0xac, 0x14, 0x9e, 0xd5, 0x2b, 0xa0, 0x9b, 0xff, 0x30, 0xc9, 0xcc, 0x8d, 0x07, 0xc2, 0x17, 0xe5, 0xe1, 0xdf, 0x9b, 0x4d, 0xa8, 0xf7, 0x0f, 0x81, 0x72, 0xb5, 0x8d, 0xa5, 0x89, 0xac, 0x43, 0x78, 0x9a, 0x88, 0x9c, 0x76, 0xa0, 0x37, 0x63, 0x43, 0xbd, 0xbb, 0x54, 0x93, 0x27, 0x92, 0x87, 0x1d, 0x35, 0xca, 0x03, 0x36, 0x20, 0x8e, 0xa0, 0x56, 0x49, 0xd6, 0x76, 0x7d, 0x79, 0x69, 0x0d, 0x5f, 0xfc, 0xe6, 0x7d, 0xf6, 0x81, 0x0c, 0xec, 0xd1, 0x33, 0x3f, 0xd2, 0xb3, 0x5d, 0x27, 0x07, 0x70, 0x1a, 0x64, 0xd8, 0x5e, 0x47, 0x93, 0xfa, 0xbc, 0x61, 0x68, 0x15, 0xe4, 0x93, 0x7e, 0xba, 0x34, 0x0b, 0xb2, 0x60, 0x8f, 0xf1, 0x01, 0x86, 0xc1, 0x04, 0xdf, 0x40, 0x0a, 0x01, 0x25, 0x86, 0xb0, 0xf8, 0xe5, 0xf5, 0xb4, 0xee, 0x0a, 0xa6, 0xb1, 0x89, 0x6e, 0x93, 0xca, 0x11, 0x4b, 0xe9, 0x35, 0x2b, 0x4e, 0x3b, 0x9f, 0x69, 0xc4, 0xe5, 0x77, 0x85, 0x72, 0xd2, 0x73, 0x2a, 0x08, 0xbb, 0xd3, 0x4b, 0x9d, 0xb7, 0xc8, 0xe5, 0x25, 0xcb, 0x99, 0x5f, 0xe3, 0xd5, 0x5b, 0x24, 0x8e, 0xcd, 0xdd, 0x3c, 0x8a, 0x91, 0xef, 0x99, 0xf0, 0x0c, 0xe8, 0xb5, 0xe5, 0x43, 0x32, 0x26, 0x0c, 0x0f, 0xe4, 0x38, 0x17, 0xc9, 0x56, 0x39, 0x58, 0x1b, 0x04, 0x71, 0xf3, 0xd2, 0x3d, 0x0d, 0x29, 0x80, 0x74, 0x84, 0x8d, 0x91, 0x2c, 0xaf, 0x8c, 0xa4, 0x90, 0x6a, 0x3c, 0x15, 0xda, 0x4c, 0xda, 0x7f, 0x3f, 0xfe, 0xeb, 0x96, 0x09, 0x3d, 0x44, 0x32, 0x49, 0x06, 0x65, 0x63, 0xab, 0xc2, 0x6a, 0xdd, 0xe5, 0x02, 0x7a, 0x33, 0x9c, 0x54, 0x16, 0x4c, 0x0b, 0x5b, 0xe9, 0xe4, 0x27, 0xe9, 0x7a, 0x92, 0xbd, 0x22, 0xd7, 0x5e, 0x21, 0x6d, 0xb8, 0x97, 0x0d, 0xb5, 0x09, 0xe2, 0x55, 0xc0, 0xbd, 0x95, 0x17, 0xd0, 0x52, 0xcc, 0xee, 0x6d, 0x1e, 0xf8, 0x45, 0xe6, 0x34, 0x6d, 0xb2, 0xf1, 0xa8, 0x37, 0x7d, 0x4b, 0x3e, 0x86, 0x9d, 0x4f, 0xc0, 0x3c, 0xfa, 0xa2, 0x9a, 0xad, 0x06, 0xba, 0x83, 0x10, 0xb2, 0xc0, 0x02, 0xf0, 0x82, 0xce, 0x01, 0x07, 0xc4, 0x01, 0xb2, 0x6c, 0x01, 0x70, 0x68, 0x01, 0x42, 0xd4, 0x9a, 0x90, 0x16, 0xb3, 0x1d, 0xb0, 0x4b, 0xc7, 0x47, 0x6d, 0x4c, 0x04, 0x4a, 0xb3, 0x83, 0x31, 0x46, 0x75, 0xf4, 0x4c, 0x28, 0x10, 0x88, 0x7b, 0x03, 0x48, 0x4d, 0xd3, 0xdb, 0xba, 0xbd, 0xca, 0x74, 0xbc, 0xfd, 0x43, 0x60, 0x76, 0xba, 0xa5, 0x63, 0xbc, 0xe9, 0x46, 0x00, 0xd7, 0x31, 0xff, 0xff, 0x19, 0x29, 0x4d, 0x01, 0x9d, 0x09, 0x30, 0xc1, 0xe7, 0x79, 0x66, 0xe1, 0x74, 0xbd, 0x03, 0x31, 0xe9, 0xbf, 0xca, 0x7e, 0xc1, 0x06, 0x94, 0x7b, 0x64, 0xe5, 0xc3, 0xe9, 0x99, 0x3f, 0x2f, 0x0c, 0x41, 0x57, 0x4c, 0x0d, 0xcd, 0xfd, 0xb2, 0x62, 0x9b, 0xf0, 0xc1, 0x34, 0x39, 0xaa, 0x04, 0x67, 0x3c, 0x23, 0x71, 0x28, 0xa9, 0x87, 0x90, 0x7d, 0x64, 0xc0, 0x0b, 0xa8, 0x51, 0x34, 0x6f, 0xfe, 0xe2, 0xf1, 0xdd, 0xa0, 0x0e, 0x68, 0xa6, 0xf1, 0x35, 0x6a, 0xbd, 0x92, 0x4c, 0x45, 0xd6, 0x3e, 0x9c, 0xea, 0x20, 0xd6, 0x67, 0xcf, 0xdb, 0xc4, 0x0b, 0xf6, 0xdd, 0xaf, 0xb8, 0xd5, 0x97, 0xc4, 0x05, 0xe1, 0x5a, 0x5e, 0xef, 0xb7, 0x0d, 0x82, 0x1f, 0xdc, 0x5e, 0x3a, 0x50, 0x51, 0x8a, 0xce, 0x6e, 0x88, 0x75, 0xea, 0x9f, 0x90, 0x17, 0x12, 0x99, 0xed, 0xe8, 0x2b, 0x44, 0x8d, 0xf2, 0xab, 0x93, 0xc1, 0xf0, 0xad, 0xd1, 0x6d, 0x14, 0x63, 0x21, 0x97, 0x83, 0x32, 0x9c, 0xeb, 0x6c, 0x59, 0xd6, 0x2a, 0x27, 0xac, 0xde, 0xb5, 0x7f, 0x69, 0x37, 0x4c, 0x60, 0xb6, 0xfd, 0x0e, 0x21, 0x27, 0x37, 0xc4, 0x3a, 0xdd, 0x4f, 0xd7, 0x1f, 0xfd, 0x28, 0x4a, 0xf1, 0x5e, 0x9d, 0x8b, 0x87, 0x3c, 0x71, 0xdc, 0xc7, 0x58, 0x88, 0x11, 0x7a, 0xb3, 0x63, 0x31, 0x48, 0x6d, 0xe6, 0x7a, 0x3d, 0xad, 0xf8, 0xd7, 0xd7, 0xe3, 0x7d, 0x19, 0x69, 0x4b, 0xf9, 0xdf, 0xab, 0x44, 0x4d, 0x8b, 0x03, 0x9d, 0x8d, 0xf5, 0x43, 0xa0, 0x12, 0x15, 0x04, 0x85, 0x2c, 0x7b, 0xec, 0x78, 0x94, 0x71, 0x50, 0xcc, 0xb8, 0x88, 0x5e, 0xe8, 0xcd, 0xbe, 0xa6, 0xe7, 0x14, 0xe1, 0x93, 0xe5, 0x68, 0x86, 0xe0, 0x0d, 0xbc, 0x0a, 0x46, 0xc6, 0xe3, 0x63, 0xaf, 0x06, 0x99, 0x22, 0x16, 0x8c, 0x8d, 0x6f, 0x2a, 0xbf, 0x21, 0xb8, 0xf3, 0x7c, 0x75, 0xf1, 0xca, 0x03, 0x26, 0x95, 0x4b, 0xad, 0xa4, 0xf4, 0x29, 0xb5, 0x07, 0x16, 0x8e, 0xb3, 0x79, 0x9b, 0xbe, 0xec, 0xdd, 0x64, 0x1f, 0xf8, 0x93, 0x7c, 0xf5, 0x0c, 0xb6, 0xdc, 0x74, 0xf6, 0xe8, 0xe7, 0x63, 0x26, 0xe8, 0x86, 0x18, 0x59, 0x5d, 0xc3, 0x13, 0xa8, 0x8d, 0xe1, 0xe9, 0x43, 0xc9, 0x58, 0xb2, 0x6c, 0x8c, 0x6d, 0x95, 0xc9, 0xa7, 0xcd, 0xc2, 0xc3, 0xfb, 0x77, 0xda, 0xf7, 0x05, 0x5e, 0x16, 0xf5, 0xc9, 0xa3, 0xa4, 0x33, 0xfe, 0x3f, 0xd4, 0x4e, 0xa1, 0xb2, 0xd7, 0x79, 0xcd, 0x5a, 0xce, 0x2b, 0xfc, 0xda, 0x5e, 0x5a, 0x8b, 0x79, 0x1c, 0xd7, 0x86, 0x62, 0x87, 0x8d, 0xcf, 0x6f, 0x52, 0x28, 0x30, 0x03, 0x97, 0xb1, 0x49, 0x7c, 0x7b, 0x05, 0x04, 0x07, 0xae, 0x2d, 0x94, 0x54, 0x06, 0xd5, 0x3d, 0x1b, 0x18, 0x3c, 0x13, 0xce, 0x3d, 0x2b, 0x4e, 0xac, 0xbe, 0x98, 0x60, 0x89, 0xcf, 0xb8, 0x25, 0xf4, 0x44, 0xe9, 0xda, 0x9d, 0xc8, 0x77, 0x33, 0x4f, 0xc0, 0x4b, 0x58, 0xaf, 0xf2, 0xd4, 0x12, 0xb8, 0xfb, 0x3a, 0x07, 0x3b, 0x7f, 0xaf, 0x3d, 0x7b, 0xf1, 0x8b, 0x09, 0xe3, 0x9c, 0x97, 0xb1, 0xd0, 0x4a, 0x32, 0xb6, 0x04, 0x23, 0x2e, 0xe5, 0xbe, 0xca, 0xad, 0xeb, 0x53, 0xfa, 0xc2, 0x8c, 0xea, 0xa0, 0x91, 0xe2, 0x9f, 0xa8, 0x68, 0xb2, 0x3f, 0x28, 0x80, 0xd6, 0x3f, 0x98, 0x5a, 0xf9, 0x96, 0xae, 0x01, 0x4c, 0xce, 0x2f, 0x1b, 0x6a, 0xd3, 0x1a, 0xd9, 0x69, 0x32, 0xc7, 0xba, 0x0e, 0x06, 0xed, 0x3e, 0x74, 0xec, 0xce, 0x80, 0x39, 0xee, 0x2e, 0x9b, 0x43, 0x44, 0xd2, 0x2d, 0x52, 0x8d, 0xf2, 0x9a, 0x20, 0x77, 0xb5, 0x21, 0xdf, 0x72, 0x8c, 0x85, 0x46, 0x4d, 0x93, 0xd1, 0x6a, 0xb2, 0x21, 0xcc, 0x97, 0x31, 0x3a, 0x89, 0xa6, 0x19, 0x77, 0x76, 0xc1, 0x7c, 0xfd, 0x2b, 0x99, 0x10, 0xbb, 0xfa, 0x16, 0xe5, 0xbf, 0xa3, 0x27, 0x19, 0x7c, 0xaf, 0xdc, 0xf9, 0x11, 0xb0, 0x00, 0xc6, 0x16, 0x9e, 0x5c, 0x4a, 0xcc, 0x19, 0x3f, 0xe0, 0x8b, 0x9a, 0x40, 0xfc, 0x44, 0x51, 0xa0, 0xab, 0xa4, 0x31, 0x13, 0x22, 0x0a, 0x1b, 0x4b, 0x37, 0x33, 0xdb, 0x21, 0x45, 0x7a, 0xfc, 0xfc, 0xc3, 0xd0, 0x3b, 0xe2, 0x27, 0x38, 0x78, 0x17, 0x0d, 0xd6, 0x4b, 0x8f, 0x77, 0x05, 0x52, 0x8f, 0xdd, 0x8d, 0xcd, 0x22, 0x48, 0x6e, 0x8d, 0x47, 0xfe, 0xbd, 0x66, 0x73, 0x2d, 0xa5, 0x95, 0x13, 0xe8, 0x5d, 0xce, 0xc2, 0xa7, 0xa5, 0xc0, 0xf5, 0x98, 0x78, 0xf5, 0x7d, 0x1a, 0x19, 0x8b, 0xd2, 0xbd, 0x7f, 0xe3, 0x07, 0xef, 0x57, 0x20, 0xd4, 0xbd, 0x4e, 0x29, 0xfc, 0xf6, 0x3c, 0x5e, 0xc8, 0x99, 0xa5, 0xf5, 0xf6, 0x26, 0x98, 0x6a, 0x1d, 0x83, 0x47, 0x52, 0x7e, 0x71, 0x53, 0xa5, 0x93, 0x95, 0x57, 0xf5, 0x12, 0x0f, 0x03, 0xc4, 0xdf, 0x30, 0x6d, 0x9d, 0x1f, 0x3a, 0x09, 0x03, 0xcc, 0x54, 0xf1, 0xea, 0xd8, 0x67, 0x30, 0x61, 0x2a, 0xa1, 0x85, 0xce, 0x62, 0x97, 0xb8, 0x90, 0x87, 0x5b, 0x34, 0x55, 0x59, 0xe8, 0x6d, 0x5b, 0x11, 0x3c, 0x0b, 0xa0, 0x3c, 0x4d, 0x15, 0x8a, 0xe8, 0x99, 0xda, 0x37, 0xce, 0xf9, 0xd2, 0x47, 0xf1, 0x84, 0xcf, 0x97, 0x1f, 0x50, 0x57, 0x5c, 0xa0, 0x74, 0x2c, 0x97, 0x83, 0x92, 0x1d, 0x2d, 0x2f, 0x00, 0xcd, 0xa9, 0xb9, 0x77, 0xad, 0x84, 0xe1, 0xaa, 0x4a, 0xdb, 0x9f, 0x83, 0x8a, 0x43, 0xc3, 0xb7, 0xe2, 0x94, 0xb1, 0xe6, 0xc5, 0x7d, 0xa9, 0x50, 0x46, 0x78, 0x1a, 0x4d, 0xcf, 0xad, 0x3f, 0x88, 0x3a, 0x30, 0x7c, 0x63, 0x9a, 0x2f, 0xb8, 0x86, 0x6f, 0xff, 0x55, 0x90, 0xa7, 0x5d, 0xd7, 0x92, 0xee, 0xe9, 0x2e, 0x39, 0xa6, 0x4c, 0x98, 0xeb, 0xa8, 0xd6, 0x06, 0xd5, 0xd3, 0x2c, 0xe1, 0x6d, 0xe0, 0xaa, 0x82, 0x4f, 0xac, 0x81, 0xa2, 0xd3, 0xdf, 0x3e, 0xf6, 0x2d, 0x0f, 0x3b, 0x93, 0x1c, 0xc4, 0xdc, 0x82, 0x13, 0xf1, 0xc4, 0x97, 0x56, 0xcc, 0x64, 0xeb, 0xf9, 0x40, 0xb5, 0x90, 0x5a, 0xc7, 0x05, 0xed, 0xa4, 0xc6, 0x53, 0x62, 0xe0, 0x3d, 0xc2, 0xde, 0xc6, 0xaf, 0xbf, 0x47, 0x8e, 0x51, 0x51, 0x3e, 0x74, 0xe8, 0x4a, 0xc6, 0x88, 0xfc, 0xcd, 0xcb, 0x19, 0xa4, 0x59, 0x4e, 0x72, 0x15, 0x73, 0xa9, 0x32, 0xa3, 0x48, 0x94, 0xd7, 0x4a, 0x4b, 0xbf, 0xec, 0x0a, 0x1f, 0xef, 0x00, 0x63, 0x4e, 0xf6, 0x12, 0x8f, 0x27, 0x97, 0x59, 0x93, 0xdd, 0xb8, 0xaa, 0xca, 0xe9, 0x23, 0x83, 0x68, 0x8f, 0x67, 0x47, 0xbd, 0xa4, 0x0f, 0x69, 0x37, 0xdc, 0xa2, 0xae, 0x4d, 0x2c, 0xcb, 0x9c, 0xb9, 0x4f, 0x56, 0xf9, 0x1e, 0xd5, 0x04, 0x55, 0xfc, 0x11, 0xfe, 0x3e, 0xd8, 0x72, 0x22, 0x03, 0xc7, 0x2d, 0x0d, 0x56, 0x19, 0xf0, 0x4b, 0xa8, 0x10, 0x2d, 0xc6, 0xed, 0xfe, 0xbe, 0xe1, 0x2d, 0x23, 0x2f, 0x5c, 0x56, 0x95, 0xde, 0xdd, 0x1b, 0x25, 0x71, 0x64, 0xfc, 0x69, 0x29, 0xf5, 0x21, 0x84, 0xb4, 0x6f, 0xab, 0x3f, 0x09, 0xdf, 0x7c, 0xd4, 0xc1, 0x11, 0x86, 0xd3, 0x8b, 0xaa, 0xfd, 0x71, 0xcf, 0xb7, 0x74, 0x81, 0xa9, 0x9e, 0xae, 0xa4, 0x8b, 0x95, 0x0d, 0x9b, 0x29, 0x63, 0xd6, 0x76, 0x08, 0xa5, 0xff, 0x6c, 0x20, 0x46, 0x4e, 0xba, 0xac, 0xa9, 0xa6, 0x68, 0xa0, 0x1a, 0xdb, 0x09, 0x38, 0x02, 0x45, 0xf9, 0xf0, 0x5d, 0x0e, 0x4a, 0xaf, 0x34, 0x40, 0x53, 0x60, 0x61, 0x91, 0x65, 0xcd, 0xb5, 0xe2, 0x5b, 0xee, 0xa4, 0x88, 0x16, 0x55, 0xbf, 0xf2, 0x82, 0x77, 0x79, 0x54, 0x2b, 0x0d, 0xec, 0xc3, 0x4b, 0xab, 0xec, 0x16, 0xd7, 0x48, 0xb8, 0x4b, 0x25, 0x79, 0xa9, 0x94, 0x1e, 0xb3, 0x22, 0xaf, 0x56, 0x10, 0x9d, 0x8f, 0x3c, 0x54, 0x65, 0xf0, 0xf4, 0xd7, 0x82, 0x21, 0x39, 0x0f, 0x42, 0x1e, 0xc9, 0xfb, 0x7f, 0x4a, 0xa1, 0x36, 0x92, 0xcd, 0x40, 0x00, 0xa2, 0xda, 0xe3, 0x4b, 0x42, 0xad, 0x00, 0xf0, 0x56, 0x37, 0x7a, 0x88, 0xfc, 0x2f, 0x88, 0xde, 0x56, 0x28, 0xe8, 0x22, 0x75, 0x38, 0x41, 0x32, 0xd5, 0x09, 0xdf, 0x75, 0x70, 0x11, 0x3c, 0x00, 0x41, 0x89, 0x8f, 0xb8, 0xda, 0xbc, 0x5a, 0x21, 0x0a, 0x3d, 0x21, 0xd5, 0x1c, 0x03, 0x73, 0x60, 0x12, 0xfc, 0x5e, 0x2a, 0x1f, 0xb7, 0x27, 0x11, 0xd8, 0x8b, 0x73, 0x1b, 0x46, 0xe1, 0xaa, 0xcc, 0x16, 0xa9, 0x04, 0xa0, 0xde, 0xbe, 0x17, 0xc8, 0x53, 0xd9, 0xcf, 0xf0, 0x93, 0x1d, 0x54, 0x9b, 0x38, 0x40, 0x23, 0xff, 0xc8, 0x86, 0xb2, 0xae, 0xd0, 0xb8, 0x25, 0xc2, 0xf5, 0x05, 0xcd, 0x68, 0xa2, 0x11, 0xcd, 0x8b, 0xe4, 0x00, 0xa9, 0xaa, 0x90, 0x31, 0x70, 0x8d, 0x4f, 0x6b, 0x48, 0x3c, 0x02, 0x76, 0x70, 0x4a, 0x91, 0xca, 0x13, 0x59, 0xbb, 0x7a, 0x87, 0x30, 0xaf, 0xbe, 0x71, 0x26, 0xa3, 0x70, 0xfa, 0xe2, 0x73, 0x41, 0xac, 0xc0, 0x5a, 0xf2, 0x7b, 0xa2, 0xaa, 0xbb, 0xb5, 0x04, 0x51, 0x36, 0x3c, 0x7f, 0x14, 0x69, 0x61, 0x99, 0xbd, 0xde, 0xb1, 0xfa, 0xa1, 0xf0, 0x1a, 0x10, 0x76, 0x2e, 0xce, 0x86, 0x2d, 0x91, 0x51, 0x76, 0x53, 0xeb, 0x89, 0x6e, 0xf2, 0x55, 0x31, 0x40, 0x84, 0x91, 0x15, 0xcc, 0x3d, 0x2b, 0xf8, 0xd1, 0x9a, 0x33, 0xa2, 0x60, 0x17, 0x1c, 0xa0, 0x73, 0x1f, 0xe9, 0x1d, 0x28, 0xa4, 0xc6, 0xd3, 0xbd, 0x0c, 0x82, 0xc0, 0xad, 0xbc, 0xf8, 0x17, 0x8d, 0x07, 0x5c, 0x3d, 0x78, 0x65, 0xb0, 0x67, 0x69, 0x8f, 0xdb, 0xbb, 0x48, 0x93, 0x26, 0x00, 0x81, 0xa7, 0x56, 0xb1, 0xec, 0xf9, 0xfe, 0x6f, 0xd6, 0x47, 0xa6, 0x0f, 0x57, 0xfb, 0x7d, 0x52, 0x2a, 0x73, 0xdc, 0x44, 0x25, 0x4b, 0x52, 0x90, 0x00, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xe0, 0x06, 0xe6, 0x81, 0xc1, 0x0d, 0x31, 0x44, 0x22, 0x38, 0x56, 0x12, 0x66, 0x2a, 0x86, 0x62, 0x1e, 0x69, 0xb2, 0x00, 0x01, 0x09, 0x0a, 0xf8, 0x53, 0x35, 0x2a, 0xd5, 0xc7, 0x8e, 0x2f, 0xdd, 0xc0, 0x53, 0xbe, 0x03, 0xea, 0x3f, 0x96, 0xbe, 0xe9, 0x75, 0xac, 0xf3, 0xda, 0xd1, 0x24, 0xed, 0xda, 0x19, 0x6d, 0xf3, 0xad, 0xb8, 0xa9, 0xc4, 0xe6, 0xde, 0xd9, 0x9c, 0xc6, 0x58, 0xcf, 0xe0, 0x17, 0xc5, 0x8e, 0xd9, 0x49, 0x65, 0x41, 0x1b, 0xb4, 0x1f, 0x79, 0xef, 0x0a, 0x37, 0x83, 0x1f, 0xf5, 0x08, 0x60, 0x31, 0xe1, 0x87, 0xfd, 0x04, 0x06, 0xe5, 0xe2, 0x8c, 0xc2, 0x02, 0xdc, 0x6b, 0xe0, 0xf4, 0x4a, 0x7b, 0x36, 0x4e, 0xfc, 0xeb, 0xc6, 0x5f, 0xc0, 0xaa, 0x8c, 0x19, 0xd4, 0xad, 0x90, 0xd3, 0xad, 0xbe, 0xc3, 0xef, 0x0c, 0xed, 0xfa, 0x26, 0xac, 0xcd, 0x04, 0x24, 0x3a, 0xa0, 0x23, 0x89, 0xa0, 0x13, 0x59, 0xdf, 0xed, 0x6d, 0x91, 0xa1, 0x9e, 0xd7, 0x8e, 0xaa, 0xf4, 0xc3, 0xd5, 0xb2, 0xa2, 0xe4, 0xab, 0xcf, 0x92, 0xab, 0x69, 0x16, 0xa7, 0x01, 0x26, 0x8f, 0x1c, 0xa5, 0x4d, 0x4f, 0x39, 0x1e, 0x46, 0x16, 0xa9, 0x59, 0x20, 0xf0, 0xb4, 0x14, 0x14, 0xe2, 0x75, 0x59, 0x50, 0x31, 0x30, 0x57, 0x91, 0x66, 0x76, 0xdd, 0xef, 0xe2, 0xb2, 0xb3, 0xbe, 0x0c, 0x5b, 0x06, 0xf5, 0xd7, 0x33, 0x83, 0x3a, 0x5b, 0x33, 0x94, 0x6b, 0x88, 0xbf, 0x87, 0xe7, 0xbb, 0xd1, 0x7d, 0xc3, 0xaf, 0x02, 0xd7, 0x96, 0xfb, 0x5b, 0xe9, 0xb9, 0x98, 0xea, 0x95, 0xda, 0x2e, 0x45, 0x05, 0x0d, 0x2c, 0x76, 0x67, 0xc7, 0x5e, 0x7a, 0x89, 0x00, 0x5a, 0xb7, 0x34, 0x1f, 0xb6, 0x1c, 0xa0, 0xe1, 0x1c, 0x58, 0xc9, 0x70, 0xc2, 0xf5, 0xb0, 0x5b, 0x2e, 0x5d, 0xf2, 0x07, 0x02, 0xed, 0xf1, 0x71, 0x87, 0x83, 0x56, 0x24, 0xf0, 0x9d, 0x74, 0x2e, 0x10, 0x8e, 0x60, 0x3b, 0x14, 0xde, 0xa1, 0xae, 0xbf, 0x96, 0x30, 0x1d, 0x3a, 0x3e, 0xaa, 0x65, 0x37, 0x31, 0x5b, 0x98, 0x82, 0x80, 0xc3, 0x59, 0x82, 0x61, 0xfd, 0xfa, 0x1f, 0x01, 0x85, 0x97, 0x16, 0x19, 0x73, 0xaf, 0x45, 0x16, 0x67, 0x62, 0x2b, 0x46, 0x15, 0x50, 0x9d, 0xc7, 0x86, 0x7a, 0xd5, 0xc2, 0x2a, 0x7d, 0x52, 0x4b, 0x8f, 0x86, 0x73, 0x30, 0x2c, 0x0d, 0xdc, 0x5a, 0x99, 0xb3, 0x8e, 0x82, 0xdf, 0x1a, 0x2e, 0x43, 0xa8, 0x54, 0xea, 0x7f, 0x78, 0x10, 0x9c, 0xe0, 0x81, 0x0c, 0xac, 0x45, 0x7c, 0x15, 0xaa, 0x9f, 0x7a, 0xca, 0x9d, 0x88, 0x08, 0xe6, 0xfa, 0xf2, 0xe1, 0xb5, 0xdd, 0x90, 0x0e, 0x4e, 0xb5, 0xf9, 0xbc, 0x7c, 0x57, 0xeb, 0xd4, 0x69, 0x28, 0xef, 0x0e, 0xcd, 0x5f, 0x73, 0xa8, 0xb6, 0x49, 0xf9, 0xfc, 0x55, 0x20, 0xa3, 0x0b, 0x72, 0xfd, 0x69, 0x4f, 0x6b, 0x99, 0x1d, 0x0f, 0xf9, 0xd7, 0x95, 0x82, 0x7a, 0x1c, 0x34, 0x21, 0x49, 0xbe, 0x26, 0x9b, 0x48, 0x5f, 0x1e, 0x92, 0x76, 0x93, 0xce, 0x4e, 0xbc, 0x82, 0xe7, 0x19, 0x62, 0xf2, 0x3d, 0x76, 0x1e, 0x64, 0xb2, 0xd5, 0xaa, 0xc8, 0x35, 0x76, 0xaf, 0x65, 0xb4, 0xce, 0xe5, 0x76, 0xc9, 0xce, 0xc8, 0x5c, 0xa4, 0x8d, 0xd2, 0x49, 0xac, 0xae, 0x97, 0xdd, 0x86, 0x4d, 0xe8, 0x6c, 0x70, 0x7e, 0x1b, 0x2f, 0xea, 0xe7, 0x3c, 0xdf, 0x17, 0x92, 0x20, 0x88, 0x00, 0xa5, 0x61, 0xc6, 0x4c, 0x12, 0xf9, 0x43, 0xa8, 0xee, 0x6d, 0x15, 0x69, 0xd6, 0x68, 0x9a, 0xbb, 0xcf, 0x07, 0x0b, 0x17, 0x00, 0x11, 0xc0, 0x95, 0x6e, 0xce, 0x69, 0x35, 0x9b, 0xd6, 0x48, 0xc4, 0xf9, 0xd3, 0x35, 0x3d, 0xb9, 0x17, 0xae, 0x31, 0x28, 0xf2, 0xc9, 0xf8, 0xde, 0xbd, 0x40, 0x29, 0x03, 0xc8, 0x0f, 0x7a, 0xe9, 0x06, 0x86, 0x33, 0x9f, 0x09, 0x2d, 0xa3, 0x00, 0x8b, 0x06, 0x4c, 0x3d, 0xde, 0x45, 0x39, 0xd5, 0xc8, 0xa6, 0x4d, 0x23, 0x00, 0x46, 0x82, 0xea, 0x54, 0x69, 0x59, 0xa0, 0xcb, 0x09, 0x85, 0x42, 0x83, 0x7c, 0xab, 0x6e, 0xab, 0xf9, 0x95, 0x6f, 0x1c, 0xb5, 0x59, 0x28, 0x63, 0xed, 0x2c, 0xae, 0x55, 0x80, 0xce, 0x67, 0x2f, 0xf0, 0xff, 0x42, 0x48, 0x43, 0x79, 0x32, 0xbb, 0x4d, 0x66, 0x89, 0x95, 0xcd, 0x83, 0x8f, 0x02, 0xa2, 0x2f, 0xe9, 0xea, 0x06, 0x59, 0x6f, 0x24, 0xa6, 0xe0, 0xd7, 0x23, 0x03, 0x5e, 0xe1, 0x23, 0x10, 0xee, 0x65, 0x94, 0x49, 0x88, 0xf5, 0xf4, 0x0b, 0x6a, 0x12, 0xab, 0xe7, 0xe0, 0x7d, 0x34, 0xa0, 0xcd, 0xfc, 0x39, 0x6a, 0xb3, 0xc7, 0x55, 0xe6, 0xe6, 0x2c, 0xc6, 0x38, 0xec, 0x13, 0xf8, 0x77, 0x27, 0x29, 0xad, 0x64, 0x5c, 0x76, 0x6a, 0x71, 0x62, 0xf8, 0x19, 0x92, 0x78, 0xba, 0x96, 0x1d, 0x0c, 0x39, 0x66, 0xe5, 0x3e, 0x71, 0x01, 0x96, 0x3a, 0x29, 0x6e, 0x9d, 0x82, 0x22, 0x58, 0x35, 0xa6, 0xef, 0xb3, 0x88, 0xbe, 0x34, 0xca, 0x44, 0xdb, 0x8f, 0x4b, 0xcf, 0x6d, 0xff, 0x5d, 0x5f, 0xa0, 0x27, 0x52, 0x8c, 0x5d, 0xd0, 0x50, 0xf4, 0xd2, 0x42, 0x14, 0x98, 0xbd, 0xdb, 0x36, 0xa1, 0x5b, 0x86, 0x60, 0x4a, 0x37, 0x0f, 0x80, 0xf0, 0x47, 0xb6, 0x79, 0xff, 0xe7, 0xd3, 0xec, 0x13, 0x0c, 0x99, 0x97, 0xd2, 0x3d, 0x85, 0x51, 0x28, 0xe4, 0x89, 0xa4, 0x3f, 0x2a, 0x1c, 0xda, 0x06, 0x1b, 0xf9, 0xc1, 0x8c, 0xaa, 0x50, 0x50, 0x43, 0x6e, 0x4f, 0xae, 0x13, 0x20, 0x6f, 0x1f, 0x60, 0xe1, 0xf6, 0x65, 0x94, 0xf2, 0x67, 0xbc, 0x0e, 0x1f, 0x6a, 0xb6, 0xf3, 0xcc, 0x8f, 0x81, 0x7b, 0xab, 0xfb, 0xbb, 0x24, 0xf1, 0x00, 0x29, 0x01, 0xce, 0xfe, 0x79, 0xdc, 0x7b, 0xc8, 0xa5, 0x3a, 0x6f, 0x0d, 0x38, 0x06, 0x15, 0xe4, 0xc3, 0xb7, 0x91, 0xf8, 0xff, 0xc5, 0x2c, 0x20, 0x25, 0x2d, 0x8e, 0x5f, 0x5f, 0x7d, 0xc9, 0x10, 0x3b, 0x84, 0xf8, 0x2b, 0x91, 0x39, 0x96, 0x19, 0x8b, 0x0d, 0x15, 0x12, 0xff, 0xab, 0x25, 0xbf, 0xde, 0x48, 0x78, 0x3e, 0xb4, 0x8c, 0xa6, 0x2d, 0xf0, 0xa1, 0x9d, 0x17, 0xe7, 0x00, 0xfe, 0x86, 0x58, 0x01, 0x1f, 0x14, 0x9a, 0x84, 0xb1, 0x99, 0x79, 0xaa, 0xcb, 0x32, 0x77, 0x92, 0x0d, 0x4c, 0xa3, 0xf3, 0xd9, 0xf5, 0xbd, 0xb8, 0x54, 0x1e, 0x92, 0x76, 0x71, 0x26, 0x0d, 0xc9, 0x50, 0x32, 0xda, 0xeb, 0xbc, 0xd8, 0x22, 0x9d, 0xf5, 0xed, 0xa2, 0xa8, 0xe6, 0xc7, 0x7b, 0xf3, 0x99, 0xfd, 0xbf, 0x6d, 0xed, 0x79, 0xe8, 0xc4, 0xc8, 0xed, 0xbb, 0xb3, 0x92, 0xf7, 0x28, 0xb8, 0x0a, 0x38, 0x32, 0xfd, 0xa4, 0xbc, 0xd5, 0x6b, 0x8f, 0x37, 0x41, 0xd5, 0xab, 0x63, 0x59, 0xb4, 0xd4, 0x4f, 0x95, 0x25, 0xcc, 0x8d, 0x1b, 0x3b, 0xc2, 0x9f, 0xff, 0xa0, 0x52, 0xfd, 0x3b, 0x4e, 0x52, 0x31, 0x91, 0x86, 0xbd, 0xbf, 0xda, 0xc6, 0x1d, 0x87, 0x9c, 0x94, 0x9b, 0xe7, 0x4f, 0x23, 0x2c, 0x9d, 0xe0, 0x04, 0x18, 0x64, 0x30, 0x98, 0xe9, 0xcd, 0x1c, 0x1a, 0x93, 0xe7, 0x5e, 0x9b, 0x13, 0x23, 0x7b, 0xc1, 0x0c, 0xa1, 0xc3, 0x62, 0x49, 0x6b, 0x39, 0x12, 0x48, 0x70, 0xbe, 0xe5, 0xa7, 0xb8, 0xcf, 0x4e, 0xaa, 0x49, 0x91, 0xb8, 0x06, 0x7c, 0xf4, 0x63, 0xb0, 0x19, 0x52, 0x39, 0xbd, 0x4f, 0x5e, 0xf8, 0xf7, 0x60, 0x83, 0x49, 0x5c, 0x31, 0x7e, 0x91, 0x47, 0x3c, 0x98, 0x5c, 0x04, 0x86, 0x7d, 0xf1, 0x0f, 0xac, 0x29, 0xae, 0x5a, 0xaf, 0x25, 0x11, 0x3e, 0xf7, 0xd8, 0xed, 0x64, 0x70, 0xe9, 0x14, 0x8a, 0xfd, 0x28, 0xbe, 0x9a, 0x95, 0x64, 0x98, 0x56, 0x7f, 0x64, 0x49, 0x33, 0x4a, 0xa6, 0x94, 0xfc, 0x5a, 0xf7, 0xff, 0xe9, 0x26, 0x93, 0x85, 0xae, 0xe4, 0x05, 0x99, 0xf4, 0x6d, 0x95, 0x25, 0x0c, 0x79, 0xc4, 0x20, 0xc8, 0x81, 0xe3, 0x03, 0x76, 0x7e, 0xa1, 0xb6, 0xd1, 0x2c, 0xa6, 0x16, 0xbb, 0x95, 0xa9, 0xcd, 0x41, 0x47, 0xba, 0x7b, 0x76, 0xad, 0x4b, 0x06, 0xbb, 0x8e, 0x0a, 0x17, 0xec, 0xcc, 0x67, 0x89, 0x53, 0xd3, 0x22, 0x7f, 0x11, 0xc1, 0x09, 0x91, 0xd3, 0xf6, 0x0e, 0x5a, 0x09, 0x9e, 0x1b, 0x41, 0x2b, 0x80, 0x80, 0x2f, 0xfe, 0x65, 0xcd, 0x34, 0x9b, 0x91, 0x1e, 0x32, 0xce, 0xe2, 0x6d, 0xc5, 0xd5, 0xf8, 0x0c, 0xbd, 0x6a, 0xd7, 0x16, 0x32, 0x79, 0x75, 0xc5, 0x2d, 0xc4, 0xa1, 0x22, 0x9e, 0x52, 0xaa, 0x95, 0x2a, 0x2f, 0xa6, 0x0d, 0x93, 0x25, 0x52, 0x79, 0xf8, 0x32, 0x6a, 0xba, 0x03, 0x08, 0xdb, 0xf6, 0x3c, 0x96, 0x25, 0x85, 0x4b, 0x76, 0x71, 0x92, 0x29, 0x48, 0x29, 0x4f, 0xac, 0x53, 0xe2, 0xdf, 0x41, 0xf3, 0xc0, 0xb7, 0x19, 0x1b, 0x50, 0xa8, 0x3b, 0x45, 0x38, 0x9a, 0x35, 0x4a, 0x20, 0xf1, 0x21, 0x20, 0xb5, 0x96, 0x03, 0xe2, 0x9f, 0x02, 0xd9, 0x9c, 0xc4, 0x37, 0xd9, 0xd4, 0x95, 0x32, 0xfb, 0x6e, 0x74, 0xe8, 0xf7, 0x42, 0xcb, 0x57, 0xbb, 0x2c, 0xe8, 0x54, 0x9f, 0x6a, 0x65, 0xa2, 0x2a, 0x75, 0x2e, 0xb9, 0x47, 0x14, 0xcd, 0xd2, 0xb9, 0xa0, 0xff, 0x5b, 0x45, 0x26, 0x89, 0x7e, 0xf9, 0xac, 0xef, 0x42, 0xc0, 0xd8, 0x73, 0x35, 0x67, 0x32, 0x8e, 0xcc, 0x65, 0x79, 0xf8, 0x42, 0x07, 0xa1, 0x86, 0xd8, 0x22, 0xe6, 0x07, 0xda, 0x10, 0xc9, 0xfa, 0xf5, 0x1f, 0x21, 0xb7, 0xef, 0x4b, 0x7c, 0x17, 0x5c, 0x7b, 0x69, 0x8a, 0x22, 0x56, 0x2c, 0xb8, 0xb2, 0x7c, 0xc7, 0x1b, 0x7d, 0x00, 0x7d, 0x4b, 0xb8, 0xab, 0x17, 0x5f, 0xd9, 0xc2, 0x1b, 0x4d, 0xac, 0x9b, 0xa0, 0xbd, 0xc8, 0xd1, 0xf7, 0x52, 0xeb, 0xf7, 0x90, 0x66, 0x3c, 0x6d, 0x17, 0x7d, 0xee, 0x06, 0xbb, 0xbf, 0xb1, 0xed, 0x8a, 0x6b, 0x76, 0x74, 0x89, 0x7d, 0xc8, 0xc6, 0x8f, 0xfc, 0x5f, 0x68, 0xba, 0x70, 0x4c, 0x44, 0xa4, 0x4c, 0xb4, 0x0d, 0x7a, 0x3e, 0xb0, 0x46, 0x8e, 0xc9, 0x5c, 0xff, 0x26, 0x94, 0x71, 0x4c, 0x3b, 0xaa, 0xa4, 0x22, 0xbe, 0xaa, 0x28, 0x5b, 0xc6, 0x63, 0xac, 0xe0, 0x8c, 0x5f, 0xf8, 0xfe, 0xc7, 0x14, 0xb4, 0x56, 0xa9, 0xcc, 0xc2, 0x67, 0xd4, 0x38, 0x6d, 0x18, 0x99, 0x3f, 0xb4, 0x79, 0x9b, 0x02, 0x37, 0xa1, 0x67, 0x01, 0x07, 0xd3, 0x57, 0xee, 0x42, 0x95, 0xc4, 0xee, 0x02, 0x6c, 0x64, 0x07, 0xc5, 0x10, 0xc5, 0xc1, 0x42, 0xe6, 0x12, 0x84, 0xc1, 0xac, 0xc7, 0x99, 0xaa, 0x82, 0x4f, 0x61, 0xb3, 0x90, 0xa5, 0x49, 0xec, 0x0b, 0x3e, 0xf7, 0x18, 0xad, 0x2f, 0xc6, 0x61, 0x88, 0xc8, 0xc9, 0x8e, 0x7c, 0x6d, 0x8e, 0x07, 0x74, 0x0c, 0x03, 0x95, 0x8b, 0x47, 0x27, 0x37, 0xa7, 0xeb, 0xc6, 0xe2, 0x7d, 0x7e, 0x1c, 0x12, 0x48, 0xef, 0x60, 0x4a, 0xd5, 0x34, 0x21, 0x6e, 0xc0, 0x11, 0x8d, 0xec, 0x1e, 0x50, 0x91, 0x99, 0xce, 0x67, 0xa4, 0xf0, 0xcb, 0x25, 0x0e, 0x00, 0xca, 0xd7, 0xc6, 0x40, 0xaf, 0xd4, 0x35, 0xb4, 0xd8, 0x39, 0x27, 0xde, 0x05, 0x4f, 0xb1, 0xa4, 0x74, 0x92, 0x59, 0x03, 0xc1, 0xd9, 0x71, 0xfd, 0xf3, 0x2d, 0x3a, 0xf9, 0xf0, 0x67, 0xd3, 0xd0, 0x95, 0x2a, 0x3f, 0x76, 0xf9, 0x9f, 0x8e, 0x22, 0xd1, 0xb9, 0x11, 0x02, 0x42, 0x1a, 0x95, 0xb0, 0x4d, 0x58, 0x5e, 0x2f, 0x24, 0xbe, 0xbb, 0xb8, 0x43, 0xa3, 0xcd, 0xc8, 0x87, 0x3d, 0x4b, 0xeb, 0x80, 0x4a, 0x5e, 0x77, 0x0e, 0xec, 0x06, 0xc4, 0x31, 0x7b, 0x82, 0xa4, 0x69, 0x72, 0x94, 0x1d, 0xc5, 0x13, 0x85, 0x2a, 0x84, 0xeb, 0xd4, 0x2f, 0x8f, 0xcb, 0xcb, 0xa2, 0x3f, 0x48, 0xa4, 0xed, 0x59, 0x40, 0x57, 0xca, 0x8b, 0xe2, 0xa2, 0x10, 0x59, 0x92, 0x92, 0x4f, 0x29, 0x50, 0x2d, 0x52, 0xe1, 0xee, 0xdc, 0xbe, 0x05, 0x2a, 0x76, 0x7d, 0x38, 0x6c, 0x3e, 0x7f, 0xb7, 0x48, 0x57, 0x35, 0x75, 0xc4, 0x41, 0x93, 0x21, 0xca, 0x87, 0xd5, 0x14, 0x30, 0x95, 0x2b, 0x4f, 0xc3, 0x6c, 0xc3, 0xce, 0x78, 0xe5, 0x25, 0x8e, 0xfe, 0x6b, 0x09, 0xfa, 0xf3, 0xd3, 0x13, 0x22, 0x14, 0xfb, 0x95, 0x50, 0x15, 0x67, 0x09, 0x4d, 0xc8, 0x91, 0x4b, 0x82, 0xd3, 0x9b, 0xf3, 0x14, 0xd9, 0xfb, 0xb2, 0x1a, 0x03, 0x30, 0xff, 0x58, 0x7e, 0xce, 0x51, 0xda, 0xb2, 0xa2, 0xc9, 0x66, 0x18, 0x84, 0x04, 0xd3, 0xe0, 0x57, 0x60, 0x8b, 0xf8, 0x74, 0x15, 0x12, 0x1c, 0x41, 0x09, 0x16, 0x59, 0xf9, 0xe7, 0x3b, 0x89, 0xe3, 0x27, 0xa9, 0x3d, 0xcd, 0x08, 0xa8, 0xe3, 0x14, 0x49, 0x87, 0x61, 0x28, 0x8f, 0x54, 0x7f, 0xdb, 0x9d, 0x0f, 0x7c, 0xde, 0x1f, 0xa2, 0x3a, 0xc8, 0xad, 0x37, 0x0a, 0x60, 0x86, 0x3f, 0x81, 0xd9, 0x52, 0x21, 0x5b, 0x49, 0xae, 0xb5, 0x18, 0x03, 0x56, 0xba, 0x46, 0x7c, 0xcc, 0xc7, 0xec, 0xf2, 0x6a, 0x29, 0xc8, 0xcc, 0x64, 0xbe, 0x5a, 0x61, 0xda, 0xf0, 0x34, 0xcb, 0x95, 0xed, 0xf2, 0x23, 0xbd, 0x6c, 0x09, 0x79, 0x68, 0x00, 0x00, 0x01, 0x09 }; +constexpr AccessUnit AVC_MULTIPLE_PACK_EXPECTED_AU_1 = { 0x15f90, 0x159b2, true, 0, {}, { 0xf3, 0x15, 0xed, 0x63, 0x82, 0x7c, 0xb1, 0xdf, 0x38, 0x75, 0x9e, 0x5e, 0xb4, 0x5e, 0xe2, 0xf2, 0x65, 0x6a, 0x58, 0xb1 } }; +constexpr AccessUnit AVC_MULTIPLE_PACK_EXPECTED_AU_2 = { 0x64615f94, 0x3c0159b2, true, 0, {}, { 0xbe, 0x1d, 0x4f, 0x54, 0x72, 0x44, 0x77, 0xa3, 0x09, 0x5e, 0x3b, 0xea, 0xc2, 0x55, 0x07, 0xb5, 0xcd, 0x33, 0x28, 0x6d } }; +constexpr AccessUnit AVC_MULTIPLE_PACK_EXPECTED_AU_3 = { 0x15f90, 0x159b2, true, 0, {}, { 0x37, 0xdb, 0xa1, 0x63, 0x9e, 0x5a, 0xff, 0x92, 0xd0, 0x54, 0xbd, 0xc6, 0x69, 0x4f, 0x38, 0x89, 0xb8, 0x4b, 0x66, 0xfb } }; +constexpr AccessUnit AVC_MULTIPLE_PACK_EXPECTED_AU_4 = { std::numeric_limits::max(), std::numeric_limits::max(), false, 0, {}, { 0x03, 0x31, 0xd3, 0xe2, 0xbb, 0x54, 0x06, 0xdb, 0xda, 0xe8, 0x0b, 0xfd, 0x96, 0x81, 0x66, 0x3f, 0x5c, 0x1b, 0xac, 0x69 } }; + +constexpr std::array M2V_MULTIPLE_PACK_STREAM = { 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xe0, 0x06, 0xe6, 0x81, 0xc1, 0x0d, 0x31, 0x00, 0x05, 0xbf, 0x21, 0x11, 0x00, 0x05, 0xb3, 0x65, 0x1e, 0x69, 0xb2, 0x00, 0x00, 0x01, 0x00, 0xb8, 0x7e, 0x91, 0xe4, 0x7b, 0x15, 0x52, 0x0c, 0x57, 0xe9, 0x3f, 0x05, 0x04, 0x5c, 0x02, 0x72, 0xde, 0x18, 0x8d, 0x08, 0x31, 0x03, 0x75, 0xa4, 0xfe, 0xfe, 0x0b, 0xda, 0xcb, 0x2f, 0x8d, 0xe9, 0xb3, 0xc0, 0x32, 0x65, 0x3e, 0xf8, 0x3d, 0x89, 0xd1, 0xe1, 0xcb, 0xe0, 0x8f, 0xad, 0x2e, 0x97, 0x22, 0x75, 0x3a, 0xcd, 0xcd, 0x6d, 0x5b, 0x4b, 0xff, 0x04, 0x9a, 0x4a, 0xfe, 0x8a, 0xc5, 0xd7, 0x10, 0x0a, 0xb1, 0x71, 0x50, 0x0b, 0x2f, 0x82, 0x31, 0x15, 0x66, 0xab, 0xe4, 0x4b, 0x25, 0x4f, 0x62, 0xf6, 0xe0, 0xab, 0x11, 0x11, 0x55, 0x65, 0x65, 0x79, 0x9b, 0xfb, 0xd8, 0x85, 0x6b, 0x53, 0x19, 0xc6, 0x1c, 0xfc, 0x24, 0x2d, 0x00, 0x9b, 0x57, 0xac, 0xd9, 0xfa, 0x7a, 0xe4, 0x60, 0x1f, 0x8a, 0xb8, 0x0c, 0x92, 0x85, 0x06, 0xe4, 0x34, 0xd7, 0xce, 0x80, 0x4b, 0x21, 0xf4, 0x5a, 0xea, 0x19, 0x4a, 0xb2, 0x0d, 0x25, 0x58, 0x07, 0x96, 0x58, 0xad, 0xde, 0x80, 0x5d, 0xa8, 0xff, 0x74, 0x8d, 0xaf, 0x1d, 0xd7, 0x90, 0x0e, 0x3d, 0xa1, 0x85, 0x1f, 0xf8, 0x1e, 0xf5, 0xc5, 0x35, 0x0d, 0x79, 0x50, 0xd4, 0x28, 0x5a, 0x8e, 0xae, 0xe3, 0x2f, 0xd1, 0x6b, 0xb7, 0xaf, 0x30, 0xa3, 0xf5, 0x00, 0xf6, 0xe5, 0x05, 0x8c, 0x5b, 0x3f, 0xb3, 0xb0, 0xb2, 0x35, 0x88, 0x65, 0x62, 0x3a, 0x7e, 0x20, 0x17, 0x61, 0x1f, 0x98, 0x10, 0x68, 0xf7, 0x8b, 0x29, 0x5a, 0x7e, 0x51, 0xe0, 0x09, 0x72, 0xde, 0xbc, 0xfd, 0x0b, 0xdf, 0x67, 0xa3, 0x8b, 0x4f, 0xe0, 0xa3, 0xfe, 0x33, 0x09, 0x38, 0x77, 0x97, 0x53, 0xa6, 0x11, 0x57, 0xb8, 0x5e, 0xed, 0x75, 0x1a, 0x66, 0xf4, 0x5f, 0x74, 0x13, 0x80, 0xb5, 0xfe, 0xce, 0x8c, 0x04, 0x32, 0x7e, 0xa1, 0x91, 0x39, 0x04, 0xcd, 0x4c, 0x2f, 0x59, 0x5d, 0xa6, 0xdb, 0x3d, 0xc6, 0x58, 0x66, 0x55, 0xca, 0x53, 0xdc, 0xc2, 0x3a, 0x07, 0xc0, 0xc2, 0x74, 0x7b, 0x28, 0xfc, 0xd0, 0xcd, 0x17, 0x03, 0xb3, 0x26, 0x8c, 0x9e, 0x60, 0x9c, 0x5b, 0x57, 0x3e, 0x44, 0x6f, 0xc0, 0x1f, 0xa7, 0xdd, 0xb7, 0xa0, 0x59, 0x3e, 0xd8, 0x25, 0x2d, 0xf1, 0x4e, 0x8a, 0x76, 0x86, 0x84, 0xe3, 0xf0, 0xec, 0x70, 0x87, 0xc2, 0x45, 0xc9, 0x3a, 0xd6, 0x4d, 0x4d, 0xc5, 0x18, 0x4b, 0x11, 0x29, 0x13, 0x05, 0x8e, 0x44, 0x90, 0xbb, 0x8c, 0xa6, 0x77, 0xeb, 0x64, 0x0c, 0xcf, 0x06, 0x14, 0x72, 0xeb, 0xfa, 0xca, 0x63, 0xc5, 0x7e, 0x9b, 0x7f, 0x83, 0x7c, 0x18, 0xd8, 0x21, 0xf0, 0xb7, 0xb6, 0x51, 0xf3, 0x7d, 0x4c, 0xb4, 0x38, 0xb4, 0xca, 0x25, 0xa9, 0x16, 0x5f, 0x48, 0xea, 0xef, 0x83, 0x92, 0x07, 0xc5, 0xec, 0x08, 0xa2, 0x39, 0x26, 0x98, 0xbb, 0x1c, 0x02, 0xba, 0xf8, 0xe4, 0xe4, 0xbb, 0xb3, 0x77, 0x19, 0x17, 0xbf, 0x97, 0xb2, 0x9a, 0x1f, 0x20, 0xea, 0xdc, 0xc5, 0x4e, 0xaa, 0xf5, 0x2e, 0x0e, 0xb8, 0x8a, 0x73, 0x8d, 0xab, 0xc3, 0x2b, 0x05, 0xe4, 0x43, 0xed, 0xbc, 0xc0, 0xd2, 0x18, 0x96, 0x1f, 0x65, 0xd0, 0xc7, 0x2b, 0x59, 0x12, 0xf3, 0x69, 0x48, 0x32, 0x47, 0xc5, 0x58, 0x8c, 0x00, 0x60, 0x8f, 0xb4, 0x29, 0x0b, 0xf0, 0x03, 0x88, 0x88, 0xfc, 0xbe, 0x7b, 0x80, 0x7d, 0x9f, 0x99, 0xae, 0xa4, 0xf2, 0x2d, 0xc0, 0x1a, 0xb3, 0xa5, 0x79, 0x7e, 0x16, 0x72, 0x74, 0xf4, 0x92, 0x77, 0x19, 0xbc, 0xfc, 0x8d, 0xf1, 0x0c, 0xf8, 0x32, 0xfc, 0xf3, 0xcf, 0x93, 0xb8, 0xc0, 0x82, 0x4e, 0x0e, 0x2f, 0x5c, 0xf2, 0x88, 0x38, 0x39, 0x0e, 0x30, 0x00, 0x7e, 0xcd, 0x84, 0xd1, 0xc6, 0x8b, 0xdd, 0x8c, 0x12, 0x0a, 0x81, 0x27, 0x23, 0x3f, 0xd4, 0x78, 0x99, 0xec, 0x53, 0xa1, 0xad, 0x71, 0x8a, 0xf8, 0x73, 0xf7, 0xb6, 0x6c, 0x07, 0xa9, 0xc0, 0xa7, 0x59, 0x70, 0x4f, 0xbd, 0x00, 0x7f, 0x65, 0xf3, 0x7f, 0x6a, 0xec, 0xe9, 0xec, 0x66, 0xce, 0x86, 0x26, 0x90, 0x01, 0x87, 0x0f, 0x4a, 0xfe, 0x13, 0xbc, 0x1b, 0xe5, 0xb2, 0x82, 0x1c, 0x5c, 0xf0, 0xcc, 0x89, 0x69, 0x0e, 0xda, 0x58, 0x2b, 0x4b, 0x42, 0x87, 0xcc, 0xd1, 0x6f, 0xc1, 0x7a, 0x80, 0x63, 0x2a, 0xc3, 0x28, 0x4c, 0xae, 0xf0, 0x77, 0x9a, 0xa9, 0xc2, 0x8b, 0x0d, 0xa3, 0xfc, 0x7e, 0xb9, 0x99, 0xa6, 0x2c, 0x9a, 0x4e, 0x10, 0x77, 0x20, 0xb5, 0x7c, 0x2d, 0xa6, 0x02, 0xee, 0x08, 0x6e, 0x4f, 0x5b, 0x8b, 0x9e, 0x35, 0xc3, 0x64, 0xdf, 0xf7, 0x7f, 0xc0, 0x57, 0xf4, 0x42, 0x0f, 0x16, 0xdd, 0xb2, 0xf5, 0x9c, 0x04, 0x0c, 0x97, 0x64, 0x48, 0x94, 0x0c, 0xc4, 0xfe, 0x9e, 0xce, 0x78, 0x0c, 0xda, 0xcd, 0x9d, 0x3d, 0x38, 0xd6, 0x83, 0x5d, 0x36, 0x52, 0x61, 0x86, 0x19, 0x23, 0x39, 0x51, 0x9f, 0xb5, 0x95, 0x5f, 0x1a, 0x6d, 0x36, 0x68, 0x3a, 0x01, 0xe3, 0x5f, 0x6e, 0x73, 0x0f, 0xf4, 0xb6, 0xc2, 0x3f, 0x14, 0x66, 0xa3, 0x77, 0x07, 0x6b, 0xed, 0x76, 0x85, 0x81, 0x0b, 0x16, 0x48, 0x34, 0x68, 0x8d, 0x50, 0xe7, 0x91, 0x85, 0x61, 0xff, 0x30, 0x37, 0x1f, 0x2f, 0x15, 0x9c, 0xa6, 0xa8, 0xcb, 0xfc, 0x0a, 0x92, 0x1a, 0xd8, 0x4c, 0x09, 0xa5, 0x40, 0x65, 0xb6, 0xbd, 0x2b, 0xca, 0xce, 0x72, 0xac, 0xb8, 0xe8, 0x46, 0xd5, 0x9a, 0x7e, 0xf1, 0x5f, 0x60, 0x2c, 0x05, 0xce, 0xb5, 0x71, 0xdd, 0xb8, 0x2f, 0xa8, 0xaa, 0x0e, 0xea, 0x37, 0x86, 0xf5, 0x06, 0x73, 0xae, 0x24, 0x9c, 0x02, 0x9d, 0x36, 0xb7, 0x0b, 0x3f, 0x5e, 0x0f, 0x80, 0xa0, 0xb1, 0xcb, 0x2a, 0x56, 0xe6, 0xa6, 0xac, 0x57, 0xe0, 0x92, 0x8d, 0xee, 0x28, 0x2b, 0x8f, 0xd3, 0x09, 0x67, 0xac, 0x37, 0xa9, 0x2d, 0x5b, 0x67, 0x38, 0xf0, 0xe0, 0x87, 0x8c, 0x6f, 0x05, 0x12, 0xff, 0xd4, 0x72, 0x02, 0x8c, 0x08, 0x05, 0xc3, 0x50, 0x3b, 0xaf, 0x97, 0x5f, 0xa3, 0xa9, 0x39, 0x63, 0xfa, 0x5a, 0x31, 0x32, 0x08, 0xbb, 0x5b, 0xf6, 0xd0, 0xd4, 0xd4, 0xb3, 0xe3, 0xa1, 0x52, 0x74, 0xd7, 0x46, 0xfe, 0x00, 0x88, 0x09, 0xaa, 0xed, 0xa3, 0x7b, 0x6b, 0x88, 0x72, 0x75, 0xf1, 0xdb, 0xc7, 0x8e, 0x49, 0x45, 0xd1, 0x02, 0x8f, 0xc0, 0x52, 0x33, 0x15, 0x9b, 0xd8, 0x5a, 0xb1, 0xf1, 0x61, 0x2a, 0x4a, 0xb0, 0x59, 0x0c, 0x5d, 0x08, 0xa7, 0xc6, 0x62, 0x4f, 0xfe, 0x5d, 0xa9, 0x54, 0xb5, 0xcd, 0xb8, 0x49, 0x7f, 0x62, 0x06, 0xa4, 0x38, 0x90, 0x0f, 0x39, 0x06, 0x3a, 0x52, 0xf1, 0x69, 0xd2, 0x98, 0x23, 0x0c, 0xbd, 0x72, 0x98, 0xf5, 0xf1, 0x12, 0x5e, 0xdf, 0xfc, 0x22, 0x00, 0x9e, 0x4b, 0xc8, 0x12, 0xf3, 0xe4, 0x84, 0xb0, 0x4e, 0xd3, 0xf2, 0xec, 0xf0, 0x11, 0x44, 0x0f, 0xb3, 0x8f, 0x12, 0xbf, 0x92, 0xa9, 0x51, 0x00, 0x00, 0x1b, 0x07, 0xf4, 0x2d, 0xa0, 0xce, 0xa3, 0x2b, 0xa0, 0x4c, 0xa7, 0x07, 0xa2, 0x05, 0x0e, 0xca, 0xd0, 0x1e, 0x85, 0xb9, 0x10, 0x6b, 0x4f, 0x21, 0x7e, 0x11, 0x46, 0x12, 0x64, 0xde, 0x78, 0x02, 0x97, 0xee, 0xe6, 0xfa, 0x1b, 0xa7, 0xe7, 0x77, 0x91, 0x11, 0x07, 0xfe, 0x06, 0x10, 0x8c, 0x8f, 0x4c, 0x3c, 0x72, 0x9d, 0x14, 0x57, 0xb1, 0x93, 0xbf, 0xad, 0x8b, 0xb1, 0x27, 0xfa, 0x0d, 0xdb, 0xae, 0xac, 0x76, 0xd8, 0xed, 0x76, 0x56, 0xb3, 0x2c, 0x5f, 0x56, 0x69, 0x06, 0x27, 0xaa, 0x24, 0x13, 0x71, 0x8d, 0x41, 0x93, 0x4f, 0x70, 0xa1, 0x3b, 0x16, 0xc6, 0xeb, 0x06, 0x20, 0x06, 0x7a, 0xb2, 0x9e, 0x48, 0x3c, 0x41, 0x94, 0xf7, 0x84, 0x41, 0x7d, 0x35, 0x58, 0xfe, 0x26, 0x8c, 0xb5, 0xd3, 0x69, 0x0f, 0x59, 0xf6, 0xf6, 0x36, 0x35, 0xb6, 0xa8, 0x9e, 0xa5, 0xbf, 0xfe, 0x7f, 0x31, 0x92, 0x28, 0x8c, 0xc3, 0x8b, 0x4a, 0x3b, 0x25, 0x9b, 0x2d, 0xdf, 0xc5, 0xfd, 0xa5, 0x45, 0x35, 0xfa, 0x7a, 0xec, 0x30, 0x4d, 0x9e, 0x10, 0x69, 0xf3, 0xa0, 0x10, 0x73, 0x67, 0x94, 0xc9, 0x63, 0x24, 0xe5, 0x46, 0x71, 0x48, 0x29, 0x48, 0x0e, 0xfa, 0xa6, 0xa8, 0xa6, 0x4b, 0x9f, 0xe6, 0x3c, 0xb5, 0x76, 0xa3, 0x4a, 0xc0, 0xeb, 0x34, 0x8f, 0x13, 0x44, 0x5e, 0x83, 0x44, 0x72, 0xd3, 0x99, 0xa1, 0x34, 0x35, 0x9c, 0x3b, 0xfd, 0xb4, 0x6c, 0x3b, 0x58, 0xf7, 0x86, 0xc0, 0x22, 0xa3, 0x02, 0xfc, 0xef, 0x4c, 0x3a, 0xf3, 0x89, 0x5f, 0x31, 0x7f, 0x9f, 0x5d, 0xab, 0x07, 0x0e, 0x8a, 0x0a, 0xed, 0x5d, 0x94, 0x90, 0xea, 0xf5, 0x28, 0x1c, 0x96, 0x3d, 0xd0, 0x3e, 0x5a, 0x6a, 0xef, 0xb4, 0x81, 0x06, 0x3c, 0x29, 0xfc, 0x1d, 0x5c, 0x79, 0x43, 0x91, 0xe0, 0xec, 0x93, 0xdc, 0xa4, 0xed, 0x66, 0xe0, 0xb9, 0xc0, 0x6a, 0x3e, 0x3b, 0x64, 0x39, 0x37, 0x8d, 0xb4, 0x0a, 0xdf, 0x46, 0x0d, 0x3f, 0xdb, 0x1a, 0x37, 0xd5, 0x96, 0x7b, 0x70, 0x09, 0x6d, 0xf8, 0xa5, 0xe0, 0xe8, 0x6e, 0xf3, 0xa4, 0x68, 0x16, 0xa3, 0xc5, 0x3a, 0x06, 0xc5, 0x31, 0x38, 0xa5, 0x15, 0xf2, 0x4d, 0xc3, 0x9f, 0x50, 0x04, 0xc9, 0x67, 0x90, 0x1a, 0x13, 0x8f, 0x48, 0x05, 0xec, 0x1d, 0x71, 0xf2, 0xae, 0x4a, 0x2b, 0x7f, 0x50, 0xef, 0x57, 0x7d, 0x68, 0x31, 0x7f, 0xf5, 0xfd, 0x9f, 0xf0, 0x74, 0x7c, 0x3b, 0xfb, 0x39, 0x33, 0xe9, 0xbb, 0x49, 0xb9, 0x01, 0xd7, 0x32, 0xb5, 0x64, 0x23, 0xb1, 0x83, 0x91, 0x2a, 0xbd, 0x4e, 0xdf, 0x84, 0x3a, 0x55, 0x62, 0x66, 0x9d, 0x16, 0x51, 0xd8, 0x2d, 0xf8, 0x86, 0x21, 0x15, 0x09, 0x00, 0xf1, 0xd2, 0x9f, 0x3b, 0x17, 0x25, 0x60, 0x5f, 0xbe, 0x6e, 0x40, 0x40, 0x58, 0xa3, 0xe3, 0x0b, 0x64, 0x34, 0x00, 0x00, 0x01, 0xba, 0xea, 0xd0, 0xb3, 0x4e, 0x2a, 0x24, 0x44, 0x53, 0xdd, 0x8b, 0x0d, 0x11, 0xf4, 0xb1, 0x4e, 0xe4, 0x56, 0x1b, 0xc1, 0x19, 0x97, 0xca, 0xf7, 0x5f, 0x52, 0x60, 0x22, 0xac, 0xa3, 0x25, 0xcd, 0xbd, 0x5c, 0xb7, 0x93, 0xaa, 0x44, 0x18, 0x08, 0xc8, 0x87, 0xa6, 0x5a, 0x21, 0x2d, 0x37, 0x8c, 0x92, 0xb4, 0xe8, 0xf2, 0x18, 0x97, 0x04, 0x71, 0x9a, 0xda, 0x51, 0x77, 0x05, 0xd7, 0x24, 0xdb, 0x9d, 0x32, 0x46, 0xbf, 0xcd, 0x6a, 0xbd, 0x05, 0xac, 0x29, 0xca, 0x20, 0x95, 0xc9, 0x6a, 0x1f, 0x02, 0x76, 0x11, 0xf6, 0x62, 0x7b, 0x09, 0x85, 0xca, 0x2e, 0x75, 0x09, 0xf9, 0x62, 0x00, 0x3f, 0x9f, 0x2d, 0xbc, 0x8f, 0x36, 0x45, 0xe0, 0x8d, 0xd1, 0xa7, 0xac, 0x32, 0x90, 0x73, 0xde, 0xd7, 0x1c, 0x98, 0xd4, 0xea, 0x97, 0x3c, 0x8b, 0xa2, 0x2a, 0x17, 0xaa, 0xfe, 0xf6, 0x20, 0x05, 0x1a, 0xdd, 0xf3, 0xef, 0xec, 0xa2, 0x2e, 0xc0, 0x57, 0x15, 0x48, 0xa0, 0x1d, 0x8a, 0x2f, 0x37, 0xc0, 0x31, 0xaa, 0x22, 0xb2, 0x1b, 0x13, 0xf4, 0xd0, 0xeb, 0xb6, 0x12, 0xeb, 0x87, 0xd1, 0xa0, 0x49, 0xe2, 0x71, 0x0b, 0x36, 0x91, 0xa2, 0x0b, 0x42, 0x1e, 0x9c, 0xfd, 0x88, 0x55, 0x41, 0x4a, 0x03, 0x05, 0xb9, 0xba, 0xfd, 0x3a, 0x39, 0x44, 0x5e, 0xf6, 0xf4, 0x29, 0x75, 0x67, 0xec, 0xfb, 0xad, 0x97, 0xf6, 0x14, 0x4f, 0xa9, 0xce, 0x6d, 0xb4, 0x6f, 0xa7, 0xec, 0xcd, 0xb8, 0xe8, 0xda, 0x38, 0x6e, 0x12, 0xa5, 0x29, 0xa9, 0x21, 0x08, 0xde, 0x5d, 0x45, 0x5b, 0x07, 0x35, 0xa5, 0xa6, 0x87, 0x55, 0x5e, 0xe8, 0x35, 0xbf, 0xe4, 0x4b, 0xcb, 0x82, 0xa0, 0x40, 0xe9, 0x2c, 0xfa, 0x5b, 0xc0, 0xee, 0xb4, 0x6b, 0xae, 0x1e, 0xeb, 0xa3, 0x2e, 0x94, 0x56, 0x14, 0x08, 0x54, 0x32, 0xcc, 0xcf, 0xa1, 0x66, 0x09, 0x9e, 0xdc, 0xae, 0xcd, 0xb7, 0x59, 0x82, 0x98, 0x55, 0x49, 0x5c, 0x64, 0xd0, 0x20, 0x90, 0x55, 0x8b, 0x68, 0xcf, 0x52, 0x3a, 0x4f, 0x66, 0xcd, 0x45, 0x6c, 0xe6, 0x55, 0xcf, 0xfe, 0x08, 0x05, 0x20, 0xae, 0xd1, 0x75, 0xed, 0x81, 0xf8, 0x07, 0xa1, 0xb7, 0xeb, 0xf4, 0x4b, 0xa2, 0x05, 0x32, 0x15, 0xbe, 0x72, 0x3c, 0x30, 0x93, 0xa1, 0xe8, 0x6a, 0x0c, 0x17, 0xb9, 0x59, 0x9f, 0xcf, 0x40, 0xdf, 0x3b, 0xe2, 0xc6, 0xb5, 0x17, 0x7f, 0xd3, 0x35, 0xdd, 0xcc, 0x90, 0x65, 0x06, 0x3a, 0x87, 0x77, 0xea, 0x45, 0x03, 0xe9, 0xbc, 0x4b, 0xf7, 0xcd, 0x4a, 0x94, 0x95, 0xc0, 0x48, 0xa9, 0xa5, 0xb0, 0x09, 0x3a, 0x2a, 0x9a, 0xf5, 0xda, 0x0b, 0x53, 0xbc, 0xf4, 0x3d, 0x29, 0xb2, 0x91, 0x9c, 0xe4, 0xc4, 0xa0, 0x31, 0xa3, 0xb6, 0x00, 0x00, 0x01, 0x09, 0x00, 0xb7, 0x03, 0xa3, 0xb5, 0xa3, 0x5f, 0x54, 0x42, 0x54, 0x25, 0x60, 0x23, 0x30, 0x0c, 0xfe, 0xe7, 0x82, 0x82, 0x62, 0x90, 0x80, 0x7e, 0x8a, 0x42, 0x04, 0x28, 0x08, 0x05, 0x25, 0x3c, 0x3e, 0xc8, 0xf0, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xe0, 0x06, 0xe6, 0x81, 0xc1, 0x0d, 0xe8, 0xa0, 0x50, 0x98, 0x8e, 0xe2, 0xf9, 0x39, 0xd1, 0xa9, 0x47, 0x6e, 0x97, 0x00, 0x1b, 0x58, 0x50, 0x91, 0xc4, 0x7e, 0x2b, 0xe4, 0x20, 0x64, 0xba, 0x27, 0x9b, 0x42, 0x41, 0x03, 0x96, 0x5e, 0x5c, 0x00, 0x5b, 0x9d, 0x08, 0xbf, 0x25, 0xba, 0xf7, 0x3b, 0xbb, 0xc0, 0xe9, 0x38, 0x77, 0x14, 0x46, 0x4b, 0xca, 0xa3, 0x1c, 0x3f, 0xa9, 0xed, 0x5c, 0x88, 0x99, 0x54, 0x00, 0xeb, 0xe5, 0xb0, 0x23, 0xe5, 0x84, 0x74, 0x29, 0x15, 0xb1, 0x37, 0x2d, 0xf6, 0x5b, 0xa4, 0xf0, 0x63, 0x9d, 0x9c, 0xd4, 0x78, 0x41, 0xfb, 0xd6, 0xf9, 0xf2, 0xb8, 0xe2, 0x0d, 0xc0, 0x32, 0x28, 0x29, 0xc5, 0xa7, 0x7b, 0xec, 0x87, 0x5f, 0x58, 0xdd, 0x8d, 0xb9, 0x47, 0xe9, 0x89, 0x27, 0x86, 0x3e, 0x9e, 0x69, 0x40, 0x15, 0xd6, 0xfc, 0x1a, 0x1c, 0xdb, 0x22, 0xbb, 0xd2, 0xc7, 0x80, 0x25, 0x6a, 0x1a, 0xe1, 0xef, 0x2d, 0x4a, 0xc8, 0xe2, 0xab, 0x48, 0x16, 0x45, 0x04, 0xad, 0x04, 0xb2, 0x63, 0x99, 0xc9, 0x09, 0x3b, 0xa3, 0xda, 0x4b, 0xcd, 0xd0, 0x5e, 0xe0, 0x64, 0x95, 0x8f, 0x48, 0x9a, 0x39, 0x99, 0x43, 0x6d, 0x4c, 0x5d, 0x03, 0xee, 0x15, 0xa2, 0x7a, 0xfa, 0xb2, 0x5f, 0xa1, 0xfe, 0x52, 0x6b, 0xc3, 0x25, 0xf6, 0xc7, 0x5b, 0x48, 0x9d, 0xea, 0xfc, 0xbd, 0xc9, 0x41, 0x8b, 0xbd, 0x3b, 0x29, 0x65, 0x92, 0xc5, 0x9f, 0x03, 0xec, 0xda, 0xa4, 0x61, 0xe3, 0x67, 0x47, 0xaf, 0xd0, 0x4b, 0xe3, 0xa4, 0x01, 0xd2, 0xef, 0x78, 0x29, 0x39, 0xf1, 0xcf, 0xf3, 0x56, 0x82, 0x0c, 0xb0, 0x37, 0x4a, 0xae, 0x48, 0x78, 0xd1, 0x7d, 0x8a, 0xdf, 0x05, 0x70, 0xe5, 0xed, 0x72, 0xe0, 0x22, 0xed, 0x16, 0x4b, 0xee, 0xec, 0x72, 0xf6, 0xb1, 0x54, 0x53, 0x2c, 0x25, 0xcb, 0x26, 0x02, 0xf3, 0x66, 0xf4, 0xec, 0x33, 0x4f, 0x99, 0x1a, 0xce, 0x2d, 0x4b, 0x9d, 0x50, 0x71, 0xd0, 0x1d, 0xf3, 0x06, 0xdb, 0x70, 0xe4, 0x58, 0xf2, 0xde, 0xb0, 0xef, 0x0d, 0xff, 0xfc, 0xe4, 0xe5, 0x0c, 0x36, 0x3a, 0x68, 0xa9, 0x25, 0x13, 0x1f, 0xed, 0xde, 0x39, 0x5e, 0x56, 0x4e, 0x29, 0x78, 0x12, 0x5c, 0x64, 0xff, 0xb2, 0xf7, 0x9e, 0x52, 0x14, 0x2d, 0xdd, 0x7d, 0x5f, 0x14, 0x87, 0xb4, 0x14, 0xa0, 0x58, 0xae, 0xf4, 0x9b, 0x83, 0x17, 0x30, 0x9c, 0xd1, 0x0c, 0x96, 0x55, 0xfb, 0x1d, 0x28, 0xc5, 0x97, 0xcf, 0x67, 0x4c, 0x68, 0x09, 0x33, 0x38, 0x4e, 0x39, 0xcc, 0x48, 0x88, 0xd6, 0xe8, 0x46, 0x95, 0x11, 0x28, 0xca, 0xf4, 0x18, 0xfc, 0xd3, 0x62, 0xea, 0x7e, 0x85, 0x3b, 0x1e, 0xbc, 0x13, 0x99, 0xc0, 0x3c, 0xd4, 0xad, 0x76, 0x8b, 0x54, 0xd4, 0x9b, 0x7c, 0xa7, 0xa1, 0xc8, 0x35, 0x2f, 0xa7, 0xfa, 0x6e, 0xe4, 0x5f, 0xf8, 0x14, 0xe5, 0x02, 0x0e, 0x7b, 0xee, 0x95, 0x21, 0x02, 0x31, 0x83, 0xd1, 0x8b, 0x40, 0x37, 0x54, 0xb4, 0x2d, 0x57, 0xad, 0x6d, 0xac, 0x1e, 0xf7, 0x13, 0x9b, 0x6b, 0xaf, 0xa3, 0x99, 0xa6, 0x06, 0x5e, 0x2d, 0x6b, 0x7c, 0xb7, 0xb0, 0x5f, 0x19, 0x0e, 0x73, 0x48, 0x77, 0xf5, 0x19, 0xb1, 0xa6, 0xec, 0x28, 0xa8, 0xb7, 0x60, 0xf4, 0x59, 0x18, 0x9f, 0xe1, 0x5a, 0x59, 0x60, 0x17, 0xa7, 0xdf, 0x53, 0x54, 0x74, 0x18, 0x50, 0x1a, 0x85, 0xb0, 0xe1, 0xa2, 0x13, 0x58, 0xd3, 0x94, 0x11, 0xa4, 0x8f, 0x63, 0xaa, 0xf0, 0x43, 0xb2, 0x64, 0x7b, 0x4f, 0x05, 0x86, 0xa0, 0xcf, 0xec, 0x4a, 0x93, 0x07, 0xf9, 0xbf, 0x85, 0x8a, 0x47, 0x24, 0x06, 0xf1, 0x56, 0xc4, 0xf3, 0x77, 0xe3, 0xb9, 0x40, 0x10, 0x73, 0x07, 0x68, 0x01, 0xce, 0x35, 0xfc, 0x5a, 0x53, 0x02, 0xfc, 0x99, 0xde, 0xdd, 0xbc, 0x0d, 0xf8, 0x8a, 0xe6, 0x0f, 0x80, 0xaf, 0xbd, 0xb1, 0xb6, 0x4f, 0x1b, 0x7a, 0x4a, 0xc4, 0x85, 0xec, 0xc1, 0x31, 0x36, 0xd7, 0x50, 0x8f, 0x98, 0x14, 0xd2, 0x1f, 0xb3, 0xac, 0x5c, 0xaa, 0x43, 0x07, 0xb0, 0xca, 0x6a, 0x0a, 0x14, 0x39, 0xfa, 0xa1, 0x0a, 0x59, 0xc8, 0xab, 0x50, 0x6a, 0xb7, 0x45, 0xbe, 0x97, 0xe4, 0xf0, 0xd3, 0xde, 0x26, 0x52, 0x55, 0x2f, 0x80, 0xc0, 0x60, 0x13, 0x08, 0xb3, 0x52, 0xbf, 0xac, 0xc0, 0xdd, 0x01, 0xac, 0xb9, 0xc8, 0xd7, 0x85, 0xf1, 0x3e, 0xf1, 0x95, 0xb5, 0x13, 0xc5, 0xc1, 0x99, 0x75, 0xf2, 0x13, 0xf3, 0x1f, 0x3b, 0x0d, 0x5b, 0xa2, 0xa7, 0x53, 0x78, 0xde, 0x12, 0x94, 0xda, 0x47, 0x67, 0xe6, 0x48, 0x9b, 0xb4, 0x0a, 0x24, 0x57, 0x46, 0x44, 0x57, 0x5e, 0x67, 0x56, 0x9c, 0xde, 0x40, 0x8b, 0x2e, 0x7c, 0xe1, 0x8a, 0x55, 0x9f, 0x7d, 0xe0, 0x91, 0xa8, 0xae, 0xbc, 0x00, 0x47, 0x7f, 0x71, 0x36, 0x7b, 0x5c, 0x6d, 0x0e, 0x64, 0xa7, 0x90, 0xf0, 0x21, 0x9c, 0x3d, 0xff, 0xcf, 0x34, 0x70, 0x7c, 0x52, 0x32, 0x79, 0xa6, 0x4d, 0xb3, 0x44, 0xb8, 0x19, 0x89, 0x10, 0x35, 0x19, 0xb7, 0x4e, 0xb5, 0x6e, 0x55, 0xe9, 0x98, 0x1c, 0x55, 0xfe, 0x83, 0xaf, 0xa4, 0xe9, 0x63, 0xa9, 0xa2, 0xd2, 0x30, 0xdb, 0xaf, 0xcb, 0xc3, 0x06, 0x59, 0xc3, 0x67, 0x98, 0x6a, 0xf4, 0xb4, 0x9c, 0x2b, 0x73, 0x97, 0x43, 0x47, 0x37, 0xec, 0x0c, 0xe9, 0x31, 0x8b, 0xf0, 0x2e, 0x6b, 0x50, 0x5f, 0x2f, 0xb4, 0x90, 0xde, 0x70, 0xc7, 0xcb, 0x68, 0x7a, 0x28, 0xa7, 0x78, 0x5d, 0xf2, 0x30, 0x80, 0xdb, 0x34, 0xde, 0xac, 0x78, 0x5a, 0xcd, 0xd8, 0xb4, 0x14, 0x77, 0x47, 0xa4, 0xdd, 0x88, 0xcf, 0x68, 0x86, 0x1b, 0x20, 0xec, 0xb1, 0xb8, 0x03, 0xc4, 0xca, 0x4e, 0x48, 0x34, 0x27, 0x24, 0x79, 0x55, 0x63, 0x9f, 0x39, 0x6c, 0x36, 0x47, 0x75, 0x91, 0x37, 0xaf, 0xb8, 0x96, 0x4e, 0x2d, 0xd3, 0x2d, 0xda, 0x60, 0x32, 0xd1, 0xc1, 0x4b, 0x6d, 0xd4, 0x68, 0xd1, 0x0f, 0x77, 0x27, 0x78, 0x22, 0x2f, 0xb6, 0x65, 0x98, 0xee, 0xd1, 0x9f, 0xa6, 0xa3, 0xeb, 0xe9, 0x12, 0xd3, 0x7a, 0x96, 0x25, 0x32, 0x29, 0xce, 0x70, 0x8b, 0xe5, 0xfc, 0x14, 0x8f, 0xd6, 0x9f, 0x0c, 0x19, 0x0d, 0x45, 0x55, 0x95, 0x5a, 0xcb, 0x97, 0x44, 0x1a, 0x5b, 0x80, 0xac, 0x62, 0xe9, 0xce, 0x14, 0x87, 0x42, 0x44, 0x04, 0x20, 0xc8, 0x88, 0x19, 0x25, 0x3a, 0xeb, 0x84, 0x67, 0x9a, 0xf2, 0x5a, 0x99, 0x3c, 0x28, 0x43, 0xb3, 0xca, 0xac, 0xfe, 0x01, 0x60, 0x91, 0x6f, 0x0d, 0x48, 0xbf, 0xf1, 0x46, 0xb9, 0x06, 0x2a, 0x95, 0xb9, 0x40, 0x6a, 0x8d, 0x9b, 0x1e, 0x61, 0xf3, 0x72, 0x43, 0xd5, 0x58, 0x2d, 0x73, 0x2f, 0x38, 0xc4, 0xc1, 0xd3, 0x15, 0xcf, 0x85, 0x82, 0x42, 0x52, 0x7d, 0x25, 0x29, 0xd0, 0x08, 0xcf, 0xab, 0x0a, 0x27, 0x60, 0x8c, 0xd3, 0xbb, 0x79, 0x73, 0x53, 0xc6, 0xdf, 0x74, 0x77, 0x3e, 0xfe, 0x6a, 0x83, 0x0a, 0x87, 0x45, 0x35, 0x9c, 0xb0, 0x1a, 0xb8, 0x41, 0x92, 0x95, 0xc7, 0x0e, 0xca, 0x0d, 0x4b, 0xf6, 0xf8, 0xf0, 0x97, 0xfc, 0x7b, 0x67, 0xb0, 0xc2, 0xe9, 0x3b, 0x38, 0xbe, 0x0a, 0x3d, 0x41, 0xed, 0x7f, 0x9c, 0x5d, 0xeb, 0x1a, 0xc6, 0x71, 0x06, 0xb4, 0x74, 0xbf, 0x7c, 0x39, 0x2f, 0xd2, 0x9a, 0x56, 0xec, 0xaf, 0x90, 0x0c, 0x57, 0x6e, 0xd7, 0x28, 0x86, 0xf4, 0xd7, 0x4f, 0x48, 0x02, 0xe7, 0xb4, 0xa9, 0xd0, 0x3e, 0x18, 0xe1, 0xc3, 0xdf, 0xf4, 0x99, 0xa6, 0x3b, 0xd1, 0xfe, 0x7f, 0xd3, 0x99, 0xbc, 0x11, 0xaf, 0x22, 0xaa, 0xcf, 0x55, 0x05, 0x45, 0x61, 0x5b, 0x3b, 0x84, 0x31, 0x53, 0x44, 0xab, 0x71, 0x57, 0xc7, 0x69, 0xd8, 0x40, 0xa4, 0x2f, 0x26, 0x3c, 0x7c, 0xc7, 0xfc, 0x61, 0x8b, 0xb3, 0xba, 0x7e, 0xf3, 0x43, 0xed, 0x71, 0xd7, 0x73, 0xa9, 0x36, 0x5d, 0x2f, 0x12, 0xe1, 0xe9, 0x18, 0x5a, 0xca, 0x6a, 0xce, 0x48, 0x54, 0x9b, 0x4c, 0x96, 0x02, 0xa8, 0xa6, 0x23, 0x92, 0x5e, 0xeb, 0x1d, 0xd2, 0x88, 0x50, 0x01, 0xa1, 0x40, 0x2b, 0x31, 0xba, 0xd4, 0x61, 0x8a, 0x4c, 0x22, 0x74, 0x87, 0x99, 0x74, 0x12, 0xff, 0x21, 0x13, 0x43, 0x7f, 0x25, 0x08, 0x8d, 0xf0, 0xdd, 0x47, 0x3a, 0x83, 0x17, 0xb4, 0x33, 0x4d, 0x25, 0xcc, 0xdd, 0x5c, 0xce, 0xed, 0xf4, 0xf1, 0x89, 0x2c, 0x2b, 0x89, 0x9a, 0x39, 0xf4, 0xc3, 0x0c, 0x7f, 0x37, 0x9d, 0xb6, 0xde, 0xdb, 0xb2, 0x3f, 0x01, 0xde, 0x1c, 0xd0, 0xe1, 0xf8, 0x2d, 0xf4, 0xbf, 0x1a, 0x8a, 0x8a, 0xc3, 0x15, 0x04, 0x4e, 0x83, 0x00, 0x06, 0xfd, 0xcb, 0xf4, 0xd1, 0x1c, 0xa7, 0x43, 0x02, 0x75, 0xa6, 0x66, 0x7d, 0x56, 0x60, 0xcc, 0x22, 0x51, 0xa9, 0xf9, 0x13, 0x51, 0x13, 0x89, 0x41, 0xfc, 0x13, 0x24, 0xcb, 0xf5, 0x2c, 0x65, 0x79, 0x7f, 0x7b, 0x6d, 0xa8, 0xdf, 0xee, 0xa2, 0x42, 0xf2, 0xe7, 0x23, 0xfe, 0xc0, 0x67, 0x5b, 0x27, 0x1c, 0x8f, 0x00, 0x3d, 0xe4, 0x37, 0x94, 0x05, 0x2e, 0xb7, 0x03, 0xb9, 0xa7, 0x69, 0xd4, 0xb8, 0xc4, 0x3c, 0xd0, 0x19, 0xc3, 0xf9, 0x78, 0x70, 0xf0, 0x2b, 0x6f, 0x89, 0xec, 0x73, 0xb7, 0xd6, 0xda, 0x55, 0xa5, 0xed, 0x39, 0xe1, 0x84, 0x7f, 0x87, 0x2a, 0x46, 0x3e, 0xa7, 0xa9, 0xcb, 0x04, 0x3e, 0xd2, 0xbf, 0xb2, 0x09, 0x35, 0x36, 0xa0, 0x14, 0xed, 0x51, 0xf8, 0x1d, 0xba, 0x98, 0xdc, 0x4e, 0x37, 0x93, 0x28, 0xc0, 0xda, 0xc9, 0xaa, 0x30, 0x8c, 0x87, 0x47, 0x60, 0xf2, 0xcc, 0xdf, 0xa2, 0xb6, 0xa6, 0xef, 0x1c, 0xa7, 0x02, 0x21, 0x39, 0xc1, 0x07, 0x85, 0xe1, 0x1a, 0x6f, 0xe3, 0xc8, 0xa4, 0x20, 0xb2, 0x8f, 0x7b, 0xfb, 0xfc, 0xe4, 0xc1, 0x9d, 0xaa, 0x10, 0x3d, 0x34, 0x70, 0xcf, 0xdf, 0x4a, 0x77, 0x40, 0x37, 0x0f, 0x81, 0xea, 0x5e, 0x96, 0x9c, 0xaf, 0x16, 0x79, 0x96, 0xb7, 0x0e, 0x5f, 0x1a, 0xc9, 0x97, 0x15, 0x79, 0x7f, 0x8e, 0x63, 0xdb, 0xcd, 0x99, 0xed, 0xdc, 0xf8, 0xbe, 0x82, 0xa6, 0x91, 0xe8, 0xb2, 0x3f, 0x91, 0x4a, 0x85, 0xf3, 0xe6, 0x1e, 0xa3, 0x55, 0x68, 0xdc, 0xe3, 0xaa, 0xe0, 0xf3, 0x20, 0x9e, 0xed, 0x30, 0x2f, 0xfb, 0xf6, 0x7e, 0x4c, 0xf3, 0x4b, 0xe8, 0xbb, 0x7c, 0x02, 0xc8, 0x78, 0x60, 0x4e, 0xe1, 0xe8, 0xe7, 0x5f, 0x0e, 0x66, 0xf1, 0x67, 0x3b, 0x98, 0x0c, 0xc2, 0xf4, 0x81, 0x95, 0xc4, 0x91, 0x94, 0xdf, 0xf9, 0x2e, 0x6d, 0x92, 0xd2, 0xf5, 0xa0, 0xa8, 0x13, 0x84, 0x5c, 0x3f, 0xc5, 0x9e, 0xf1, 0xab, 0xb7, 0x73, 0x16, 0x7b, 0x83, 0xe5, 0xf8, 0xe9, 0xfd, 0xce, 0xa4, 0x32, 0xa5, 0xeb, 0x33, 0x3c, 0x62, 0x14, 0x71, 0x2e, 0xe5, 0xa7, 0xa6, 0xf2, 0x48, 0x98, 0x2e, 0x43, 0xf0, 0xbb, 0xd0, 0xba, 0x26, 0x02, 0xd5, 0x41, 0xba, 0xcf, 0xd3, 0xf0, 0xcd, 0xd1, 0xf2, 0x49, 0xcf, 0x59, 0x30, 0x6a, 0x4c, 0xbf, 0xea, 0xb3, 0x03, 0x0b, 0x59, 0xb4, 0x13, 0x85, 0x03, 0xbe, 0xe2, 0xa1, 0xe3, 0x4c, 0x86, 0x71, 0xc7, 0x21, 0xdd, 0x80, 0xc1, 0x6a, 0x29, 0xda, 0x81, 0xb1, 0x0c, 0xcc, 0xa9, 0x75, 0xa0, 0x0c, 0x1f, 0xf1, 0x6b, 0xd5, 0x04, 0xf1, 0x9e, 0x46, 0x69, 0x07, 0x7b, 0x05, 0x76, 0xbf, 0xe3, 0x9a, 0xb5, 0x03, 0x2f, 0xb8, 0x4d, 0xbc, 0xca, 0x88, 0xa1, 0x06, 0x5b, 0xce, 0x06, 0x52, 0xa6, 0x1d, 0x80, 0x9d, 0x14, 0xca, 0xc0, 0xd8, 0x08, 0x7c, 0x94, 0x75, 0x17, 0x42, 0xd4, 0x1f, 0x6a, 0xca, 0x98, 0xf9, 0x0f, 0x45, 0x34, 0x8a, 0xac, 0xbe, 0x4d, 0x65, 0x7f, 0x4e, 0x9e, 0xd2, 0x2c, 0xc3, 0x75, 0x9e, 0x6f, 0xe9, 0x83, 0xb0, 0x3e, 0x9c, 0xee, 0x7c, 0x52, 0x04, 0x53, 0x59, 0x77, 0x68, 0x5c, 0x8c, 0x10, 0xfb, 0x3a, 0x34, 0x57, 0x22, 0xa2, 0xf0, 0xb1, 0x32, 0x3c, 0x4d, 0x33, 0xf9, 0xd8, 0x7b, 0xed, 0xbc, 0xbc, 0x00, 0xf2, 0x7d, 0x1a, 0xd9, 0x0e, 0x6e, 0xdc, 0x43, 0xa1, 0x7d, 0xa4, 0x1c, 0x72, 0x59, 0xf2, 0x04, 0xb7, 0x4e, 0x9e, 0xe0, 0x03, 0xe7, 0xcd, 0xe7, 0xfe, 0x2c, 0x81, 0x54, 0xc4, 0x48, 0x30, 0x9b, 0x4e, 0x07, 0x85, 0x34, 0x5b, 0xf5, 0xb5, 0x55, 0xb9, 0xb7, 0x36, 0xc8, 0xa2, 0xa7, 0xbb, 0xfd, 0xfd, 0x9b, 0x26, 0x91, 0xa6, 0x37, 0x0a, 0xbf, 0x7f, 0xd5, 0x4d, 0xf9, 0xf3, 0x50, 0x7c, 0x84, 0x63, 0xbe, 0x66, 0x01, 0x5f, 0x37, 0x78, 0xc5, 0x23, 0x93, 0x30, 0xbe, 0x1d, 0x8f, 0x51, 0xa3, 0x87, 0x38, 0x24, 0xb1, 0x36, 0xc6, 0xd5, 0xf3, 0x85, 0x47, 0xf0, 0xef, 0x1f, 0xdb, 0x95, 0xcf, 0x10, 0xb7, 0x10, 0x0c, 0xb5, 0x5d, 0x0a, 0x0d, 0x2a, 0xde, 0xd1, 0x0e, 0xf0, 0x28, 0x53, 0x24, 0x9b, 0xd6, 0x91, 0x79, 0x6e, 0x8f, 0xae, 0x73, 0x3c, 0x86, 0x2e, 0xb8, 0x9b, 0xf2, 0x29, 0xe8, 0xfc, 0x4b, 0x08, 0xd6, 0x81, 0xbb, 0xc3, 0x50, 0xb0, 0x5b, 0x8a, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xe0, 0x06, 0xe6, 0x81, 0xc1, 0x0d, 0x31, 0x00, 0x05, 0xbf, 0x21, 0x11, 0x00, 0x05, 0xb3, 0x65, 0x1e, 0x69, 0xb2, 0x01, 0x00, 0x0e, 0x6b, 0x6b, 0x11, 0xaf, 0x22, 0x52, 0x3f, 0x82, 0x51, 0x0e, 0xd7, 0x03, 0xd4, 0xae, 0x54, 0x10, 0x1e, 0x83, 0x75, 0x11, 0x11, 0xeb, 0xa0, 0xde, 0x5e, 0x24, 0x28, 0x9d, 0x29, 0x11, 0x45, 0xfd, 0x06, 0x89, 0xb8, 0x3a, 0x3d, 0xd5, 0x11, 0xa1, 0xb8, 0xb7, 0x7f, 0x02, 0xf0, 0x1b, 0xcf, 0xbd, 0x27, 0xf3, 0xd9, 0x5a, 0x92, 0xf4, 0x7f, 0x18, 0x4f, 0x61, 0x9a, 0x26, 0x0d, 0xe4, 0x2a, 0x7a, 0xab, 0x21, 0x9a, 0xa5, 0xa0, 0x12, 0x9a, 0x81, 0xab, 0xff, 0x10, 0xdb, 0x43, 0x61, 0x77, 0x7f, 0xe6, 0xc8, 0xb8, 0x96, 0x84, 0xa1, 0x2d, 0x0f, 0x0a, 0xbb, 0x8c, 0x68, 0x83, 0x7b, 0x6b, 0xc0, 0xf8, 0x51, 0xbb, 0x27, 0x2d, 0x70, 0x80, 0x90, 0x71, 0x4e, 0x0e, 0x21, 0x23, 0xe9, 0xb8, 0x6e, 0x49, 0x1f, 0x67, 0xea, 0x01, 0x3d, 0xff, 0xe0, 0xdc, 0xbe, 0xd6, 0x6a, 0x95, 0xcb, 0xda, 0xaf, 0x2b, 0x51, 0xce, 0xba, 0xa4, 0x9f, 0x09, 0x29, 0x8a, 0x20, 0x48, 0xd8, 0xa0, 0x37, 0xed, 0xc8, 0x75, 0xba, 0xc0, 0x01, 0x47, 0x47, 0x15, 0x15, 0xb5, 0xe2, 0x07, 0x7d, 0x89, 0x9d, 0x07, 0x7e, 0xa7, 0xcf, 0xe3, 0xe8, 0xe0, 0xa2, 0xf5, 0x12, 0x2b, 0xc0, 0x79, 0xc6, 0x64, 0xcd, 0xa4, 0x9f, 0xda, 0x2a, 0x39, 0x30, 0x69, 0x07, 0xbe, 0x6d, 0xb5, 0x4a, 0xa4, 0x79, 0x31, 0xef, 0xda, 0x88, 0x65, 0xc6, 0x95, 0x17, 0xfd, 0x0e, 0x13, 0xf2, 0x76, 0x47, 0xb4, 0x64, 0x7e, 0x4f, 0xb4, 0xa5, 0xb5, 0x36, 0xa3, 0x92, 0xa7, 0xc5, 0x3d, 0xfe, 0xb1, 0x64, 0x4a, 0xd6, 0x76, 0x5e, 0x17, 0xf9, 0x01, 0xe1, 0xc5, 0x42, 0x11, 0xf0, 0xcf, 0x96, 0x8f, 0x1c, 0x21, 0x64, 0x8a, 0x14, 0xb4, 0x80, 0xc8, 0x97, 0x31, 0x04, 0xff, 0xce, 0x5e, 0xc0, 0x10, 0xf7, 0xf2, 0x09, 0x80, 0x6f, 0x05, 0xc3, 0x44, 0xdc, 0xa7, 0xfe, 0x2f, 0x47, 0x43, 0xcc, 0xc7, 0xf9, 0xdf, 0x0f, 0xe4, 0x23, 0xdc, 0x44, 0xc5, 0xd8, 0x32, 0x5d, 0x8b, 0xda, 0x51, 0xf7, 0x34, 0xc7, 0xc1, 0xc8, 0xdd, 0x79, 0x18, 0x68, 0xb2, 0x33, 0xa5, 0x85, 0xec, 0xa2, 0x5f, 0xf8, 0x21, 0xf5, 0x4c, 0xb6, 0xb4, 0xd4, 0xdf, 0xaa, 0x7a, 0x93, 0x1b, 0x83, 0x26, 0x11, 0x06, 0xdb, 0x45, 0x65, 0x83, 0xb7, 0xe2, 0xba, 0xc9, 0x02, 0x4a, 0x29, 0x0f, 0xa7, 0x74, 0x3a, 0xd7, 0x8f, 0x23, 0xfa, 0x90, 0x29, 0x27, 0xf9, 0xa9, 0x13, 0x0b, 0x2d, 0x3d, 0x6c, 0xbe, 0xd4, 0xa0, 0xbc, 0x37, 0x28, 0x7f, 0x69, 0x82, 0x2f, 0xa7, 0x4d, 0x22, 0x87, 0x9f, 0xa7, 0x96, 0x6c, 0x93, 0xaa, 0x91, 0xe9, 0x1d, 0x36, 0x9c, 0x87, 0x7e, 0x27, 0x7f, 0x13, 0x59, 0xea, 0x3d, 0xcb, 0xe4, 0xe3, 0x56, 0x31, 0xb0, 0x9a, 0xfb, 0xc1, 0xe8, 0xe6, 0xf3, 0x10, 0x62, 0x80, 0x8b, 0x53, 0x1d, 0xe0, 0x1d, 0xc5, 0x44, 0x59, 0xb1, 0x29, 0xe2, 0x0c, 0x24, 0x37, 0xad, 0x7a, 0xd6, 0x7c, 0xb2, 0x68, 0xf6, 0x00, 0xa4, 0x30, 0x22, 0x0a, 0xd9, 0x06, 0xf5, 0xd2, 0x36, 0x0a, 0x27, 0x90, 0x11, 0x2b, 0x17, 0x6f, 0x22, 0x77, 0x6f, 0x19, 0x91, 0x73, 0x24, 0xfd, 0x42, 0x1f, 0x1d, 0x20, 0x8b, 0x45, 0x76, 0x35, 0x10, 0xcb, 0x21, 0x9f, 0x6d, 0x01, 0xd7, 0xda, 0x1c, 0xbd, 0x98, 0x0d, 0x19, 0x8b, 0x4a, 0x5b, 0x3d, 0x99, 0x73, 0x98, 0x7d, 0x7e, 0xac, 0xeb, 0x5b, 0xad, 0x97, 0xd1, 0xbc, 0x6f, 0x60, 0xed, 0x05, 0xe5, 0xa6, 0xa8, 0xda, 0x87, 0x34, 0x22, 0xad, 0x6d, 0xd9, 0x71, 0x3c, 0xc0, 0xce, 0x25, 0xef, 0xcd, 0x30, 0x54, 0x6d, 0xc5, 0xd4, 0xf7, 0x37, 0x89, 0x78, 0x89, 0x41, 0x0b, 0x65, 0xaa, 0x7b, 0x1b, 0xe0, 0xe7, 0x14, 0x0d, 0xe7, 0x24, 0xe4, 0x73, 0xa6, 0xd4, 0x06, 0xd2, 0x7a, 0x36, 0x44, 0xfe, 0xfd, 0xb8, 0x8f, 0xd9, 0x45, 0xc6, 0xb2, 0x35, 0x82, 0xdc, 0x1c, 0xf5, 0x9b, 0x2a, 0x4f, 0x30, 0xa0, 0xb6, 0x27, 0xc6, 0x93, 0x95, 0x35, 0x00, 0x2f, 0xfe, 0xab, 0x6f, 0xc6, 0x9d, 0xa3, 0x1e, 0x31, 0xe6, 0xd9, 0x7f, 0x53, 0x5d, 0x14, 0x56, 0xb2, 0x79, 0xf9, 0x06, 0xd9, 0x9e, 0x6a, 0x1d, 0x39, 0xba, 0x40, 0x26, 0xa1, 0xae, 0xf8, 0x57, 0xaf, 0x45, 0xad, 0x54, 0x31, 0x0c, 0x4a, 0xb0, 0xdd, 0x8c, 0xc2, 0xa3, 0x9b, 0x10, 0xe9, 0x67, 0x0f, 0x25, 0x5b, 0x53, 0x12, 0x0a, 0xda, 0x90, 0x7f, 0x62, 0x01, 0xba, 0x03, 0xd0, 0x6a, 0x61, 0x19, 0x88, 0x18, 0x0f, 0xe5, 0x7f, 0xec, 0x0e, 0x49, 0x25, 0x16, 0x0e, 0x9a, 0xd1, 0x3d, 0xf7, 0x5f, 0xfb, 0x92, 0x27, 0x85, 0x68, 0x9a, 0xbb, 0xf2, 0xc6, 0x98, 0xa2, 0xf2, 0x3b, 0xb5, 0x9f, 0xfe, 0x5f, 0x9d, 0x6e, 0xb6, 0xc4, 0x1e, 0xcc, 0xbd, 0x4c, 0x10, 0x24, 0xe1, 0x03, 0xf9, 0x7f, 0x7f, 0x3f, 0xb2, 0xe1, 0x63, 0x28, 0xfd, 0x8c, 0x2b, 0xff, 0xa7, 0xf9, 0x05, 0xc9, 0xd3, 0x92, 0xfd, 0xf8, 0x2f, 0x48, 0x0d, 0xa2, 0x9f, 0xb3, 0x23, 0xfe, 0xae, 0x95, 0x1d, 0x6e, 0xa6, 0xd8, 0xe1, 0x1a, 0x9f, 0xd7, 0x98, 0x34, 0x5e, 0x97, 0x26, 0xd1, 0xfe, 0x2e, 0xbb, 0xe2, 0x39, 0xa8, 0x09, 0xec, 0xcb, 0xb2, 0x07, 0xf1, 0x83, 0xf4, 0x5e, 0x1d, 0xa9, 0x0c, 0xa4, 0x8f, 0xa4, 0x7e, 0xba, 0x09, 0x30, 0xb0, 0x20, 0x1e, 0x23, 0xb6, 0x45, 0x1b, 0x6f, 0x44, 0x39, 0x3b, 0x28, 0xf0, 0xca, 0xe1, 0xf1, 0xc3, 0x4e, 0x6c, 0xb0, 0x57, 0xcf, 0x4f, 0xb5, 0x7a, 0x1b, 0xce, 0x45, 0x67, 0xd3, 0x36, 0xc7, 0x41, 0x84, 0x01, 0xb5, 0x57, 0xab, 0x0f, 0x34, 0xe0, 0xb8, 0x2c, 0xfe, 0xb2, 0x2f, 0x70, 0x9a, 0x5c, 0xbe, 0x7b, 0xc3, 0xdc, 0x6c, 0x9e, 0x76, 0xf2, 0xa2, 0xf6, 0x76, 0xbe, 0xb0, 0x70, 0x44, 0x77, 0x17, 0x69, 0x55, 0x7e, 0x85, 0xc5, 0xd7, 0x09, 0x55, 0x5a, 0x7f, 0x9b, 0xf3, 0x6a, 0xfa, 0x1e, 0x37, 0xad, 0xac, 0xe8, 0x75, 0x22, 0x32, 0xe8, 0x5c, 0xfc, 0x11, 0xf7, 0xb2, 0x5b, 0xce, 0xb7, 0x3b, 0x90, 0xaf, 0xec, 0xe2, 0x14, 0x1c, 0xdd, 0x56, 0x2e, 0xaf, 0x00, 0x24, 0x8c, 0x46, 0x64, 0x60, 0x51, 0x55, 0x1f, 0x62, 0xf5, 0x1c, 0x20, 0x11, 0x0a, 0x3a, 0x2c, 0x5c, 0xf1, 0x21, 0x04, 0x2e, 0x6a, 0x61, 0xc2, 0x11, 0x27, 0x1e, 0xf3, 0xfc, 0x26, 0x5a, 0x9f, 0x52, 0x02, 0xd4, 0x3a, 0xd8, 0x6d, 0xca, 0x4e, 0x34, 0x2a, 0x36, 0x41, 0xd3, 0x29, 0x71, 0xf7, 0x8c, 0xdb, 0x6d, 0x76, 0x3b, 0x1f, 0xfa, 0x3b, 0x83, 0xeb, 0x56, 0xcc, 0x46, 0x57, 0x43, 0x5e, 0x24, 0x2d, 0x6a, 0xb1, 0x42, 0xb8, 0x14, 0xe4, 0xdd, 0xc6, 0xed, 0xb0, 0x93, 0xc7, 0xbf, 0x1c, 0xcc, 0xc3, 0x0c, 0x5c, 0x32, 0x42, 0x73, 0xca, 0x71, 0x39, 0x5b, 0xfa, 0x8e, 0x8f, 0x28, 0xba, 0xa8, 0x69, 0xdc, 0xe7, 0x08, 0xa1, 0x8f, 0xdf, 0x6f, 0x3f, 0xb3, 0x8f, 0xc0, 0x86, 0xfb, 0xf7, 0xb2, 0x55, 0xd5, 0x77, 0x48, 0x27, 0x60, 0xdb, 0x12, 0x6f, 0x32, 0xc2, 0x4d, 0xd3, 0xbc, 0x34, 0xf4, 0xb4, 0x28, 0xf4, 0x90, 0xab, 0x78, 0x4d, 0xc8, 0x9f, 0x34, 0x4a, 0x66, 0x2c, 0x57, 0x73, 0xac, 0xde, 0x00, 0xc2, 0x23, 0x29, 0xd7, 0x47, 0x52, 0xc6, 0x36, 0x4d, 0xba, 0xbc, 0xce, 0x6c, 0xe6, 0xf2, 0xa2, 0x05, 0x59, 0x32, 0x99, 0x18, 0x38, 0xd4, 0x1b, 0x02, 0x03, 0x99, 0x06, 0xbe, 0x77, 0x42, 0xa0, 0x22, 0x2d, 0x01, 0x41, 0x58, 0x4b, 0x58, 0x7a, 0x0e, 0xf8, 0x94, 0x53, 0xe5, 0x24, 0xe5, 0xec, 0x23, 0x6b, 0x88, 0x65, 0xd3, 0x4e, 0xb9, 0xe9, 0x26, 0xab, 0x0b, 0x4f, 0xfb, 0xb3, 0x2d, 0x30, 0x7e, 0x27, 0x6d, 0x22, 0xd7, 0x06, 0x34, 0x35, 0xf4, 0x8b, 0x7f, 0xe0, 0x38, 0xc2, 0xbb, 0x30, 0xc9, 0x0d, 0xbe, 0x57, 0xcd, 0x5c, 0xa2, 0x48, 0x91, 0x9b, 0x11, 0x03, 0x65, 0xb1, 0x18, 0x81, 0x84, 0x56, 0x20, 0x54, 0xfc, 0x86, 0xc0, 0x6e, 0x7c, 0xdf, 0x59, 0x01, 0x67, 0x0e, 0x1d, 0x44, 0x21, 0xf7, 0xb4, 0xf4, 0xcc, 0x44, 0xb7, 0xf7, 0x27, 0xd7, 0xd4, 0xde, 0x82, 0xba, 0xac, 0xd2, 0x6c, 0x7d, 0x70, 0x79, 0x76, 0xf7, 0x56, 0x12, 0xf6, 0x69, 0x7c, 0x1c, 0x08, 0x98, 0x84, 0x90, 0x3e, 0x8d, 0x7f, 0x81, 0x2a, 0x65, 0xe4, 0x08, 0xc2, 0xb7, 0x84, 0x15, 0x92, 0x14, 0x70, 0xc9, 0xb3, 0xaf, 0x2c, 0x21, 0x32, 0x9d, 0x99, 0x60, 0xed, 0xf7, 0x81, 0x48, 0x41, 0x57, 0x51, 0xfb, 0x34, 0x26, 0x98, 0x8e, 0x21, 0x28, 0x29, 0xb9, 0x5c, 0xf3, 0x3b, 0x3b, 0x92, 0x49, 0x01, 0xd4, 0x71, 0x92, 0x39, 0x2a, 0x1a, 0xda, 0x2c, 0xa0, 0x2b, 0xed, 0xba, 0xe2, 0xb4, 0x27, 0x1f, 0x6a, 0x7c, 0x9b, 0xe9, 0xf7, 0x8a, 0x50, 0xc5, 0xc8, 0x89, 0xb4, 0xfe, 0x50, 0x46, 0x5b, 0xae, 0x52, 0x03, 0x52, 0x87, 0xcf, 0x2e, 0x31, 0x39, 0xa8, 0x16, 0xa6, 0xee, 0x39, 0x12, 0x55, 0x3c, 0xc7, 0xec, 0xba, 0x63, 0x14, 0xc8, 0x15, 0xa5, 0xae, 0x1f, 0x7e, 0x31, 0xb8, 0x05, 0xf7, 0xb8, 0xf3, 0x72, 0xb0, 0xe6, 0x6b, 0x63, 0x0e, 0x18, 0x5c, 0x87, 0xde, 0x18, 0x83, 0xc6, 0xb4, 0x44, 0x7c, 0xcc, 0x19, 0xdc, 0x63, 0x1d, 0x87, 0x9b, 0x39, 0xd5, 0x07, 0x90, 0xf0, 0x7b, 0x22, 0x7e, 0x72, 0x17, 0xe0, 0x6a, 0x87, 0x6f, 0xf3, 0x42, 0x62, 0x17, 0x84, 0x23, 0x63, 0xc0, 0xf4, 0x9a, 0x05, 0x63, 0x37, 0xae, 0x97, 0xf0, 0x33, 0xe0, 0x40, 0xc5, 0x2c, 0x27, 0x4e, 0x5a, 0xf3, 0x88, 0xab, 0xe8, 0x35, 0x84, 0x59, 0x50, 0xeb, 0x03, 0xab, 0x3a, 0x9e, 0xe9, 0x50, 0xf7, 0x54, 0x04, 0xb5, 0x9b, 0xf2, 0x75, 0xbd, 0xad, 0x03, 0xca, 0xce, 0x94, 0x79, 0x7c, 0x78, 0x4b, 0x0b, 0xd0, 0x3d, 0xfb, 0x99, 0xd3, 0x71, 0x35, 0x10, 0x4c, 0x29, 0xbd, 0xee, 0xcb, 0x16, 0xd8, 0xdc, 0x41, 0xb4, 0x81, 0xe3, 0xd9, 0x3a, 0xf8, 0x2f, 0x5c, 0xb4, 0x58, 0xb5, 0xf8, 0x55, 0x73, 0x56, 0xa2, 0x68, 0x8f, 0xb4, 0xe1, 0xe5, 0x5c, 0xbc, 0xe8, 0xad, 0x78, 0x72, 0x6e, 0x7d, 0x1e, 0xed, 0x4d, 0x1f, 0xa4, 0x95, 0x5d, 0x3b, 0x96, 0x3e, 0x8c, 0x2c, 0x2e, 0x7a, 0x34, 0x0d, 0xb2, 0xd7, 0x94, 0x44, 0x75, 0x92, 0x2d, 0xa3, 0x80, 0x49, 0x5f, 0x58, 0x2d, 0x08, 0x63, 0x50, 0x98, 0x59, 0x14, 0xe7, 0xf0, 0x0c, 0xb3, 0xb9, 0x38, 0x43, 0xaf, 0x93, 0x22, 0x2f, 0x73, 0x0a, 0xed, 0xd2, 0xdc, 0xe8, 0xdf, 0x02, 0x4b, 0xfe, 0x55, 0xda, 0x37, 0xfe, 0x4c, 0xb4, 0xce, 0x8f, 0x23, 0xb8, 0x2d, 0x1d, 0xde, 0x3b, 0x07, 0x48, 0x39, 0xee, 0x80, 0x36, 0x9f, 0x54, 0xfb, 0x99, 0xfe, 0xad, 0xac, 0x30, 0x08, 0x8e, 0x96, 0xdd, 0xca, 0x51, 0xd0, 0x69, 0xbd, 0x5d, 0xec, 0x34, 0x33, 0x41, 0xa9, 0x62, 0xbd, 0xac, 0x86, 0x83, 0x3e, 0xb9, 0x11, 0x2d, 0x35, 0xa8, 0xac, 0xba, 0x8c, 0xd2, 0xfe, 0x6c, 0xdf, 0xc5, 0xf6, 0x6b, 0xd8, 0x90, 0xc6, 0x9c, 0x6f, 0xf3, 0x49, 0x5d, 0x44, 0x89, 0xc7, 0x74, 0xdb, 0xe4, 0xf5, 0x7c, 0xe1, 0x82, 0x23, 0x74, 0x53, 0xf7, 0xa1, 0x22, 0xbf, 0xc0, 0xb7, 0xaf, 0xb6, 0xdf, 0x47, 0x15, 0x81, 0x64, 0x1c, 0xca, 0x21, 0xb9, 0x78, 0xa8, 0x70, 0x1d, 0x43, 0xdd, 0x54, 0xda, 0xd8, 0x51, 0xb9, 0xc8, 0x02, 0x7f, 0xe0, 0xaa, 0xd1, 0x35, 0x6c, 0x66, 0x2b, 0xff, 0x64, 0x5f, 0x82, 0xca, 0xd2, 0x09, 0xb8, 0x95, 0x23, 0xd5, 0x32, 0x31, 0xef, 0x30, 0xa3, 0x3b, 0x4d, 0xe5, 0xe2, 0x04, 0x07, 0xb6, 0x09, 0x1e, 0x4f, 0x87, 0xb8, 0x7e, 0xae, 0x34, 0x62, 0xe3, 0x73, 0x5c, 0xa8, 0x67, 0x76, 0x9f, 0xd2, 0xf5, 0x08, 0x36, 0x5a, 0x15, 0x42, 0x77, 0x54, 0x7f, 0x38, 0x54, 0x33, 0x11, 0xda, 0xf4, 0x96, 0x3e, 0x41, 0xcf, 0xe8, 0x59, 0x47, 0xb5, 0xd2, 0x77, 0x69, 0xf2, 0x7e, 0xd9, 0x12, 0x1c, 0xfa, 0x3f, 0x67, 0xc3, 0x12, 0x1e, 0x8d, 0x94, 0xa3, 0x5e, 0x8c, 0x5c, 0x89, 0x0d, 0xe6, 0xf4, 0x18, 0xeb, 0x8b, 0x03, 0x97, 0xd7, 0x3f, 0xb1, 0xda, 0x8d, 0x76, 0x2c, 0x04, 0x86, 0xd1, 0x20, 0xbf, 0x93, 0xa5, 0x79, 0xb3, 0xe2, 0x33, 0x22, 0xef, 0x14, 0x59, 0x03, 0x03, 0x7a, 0x05, 0xed, 0x30, 0x2c, 0x76, 0xf1, 0x12, 0x00, 0x5f, 0x0c, 0x13, 0xc0, 0xef, 0x79, 0xd6, 0xb6, 0x19, 0xa0, 0xb3, 0xc8, 0xf7, 0xbf, 0x29, 0xc7, 0x78, 0xcf, 0x6a, 0x39, 0x04, 0x1e, 0x78, 0x78, 0xbf, 0x52, 0xc1, 0x56, 0xfd, 0xd1, 0x2c, 0xcf, 0xe2, 0xb8, 0x6c, 0x2a, 0xbc, 0xdb, 0x57, 0xec, 0xba, 0x83, 0xaa, 0x07, 0xb4, 0xd4, 0x11, 0xe2, 0xbf, 0xa7, 0x24, 0x79, 0x3b, 0x84, 0x8c, 0x05, 0x4d, 0x94, 0xaf, 0x7a, 0x0d, 0x96, 0xc5, 0x00, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xe0, 0x06, 0xe6, 0x81, 0xc1, 0x0d, 0x08, 0x5c, 0x89, 0xee, 0xed, 0x68, 0xbf, 0x74, 0xa2, 0x2c, 0x63, 0x0a, 0x80, 0x00, 0x01, 0x00, 0x25, 0x9f, 0xe4, 0x7b, 0xd4, 0xac, 0x7c, 0x3f, 0x34, 0xd5, 0xc5, 0xca, 0x11, 0xd2, 0xef, 0xbf, 0x83, 0xf5, 0x1e, 0x60, 0x48, 0x26, 0x6e, 0x5a, 0xe3, 0x03, 0xe5, 0x7e, 0xa4, 0xee, 0x66, 0xbb, 0x68, 0xcb, 0x37, 0x3a, 0x38, 0x3b, 0x0f, 0x99, 0x78, 0xa7, 0x2c, 0x99, 0x9c, 0xc3, 0xa6, 0xc5, 0x97, 0x72, 0x0e, 0x27, 0x48, 0xce, 0xe6, 0x5e, 0x98, 0xd0, 0xb2, 0xce, 0x4f, 0xf3, 0xff, 0xe7, 0x80, 0x16, 0xb9, 0x0a, 0x4f, 0xcc, 0x5c, 0xc6, 0x05, 0x48, 0xd2, 0xfa, 0x56, 0x3b, 0x7e, 0xe8, 0x8c, 0x67, 0x6a, 0xb0, 0x86, 0x95, 0x56, 0x86, 0x94, 0x7b, 0xac, 0x41, 0xef, 0xdf, 0x25, 0xcf, 0xc3, 0x91, 0xc7, 0x8e, 0xfb, 0xde, 0xca, 0x7b, 0xe5, 0x0c, 0x6d, 0x72, 0x27, 0xad, 0x5e, 0xd0, 0x57, 0x20, 0x99, 0x62, 0x02, 0x13, 0x26, 0x28, 0x1f, 0xc8, 0x38, 0x49, 0xcd, 0x80, 0xe6, 0x50, 0xea, 0xcd, 0x4c, 0xe9, 0x71, 0xfa, 0xca, 0xfd, 0xbd, 0xb1, 0xc5, 0x42, 0x31, 0x04, 0xa4, 0x79, 0x92, 0x55, 0xdf, 0x08, 0x8d, 0x42, 0x9d, 0xd6, 0x3c, 0x38, 0x0c, 0x5f, 0x3d, 0xf9, 0x0d, 0x41, 0xc4, 0xc5, 0xf7, 0x41, 0x9f, 0x37, 0x05, 0xc3, 0x94, 0xa6, 0x45, 0xbe, 0x9e, 0x32, 0x07, 0x64, 0x71, 0x2d, 0x04, 0x4c, 0x36, 0x89, 0xd3, 0xbc, 0x36, 0xfb, 0x40, 0x9c, 0x4f, 0x74, 0x34, 0xd1, 0x44, 0x75, 0x34, 0x3c, 0xf2, 0x2c, 0x89, 0x02, 0xe2, 0xc3, 0xb7, 0xcd, 0x37, 0x39, 0xa6, 0xf1, 0x5a, 0x84, 0xff, 0xfe, 0xbb, 0xd2, 0x50, 0xa8, 0x71, 0x16, 0xc7, 0xf1, 0x37, 0x4f, 0xc5, 0x2b, 0x14, 0x56, 0x7d, 0xd2, 0x94, 0xa3, 0x57, 0x36, 0xb0, 0xe6, 0x40, 0x6b, 0xa6, 0xbb, 0x43, 0xe9, 0x08, 0x41, 0x07, 0x65, 0x96, 0x7c, 0x60, 0xaa, 0x6d, 0x9b, 0xc6, 0x22, 0x56, 0x93, 0x55, 0x08, 0x60, 0x21, 0xa9, 0xd4, 0xda, 0x4d, 0x53, 0x05, 0x4f, 0xf1, 0x30, 0x06, 0xc4, 0x19, 0xa4, 0xc8, 0x2e, 0xd5, 0x82, 0xca, 0x79, 0xff, 0xea, 0x4f, 0x4f, 0xd4, 0xf7, 0x40, 0x84, 0x2e, 0x00, 0x23, 0xc6, 0x0a, 0xd8, 0xfc, 0xb8, 0x58, 0xd8, 0x71, 0xf6, 0xb0, 0xbc, 0x77, 0x7a, 0x12, 0xf2, 0xbe, 0xb1, 0xdb, 0x7f, 0xe4, 0xde, 0x2e, 0x49, 0x19, 0xb4, 0xc6, 0xee, 0xa0, 0x07, 0x51, 0x96, 0x81, 0xa1, 0xc2, 0x05, 0xac, 0xb5, 0x1d, 0x58, 0xc0, 0xba, 0x11, 0xb7, 0x93, 0xbf, 0x32, 0xd3, 0x0c, 0xb3, 0x0a, 0xbe, 0x96, 0xc7, 0x89, 0xfc, 0x89, 0x80, 0x4f, 0x59, 0x2a, 0xf8, 0xf4, 0x7d, 0x2c, 0x27, 0xf9, 0x3b, 0x6e, 0xc7, 0xc0, 0x86, 0x68, 0x08, 0xe8, 0x7f, 0x69, 0x22, 0xab, 0xe3, 0x1d, 0x1e, 0x5d, 0x2d, 0x0a, 0xd9, 0x40, 0x0b, 0x3d, 0x62, 0x18, 0xac, 0xf0, 0x77, 0x89, 0xd1, 0x96, 0x12, 0xdb, 0x07, 0xc5, 0x7e, 0xa3, 0xf5, 0x59, 0xcb, 0xd7, 0xae, 0x1d, 0x91, 0xf9, 0xb8, 0x62, 0xf4, 0x5f, 0x95, 0x79, 0x2f, 0x3c, 0x2e, 0x53, 0xb5, 0x85, 0xe0, 0x60, 0x68, 0x5b, 0x30, 0xf3, 0xa7, 0xd9, 0xc0, 0x69, 0x4b, 0xf7, 0x80, 0x5b, 0x52, 0x3d, 0xf8, 0x82, 0x9e, 0x08, 0xfb, 0xfe, 0x1d, 0x19, 0xc9, 0xd0, 0xb6, 0xaf, 0x56, 0x55, 0xd4, 0x92, 0x3b, 0x74, 0x5b, 0x71, 0x4b, 0x59, 0x36, 0xed, 0x8b, 0x40, 0xb8, 0xd6, 0xd2, 0x84, 0x49, 0x86, 0x29, 0x3d, 0x7e, 0xb7, 0x54, 0xdc, 0x87, 0xf8, 0xc9, 0x05, 0x8a, 0xef, 0x58, 0x80, 0x6b, 0xa3, 0x93, 0x04, 0x85, 0x7c, 0x88, 0xbf, 0x7b, 0xba, 0x22, 0xa5, 0x7f, 0x6f, 0xd3, 0x3e, 0xa2, 0x10, 0x8c, 0x7d, 0x7c, 0x93, 0x72, 0xb4, 0xb0, 0xed, 0xd7, 0x5e, 0xd4, 0x7c, 0x6b, 0x2b, 0x56, 0xca, 0x72, 0x14, 0xbd, 0xef, 0xe9, 0xb5, 0xa8, 0x49, 0x96, 0x62, 0x08, 0x09, 0x2c, 0xdd, 0xe7, 0xc7, 0x93, 0x7c, 0x58, 0x0b, 0x39, 0x94, 0x4b, 0xac, 0x82, 0x88, 0x3a, 0x99, 0x17, 0x21, 0xad, 0x27, 0x9a, 0xb4, 0x30, 0x72, 0x88, 0x4c, 0x17, 0x42, 0xe8, 0x34, 0xb9, 0xcb, 0x0d, 0xc8, 0x16, 0x18, 0xde, 0x70, 0xdd, 0xdf, 0x95, 0x36, 0xd1, 0x95, 0x98, 0x69, 0x42, 0x84, 0x11, 0xfa, 0xd1, 0xee, 0x17, 0xe5, 0x3d, 0xdc, 0x85, 0x6d, 0x05, 0xfe, 0x8c, 0x80, 0x48, 0x8e, 0x8a, 0xdc, 0xe7, 0x67, 0x16, 0x81, 0xeb, 0xfc, 0xae, 0x00, 0x3f, 0x23, 0xdc, 0xd1, 0x75, 0x12, 0x7c, 0x70, 0x71, 0xb6, 0x4b, 0xdd, 0xc8, 0x1e, 0x2f, 0x28, 0x62, 0x53, 0x72, 0xfe, 0x9e, 0x07, 0xe4, 0x5e, 0x23, 0x1a, 0xb5, 0xf0, 0xd9, 0xd7, 0xcb, 0x21, 0x22, 0xa8, 0x2b, 0x48, 0x46, 0xed, 0x96, 0xfc, 0x01, 0x65, 0x91, 0xe4, 0x5b, 0xd9, 0x9d, 0xdd, 0x74, 0x0c, 0x49, 0x11, 0x16, 0x60, 0x08, 0x14, 0x95, 0x88, 0x4f, 0x2a, 0xb6, 0x1a, 0x7a, 0x1c, 0x15, 0x79, 0xd2, 0x7e, 0xbc, 0xa3, 0x4f, 0x58, 0xd8, 0xa9, 0x85, 0xf4, 0xf5, 0x78, 0x72, 0x78, 0xd5, 0xcd, 0x61, 0x24, 0xef, 0x3b, 0xcf, 0x88, 0xa9, 0x86, 0xd5, 0xea, 0x8e, 0x66, 0xbb, 0x9d, 0x68, 0xd4, 0xca, 0x8a, 0x9b, 0x71, 0x31, 0x7c, 0x30, 0x9d, 0xb3, 0x33, 0xc4, 0xfd, 0xfb, 0x5d, 0xae, 0xe5, 0x8f, 0x63, 0xcd, 0xa0, 0x09, 0x5d, 0x8d, 0x63, 0xf3, 0xba, 0xa1, 0x80, 0xa5, 0xe3, 0x53, 0x84, 0x2c, 0x37, 0x4f, 0xf1, 0x82, 0xb6, 0x3a, 0x74, 0x12, 0xc3, 0xc2, 0x76, 0x3d, 0x2e, 0x87, 0x8b, 0xd6, 0x47, 0x38, 0x8b, 0x04, 0x19, 0x74, 0x86, 0xc5, 0x0e, 0xd0, 0x8c, 0xd4, 0x2c, 0xeb, 0x75, 0xfc, 0xa6, 0xaf, 0x3e, 0xdf, 0xac, 0x41, 0x17, 0x69, 0x91, 0x16, 0x73, 0xe0, 0x0e, 0xdc, 0x4b, 0x41, 0xa3, 0x7a, 0x72, 0x2c, 0xaa, 0xa7, 0xb6, 0x10, 0x3f, 0x51, 0x8c, 0xfe, 0xdb, 0x64, 0x2b, 0x3f, 0xee, 0xca, 0x94, 0x74, 0x13, 0x53, 0xa3, 0xa8, 0x8f, 0x5f, 0x6b, 0x4e, 0xbd, 0x8c, 0xc9, 0xd2, 0x9f, 0x4f, 0x01, 0xf0, 0xec, 0xdd, 0x4b, 0x77, 0x01, 0xd8, 0x7f, 0x16, 0x37, 0xec, 0xbf, 0xee, 0x54, 0xcc, 0xf0, 0x8d, 0xb0, 0x34, 0xc6, 0x31, 0x2d, 0xea, 0x07, 0x31, 0xe8, 0xdd, 0x45, 0x9b, 0x35, 0x47, 0x56, 0xe4, 0x61, 0x2f, 0xfe, 0x45, 0xdf, 0xde, 0xe8, 0x59, 0x25, 0x75, 0x75, 0xef, 0x69, 0x66, 0x33, 0x89, 0x9e, 0x2b, 0x8a, 0x44, 0x04, 0x6a, 0x81, 0x50, 0xad, 0x78, 0x39, 0xad, 0x16, 0x3e, 0x21, 0xd6, 0xbd, 0x98, 0x7e, 0x58, 0x25, 0xf5, 0x31, 0x3f, 0xcc, 0xce, 0xd0, 0x7d, 0x62, 0xe2, 0x2b, 0x3e, 0xe5, 0xec, 0xe3, 0x3b, 0xb5, 0x3d, 0x34, 0xc7, 0xf8, 0x64, 0x4b, 0x8c, 0xa2, 0xd8, 0x28, 0x32, 0xaa, 0xa7, 0x16, 0x55, 0xd8, 0xe8, 0x44, 0x20, 0x90, 0xc8, 0xb1, 0x7c, 0xbb, 0x99, 0xd1, 0xb1, 0x2d, 0x7a, 0x25, 0xaa, 0x85, 0x0d, 0xb1, 0xaf, 0x71, 0x66, 0x9a, 0x12, 0xc9, 0xe6, 0xc2, 0x27, 0xea, 0x69, 0x7d, 0xd3, 0x42, 0x6a, 0x3e, 0x22, 0x47, 0x62, 0xa6, 0x46, 0x21, 0xd3, 0xbe, 0x9d, 0x83, 0x0c, 0xcf, 0xa6, 0x11, 0xe7, 0x7a, 0xfd, 0x15, 0xd1, 0x9b, 0xd4, 0x2b, 0x0b, 0x16, 0x93, 0x68, 0x49, 0xdc, 0xd2, 0x00, 0x92, 0x1d, 0x08, 0xb2, 0x2f, 0x84, 0xfd, 0xda, 0xc0, 0xb1, 0x90, 0xf2, 0x63, 0x9c, 0xe0, 0x9e, 0x16, 0x91, 0x18, 0xc1, 0x6e, 0xc0, 0xde, 0xbf, 0x1d, 0xa3, 0xa7, 0xaa, 0x24, 0xde, 0x41, 0x1a, 0x8a, 0x77, 0xba, 0x18, 0xcc, 0x0e, 0xc7, 0x77, 0x34, 0x07, 0xaa, 0xfb, 0xfd, 0x6e, 0x6e, 0x8b, 0x34, 0x52, 0x20, 0x9d, 0x1c, 0xdf, 0x0e, 0x57, 0xef, 0x8c, 0xba, 0xcc, 0x26, 0x00, 0x7c, 0xf5, 0xf6, 0x23, 0x3e, 0x9b, 0x48, 0x54, 0xe3, 0x9c, 0x6e, 0xdc, 0x98, 0x79, 0xa7, 0xc4, 0x74, 0x7e, 0x15, 0xcf, 0x0e, 0x9c, 0xae, 0xca, 0xaa, 0x98, 0xbf, 0xaf, 0xd7, 0x0a, 0x05, 0x6d, 0xf7, 0xf3, 0xcb, 0x7c, 0x07, 0x03, 0x2a, 0x11, 0xc0, 0x66, 0x8e, 0x27, 0x16, 0xfc, 0x67, 0x58, 0x6f, 0x01, 0x21, 0x92, 0xe4, 0x68, 0x0c, 0x80, 0x97, 0x37, 0xb8, 0x1e, 0xd2, 0x07, 0x57, 0x8f, 0xe0, 0x3f, 0xc3, 0xda, 0xf1, 0x22, 0x43, 0xc2, 0x95, 0xa8, 0x0d, 0xd5, 0x7c, 0xc9, 0x8a, 0x87, 0x14, 0xd7, 0xb2, 0xb9, 0x4e, 0xdf, 0x5b, 0xd1, 0x59, 0xe5, 0xe4, 0x99, 0x8f, 0xa4, 0x8d, 0xdc, 0x2a, 0x6f, 0x87, 0x00, 0x22, 0x23, 0xe0, 0x58, 0xff, 0xf6, 0x37, 0xea, 0x7a, 0xbf, 0x38, 0x98, 0x56, 0x64, 0xb6, 0x01, 0xc3, 0x7a, 0x43, 0x1b, 0x15, 0x96, 0x80, 0x69, 0xc2, 0xa8, 0x9c, 0xac, 0x79, 0x8b, 0x2a, 0xd6, 0x58, 0xa3, 0x0b, 0x9a, 0x41, 0xc3, 0x57, 0xc0, 0x91, 0x91, 0x2a, 0x68, 0x23, 0xd2, 0x0f, 0xeb, 0x80, 0x16, 0xf0, 0x0c, 0xff, 0x96, 0xb4, 0x4f, 0x31, 0x65, 0xd7, 0x3d, 0xc5, 0xaf, 0xf6, 0x68, 0x15, 0xa5, 0x34, 0x3a, 0xb7, 0x34, 0x16, 0x0d, 0x42, 0xda, 0xde, 0x1e, 0x4a, 0x3c, 0xde, 0x3a, 0xd0, 0x5e, 0x25, 0xb6, 0x95, 0x8c, 0x07, 0x8d, 0xd6, 0x22, 0xac, 0x83, 0x75, 0x64, 0xa4, 0x8d, 0x8a, 0xa4, 0x60, 0x21, 0xb7, 0x1d, 0xf5, 0xc9, 0xb0, 0x0c, 0xca, 0xfe, 0x63, 0xd8, 0x16, 0xb2, 0xad, 0x63, 0xc4, 0xdb, 0x61, 0x36, 0xb0, 0x11, 0x29, 0xe6, 0xa2, 0xfe, 0xdf, 0x66, 0x89, 0x3f, 0xa9, 0xe0, 0xfc, 0x4e, 0x6b, 0x83, 0xdd, 0x75, 0x09, 0x66, 0x36, 0x20, 0x95, 0xb3, 0xdb, 0x3c, 0x9b, 0xba, 0x3e, 0xb4, 0xe8, 0xad, 0xc2, 0x24, 0xee, 0xb3, 0x8d, 0xc3, 0xa8, 0x0b, 0xa2, 0x95, 0x0d, 0xd0, 0x68, 0xba, 0x64, 0x4b, 0xdb, 0x20, 0x10, 0xb7, 0xcc, 0x1d, 0xb9, 0x3a, 0x4c, 0xf5, 0x7c, 0xf5, 0xd6, 0x24, 0x82, 0xec, 0x17, 0x3e, 0x1f, 0x7b, 0xdd, 0x63, 0xfe, 0xc3, 0xed, 0x93, 0x34, 0x78, 0x90, 0xe4, 0xe1, 0xec, 0xa8, 0x3d, 0xb9, 0x52, 0xee, 0x7b, 0x1b, 0xf6, 0x33, 0x53, 0x5b, 0xb9, 0x08, 0x96, 0x04, 0x9e, 0xdd, 0xe1, 0x6f, 0xbe, 0x59, 0xe0, 0xdf, 0x8a, 0x9a, 0x2c, 0x64, 0x17, 0xf1, 0x2d, 0x86, 0x1e, 0xe1, 0x66, 0xa9, 0xe6, 0xaa, 0x81, 0x2c, 0xca, 0x6f, 0xc9, 0xe1, 0xe1, 0x48, 0x0b, 0xdf, 0xe6, 0x39, 0xda, 0xd0, 0x14, 0x45, 0x44, 0x6b, 0x96, 0xe1, 0xb2, 0xbb, 0x78, 0xaa, 0x40, 0xe5, 0x89, 0xba, 0x56, 0x83, 0x8b, 0x70, 0x80, 0x18, 0xa4, 0x9f, 0x4c, 0xb2, 0x94, 0x72, 0xdf, 0x42, 0xa6, 0x3b, 0xd4, 0xe4, 0x88, 0x97, 0x29, 0x4f, 0x82, 0xa1, 0xde, 0xfd, 0x6c, 0x4c, 0xdc, 0x01, 0x6b, 0x1f, 0x89, 0x31, 0x6b, 0x71, 0x87, 0x7f, 0xe8, 0x9f, 0xf3, 0xd4, 0x0b, 0xc8, 0x0e, 0x1c, 0xc8, 0x4f, 0x4c, 0x66, 0xe3, 0x86, 0x7c, 0xb4, 0x8b, 0x24, 0xb6, 0x3d, 0x65, 0x13, 0x97, 0xea, 0x3f, 0x3c, 0xfd, 0x02, 0x1f, 0xe6, 0x10, 0x0f, 0x6d, 0xc4, 0xe3, 0x5a, 0x82, 0xd5, 0x61, 0xc1, 0xd3, 0x72, 0x66, 0x7f, 0xf4, 0x0c, 0xe5, 0x9f, 0x98, 0x04, 0xd2, 0x59, 0x5b, 0x89, 0xe1, 0xc4, 0x13, 0x66, 0x8b, 0xed, 0x49, 0x44, 0x06, 0x00, 0x0a, 0xab, 0x6b, 0x45, 0x4a, 0x44, 0x51, 0xcc, 0x02, 0x0b, 0x86, 0x9f, 0xdb, 0xb2, 0xa7, 0x49, 0x58, 0x09, 0xdc, 0x81, 0x79, 0x5b, 0x7c, 0x36, 0x8c, 0x8f, 0x88, 0x37, 0x8e, 0x22, 0x3e, 0x39, 0xb6, 0xa7, 0x46, 0x8f, 0x4f, 0x2c, 0x3c, 0x7a, 0xe8, 0xf2, 0xaf, 0x1b, 0x34, 0xa7, 0xf7, 0x1f, 0x3f, 0x94, 0x6e, 0xba, 0xb5, 0xae, 0xdb, 0xe5, 0xfa, 0x7d, 0x41, 0x3f, 0xfe, 0xdd, 0x67, 0x62, 0x31, 0xa7, 0xdf, 0x7f, 0x0a, 0x81, 0xcb, 0x56, 0x0f, 0xde, 0x40, 0x0c, 0x75, 0x22, 0xe4, 0x06, 0x0a, 0x97, 0x9a, 0x81, 0x33, 0xa3, 0xd5, 0xa9, 0x5d, 0xb6, 0x4b, 0xf9, 0x11, 0x9b, 0xb7, 0xac, 0x7a, 0xc9, 0x70, 0x33, 0x9a, 0xa8, 0x63, 0x13, 0x84, 0x94, 0x69, 0x41, 0xf1, 0x82, 0xf3, 0x03, 0x6c, 0x27, 0x64, 0xb9, 0xfc, 0x8c, 0xc9, 0x66, 0x6d, 0x89, 0x87, 0x64, 0x04, 0xa8, 0xf6, 0x93, 0x5e, 0x0a, 0x73, 0x9e, 0xcb, 0xee, 0x60, 0x15, 0x04, 0xeb, 0x9b, 0x7e, 0x8d, 0x51, 0x45, 0xc5, 0x54, 0x3e, 0x51, 0xdb, 0x7e, 0x07, 0x51, 0x0d, 0x1d, 0x2f, 0xf8, 0x9f, 0xe7, 0xef, 0x0b, 0x13, 0x4d, 0xa2, 0x37, 0xdd, 0x38, 0x7d, 0x8c, 0x97, 0x2f, 0xcb, 0xbd, 0x1b, 0x56, 0x61, 0xd1, 0xe3, 0x6c, 0x02, 0x4f, 0x6b, 0x41, 0xff, 0xc9, 0xa5, 0x49, 0x0f, 0x92, 0x03, 0x1b, 0x32, 0xc4, 0xdf, 0x84, 0x02, 0x4f, 0x59, 0x47, 0xe4, 0x1d, 0xd2, 0x95, 0x5f, 0x6c, 0x9f, 0x3e, 0x2c, 0x6a, 0xd4, 0xae, 0x69, 0x5a, 0xed, 0xc6, 0xcb, 0x92, 0xee, 0xb8, 0x58, 0x0e, 0x51, 0xed, 0x72, 0xab, 0x58, 0xa4, 0x11, 0x5c, 0x02, 0x9f, 0xb0, 0xce, 0x88, 0x7d, 0x35, 0xca, 0xa3, 0xd9, 0xc7, 0x62, 0x75, 0x36, 0xc4, 0xe4, 0xec, 0x00, 0x00, 0x01, 0xb7 }; +constexpr AccessUnit M2V_MULTIPLE_PACK_EXPECTED_AU_1 = { 0x15f90, 0x159b2, true, 0, {}, { 0xb2, 0x5b, 0x25, 0x1f, 0x28, 0xf8, 0x1e, 0x80, 0xc8, 0x72, 0x45, 0xed, 0xef, 0xe9, 0xb6, 0x08, 0x83, 0x20, 0xcd, 0x25 } }; +constexpr AccessUnit M2V_MULTIPLE_PACK_EXPECTED_AU_2 = { 0x28144c47, 0x7e4e68d4, true, 0, {}, { 0xee, 0x18, 0x40, 0x38, 0x32, 0xb8, 0x2d, 0xa4, 0xe1, 0x8b, 0x09, 0x40, 0xfa, 0x8e, 0xfa, 0x64, 0x8f, 0xcd, 0x7c, 0x40 } }; +constexpr AccessUnit M2V_MULTIPLE_PACK_EXPECTED_AU_3 = { 0x15f90, 0x159b2, true, 0, {}, { 0xf5, 0x44, 0x36, 0x81, 0xe4, 0xff, 0x09, 0x3d, 0xd8, 0x28, 0xd3, 0x2b, 0xf2, 0x04, 0x7e, 0xdb, 0x90, 0x88, 0x6d, 0xdb } }; +constexpr AccessUnit M2V_MULTIPLE_PACK_EXPECTED_AU_4 = { std::numeric_limits::max(), std::numeric_limits::max(), false, 0, {}, { 0xd4, 0x82, 0xc6, 0x8d, 0x56, 0x01, 0x42, 0x07, 0x40, 0x81, 0xeb, 0x25, 0xc5, 0xc9, 0x24, 0x24, 0x0e, 0x24, 0x39, 0x4c } }; + +constexpr std::array ATRACX_MULTIPLE_PACK_STREAM = { 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xbd, 0x06, 0xe6, 0x81, 0xc1, 0x0d, 0x31, 0x00, 0x05, 0xbf, 0x21, 0x11, 0x00, 0x05, 0xb3, 0x65, 0x1e, 0x69, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xfb, 0xb7, 0x4a, 0xf6, 0xa9, 0xd4, 0x7b, 0x0f, 0xd0, 0x00, 0xd7, 0xe7, 0x12, 0x43, 0x4c, 0x62, 0x89, 0xa6, 0xc2, 0x04, 0x70, 0x0e, 0x0b, 0xab, 0x92, 0x01, 0x5f, 0x90, 0x5c, 0x0a, 0x9a, 0xc6, 0x0c, 0x34, 0x34, 0xae, 0x42, 0x9c, 0x20, 0x2e, 0x01, 0x84, 0xbf, 0xf9, 0x16, 0x5f, 0xab, 0xb7, 0x91, 0xaa, 0xb2, 0x45, 0xc8, 0x5d, 0x83, 0x75, 0xbc, 0x67, 0xfe, 0xe8, 0x4f, 0xa0, 0xf6, 0x59, 0x01, 0xbb, 0xeb, 0x58, 0x61, 0x1f, 0x2b, 0xe1, 0x29, 0x19, 0x59, 0x6f, 0xfc, 0x3b, 0x04, 0xb2, 0xb2, 0x44, 0x0a, 0xa3, 0xd7, 0x5c, 0x13, 0x8c, 0x75, 0x89, 0x3a, 0x08, 0xce, 0xe8, 0x88, 0xc7, 0x31, 0xf1, 0x29, 0x74, 0x45, 0xc8, 0x34, 0x89, 0xac, 0xc3, 0x83, 0x21, 0xed, 0x1c, 0x70, 0xea, 0x47, 0x92, 0x74, 0x8f, 0xa7, 0x81, 0xf6, 0xae, 0x70, 0x64, 0xae, 0xb0, 0x73, 0xad, 0x6e, 0x54, 0xcb, 0x98, 0x46, 0x39, 0x41, 0x45, 0x11, 0xad, 0xde, 0xb6, 0xdd, 0xa9, 0xe3, 0x8c, 0xf8, 0xe2, 0x3d, 0x73, 0x98, 0x81, 0xf3, 0x70, 0x8e, 0x7e, 0xe1, 0x5a, 0x1f, 0x25, 0x47, 0x01, 0x74, 0x39, 0xf0, 0xe7, 0x85, 0x9d, 0x37, 0x6e, 0x12, 0xed, 0x4d, 0x12, 0x52, 0x21, 0xc1, 0xc2, 0xf8, 0x68, 0xc1, 0xf9, 0x18, 0x0d, 0xda, 0x8c, 0x6f, 0x30, 0xa2, 0x39, 0x5d, 0x4d, 0x7f, 0x7f, 0x93, 0x72, 0xf6, 0x17, 0x9a, 0xd5, 0xa0, 0x03, 0x64, 0xfe, 0x33, 0xfd, 0xc9, 0x9d, 0xab, 0x30, 0xb1, 0x04, 0x4c, 0x85, 0x95, 0xb5, 0x00, 0xb4, 0x53, 0x8c, 0xbb, 0x93, 0x99, 0x86, 0x47, 0x51, 0x94, 0x39, 0x96, 0xcc, 0x87, 0x1a, 0x05, 0xdf, 0xff, 0xbe, 0x29, 0xa3, 0x76, 0xe4, 0x4a, 0xcd, 0xaf, 0x68, 0xc8, 0xb2, 0x30, 0x03, 0x29, 0x51, 0x15, 0xd5, 0xb1, 0x75, 0xcb, 0x5d, 0xba, 0xfe, 0x04, 0x98, 0x48, 0x86, 0xe1, 0xcc, 0x16, 0x3d, 0x9e, 0x3c, 0xab, 0x8f, 0xf2, 0xec, 0x05, 0x24, 0xeb, 0xa8, 0x17, 0xd5, 0xe1, 0x86, 0xac, 0x86, 0x49, 0xb8, 0xe3, 0xc5, 0x88, 0x2e, 0xc7, 0xaf, 0xa4, 0xa9, 0x56, 0x98, 0x82, 0xc3, 0x1f, 0x4c, 0x4c, 0x39, 0x3a, 0x40, 0x58, 0x16, 0x1f, 0x75, 0x35, 0x47, 0x13, 0x82, 0x58, 0xb6, 0xd7, 0xb6, 0x31, 0xed, 0x6e, 0x4b, 0x69, 0x7e, 0x9d, 0x51, 0xc6, 0x43, 0x95, 0x42, 0xd7, 0xe7, 0x25, 0x94, 0x3c, 0xf0, 0xd1, 0xc8, 0x2d, 0xac, 0x01, 0x31, 0x1a, 0x13, 0xe5, 0xf7, 0x0f, 0x51, 0xef, 0x59, 0xb8, 0x36, 0x02, 0xe1, 0xe5, 0x47, 0x98, 0x36, 0x90, 0x2a, 0xc0, 0x20, 0x50, 0xc4, 0xe2, 0x32, 0x02, 0xa0, 0xe2, 0x91, 0x7d, 0x6f, 0x54, 0xf0, 0x84, 0xf9, 0xcb, 0xcf, 0x8b, 0x45, 0xe9, 0x88, 0x5c, 0xa9, 0x56, 0xe5, 0x3a, 0x0d, 0x98, 0x9d, 0xf8, 0x23, 0x3d, 0x90, 0xd6, 0x59, 0x5e, 0x1c, 0xdc, 0x4e, 0x4a, 0x70, 0x80, 0x20, 0xdb, 0x52, 0x8a, 0x08, 0x69, 0xea, 0x78, 0x2f, 0xf9, 0x72, 0xd5, 0x66, 0x1d, 0x9f, 0x9f, 0xc0, 0x00, 0xd0, 0x55, 0x55, 0xd1, 0x5d, 0xbd, 0x3a, 0x41, 0x13, 0x39, 0x71, 0x1c, 0xbc, 0x9a, 0xd1, 0x00, 0x17, 0x6a, 0xfd, 0x81, 0xea, 0xb6, 0x83, 0xb9, 0xb0, 0x86, 0xd2, 0x65, 0xcc, 0xc8, 0x2b, 0x15, 0x07, 0xb1, 0x13, 0xde, 0xf5, 0x30, 0xac, 0x48, 0x75, 0xd9, 0x50, 0xee, 0x0a, 0x12, 0x91, 0x4d, 0x5f, 0xe8, 0x0d, 0x6c, 0xc3, 0x50, 0xc8, 0xdb, 0x33, 0x2c, 0x9f, 0x01, 0xe9, 0x97, 0xe9, 0xb8, 0x4d, 0x18, 0xe2, 0xcd, 0x65, 0x6d, 0xcb, 0x18, 0x46, 0x00, 0x1f, 0x76, 0x96, 0x22, 0x5d, 0x1d, 0xa7, 0x6c, 0xf6, 0x5c, 0x4f, 0x60, 0xf0, 0xe3, 0x47, 0xd5, 0xef, 0x8f, 0xba, 0x37, 0xcc, 0xc0, 0x33, 0xe9, 0x60, 0x0f, 0xaa, 0x8d, 0x13, 0xca, 0xda, 0x04, 0xd7, 0xab, 0x51, 0x1d, 0x9d, 0x11, 0x5e, 0x9b, 0x7b, 0x59, 0x65, 0x4e, 0x43, 0x47, 0x84, 0xb2, 0x2a, 0x9c, 0xb3, 0x9f, 0x1d, 0x6e, 0x72, 0x3b, 0x18, 0x30, 0x19, 0xee, 0xba, 0xd7, 0x50, 0xce, 0x76, 0x3e, 0x6d, 0xe2, 0x68, 0xd3, 0xe3, 0xa8, 0x26, 0x63, 0x1b, 0x3b, 0xbb, 0x03, 0x15, 0x6d, 0xb7, 0x6b, 0x84, 0x38, 0xe7, 0x6e, 0xc0, 0x0f, 0x24, 0x60, 0x81, 0xfc, 0x3d, 0x4c, 0x07, 0xd9, 0xb4, 0xd0, 0x87, 0xc5, 0x1c, 0xb4, 0x2c, 0x8a, 0xe4, 0xb3, 0xbc, 0x0e, 0x39, 0xd5, 0x8b, 0xd3, 0xd1, 0xaf, 0x5c, 0x48, 0x54, 0x2e, 0xa9, 0xeb, 0x49, 0xa4, 0x36, 0x6f, 0x60, 0xc4, 0x88, 0x48, 0x75, 0xc2, 0x9b, 0xf7, 0x61, 0x15, 0x1e, 0xd4, 0x8d, 0x70, 0xbe, 0x73, 0x6d, 0xb7, 0x5c, 0x8b, 0xd1, 0x30, 0x61, 0x0e, 0xec, 0x5d, 0x9a, 0x03, 0x19, 0xc9, 0xe4, 0xce, 0x65, 0x38, 0xee, 0x2c, 0xf5, 0x58, 0x84, 0x83, 0x9a, 0x8f, 0xe1, 0x73, 0xe6, 0x38, 0x04, 0xc1, 0x54, 0x6b, 0xde, 0x22, 0x73, 0xd6, 0x3c, 0x91, 0x91, 0x38, 0x64, 0xda, 0x6e, 0x39, 0x76, 0xac, 0x85, 0x46, 0x48, 0x3b, 0x50, 0x17, 0x7f, 0x55, 0xd0, 0x50, 0x96, 0xbc, 0xb0, 0x46, 0xc4, 0x9e, 0xfb, 0xfe, 0xaf, 0xc4, 0x50, 0xb5, 0xc8, 0xfd, 0x38, 0xda, 0x50, 0xde, 0x46, 0x8f, 0xa7, 0x9f, 0xb2, 0x75, 0x04, 0x8f, 0xad, 0x7e, 0x95, 0x51, 0x53, 0xb2, 0xb0, 0xe4, 0xde, 0x31, 0x90, 0x5c, 0x2d, 0x34, 0x5c, 0xc7, 0x8e, 0x77, 0x39, 0xc8, 0xe8, 0x18, 0x66, 0x30, 0x38, 0x87, 0xc9, 0x6d, 0x27, 0x80, 0xf9, 0x89, 0xf3, 0xcf, 0x6b, 0x40, 0x20, 0x39, 0x29, 0x3e, 0xb2, 0xf7, 0x05, 0x08, 0x0e, 0xdc, 0x34, 0xf5, 0x9e, 0x55, 0xce, 0xa5, 0xa7, 0x1a, 0xaf, 0xcf, 0x1c, 0x1a, 0x4d, 0x89, 0x94, 0x4f, 0x02, 0x7b, 0x0c, 0x5a, 0xb9, 0x8e, 0x62, 0x76, 0x1d, 0x3e, 0x5b, 0x74, 0x2f, 0x8d, 0x7c, 0x54, 0xf4, 0x54, 0x3c, 0x9a, 0x0c, 0xde, 0x7a, 0xfc, 0x65, 0x39, 0x95, 0x39, 0xf8, 0x93, 0xde, 0x57, 0x32, 0x41, 0xfd, 0xb4, 0x15, 0xc4, 0xce, 0xdb, 0xab, 0x6d, 0xf5, 0x37, 0x0c, 0x1a, 0x92, 0x4b, 0xe9, 0xb5, 0xfc, 0x82, 0xa7, 0x3e, 0xee, 0xa2, 0x98, 0x85, 0xfb, 0x52, 0xdb, 0xd8, 0x19, 0xf2, 0xdf, 0xe1, 0xcb, 0x62, 0x57, 0x49, 0x80, 0x74, 0x63, 0xfc, 0x1e, 0xbb, 0x8b, 0x8f, 0xf7, 0x7a, 0x7b, 0xd8, 0x43, 0x14, 0x25, 0xb9, 0x13, 0x33, 0xed, 0x32, 0x7c, 0x92, 0x18, 0x05, 0xd0, 0xe6, 0xc9, 0xd2, 0x6d, 0x7b, 0xb8, 0x4c, 0x87, 0x51, 0x53, 0xde, 0x07, 0x41, 0xc7, 0xa7, 0x18, 0xb5, 0x78, 0xa6, 0x62, 0xa3, 0x75, 0xaf, 0x58, 0x52, 0x11, 0x0b, 0xd6, 0x8d, 0x6e, 0x37, 0x07, 0x88, 0xa7, 0x12, 0xaa, 0xce, 0x58, 0xa2, 0x9e, 0x50, 0x3b, 0x58, 0xfe, 0xff, 0x96, 0x37, 0x85, 0xec, 0xa9, 0x0b, 0x64, 0x5a, 0x2d, 0xbc, 0xa4, 0x57, 0x25, 0x4e, 0x97, 0x4d, 0x0c, 0x81, 0xeb, 0xb7, 0xa1, 0xcc, 0x1e, 0x27, 0x8c, 0xd5, 0x80, 0x41, 0x52, 0xab, 0x0b, 0x89, 0xa3, 0x97, 0x27, 0xeb, 0x17, 0x32, 0x92, 0x9c, 0x83, 0x81, 0xaf, 0x7e, 0xb4, 0x5e, 0x80, 0xa3, 0x6e, 0x68, 0x13, 0x49, 0x82, 0x8b, 0x80, 0x23, 0xb2, 0x5e, 0x4c, 0x6f, 0xb1, 0x51, 0xb9, 0xf8, 0xb6, 0xea, 0xbf, 0x07, 0x7a, 0x3c, 0x47, 0x69, 0x68, 0xc1, 0x14, 0xc7, 0xfe, 0x46, 0x74, 0x47, 0x5c, 0xca, 0xb7, 0x80, 0xa8, 0xeb, 0x0b, 0x78, 0x4e, 0xd0, 0x95, 0x56, 0x8d, 0x65, 0x21, 0x03, 0xf1, 0x2a, 0x3f, 0xcf, 0x7a, 0xd2, 0x7c, 0xef, 0x5c, 0xcf, 0x22, 0x6f, 0x88, 0xf2, 0x40, 0xec, 0x02, 0x0c, 0x5e, 0xd4, 0x2a, 0x9e, 0x07, 0xfc, 0x51, 0xd4, 0xf2, 0x10, 0xcc, 0x27, 0xee, 0x69, 0xbf, 0xbd, 0x72, 0x9c, 0x72, 0xf2, 0x99, 0x11, 0xf9, 0xd0, 0xcf, 0x56, 0x4a, 0x56, 0x2c, 0x10, 0x94, 0x08, 0x41, 0x84, 0xc5, 0x06, 0x07, 0x30, 0x13, 0x29, 0x9a, 0xc3, 0x06, 0x97, 0xe4, 0x1d, 0x61, 0x4d, 0x78, 0x93, 0xe3, 0xd5, 0xf7, 0xc8, 0xd1, 0x21, 0x76, 0x14, 0x25, 0xaf, 0xb6, 0x3d, 0x74, 0x48, 0xa8, 0xcb, 0x4d, 0x99, 0x03, 0xed, 0xc1, 0x37, 0x2e, 0x80, 0x05, 0xab, 0x79, 0xdc, 0x74, 0x60, 0x79, 0x35, 0xf0, 0xb2, 0xac, 0x20, 0xe5, 0xb2, 0x7a, 0x31, 0xe0, 0x74, 0x9b, 0x3d, 0x95, 0x22, 0x97, 0xa0, 0x28, 0x6f, 0x30, 0x2c, 0x0b, 0xe5, 0x5e, 0x9b, 0x01, 0xef, 0x46, 0xf4, 0x4b, 0xd9, 0x83, 0xe7, 0xcc, 0x56, 0x92, 0x5a, 0x96, 0xa1, 0x57, 0xcb, 0xec, 0xa4, 0x32, 0x0e, 0x5d, 0xc7, 0x3e, 0x5b, 0x8b, 0x67, 0xca, 0xd9, 0xf9, 0xb0, 0xfb, 0x11, 0xe5, 0x12, 0x0e, 0xe4, 0xf0, 0x98, 0x91, 0xbf, 0x1d, 0xea, 0x2d, 0x7a, 0x4a, 0x29, 0x85, 0x14, 0x75, 0xb1, 0xa9, 0x5c, 0xd2, 0xb1, 0x79, 0x01, 0x70, 0xcf, 0x83, 0x01, 0xff, 0xc0, 0x1d, 0xa5, 0x28, 0xd3, 0x38, 0xe6, 0xc5, 0x38, 0xee, 0x0b, 0xf7, 0x13, 0x10, 0x34, 0xf1, 0x78, 0xfc, 0x93, 0x14, 0xa4, 0x7a, 0x03, 0x0a, 0x77, 0x30, 0xae, 0xe2, 0x48, 0x78, 0x4e, 0x2c, 0xff, 0xac, 0x83, 0xee, 0x31, 0x6d, 0x49, 0x55, 0x41, 0x4a, 0x4a, 0x44, 0xf4, 0x65, 0x66, 0x79, 0xb0, 0x05, 0xb7, 0xf9, 0x9b, 0xb4, 0x12, 0xb8, 0xa0, 0xdc, 0xe2, 0xec, 0x90, 0x5b, 0xca, 0x70, 0xdf, 0xb0, 0x2c, 0x63, 0x75, 0x6b, 0x2a, 0x4c, 0x14, 0x3d, 0x0e, 0x01, 0x6b, 0x1a, 0x25, 0xac, 0x9b, 0x4b, 0x2b, 0x62, 0x1d, 0x71, 0xb8, 0x86, 0x65, 0x16, 0xc4, 0x37, 0xa2, 0x7f, 0x63, 0x43, 0xb9, 0xf9, 0x44, 0x2b, 0x0a, 0x32, 0xa8, 0xdd, 0x7d, 0x33, 0x1d, 0xb7, 0xae, 0x6a, 0x97, 0xa2, 0xb4, 0xd5, 0xe8, 0x3e, 0x7d, 0x87, 0x5e, 0x88, 0x8d, 0xa8, 0x3c, 0xb0, 0x76, 0xab, 0x0b, 0x12, 0x73, 0x2f, 0x3c, 0xfe, 0xcb, 0x17, 0xbf, 0xa5, 0x8a, 0xf1, 0xef, 0x99, 0x25, 0xd6, 0x63, 0x15, 0xb7, 0xb8, 0xbc, 0xf3, 0x21, 0x05, 0x0f, 0x03, 0x75, 0xa8, 0xb4, 0xca, 0xeb, 0x37, 0xa7, 0x29, 0x5a, 0x9c, 0xf3, 0xcc, 0x08, 0x2b, 0xaa, 0x39, 0x74, 0xcd, 0xeb, 0xc7, 0xd5, 0xd3, 0x4a, 0xf3, 0x34, 0x05, 0xba, 0xd0, 0xbe, 0x00, 0x90, 0xb0, 0x2f, 0x33, 0xfd, 0x34, 0x51, 0xc6, 0xd5, 0xf5, 0x68, 0xd3, 0xa6, 0xb9, 0xa9, 0xf4, 0xcb, 0xdb, 0x28, 0x1a, 0x8e, 0x06, 0x04, 0xd7, 0x75, 0x82, 0x11, 0x6f, 0x88, 0xaf, 0x9b, 0x71, 0x53, 0x90, 0xe7, 0xb9, 0x7b, 0xc9, 0x4c, 0xe3, 0x13, 0x20, 0xdd, 0x1e, 0xa3, 0x7c, 0x27, 0x0b, 0xdd, 0x66, 0xc9, 0xad, 0x02, 0xf9, 0x50, 0xd6, 0xe6, 0x01, 0x83, 0x85, 0x8c, 0x60, 0x9c, 0x45, 0xee, 0xed, 0x91, 0x2d, 0xa4, 0xc5, 0x80, 0x37, 0x08, 0x00, 0x2b, 0x52, 0xe6, 0x1b, 0xb5, 0x14, 0x3b, 0x67, 0x3e, 0x6b, 0x02, 0xc5, 0x4f, 0x39, 0xf2, 0xc7, 0x48, 0xf2, 0x25, 0x4c, 0x9b, 0x07, 0x41, 0x05, 0x43, 0xa5, 0x2e, 0xb7, 0xbb, 0x9f, 0x07, 0xdb, 0x5e, 0xc8, 0x91, 0x75, 0x3a, 0x06, 0x46, 0x01, 0x5f, 0xd1, 0x8b, 0x6c, 0xab, 0xcd, 0xe2, 0xe7, 0xde, 0x29, 0x6b, 0x2e, 0x41, 0xbc, 0x97, 0x21, 0x51, 0x1d, 0x9e, 0x45, 0x2e, 0x4d, 0x88, 0xe0, 0xea, 0x61, 0x87, 0xf6, 0xed, 0x3f, 0xa0, 0x28, 0x70, 0x59, 0x89, 0xe4, 0x9c, 0xba, 0xd0, 0x14, 0x8f, 0x10, 0x85, 0x34, 0xd6, 0x9a, 0x2e, 0xc0, 0x23, 0xc7, 0xfe, 0x64, 0xd2, 0xdd, 0x11, 0x31, 0x1e, 0xbc, 0xb5, 0x2e, 0x06, 0xbb, 0xd0, 0x44, 0xbe, 0xeb, 0x4b, 0x90, 0x2a, 0xb9, 0x1a, 0x61, 0x05, 0x52, 0x13, 0x4f, 0x4b, 0xed, 0xb0, 0x22, 0x2d, 0xe4, 0xef, 0x2d, 0x40, 0x02, 0x58, 0x6f, 0xb5, 0x7b, 0x90, 0x1e, 0x41, 0xb7, 0xab, 0x40, 0x53, 0x72, 0x35, 0x10, 0x0c, 0x6e, 0xf0, 0xd1, 0x88, 0x21, 0x75, 0x29, 0xd0, 0xc3, 0xe4, 0x39, 0xa1, 0xec, 0x53, 0xc1, 0xf2, 0xcb, 0x62, 0x4c, 0x8d, 0xee, 0x78, 0x80, 0x34, 0x60, 0x5f, 0x64, 0x3f, 0x3f, 0xe1, 0x1e, 0xca, 0x56, 0x7f, 0xb5, 0xde, 0x0f, 0x85, 0x33, 0x93, 0x8f, 0x85, 0x6c, 0xf9, 0xd3, 0xf4, 0x86, 0xe8, 0xc2, 0xb7, 0x48, 0xe3, 0x3a, 0xa4, 0xf2, 0x43, 0xf6, 0x21, 0xff, 0xec, 0x11, 0x7c, 0x11, 0x53, 0xbb, 0xf1, 0x15, 0x9b, 0xdb, 0x30, 0x95, 0xa0, 0xa3, 0x42, 0x6e, 0x7d, 0x70, 0xc5, 0x6e, 0x8c, 0x58, 0x35, 0xf5, 0xde, 0xd1, 0xce, 0x2e, 0xb0, 0x15, 0x97, 0xbc, 0x33, 0x88, 0x62, 0xdd, 0xfe, 0xe2, 0x69, 0xe7, 0x46, 0x98, 0x41, 0xc8, 0xe6, 0x55, 0x60, 0x3e, 0xf6, 0x1c, 0x3d, 0x8e, 0x46, 0x0c, 0xf3, 0xff, 0xd0, 0xbd, 0xc5, 0x96, 0x62, 0x1a, 0x50, 0x02, 0x45, 0xc0, 0xe6, 0xa5, 0x98, 0x62, 0xea, 0x41, 0xa9, 0x56, 0x28, 0x45, 0xc8, 0xc3, 0x64, 0xf7, 0x37, 0x95, 0x29, 0x97, 0xbd, 0xe2, 0x39, 0x46, 0x1b, 0xa6, 0xbb, 0x4b, 0x10, 0x0f, 0xd0, 0x00, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xbd, 0x06, 0xe6, 0x81, 0xc1, 0x10, 0xf0, 0xab, 0xbf, 0xd5, 0xd3, 0xcb, 0xde, 0x20, 0x0d, 0x88, 0x1e, 0x69, 0xb2, 0x13, 0xa2, 0x45, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x35, 0xf3, 0xe5, 0x17, 0x48, 0x8f, 0x5c, 0x96, 0xa3, 0xe9, 0x58, 0xd7, 0xb6, 0xfc, 0xc5, 0xc5, 0x11, 0xa2, 0x74, 0x77, 0x19, 0xfa, 0x7b, 0x58, 0x17, 0x28, 0x89, 0x78, 0xf3, 0xd7, 0x98, 0x7b, 0x1a, 0xf9, 0x9f, 0x05, 0x83, 0x87, 0xd3, 0x42, 0x55, 0xa2, 0x02, 0x37, 0x64, 0xa7, 0xac, 0x38, 0x13, 0x5d, 0x06, 0xe7, 0xbb, 0xcb, 0xc2, 0x92, 0x4d, 0x2a, 0xc4, 0xcd, 0x2a, 0x4b, 0x85, 0x5a, 0xfc, 0x70, 0xbc, 0x79, 0xbe, 0x48, 0x90, 0x35, 0xfb, 0x25, 0x0e, 0x93, 0xfd, 0x7d, 0x6c, 0x25, 0x8a, 0x59, 0x7e, 0x9c, 0x0b, 0xa0, 0x58, 0x3b, 0x4e, 0x64, 0x16, 0xef, 0x30, 0x6b, 0xcc, 0xf9, 0x62, 0xe0, 0x68, 0x57, 0x65, 0x93, 0xcc, 0xeb, 0x07, 0xfd, 0xd6, 0x31, 0x38, 0xb5, 0x75, 0xd8, 0xfe, 0x27, 0x86, 0x3b, 0x0a, 0xdc, 0x7c, 0x6f, 0x65, 0x9c, 0x82, 0x08, 0x43, 0x2a, 0x91, 0x45, 0x23, 0x3e, 0x8a, 0x49, 0x34, 0x7e, 0x0a, 0x99, 0x84, 0x11, 0xd2, 0x4a, 0x93, 0xae, 0x8e, 0xcd, 0x1b, 0x6f, 0xa7, 0xf1, 0x50, 0xed, 0x95, 0x97, 0x5c, 0x3d, 0xf9, 0xd1, 0xb7, 0xdb, 0xcf, 0xa3, 0x60, 0xb1, 0x28, 0xe6, 0xa5, 0x22, 0x2c, 0xd1, 0xac, 0x1f, 0x9c, 0x15, 0xd0, 0xe8, 0x8c, 0xab, 0xcb, 0xe0, 0xe9, 0xe9, 0x77, 0xa0, 0x7f, 0x02, 0x02, 0xa1, 0xfb, 0x07, 0x42, 0x72, 0xb8, 0x1a, 0x0f, 0x8d, 0x97, 0x53, 0xa9, 0x75, 0xa1, 0x8b, 0xff, 0x09, 0x21, 0xc3, 0x1e, 0xf9, 0xa3, 0xb9, 0xd7, 0x72, 0x33, 0x62, 0x6e, 0x9a, 0x54, 0xb0, 0x0c, 0x98, 0x0a, 0xbd, 0x30, 0xc7, 0x38, 0x7e, 0x4d, 0xf9, 0xb6, 0x38, 0x3c, 0xb3, 0x7b, 0x4f, 0x86, 0xa2, 0xf3, 0xac, 0x9e, 0x81, 0x15, 0xe4, 0xb5, 0x30, 0x3c, 0xe5, 0x11, 0xf9, 0x05, 0x5c, 0x28, 0x50, 0x0a, 0xa2, 0x9d, 0xe1, 0xfa, 0xe9, 0x80, 0xcd, 0x9d, 0x9e, 0x9a, 0x90, 0x42, 0x2e, 0xe6, 0xd2, 0x4b, 0x1a, 0xd6, 0x84, 0x6e, 0x95, 0x0c, 0x17, 0xc1, 0xb8, 0x1d, 0x84, 0x3a, 0x76, 0xae, 0xfc, 0xd1, 0x32, 0x4d, 0x52, 0xac, 0x6e, 0xe6, 0x4f, 0xcd, 0x76, 0x4d, 0xd3, 0x00, 0x81, 0x82, 0x2e, 0x60, 0xbd, 0x8f, 0x42, 0xe8, 0x83, 0xcb, 0xdd, 0x9b, 0xeb, 0x6f, 0x5a, 0xe8, 0xf9, 0x0c, 0x7a, 0x90, 0x92, 0x2b, 0xe6, 0x04, 0x17, 0x58, 0xd4, 0xa4, 0x43, 0x13, 0xb3, 0xec, 0xb1, 0x39, 0xfe, 0x0e, 0x1d, 0x55, 0xe8, 0x96, 0xa1, 0x13, 0xd6, 0x59, 0xef, 0x36, 0x69, 0xa5, 0x20, 0x83, 0x21, 0xfc, 0xed, 0x6f, 0xa5, 0x85, 0x64, 0x27, 0xeb, 0xdb, 0x53, 0x7f, 0x89, 0x4d, 0xe6, 0x00, 0x61, 0xc4, 0x1e, 0x69, 0x36, 0x74, 0xbe, 0xa3, 0xc0, 0x28, 0x7e, 0x60, 0x97, 0x46, 0xae, 0x9b, 0x9c, 0x70, 0xee, 0xa2, 0x5f, 0x67, 0x18, 0x98, 0x21, 0xef, 0x79, 0xad, 0x4d, 0xff, 0x42, 0xc8, 0x32, 0x28, 0x6e, 0x45, 0xa4, 0x3c, 0x0a, 0x75, 0x19, 0x8a, 0x6b, 0x68, 0x71, 0x11, 0x97, 0x07, 0x8d, 0xf7, 0xcf, 0xdc, 0x61, 0x99, 0xb4, 0xfb, 0xab, 0x7e, 0x0a, 0xf0, 0xf5, 0x08, 0x8b, 0x7e, 0x03, 0x75, 0x4d, 0x75, 0xd8, 0xef, 0x07, 0x3f, 0x80, 0xf4, 0xa1, 0x8e, 0xbc, 0x5b, 0xa5, 0x25, 0x4f, 0xfe, 0x9c, 0xb7, 0x0e, 0x76, 0x39, 0xad, 0xc8, 0x07, 0x2b, 0x87, 0x16, 0xdc, 0x2b, 0xb2, 0xcf, 0x40, 0x4d, 0x23, 0xc0, 0xb9, 0x26, 0xf9, 0xe2, 0x52, 0x55, 0x4a, 0x34, 0x95, 0x5f, 0xbb, 0x14, 0x52, 0x8f, 0xfa, 0x59, 0xd1, 0x2e, 0x53, 0x35, 0x9e, 0x43, 0xcf, 0xa3, 0x1b, 0x24, 0x0b, 0x03, 0xb3, 0x2e, 0x42, 0xb9, 0x85, 0x23, 0x47, 0x4f, 0xfb, 0x69, 0xb6, 0x15, 0x1e, 0x2b, 0xa6, 0xa5, 0x2b, 0xf9, 0x60, 0xae, 0x36, 0x5d, 0x13, 0x10, 0x33, 0xf8, 0x40, 0x61, 0x3a, 0x07, 0x6f, 0xa2, 0x57, 0xdf, 0x38, 0xc1, 0xaf, 0x5b, 0xe6, 0x15, 0x3a, 0x24, 0xaf, 0xb8, 0x2a, 0x43, 0x9f, 0x18, 0xe6, 0xec, 0x89, 0x4d, 0x98, 0x4a, 0xc9, 0x8b, 0x77, 0xf2, 0x4e, 0x50, 0xbd, 0x1e, 0x80, 0x45, 0xcf, 0x94, 0xff, 0xfd, 0xca, 0x9e, 0x57, 0x01, 0x28, 0xf1, 0x4d, 0x1c, 0xd5, 0xd7, 0xe6, 0x1b, 0xcb, 0x4c, 0xac, 0xc7, 0x7c, 0x84, 0x3e, 0xbe, 0x16, 0xab, 0xf2, 0xe8, 0x72, 0xee, 0x69, 0xe4, 0xe2, 0x73, 0x9f, 0x34, 0xec, 0xdb, 0x56, 0x8a, 0xa1, 0x01, 0x53, 0x65, 0x85, 0x23, 0x45, 0xb7, 0xed, 0x85, 0x7a, 0xc5, 0x4e, 0xb4, 0x1e, 0x06, 0x13, 0x54, 0x43, 0xa5, 0x4b, 0xf9, 0x90, 0x8e, 0x4e, 0x55, 0xb5, 0xeb, 0xa7, 0xb6, 0xc0, 0x1f, 0x8d, 0x7d, 0x35, 0xd4, 0xc8, 0xa2, 0xc6, 0x2d, 0x2f, 0xb1, 0xcd, 0xf0, 0xa3, 0x71, 0x5a, 0x67, 0x76, 0xd7, 0x51, 0x3c, 0x9b, 0x14, 0xc8, 0xb6, 0x30, 0x16, 0xbc, 0x4c, 0x95, 0xf0, 0xd2, 0x4f, 0xb0, 0xc3, 0x68, 0x0c, 0xb0, 0x57, 0x3f, 0xa1, 0xa4, 0xda, 0x9d, 0x8f, 0xeb, 0x27, 0xf7, 0x72, 0x22, 0x84, 0xc8, 0xae, 0x81, 0x7e, 0xb9, 0x0f, 0x98, 0xb3, 0x60, 0xa7, 0x27, 0x7b, 0x45, 0x12, 0xf3, 0xa8, 0x2d, 0xff, 0x1b, 0xac, 0x95, 0x80, 0xa3, 0x67, 0x83, 0x5e, 0x6c, 0x54, 0xe9, 0xdb, 0x6e, 0x9a, 0xdf, 0x96, 0x42, 0xbb, 0x44, 0xb9, 0xd2, 0x60, 0xd2, 0x68, 0x37, 0x2a, 0x8d, 0x09, 0xdf, 0xa5, 0x0e, 0x23, 0xc8, 0xb4, 0x65, 0x65, 0x05, 0xc5, 0x75, 0x3e, 0x6b, 0xe5, 0xa4, 0x3e, 0xbe, 0xed, 0xa8, 0x8e, 0xd1, 0x32, 0xe8, 0x5f, 0x5c, 0x0c, 0x73, 0x4a, 0xc9, 0xc7, 0x07, 0xc8, 0x2c, 0xa0, 0x95, 0x79, 0x42, 0xe9, 0x46, 0xae, 0x99, 0x41, 0xc8, 0xfa, 0xa8, 0xdf, 0x36, 0xa2, 0x1d, 0x6e, 0x3d, 0x90, 0x76, 0x59, 0xd4, 0x53, 0x96, 0xa7, 0x66, 0x3c, 0x42, 0x30, 0xfa, 0x41, 0xe5, 0x38, 0x76, 0x51, 0x1a, 0x8d, 0x94, 0x57, 0xee, 0x5d, 0x0b, 0x30, 0xbe, 0x91, 0x72, 0x18, 0xf4, 0x87, 0xd0, 0xc7, 0x7e, 0xbc, 0xce, 0xe8, 0x98, 0x17, 0xc1, 0x0d, 0xbf, 0xa7, 0xe9, 0x1c, 0x57, 0x47, 0x03, 0x88, 0x04, 0xb4, 0x8f, 0xbb, 0x15, 0xda, 0x12, 0x0a, 0x7d, 0xc6, 0x66, 0xb8, 0x74, 0xf0, 0xaa, 0x3c, 0xf0, 0x96, 0x6a, 0x59, 0x3d, 0x5a, 0x28, 0x08, 0xdd, 0x56, 0xb6, 0x8b, 0xa2, 0xbf, 0x45, 0xcc, 0xe5, 0x2f, 0xa1, 0x56, 0xa9, 0xe5, 0x4e, 0x73, 0x3f, 0x41, 0xf9, 0x0b, 0x05, 0x25, 0xcd, 0x65, 0x15, 0x83, 0xf8, 0xfc, 0x12, 0x97, 0x3b, 0xfb, 0xe6, 0xac, 0xab, 0x29, 0x3f, 0x57, 0xb3, 0x8f, 0x40, 0xd7, 0x70, 0x81, 0x55, 0xa2, 0x1d, 0xc7, 0x2a, 0x4a, 0x5c, 0xc4, 0x08, 0x2b, 0x11, 0x5a, 0xac, 0x22, 0x34, 0xcd, 0xa0, 0x42, 0x4b, 0xf6, 0xd2, 0x1f, 0x14, 0xeb, 0xce, 0x99, 0x70, 0xcf, 0xe8, 0x45, 0xbe, 0xd2, 0xe3, 0x12, 0x27, 0xc5, 0x16, 0xc8, 0xa8, 0xa3, 0xff, 0xd3, 0x3b, 0xff, 0x7e, 0x88, 0xef, 0xff, 0xbf, 0xa1, 0x8b, 0x9d, 0xfe, 0xbc, 0xb1, 0xbe, 0x6b, 0xd3, 0x92, 0x9b, 0x7a, 0xaf, 0xfd, 0x2b, 0x5d, 0xc4, 0xe1, 0x3f, 0xfc, 0x1e, 0xc5, 0xe8, 0xf3, 0xd2, 0x84, 0x86, 0x07, 0x06, 0x96, 0xd3, 0x61, 0x72, 0x75, 0x6b, 0xa3, 0x02, 0x2c, 0x9e, 0x75, 0x27, 0xa4, 0xfd, 0x8d, 0x57, 0xde, 0x00, 0xa8, 0x9c, 0x80, 0xa6, 0xe2, 0x53, 0xa2, 0x66, 0x5c, 0x5b, 0x0d, 0xb1, 0x97, 0xc2, 0x40, 0xda, 0x55, 0x51, 0x9a, 0x36, 0x4c, 0xc6, 0xbc, 0x29, 0xd9, 0x1e, 0x5a, 0x58, 0x36, 0x2d, 0x3d, 0x8e, 0x7d, 0xa1, 0x50, 0x58, 0x6a, 0x0f, 0xf2, 0x4f, 0xb0, 0x6f, 0xc9, 0x20, 0x09, 0x55, 0xc4, 0x86, 0x2a, 0x0f, 0x75, 0x85, 0x6d, 0x51, 0xbd, 0x75, 0x5f, 0xc3, 0xfe, 0x0c, 0xee, 0x03, 0xd0, 0xad, 0x89, 0x20, 0x4c, 0x92, 0xda, 0xbf, 0xa5, 0x3c, 0x87, 0xc0, 0x34, 0x08, 0x44, 0x58, 0x6c, 0x66, 0xee, 0x93, 0x6f, 0x46, 0x1b, 0x2e, 0x97, 0x86, 0x6c, 0x9a, 0x2c, 0xb7, 0x55, 0x48, 0xb4, 0x16, 0x9d, 0xcd, 0xfc, 0x89, 0xb5, 0x72, 0x9b, 0x89, 0xc1, 0x6c, 0x16, 0x8d, 0x9d, 0x15, 0x14, 0x5c, 0xe6, 0x5d, 0x08, 0x4d, 0x75, 0xf1, 0x7f, 0x40, 0xee, 0x9e, 0x51, 0xaf, 0xf6, 0xca, 0x29, 0x1b, 0xca, 0x8e, 0x5a, 0x43, 0x3b, 0x3f, 0x39, 0x4e, 0xff, 0x02, 0xdb, 0x76, 0x56, 0x33, 0xfe, 0xf4, 0xfb, 0xc3, 0xbe, 0x5f, 0xf9, 0x42, 0xe9, 0x53, 0x1c, 0x83, 0x52, 0x44, 0x07, 0x91, 0x0e, 0x11, 0x20, 0x60, 0xdd, 0xaf, 0x16, 0xc8, 0xca, 0xf1, 0x89, 0x31, 0x7c, 0xd3, 0xde, 0xe2, 0xd3, 0x59, 0x17, 0x27, 0xc5, 0xc0, 0x2b, 0x80, 0x7a, 0xdc, 0x25, 0x31, 0x83, 0xc4, 0x00, 0xb5, 0x4e, 0x88, 0x8a, 0x71, 0xdc, 0xcc, 0xbe, 0xfc, 0xbd, 0x47, 0x81, 0xac, 0xa1, 0xa6, 0xa8, 0x29, 0x2d, 0x91, 0x41, 0xff, 0x2e, 0x2c, 0xc7, 0x3c, 0x76, 0x3a, 0xa1, 0x0f, 0x1e, 0xbe, 0xf1, 0x09, 0xd5, 0x32, 0xfe, 0x63, 0x7e, 0x50, 0x06, 0x0f, 0x42, 0x0d, 0xf6, 0xa6, 0xb1, 0xd2, 0x76, 0x78, 0x13, 0xe1, 0xd3, 0x44, 0x33, 0xda, 0x48, 0xe5, 0x96, 0x4f, 0xa2, 0x1a, 0x9d, 0x21, 0xf1, 0x29, 0x28, 0x38, 0x47, 0xff, 0xc6, 0xb1, 0xbd, 0x93, 0xc5, 0x4a, 0x55, 0x33, 0xcb, 0xd7, 0x0d, 0x06, 0x7d, 0x06, 0xd9, 0x9b, 0x35, 0x62, 0x32, 0x6e, 0x35, 0xe5, 0x95, 0x9f, 0x68, 0x11, 0xba, 0x80, 0x22, 0xd7, 0xdb, 0x9d, 0x9f, 0x3b, 0xd6, 0x3d, 0x61, 0x75, 0x47, 0x07, 0x64, 0x2e, 0x3e, 0x72, 0xdc, 0x1b, 0xfe, 0x0e, 0xc3, 0x33, 0xa9, 0x13, 0x82, 0xa7, 0x54, 0x67, 0x0c, 0xe2, 0x88, 0x30, 0x69, 0x73, 0xdb, 0xcb, 0x61, 0xab, 0x46, 0xb6, 0x5b, 0x2d, 0x7b, 0x92, 0xfb, 0xe9, 0xb0, 0xcc, 0x0d, 0xf2, 0x2c, 0xfb, 0x42, 0x15, 0x33, 0x73, 0x03, 0xc2, 0xf7, 0x96, 0x66, 0x22, 0xb5, 0x2f, 0x17, 0x29, 0xca, 0xd7, 0xfd, 0xec, 0x7d, 0x2c, 0x72, 0xcc, 0x88, 0x65, 0x07, 0x6d, 0x9b, 0x4f, 0xea, 0xf4, 0x20, 0x56, 0x8c, 0x7f, 0x5a, 0x17, 0x92, 0xa1, 0x30, 0x09, 0x05, 0x85, 0xab, 0x32, 0x42, 0x4c, 0x9f, 0x67, 0xcd, 0xcc, 0xa3, 0x4d, 0x1a, 0xe7, 0x22, 0x03, 0x8b, 0x0d, 0x6a, 0x36, 0xef, 0xf0, 0xcd, 0x50, 0x20, 0x53, 0xdf, 0xa2, 0xdf, 0xe8, 0xb9, 0x94, 0xc3, 0xec, 0x2e, 0x49, 0xe7, 0x24, 0xe0, 0x9d, 0x12, 0xe7, 0x2e, 0x31, 0xfe, 0xd6, 0xa3, 0x2b, 0xd2, 0x38, 0x62, 0x6e, 0x9a, 0xbd, 0xe1, 0xea, 0xe6, 0x82, 0xa5, 0xff, 0x7e, 0x63, 0x87, 0x22, 0xf5, 0x42, 0x56, 0xc9, 0xa8, 0xc4, 0xa2, 0xa4, 0xa1, 0xf3, 0x6a, 0x76, 0x8b, 0x47, 0xb9, 0xe7, 0xb4, 0xe1, 0xe2, 0x18, 0xa7, 0x70, 0x94, 0xc8, 0x2f, 0xa0, 0xd9, 0xac, 0x55, 0x7d, 0x41, 0x34, 0x50, 0xfa, 0x24, 0x1c, 0x8e, 0xcb, 0x7e, 0xaf, 0xe3, 0x81, 0x5f, 0xaa, 0x44, 0x16, 0xad, 0xd0, 0x26, 0x1c, 0x19, 0xf3, 0xcd, 0x08, 0xc7, 0x51, 0x0b, 0x8d, 0xc0, 0xe9, 0xa4, 0xa2, 0xea, 0xeb, 0x4f, 0x1c, 0xc6, 0x73, 0x5c, 0x0c, 0xae, 0x8d, 0x59, 0xe0, 0x85, 0xdf, 0x82, 0x04, 0xa7, 0x9a, 0xa2, 0x08, 0xf7, 0x97, 0xfe, 0xc8, 0xe6, 0x66, 0xd5, 0x66, 0x3e, 0xc3, 0x73, 0xbf, 0x45, 0x42, 0xbd, 0x68, 0xf0, 0x47, 0xd1, 0xcd, 0xcc, 0xeb, 0xfd, 0x45, 0xe7, 0xa6, 0x71, 0x1f, 0xef, 0x78, 0x74, 0x37, 0xdb, 0x3d, 0xea, 0xbb, 0xcb, 0xe3, 0xe7, 0xbc, 0x2c, 0x88, 0xa8, 0xe6, 0x69, 0x31, 0xa5, 0x39, 0x7b, 0x47, 0x89, 0x5f, 0x4b, 0xfa, 0x12, 0xca, 0xb3, 0xd7, 0xcf, 0xcc, 0xb7, 0xe8, 0x29, 0x13, 0xbe, 0x08, 0xc7, 0xc4, 0x8d, 0x00, 0x5a, 0x8e, 0x22, 0x54, 0x1e, 0x9b, 0x6c, 0x30, 0x57, 0x41, 0x87, 0x04, 0x5d, 0x4e, 0x57, 0xa5, 0x34, 0x08, 0xb1, 0xa6, 0x70, 0xf2, 0x9a, 0x3e, 0x52, 0xce, 0x4b, 0xb1, 0x67, 0x35, 0x92, 0xb8, 0x12, 0x01, 0x61, 0x9b, 0x51, 0x2d, 0x00, 0xfc, 0xf7, 0x1a, 0xe8, 0x83, 0x1c, 0xd1, 0x4a, 0x9b, 0xed, 0x5e, 0x79, 0xa1, 0x30, 0x59, 0x6d, 0x29, 0x5f, 0xe2, 0x9e, 0x56, 0x68, 0x04, 0xa2, 0x65, 0x82, 0x72, 0xa0, 0x09, 0x78, 0x54, 0x82, 0x86, 0xb8, 0x82, 0x33, 0x19, 0x1d, 0xa3, 0xf7, 0x5f, 0x31, 0x72, 0xf9, 0x53, 0x8f, 0x6d, 0x60, 0xd4, 0x5e, 0x56, 0x89, 0x11, 0x70, 0x46, 0x61, 0x4a, 0x2d, 0xc7, 0x89, 0xdb, 0x31, 0x9e, 0x6e, 0x9d, 0xbc, 0x2a, 0x1f, 0x3d, 0xda, 0x19, 0x9c, 0x90, 0x5a, 0x28, 0x9f, 0xc9, 0x5f, 0x7a, 0x4a, 0xf9, 0xc7, 0xe2, 0xbe, 0x51, 0x01, 0x37, 0x0e, 0x81, 0x41, 0xb6, 0x2a, 0x66, 0xed, 0xc2, 0xf0, 0x7b, 0xfc, 0xb2, 0x50, 0xf6, 0xbb, 0x59, 0xe3, 0x48, 0x24, 0xea, 0x29, 0x86, 0x87, 0x75, 0x37, 0xaf, 0xee, 0x43, 0x7d, 0xe7, 0x49, 0xb8, 0x16, 0x36, 0x0f, 0xd0, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xbd, 0x06, 0xe6, 0x81, 0xc1, 0x10, 0x31, 0x00, 0x05, 0xbf, 0x21, 0x11, 0x00, 0x05, 0xb3, 0x65, 0x1e, 0x69, 0xb2, 0xda, 0xf8, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0xb3, 0x11, 0x81, 0x8c, 0xab, 0xb1, 0x64, 0x58, 0x83, 0x44, 0xea, 0xca, 0x89, 0xf8, 0x82, 0x03, 0x91, 0x6b, 0xef, 0xe8, 0x74, 0x4a, 0x34, 0xeb, 0xfc, 0x82, 0xd4, 0xab, 0xbb, 0x0d, 0x01, 0x7d, 0x87, 0xbf, 0x9c, 0x88, 0x78, 0xa2, 0xdb, 0x7e, 0x84, 0x22, 0xd7, 0xc7, 0x1f, 0x0c, 0x11, 0xe4, 0xea, 0xfe, 0x86, 0x42, 0xff, 0xe2, 0x10, 0x43, 0x61, 0x8a, 0xa2, 0xc3, 0x22, 0x18, 0x71, 0xbe, 0x17, 0x50, 0x3e, 0xd0, 0x4f, 0x33, 0x63, 0x31, 0x25, 0x6e, 0x5c, 0xd9, 0xac, 0x33, 0xc9, 0x28, 0xda, 0xbc, 0x89, 0xc6, 0xac, 0xd6, 0x64, 0x77, 0xf2, 0x35, 0x51, 0xee, 0xdc, 0x9a, 0x68, 0x67, 0xbc, 0xd4, 0x4f, 0x55, 0xc9, 0x30, 0x2a, 0x4a, 0x75, 0x23, 0xb5, 0x84, 0x2f, 0x03, 0xd9, 0x1a, 0xe2, 0xc8, 0xbb, 0xae, 0x95, 0xc9, 0xb1, 0xf4, 0xe7, 0xa2, 0x19, 0x13, 0xad, 0xd8, 0xcc, 0x0c, 0x9f, 0x75, 0xc9, 0xd4, 0x31, 0x6c, 0xfa, 0xb5, 0x5e, 0x57, 0xad, 0xe3, 0xad, 0xbc, 0x21, 0xc6, 0x42, 0xf5, 0x11, 0x4a, 0x48, 0x3d, 0x22, 0xf8, 0x91, 0x73, 0xbe, 0x51, 0x81, 0x1f, 0xd3, 0x44, 0xf9, 0x2a, 0xce, 0x34, 0x62, 0x8e, 0x1e, 0x3d, 0x57, 0x77, 0x8e, 0x7c, 0x12, 0x5b, 0x82, 0x97, 0x83, 0x9b, 0x91, 0x21, 0x8c, 0xde, 0xfa, 0x2b, 0xcc, 0xd0, 0x04, 0x2e, 0xe4, 0xaf, 0x05, 0x97, 0x22, 0x2d, 0x08, 0xf0, 0x2c, 0x5d, 0x41, 0xb8, 0xc6, 0x5e, 0xf1, 0x32, 0x4e, 0xa7, 0xc6, 0x71, 0xe4, 0x37, 0xb8, 0x3d, 0x70, 0xee, 0x96, 0xf6, 0x0b, 0x67, 0xd3, 0xb7, 0x60, 0x49, 0x17, 0x20, 0xec, 0x9a, 0xab, 0x38, 0x54, 0xd8, 0xdd, 0x6e, 0xd5, 0x43, 0xfd, 0x30, 0xfb, 0x9c, 0xdd, 0x2c, 0x38, 0xe3, 0x04, 0xed, 0x2d, 0x2f, 0x7a, 0x00, 0x87, 0xcf, 0x8e, 0xd4, 0x29, 0x2e, 0x55, 0xbc, 0x31, 0x03, 0xe9, 0x84, 0x97, 0x77, 0xca, 0x59, 0x4a, 0x4f, 0x4b, 0x51, 0x71, 0xc8, 0x3d, 0x28, 0x15, 0xd8, 0x83, 0xad, 0x19, 0x04, 0x70, 0x8e, 0xf8, 0xfc, 0xe3, 0x19, 0xa2, 0x54, 0x76, 0x32, 0xd1, 0xac, 0xdb, 0x20, 0x43, 0xfb, 0xbd, 0xfb, 0x34, 0x44, 0x67, 0xfc, 0x30, 0x69, 0xb4, 0x7a, 0x30, 0x0b, 0xf8, 0x89, 0xa9, 0x2f, 0x72, 0xc5, 0x48, 0x2e, 0x38, 0x76, 0xaa, 0x2b, 0xb3, 0xf8, 0xe4, 0xf5, 0xcb, 0x5f, 0xd7, 0xb9, 0x89, 0xfc, 0xf1, 0x2c, 0x6e, 0x68, 0xd8, 0x42, 0x7b, 0xb7, 0x36, 0xee, 0xe0, 0xff, 0x5f, 0x88, 0x58, 0x53, 0x37, 0x2e, 0xd5, 0x73, 0x21, 0x04, 0x59, 0x57, 0x68, 0xcd, 0xcb, 0xfa, 0x42, 0x3e, 0x77, 0x30, 0x0d, 0x7f, 0x5e, 0x38, 0x4c, 0xf2, 0x90, 0xac, 0x42, 0x6c, 0xc7, 0x5f, 0x3c, 0xc7, 0x82, 0x75, 0x61, 0xa8, 0xd3, 0xea, 0x09, 0x8a, 0xaa, 0xaf, 0x18, 0x22, 0x1b, 0x35, 0x4a, 0x30, 0x0d, 0x69, 0x0f, 0x4e, 0x6b, 0x48, 0xa3, 0x44, 0x50, 0xc4, 0xa8, 0x18, 0xc0, 0x1a, 0x53, 0xce, 0x84, 0x88, 0xab, 0x38, 0x1b, 0xc5, 0xe1, 0x6b, 0x23, 0x4e, 0x87, 0x6a, 0x71, 0xbd, 0x04, 0x7d, 0x0f, 0x6e, 0x3a, 0x62, 0x8d, 0xf7, 0x9d, 0xcc, 0x3d, 0xf4, 0x8e, 0xe3, 0xdc, 0x53, 0x75, 0x17, 0x56, 0xd0, 0x13, 0xe1, 0x35, 0x8a, 0x4f, 0xe0, 0xc9, 0xce, 0x2c, 0x50, 0x90, 0xbb, 0xbe, 0xd6, 0xf0, 0x75, 0xf3, 0x2e, 0xbc, 0xbd, 0x91, 0x34, 0xf5, 0x71, 0x12, 0x48, 0x91, 0x4d, 0xe2, 0x9b, 0xcb, 0x53, 0xdf, 0xa4, 0x87, 0xaf, 0x90, 0xc7, 0x8a, 0xad, 0x1a, 0xc6, 0x28, 0xd6, 0x12, 0x59, 0x8f, 0x31, 0x39, 0xf3, 0xb0, 0xb2, 0x7a, 0x43, 0xef, 0x69, 0x4e, 0xa9, 0x6e, 0xaf, 0x94, 0xbc, 0x10, 0x78, 0x60, 0x44, 0x54, 0x35, 0x7a, 0xfe, 0x36, 0x4a, 0xdd, 0xca, 0x55, 0x01, 0x55, 0xd7, 0x78, 0xcc, 0x7d, 0x4c, 0xeb, 0xd6, 0x0b, 0x81, 0x23, 0x33, 0x27, 0x2f, 0xaf, 0xfd, 0x8b, 0xf2, 0x59, 0x42, 0x77, 0x1e, 0xb7, 0x51, 0x58, 0xaf, 0xcf, 0x21, 0xd5, 0x8b, 0x04, 0x41, 0xb3, 0xc6, 0xb3, 0x8a, 0xf0, 0x07, 0xcb, 0x57, 0x80, 0xac, 0xb3, 0x4a, 0xfc, 0xb4, 0x55, 0x10, 0x5f, 0xc6, 0x21, 0xba, 0xfb, 0x52, 0x5a, 0xbb, 0x4f, 0x76, 0x35, 0x10, 0xa3, 0x7a, 0xff, 0x65, 0xe6, 0x43, 0x7a, 0xb6, 0x85, 0x35, 0x23, 0xa0, 0x9b, 0x22, 0x49, 0x04, 0x7c, 0x4a, 0xb2, 0xb0, 0x9e, 0x2b, 0xda, 0x4f, 0xf5, 0xac, 0xeb, 0x25, 0x71, 0x90, 0x9a, 0x47, 0xd7, 0xc1, 0x5c, 0x54, 0x2b, 0x10, 0xeb, 0x9f, 0xdd, 0x06, 0x80, 0xe0, 0x09, 0xd9, 0x34, 0x39, 0x5d, 0x94, 0x0d, 0x27, 0x99, 0xd4, 0x37, 0xba, 0xdf, 0xd4, 0x29, 0x1e, 0x15, 0x34, 0xe5, 0xe1, 0x72, 0x6b, 0x67, 0x3e, 0x7a, 0x1b, 0xd0, 0x42, 0x90, 0x91, 0x4a, 0xbe, 0x7d, 0x5c, 0xdb, 0x52, 0x4c, 0x59, 0xab, 0x9d, 0xa4, 0x2b, 0x8b, 0x9a, 0xb3, 0xf5, 0x3b, 0xa6, 0x30, 0xa9, 0x0a, 0x15, 0xb0, 0xa9, 0xd8, 0x86, 0x8e, 0x37, 0xf5, 0xbe, 0x0d, 0xb2, 0x59, 0x86, 0x3b, 0xf0, 0xec, 0xd0, 0xcb, 0x3c, 0x25, 0x10, 0xa6, 0x13, 0x0a, 0x82, 0xc8, 0xc4, 0x6a, 0xc3, 0x91, 0xdb, 0x46, 0x9a, 0x70, 0xc5, 0x58, 0xca, 0x4d, 0x84, 0x48, 0x48, 0x69, 0xc8, 0x9c, 0x17, 0xe3, 0x10, 0x1a, 0xba, 0x0e, 0x80, 0x75, 0x1f, 0xc3, 0xf9, 0x88, 0x93, 0xf6, 0x6d, 0x18, 0x9c, 0x93, 0xe8, 0xa0, 0x44, 0xef, 0x32, 0x03, 0xdd, 0xc0, 0x6b, 0xf7, 0x1c, 0x2c, 0x3f, 0x2f, 0xaa, 0x95, 0x5c, 0x2f, 0xd9, 0x3c, 0xeb, 0xc3, 0xd4, 0x22, 0x41, 0x20, 0x95, 0xf7, 0x50, 0xdc, 0x29, 0x54, 0x64, 0xbf, 0x1c, 0x3e, 0x21, 0x88, 0x74, 0xb9, 0x1c, 0x63, 0x2d, 0x7c, 0xe3, 0x91, 0xe5, 0x0e, 0xee, 0xae, 0xbf, 0x16, 0xeb, 0x4c, 0xa0, 0x3a, 0xa2, 0xab, 0xec, 0x3b, 0x7c, 0x9f, 0xe4, 0x82, 0xf8, 0xae, 0x3e, 0x0a, 0xab, 0x3b, 0xba, 0x7a, 0xc6, 0x5b, 0x98, 0x6c, 0x65, 0x7a, 0xcb, 0x8c, 0x98, 0x93, 0x76, 0x00, 0xc6, 0x2b, 0xcf, 0x52, 0x71, 0xec, 0x85, 0x29, 0xa0, 0xbc, 0xe3, 0xfc, 0xa3, 0x4a, 0xd0, 0x71, 0xe0, 0x13, 0x54, 0xbb, 0x1d, 0xb1, 0xe4, 0xfe, 0xd8, 0x97, 0xb0, 0x76, 0xa2, 0x7b, 0x8f, 0x47, 0xec, 0xa2, 0xdf, 0xa2, 0xb4, 0xf4, 0xee, 0x6c, 0x8d, 0x0d, 0x81, 0x6b, 0x36, 0x9b, 0x09, 0xd0, 0xb6, 0x80, 0x05, 0x93, 0x5d, 0x64, 0x99, 0xf5, 0xeb, 0xa1, 0xce, 0x57, 0xc4, 0x4a, 0x2c, 0x41, 0x7d, 0xd1, 0x58, 0x48, 0x40, 0x46, 0x70, 0xf2, 0x89, 0x56, 0xcc, 0x3d, 0xdf, 0xb1, 0x92, 0xb1, 0x6f, 0x9b, 0x2a, 0x39, 0xb8, 0xa9, 0xc8, 0x6b, 0x03, 0xf8, 0x21, 0x85, 0xf4, 0x59, 0x54, 0xb4, 0x92, 0xa4, 0xb5, 0x8d, 0x13, 0xf7, 0x4e, 0xfb, 0xc4, 0x56, 0x50, 0xc6, 0xe0, 0xcf, 0x17, 0x7e, 0x13, 0x3b, 0xfd, 0x94, 0x37, 0xbb, 0xc1, 0x8a, 0x59, 0x13, 0x6f, 0x02, 0xfe, 0x3e, 0xea, 0xff, 0x9b, 0x40, 0xed, 0xe3, 0x35, 0x77, 0x6a, 0x2b, 0x18, 0xab, 0xce, 0xea, 0x36, 0xfb, 0x68, 0x00, 0xba, 0xf1, 0xaa, 0xc6, 0x19, 0x9d, 0x9f, 0x8a, 0x90, 0xa5, 0xc1, 0xd5, 0xb5, 0x62, 0xdd, 0x39, 0xa4, 0x4c, 0x71, 0x0c, 0x4e, 0x7d, 0x23, 0xaf, 0x55, 0x87, 0x7f, 0x07, 0xf7, 0x31, 0x87, 0x75, 0xb6, 0x9f, 0x9f, 0x28, 0xa2, 0x54, 0xa8, 0x21, 0x06, 0x47, 0x3f, 0xbf, 0x29, 0x26, 0x3f, 0x9a, 0x4c, 0x2b, 0x15, 0x28, 0xb1, 0x3a, 0xc2, 0x2d, 0xda, 0x28, 0x52, 0xbb, 0x58, 0x6e, 0x96, 0xa3, 0x50, 0xe3, 0xd0, 0x5c, 0xe1, 0xd6, 0x98, 0xa5, 0x2e, 0xbb, 0x33, 0x9f, 0xd8, 0x55, 0x37, 0x85, 0x99, 0xd9, 0x49, 0x31, 0xe0, 0xfe, 0xbb, 0x9a, 0x8d, 0x01, 0x09, 0x52, 0x38, 0xac, 0xe6, 0x56, 0x6d, 0x8b, 0x16, 0x32, 0x96, 0xce, 0xac, 0x8e, 0x94, 0xfc, 0xf7, 0xd8, 0x4e, 0x56, 0x16, 0xea, 0xf3, 0x94, 0xf1, 0xe6, 0xa7, 0xf8, 0x30, 0xbc, 0x26, 0x58, 0x6b, 0x72, 0x92, 0xe1, 0x06, 0x8c, 0x41, 0x1f, 0x78, 0x8d, 0xca, 0x4f, 0x76, 0xff, 0x46, 0xe2, 0x18, 0xe0, 0xac, 0x7c, 0x0e, 0x46, 0x91, 0x59, 0x2c, 0x20, 0x42, 0x24, 0x70, 0xa8, 0x3d, 0x35, 0xfe, 0xae, 0x06, 0x9f, 0xc0, 0x62, 0x20, 0x6e, 0xcb, 0x5c, 0xe3, 0xcd, 0x7c, 0x8b, 0xbd, 0x1d, 0xe6, 0x67, 0x0e, 0x6e, 0xf1, 0xb3, 0x9b, 0xf2, 0xd0, 0x68, 0x1c, 0x7c, 0x34, 0x6f, 0xa1, 0x0c, 0x03, 0x75, 0x9d, 0x9d, 0x0d, 0x11, 0xc7, 0x32, 0x60, 0x3c, 0x44, 0x0e, 0x8d, 0x4e, 0xa8, 0x90, 0xc7, 0x6b, 0x2a, 0x37, 0x7f, 0x9c, 0x8b, 0x27, 0xe9, 0xde, 0xb4, 0xe4, 0x1a, 0xe9, 0x4f, 0x6b, 0x03, 0x0e, 0x4a, 0xb4, 0x03, 0x35, 0x58, 0x6b, 0xf4, 0x44, 0x19, 0x45, 0xc7, 0xb6, 0xca, 0x4a, 0xe6, 0xc3, 0x77, 0x81, 0x74, 0x19, 0x66, 0x7b, 0xdf, 0x38, 0x5e, 0x9a, 0x44, 0xef, 0xf7, 0x30, 0x84, 0x11, 0xb6, 0x1e, 0xd8, 0xd1, 0x0e, 0x9c, 0x7c, 0x56, 0x86, 0xc4, 0xa9, 0x0f, 0x68, 0x1c, 0xfc, 0x7d, 0x08, 0xf7, 0x0b, 0x96, 0x32, 0xee, 0x77, 0xdd, 0xdd, 0xed, 0x79, 0x0c, 0x77, 0x0f, 0x7c, 0x87, 0xae, 0xbe, 0x3a, 0x8c, 0xcd, 0x68, 0x55, 0xa3, 0xc2, 0xca, 0x88, 0x19, 0x01, 0xa2, 0x25, 0x11, 0x1b, 0x5b, 0x3b, 0xad, 0xe6, 0x46, 0xe0, 0xac, 0xc6, 0xca, 0x58, 0x7f, 0xd1, 0x04, 0xa1, 0x45, 0x65, 0xff, 0x45, 0x2e, 0x68, 0xef, 0xcf, 0x2f, 0x20, 0x65, 0xaa, 0x86, 0x23, 0x2a, 0xa9, 0x42, 0xcd, 0x98, 0xd7, 0x09, 0x79, 0xff, 0xbb, 0xb3, 0x7e, 0x93, 0x51, 0x8a, 0x01, 0xcd, 0x19, 0xad, 0xd3, 0xb3, 0xf8, 0x07, 0xea, 0x58, 0xed, 0xe7, 0x96, 0x0a, 0xf7, 0x0c, 0x10, 0xf4, 0x51, 0xb9, 0xa9, 0x4e, 0x2e, 0x6a, 0xd4, 0x05, 0x11, 0x6d, 0xab, 0xf4, 0xc5, 0x0f, 0xc9, 0xa9, 0x86, 0xe5, 0x4e, 0x05, 0xcb, 0xab, 0xea, 0x01, 0x68, 0x1a, 0xd4, 0x21, 0x0f, 0x61, 0x08, 0x65, 0x98, 0xac, 0x22, 0xc6, 0xd5, 0x01, 0x04, 0xfc, 0x2f, 0x5f, 0xf7, 0x55, 0x21, 0x23, 0x90, 0xb7, 0xf9, 0x3e, 0x3a, 0x47, 0x8b, 0x60, 0x60, 0x13, 0x09, 0x92, 0xd1, 0xe3, 0x5c, 0x03, 0x42, 0xad, 0xc4, 0x24, 0x35, 0x02, 0xc5, 0x86, 0xbc, 0x62, 0x13, 0x43, 0x31, 0xa0, 0x93, 0x83, 0x3c, 0xe1, 0x11, 0x36, 0x15, 0xa7, 0x30, 0x7d, 0x9b, 0x28, 0x36, 0x79, 0x16, 0xf8, 0xfd, 0xd0, 0x9e, 0x61, 0x40, 0x10, 0x52, 0xa0, 0x3b, 0x2f, 0xe8, 0x92, 0x7d, 0x5d, 0x73, 0x96, 0xb9, 0xfc, 0xcb, 0x93, 0x49, 0xcb, 0xc1, 0xa5, 0x25, 0xb6, 0x7b, 0x2e, 0x76, 0x14, 0xb3, 0x42, 0x80, 0xf7, 0xdb, 0xfe, 0xf0, 0x44, 0x42, 0x35, 0xd7, 0x78, 0x14, 0x2c, 0x06, 0x73, 0xa2, 0x9a, 0x50, 0xaf, 0x5c, 0x11, 0x56, 0x6c, 0x99, 0x27, 0x85, 0xad, 0x29, 0x06, 0x28, 0x5f, 0x32, 0xd1, 0x3b, 0x08, 0x24, 0xdf, 0x78, 0x7d, 0xeb, 0x4f, 0x18, 0x66, 0x14, 0xab, 0x5e, 0x25, 0x03, 0x79, 0xd4, 0x96, 0x9f, 0x47, 0xe0, 0x94, 0x57, 0x27, 0x3a, 0xd1, 0x17, 0x1e, 0xa4, 0x58, 0x9f, 0x81, 0x06, 0x77, 0x45, 0xbc, 0x3a, 0x0a, 0x21, 0x11, 0x91, 0xa1, 0xf9, 0x0d, 0xd3, 0xfb, 0xb0, 0x94, 0x43, 0xee, 0x0c, 0xed, 0x73, 0x13, 0xb1, 0x1b, 0x1a, 0xd7, 0xd8, 0xbe, 0xc3, 0xe2, 0xde, 0x2b, 0x48, 0x77, 0xaa, 0x8e, 0x41, 0x69, 0x55, 0x37, 0xec, 0x65, 0xf2, 0x28, 0xf1, 0xcd, 0x31, 0xf8, 0xe5, 0x12, 0x01, 0xf6, 0x96, 0xd2, 0x68, 0x94, 0x22, 0xd0, 0x5b, 0x02, 0xf7, 0x58, 0x5d, 0x29, 0x35, 0xc8, 0xba, 0xeb, 0xf1, 0x79, 0x85, 0x35, 0x90, 0x78, 0x85, 0xd9, 0xe7, 0xd4, 0xa3, 0x80, 0x81, 0x76, 0x32, 0xb1, 0x0a, 0xfc, 0x75, 0xd9, 0x89, 0x87, 0x53, 0x4d, 0xf2, 0x98, 0x69, 0x81, 0xc3, 0xf9, 0x19, 0x61, 0xd2, 0x88, 0xf8, 0x62, 0xf7, 0x24, 0xf7, 0x27, 0x77, 0x51, 0x96, 0x83, 0x85, 0x86, 0xe9, 0xdc, 0x8e, 0xb6, 0x8f, 0xef, 0x35, 0xff, 0xa9, 0xe3, 0x34, 0x29, 0x6e, 0x3b, 0x94, 0x5a, 0xf6, 0x7b, 0x17, 0x76, 0x7a, 0x5b, 0xde, 0x2b, 0x09, 0xf1, 0x33, 0x5d, 0x74, 0xe4, 0x62, 0x99, 0xdb, 0x7a, 0x4b, 0xc3, 0xdc, 0x7c, 0x26, 0x72, 0xbe, 0x66, 0x11, 0xde, 0xcf, 0xdc, 0xed, 0x3c, 0x06, 0x51, 0xae, 0x51, 0x39, 0x68, 0x72, 0x00, 0x87, 0x1a, 0x97, 0x19, 0x61, 0x56, 0xe6, 0x1d, 0x8b, 0x47, 0xb2, 0x82, 0x19, 0x7d, 0xe3, 0x0f, 0xbc, 0xab, 0x72, 0xdc, 0x5d, 0x32, 0x71, 0x5e, 0xcc, 0x96, 0x3d, 0x2b, 0x02, 0x57, 0x34, 0x84, 0xfc, 0x3f, 0x81, 0xb6, 0x94, 0xca, 0x93, 0xef, 0x5b, 0x94, 0x0e, 0xc0, 0xaf, 0xb7, 0x57, 0x62, 0x31, 0x0e, 0x01, 0x8d, 0xef, 0x50, 0x12, 0x96, 0xca, 0xc7, 0x4b, 0x0f, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xbd, 0x06, 0xe6, 0x81, 0xc1, 0x14, 0x31, 0x00, 0x05, 0xbf, 0x21, 0x11, 0x00, 0x05, 0xb3, 0x65, 0x1e, 0x69, 0xb2, 0x33, 0xc2, 0x90, 0xa3, 0x43, 0x52, 0x20, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x00, 0xd7, 0x18, 0xa6, 0xad, 0x12, 0x6a, 0x1a, 0xaa, 0xe9, 0xfb, 0x77, 0x1a, 0x30, 0x10, 0x87, 0x2d, 0xaa, 0x12, 0x77, 0x0a, 0x87, 0x16, 0x82, 0x84, 0xc6, 0x2b, 0xc0, 0x05, 0x5f, 0xfd, 0x4c, 0x34, 0xd3, 0x24, 0xde, 0x70, 0xd4, 0xaa, 0x4f, 0x07, 0x56, 0x02, 0xca, 0xe5, 0xb1, 0x3d, 0xfa, 0x58, 0xbf, 0x2b, 0x08, 0x68, 0x8d, 0x6d, 0x9f, 0x2e, 0x81, 0x52, 0x95, 0xba, 0xcf, 0x71, 0xb3, 0xe2, 0xe9, 0x11, 0xce, 0x92, 0x3a, 0xab, 0x95, 0x92, 0x40, 0xb8, 0x35, 0xc0, 0x18, 0x0c, 0xff, 0x41, 0x16, 0x53, 0x0a, 0xe2, 0x36, 0xd8, 0x4c, 0x4e, 0xb3, 0x93, 0x88, 0xac, 0x8a, 0xcd, 0x23, 0xa5, 0xb7, 0x1b, 0x1c, 0x28, 0x91, 0x74, 0x1a, 0x86, 0x9a, 0xcb, 0x1b, 0x8d, 0xc4, 0x00, 0xf1, 0x30, 0x95, 0xa3, 0x36, 0x25, 0xd6, 0x07, 0x6b, 0x41, 0x23, 0xdc, 0x6b, 0x0b, 0xd3, 0x02, 0x7c, 0xd2, 0xfc, 0x03, 0xf6, 0xaa, 0xf6, 0x49, 0xc9, 0x8a, 0x45, 0x19, 0xc7, 0xf9, 0x96, 0x06, 0xc2, 0xe6, 0x6e, 0x2e, 0x1e, 0xbc, 0x49, 0x68, 0xa8, 0x37, 0x57, 0x7a, 0xeb, 0x09, 0x52, 0xd4, 0x1c, 0x8a, 0xe1, 0x09, 0x53, 0xe9, 0x93, 0x82, 0x96, 0xe7, 0x0a, 0x8b, 0x03, 0x63, 0x9a, 0x24, 0x96, 0xd0, 0xfc, 0x33, 0xe0, 0xdc, 0x77, 0x41, 0x1d, 0xd5, 0x1f, 0x1b, 0x05, 0x16, 0x1e, 0x31, 0x4f, 0xdf, 0x3c, 0xa6, 0x26, 0xc3, 0x4f, 0xef, 0x13, 0x3a, 0x39, 0x72, 0x18, 0x9b, 0x8e, 0x54, 0x77, 0x69, 0xf9, 0x71, 0x4a, 0x3e, 0x01, 0x19, 0x59, 0x8d, 0xe5, 0x3b, 0x45, 0xe4, 0xb1, 0x2a, 0xa7, 0xc8, 0x17, 0xb3, 0xd5, 0x9b, 0x75, 0xd5, 0xab, 0x03, 0x36, 0x11, 0xf7, 0xab, 0x75, 0xf3, 0x60, 0x4a, 0xc3, 0x5a, 0xed, 0xd4, 0x27, 0xfb, 0x1b, 0xc5, 0xce, 0x33, 0x5b, 0x76, 0x54, 0x8d, 0xe8, 0x00, 0xc9, 0xa7, 0x20, 0x4b, 0xc8, 0x1d, 0x67, 0xe8, 0xdd, 0x07, 0x47, 0x8d, 0x5c, 0xd9, 0xb3, 0x7d, 0xf7, 0x02, 0x64, 0x50, 0x89, 0xae, 0x89, 0x41, 0x65, 0x09, 0xa3, 0x86, 0x28, 0x38, 0xf0, 0x56, 0x19, 0x11, 0x0a, 0x6c, 0x8d, 0x0c, 0x1f, 0x3c, 0x3b, 0x83, 0x22, 0xd3, 0x1d, 0x8d, 0xab, 0x22, 0x13, 0xad, 0x7a, 0x82, 0x27, 0x66, 0x97, 0x02, 0x80, 0xc1, 0xa0, 0x29, 0xcc, 0x71, 0x1f, 0x34, 0xe6, 0x9f, 0x9e, 0x35, 0xb2, 0x5e, 0x78, 0x52, 0xa9, 0x23, 0xac, 0x23, 0xd5, 0x6b, 0x69, 0x2e, 0xa8, 0xdd, 0x3e, 0x33, 0x62, 0x99, 0x6d, 0x1f, 0xa1, 0xfb, 0xd4, 0x8f, 0xb7, 0xba, 0x05, 0x9b, 0x74, 0x36, 0x44, 0xa8, 0xe3, 0x4e, 0xfe, 0xba, 0x9f, 0x63, 0x10, 0x2f, 0x96, 0xfa, 0x9b, 0xec, 0x87, 0x41, 0x05, 0xc4, 0x41, 0xf4, 0x81, 0x02, 0xc8, 0x6e, 0x30, 0x81, 0x8b, 0xfa, 0x67, 0x55, 0x8a, 0xed, 0xa6, 0x6c, 0xd7, 0x66, 0xad, 0x15, 0x2b, 0x00, 0xbc, 0x69, 0x04, 0x4b, 0x7d, 0x81, 0x3e, 0x80, 0xed, 0x0a, 0xb2, 0x68, 0x88, 0xc5, 0x56, 0x32, 0x7c, 0x4c, 0xb2, 0x0f, 0xef, 0xfe, 0x3c, 0x1b, 0x6e, 0xfe, 0x28, 0x08, 0x2c, 0x71, 0x48, 0xaf, 0x4a, 0xe0, 0xb6, 0x42, 0x9e, 0x0b, 0x9e, 0xce, 0x8e, 0xed, 0x58, 0x8b, 0x50, 0x63, 0xd0, 0x2e, 0x66, 0x04, 0x7f, 0xc8, 0xea, 0xb4, 0x38, 0xc5, 0x76, 0xe6, 0xba, 0xb4, 0x17, 0xaa, 0x80, 0xd5, 0x64, 0x98, 0x50, 0x78, 0xa3, 0xce, 0x1d, 0x6d, 0x6f, 0xb4, 0x65, 0x7e, 0xd8, 0xd4, 0x17, 0xdf, 0x68, 0x0c, 0xf7, 0x56, 0xcf, 0xfa, 0x8a, 0xca, 0x5d, 0x1c, 0xa6, 0x72, 0x00, 0x39, 0xea, 0x79, 0xca, 0x4e, 0x63, 0x93, 0x51, 0x20, 0xbc, 0xea, 0xa4, 0x69, 0x05, 0xbd, 0xd4, 0xc1, 0xa4, 0xd4, 0xd0, 0xbd, 0x1a, 0x66, 0xc4, 0x4e, 0xbc, 0xca, 0xf7, 0x25, 0xd8, 0x9a, 0x42, 0x63, 0x7d, 0x15, 0x2f, 0xd1, 0x46, 0x63, 0xf3, 0xf9, 0x6a, 0x2e, 0x8f, 0x4e, 0xe5, 0xc2, 0x46, 0xee, 0x22, 0x93, 0x3b, 0x2c, 0x07, 0x5d, 0xfe, 0x7d, 0x8f, 0x75, 0x84, 0xbc, 0x22, 0x06, 0x58, 0x38, 0x76, 0x9e, 0x8f, 0x71, 0xbe, 0x07, 0x16, 0x61, 0xff, 0x25, 0x64, 0x7f, 0x32, 0x84, 0x88, 0xe1, 0xd2, 0xb1, 0x1e, 0xd6, 0xba, 0x24, 0x0c, 0x72, 0xbf, 0xf3, 0x7a, 0xa1, 0xfe, 0x76, 0x65, 0xab, 0xaa, 0x27, 0xfb, 0x68, 0x1e, 0x67, 0x59, 0x75, 0xec, 0x6d, 0x8d, 0x68, 0xe3, 0xb3, 0x42, 0x20, 0x3a, 0x76, 0x65, 0xa5, 0x7e, 0xd2, 0xca, 0x62, 0xb2, 0x7e, 0xe0, 0x24, 0xae, 0x2d, 0x3b, 0x2a, 0x89, 0xc2, 0xf0, 0xc2, 0xc8, 0x66, 0xb8, 0xbe, 0xfb, 0x53, 0x89, 0x2f, 0x1f, 0x2c, 0xda, 0x5c, 0x02, 0x50, 0x7a, 0x11, 0x6f, 0x64, 0x52, 0xd5, 0x53, 0x8f, 0x9a, 0xa9, 0x0f, 0x30, 0xfa, 0xee, 0x5c, 0x68, 0xd6, 0x6f, 0x5f, 0xb7, 0x95, 0xd9, 0xa9, 0x1b, 0x62, 0x51, 0xd2, 0xf8, 0x99, 0x7a, 0x6c, 0xb5, 0xe1, 0x27, 0x4b, 0x06, 0xed, 0xbc, 0x18, 0x25, 0x21, 0xe5, 0x62, 0x5e, 0x15, 0xb8, 0x14, 0x24, 0xb1, 0xd1, 0x40, 0x1f, 0x36, 0xf7, 0x8d, 0xa6, 0xb2, 0xfd, 0xb2, 0x07, 0x2c, 0xbe, 0x05, 0x4d, 0x75, 0x72, 0xbc, 0xf1, 0xbc, 0xc9, 0x0c, 0xc2, 0x8c, 0xa0, 0x70, 0x63, 0x14, 0xe2, 0xec, 0x7e, 0x6c, 0xf6, 0xbb, 0xb5, 0x40, 0x53, 0xda, 0x97, 0x27, 0x21, 0xb0, 0x46, 0x48, 0x59, 0x35, 0xd2, 0x98, 0xb0, 0x84, 0x03, 0x3d, 0xe6, 0x0f, 0xb5, 0xf0, 0x5d, 0xa6, 0xc0, 0xcd, 0xf3, 0x75, 0x02, 0xda, 0xce, 0x20, 0x06, 0x12, 0x15, 0xac, 0xe0, 0xae, 0xe8, 0x06, 0x1c, 0x8d, 0x4c, 0x96, 0xca, 0x03, 0x45, 0x74, 0xc1, 0x02, 0x96, 0xe1, 0xeb, 0x8f, 0xc4, 0xb2, 0xe7, 0xae, 0xd8, 0xbe, 0x52, 0x9b, 0x0f, 0xa5, 0xf9, 0x4e, 0x27, 0xab, 0x96, 0xc9, 0x27, 0xed, 0x89, 0xd0, 0x3c, 0x45, 0xa5, 0x18, 0xe3, 0x4c, 0xc6, 0x99, 0x9d, 0xe9, 0x9b, 0x83, 0x56, 0x16, 0x5d, 0x3a, 0x21, 0x82, 0x19, 0x48, 0x6c, 0x73, 0x3f, 0x0d, 0xf0, 0x3e, 0xce, 0x86, 0x70, 0x0c, 0x22, 0xdb, 0x7d, 0x0e, 0x5b, 0x35, 0x98, 0x73, 0x7a, 0x33, 0x94, 0xf9, 0x78, 0xd8, 0xee, 0x5e, 0x99, 0xb0, 0x8b, 0xd3, 0x42, 0x46, 0x6e, 0x93, 0x1b, 0x25, 0xa8, 0x14, 0xa8, 0x7d, 0xc4, 0x7b, 0x01, 0xc1, 0x01, 0xdd, 0x05, 0x57, 0x4b, 0x2a, 0x74, 0xda, 0x2e, 0x04, 0x58, 0x10, 0x34, 0xd1, 0x0e, 0xaa, 0xca, 0x24, 0x66, 0x91, 0x17, 0xec, 0xca, 0xab, 0xb7, 0x6d, 0xa2, 0x35, 0xad, 0x0d, 0x60, 0xd3, 0x36, 0xbd, 0x63, 0x40, 0x8b, 0xd7, 0xad, 0x42, 0x17, 0xe8, 0xda, 0xc6, 0x27, 0x72, 0xcc, 0x78, 0x18, 0x8e, 0x66, 0x20, 0xc8, 0x84, 0x86, 0x5d, 0x59, 0x20, 0x3e, 0x7c, 0x08, 0x7e, 0x66, 0xaf, 0x9b, 0x38, 0x3e, 0x34, 0x4b, 0x33, 0xa7, 0xf1, 0xce, 0x27, 0x04, 0x6d, 0xc1, 0x2f, 0xa7, 0x85, 0xa7, 0x96, 0x84, 0x42, 0xb0, 0x73, 0x70, 0xd1, 0xe5, 0xa1, 0xbf, 0xec, 0x65, 0xce, 0xe8, 0x50, 0x2e, 0x2d, 0x61, 0xca, 0xb6, 0x7d, 0xb5, 0x4e, 0x48, 0x20, 0xc8, 0x80, 0x52, 0x5e, 0xca, 0xfb, 0xc4, 0x1b, 0xdb, 0x4e, 0x46, 0xcc, 0x49, 0xe6, 0xef, 0xb5, 0xde, 0x99, 0xdb, 0x65, 0x74, 0x05, 0xe3, 0x47, 0xa1, 0xd6, 0x7a, 0xed, 0x91, 0xd6, 0xe3, 0x81, 0x27, 0x50, 0x0d, 0x41, 0xc1, 0xf5, 0x93, 0x25, 0x2b, 0x6c, 0xa9, 0x36, 0xd2, 0xe7, 0x1e, 0xe0, 0xa9, 0x95, 0x68, 0xfd, 0xa7, 0xb9, 0xe1, 0x81, 0x95, 0xd0, 0x8c, 0xce, 0x12, 0x6c, 0xe0, 0x29, 0x6f, 0xee, 0x33, 0xde, 0x46, 0x64, 0xa9, 0x72, 0x82, 0x03, 0x1d, 0x1e, 0xdd, 0x9f, 0x1c, 0x5c, 0x39, 0xc8, 0xc3, 0x16, 0x9c, 0xf6, 0xb3, 0x7b, 0xec, 0x86, 0xb9, 0xe9, 0xe1, 0x4e, 0xb1, 0x14, 0xfd, 0x9c, 0x26, 0xb3, 0x81, 0x25, 0xab, 0x4c, 0x25, 0xd3, 0xa2, 0x63, 0x77, 0x0f, 0xf5, 0x26, 0xc5, 0x14, 0x0c, 0x53, 0x35, 0xa7, 0x7d, 0xa0, 0xce, 0x4e, 0x04, 0x97, 0x77, 0x4c, 0x74, 0x6a, 0xf3, 0xeb, 0xdd, 0xae, 0x27, 0xfc, 0xf7, 0xd0, 0x21, 0xea, 0x46, 0x36, 0x22, 0x84, 0x9d, 0x8c, 0x0c, 0xef, 0x87, 0x0c, 0xac, 0x3a, 0xcc, 0x76, 0xf3, 0xe0, 0xac, 0x7d, 0x01, 0x93, 0x1a, 0x2d, 0x42, 0x99, 0xf3, 0x46, 0xc6, 0xa5, 0x87, 0x9a, 0x44, 0xa4, 0x29, 0xa2, 0xb3, 0x5c, 0x80, 0x10, 0xd4, 0xb7, 0x35, 0x58, 0xc0, 0xd2, 0x65, 0x14, 0x28, 0x4c, 0x95, 0x6e, 0x9b, 0x33, 0x6c, 0x9a, 0xf5, 0x8b, 0x33, 0x92, 0xae, 0x89, 0x53, 0xc5, 0x08, 0x62, 0xbd, 0x57, 0x72, 0xad, 0xb9, 0x35, 0x2c, 0xe5, 0xf6, 0xa4, 0x70, 0xeb, 0xd1, 0xb9, 0x6c, 0x58, 0x1a, 0x12, 0xf5, 0x55, 0xb9, 0x95, 0x69, 0x22, 0xcf, 0x58, 0x88, 0xd2, 0x3f, 0x1f, 0x1d, 0xca, 0x90, 0x5e, 0x73, 0xce, 0x9d, 0xd6, 0x8b, 0x74, 0xa6, 0xb2, 0xe2, 0x62, 0x64, 0xa0, 0xa6, 0xc4, 0xfe, 0xf7, 0x4b, 0x07, 0x37, 0xd2, 0xe3, 0xd3, 0xe1, 0xc3, 0x92, 0xd0, 0x7c, 0x1c, 0x93, 0x08, 0xd9, 0xc5, 0x76, 0xeb, 0x45, 0x58, 0x3f, 0xf4, 0x2c, 0xab, 0xca, 0x93, 0x5c, 0x6c, 0x75, 0xed, 0x1e, 0xa1, 0x15, 0xc5, 0xfa, 0x22, 0xbd, 0x40, 0x6b, 0x96, 0xae, 0xa3, 0x4c, 0x49, 0xee, 0xb9, 0xd7, 0x85, 0x53, 0x24, 0x11, 0x86, 0x43, 0x18, 0x9b, 0x3c, 0x00, 0x89, 0x48, 0x73, 0x5c, 0x91, 0x1b, 0x80, 0x9a, 0x19, 0x0e, 0x19, 0x35, 0x95, 0x51, 0x88, 0xfe, 0xe9, 0x2c, 0x59, 0xdd, 0x95, 0x19, 0xe6, 0x71, 0xa8, 0x84, 0x66, 0x2c, 0xee, 0xc0, 0xa7, 0x4b, 0x9d, 0xef, 0xbf, 0xa5, 0x11, 0x0f, 0xb7, 0xa8, 0x38, 0xb6, 0x4c, 0x1c, 0x93, 0x3d, 0x00, 0x32, 0xb2, 0x4b, 0xb4, 0x7d, 0xf7, 0xb0, 0xab, 0xdb, 0xc0, 0xb0, 0xb1, 0x71, 0x2c, 0xd7, 0x83, 0x2e, 0xe8, 0x88, 0x3b, 0x01, 0xb2, 0xe1, 0x36, 0xcf, 0xca, 0xea, 0x6f, 0xd8, 0x09, 0xa7, 0x6d, 0x61, 0x99, 0x29, 0x35, 0x46, 0xc7, 0xf2, 0x0d, 0xf6, 0xd0, 0x4b, 0x4e, 0x8f, 0x66, 0x58, 0x31, 0x0b, 0x0b, 0x74, 0xbc, 0x31, 0x3d, 0x35, 0x7d, 0x54, 0x3f, 0x13, 0x47, 0x24, 0xb9, 0xea, 0x94, 0x48, 0x4c, 0x3c, 0xdc, 0xb1, 0x97, 0x0f, 0xbe, 0x74, 0x07, 0xe1, 0x80, 0x98, 0x6c, 0xd4, 0xc5, 0xd1, 0xe9, 0x7e, 0x00, 0xf1, 0x79, 0x26, 0x2e, 0xdc, 0x90, 0x91, 0xb1, 0x44, 0x7e, 0xa4, 0x8f, 0x48, 0xe8, 0xea, 0xbf, 0x39, 0xfe, 0xb3, 0xb3, 0x60, 0xed, 0xfa, 0xc8, 0x89, 0x27, 0x16, 0x76, 0x58, 0x51, 0xcc, 0xa7, 0xf5, 0x24, 0x8a, 0xaa, 0x0d, 0x19, 0x36, 0x92, 0x66, 0x1b, 0xe9, 0x9f, 0xb7, 0x26, 0x12, 0xf2, 0xf5, 0x36, 0x33, 0x88, 0x5a, 0xa1, 0x54, 0x41, 0x69, 0x3b, 0x05, 0x46, 0x2d, 0x8c, 0x00, 0xc5, 0xf9, 0x67, 0x63, 0xba, 0x6f, 0x01, 0x4f, 0x4a, 0x82, 0x2f, 0x28, 0x35, 0xc8, 0x01, 0xce, 0x6f, 0xc8, 0x5a, 0xea, 0x24, 0x14, 0xeb, 0xf0, 0x69, 0x93, 0x50, 0xd9, 0x2b, 0x96, 0x8c, 0x5e, 0x75, 0x50, 0x92, 0xea, 0xcb, 0xcd, 0x38, 0x87, 0xdf, 0x0f, 0x21, 0x2c, 0x8c, 0x28, 0xdc, 0xc7, 0x94, 0x6a, 0x32, 0xe6, 0x67, 0xa0, 0x6b, 0x54, 0xf8, 0x10, 0x92, 0xa6, 0xc7, 0x55, 0xba, 0xc5, 0x82, 0xf8, 0x98, 0x96, 0x1f, 0x0a, 0x54, 0x86, 0xd9, 0x6c, 0xa7, 0xa8, 0x1f, 0x0d, 0x15, 0x54, 0x89, 0x10, 0xe5, 0xe5, 0xb5, 0xe2, 0x2c, 0x21, 0x0a, 0x70, 0x49, 0x43, 0x5f, 0xa5, 0xa2, 0xa9, 0x38, 0x4a, 0x93, 0x43, 0x5f, 0xfe, 0xd2, 0x8b, 0xfb, 0x56, 0x3d, 0x05, 0x2a, 0xd8, 0x74, 0x49, 0x15, 0x2b, 0xcb, 0xcb, 0xf0, 0x01, 0x54, 0x50, 0x9d, 0xed, 0x71, 0xcf, 0x19, 0x6d, 0x49, 0x68, 0xdc, 0x66, 0x33, 0xa9, 0x42, 0x6f, 0xe6, 0x0e, 0xd8, 0xd1, 0x4b, 0x22, 0x3a, 0x8c, 0xc0, 0x81, 0x5a, 0xc8, 0x64, 0x97, 0x18, 0x3d, 0xf8, 0xad, 0x3b, 0xec, 0x6f, 0x9a, 0x17, 0x90, 0x47, 0x38, 0x6a, 0xfe, 0x56, 0x80, 0x88, 0x6d, 0xfa, 0x00, 0xba, 0xda, 0x66, 0x45, 0x41, 0x06, 0x3e, 0xe0, 0x4b, 0xdc, 0x83, 0x59, 0x71, 0x16, 0x99, 0x6e, 0xc9, 0x41, 0xa3, 0x81, 0x3c, 0xf7, 0x18, 0x96, 0x6a, 0x24, 0x40, 0x6f, 0x3f, 0xbd, 0x6a, 0xe7, 0xba, 0x63, 0xff, 0xe8, 0x4b, 0x75, 0xc3, 0x54, 0xe6, 0xc8, 0xc8, 0x89, 0x29, 0x2e, 0x4a, 0xec, 0xf3, 0x2f, 0x6d, 0x84, 0x31, 0xc3, 0x22, 0x52, 0x62, 0xf6, 0xf3, 0x16, 0xe9, 0xcb, 0xe0, 0x68, 0xef, 0x75, 0x7a, 0x6d, 0x95, 0xdf, 0x84, 0x3a, 0xa0, 0x10, 0xf8, 0x7d, 0x1d, 0xda, 0x8d, 0x8a, 0x30, 0x18, 0xd5, 0x80, 0xd4, 0x4e, 0x05, 0xbc, 0x6d, 0x1f, 0x79, 0x3d, 0x83, 0x0a, 0x5a, 0x4f, 0x41, 0xb4, 0x46, 0xba, 0xcb, 0x0f, 0xd0, 0xc9, 0x87 }; +constexpr AccessUnit ATRACX_MULTIPLE_PACK_EXPECTED_AU_1 = { 0x15f90, 0x159b2, false, 0, {}, { 0x78, 0x2c, 0xd2, 0xa4, 0x87, 0x7f, 0xa1, 0xcb, 0x57, 0xad, 0x86, 0x2b, 0xe4, 0xb7, 0xe1, 0xfc, 0xa1, 0xab, 0xb8, 0xc5 } }; +constexpr AccessUnit ATRACX_MULTIPLE_PACK_EXPECTED_AU_2 = { 0x2aefeae9, 0x778806c4, false, 0, {}, { 0x0e, 0x9b, 0x87, 0x06, 0x59, 0x9a, 0xe2, 0xb6, 0xf7, 0x53, 0xfc, 0x2d, 0x47, 0x60, 0xca, 0x7d, 0x52, 0xd1, 0xd4, 0x61 } }; +constexpr AccessUnit ATRACX_MULTIPLE_PACK_EXPECTED_AU_3 = { 0x15f90, 0x159b2, false, 0, {}, { 0x59, 0x1b, 0x5e, 0x0b, 0x45, 0xe7, 0x7d, 0xfb, 0x30, 0x15, 0xce, 0x9b, 0xc1, 0xea, 0xc7, 0x1c, 0xad, 0x4d, 0x3c, 0xe1 } }; +constexpr AccessUnit ATRACX_MULTIPLE_PACK_EXPECTED_AU_4 = { std::numeric_limits::max(), std::numeric_limits::max(), false, 0, {}, { 0x8c, 0xf7, 0x8f, 0x01, 0x95, 0x33, 0x90, 0xf4, 0xb6, 0x81, 0xcf, 0x8f, 0x9f, 0xd2, 0xf0, 0x9c, 0xd9, 0xae, 0xc1, 0xe4 } }; + +constexpr std::array AC3_MULTIPLE_PACK_STREAM = { 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xbd, 0x06, 0xe6, 0x81, 0xc1, 0x0d, 0x31, 0x00, 0x05, 0xbf, 0x21, 0x11, 0x00, 0x05, 0xb3, 0x65, 0x1e, 0x69, 0xb2, 0x30, 0x00, 0x00, 0x00, 0xf3, 0xa6, 0x50, 0x0c, 0xe5, 0x05, 0x0e, 0x03, 0xb9, 0x70, 0x70, 0xf1, 0xfa, 0xac, 0xf5, 0xd7, 0x56, 0x65, 0xa2, 0x06, 0x5a, 0x45, 0xc1, 0x76, 0x51, 0xd2, 0xde, 0x1a, 0xcd, 0x4c, 0xa4, 0x7c, 0xb5, 0xaf, 0xc9, 0xc6, 0xd5, 0xd5, 0x4b, 0x35, 0x5b, 0x70, 0x38, 0xbb, 0xf4, 0x89, 0x9d, 0x5d, 0xa7, 0x5d, 0x05, 0x21, 0x84, 0x11, 0xf6, 0xdc, 0x83, 0x0a, 0x1b, 0xa7, 0x79, 0x16, 0xe5, 0xdc, 0x2a, 0x8e, 0x45, 0x86, 0xe5, 0x45, 0xdc, 0x0b, 0x77, 0x56, 0xd1, 0x5d, 0x71, 0x45, 0xf7, 0xb6, 0xbe, 0x24, 0xd4, 0x03, 0xce, 0xea, 0x38, 0xed, 0xc8, 0x79, 0xb8, 0x05, 0xbb, 0x49, 0x5c, 0x08, 0xbe, 0x2c, 0x9c, 0x06, 0xf2, 0x58, 0x04, 0x30, 0x62, 0x75, 0x45, 0x3e, 0xf8, 0xda, 0x1b, 0x63, 0x06, 0x96, 0x35, 0xc2, 0x03, 0xdc, 0x2a, 0x0c, 0xb9, 0x61, 0x06, 0x1f, 0x66, 0x46, 0xa1, 0xe5, 0x40, 0xba, 0xec, 0xf2, 0x4b, 0xdc, 0xab, 0xd3, 0xaa, 0xe0, 0xf4, 0x3a, 0xdd, 0x40, 0x0d, 0xfb, 0x6e, 0x2e, 0x79, 0x1c, 0xd4, 0xd0, 0x41, 0xd1, 0x3b, 0x26, 0x9e, 0x84, 0xc7, 0x3b, 0x94, 0x6a, 0x46, 0x67, 0xef, 0x5c, 0x96, 0x31, 0xa4, 0xea, 0xb8, 0xfa, 0x4d, 0x1b, 0xac, 0x8b, 0x4c, 0xe5, 0x90, 0xc7, 0xda, 0x98, 0x01, 0xcb, 0x2e, 0x86, 0x8f, 0xbe, 0xb5, 0x8a, 0x3e, 0x01, 0xad, 0xb9, 0x24, 0x7f, 0x7a, 0xb8, 0xe9, 0xb3, 0x64, 0xe0, 0xe1, 0x32, 0x40, 0xed, 0x30, 0x1c, 0x3a, 0x1b, 0x22, 0x86, 0xee, 0xf1, 0x7d, 0xbc, 0x2a, 0xd6, 0x2e, 0x01, 0x1b, 0x0d, 0xb0, 0x54, 0xdd, 0xe7, 0xbf, 0x64, 0x98, 0x4a, 0x48, 0x9e, 0x7c, 0x6e, 0x35, 0x04, 0x38, 0x5b, 0x7b, 0x18, 0xbd, 0x06, 0x51, 0x66, 0xe3, 0x1b, 0x61, 0xf4, 0x35, 0xbc, 0x4b, 0xbd, 0x67, 0x2d, 0x95, 0x55, 0x06, 0xb8, 0x20, 0xb3, 0xac, 0xdc, 0x1c, 0x2c, 0x5d, 0x3f, 0xf1, 0xb6, 0x6c, 0xdb, 0x81, 0x6c, 0xc3, 0xca, 0x03, 0x7e, 0x6a, 0x39, 0x53, 0x8e, 0xd0, 0xbe, 0xe3, 0x24, 0x45, 0x3a, 0x40, 0xd1, 0xba, 0x90, 0x61, 0x4d, 0xfe, 0x59, 0xfd, 0x90, 0x0d, 0x66, 0xe9, 0x79, 0x78, 0x5f, 0x52, 0xce, 0xf8, 0xc6, 0x6c, 0xeb, 0x83, 0x42, 0xba, 0xe2, 0x20, 0x93, 0x39, 0xa7, 0x3b, 0xfc, 0x7c, 0x6a, 0x44, 0xaa, 0x21, 0x76, 0xbb, 0xc2, 0x05, 0x7e, 0xfd, 0xc7, 0x0c, 0x9e, 0x1b, 0xf0, 0xa3, 0x09, 0x0d, 0xb8, 0xbe, 0x4a, 0x14, 0xa6, 0x1c, 0x8a, 0xf0, 0xf8, 0x8a, 0x63, 0x9a, 0xb6, 0x87, 0xd4, 0x40, 0xd9, 0x65, 0xa3, 0x14, 0xf2, 0x43, 0x75, 0x47, 0x0a, 0xb1, 0xf6, 0x8a, 0xa1, 0x5c, 0xe9, 0x44, 0xe6, 0x89, 0x6d, 0x94, 0xc3, 0x2b, 0xe4, 0x6e, 0xba, 0xb8, 0x3b, 0x40, 0xff, 0xa0, 0x9a, 0x32, 0x17, 0x35, 0x3c, 0xea, 0x5e, 0x7b, 0x43, 0x4e, 0x0e, 0x7c, 0xfd, 0x2a, 0x19, 0x3d, 0xf7, 0x88, 0xab, 0x64, 0xa8, 0x3b, 0xcd, 0x6b, 0x41, 0x09, 0x21, 0xa9, 0xe3, 0x0c, 0x20, 0x5a, 0xa5, 0xda, 0x0e, 0xb7, 0xb4, 0x4a, 0xe2, 0xef, 0x14, 0x38, 0xe3, 0xc0, 0xac, 0x0e, 0x24, 0xb3, 0xc4, 0xbe, 0x01, 0x9c, 0x61, 0xbf, 0x04, 0x85, 0xc2, 0x9b, 0x18, 0xea, 0x65, 0xf0, 0x3f, 0x1b, 0xba, 0xff, 0x40, 0x70, 0x46, 0x86, 0x74, 0x7b, 0x45, 0x5a, 0x36, 0x8f, 0x7c, 0xc6, 0x4a, 0xfd, 0x97, 0xa8, 0x13, 0x3e, 0xf1, 0xec, 0xe5, 0x88, 0x13, 0xfc, 0xc6, 0x0c, 0x4a, 0x14, 0xb3, 0xa4, 0x04, 0x97, 0x66, 0x8c, 0x9d, 0xb3, 0x65, 0x4e, 0x05, 0xf9, 0x33, 0x0d, 0x3f, 0xe8, 0x5f, 0x69, 0xf2, 0x2b, 0x6b, 0x1b, 0x8f, 0x81, 0xf7, 0xca, 0x06, 0xf4, 0xe4, 0x81, 0x1f, 0xa8, 0x20, 0x25, 0xc5, 0x48, 0x3c, 0xaa, 0xfb, 0x78, 0x01, 0x3c, 0xc4, 0x04, 0x46, 0x80, 0x57, 0x77, 0x2d, 0x64, 0x60, 0x8e, 0x60, 0x52, 0x5e, 0x9e, 0xc1, 0x3e, 0x22, 0x4d, 0xc8, 0x39, 0x76, 0x24, 0x11, 0x9a, 0x1f, 0xfc, 0xe7, 0x4f, 0x04, 0xfa, 0xed, 0x65, 0xca, 0x83, 0xc4, 0xfe, 0x30, 0xd8, 0xe5, 0x2c, 0x99, 0x5d, 0x2c, 0x86, 0xb8, 0xf2, 0x88, 0x3d, 0x2c, 0x84, 0xe2, 0x62, 0x94, 0xa6, 0x1a, 0x3f, 0xed, 0x56, 0x29, 0x18, 0x7b, 0x0b, 0x02, 0xa7, 0x3b, 0xe5, 0x48, 0xfe, 0xbf, 0xa6, 0xad, 0x55, 0x52, 0x1b, 0x50, 0x5a, 0xec, 0x4f, 0x1b, 0xa2, 0x09, 0x52, 0xc3, 0xbc, 0x8a, 0x6b, 0xb1, 0x8e, 0xd1, 0x44, 0xc4, 0x96, 0x21, 0xc0, 0x03, 0x04, 0xfd, 0x7f, 0x49, 0x0a, 0x66, 0x24, 0x58, 0x00, 0xb1, 0x1a, 0xbe, 0x91, 0x0c, 0x92, 0x9a, 0xe8, 0x53, 0x67, 0x08, 0xfc, 0xbf, 0xb0, 0x7c, 0xaa, 0x38, 0xf8, 0x03, 0x88, 0x44, 0xd0, 0xeb, 0x48, 0x08, 0xa4, 0x35, 0x17, 0x98, 0x7a, 0x12, 0xb2, 0x30, 0x8c, 0xa4, 0xbd, 0xa1, 0xf2, 0x19, 0x60, 0xd2, 0xa2, 0xb9, 0x7f, 0x2a, 0xbc, 0xc6, 0x8e, 0xbd, 0xa8, 0xc0, 0xcb, 0xb3, 0x57, 0xea, 0x67, 0x0e, 0xd2, 0xf8, 0x22, 0x93, 0x1e, 0x71, 0x0e, 0xb5, 0x08, 0x00, 0x74, 0xd3, 0x8a, 0x9c, 0xc6, 0xf5, 0x61, 0x31, 0x65, 0xb8, 0x1c, 0x31, 0xa0, 0xb6, 0x20, 0x1d, 0xf8, 0x5d, 0x50, 0xdd, 0xde, 0x0f, 0x41, 0xd9, 0x67, 0xac, 0xc2, 0x42, 0x65, 0x34, 0xb9, 0x8d, 0x02, 0x2c, 0x10, 0x33, 0x77, 0x25, 0x9d, 0xfc, 0x0c, 0x1b, 0xed, 0xe8, 0x21, 0x06, 0x33, 0xf5, 0xe8, 0xb9, 0x63, 0x9a, 0x89, 0x34, 0x1b, 0x4e, 0xb5, 0x0c, 0xbe, 0x10, 0xd1, 0x30, 0x30, 0x92, 0xef, 0x34, 0xf8, 0xcf, 0x61, 0x90, 0x29, 0x9b, 0x65, 0x64, 0x95, 0xac, 0xbe, 0xce, 0x24, 0x38, 0x1c, 0xa3, 0xd6, 0xf4, 0x7d, 0x7a, 0x47, 0x2e, 0xa4, 0x0d, 0x86, 0x6b, 0xd2, 0xa1, 0x7c, 0xce, 0x30, 0x37, 0xfa, 0x9b, 0x9e, 0xe2, 0xbe, 0x0f, 0xad, 0x0e, 0x43, 0xed, 0x5f, 0xa0, 0x9f, 0xae, 0xaf, 0x93, 0x5f, 0xcd, 0x44, 0xc5, 0xc7, 0x87, 0xaf, 0xc2, 0xda, 0x30, 0x50, 0x8d, 0x71, 0xda, 0x0c, 0x81, 0x16, 0x7a, 0xb3, 0xb9, 0xda, 0x49, 0x49, 0x3f, 0x46, 0xcd, 0x5f, 0xe6, 0xda, 0xa0, 0xf5, 0x76, 0x5d, 0x78, 0xeb, 0x9e, 0xdf, 0xf3, 0x59, 0x7c, 0x1a, 0x12, 0x54, 0x9b, 0xe9, 0x39, 0x4c, 0xe2, 0x89, 0xe6, 0x33, 0x96, 0xf9, 0xd7, 0xe8, 0x21, 0x9f, 0x20, 0x5c, 0xd8, 0xdb, 0x3d, 0xeb, 0x20, 0xc9, 0xa1, 0x42, 0xad, 0x54, 0xb7, 0xbd, 0x88, 0x13, 0x58, 0x11, 0x3c, 0xcc, 0x77, 0xae, 0xfe, 0xef, 0xea, 0xd5, 0x7b, 0x5f, 0xde, 0xf5, 0xbb, 0xd9, 0xbf, 0xea, 0x2c, 0x33, 0xca, 0xaa, 0xf2, 0x1e, 0x76, 0xbb, 0x52, 0x12, 0x00, 0xf7, 0xcb, 0xe1, 0x4a, 0x9b, 0x77, 0x25, 0xdf, 0xff, 0x4f, 0x5f, 0x26, 0x53, 0x76, 0x62, 0x0e, 0x9d, 0xe8, 0x04, 0x58, 0x4a, 0x41, 0x19, 0xe4, 0x21, 0x70, 0xe6, 0xd1, 0xef, 0x43, 0x45, 0x36, 0x6d, 0xf9, 0x66, 0xa3, 0x3e, 0xc3, 0xac, 0x2a, 0x92, 0x84, 0xf3, 0xea, 0xbd, 0x0c, 0xac, 0xd8, 0x6e, 0x83, 0x32, 0x5f, 0x3f, 0x0b, 0xbb, 0x52, 0xa8, 0xdc, 0xec, 0xcf, 0x2c, 0xe0, 0xbc, 0x39, 0x2c, 0xb2, 0xf2, 0x10, 0x96, 0x35, 0xf1, 0xe7, 0xff, 0x21, 0xe4, 0x3f, 0x24, 0xeb, 0x6c, 0x10, 0x9e, 0x35, 0xcb, 0x4f, 0x29, 0xcf, 0xcf, 0x00, 0xe6, 0xc2, 0xd0, 0xda, 0x11, 0x30, 0xb2, 0x38, 0x24, 0x5c, 0x18, 0xec, 0x96, 0x1f, 0x69, 0x30, 0xc9, 0x74, 0xc0, 0x20, 0xd7, 0x04, 0xe1, 0xb1, 0x4c, 0xc9, 0x04, 0x70, 0x39, 0xbf, 0xae, 0x53, 0x0e, 0xa4, 0x21, 0xfe, 0xd5, 0xdb, 0x88, 0x6a, 0x75, 0xf0, 0xb8, 0x51, 0xf6, 0xd2, 0xce, 0x45, 0x9a, 0x03, 0x0c, 0x64, 0xea, 0x3f, 0x16, 0x41, 0x7e, 0x79, 0xe1, 0x99, 0x41, 0x40, 0xa6, 0x71, 0x06, 0x15, 0x31, 0x8f, 0x88, 0x24, 0x41, 0xf7, 0xed, 0x1a, 0xb9, 0xac, 0x22, 0x74, 0x74, 0xf6, 0x90, 0x41, 0x57, 0x9f, 0xae, 0x85, 0xb7, 0xe2, 0xa4, 0x20, 0xa1, 0x56, 0xec, 0x76, 0x3c, 0x5c, 0x60, 0x24, 0xc9, 0xd5, 0xca, 0xfb, 0xa1, 0x8c, 0x34, 0x6e, 0xca, 0x3a, 0xea, 0x25, 0xaf, 0xd8, 0x49, 0x87, 0xf7, 0x39, 0x25, 0x52, 0x7c, 0xc0, 0xec, 0xb3, 0x36, 0x62, 0xac, 0xc3, 0x5f, 0x84, 0x5a, 0x26, 0xb6, 0xd2, 0x95, 0x2a, 0xf2, 0x7e, 0xc7, 0x70, 0x4e, 0xbf, 0x45, 0x57, 0x04, 0x4b, 0xb5, 0xb7, 0xfc, 0xd6, 0x6c, 0xae, 0xef, 0xe2, 0x25, 0xff, 0xa1, 0xaa, 0x2c, 0x31, 0xd9, 0xe5, 0xa0, 0xca, 0x8d, 0x87, 0xbc, 0x45, 0x42, 0x7a, 0x87, 0x1d, 0x29, 0x18, 0x9f, 0xa1, 0x75, 0x41, 0x0d, 0x96, 0xa7, 0x61, 0xf1, 0xd9, 0x24, 0x35, 0xc6, 0xdf, 0xf8, 0x6e, 0x66, 0x36, 0xea, 0x59, 0xcd, 0xb8, 0xd8, 0xb0, 0x10, 0xa2, 0x03, 0xf2, 0x3f, 0x83, 0x12, 0xb7, 0xc3, 0x85, 0x47, 0x03, 0x95, 0xea, 0x3a, 0x6d, 0xe4, 0xb9, 0xa6, 0x3b, 0x9b, 0x4d, 0xb4, 0x29, 0x63, 0xf4, 0xac, 0x14, 0xc6, 0xb7, 0xca, 0xec, 0xe7, 0xab, 0x9a, 0xf9, 0x68, 0xb6, 0xf1, 0x8c, 0x7b, 0xca, 0x9a, 0xb2, 0xc5, 0x90, 0x47, 0xbc, 0x39, 0xd0, 0x36, 0x1f, 0xe1, 0x2e, 0xaa, 0x1d, 0x08, 0x1c, 0xfa, 0x7e, 0x30, 0x31, 0x82, 0x5f, 0xf8, 0x98, 0xc7, 0x9d, 0xaa, 0x5c, 0x99, 0xbc, 0x0c, 0x0c, 0xa0, 0x31, 0xf5, 0x75, 0xb8, 0x03, 0x5d, 0xa1, 0x13, 0x6c, 0xd9, 0x0b, 0x50, 0xca, 0x7b, 0xad, 0x9b, 0xbc, 0x7a, 0xde, 0x31, 0x67, 0xad, 0xf9, 0x35, 0x61, 0xf5, 0x26, 0xcc, 0x27, 0xb7, 0xa1, 0x70, 0xa5, 0x60, 0x5e, 0xf2, 0x94, 0xe6, 0xf9, 0x88, 0x59, 0xdf, 0xf1, 0xc1, 0x50, 0x2e, 0xed, 0xe7, 0x92, 0xf5, 0x2a, 0x40, 0x75, 0x5f, 0x40, 0xa3, 0xce, 0x8e, 0xb0, 0x4b, 0xcb, 0x0e, 0x6f, 0x11, 0xb3, 0xa1, 0x46, 0x7f, 0x3f, 0x2a, 0xcb, 0x7f, 0xa8, 0xb0, 0x9f, 0x31, 0xcd, 0x85, 0xcb, 0x35, 0xde, 0x34, 0x12, 0x16, 0x61, 0x5d, 0x18, 0xda, 0x04, 0x85, 0xa1, 0xf0, 0x08, 0xe7, 0xad, 0x57, 0xab, 0x37, 0xbd, 0x63, 0x38, 0x0f, 0xc5, 0x5f, 0x89, 0x0a, 0x40, 0xa7, 0x38, 0x3c, 0x95, 0x5a, 0x33, 0xa3, 0x12, 0x19, 0x73, 0x72, 0x1b, 0x58, 0x0b, 0x65, 0xd7, 0x11, 0x9c, 0x6e, 0x44, 0xff, 0x6f, 0x31, 0x64, 0x50, 0x57, 0xe1, 0x88, 0xad, 0x11, 0xa8, 0xd8, 0x71, 0x67, 0x52, 0xa1, 0xcb, 0x49, 0x88, 0x05, 0x3f, 0x6e, 0xb1, 0x50, 0x33, 0xd0, 0x28, 0x08, 0x2f, 0x5a, 0xd4, 0x6b, 0xcb, 0xc0, 0x08, 0xfd, 0xbc, 0xc2, 0x49, 0xe7, 0x29, 0x15, 0x4f, 0x01, 0x82, 0x0c, 0x75, 0xd8, 0xc1, 0xc5, 0xa4, 0x98, 0x78, 0x61, 0x3f, 0xf5, 0x72, 0x78, 0x7c, 0x15, 0xb6, 0xe9, 0x58, 0x90, 0x1c, 0x0c, 0xa8, 0x63, 0xe3, 0x37, 0x15, 0xc3, 0xfe, 0xa9, 0xe0, 0x22, 0x0f, 0x35, 0x28, 0xd9, 0x6c, 0x33, 0x92, 0x3a, 0x3c, 0xd2, 0x26, 0x52, 0x7f, 0xa8, 0x0b, 0xde, 0x77, 0x93, 0x03, 0xc2, 0x1c, 0x19, 0xa7, 0x99, 0x6f, 0x98, 0xa2, 0x12, 0x5b, 0xa2, 0xce, 0xcc, 0x7b, 0x87, 0x30, 0x13, 0x04, 0x9e, 0x6b, 0xc1, 0xf5, 0x4d, 0x4d, 0xb1, 0xcb, 0xf2, 0x7e, 0xce, 0x90, 0x14, 0x7f, 0xd4, 0xca, 0x52, 0xb0, 0xf9, 0xd6, 0xeb, 0x16, 0x3f, 0x4a, 0x55, 0x43, 0xdf, 0x09, 0xa8, 0xfa, 0x8e, 0x7c, 0xed, 0x61, 0x62, 0xc3, 0x89, 0x96, 0xc3, 0x67, 0xef, 0x8d, 0xf4, 0x34, 0xde, 0x87, 0x20, 0x8e, 0x70, 0x93, 0x0e, 0xf8, 0x34, 0xc0, 0x99, 0xb5, 0x8c, 0xa9, 0xe8, 0x40, 0x99, 0x03, 0xb9, 0xe1, 0x00, 0x10, 0x3e, 0xd0, 0x1c, 0x7e, 0xd5, 0xa0, 0x71, 0x10, 0xef, 0xf3, 0xc2, 0x54, 0x14, 0x57, 0x22, 0xf5, 0x5b, 0xc8, 0x6c, 0x60, 0xbd, 0xe9, 0x20, 0x7b, 0x67, 0xbe, 0x3b, 0xfe, 0xa4, 0xcf, 0x32, 0x1c, 0x45, 0xa7, 0xd8, 0x20, 0x22, 0xf7, 0xac, 0x16, 0x00, 0xb1, 0x5a, 0xcc, 0x41, 0x6d, 0x76, 0x6b, 0x85, 0xc7, 0x22, 0x29, 0x21, 0x78, 0x21, 0xf0, 0x5c, 0xa0, 0xfb, 0x52, 0x50, 0x40, 0xbb, 0x7a, 0x9e, 0x65, 0x08, 0xd8, 0x84, 0xa5, 0xed, 0x22, 0x87, 0x65, 0x88, 0x07, 0x6b, 0x19, 0x3d, 0x43, 0xc9, 0x81, 0xa6, 0x9a, 0xd9, 0x45, 0xb7, 0x1d, 0xf5, 0x18, 0x35, 0x5c, 0x0e, 0xbc, 0x69, 0x0d, 0x5a, 0x63, 0x6a, 0x88, 0x24, 0xb2, 0x83, 0x1f, 0x7c, 0xb4, 0x4d, 0xc9, 0xd9, 0x52, 0x98, 0xbf, 0x64, 0x2d, 0x6c, 0xe9, 0x03, 0x39, 0xb9, 0x26, 0x2f, 0x61, 0x62, 0xed, 0x21, 0xf5, 0x8d, 0xce, 0x86, 0xa5, 0x68, 0xe3, 0x79, 0x4c, 0x8e, 0x2e, 0xb7, 0xee, 0x47, 0xe6, 0xb5, 0x3f, 0xff, 0x51, 0x0f, 0x93, 0x10, 0xd9, 0x0d, 0xd8, 0x16, 0x01, 0xb1, 0x65, 0x6a, 0x3f, 0x63, 0x7a, 0x43, 0x4b, 0x8e, 0x1b, 0x3a, 0xee, 0x99, 0x1f, 0x76, 0xe1, 0xf6, 0x05, 0xff, 0x29, 0xf0, 0x94, 0x0b, 0x77, 0xc6, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xbd, 0x06, 0xe6, 0x81, 0xc1, 0x58, 0x2a, 0xb0, 0xc3, 0x77, 0x15, 0xd0, 0x4c, 0xad, 0x77, 0xba, 0x27, 0x93, 0x3f, 0x6d, 0x5e, 0x55, 0x75, 0x54, 0x80, 0x0d, 0x1b, 0xba, 0x36, 0x05, 0xea, 0xe2, 0xca, 0xcb, 0xc8, 0xfd, 0xae, 0x63, 0x21, 0xc6, 0xc9, 0x82, 0x33, 0x86, 0xd2, 0x0e, 0x59, 0xa4, 0xf9, 0xc6, 0x89, 0xfa, 0xd2, 0x68, 0x50, 0x72, 0xee, 0x6e, 0xc5, 0xdb, 0x28, 0xf9, 0x98, 0x8d, 0xdd, 0x19, 0x58, 0x92, 0xa2, 0x82, 0x6a, 0xcd, 0x22, 0x7f, 0xc8, 0x39, 0x19, 0x43, 0x3c, 0x65, 0x09, 0xe8, 0x61, 0x95, 0xc8, 0x66, 0x33, 0x0b, 0xf7, 0x1e, 0x92, 0x43, 0xee, 0x1a, 0x30, 0x00, 0x00, 0x00, 0xf0, 0x5d, 0xfc, 0x8d, 0xcc, 0x31, 0x59, 0x61, 0x35, 0xf5, 0xd4, 0xcb, 0x69, 0xca, 0x76, 0x4f, 0x43, 0x12, 0xb0, 0xf5, 0x3c, 0xd7, 0x74, 0x3f, 0xef, 0x25, 0xd5, 0x66, 0xa2, 0xd5, 0x87, 0x45, 0x2f, 0x90, 0x3b, 0x55, 0x86, 0x64, 0xc3, 0x57, 0xba, 0x23, 0xaf, 0x96, 0x69, 0xa8, 0x66, 0xf2, 0x35, 0x58, 0xbd, 0xe5, 0x3a, 0xef, 0x07, 0x20, 0x06, 0xf1, 0x83, 0xc9, 0xdc, 0x34, 0xb0, 0xd6, 0x6c, 0x23, 0x1f, 0xb2, 0x5b, 0x49, 0xa7, 0xdf, 0x85, 0x3b, 0x04, 0x27, 0x61, 0x8d, 0x83, 0xa6, 0xce, 0x31, 0xd4, 0x08, 0x40, 0xaf, 0x7c, 0x0b, 0xcf, 0x9b, 0xfc, 0xe7, 0x54, 0x6d, 0x7a, 0x17, 0x04, 0xe8, 0xcb, 0xd7, 0x14, 0x45, 0x31, 0xcd, 0x79, 0xd5, 0x68, 0x33, 0xdf, 0x6a, 0x15, 0x1d, 0x8d, 0x0f, 0xb6, 0x9e, 0xf2, 0xde, 0x8a, 0x16, 0x4c, 0x79, 0xd1, 0x03, 0x74, 0xb6, 0x09, 0xf0, 0x1e, 0x22, 0xd6, 0x62, 0x79, 0x58, 0x35, 0x60, 0xfc, 0x2f, 0xec, 0xb8, 0xf4, 0xf2, 0x30, 0x87, 0x6f, 0xc6, 0x53, 0x21, 0xf1, 0x8f, 0x27, 0x57, 0x93, 0xe2, 0xb0, 0x89, 0x95, 0x26, 0xd3, 0x03, 0xfe, 0xfa, 0x81, 0x0e, 0x78, 0xeb, 0x96, 0xca, 0x6e, 0x02, 0x31, 0x07, 0xcb, 0x1c, 0x7e, 0x82, 0xe2, 0xbb, 0x89, 0xce, 0xaa, 0xf3, 0xfd, 0x7d, 0x19, 0x7c, 0x6c, 0x21, 0xb6, 0x6c, 0xba, 0xa0, 0xf7, 0x7e, 0xb0, 0xb3, 0x87, 0xfd, 0xe9, 0x69, 0x59, 0x8a, 0xdf, 0x50, 0x0e, 0x38, 0x28, 0x46, 0x21, 0x7f, 0x98, 0x3e, 0x94, 0x63, 0x24, 0xcb, 0xbb, 0xad, 0x62, 0xaa, 0x24, 0x4b, 0x62, 0x7d, 0xa7, 0x3a, 0x1b, 0xfe, 0xa4, 0xa4, 0xbb, 0x0a, 0x88, 0x7d, 0x7d, 0x49, 0xe0, 0x3f, 0xce, 0x91, 0xf0, 0x73, 0xc0, 0x56, 0x31, 0xee, 0x6c, 0xec, 0x66, 0x2e, 0x27, 0xa3, 0x32, 0xc8, 0xbb, 0xd9, 0x19, 0x66, 0x48, 0x32, 0x66, 0xd3, 0x33, 0xc1, 0x59, 0xf1, 0xeb, 0xab, 0x73, 0x42, 0x81, 0xb5, 0x57, 0x48, 0x93, 0xda, 0x74, 0x58, 0x4a, 0x39, 0xbd, 0x98, 0x4a, 0x88, 0xf8, 0xdc, 0x87, 0x9d, 0xa2, 0xb0, 0xde, 0xc7, 0x36, 0xbb, 0xb0, 0x8d, 0x37, 0xe0, 0x84, 0x34, 0x28, 0xca, 0x35, 0xc9, 0xeb, 0x00, 0x3f, 0xd1, 0x1f, 0x84, 0x7e, 0xf3, 0x58, 0x5f, 0x7c, 0x6d, 0x66, 0x7d, 0xdc, 0x8e, 0x9c, 0xa8, 0xed, 0x1f, 0x81, 0x62, 0x0f, 0x92, 0xae, 0x75, 0x60, 0x6b, 0x75, 0x5c, 0x48, 0x19, 0x90, 0xea, 0x45, 0x63, 0x5a, 0x2f, 0x79, 0x78, 0x06, 0x20, 0x8f, 0xc4, 0xc2, 0x29, 0xa6, 0x03, 0xc9, 0xd9, 0x05, 0x06, 0xbe, 0xf4, 0x98, 0x28, 0x48, 0x8f, 0xa6, 0xb9, 0xee, 0xd1, 0x6d, 0x41, 0x3e, 0x35, 0x63, 0x87, 0x49, 0x5b, 0x35, 0x51, 0x27, 0x3e, 0x1d, 0x8c, 0x5b, 0x25, 0xeb, 0x98, 0x47, 0x0f, 0x5b, 0xed, 0x76, 0x36, 0x5f, 0x03, 0xc8, 0xdd, 0x6f, 0x2f, 0x8c, 0x4f, 0xf4, 0xe7, 0xda, 0xaa, 0xbc, 0x47, 0xdc, 0x76, 0xca, 0xe0, 0x67, 0xcc, 0x3d, 0xb8, 0xcf, 0xe3, 0x0b, 0x81, 0x64, 0xbf, 0x89, 0x60, 0x54, 0x32, 0xcd, 0x90, 0x5c, 0xc9, 0x5d, 0xc0, 0xdb, 0xdf, 0x4d, 0x3f, 0xce, 0x96, 0x87, 0xe5, 0x29, 0x7d, 0xbd, 0xde, 0x9e, 0xda, 0xd3, 0xfa, 0x8c, 0xd1, 0xa0, 0x2b, 0x6b, 0x84, 0x66, 0xb8, 0x65, 0x31, 0xcf, 0x56, 0xaf, 0x79, 0x43, 0x48, 0x70, 0x5f, 0xaa, 0xb1, 0xd9, 0xe9, 0x40, 0xc0, 0xfd, 0xc6, 0xa2, 0xf5, 0xf5, 0x6f, 0x9d, 0xa6, 0x0a, 0x22, 0x84, 0xa8, 0x28, 0x59, 0xdf, 0x1d, 0xff, 0xbf, 0x05, 0xe9, 0x5f, 0x3f, 0x65, 0x31, 0x2c, 0x2a, 0x02, 0x14, 0x92, 0xcf, 0xab, 0x70, 0xc0, 0x5d, 0x60, 0xe3, 0x29, 0x34, 0x7a, 0x8a, 0x73, 0xdd, 0xa1, 0x85, 0x31, 0x49, 0x35, 0x90, 0xba, 0xf3, 0x2e, 0x0f, 0xf9, 0x1f, 0xbb, 0xa9, 0x75, 0x0c, 0xc8, 0xf4, 0xe9, 0x1f, 0x2e, 0x79, 0x7f, 0xc3, 0x84, 0x0e, 0x71, 0xb0, 0x82, 0x1b, 0x59, 0x75, 0xae, 0xe8, 0xe1, 0xf9, 0x86, 0x31, 0xa8, 0x6e, 0x05, 0xa8, 0x35, 0x76, 0x68, 0x22, 0x45, 0xd7, 0x55, 0x5b, 0x70, 0x36, 0xb2, 0x46, 0x36, 0x7d, 0xcc, 0x3b, 0xe7, 0x9e, 0x43, 0x2c, 0xd2, 0xb0, 0x2b, 0x3e, 0x17, 0xe6, 0xf7, 0xd9, 0xaf, 0x16, 0xba, 0x5c, 0x86, 0x20, 0x22, 0x1d, 0xee, 0xa1, 0x32, 0x7c, 0xc1, 0xa2, 0x9a, 0xc2, 0xde, 0xe1, 0xd9, 0x8d, 0x3d, 0x9a, 0xbe, 0xf4, 0x46, 0x83, 0x07, 0x91, 0x01, 0xa4, 0x89, 0xa3, 0x1e, 0x1f, 0x6e, 0xbe, 0x9c, 0x54, 0x41, 0x0a, 0x5a, 0x74, 0x1b, 0xfb, 0x0c, 0xd7, 0xb6, 0x43, 0x6d, 0x8b, 0x61, 0x5e, 0x86, 0x34, 0x87, 0xb1, 0x9e, 0xce, 0xa4, 0xa2, 0x06, 0x3f, 0x69, 0xfe, 0xfd, 0xb1, 0x20, 0xfe, 0x4b, 0x23, 0x8d, 0x99, 0x26, 0x14, 0xb8, 0x4c, 0x24, 0xcf, 0xd7, 0xf8, 0x10, 0x94, 0xb5, 0x29, 0xe6, 0x7b, 0xb6, 0xdf, 0xc1, 0xb6, 0x71, 0xd2, 0x55, 0x1e, 0x1c, 0x26, 0x3a, 0x63, 0x02, 0x20, 0x89, 0xf3, 0xd4, 0xe1, 0x89, 0xc5, 0x1c, 0xdc, 0x2f, 0xf2, 0x54, 0x10, 0xc7, 0xa2, 0x25, 0x49, 0x7d, 0x1f, 0x67, 0x21, 0x53, 0xc8, 0x30, 0xdc, 0xf2, 0x2d, 0x55, 0x5d, 0xf0, 0x8e, 0x56, 0x18, 0xc0, 0xf4, 0xd1, 0x17, 0xd2, 0x9e, 0x94, 0x71, 0x6b, 0x5e, 0xa4, 0xa4, 0xf7, 0xb6, 0xe1, 0x04, 0xf3, 0xfe, 0xcf, 0x39, 0xa1, 0x71, 0xe6, 0xb6, 0xa9, 0x54, 0x73, 0xb2, 0xf0, 0xfb, 0x4f, 0x08, 0x85, 0x99, 0xb7, 0x74, 0xe5, 0x5e, 0x0c, 0x41, 0xc3, 0x87, 0x3d, 0x33, 0x51, 0x51, 0x81, 0xe9, 0xce, 0x26, 0x4f, 0x9c, 0x0c, 0xc3, 0xc3, 0xef, 0xea, 0xd2, 0x45, 0x3c, 0xbf, 0xd1, 0x79, 0xb0, 0x7a, 0x95, 0x80, 0xae, 0x79, 0x56, 0xca, 0xe0, 0x1d, 0x02, 0xf9, 0xb3, 0xab, 0x37, 0x84, 0x52, 0x09, 0x1e, 0x7d, 0x3b, 0xf7, 0x89, 0x97, 0x4e, 0xc0, 0x7b, 0xb0, 0x75, 0xae, 0xef, 0x47, 0x9a, 0xbd, 0x21, 0x13, 0xfc, 0x12, 0x5f, 0x66, 0xd6, 0xad, 0xab, 0xe8, 0x38, 0xdf, 0x8b, 0xf3, 0xbe, 0xee, 0x53, 0xb0, 0x07, 0x89, 0xa6, 0xed, 0x18, 0x6d, 0x5d, 0xa8, 0x15, 0xfd, 0x8e, 0x8f, 0x28, 0x29, 0x89, 0xec, 0x99, 0xf6, 0x17, 0x39, 0xbe, 0xdb, 0x67, 0xb3, 0x4b, 0x87, 0x1a, 0x70, 0x5d, 0xf1, 0xdc, 0xae, 0x3f, 0x38, 0xaa, 0x44, 0xae, 0xcb, 0x6d, 0xdc, 0x13, 0x16, 0xbc, 0x84, 0x30, 0xb0, 0xeb, 0xe1, 0xa6, 0x74, 0x7d, 0x60, 0x55, 0x26, 0x29, 0x60, 0xce, 0xda, 0x4a, 0xb2, 0x82, 0xb0, 0x46, 0xd9, 0xae, 0xea, 0x7b, 0x30, 0x79, 0x29, 0xe3, 0x79, 0x08, 0x06, 0xbd, 0x2a, 0x20, 0x34, 0xba, 0xf4, 0xe7, 0x3e, 0x4c, 0x40, 0xb2, 0x6e, 0x49, 0xeb, 0x6e, 0x75, 0x03, 0xec, 0xe8, 0xb6, 0x1f, 0xd1, 0xd4, 0x4f, 0x07, 0x72, 0x05, 0x16, 0x8d, 0x3e, 0xc7, 0xa6, 0xe3, 0x88, 0x3b, 0xb4, 0xdf, 0xcb, 0x0d, 0x4e, 0xd2, 0xf4, 0xad, 0x31, 0x2d, 0xca, 0x33, 0x03, 0x8a, 0x2b, 0xc9, 0x2b, 0xdf, 0x3d, 0xe2, 0xf3, 0xfd, 0xfc, 0xe9, 0x09, 0x07, 0xbd, 0xee, 0x03, 0xf6, 0xbf, 0xbd, 0x93, 0x2b, 0x6a, 0x38, 0xa8, 0xc3, 0x20, 0x8e, 0x8f, 0x6b, 0xef, 0x29, 0x9b, 0x92, 0xee, 0x88, 0x99, 0x8c, 0xf2, 0x28, 0xba, 0xe4, 0x53, 0x4b, 0x2a, 0x5b, 0x3e, 0x0b, 0x96, 0x6c, 0xa7, 0x16, 0x86, 0x95, 0xf7, 0x0e, 0xed, 0xff, 0xc5, 0xe6, 0xbb, 0x6f, 0xa0, 0x95, 0xf7, 0xf4, 0xd1, 0xc6, 0xb6, 0xed, 0x0e, 0xc1, 0xbb, 0xf5, 0x2d, 0xcf, 0x04, 0x30, 0x19, 0xf9, 0x53, 0x38, 0x68, 0x5e, 0x07, 0xe1, 0xd3, 0x9b, 0xd0, 0x28, 0x41, 0xdb, 0x99, 0x74, 0x59, 0xc2, 0xc0, 0x92, 0xcb, 0xf1, 0xcc, 0xc3, 0xdd, 0x9c, 0x87, 0x20, 0x41, 0x8c, 0xcf, 0x2e, 0xfe, 0x95, 0x4b, 0xb1, 0x84, 0xbb, 0xed, 0x37, 0xa4, 0x51, 0xb3, 0xd9, 0xa5, 0x1f, 0xe8, 0xdc, 0x97, 0x7a, 0x8d, 0xa7, 0x86, 0xa4, 0x25, 0x05, 0xa4, 0x5e, 0x2a, 0xe7, 0x6a, 0xf2, 0x93, 0x97, 0xca, 0xb4, 0x72, 0xaf, 0xd4, 0x52, 0x66, 0x12, 0x90, 0x34, 0xa4, 0x20, 0x6f, 0x20, 0x56, 0x4c, 0xb2, 0x20, 0x39, 0x1c, 0x05, 0x30, 0x98, 0x76, 0x7a, 0x8d, 0x8f, 0x42, 0x48, 0x00, 0x81, 0xa7, 0xb7, 0x8c, 0xfd, 0xb1, 0xc1, 0xab, 0x47, 0x16, 0x37, 0x66, 0xbe, 0xf6, 0x02, 0x91, 0x4c, 0x75, 0x6a, 0x60, 0x2e, 0x5e, 0xfd, 0x5d, 0x00, 0x5a, 0x90, 0x37, 0x0f, 0xe2, 0x30, 0xf1, 0x61, 0xa2, 0xee, 0x35, 0x7a, 0x04, 0xcc, 0xae, 0x08, 0x11, 0xa5, 0xda, 0xee, 0x47, 0xff, 0x73, 0x6f, 0x7d, 0x4e, 0x2d, 0x6f, 0x57, 0x60, 0xd1, 0xf6, 0x53, 0xeb, 0xa7, 0x8b, 0x22, 0x41, 0x90, 0xc4, 0x9f, 0xd6, 0x0e, 0xa9, 0x24, 0x01, 0xdb, 0xe0, 0xbd, 0x9f, 0xe1, 0xf8, 0x5a, 0xf3, 0x84, 0xc0, 0xdf, 0xd9, 0xc8, 0x17, 0x43, 0x04, 0x3e, 0x2e, 0xf4, 0xba, 0x06, 0x76, 0xbe, 0x66, 0x48, 0x3f, 0xfe, 0x10, 0xf5, 0x0f, 0xbe, 0xad, 0x01, 0x4a, 0xb7, 0x43, 0xef, 0xf6, 0xb4, 0x1d, 0xed, 0x0a, 0x99, 0xd5, 0x4b, 0x97, 0xca, 0x69, 0xf3, 0xee, 0xaa, 0xff, 0x8e, 0x82, 0xb7, 0x89, 0x83, 0xfb, 0x2b, 0x39, 0xbb, 0x56, 0x15, 0xfc, 0x82, 0x32, 0x90, 0xcb, 0x88, 0x4c, 0x23, 0x4c, 0x3a, 0x87, 0x36, 0xe8, 0xf0, 0x79, 0x12, 0xf3, 0xb4, 0x35, 0x93, 0xaa, 0xac, 0xd1, 0x83, 0x19, 0x55, 0x0b, 0x9d, 0xaf, 0x50, 0x71, 0xb0, 0x48, 0x53, 0xa4, 0xb6, 0x4c, 0x58, 0x4a, 0x6a, 0xad, 0x0a, 0xa8, 0x8a, 0x33, 0x09, 0x09, 0x8e, 0xf0, 0x6f, 0x95, 0x83, 0xc2, 0xb1, 0x87, 0xd6, 0xa0, 0xf7, 0x9a, 0x0c, 0x68, 0x0a, 0x70, 0x36, 0xf2, 0x77, 0x8e, 0x06, 0x09, 0x1d, 0x44, 0x36, 0xaf, 0xb2, 0xb9, 0x05, 0x65, 0xf0, 0x7b, 0xb4, 0x30, 0x12, 0x14, 0xe9, 0x92, 0x69, 0x85, 0x11, 0xac, 0xd5, 0x50, 0xc4, 0x8e, 0x39, 0xf1, 0x38, 0x84, 0x55, 0x17, 0x88, 0xda, 0x52, 0x91, 0x80, 0xd5, 0xb8, 0x64, 0x23, 0x0e, 0x12, 0x4e, 0x59, 0xbb, 0x12, 0x90, 0xbd, 0xca, 0xd7, 0x93, 0xd1, 0x03, 0x73, 0xe5, 0x3f, 0x84, 0xb3, 0xc7, 0x51, 0x1b, 0x96, 0xcb, 0x87, 0x23, 0x01, 0x54, 0x20, 0x0b, 0xd5, 0x1e, 0xfc, 0x96, 0x36, 0xc4, 0x4e, 0x85, 0xbd, 0xb4, 0x8f, 0x07, 0x6c, 0x7e, 0x75, 0xb9, 0x54, 0x86, 0x0b, 0x07, 0x80, 0xe2, 0x5f, 0xe9, 0xfe, 0x5d, 0x71, 0xcd, 0xc2, 0x7b, 0xdd, 0x05, 0x73, 0xbf, 0x5b, 0x86, 0x2f, 0xe1, 0x0e, 0x12, 0x7d, 0x29, 0x4b, 0x2f, 0x30, 0xdd, 0xb0, 0xf9, 0xed, 0xfb, 0x97, 0x96, 0x9e, 0x7a, 0x1e, 0x73, 0x11, 0x9a, 0xa7, 0xe3, 0x33, 0xc4, 0x2e, 0xc7, 0x5f, 0x8a, 0x69, 0xe3, 0xfc, 0x85, 0xf0, 0x97, 0x45, 0xfd, 0x7f, 0x25, 0x1f, 0xa6, 0xd3, 0xf6, 0x12, 0x0d, 0x2e, 0xd1, 0x73, 0xdb, 0xc9, 0x48, 0x07, 0xa8, 0xbe, 0xfa, 0x5e, 0x95, 0x9c, 0xcf, 0x08, 0x28, 0xad, 0x16, 0x4c, 0x92, 0x58, 0xd0, 0x71, 0xa9, 0xb4, 0x84, 0x83, 0xa3, 0x3b, 0xa6, 0x2b, 0x2f, 0x08, 0x18, 0xe8, 0x5d, 0x7f, 0x21, 0xfd, 0x5d, 0x53, 0xe7, 0x2e, 0x6b, 0xed, 0x83, 0x2f, 0xab, 0x56, 0x88, 0xd5, 0x5c, 0x5d, 0xe3, 0x9f, 0xdd, 0xe2, 0x21, 0xd4, 0xda, 0x96, 0x7e, 0x56, 0x3d, 0xa3, 0xaf, 0x93, 0xb2, 0xbb, 0x9b, 0xb4, 0x2e, 0xe8, 0xe6, 0x73, 0x0b, 0x9b, 0xa8, 0xbe, 0x3b, 0x34, 0x7d, 0x2e, 0x20, 0x8b, 0x07, 0xfc, 0xfa, 0x5f, 0x78, 0x49, 0x66, 0xdc, 0xb6, 0x14, 0x25, 0xb2, 0x8e, 0x92, 0xb0, 0x9a, 0x40, 0xff, 0x1b, 0x66, 0xd2, 0xde, 0x32, 0x68, 0x79, 0xdf, 0x2f, 0x01, 0x57, 0x6e, 0x48, 0x6b, 0xc0, 0x3e, 0x49, 0x5f, 0x2e, 0xe3, 0x7f, 0xdc, 0xcf, 0x24, 0xcd, 0x7a, 0x01, 0x3d, 0x84, 0xf8, 0x5c, 0x70, 0x54, 0xfc, 0xe3, 0xdf, 0x4d, 0x56, 0x6a, 0xe3, 0xee, 0x20, 0xfa, 0x9b, 0xe2, 0x41, 0x62, 0x9c, 0x7d, 0x94, 0x03, 0xc7, 0x48, 0xf7, 0x02, 0x00, 0xa2, 0x78, 0xaa, 0x43, 0xa3, 0xdb, 0xf5, 0xf9, 0x13, 0x3b, 0x2b, 0x31, 0xbb, 0x65, 0xaf, 0xaf, 0x59, 0x09, 0x4e, 0x66, 0x43, 0x5d, 0xd6, 0xc5, 0xe4, 0x97, 0x89, 0x00, 0x10, 0xe4, 0x9d, 0x73, 0x0c, 0x9d, 0x23, 0x32, 0xf3, 0x0b, 0x77, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xbd, 0x06, 0xe6, 0x81, 0xc1, 0x58, 0x31, 0x00, 0x05, 0xbf, 0x21, 0x11, 0x00, 0x05, 0xb3, 0x65, 0x1e, 0x69, 0xb2, 0x8f, 0x30, 0xcd, 0xaf, 0x26, 0x40, 0x2c, 0xf9, 0x92, 0xb8, 0x31, 0x61, 0x6a, 0x06, 0x23, 0x24, 0xde, 0xf7, 0xf9, 0x2a, 0x7c, 0xa5, 0xc3, 0x99, 0x4d, 0x6f, 0x15, 0xcc, 0xdc, 0x17, 0xb3, 0x74, 0x5b, 0xd4, 0xa2, 0x68, 0xab, 0x5d, 0x2c, 0x2b, 0xc5, 0xc1, 0x3e, 0xc5, 0x6a, 0x17, 0xbd, 0xb0, 0x57, 0x61, 0x5a, 0x48, 0xe3, 0x48, 0x99, 0x93, 0xde, 0xb0, 0x5e, 0x70, 0x9f, 0xcd, 0xd0, 0xf2, 0x07, 0xd5, 0xed, 0xe9, 0x4c, 0x3a, 0x08, 0xe6, 0x8e, 0xec, 0x78, 0x30, 0x00, 0x00, 0x00, 0x81, 0x9f, 0x5d, 0x92, 0x15, 0xe7, 0x37, 0x10, 0x4c, 0x42, 0xec, 0x9a, 0x12, 0x0a, 0x79, 0x55, 0x54, 0x02, 0x01, 0xb1, 0xc1, 0x08, 0x02, 0x31, 0x10, 0xd0, 0x03, 0x32, 0xae, 0x6a, 0x84, 0x3f, 0xcf, 0x82, 0x53, 0x9d, 0xf0, 0x9a, 0xce, 0x68, 0x6f, 0x07, 0xeb, 0x47, 0x19, 0xa4, 0x62, 0x79, 0x4c, 0x83, 0xcd, 0xfa, 0x1c, 0x78, 0x4e, 0xad, 0x5a, 0x6e, 0xc9, 0x63, 0x1f, 0x6d, 0x56, 0x33, 0x11, 0xd3, 0xfb, 0x35, 0x29, 0xc1, 0x8e, 0x39, 0xf7, 0xaa, 0x54, 0x44, 0x05, 0x4e, 0x81, 0x96, 0x77, 0xc4, 0x22, 0xbd, 0x85, 0xaf, 0x4e, 0xf5, 0x1e, 0xfb, 0x09, 0x83, 0x8c, 0x8f, 0x1c, 0x51, 0x89, 0xc5, 0x9a, 0xaa, 0xa0, 0xc0, 0x81, 0xac, 0x35, 0xe0, 0x12, 0x88, 0xb0, 0xdd, 0x79, 0xa4, 0x13, 0x54, 0x83, 0xde, 0x57, 0x98, 0x0d, 0xcc, 0x4c, 0xf2, 0x14, 0x17, 0xcc, 0x5e, 0x31, 0x53, 0x7d, 0x01, 0xa1, 0x09, 0xe7, 0x0a, 0x73, 0xbc, 0x1f, 0xd8, 0x50, 0xfa, 0x4e, 0x9b, 0x3d, 0x46, 0x7a, 0x11, 0xf2, 0xfb, 0x16, 0xac, 0x4b, 0x61, 0x7a, 0xae, 0xbf, 0xd6, 0x32, 0x10, 0x66, 0xe6, 0xcb, 0xf5, 0x3b, 0x56, 0xa5, 0xed, 0xfa, 0x48, 0x48, 0xbf, 0x39, 0xf9, 0xba, 0xc3, 0x9b, 0xcb, 0xbf, 0x1d, 0x49, 0xd9, 0xb4, 0x5a, 0x70, 0xa0, 0x2c, 0x7b, 0x21, 0x8c, 0x84, 0xda, 0x44, 0x8a, 0xa8, 0x85, 0xdb, 0x06, 0x89, 0x43, 0xc1, 0x81, 0x2c, 0xd9, 0xad, 0xa6, 0xc3, 0xa1, 0x24, 0x90, 0x31, 0x15, 0xab, 0xc6, 0x58, 0xd9, 0x60, 0xac, 0xcf, 0x2e, 0x5a, 0xa1, 0x61, 0x14, 0x71, 0x72, 0xc0, 0x14, 0x0a, 0xb8, 0x9e, 0xc3, 0x93, 0xe2, 0xb2, 0x74, 0x54, 0x55, 0x72, 0x47, 0x21, 0xfb, 0xb5, 0x76, 0xde, 0x08, 0xfc, 0x57, 0xda, 0x3f, 0x56, 0x44, 0xbe, 0x69, 0x1d, 0x49, 0xad, 0xb9, 0xe0, 0x30, 0x68, 0xfd, 0xd4, 0xeb, 0xde, 0x96, 0x66, 0x13, 0xfa, 0x20, 0x7c, 0x82, 0xcb, 0xf6, 0x62, 0x70, 0xac, 0x62, 0x1a, 0xae, 0x1e, 0x50, 0xee, 0x78, 0x61, 0x79, 0x7f, 0xe7, 0xe2, 0xdd, 0x98, 0x56, 0x43, 0xfb, 0x1c, 0x37, 0x50, 0x31, 0xab, 0x0a, 0xd0, 0x99, 0x22, 0x5e, 0x85, 0xae, 0x64, 0xde, 0xdc, 0xb5, 0xae, 0x35, 0x20, 0x00, 0xfb, 0x0b, 0xb4, 0x81, 0xc4, 0xb7, 0x17, 0x04, 0xc0, 0x6e, 0xa0, 0x04, 0x74, 0x4f, 0xef, 0x9c, 0xa0, 0xb6, 0x77, 0xa7, 0x7d, 0x80, 0x0b, 0x46, 0x2b, 0xa9, 0x1f, 0x7c, 0xb1, 0xd6, 0x92, 0xc1, 0x53, 0x64, 0x7c, 0x7e, 0x44, 0xbb, 0x66, 0xee, 0xf0, 0x19, 0x1c, 0xc4, 0xff, 0xae, 0xde, 0x4f, 0xc7, 0x80, 0xe2, 0xb1, 0x54, 0x58, 0xf2, 0x7d, 0xe3, 0x0c, 0xd2, 0x8c, 0x38, 0x70, 0x2f, 0x88, 0xf5, 0x3e, 0x10, 0x91, 0xa5, 0x5b, 0x10, 0x6b, 0xad, 0xf1, 0x1b, 0x23, 0x36, 0xb9, 0x47, 0x57, 0xf7, 0x4c, 0x41, 0x14, 0xd4, 0x48, 0xb1, 0x2c, 0x6a, 0x6a, 0xcd, 0xc4, 0x90, 0x8c, 0x2e, 0xc5, 0xae, 0xaf, 0x5f, 0x96, 0xdd, 0x82, 0x07, 0x04, 0x47, 0x17, 0x98, 0x5c, 0xb1, 0x20, 0xcb, 0xae, 0xec, 0x57, 0x70, 0x9a, 0xbc, 0xd2, 0xd5, 0x42, 0x3a, 0x17, 0x05, 0xe8, 0xae, 0x98, 0x94, 0xe1, 0xc3, 0x70, 0xa0, 0x68, 0x1d, 0xf6, 0x3b, 0x08, 0xc7, 0xb3, 0xfc, 0xcb, 0x7e, 0xd2, 0xf6, 0xbc, 0x44, 0xe0, 0x05, 0x54, 0xfb, 0xd8, 0xfd, 0x25, 0x6d, 0xe6, 0x99, 0xca, 0x89, 0x58, 0x55, 0x53, 0xcb, 0x66, 0xc3, 0x70, 0x11, 0x09, 0xb6, 0xd7, 0x00, 0xb5, 0x74, 0xa7, 0x05, 0x74, 0xf0, 0xdc, 0x53, 0x17, 0x9b, 0x13, 0xe1, 0x25, 0xda, 0xc5, 0x16, 0x00, 0x9b, 0xc5, 0x06, 0x8b, 0xa2, 0x77, 0x22, 0x3d, 0xa4, 0x53, 0xff, 0x01, 0xfe, 0x6d, 0x61, 0x9b, 0x89, 0x5e, 0x26, 0xe0, 0xa7, 0xee, 0xb9, 0xbb, 0x4a, 0x29, 0x5b, 0x0e, 0xb9, 0x16, 0x94, 0xa8, 0x66, 0x80, 0xfd, 0xa1, 0x76, 0x02, 0x0b, 0x9c, 0x2f, 0x7e, 0x6a, 0x8b, 0xcb, 0xf3, 0x3b, 0xf8, 0x85, 0xc8, 0xef, 0x8b, 0xc2, 0xfd, 0xbd, 0xf0, 0x00, 0xd8, 0xe8, 0xed, 0xc7, 0xf5, 0x67, 0xa3, 0x64, 0xb5, 0x13, 0x87, 0xec, 0x11, 0x03, 0x47, 0xfb, 0x08, 0x99, 0x0b, 0x1f, 0x3e, 0x00, 0xb9, 0x9e, 0x41, 0x58, 0xd8, 0x0a, 0xa9, 0x20, 0x9a, 0xe8, 0xf2, 0x15, 0x39, 0xd1, 0xf9, 0xee, 0xe4, 0x8d, 0x18, 0xda, 0x27, 0x83, 0xe0, 0xea, 0xd0, 0xe2, 0x02, 0xda, 0xe3, 0xe2, 0xeb, 0x88, 0x87, 0xce, 0xc2, 0x85, 0x0f, 0xb5, 0x7b, 0x81, 0xba, 0x64, 0x26, 0x3a, 0xea, 0x57, 0x3e, 0xd5, 0xcc, 0xac, 0x5c, 0xf2, 0x36, 0x6c, 0x37, 0xcb, 0xe0, 0x5c, 0xec, 0xb1, 0x06, 0xe6, 0xfa, 0x0a, 0xe4, 0x43, 0x6c, 0xdf, 0xec, 0xe2, 0xfa, 0x6e, 0xd5, 0x13, 0xea, 0x6f, 0x14, 0x23, 0x2a, 0x0b, 0x56, 0x7c, 0x1e, 0xb8, 0x73, 0x18, 0xba, 0x47, 0x0c, 0x7f, 0xcd, 0xf1, 0x3d, 0xff, 0xb7, 0x96, 0x30, 0x12, 0x7a, 0xf0, 0x73, 0xa2, 0x52, 0xfc, 0x3b, 0xd1, 0x3b, 0xd2, 0xbf, 0x65, 0xfc, 0xc0, 0xdc, 0x51, 0x75, 0x69, 0xf9, 0xcf, 0x8b, 0x2f, 0xf3, 0x56, 0x1f, 0x18, 0x96, 0xdd, 0xa9, 0x36, 0x5e, 0x73, 0x3e, 0x52, 0xef, 0x58, 0x49, 0x65, 0x71, 0x88, 0xaf, 0xe9, 0x78, 0xc9, 0x45, 0xab, 0xb6, 0x50, 0xf2, 0xe9, 0xa5, 0x3e, 0xf1, 0xe6, 0x59, 0x0b, 0x4e, 0x7d, 0x76, 0x01, 0xfd, 0x0b, 0x20, 0x8f, 0xdc, 0x0d, 0xd5, 0xb6, 0xa8, 0xd1, 0xf7, 0x4d, 0xf8, 0x32, 0x5e, 0xcd, 0x9e, 0x52, 0x21, 0xc9, 0xa9, 0x70, 0x6f, 0x4e, 0x6d, 0x6b, 0x22, 0x36, 0x20, 0x8a, 0x5d, 0x46, 0x4b, 0x77, 0x36, 0x41, 0xe4, 0xc8, 0xed, 0x80, 0x93, 0x1f, 0x0f, 0xc1, 0x2e, 0x62, 0x80, 0x8e, 0x02, 0xf9, 0xa9, 0xaf, 0xf5, 0x0c, 0x78, 0xc5, 0x17, 0x87, 0xb0, 0x52, 0x0a, 0x9e, 0x58, 0x68, 0x22, 0x1f, 0x87, 0x78, 0xe1, 0x7b, 0x6c, 0x3e, 0x5c, 0x37, 0x28, 0x13, 0x5a, 0x74, 0x7e, 0x73, 0xf1, 0xf7, 0xc8, 0xf1, 0xb9, 0xa1, 0x75, 0x3b, 0x75, 0x81, 0xd2, 0xe3, 0x97, 0x0b, 0x86, 0x0f, 0x27, 0x9f, 0x62, 0x14, 0x6d, 0x84, 0x21, 0xf3, 0x2e, 0x52, 0x4d, 0x44, 0x6f, 0x98, 0x59, 0x14, 0xdc, 0x20, 0xb6, 0xe0, 0x70, 0xb2, 0xd5, 0x9a, 0xde, 0x24, 0xde, 0x90, 0x33, 0xba, 0x20, 0xc0, 0x85, 0x1e, 0x5d, 0x0e, 0xac, 0x14, 0x9e, 0xb9, 0x4d, 0x79, 0xb0, 0x08, 0x45, 0xdf, 0x33, 0x36, 0x38, 0x68, 0xb6, 0x99, 0xf5, 0x70, 0x9c, 0x14, 0xf0, 0x8e, 0xeb, 0x8f, 0xc9, 0xc7, 0x5c, 0x99, 0xd2, 0x9e, 0x16, 0x35, 0x00, 0x94, 0xf1, 0xb3, 0x62, 0x54, 0x1d, 0xbd, 0x2c, 0x21, 0x87, 0x4f, 0xe0, 0xa7, 0x22, 0x25, 0xf2, 0x43, 0x18, 0x0a, 0x5d, 0xf1, 0x4e, 0xf0, 0x48, 0x2d, 0x49, 0x2b, 0x02, 0x7c, 0xb4, 0x69, 0xb8, 0x2d, 0x6f, 0xa4, 0x67, 0x8a, 0x28, 0xc1, 0xaa, 0xe3, 0x8e, 0x41, 0x31, 0xd1, 0xbe, 0x81, 0xb5, 0x6f, 0xa2, 0xfd, 0x0c, 0xee, 0xea, 0x7a, 0x82, 0xd3, 0xb1, 0x4f, 0xc7, 0x35, 0x43, 0x22, 0x3d, 0xfa, 0xb8, 0x21, 0x2e, 0x43, 0xf9, 0x44, 0xcc, 0x7c, 0x3c, 0x01, 0xda, 0x0a, 0xd1, 0xcf, 0x9c, 0xba, 0x8b, 0x14, 0xac, 0x84, 0x98, 0xa6, 0x13, 0x0b, 0x54, 0xd3, 0xcd, 0x9e, 0x4b, 0x20, 0x19, 0x55, 0xae, 0xdc, 0x3b, 0xcd, 0x01, 0xda, 0xdd, 0xb7, 0x20, 0x39, 0x00, 0x16, 0x98, 0x4d, 0xee, 0x06, 0x0d, 0x1b, 0xf1, 0x4f, 0x1f, 0x97, 0x4d, 0x7f, 0x33, 0x05, 0xf6, 0x2b, 0x38, 0x50, 0xe9, 0xbc, 0xe6, 0xa1, 0xb7, 0x40, 0xcf, 0xed, 0x6e, 0x64, 0xce, 0xc7, 0xec, 0x12, 0x0d, 0x01, 0x3e, 0x56, 0x95, 0xd6, 0x32, 0x87, 0xd8, 0x82, 0x5b, 0x83, 0x58, 0xa8, 0xe1, 0xbd, 0x32, 0xea, 0x39, 0x69, 0x57, 0x34, 0x7a, 0x5a, 0xb3, 0xf7, 0x83, 0x39, 0xc7, 0x9a, 0xbc, 0x4c, 0x5d, 0xce, 0x93, 0xcf, 0x38, 0xf8, 0x03, 0x62, 0x78, 0xbf, 0x19, 0x8f, 0x8b, 0xdb, 0x35, 0x7b, 0xdf, 0x93, 0x1d, 0x49, 0x42, 0x6a, 0x6f, 0x87, 0xdf, 0xdf, 0xd3, 0x05, 0xe7, 0xbe, 0xec, 0x47, 0xc0, 0xb6, 0xa9, 0xa5, 0x40, 0x76, 0x53, 0x66, 0x8c, 0x54, 0x44, 0xc5, 0x09, 0xfa, 0x09, 0xa2, 0x4d, 0x78, 0x76, 0x96, 0x47, 0x4e, 0xbe, 0xda, 0xb3, 0xed, 0xc8, 0x7e, 0xb6, 0x69, 0x26, 0xed, 0x4e, 0x18, 0x4e, 0x9f, 0x02, 0x84, 0x6b, 0xb3, 0x73, 0x07, 0x16, 0x2e, 0x3d, 0xd5, 0xe8, 0x0e, 0xe2, 0x32, 0xa3, 0x20, 0x52, 0x26, 0x92, 0xa4, 0xcf, 0x47, 0xf9, 0xbc, 0x11, 0xc1, 0x1a, 0xa8, 0x6e, 0x0a, 0x7a, 0x44, 0x2f, 0xf7, 0xa4, 0xd4, 0x68, 0x24, 0x68, 0x1d, 0xc6, 0x18, 0x37, 0xb6, 0x3b, 0x2c, 0x55, 0x60, 0x6c, 0xd9, 0x29, 0x85, 0xbe, 0x72, 0xe8, 0xae, 0x74, 0xf1, 0xdb, 0x26, 0xc5, 0x27, 0xce, 0xad, 0x40, 0x76, 0x37, 0x70, 0x77, 0x17, 0x6c, 0xa0, 0x95, 0x99, 0x50, 0x25, 0xe1, 0xf7, 0x49, 0x6d, 0x41, 0x9f, 0x47, 0x1b, 0x9b, 0x87, 0x78, 0x2f, 0xc4, 0x69, 0xbb, 0x5f, 0xd0, 0x81, 0xac, 0x79, 0xe0, 0x43, 0xa3, 0x63, 0x9f, 0x74, 0x89, 0x7b, 0x7c, 0x9f, 0x75, 0xed, 0xa9, 0x0d, 0x4d, 0xb6, 0x7e, 0x03, 0x78, 0xa3, 0xa1, 0xe4, 0x63, 0x69, 0x54, 0x83, 0xe2, 0x2c, 0x60, 0xc9, 0xa9, 0x15, 0x90, 0xb4, 0xd6, 0x92, 0x6c, 0x1b, 0x09, 0x1e, 0x66, 0xae, 0xc7, 0xa4, 0x25, 0x25, 0x58, 0x1b, 0x49, 0xbb, 0xf3, 0x10, 0xcf, 0xf7, 0x88, 0x69, 0xc5, 0x5e, 0x78, 0x2e, 0xa6, 0x34, 0xce, 0x66, 0x61, 0xa3, 0x3e, 0xed, 0xea, 0xea, 0x1c, 0x35, 0xf8, 0xfa, 0xf1, 0xb7, 0x3c, 0xd5, 0x08, 0x63, 0x83, 0x54, 0x0c, 0x3b, 0x39, 0x30, 0x47, 0xce, 0x7d, 0x59, 0x5c, 0xf4, 0x98, 0xec, 0x0a, 0x2e, 0x78, 0xcb, 0x25, 0x77, 0x35, 0x97, 0x7a, 0x2b, 0x0a, 0x7b, 0x7d, 0x47, 0x3c, 0xf2, 0x7f, 0x3b, 0x6b, 0x20, 0x74, 0x7c, 0x8e, 0x1d, 0xad, 0x03, 0x57, 0x7f, 0x17, 0x14, 0x78, 0xb3, 0xfe, 0x1d, 0xc6, 0xcd, 0x0e, 0x8c, 0xc6, 0x4e, 0xe0, 0x80, 0x8f, 0x12, 0x88, 0x27, 0x79, 0x32, 0xd3, 0xcc, 0xa7, 0x42, 0x66, 0x7e, 0x30, 0x62, 0x6b, 0x64, 0xf8, 0x49, 0xf4, 0x0a, 0x04, 0x04, 0x2c, 0x70, 0xe7, 0x9b, 0xf0, 0xba, 0xb5, 0xd9, 0x8a, 0x54, 0x61, 0xfd, 0x38, 0x1f, 0x5a, 0x81, 0xc6, 0xca, 0x48, 0x3a, 0x32, 0x3a, 0xa4, 0xf1, 0xcd, 0x06, 0xde, 0x00, 0xa6, 0x69, 0x56, 0xeb, 0x36, 0x6a, 0x79, 0xad, 0x41, 0x59, 0x8f, 0xa2, 0x38, 0xd0, 0x2d, 0x36, 0x69, 0x3d, 0xb1, 0x1a, 0xb9, 0x78, 0x52, 0x49, 0xa0, 0x53, 0x15, 0xae, 0xb7, 0x98, 0xbe, 0x0c, 0xf5, 0x87, 0x3d, 0x2e, 0xfc, 0xf8, 0x76, 0xda, 0x20, 0xca, 0xfb, 0xbb, 0xf4, 0xc2, 0x7d, 0x40, 0xe6, 0x2e, 0x7c, 0x4e, 0x4f, 0xbd, 0x0e, 0xec, 0xe3, 0x3c, 0xf9, 0xc5, 0x20, 0xa0, 0x81, 0x05, 0xec, 0x6b, 0x53, 0xdc, 0x14, 0x58, 0xfb, 0xdc, 0x57, 0xdd, 0xca, 0x1d, 0x47, 0xa3, 0x7c, 0x55, 0x08, 0x2a, 0x67, 0xe2, 0xc9, 0xcb, 0x2b, 0x09, 0xd6, 0x9f, 0x20, 0x2e, 0xc6, 0xe6, 0x92, 0x23, 0x57, 0x37, 0x2b, 0x90, 0x1d, 0xa4, 0x99, 0x3c, 0x1c, 0x3c, 0x3a, 0xa7, 0x0e, 0x8d, 0x43, 0xba, 0x0b, 0xa8, 0x48, 0xfe, 0xed, 0xaf, 0x0c, 0xc9, 0x1c, 0x3a, 0xe6, 0xbe, 0x88, 0x33, 0x9f, 0x2e, 0x52, 0x0e, 0x5d, 0xa9, 0x56, 0xcc, 0xb1, 0xe9, 0x24, 0x57, 0xba, 0x84, 0x32, 0xbb, 0xbb, 0x70, 0xf3, 0x15, 0xc7, 0xb8, 0x9d, 0x65, 0xe4, 0x0e, 0x46, 0x0a, 0xcb, 0xe4, 0xc5, 0xe0, 0xd6, 0x97, 0x31, 0x61, 0xff, 0x7c, 0xd1, 0x58, 0xab, 0xf0, 0x49, 0x79, 0x6d, 0xce, 0x74, 0xdb, 0x1f, 0x61, 0xd6, 0xed, 0xb9, 0xa2, 0x3d, 0x45, 0x38, 0x2a, 0xa3, 0x01, 0xbd, 0x13, 0x9a, 0x89, 0x2d, 0xc0, 0xc6, 0x65, 0x7c, 0xa8, 0x78, 0x21, 0xf9, 0x14, 0xd6, 0xcf, 0x2e, 0xfb, 0xbb, 0x32, 0x8c, 0x54, 0x3a, 0xd2, 0x59, 0xef, 0xfa, 0x86, 0x8b, 0xa9, 0xf5, 0xca, 0x21, 0x43, 0x64, 0x04, 0x1f, 0xe6, 0x34, 0x86, 0x0a, 0x78, 0x7e, 0x5b, 0x77, 0xe2, 0x33, 0x4c, 0x03, 0x28, 0x4a, 0x43, 0x43, 0xed, 0xab, 0x5d, 0x71, 0x27, 0x89, 0x1e, 0x60, 0x0b, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xbd, 0x06, 0xe6, 0x81, 0xc1, 0x54, 0x6f, 0xac, 0xd2, 0xf5, 0x33, 0x2c, 0xba, 0x45, 0x07, 0x6c, 0x61, 0x0b, 0x2e, 0x28, 0x8f, 0x00, 0x2e, 0x36, 0x6f, 0xb2, 0x4f, 0x99, 0x02, 0xde, 0x8a, 0xe7, 0xa3, 0xf3, 0x49, 0xc1, 0x44, 0xab, 0x21, 0x21, 0x35, 0x07, 0x00, 0x05, 0x27, 0x1f, 0xe9, 0x04, 0xfe, 0xe7, 0xbb, 0x2e, 0x02, 0xfa, 0xc3, 0xd2, 0xb1, 0x9f, 0x33, 0x25, 0x56, 0xe2, 0x92, 0x48, 0x31, 0xaf, 0xf7, 0xbc, 0x67, 0x59, 0x3b, 0x2d, 0xb6, 0x46, 0x08, 0xd5, 0x59, 0xc2, 0x98, 0x68, 0xe2, 0xa6, 0xb9, 0x9a, 0x92, 0x53, 0xbc, 0xa8, 0xff, 0x6b, 0x30, 0x00, 0x00, 0x00, 0x77, 0xe3, 0xef, 0x5d, 0x5d, 0x23, 0xc7, 0x48, 0x6b, 0xe5, 0x94, 0xbe, 0x8f, 0x9b, 0xa7, 0x8b, 0xf2, 0xc3, 0x8e, 0x70, 0xde, 0xd2, 0xfb, 0x50, 0x7a, 0x12, 0x4a, 0x40, 0xcc, 0x9b, 0x51, 0x91, 0xef, 0x1c, 0xdc, 0x5a, 0x60, 0xf0, 0xfa, 0xab, 0xac, 0xaf, 0xfb, 0x9a, 0x29, 0xce, 0xa3, 0x6f, 0x23, 0x35, 0x9d, 0x23, 0x51, 0xc2, 0x2f, 0xda, 0x93, 0x03, 0x76, 0x77, 0x28, 0xd7, 0x6f, 0x00, 0xca, 0x1c, 0xf2, 0x59, 0x0a, 0xab, 0x03, 0xe3, 0x3f, 0xac, 0xbf, 0x3c, 0x75, 0x52, 0x00, 0xd0, 0xc4, 0x1f, 0x60, 0xc2, 0x01, 0x52, 0xed, 0xa3, 0x34, 0x87, 0x2e, 0xc1, 0xd5, 0x82, 0xe0, 0xb4, 0x2c, 0xa9, 0x27, 0xab, 0x7f, 0x46, 0x66, 0x21, 0xb9, 0x84, 0x85, 0x0a, 0xfe, 0x7a, 0x71, 0xe8, 0x1c, 0xa1, 0x3f, 0xae, 0xfe, 0x00, 0xf1, 0x09, 0x0b, 0xf0, 0x20, 0x8d, 0xcb, 0x0b, 0x96, 0x91, 0xbd, 0x27, 0xee, 0x7a, 0xee, 0xde, 0x42, 0x5c, 0x69, 0x4b, 0x07, 0xb3, 0xd1, 0xef, 0xec, 0xd6, 0x91, 0x0f, 0x22, 0x70, 0x81, 0x63, 0xd6, 0xfd, 0x7e, 0x29, 0xc6, 0xbe, 0xfe, 0x1a, 0x18, 0xe8, 0x14, 0x91, 0xc5, 0xee, 0x81, 0x63, 0xd8, 0xa9, 0x0a, 0x49, 0xb7, 0x1d, 0x8f, 0x8b, 0x5c, 0xb5, 0xce, 0x46, 0x92, 0x4c, 0xa5, 0xff, 0xc9, 0x54, 0x09, 0xa1, 0xf9, 0x73, 0x23, 0xbc, 0x16, 0x9d, 0xac, 0x28, 0xa5, 0x85, 0x68, 0xea, 0x09, 0xd5, 0x0d, 0xde, 0x11, 0xde, 0xf9, 0x9b, 0x0a, 0x30, 0xf0, 0x60, 0xa3, 0xb1, 0x96, 0x6c, 0x6d, 0x97, 0xa7, 0x0a, 0xb9, 0x3a, 0xba, 0xa1, 0xc6, 0xfa, 0x63, 0xc3, 0x01, 0x2d, 0x2e, 0xd5, 0xc5, 0x29, 0xfb, 0x12, 0x8a, 0x88, 0x5a, 0x92, 0x13, 0xc0, 0x9c, 0xc9, 0xe8, 0xa2, 0x93, 0xac, 0x1d, 0xdd, 0xa6, 0xda, 0xd0, 0xa0, 0xb6, 0xb2, 0xd1, 0xb8, 0xa7, 0x1a, 0x1f, 0x21, 0xef, 0x07, 0xd0, 0xae, 0xeb, 0x54, 0x12, 0x94, 0x80, 0x25, 0x3b, 0x0f, 0xaf, 0x4b, 0x0d, 0x8a, 0xa3, 0x8d, 0xf7, 0x4b, 0x3d, 0x37, 0x8b, 0xcf, 0xf0, 0x6b, 0x84, 0x30, 0x5d, 0x20, 0xd8, 0x9a, 0xf6, 0x73, 0xb6, 0xd3, 0xc4, 0x2a, 0xc2, 0xe9, 0xc0, 0x01, 0xa6, 0x9c, 0xc8, 0x56, 0xa0, 0x0e, 0xc0, 0x1f, 0x29, 0xb2, 0xcb, 0x8c, 0x49, 0xb9, 0xf9, 0xe0, 0x85, 0x47, 0x05, 0x7d, 0xb4, 0xe9, 0xdb, 0x92, 0xbd, 0x24, 0xd5, 0xda, 0x30, 0x4e, 0xd2, 0x75, 0x55, 0x42, 0x62, 0x6a, 0x74, 0xa9, 0xb8, 0xe8, 0xd0, 0xfd, 0x88, 0xa9, 0xde, 0x84, 0x89, 0x3d, 0x9e, 0x5b, 0xc8, 0x08, 0x3c, 0x8e, 0x96, 0x47, 0x4c, 0x2d, 0x91, 0x28, 0x5c, 0xee, 0xf9, 0x74, 0xb4, 0x74, 0xc3, 0xe5, 0xb8, 0xda, 0x35, 0xf9, 0x9c, 0x83, 0x0a, 0x21, 0x70, 0xff, 0xcb, 0x95, 0x0c, 0x5a, 0xfa, 0x96, 0x01, 0x0a, 0x2c, 0x7b, 0x7d, 0x3c, 0x0e, 0xcf, 0x78, 0x81, 0x83, 0x64, 0x8c, 0x55, 0x64, 0xe2, 0xdb, 0x6e, 0x4b, 0xdd, 0xd8, 0x49, 0x23, 0x89, 0x34, 0x97, 0x86, 0x87, 0xe7, 0x36, 0x31, 0x9a, 0xb9, 0xdc, 0x60, 0x80, 0xb2, 0xea, 0x55, 0xbc, 0x82, 0x31, 0xc7, 0xb2, 0x35, 0x46, 0x2a, 0x7a, 0xe7, 0x7f, 0x94, 0xfc, 0x18, 0xef, 0x90, 0x6b, 0xe1, 0x71, 0xf0, 0x79, 0xff, 0xf8, 0xcd, 0x05, 0x2b, 0x16, 0x00, 0x3e, 0x5a, 0x3c, 0x57, 0x7d, 0x67, 0x7c, 0x13, 0x02, 0x3d, 0xed, 0xc6, 0x05, 0x29, 0x90, 0x60, 0x1c, 0x46, 0x40, 0x6f, 0xf0, 0xaa, 0xb5, 0xde, 0x7c, 0x75, 0xeb, 0x51, 0x99, 0xa7, 0xbb, 0x40, 0x85, 0xd4, 0x13, 0x9c, 0x99, 0xb5, 0x03, 0xc6, 0xbc, 0x27, 0x04, 0x65, 0x49, 0xc7, 0x3b, 0xff, 0x21, 0xa0, 0x28, 0xb2, 0x06, 0x66, 0x29, 0xdf, 0x29, 0x00, 0x3c, 0x66, 0x30, 0x8b, 0x98, 0xe5, 0xea, 0x0d, 0xf9, 0xe3, 0xbb, 0x2c, 0x45, 0x06, 0x3b, 0xff, 0x78, 0xfb, 0xf8, 0x67, 0xca, 0xe4, 0x92, 0x29, 0xd7, 0xb2, 0x3c, 0x06, 0xf3, 0x16, 0x40, 0x35, 0x3b, 0xdd, 0xd2, 0xd2, 0xdb, 0xc0, 0x73, 0xd6, 0x3e, 0xd1, 0x0a, 0xb2, 0xa6, 0x82, 0x56, 0x75, 0xf2, 0xcf, 0xa4, 0x97, 0x21, 0xbf, 0xc2, 0xa6, 0x8c, 0xc6, 0xfb, 0x5b, 0xe2, 0xf4, 0xe0, 0x6f, 0x9c, 0x73, 0x36, 0x53, 0x05, 0x09, 0x59, 0x03, 0xba, 0x28, 0xca, 0xe2, 0x68, 0xd6, 0xee, 0x38, 0x14, 0x7a, 0x74, 0xe9, 0xe4, 0x13, 0xcb, 0x82, 0xde, 0x11, 0x1a, 0x97, 0x75, 0x6a, 0xc4, 0xa6, 0x55, 0x27, 0x11, 0xc1, 0x67, 0xfb, 0xe9, 0xbf, 0x0e, 0x45, 0x02, 0x0c, 0xbf, 0xce, 0x7e, 0xde, 0xdc, 0xf7, 0x18, 0xf5, 0xff, 0x8e, 0xc7, 0xf4, 0xd5, 0xe9, 0xa4, 0x37, 0x05, 0xc8, 0x68, 0xfc, 0xc3, 0x81, 0x62, 0x15, 0x97, 0x22, 0xa6, 0x61, 0x7d, 0x58, 0x8d, 0x21, 0xc8, 0x4e, 0x0f, 0x30, 0x20, 0x4f, 0x5a, 0x8c, 0x37, 0x81, 0x8d, 0x60, 0xcb, 0xd5, 0x7d, 0x89, 0x14, 0x16, 0xc2, 0x0e, 0x7f, 0x48, 0xe3, 0x26, 0x77, 0x75, 0xc2, 0x27, 0xa6, 0xa6, 0x43, 0xeb, 0xcf, 0x37, 0xc2, 0xfa, 0x10, 0x23, 0xa9, 0xdc, 0xe1, 0x94, 0xb8, 0xf9, 0xc9, 0xd8, 0xff, 0xc8, 0xd5, 0xc5, 0xd9, 0xdf, 0xb5, 0x9e, 0x60, 0x64, 0xe1, 0x6a, 0x62, 0x1a, 0xf5, 0xcb, 0x05, 0x88, 0x15, 0xd4, 0x94, 0xc5, 0x3f, 0xdc, 0x26, 0x89, 0x7f, 0x7d, 0x63, 0x34, 0x53, 0x81, 0x8e, 0xb9, 0x4b, 0xd9, 0x5c, 0x06, 0xf6, 0x95, 0xe3, 0x4a, 0xac, 0x67, 0xed, 0x2c, 0x8d, 0x1f, 0x53, 0xf0, 0xd4, 0x10, 0x34, 0xcd, 0x50, 0x3f, 0x1b, 0x1f, 0xbe, 0x9c, 0x68, 0x16, 0x9d, 0x02, 0x66, 0xc8, 0x92, 0x5c, 0x2e, 0x22, 0xe4, 0x25, 0xa1, 0x78, 0x93, 0xfb, 0xbe, 0x4b, 0x1f, 0x50, 0x7c, 0x10, 0x99, 0xda, 0x35, 0x16, 0xb8, 0x35, 0x38, 0x79, 0x5d, 0xcd, 0xa2, 0x1c, 0x5a, 0xa4, 0x9b, 0x26, 0x56, 0x37, 0x2f, 0xa3, 0x63, 0x7e, 0x8f, 0xf7, 0x89, 0xbd, 0x62, 0x30, 0xec, 0x49, 0x5b, 0xc9, 0x13, 0x75, 0x96, 0x6e, 0x2d, 0x92, 0x32, 0x27, 0x67, 0x31, 0x4d, 0xf9, 0xf3, 0x2e, 0xc7, 0xbe, 0x01, 0x69, 0xac, 0x5a, 0x20, 0xf3, 0xfd, 0xa0, 0xf1, 0x44, 0xba, 0x45, 0x89, 0x71, 0x2a, 0xca, 0x82, 0xfa, 0x28, 0x22, 0xd9, 0x4b, 0xc4, 0x00, 0xb7, 0xa1, 0x4d, 0xd1, 0xe8, 0xa3, 0xc7, 0xd5, 0x25, 0xf5, 0xcb, 0x0e, 0xa6, 0x3e, 0xa3, 0x7a, 0x10, 0x99, 0xad, 0xc0, 0x84, 0x4d, 0x43, 0x7d, 0x04, 0x9e, 0xea, 0xf1, 0xbe, 0xa7, 0xb0, 0xf0, 0x44, 0xfa, 0x0a, 0x2f, 0xed, 0x27, 0xf6, 0x9e, 0x96, 0x0a, 0x89, 0x10, 0x07, 0x6f, 0x19, 0x3b, 0x21, 0x0e, 0xac, 0x89, 0xa1, 0xb7, 0xeb, 0x25, 0x21, 0xea, 0x4c, 0x53, 0xcc, 0x4b, 0xfc, 0xc0, 0xb9, 0x86, 0x65, 0x98, 0x92, 0xbe, 0x64, 0x26, 0x12, 0xac, 0x80, 0x74, 0x90, 0x15, 0x47, 0x67, 0x3d, 0x69, 0x56, 0x98, 0x6c, 0xaf, 0x4d, 0x04, 0x4a, 0xac, 0xcb, 0xc8, 0xe2, 0xb1, 0x75, 0xf8, 0xcf, 0xf6, 0xa2, 0x3f, 0xa1, 0x6e, 0xfe, 0xd6, 0xf7, 0x03, 0x30, 0x1f, 0x0c, 0x59, 0x3a, 0xd0, 0x31, 0x75, 0xf2, 0xd2, 0x33, 0x94, 0xdc, 0xe1, 0xb4, 0xe2, 0xe8, 0xdf, 0xaf, 0x65, 0xa3, 0x92, 0x83, 0x56, 0x27, 0x71, 0x28, 0xf6, 0x38, 0x1d, 0x25, 0x60, 0xa7, 0x0f, 0x4b, 0xb8, 0x50, 0xe9, 0x67, 0xeb, 0x72, 0x5d, 0x31, 0xae, 0x5e, 0x40, 0x23, 0x38, 0xe1, 0x5f, 0x0f, 0x10, 0x27, 0xa6, 0x6d, 0x6f, 0x11, 0xf8, 0x62, 0xc3, 0x23, 0x4f, 0x19, 0x4a, 0x7d, 0x7f, 0xdb, 0x2a, 0x39, 0x34, 0x73, 0x65, 0x45, 0x0e, 0x0d, 0xee, 0x31, 0x55, 0x60, 0x64, 0x07, 0xb9, 0x59, 0x12, 0xa0, 0x27, 0xc1, 0xc7, 0xdf, 0x65, 0x31, 0x7f, 0x8e, 0x6f, 0x32, 0x7c, 0xcc, 0x6b, 0x1d, 0xfa, 0x42, 0x4b, 0x34, 0xec, 0xd3, 0x7e, 0x65, 0x68, 0x66, 0x64, 0x86, 0x47, 0x20, 0x69, 0x21, 0xfb, 0x82, 0x06, 0x75, 0x40, 0x37, 0x18, 0x6e, 0x30, 0x6c, 0xe6, 0x8d, 0xcb, 0x2f, 0x4d, 0xf7, 0xcb, 0xe4, 0x65, 0x06, 0x75, 0xe3, 0xd8, 0x9a, 0x47, 0x09, 0x5a, 0x50, 0x07, 0x1e, 0x2e, 0xe0, 0xda, 0x77, 0xe3, 0xbb, 0x52, 0x0d, 0xf5, 0x52, 0xc0, 0xd4, 0x33, 0xbf, 0xec, 0x6e, 0x41, 0x10, 0x4f, 0xda, 0x37, 0x53, 0xfa, 0x96, 0x4f, 0x39, 0xcf, 0x06, 0xf2, 0x92, 0x3a, 0xe5, 0x43, 0x7e, 0x5a, 0x3d, 0x8d, 0xcf, 0xb1, 0x6c, 0xc6, 0x09, 0xdd, 0xda, 0x64, 0x43, 0xd5, 0xbb, 0x46, 0x56, 0x59, 0x36, 0x3d, 0x70, 0xe4, 0xd1, 0xea, 0x48, 0xd4, 0x49, 0x49, 0xb5, 0x1a, 0xbc, 0x45, 0x16, 0x04, 0x78, 0xb6, 0xa1, 0x6e, 0xea, 0x53, 0x14, 0x1a, 0x77, 0xb9, 0x01, 0x98, 0xa3, 0x66, 0x19, 0x4d, 0x5d, 0x86, 0x24, 0x08, 0x3b, 0x21, 0xbb, 0x99, 0x96, 0x90, 0x9e, 0xe3, 0x2e, 0xcb, 0xb2, 0xc4, 0x38, 0x55, 0xb5, 0x4c, 0xe4, 0x5a, 0x52, 0xe2, 0xdf, 0xc2, 0xa1, 0xfc, 0xa4, 0xe7, 0x1f, 0x10, 0xc7, 0x20, 0xc4, 0xf3, 0x21, 0x41, 0xfd, 0x42, 0x34, 0x0d, 0xa2, 0x4c, 0x56, 0x7d, 0xd4, 0xc5, 0xc1, 0x7d, 0x97, 0x6a, 0xed, 0x8a, 0x10, 0xfc, 0xec, 0x21, 0xa6, 0xfb, 0x94, 0x16, 0x6b, 0xf9, 0xe4, 0xae, 0x85, 0xbd, 0x86, 0x08, 0x35, 0xbc, 0x7e, 0x52, 0x7a, 0xb5, 0x24, 0x70, 0x81, 0x29, 0xb2, 0x6e, 0x84, 0xbd, 0x53, 0xb1, 0x0b, 0x90, 0xf1, 0x6f, 0x87, 0xe8, 0x57, 0x2d, 0x5c, 0x57, 0x2a, 0x7a, 0x11, 0xc9, 0x39, 0x60, 0x3c, 0xda, 0x5f, 0xa5, 0x20, 0x85, 0xa7, 0x5d, 0x30, 0x56, 0x78, 0xfe, 0x2c, 0x6f, 0x92, 0x99, 0x32, 0x9d, 0x28, 0x26, 0xd5, 0x4a, 0x72, 0xb0, 0x86, 0x25, 0x43, 0x21, 0xc8, 0x7b, 0x93, 0x3e, 0xdb, 0x8a, 0x6b, 0xcd, 0x1d, 0x28, 0x99, 0x9f, 0x51, 0x4b, 0x1a, 0x49, 0x49, 0x93, 0x99, 0xa8, 0x4b, 0xfd, 0xe6, 0x42, 0xaa, 0x41, 0x66, 0xec, 0xf1, 0xf2, 0xae, 0x9d, 0x6f, 0x6f, 0x17, 0xf6, 0x6d, 0x74, 0x61, 0x81, 0xb9, 0x3e, 0x80, 0x17, 0xec, 0x08, 0xe8, 0x73, 0x63, 0x0b, 0x5e, 0x3e, 0x37, 0xfd, 0x1c, 0xd8, 0x5f, 0xf4, 0xfd, 0x65, 0x7b, 0x88, 0xe8, 0x45, 0xf6, 0x02, 0x29, 0x5c, 0xab, 0xbd, 0xed, 0x34, 0xff, 0x8b, 0xcb, 0x8c, 0xd6, 0x0c, 0x4c, 0xc4, 0xa7, 0xff, 0x44, 0xd2, 0xa9, 0xf1, 0x35, 0x55, 0x5f, 0x89, 0x08, 0xa5, 0x92, 0xd9, 0x69, 0xe0, 0x8e, 0x1b, 0xa3, 0xc4, 0xdb, 0x6e, 0x10, 0xfe, 0xb9, 0x2b, 0x89, 0xfa, 0x5d, 0xf0, 0x15, 0x4c, 0xa7, 0x5c, 0xa9, 0x0d, 0x23, 0x2f, 0xf0, 0xc1, 0x29, 0xf6, 0xd6, 0x7e, 0xce, 0xc1, 0x44, 0xd9, 0xdd, 0x13, 0x2f, 0x7a, 0x72, 0x17, 0xaf, 0x89, 0xd4, 0xee, 0x9d, 0x1b, 0xb6, 0xbf, 0xc1, 0x58, 0x98, 0x22, 0xc3, 0x24, 0x89, 0xf5, 0x48, 0xb1, 0xbb, 0x84, 0x1b, 0x67, 0x5e, 0x49, 0x0b, 0xd3, 0xee, 0xa4, 0xe6, 0x34, 0x45, 0xb7, 0xeb, 0x0b, 0xd4, 0x62, 0x2e, 0x4b, 0x4b, 0xe4, 0x41, 0xc2, 0xda, 0x41, 0x58, 0x56, 0x06, 0x83, 0xdc, 0xe1, 0xda, 0xff, 0x8f, 0x57, 0x83, 0xe6, 0xeb, 0x0d, 0xfd, 0x7a, 0x2f, 0x4b, 0x33, 0x48, 0x19, 0x5f, 0xa0, 0xe0, 0x8c, 0xae, 0x03, 0x92, 0xeb, 0xb9, 0xbd, 0xef, 0xdf, 0x6c, 0x66, 0x8e, 0x5e, 0xf0, 0xd7, 0x74, 0xaa, 0xf6, 0xe6, 0x56, 0x4e, 0x51, 0x0f, 0x23, 0x68, 0xb5, 0xcb, 0x6b, 0x41, 0x0d, 0x8a, 0x6c, 0x2b, 0x0f, 0x19, 0xaf, 0xf1, 0xe5, 0xc8, 0xad, 0x43, 0x2f, 0x94, 0x44, 0xa9, 0xcb, 0x54, 0x29, 0x79, 0xa1, 0xab, 0x76, 0xec, 0x29, 0x7c, 0xaf, 0xa0, 0x83, 0x9a, 0x89, 0x0d, 0x51, 0xed, 0x19, 0xec, 0x75, 0xea, 0x72, 0xa9, 0x7d, 0x67, 0x22, 0x7d, 0x65, 0x7d, 0xc4, 0xf6, 0xd5, 0xc9, 0x0a, 0x8b, 0xba, 0x16, 0x02, 0xb5, 0x98, 0x63, 0x4a, 0x36, 0xc2, 0xae, 0x68, 0xec, 0x60, 0x0b, 0xdc, 0x53, 0x8e, 0xfd, 0x3a, 0x9c, 0xf9, 0x4e, 0x8f, 0x70, 0xec, 0x69, 0x4f, 0x6e, 0x02, 0xf3, 0x5f, 0x23, 0xf8, 0xa4, 0x28, 0xdd, 0x42, 0xaf, 0xc9, 0xaa, 0xaf, 0x2f, 0x9c, 0x10, 0xa1, 0x78, 0x26, 0x76, 0x39, 0x6f, 0x4f, 0x32, 0x60, 0xf5, 0x88, 0xb6, 0xf4, 0x98, 0x01, 0x6e, 0x65, 0x92, 0xfd, 0x86, 0x98, 0xfe, 0x11, 0xaa, 0x0f, 0xb6, 0x4f, 0x36, 0xfb, 0x0b, 0x77, 0x58, 0xfa }; +constexpr AccessUnit AC3_MULTIPLE_PACK_EXPECTED_AU_1 = { 0x15f90, 0x159b2, false, 0, {}, { 0x79, 0x8a, 0x07, 0x46, 0x57, 0xa6, 0x1d, 0x59, 0x7a, 0xdd, 0x08, 0xfc, 0xd0, 0xe3, 0x3b, 0xef, 0xe7, 0x60, 0xa5, 0x91 } }; +constexpr AccessUnit AC3_MULTIPLE_PACK_EXPECTED_AU_2 = { 0x6c30bb8a, 0x132b3bdd, false, 0, {}, { 0x67, 0x41, 0xc8, 0x5f, 0xec, 0xad, 0xd9, 0x3d, 0xce, 0x0f, 0x03, 0x89, 0x70, 0x81, 0x04, 0x15, 0xa1, 0x4a, 0x0c, 0xf9 } }; +constexpr AccessUnit AC3_MULTIPLE_PACK_EXPECTED_AU_3 = { 0x15f90, 0x159b2, false, 0, {}, { 0x7c, 0x0e, 0xf4, 0xe5, 0x3e, 0x5d, 0x1f, 0xaa, 0x37, 0x09, 0x54, 0x74, 0x63, 0x57, 0xae, 0xc3, 0x72, 0x53, 0x53, 0xab } }; +constexpr AccessUnit AC3_MULTIPLE_PACK_EXPECTED_AU_4 = { std::numeric_limits::max(), std::numeric_limits::max(), false, 0, {}, { 0xa0, 0xcf, 0xde, 0x0c, 0x55, 0x6a, 0x70, 0x0b, 0x74, 0x55, 0x2b, 0x81, 0x2e, 0x70, 0xe7, 0x55, 0x67, 0xfa, 0x32, 0xa4 } }; + + +constexpr std::array AVC_TINY_PACKETS_STREAM = { 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xe9, 0xb2, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0xee, 0x01, 0xe0, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x37, 0x00, 0x80, 0xbe, 0x21, 0x00, 0x80, 0x0a, 0xd8, 0x00, 0x00, 0x0a, 0xb1, 0x00, 0x80, 0x09, 0xa5, 0x00, 0x00, 0x0a, 0x1d, 0x00, 0x80, 0x09, 0x53, 0x00, 0x00, 0x09, 0x6d, 0x00, 0x80, 0x08, 0xca, 0x00, 0x00, 0x09, 0x5b, 0x00, 0x80, 0x08, 0xa2, 0x00, 0x00, 0x08, 0xda, 0x00, 0x80, 0x08, 0x73, 0x00, 0x00, 0x09, 0x16, 0x00, 0x80, 0x08, 0x61, 0x00, 0x00, 0x08, 0x9f, 0x00, 0x80, 0x08, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x80, 0x08, 0x56, 0x00, 0x00, 0x08, 0x61, 0x00, 0x80, 0x08, 0x20, 0x00, 0x00, 0x08, 0x67, 0x00, 0x80, 0x07, 0xcc, 0x00, 0x00, 0x08, 0x8f, 0x00, 0x80, 0x08, 0x25, 0x00, 0x00, 0x08, 0x53, 0x00, 0x80, 0x07, 0xa0, 0x00, 0x00, 0x08, 0x14, 0x00, 0x80, 0x07, 0xc9, 0x00, 0x00, 0x08, 0x17, 0x00, 0x80, 0x07, 0xc1, 0x00, 0x00, 0x08, 0x46, 0x00, 0x80, 0x07, 0xb0, 0x00, 0x00, 0x07, 0xbd, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x08, 0x0c, 0x00, 0x80, 0x07, 0x91, 0x00, 0x00, 0x08, 0x5d, 0x00, 0x80, 0x07, 0x8f, 0x00, 0x00, 0x07, 0xdd, 0x00, 0x80, 0x07, 0x80, 0x00, 0x00, 0x07, 0xe6, 0x00, 0x80, 0x07, 0x7f, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x80, 0x07, 0x94, 0x00, 0x00, 0x07, 0xc5, 0x00, 0x80, 0x07, 0xab, 0x00, 0x00, 0x07, 0xec, 0x00, 0x80, 0x07, 0x74, 0x00, 0x00, 0x07, 0xb6, 0x00, 0x80, 0x07, 0x79, 0x00, 0x00, 0x07, 0xff, 0x00, 0x80, 0x07, 0x76, 0x00, 0x00, 0x07, 0xe2, 0x00, 0x80, 0x07, 0xd1, 0x00, 0x00, 0x07, 0xb3, 0x00, 0x00, 0x01, 0xe0, 0x06, 0xe6, 0x81, 0xc1, 0x0d, 0x31, 0x00, 0x05, 0xbf, 0x21, 0x11, 0x00, 0x05, 0xb3, 0x65, 0x1e, 0x69, 0xb2, 0x75, 0x62, 0x06, 0xcf, 0xeb, 0x38, 0xf4, 0x91, 0x03, 0xac, 0x06, 0xee, 0xf5, 0x5a, 0x22, 0x5e, 0xb8, 0xd5, 0xf1, 0x50, 0x3f, 0x49, 0xd9, 0x47, 0x75, 0xc3, 0x8c, 0x6d, 0xac, 0x33, 0xc5, 0xc6, 0xc8, 0x25, 0x8f, 0x11, 0xd3, 0xf6, 0xf6, 0xdb, 0xad, 0xca, 0x5d, 0x4e, 0x0f, 0xb9, 0x1f, 0x1d, 0xe5, 0x5d, 0xb7, 0xd3, 0xfa, 0x76, 0xa6, 0x64, 0x99, 0xd0, 0x7b, 0x8e, 0xc2, 0x09, 0xf4, 0x2a, 0x11, 0x3c, 0x1b, 0xe4, 0xe5, 0xee, 0xe4, 0x36, 0x2f, 0x63, 0xa5, 0x8e, 0x5e, 0x32, 0x59, 0x17, 0xcd, 0x22, 0xb5, 0xf0, 0xea, 0xe3, 0xef, 0x22, 0x1e, 0x67, 0x46, 0xeb, 0x93, 0x3f, 0x90, 0x49, 0x38, 0x0c, 0xa0, 0xe5, 0x1c, 0x11, 0x94, 0xec, 0x8f, 0xc0, 0x4f, 0x87, 0xaf, 0xcb, 0x41, 0xa8, 0x17, 0xa7, 0x2e, 0xdb, 0x53, 0xaf, 0x6c, 0x07, 0x54, 0x78, 0xba, 0x15, 0xf0, 0xdc, 0xd7, 0x18, 0x9d, 0x9e, 0x6d, 0x3b, 0x0b, 0xac, 0xfb, 0x58, 0x04, 0x1c, 0x96, 0x36, 0xe8, 0x40, 0xf2, 0x76, 0xb8, 0x71, 0x30, 0x6c, 0x66, 0x24, 0x50, 0xa4, 0x58, 0x7b, 0x45, 0xaa, 0x5e, 0x04, 0x1d, 0x17, 0xf8, 0x5b, 0x68, 0x51, 0xf0, 0xb1, 0x06, 0xe5, 0x47, 0xb0, 0xb0, 0x55, 0xe1, 0xb8, 0x3d, 0x28, 0x6e, 0x8e, 0x63, 0x4c, 0x61, 0x05, 0xa8, 0xfd, 0x5a, 0x15, 0xf3, 0xed, 0xbb, 0x7d, 0xe3, 0x7e, 0x35, 0x93, 0x55, 0xb2, 0x8d, 0x0c, 0xe9, 0x89, 0xbc, 0xaa, 0xf5, 0x9f, 0x6a, 0xc3, 0x41, 0xf8, 0x34, 0xb7, 0xd5, 0x09, 0x41, 0x37, 0x6b, 0x0e, 0xc3, 0xd1, 0x1a, 0x3e, 0xe4, 0x68, 0xb9, 0x9a, 0xc4, 0x24, 0x7c, 0x57, 0x8a, 0x2c, 0x69, 0xf9, 0x4b, 0x4d, 0xd0, 0x4a, 0x9b, 0x0e, 0x93, 0x4f, 0xcd, 0xb5, 0x41, 0xc6, 0x2e, 0x98, 0x0a, 0x14, 0x8d, 0xa4, 0xf7, 0x3a, 0x19, 0x85, 0x89, 0x56, 0xcb, 0x85, 0x0b, 0x4b, 0x99, 0x8b, 0xb0, 0x11, 0xd6, 0xd7, 0xbe, 0x0c, 0xf8, 0x6d, 0x9c, 0xd9, 0xb0, 0x96, 0x8c, 0x70, 0x74, 0x10, 0x54, 0xd7, 0x98, 0x50, 0x5d, 0x4e, 0x24, 0xb9, 0x41, 0xe3, 0x6f, 0xe6, 0x9d, 0x89, 0x9e, 0xef, 0x3f, 0xc0, 0x4e, 0x11, 0x59, 0xe6, 0x5d, 0x94, 0x4e, 0x5d, 0xb6, 0x21, 0xf6, 0xcd, 0x2b, 0x8e, 0x82, 0x6e, 0xc1, 0xb1, 0x1a, 0xcd, 0xad, 0xfc, 0x4c, 0x16, 0x9b, 0x98, 0xa9, 0x6b, 0xcd, 0xd0, 0xd5, 0x78, 0x0e, 0x97, 0x97, 0x1a, 0xa2, 0xf0, 0xdb, 0xea, 0xf9, 0x88, 0x74, 0xea, 0x85, 0x8a, 0x80, 0xcb, 0x70, 0xfd, 0x6b, 0xf6, 0x31, 0xab, 0xaf, 0x8d, 0xee, 0xba, 0x67, 0xcc, 0xdc, 0x0c, 0xe7, 0x59, 0xd2, 0xba, 0x5e, 0xb7, 0x5d, 0x2f, 0x82, 0xa0, 0x77, 0xc1, 0x4a, 0x0b, 0x77, 0xd1, 0xaa, 0x1c, 0x19, 0xfa, 0xaf, 0xbc, 0xb3, 0xa0, 0x96, 0x27, 0x9c, 0x32, 0x9d, 0x34, 0x23, 0xc9, 0x7f, 0xf9, 0x7a, 0x68, 0x46, 0xa7, 0x8b, 0x0e, 0x2a, 0x4c, 0xe4, 0xbe, 0x3a, 0xca, 0x56, 0x52, 0xa2, 0x6c, 0x22, 0x00, 0x67, 0xef, 0x7a, 0x7d, 0x70, 0x7b, 0x52, 0x4a, 0xcd, 0xcd, 0xe9, 0x3e, 0x5e, 0x81, 0xf0, 0xe2, 0x41, 0x08, 0x6f, 0x4a, 0x93, 0xf2, 0xbd, 0xf2, 0xe0, 0xfa, 0x6b, 0x98, 0xc5, 0xdc, 0xea, 0xc5, 0xc3, 0x07, 0x6a, 0x15, 0x0e, 0x5e, 0xe7, 0xf0, 0xe6, 0x48, 0xe7, 0x48, 0x2f, 0x3c, 0xc1, 0x12, 0xa5, 0xe3, 0xdc, 0x49, 0x0a, 0xa2, 0x5c, 0x14, 0x37, 0x29, 0xf0, 0x29, 0x9a, 0x0c, 0xeb, 0xf9, 0xd0, 0x6e, 0x13, 0xb4, 0x3f, 0xc3, 0x35, 0x28, 0x63, 0x76, 0x89, 0xa4, 0xf2, 0x8a, 0x47, 0x7b, 0x97, 0xef, 0xa7, 0x0e, 0x86, 0xe3, 0x89, 0xa4, 0xae, 0x7d, 0xa3, 0x8e, 0x0a, 0xee, 0x17, 0x99, 0x1c, 0x56, 0xba, 0xc7, 0xca, 0x32, 0xea, 0x9b, 0x23, 0xf0, 0x88, 0xe3, 0x1c, 0xd6, 0xb0, 0xc7, 0xad, 0x6f, 0x58, 0x03, 0xaa, 0xd6, 0x79, 0x33, 0xc2, 0x43, 0xbd, 0xae, 0x1b, 0xcb, 0x17, 0xac, 0x34, 0x35, 0xfc, 0xb3, 0x50, 0x16, 0xd5, 0x1b, 0xcf, 0x99, 0xd3, 0xea, 0xe0, 0x59, 0xc8, 0x1b, 0x4d, 0xad, 0xb0, 0xa2, 0x37, 0x88, 0xa7, 0x2a, 0x45, 0x4a, 0x3b, 0xd2, 0xcd, 0x81, 0x7e, 0x4d, 0x3e, 0x9d, 0x9d, 0xe6, 0xb1, 0xfc, 0x7b, 0x1e, 0xf3, 0x7b, 0x74, 0x0a, 0x3d, 0x66, 0x02, 0x99, 0xf7, 0xdb, 0x6d, 0x4d, 0x3f, 0x1f, 0x7f, 0x6e, 0xd4, 0x57, 0x62, 0x51, 0xd6, 0x62, 0xae, 0x28, 0x3e, 0xed, 0xc3, 0x8b, 0x8d, 0x0f, 0xb9, 0x1a, 0xe6, 0x79, 0xa7, 0x28, 0xb8, 0xf9, 0xb3, 0x39, 0x50, 0x55, 0x30, 0x59, 0xef, 0x17, 0xb5, 0x18, 0xff, 0xdc, 0xbc, 0xd0, 0x22, 0x6b, 0x79, 0x62, 0x70, 0x5e, 0xdc, 0x5c, 0x24, 0xa1, 0x65, 0xb5, 0x5b, 0x96, 0x1f, 0x1b, 0xe2, 0x3c, 0xd4, 0x15, 0xf4, 0xc8, 0x1f, 0xd7, 0x9e, 0x72, 0xc2, 0x0f, 0x9e, 0x00, 0x9a, 0xf8, 0x68, 0x70, 0x6e, 0x07, 0xac, 0xde, 0x61, 0x03, 0x7d, 0x09, 0xd0, 0x45, 0xae, 0x2e, 0x98, 0x7c, 0x8f, 0xc9, 0x9a, 0x3a, 0x47, 0xd2, 0x70, 0x80, 0xd2, 0x9d, 0x19, 0xd7, 0xf4, 0x26, 0x05, 0x17, 0x0c, 0x12, 0x0d, 0x3a, 0xd8, 0xf6, 0xeb, 0x21, 0xa4, 0xd9, 0x2a, 0x83, 0x00, 0x8b, 0x9d, 0x07, 0xf9, 0x44, 0xc2, 0x18, 0x9e, 0xf9, 0xb9, 0xa0, 0xa0, 0x2a, 0x4c, 0x77, 0x50, 0xc4, 0x25, 0x3f, 0x9d, 0xab, 0x35, 0x9d, 0x41, 0x1e, 0x79, 0x5c, 0xd5, 0x61, 0x01, 0x95, 0x01, 0x26, 0x7f, 0x57, 0xe3, 0xaa, 0xfd, 0x02, 0x21, 0x01, 0xeb, 0x38, 0xfa, 0xa7, 0x4c, 0x99, 0x26, 0x46, 0xdf, 0x8d, 0x34, 0xc2, 0xc5, 0x6a, 0xc8, 0xda, 0x90, 0x48, 0xdc, 0x48, 0x3b, 0x87, 0x0b, 0x1b, 0x4f, 0xf1, 0x5b, 0x2f, 0x1e, 0x1e, 0x12, 0xd6, 0x9e, 0x7d, 0x01, 0x1d, 0x10, 0xd4, 0x1d, 0x42, 0x30, 0x08, 0xf1, 0xa8, 0x9e, 0x5c, 0xdf, 0xfe, 0xdb, 0x6f, 0x62, 0x12, 0x5d, 0x70, 0x7d, 0xe7, 0x81, 0x7b, 0xa7, 0xb2, 0xed, 0xa4, 0x3c, 0x6e, 0x51, 0xf3, 0x08, 0x44, 0xf7, 0x76, 0xaa, 0x6b, 0xb2, 0x8b, 0xd8, 0xb7, 0x9d, 0x65, 0x2a, 0x3d, 0x4a, 0xeb, 0x08, 0xfc, 0xd6, 0xc6, 0x4e, 0x52, 0xbb, 0x43, 0xd1, 0x05, 0x5e, 0x76, 0x09, 0x98, 0x2e, 0x6d, 0xcb, 0xfa, 0x22, 0x41, 0x73, 0x84, 0x00, 0x6b, 0xab, 0xf0, 0x38, 0x90, 0x2e, 0x3e, 0xe7, 0x9e, 0x16, 0xee, 0x67, 0x51, 0xb5, 0xe2, 0x49, 0x1d, 0xb1, 0x19, 0xa9, 0x0f, 0x58, 0x13, 0xec, 0x43, 0xb4, 0x6b, 0x82, 0xaf, 0x1b, 0x9a, 0x17, 0xe0, 0xab, 0x0f, 0xfe, 0xf7, 0x03, 0xf8, 0xf3, 0xc8, 0x6f, 0x09, 0x1a, 0x7a, 0x72, 0x4e, 0xa7, 0x2f, 0x9e, 0x1f, 0x63, 0x91, 0x7c, 0xca, 0x37, 0x3b, 0x26, 0x2b, 0x08, 0x75, 0x76, 0x38, 0xbb, 0xec, 0x9a, 0xa0, 0x6f, 0x8d, 0x33, 0xd4, 0xf2, 0x36, 0x31, 0x9d, 0x40, 0xb1, 0xc7, 0xe5, 0xbb, 0x8e, 0x0a, 0x23, 0xa3, 0x74, 0x90, 0xe3, 0xb2, 0x25, 0x1e, 0xab, 0x07, 0x1f, 0x0c, 0x5a, 0xe3, 0x56, 0x7f, 0xf4, 0x9c, 0x1b, 0x55, 0x07, 0x6b, 0x4b, 0xab, 0xd6, 0x49, 0xdf, 0xaf, 0x62, 0xdf, 0x6b, 0x53, 0x14, 0x1e, 0xa5, 0xa2, 0x54, 0xcb, 0xe7, 0xce, 0x41, 0x0c, 0x37, 0xe0, 0x3a, 0x54, 0xe3, 0x2e, 0x4e, 0x9a, 0x64, 0x11, 0x36, 0x59, 0xc2, 0xda, 0xc3, 0x60, 0xdd, 0x57, 0xab, 0xa4, 0xa5, 0xbc, 0x11, 0x7a, 0xf1, 0x34, 0x65, 0x95, 0x75, 0xc8, 0x60, 0x77, 0x36, 0x73, 0x7d, 0x12, 0x9b, 0xd7, 0xa5, 0x7c, 0x28, 0xe5, 0x71, 0x67, 0x6d, 0xd3, 0x0f, 0x3c, 0x10, 0x37, 0xc3, 0xfd, 0x04, 0x11, 0x3b, 0xdd, 0x83, 0x3c, 0xcc, 0x58, 0x11, 0x01, 0x4f, 0xbc, 0xb7, 0x9c, 0x0d, 0x63, 0x4a, 0xc5, 0x87, 0xf9, 0x53, 0xd2, 0xb1, 0x95, 0x2e, 0x41, 0x8d, 0x8b, 0x02, 0x0b, 0x81, 0x1d, 0x5c, 0x39, 0x5b, 0xfd, 0xc6, 0x73, 0xc9, 0x6e, 0xed, 0xe2, 0xe3, 0x2d, 0x4e, 0xb3, 0xfb, 0x95, 0xe6, 0x9a, 0x7f, 0x2f, 0x64, 0xc1, 0x83, 0xb8, 0x55, 0xb1, 0x05, 0xcb, 0xaa, 0xdc, 0xaa, 0xed, 0xf7, 0x56, 0xd5, 0xdc, 0x3b, 0x5b, 0x5c, 0xa8, 0xd4, 0x2b, 0x4c, 0xf1, 0xbf, 0xe7, 0x37, 0x47, 0x28, 0x9c, 0x74, 0x54, 0x19, 0x9d, 0xe7, 0x64, 0x09, 0x35, 0xd0, 0x78, 0xdf, 0x8d, 0xcc, 0x9e, 0x9c, 0x19, 0xa5, 0xb6, 0xe2, 0x85, 0x0e, 0x7e, 0x1f, 0x3b, 0x69, 0x63, 0xbd, 0xda, 0x79, 0xd0, 0x9d, 0x67, 0x31, 0x6a, 0xf3, 0xcf, 0xdf, 0x4e, 0x55, 0x01, 0xe8, 0x22, 0xf1, 0x4a, 0x2a, 0x06, 0xb3, 0x3a, 0x82, 0x6c, 0xa8, 0xb3, 0x39, 0xb3, 0x98, 0x09, 0xf8, 0xde, 0x66, 0x39, 0xaf, 0xb1, 0x71, 0xf9, 0x01, 0xe3, 0x5f, 0x83, 0x8c, 0x42, 0xbb, 0x66, 0x5c, 0xcc, 0xaf, 0xce, 0x38, 0xad, 0x08, 0x99, 0xf2, 0x47, 0xc7, 0xf4, 0xe6, 0xeb, 0x15, 0x68, 0x7f, 0xf3, 0xc7, 0xe6, 0x3e, 0xcc, 0x2c, 0x74, 0xdc, 0xb7, 0x57, 0xfc, 0x2d, 0x70, 0x74, 0xa0, 0xf0, 0xf2, 0x97, 0x69, 0x31, 0x14, 0x96, 0x18, 0x6d, 0x23, 0xb1, 0xd6, 0x69, 0x8d, 0x53, 0xeb, 0x46, 0xde, 0xb3, 0xb4, 0x2b, 0x45, 0x1b, 0x2c, 0x48, 0x44, 0x22, 0x72, 0x0d, 0xc2, 0xa4, 0x9b, 0x86, 0x16, 0xc7, 0x9c, 0x34, 0x47, 0xc5, 0x97, 0xd0, 0x56, 0xd7, 0x54, 0x63, 0x5d, 0x64, 0xa0, 0xbb, 0x85, 0x46, 0x77, 0xe7, 0x05, 0x1c, 0x50, 0x90, 0x4d, 0x73, 0xac, 0x2c, 0x38, 0xb5, 0xb1, 0x36, 0x34, 0x63, 0x13, 0xa8, 0x40, 0x8d, 0x6b, 0xea, 0x99, 0x71, 0x11, 0x43, 0xf3, 0x4b, 0x96, 0x19, 0x6b, 0x28, 0xf3, 0x8b, 0xaa, 0x7c, 0x19, 0x36, 0xc5, 0x64, 0xce, 0x05, 0x43, 0x58, 0x27, 0x21, 0xaa, 0x3e, 0xb1, 0xed, 0x06, 0x41, 0x8a, 0x54, 0x8f, 0xfc, 0x49, 0xbe, 0x4b, 0xf6, 0x9c, 0x39, 0xc8, 0xaa, 0xbd, 0xa8, 0xba, 0x0b, 0x8a, 0x5c, 0x2b, 0xc7, 0x85, 0x56, 0x0e, 0x75, 0x86, 0x9e, 0x24, 0x5e, 0x62, 0xd7, 0x9f, 0xbc, 0xc0, 0x55, 0x52, 0xb9, 0xca, 0xe0, 0xa8, 0xa0, 0xa6, 0x27, 0xc4, 0x26, 0xf7, 0x60, 0x5e, 0x67, 0xe8, 0xd4, 0x1b, 0x76, 0x7c, 0x9c, 0x74, 0x79, 0x1a, 0xe2, 0x14, 0xc3, 0x6e, 0xe8, 0xe1, 0x62, 0xba, 0x65, 0x06, 0xba, 0x86, 0xa1, 0x45, 0x75, 0x26, 0x18, 0xcd, 0x1f, 0x8c, 0x6e, 0x10, 0x9d, 0x7e, 0x3a, 0x21, 0x29, 0x25, 0xcb, 0x4f, 0x74, 0xb5, 0xff, 0x35, 0x2b, 0xd4, 0xd8, 0x66, 0x0b, 0x48, 0x6c, 0x86, 0xd5, 0x8b, 0x08, 0x70, 0xad, 0xf3, 0xf6, 0x5d, 0x3c, 0x36, 0x41, 0xd5, 0x92, 0xee, 0xab, 0x3e, 0x5b, 0x30, 0x4e, 0xf3, 0xfe, 0x2d, 0x1b, 0xe2, 0x68, 0xf2, 0x95, 0x8c, 0xd0, 0xb2, 0x09, 0x47, 0xc5, 0x57, 0x1b, 0x33, 0xcc, 0x63, 0xbd, 0x96, 0x44, 0xdc, 0xe1, 0xff, 0x17, 0x6a, 0xa1, 0x49, 0x2c, 0xc4, 0xab, 0x93, 0xc6, 0x3b, 0x8d, 0x60, 0xe8, 0x57, 0x43, 0x58, 0xe4, 0x20, 0x41, 0x43, 0xa3, 0x07, 0xc9, 0xeb, 0x3d, 0xfa, 0xd1, 0x21, 0xef, 0x82, 0x9a, 0x09, 0xcb, 0xf0, 0x09, 0x1f, 0xad, 0xa1, 0x0d, 0x41, 0xdd, 0x8d, 0x9d, 0x63, 0xbb, 0xcf, 0xf4, 0xee, 0x9a, 0xbc, 0x5a, 0xf2, 0x58, 0xdf, 0xcd, 0x08, 0x9c, 0xf3, 0x48, 0xd9, 0x52, 0xc2, 0x7d, 0x3a, 0xd3, 0x7b, 0x1e, 0xce, 0xf4, 0xd4, 0x90, 0x36, 0x88, 0xf3, 0xff, 0xb1, 0x11, 0x1c, 0x80, 0xa5, 0x78, 0xaa, 0xe7, 0x32, 0x78, 0x53, 0xba, 0x29, 0x24, 0x2f, 0x20, 0x6a, 0x67, 0x36, 0x66, 0x0e, 0x4b, 0x16, 0xc7, 0xf2, 0xc1, 0x69, 0xe2, 0x45, 0x04, 0x73, 0xc9, 0x15, 0x50, 0x04, 0x0d, 0x25, 0x96, 0xf6, 0xc9, 0x23, 0xb5, 0x61, 0x6c, 0x4b, 0x64, 0x3a, 0x9f, 0xa9, 0x3a, 0x13, 0xc6, 0x7c, 0x03, 0xda, 0xee, 0x4a, 0x67, 0xbb, 0xf3, 0xd7, 0xc2, 0x01, 0xd2, 0xd4, 0x9c, 0x32, 0x88, 0x04, 0x9a, 0x9b, 0xb8, 0x0d, 0xa5, 0x95, 0xe6, 0xd8, 0x10, 0x41, 0x6f, 0xf7, 0x1a, 0x00, 0x85, 0xa2, 0xa9, 0x26, 0xfd, 0xc3, 0x2c, 0xe1, 0xe7, 0xdf, 0x7d, 0x63, 0xba, 0x0d, 0xc9, 0x2e, 0x28, 0x34, 0xff, 0x40, 0x03, 0x79, 0x00, 0xcb, 0xa4, 0x97, 0xce, 0xd7, 0x14, 0x08, 0x54, 0x4c, 0xaa, 0x9e, 0x51, 0x03, 0x82, 0xcf, 0xf6, 0xe2, 0xee, 0x05, 0x2f, 0xd3, 0x70, 0x2b, 0x71, 0x62, 0xf7, 0xbc, 0xa6, 0x38, 0x56, 0x0b, 0xdc, 0xd0, 0x60, 0x59, 0x60, 0x99, 0x17, 0x7f, 0x7a, 0x0d, 0x2c, 0xd0, 0x94, 0x05, 0x88, 0x2b, 0x40, 0x91, 0xb2, 0x83, 0xd9, 0xfa, 0xd8, 0x05, 0x62, 0xec, 0xd0, 0xbf, 0xb4, 0xa2, 0xf4, 0x3d, 0x34, 0xbe, 0x8d, 0xcd, 0x9c, 0xbe, 0xe8, 0x16, 0xac, 0x4e, 0x2f, 0x71, 0xd9, 0xab, 0x3f, 0x84, 0x87, 0xb7, 0xce, 0xd7, 0xf5, 0x54, 0x75, 0x34, 0xb0, 0x63, 0xb7, 0x50, 0x3c, 0xb5, 0x32, 0xed, 0x7e, 0x6a, 0xd7, 0x7a, 0x00, 0x00, 0x01, 0x09, 0x06, 0x4c, 0x64, 0xe2, 0x00, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x04, 0x81, 0x01, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x04, 0x81, 0x01, 0x00, 0x01, 0xbb, 0xbb, 0xbb, 0xbb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x04, 0x81, 0x01, 0x00, 0x09, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +constexpr std::array M2V_TINY_PACKETS_STREAM = { 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x0c, 0x83, 0xa9, 0x81, 0x80, 0xf0, 0x7f, 0xb9, 0xf3, 0x3b, 0xbd, 0xe7, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x00, 0x7a, 0x01, 0xe0, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x1a, 0x00, 0x80, 0x20, 0x90, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x4f, 0x00, 0x00, 0x01, 0xe0, 0x07, 0x5a, 0x81, 0xc1, 0x0d, 0x31, 0x00, 0x05, 0xbf, 0x21, 0x11, 0x00, 0x05, 0xa7, 0xab, 0x1e, 0x73, 0x3b, 0x00, 0x00, 0x01, 0x00, 0x35, 0xf9, 0x2e, 0x87, 0xf2, 0x56, 0x91, 0x4f, 0xcc, 0x26, 0x6b, 0x91, 0x91, 0xb1, 0x2f, 0x9c, 0xd6, 0xe6, 0x70, 0xa4, 0xe1, 0x20, 0xae, 0x5b, 0x09, 0x39, 0x8b, 0xc5, 0x59, 0xd8, 0x6a, 0xee, 0x7a, 0x50, 0x8e, 0x52, 0x41, 0x71, 0x40, 0x1f, 0x55, 0x19, 0x85, 0xa4, 0xd1, 0x7b, 0x75, 0x89, 0xdf, 0x58, 0x41, 0xba, 0x9b, 0xa2, 0x66, 0x0a, 0xcf, 0x53, 0xb2, 0xfe, 0x4c, 0x60, 0x09, 0x51, 0xf3, 0x12, 0x11, 0x11, 0xb6, 0x41, 0x3d, 0x71, 0x22, 0x23, 0xd6, 0xaa, 0x31, 0xb6, 0xf0, 0x8a, 0x86, 0xfb, 0x86, 0x89, 0x46, 0x7b, 0x0c, 0x82, 0x2f, 0xe0, 0x48, 0x71, 0xad, 0x88, 0x3a, 0xc9, 0xf9, 0x64, 0x55, 0x3f, 0x9b, 0x93, 0x74, 0x33, 0xc3, 0x72, 0x2a, 0x01, 0x60, 0x29, 0x67, 0xe1, 0xf0, 0xe7, 0x97, 0x2e, 0x54, 0x4c, 0xa3, 0x34, 0x42, 0xbf, 0x93, 0xdd, 0x13, 0xa9, 0x9e, 0xd8, 0xfd, 0xd1, 0xee, 0x1b, 0x0d, 0x5b, 0x82, 0xda, 0x5c, 0x1b, 0xc2, 0x4a, 0x61, 0x40, 0xd5, 0xd2, 0x56, 0x99, 0xc1, 0x8b, 0x0e, 0xd9, 0xe4, 0x16, 0xb7, 0xb7, 0x4d, 0x43, 0x6c, 0xc2, 0x08, 0x05, 0x81, 0x48, 0x63, 0xaa, 0xfd, 0xb0, 0xb8, 0x5e, 0xa5, 0x13, 0x52, 0x67, 0x89, 0x0b, 0x67, 0xa7, 0x06, 0xf0, 0x47, 0x44, 0x8d, 0x0c, 0x39, 0xa2, 0xcf, 0x70, 0xa5, 0xea, 0xf6, 0x73, 0x82, 0xdc, 0x1c, 0x19, 0x2f, 0xb2, 0x30, 0xcc, 0x1c, 0x3b, 0xe9, 0x38, 0x01, 0x83, 0x84, 0x3d, 0x80, 0xab, 0x5e, 0x32, 0x5c, 0xc5, 0xc3, 0xf1, 0xc2, 0xd7, 0x60, 0x77, 0x3b, 0x5d, 0x48, 0x04, 0x49, 0xeb, 0x78, 0xfd, 0xc0, 0xbf, 0x41, 0x0d, 0x67, 0x70, 0x0a, 0x47, 0x6d, 0x09, 0x4e, 0x2f, 0xb8, 0x31, 0xd6, 0x05, 0x2b, 0x3a, 0x72, 0xb8, 0x52, 0x36, 0xd4, 0x3e, 0x27, 0x6b, 0x48, 0x5d, 0xcc, 0xc5, 0x55, 0x0c, 0x7b, 0x20, 0x9b, 0xf8, 0x07, 0x81, 0x79, 0xe4, 0xa4, 0xaa, 0x3c, 0xdb, 0xd8, 0x8d, 0xf5, 0x77, 0xcf, 0x95, 0x31, 0xb7, 0x73, 0xc4, 0x29, 0x1b, 0xf2, 0x24, 0x34, 0x0c, 0xb0, 0x02, 0x85, 0xc5, 0xb5, 0xe9, 0x82, 0x31, 0x1e, 0x78, 0x3f, 0x96, 0x2b, 0x5a, 0xf2, 0xe2, 0xdf, 0x19, 0x58, 0xf8, 0x5b, 0x8a, 0x6c, 0x66, 0x5e, 0x0d, 0xf0, 0x45, 0x9b, 0xe1, 0x9c, 0x44, 0xcf, 0x3b, 0xf0, 0x0a, 0xbb, 0xf1, 0x09, 0x85, 0x81, 0xdf, 0xf9, 0xc8, 0xfa, 0x53, 0x6c, 0x87, 0x00, 0x30, 0xb0, 0x5b, 0xd3, 0x94, 0x62, 0x61, 0x03, 0x1e, 0x50, 0xdc, 0x94, 0x3c, 0x64, 0xd9, 0x34, 0x11, 0x8f, 0x21, 0xcb, 0xd5, 0x1b, 0xe1, 0xba, 0xc6, 0xd6, 0xca, 0x7e, 0x0f, 0xf8, 0xb2, 0xa1, 0x35, 0xc3, 0xd9, 0x30, 0xf0, 0x26, 0x6b, 0x07, 0x89, 0x02, 0xde, 0xc2, 0x12, 0xc4, 0x45, 0x20, 0x26, 0x72, 0xb5, 0x19, 0xf2, 0x74, 0x59, 0x07, 0xc2, 0x99, 0xcf, 0x95, 0x50, 0x38, 0xef, 0x5e, 0x8c, 0x68, 0x0f, 0x60, 0xa0, 0xa0, 0x66, 0xc1, 0x64, 0x54, 0x33, 0x81, 0x87, 0x49, 0xa6, 0x08, 0x21, 0xbc, 0xd4, 0xcb, 0x6d, 0xa6, 0x22, 0x59, 0xea, 0x9a, 0xee, 0x96, 0x1b, 0x22, 0x6d, 0x04, 0x9e, 0x8c, 0xfc, 0x43, 0x69, 0x8c, 0x5d, 0x3c, 0x49, 0x29, 0xa3, 0x9d, 0x01, 0xd3, 0xbf, 0x95, 0xad, 0xa4, 0xf1, 0xfd, 0x2e, 0x16, 0x99, 0x55, 0xdb, 0xc7, 0x22, 0x46, 0xb7, 0x01, 0x01, 0x96, 0xd8, 0x31, 0x05, 0xaf, 0xd4, 0x78, 0x7b, 0x38, 0x55, 0xf5, 0xdb, 0x59, 0x2b, 0x97, 0xf4, 0xa2, 0x79, 0x74, 0xe0, 0xbd, 0xdf, 0xff, 0x3b, 0x55, 0xb4, 0x9d, 0x4b, 0xe3, 0xb1, 0x73, 0x21, 0x4b, 0xab, 0x6c, 0xf1, 0x6c, 0x2f, 0xc8, 0x12, 0x28, 0x2c, 0xc2, 0x6d, 0x6b, 0xf2, 0x1c, 0x4f, 0x41, 0x38, 0x8b, 0xdd, 0x0f, 0xf0, 0x6c, 0xac, 0x67, 0x1a, 0x31, 0x2b, 0x1d, 0xda, 0x6b, 0xea, 0x8d, 0x8c, 0x65, 0xee, 0x39, 0x8c, 0xb2, 0x96, 0x35, 0xf2, 0x30, 0xce, 0xfe, 0x8a, 0x3f, 0x7e, 0xb6, 0xa1, 0x5d, 0x85, 0xea, 0x95, 0x3f, 0xb2, 0x4d, 0x33, 0x2c, 0x6b, 0x18, 0x46, 0x2e, 0x1c, 0xfb, 0xf4, 0x58, 0x8b, 0xc5, 0xbf, 0x44, 0xa0, 0x39, 0x53, 0x6e, 0x57, 0xaf, 0x69, 0x31, 0xd2, 0x7a, 0x6f, 0x6f, 0xdc, 0x39, 0xc5, 0x2f, 0x37, 0x7c, 0xae, 0xc8, 0x94, 0x6c, 0x4e, 0x58, 0x19, 0x68, 0x60, 0x98, 0xbd, 0xb7, 0x63, 0x5b, 0xed, 0xc5, 0x7b, 0x44, 0x44, 0x90, 0x49, 0x76, 0x42, 0x39, 0x61, 0x5d, 0x47, 0xdc, 0x3c, 0xc3, 0x4b, 0x1d, 0xb8, 0xd6, 0x17, 0x24, 0x8e, 0xd6, 0xea, 0xd9, 0x50, 0x88, 0xdb, 0xa6, 0xd4, 0xac, 0x5d, 0x1b, 0x1d, 0x0b, 0xb9, 0x28, 0x28, 0xe6, 0x68, 0xd4, 0x3a, 0xd6, 0x90, 0xa4, 0x79, 0x5a, 0x20, 0x0f, 0x07, 0xb9, 0x46, 0xc2, 0xe6, 0xeb, 0x3b, 0x8b, 0x4b, 0xa2, 0xa2, 0x21, 0x35, 0xbd, 0xf5, 0x34, 0x6e, 0xb0, 0xb9, 0x70, 0x4a, 0xae, 0x80, 0x60, 0xc0, 0x9c, 0xe6, 0x59, 0xbf, 0x24, 0x0d, 0xe2, 0xd2, 0x69, 0x59, 0x39, 0x7b, 0x2d, 0x5b, 0xeb, 0xd8, 0x72, 0x33, 0xa8, 0x6a, 0xea, 0xdd, 0xbb, 0x29, 0xb7, 0x2e, 0xd7, 0x35, 0x4d, 0x6d, 0x25, 0xc0, 0x86, 0xda, 0xb7, 0x16, 0x28, 0x8d, 0xdd, 0xd5, 0x73, 0x6b, 0xf1, 0xb6, 0x87, 0x3e, 0x9b, 0x85, 0x9a, 0x11, 0xb0, 0x1e, 0x62, 0x63, 0x10, 0x8c, 0x34, 0xe5, 0x3f, 0xb3, 0x99, 0xb4, 0x9f, 0x07, 0x80, 0x64, 0x6c, 0x49, 0x3d, 0x3d, 0xf8, 0x50, 0xf6, 0x7b, 0xc6, 0x43, 0x36, 0x7c, 0x74, 0xe3, 0xcd, 0x25, 0xa3, 0xbd, 0x29, 0xf8, 0x46, 0x59, 0xd1, 0x8f, 0xfe, 0xd2, 0xb9, 0x7f, 0x80, 0x69, 0x87, 0xdc, 0x1c, 0xe9, 0x13, 0xe2, 0xe3, 0x07, 0xa5, 0x6d, 0x09, 0x12, 0xce, 0x50, 0x7e, 0x87, 0xd6, 0xba, 0xde, 0x79, 0x16, 0x2f, 0x25, 0xd5, 0xcd, 0xc2, 0xde, 0xe6, 0x2a, 0x9b, 0xac, 0xbd, 0xb0, 0x03, 0x5e, 0x48, 0x2a, 0x62, 0xfd, 0x43, 0xca, 0x07, 0x7d, 0x58, 0x35, 0x9a, 0xf9, 0x0a, 0x90, 0x82, 0xb1, 0x48, 0xd4, 0xc2, 0x28, 0xcb, 0xf8, 0xf6, 0x1d, 0x84, 0xbc, 0x7c, 0x3b, 0xdd, 0x20, 0xf9, 0xbc, 0x7d, 0xd7, 0xc8, 0x5d, 0xce, 0x3e, 0xf6, 0x5b, 0x8d, 0xa4, 0xdd, 0x57, 0x08, 0xed, 0x90, 0x62, 0xe4, 0xe3, 0x8d, 0x7f, 0x88, 0xba, 0x8a, 0x6d, 0x88, 0x94, 0x35, 0x7a, 0xa9, 0x13, 0x45, 0xb6, 0x65, 0x44, 0x41, 0xcd, 0xfa, 0x73, 0xc7, 0x4e, 0x6e, 0xaa, 0x43, 0x40, 0x22, 0xf1, 0x5c, 0x29, 0xc8, 0x95, 0x92, 0x0e, 0xdf, 0x0c, 0xbe, 0xf4, 0x0e, 0x2a, 0x81, 0xea, 0x04, 0xd7, 0xd1, 0xbe, 0x9f, 0x6e, 0x21, 0xc9, 0x99, 0x6d, 0xef, 0x78, 0xfb, 0x2a, 0x95, 0x8c, 0xff, 0xb5, 0xc3, 0x35, 0x38, 0x13, 0xf4, 0x6d, 0x25, 0x7b, 0xb7, 0x4c, 0x7b, 0x4a, 0xbe, 0x3f, 0xd4, 0xcf, 0xeb, 0x3d, 0x8e, 0x27, 0xe0, 0x84, 0x05, 0xc2, 0xc4, 0x6b, 0x79, 0x5b, 0x45, 0x4c, 0x46, 0x67, 0x05, 0xa6, 0x38, 0x58, 0xfd, 0xe6, 0x35, 0x29, 0x7f, 0x84, 0x75, 0x14, 0xed, 0x62, 0x05, 0x72, 0x46, 0x8d, 0x5a, 0x13, 0x16, 0xe3, 0x18, 0x9f, 0x82, 0x30, 0x71, 0xc5, 0x65, 0xc1, 0xa4, 0x47, 0xc7, 0x91, 0x92, 0x33, 0x19, 0x79, 0x6c, 0xcd, 0x03, 0x1e, 0xe5, 0xfe, 0xb4, 0x6f, 0x85, 0x4c, 0xf8, 0xfd, 0xee, 0xad, 0x84, 0x80, 0x33, 0xc4, 0x48, 0x44, 0xae, 0x48, 0xae, 0x63, 0xcb, 0xa9, 0x0f, 0xff, 0xd4, 0x47, 0xd9, 0xdb, 0xac, 0xb0, 0x14, 0x0f, 0xfb, 0xcf, 0x5d, 0xb8, 0x48, 0xfa, 0x7a, 0xd1, 0xf9, 0x41, 0x0b, 0xa8, 0x3b, 0x85, 0x19, 0x95, 0x41, 0x16, 0x7a, 0xdc, 0x70, 0xf7, 0x4c, 0xed, 0x4e, 0x0b, 0xf1, 0x72, 0x5c, 0xb0, 0x67, 0xc2, 0x28, 0xa4, 0xd6, 0xc0, 0x44, 0x2f, 0xac, 0x3f, 0xf0, 0xf1, 0xb3, 0x5d, 0x96, 0xc9, 0xdc, 0x89, 0x7e, 0xb5, 0xcb, 0x0a, 0x4a, 0xae, 0x4c, 0x4d, 0x17, 0xcc, 0x3b, 0x5b, 0x65, 0x3f, 0x95, 0x15, 0x24, 0xec, 0xaf, 0x40, 0x75, 0xb3, 0xd0, 0x72, 0x09, 0xb2, 0xa6, 0x55, 0x30, 0x0c, 0x5d, 0xf7, 0xff, 0x00, 0x43, 0xff, 0x19, 0x5e, 0x44, 0x04, 0x07, 0xa8, 0xb3, 0x64, 0x36, 0x63, 0x1d, 0x59, 0xe9, 0x6d, 0x20, 0x26, 0xd9, 0x61, 0x8b, 0x8a, 0x40, 0x4e, 0x33, 0xf9, 0x7b, 0x5f, 0x4b, 0x2c, 0x9f, 0x25, 0x2a, 0x04, 0x9c, 0xad, 0xcd, 0xea, 0xbd, 0x93, 0x7a, 0x11, 0xbf, 0xb5, 0x5e, 0x56, 0xb5, 0x3f, 0x01, 0x90, 0x74, 0x26, 0xe8, 0x99, 0x55, 0x62, 0xcd, 0x66, 0x69, 0x64, 0x39, 0xe7, 0x80, 0xa6, 0x6d, 0x92, 0x98, 0x52, 0xe2, 0xcc, 0x9a, 0x54, 0xd5, 0x9b, 0x78, 0x64, 0x9e, 0x45, 0x0b, 0xcd, 0xd1, 0xd5, 0x4c, 0x06, 0x55, 0xa7, 0xcb, 0x5f, 0x0a, 0x6f, 0x73, 0x54, 0x9e, 0x5d, 0x05, 0x5a, 0x9a, 0x58, 0xd6, 0x1b, 0xe3, 0x6d, 0xc3, 0x86, 0x2b, 0xec, 0x5a, 0x30, 0x07, 0xd4, 0xb1, 0xd9, 0xb0, 0x7c, 0x6c, 0x19, 0xa4, 0xaf, 0xe9, 0x8a, 0xa6, 0x99, 0x95, 0xfb, 0xd6, 0x36, 0xd6, 0x6b, 0xe6, 0x38, 0x24, 0xe9, 0x96, 0x80, 0x21, 0x99, 0x0b, 0xa5, 0xe4, 0x71, 0xa6, 0x25, 0xb1, 0x77, 0x66, 0x43, 0xe4, 0x87, 0x0c, 0xa0, 0xbb, 0xfd, 0x7e, 0x1d, 0x4e, 0xb9, 0x20, 0x8d, 0xe2, 0x58, 0x27, 0x49, 0x52, 0xb1, 0x22, 0xb0, 0x63, 0xd0, 0x24, 0x18, 0x16, 0x10, 0x6b, 0xcf, 0x5b, 0x0f, 0x5b, 0x19, 0xc5, 0x92, 0x27, 0x5d, 0x11, 0xa6, 0x96, 0xe9, 0xa3, 0x80, 0x9e, 0xf3, 0x57, 0xf2, 0xdb, 0xd5, 0x35, 0x7a, 0x13, 0x98, 0xf9, 0x43, 0x4c, 0x4d, 0x77, 0x8b, 0x2c, 0xdb, 0x41, 0x5d, 0x9d, 0x23, 0x28, 0x8b, 0xf2, 0xbd, 0x7d, 0x45, 0x14, 0x9f, 0x1c, 0xda, 0x59, 0x6d, 0xaa, 0x60, 0x20, 0x5c, 0xa6, 0x64, 0x59, 0xcb, 0x1a, 0xdc, 0x7b, 0x01, 0x12, 0xf3, 0xa3, 0xc8, 0x38, 0x72, 0xde, 0xbb, 0x27, 0xd9, 0xd1, 0x8c, 0x58, 0x71, 0x43, 0x94, 0xc4, 0xe2, 0x3b, 0x71, 0x94, 0x1d, 0xba, 0x90, 0x83, 0x9d, 0x4a, 0xcd, 0xbe, 0x5b, 0xce, 0xa2, 0x74, 0xee, 0x6c, 0x87, 0x5c, 0xb1, 0x74, 0x6c, 0xe2, 0xf6, 0x8a, 0x87, 0xbd, 0x91, 0x92, 0xd2, 0x2c, 0x48, 0x13, 0xed, 0x12, 0xf6, 0x12, 0x57, 0xac, 0x6b, 0x9d, 0x17, 0xa3, 0x54, 0x85, 0x54, 0xae, 0xb7, 0x09, 0x7f, 0x0c, 0xd5, 0x58, 0xf8, 0x7a, 0x73, 0x45, 0x64, 0x8b, 0xe4, 0x93, 0x16, 0x67, 0x4f, 0x95, 0x40, 0x63, 0x0e, 0x32, 0xcc, 0x06, 0x27, 0x6d, 0x16, 0x4b, 0x2e, 0x06, 0xef, 0x58, 0x1b, 0xdf, 0x8a, 0xe8, 0xe8, 0x28, 0x52, 0x18, 0xf2, 0x93, 0xc7, 0x66, 0x7b, 0xfd, 0xd3, 0x0d, 0xd0, 0x59, 0x3e, 0x0d, 0xdc, 0xcb, 0x3d, 0x79, 0x3e, 0x3d, 0x2d, 0xfa, 0x24, 0xd9, 0xfe, 0x8b, 0x7c, 0x36, 0xf6, 0xd9, 0x4b, 0x26, 0xa4, 0xe5, 0x29, 0x65, 0x4d, 0xb4, 0x3c, 0xac, 0x2d, 0x3b, 0x37, 0xd8, 0x30, 0xd7, 0x2a, 0x30, 0x2e, 0xf4, 0x30, 0xee, 0xaf, 0xbb, 0x45, 0xaa, 0xc2, 0xe4, 0xd0, 0x3e, 0x85, 0x08, 0xb3, 0x38, 0x49, 0x12, 0xe3, 0x11, 0x85, 0xa3, 0xdf, 0x9c, 0xfe, 0x91, 0x82, 0x73, 0xd2, 0xcf, 0x16, 0x59, 0x54, 0x67, 0x93, 0xcb, 0xe5, 0x5b, 0x75, 0x4b, 0x2c, 0x86, 0xa0, 0x05, 0x6d, 0xe4, 0x27, 0xe7, 0xd3, 0xd0, 0x00, 0x52, 0xf2, 0x21, 0xf2, 0xf3, 0xd4, 0x32, 0x47, 0x6d, 0x53, 0x44, 0x12, 0xe1, 0x9b, 0xc7, 0x0f, 0x7f, 0x0e, 0x6c, 0x6c, 0xb0, 0xe6, 0x18, 0x0b, 0x83, 0x58, 0x1f, 0x05, 0x61, 0x06, 0x58, 0x72, 0x45, 0x0a, 0xe1, 0xd6, 0xf5, 0xf1, 0xc6, 0xad, 0xed, 0x58, 0xcb, 0xe5, 0x09, 0x21, 0x0d, 0x60, 0x1a, 0x59, 0x42, 0xb3, 0xf2, 0x4b, 0xc2, 0xc3, 0x90, 0x65, 0xb1, 0xfc, 0x77, 0xdb, 0xe3, 0x40, 0x6d, 0x3a, 0x5b, 0xc1, 0x0e, 0x49, 0x79, 0x6f, 0xfe, 0xf9, 0x3d, 0xa9, 0xb3, 0x38, 0x36, 0x59, 0x11, 0xec, 0xf7, 0xac, 0x4e, 0x6a, 0x32, 0x0c, 0xe8, 0x25, 0xd2, 0x11, 0xa0, 0x7e, 0xb2, 0x84, 0xb1, 0xdf, 0xcb, 0xbd, 0xcc, 0x87, 0xfc, 0xde, 0x8f, 0xc1, 0xb6, 0xcd, 0x69, 0x68, 0x43, 0xdd, 0x3c, 0xe1, 0x6a, 0x89, 0x24, 0x07, 0x9c, 0xc2, 0x2f, 0x9e, 0x03, 0x9c, 0xf5, 0x51, 0x06, 0x6f, 0x59, 0x4e, 0x30, 0xa5, 0xe3, 0x09, 0x82, 0xde, 0x74, 0xb2, 0x96, 0x13, 0x55, 0x6a, 0x38, 0xe6, 0xd6, 0x44, 0x3a, 0x52, 0xf9, 0x99, 0xb4, 0x51, 0xe8, 0x4b, 0x04, 0x4a, 0x34, 0xe6, 0x27, 0x41, 0x16, 0xcd, 0x4e, 0x2d, 0x28, 0xdf, 0xc3, 0xe6, 0x63, 0x3f, 0x83, 0x91, 0x47, 0x2d, 0x20, 0x80, 0x81, 0x16, 0xcf, 0xe1, 0x76, 0x4c, 0xb5, 0xbc, 0x7d, 0x1a, 0xdd, 0x1b, 0xbf, 0x08, 0x60, 0x53, 0xf8, 0x97, 0xab, 0xd8, 0x98, 0xcf, 0xfb, 0x02, 0xf9, 0x50, 0x64, 0xb1, 0xb4, 0xd5, 0x06, 0xcd, 0x40, 0x4c, 0x50, 0xe7, 0x67, 0x00, 0x5d, 0x99, 0x3a, 0x6d, 0xd9, 0x62, 0x9a, 0xb3, 0x00, 0x10, 0x76, 0xdc, 0x94, 0x01, 0x4f, 0x54, 0xeb, 0xd2, 0xb3, 0x42, 0x65, 0x32, 0xb1, 0xb6, 0xfc, 0x00, 0x7c, 0xd0, 0xac, 0xe6, 0xbd, 0x49, 0xed, 0x11, 0x53, 0x19, 0x85, 0xca, 0x71, 0x17, 0x59, 0xf5, 0x6b, 0xbe, 0x18, 0xd4, 0x92, 0x9a, 0xd5, 0x89, 0xf6, 0xe4, 0xf9, 0x27, 0xfd, 0x5d, 0x17, 0x64, 0x01, 0x7e, 0x95, 0x36, 0x8e, 0x6d, 0x2c, 0xe3, 0xdb, 0x6a, 0xb4, 0x4d, 0x91, 0x98, 0xc4, 0x96, 0x14, 0x55, 0x0a, 0x54, 0xc6, 0x83, 0x83, 0xf1, 0x09, 0x7a, 0xd2, 0xf5, 0xf5, 0x88, 0x6f, 0x54, 0xff, 0x28, 0x7e, 0x03, 0x11, 0x69, 0x64, 0x5f, 0xcb, 0x1c, 0x7d, 0x3c, 0xeb, 0xd0, 0x99, 0x99, 0x13, 0xac, 0x02, 0x55, 0x00, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x04, 0x81, 0x01, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x04, 0x81, 0x01, 0x00, 0x01, 0xbb, 0xbb, 0xbb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x04, 0x00, 0xf5, 0xb1, 0x07, 0x53, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x04, 0x81, 0x01, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + +constexpr std::array AVC_FLUSH_EXPECTED_AU_SHA1 = { 0xe6, 0xf9, 0x41, 0x5f, 0x85, 0x80, 0x14, 0x9d, 0xf1, 0x24, 0x8a, 0xf5, 0x4d, 0x4b, 0x9f, 0x22, 0xd6, 0x60, 0x46, 0x0d }; From bd7d5faa9f175f9728c873cb74934d04b2d30690 Mon Sep 17 00:00:00 2001 From: capriots <29807355+capriots@users.noreply.github.com> Date: Thu, 10 Jul 2025 19:39:49 +0200 Subject: [PATCH 112/175] cellDmuxPamf implementation part 2: PPU thread --- rpcs3/Emu/Cell/Modules/cellDmux.cpp | 42 +- rpcs3/Emu/Cell/Modules/cellDmux.h | 168 +-- rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp | 1663 ++++++++++++++++++++++- rpcs3/Emu/Cell/Modules/cellDmuxPamf.h | 374 ++++- rpcs3/Emu/Cell/lv2/sys_prx.cpp | 2 +- 5 files changed, 2040 insertions(+), 209 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/cellDmux.cpp b/rpcs3/Emu/Cell/Modules/cellDmux.cpp index d7f6f84f3f..fb1f32837d 100644 --- a/rpcs3/Emu/Cell/Modules/cellDmux.cpp +++ b/rpcs3/Emu/Cell/Modules/cellDmux.cpp @@ -169,18 +169,18 @@ public: static const u32 id_count = 1023; SAVESTATE_INIT_POS(34); - ElementaryStream(Demuxer* dmux, u32 addr, u32 size, u32 fidMajor, u32 fidMinor, u32 sup1, u32 sup2, vm::ptr cbFunc, u32 cbArg, u32 spec); + ElementaryStream(Demuxer* dmux, vm::ptr addr, u32 size, u32 fidMajor, u32 fidMinor, u32 sup1, u32 sup2, vm::ptr cbFunc, vm::ptr cbArg, u32 spec); Demuxer* dmux; const u32 id = idm::last_id(); - const u32 memAddr; + const vm::ptr memAddr; const u32 memSize; const u32 fidMajor; const u32 fidMinor; const u32 sup1; const u32 sup2; const vm::ptr cbFunc; - const u32 cbArg; + const vm::ptr cbArg; const u32 spec; //addr std::vector raw_data; // demultiplexed data stream (managed by demuxer thread) @@ -208,13 +208,13 @@ public: const u32 memAddr; const u32 memSize; const vm::ptr cbFunc; - const u32 cbArg; + const vm::ptr cbArg; volatile bool is_finished = false; volatile bool is_closed = false; atomic_t is_running = false; atomic_t is_working = false; - Demuxer(u32 addr, u32 size, vm::ptr func, u32 arg) + Demuxer(u32 addr, u32 size, vm::ptr func, vm::ptr arg) : ppu_thread({}, "", 0) , memAddr(addr) , memSize(size) @@ -755,11 +755,11 @@ PesHeader::PesHeader(DemuxerStream& stream) is_ok = true; } -ElementaryStream::ElementaryStream(Demuxer* dmux, u32 addr, u32 size, u32 fidMajor, u32 fidMinor, u32 sup1, u32 sup2, vm::ptr cbFunc, u32 cbArg, u32 spec) - : put(utils::align(addr, 128)) +ElementaryStream::ElementaryStream(Demuxer* dmux, vm::ptr addr, u32 size, u32 fidMajor, u32 fidMinor, u32 sup1, u32 sup2, vm::ptr cbFunc, vm::ptr cbArg, u32 spec) + : put(utils::align(addr.addr(), 128)) , dmux(dmux) - , memAddr(utils::align(addr, 128)) - , memSize(size - (addr - memAddr)) + , memAddr(vm::ptr::make(utils::align(addr.addr(), 128))) + , memSize(size - (addr.addr() - memAddr.addr())) , fidMajor(fidMajor) , fidMinor(fidMinor) , sup1(sup1) @@ -788,9 +788,9 @@ bool ElementaryStream::is_full(u32 space) { return first - put < space + 128; } - else if (put + space + 128 > memAddr + memSize) + else if (put + space + 128 > memAddr.addr() + memSize) { - return first - memAddr < space + 128; + return first - memAddr.addr() < space + 128; } else { @@ -816,35 +816,35 @@ void ElementaryStream::push_au(u32 size, u64 dts, u64 pts, u64 userdata, bool ra std::lock_guard lock(m_mutex); ensure(!is_full(size)); - if (put + size + 128 > memAddr + memSize) + if (put + size + 128 > memAddr.addr() + memSize) { - put = memAddr; + put = memAddr.addr(); } std::memcpy(vm::base(put + 128), raw_data.data(), size); raw_data.erase(raw_data.begin(), raw_data.begin() + size); auto info = vm::ptr::make(put); - info->auAddr = put + 128; + info->auAddr.set(put + 128); info->auSize = size; info->dts.lower = static_cast(dts); info->dts.upper = static_cast(dts >> 32); info->pts.lower = static_cast(pts); info->pts.upper = static_cast(pts >> 32); info->isRap = rap; - info->reserved = 0; + info->auMaxSize = 0; info->userData = userdata; auto spec = vm::ptr::make(put + u32{sizeof(CellDmuxAuInfoEx)}); *spec = specific; auto inf = vm::ptr::make(put + 64); - inf->auAddr = put + 128; + inf->auAddr.set(put + 128); inf->auSize = size; - inf->dtsLower = static_cast(dts); - inf->dtsUpper = static_cast(dts >> 32); - inf->ptsLower = static_cast(pts); - inf->ptsUpper = static_cast(pts >> 32); + inf->dts.lower = static_cast(dts); + inf->dts.upper = static_cast(dts >> 32); + inf->pts.lower = static_cast(pts); + inf->pts.upper = static_cast(pts >> 32); inf->auMaxSize = 0; // ????? inf->userData = userdata; @@ -927,7 +927,7 @@ bool ElementaryStream::peek(u32& out_data, bool no_ex, u32& out_spec, bool updat void ElementaryStream::reset() { std::lock_guard lock(m_mutex); - put = memAddr; + put = memAddr.addr(); entries.clear(); put_count = 0; got_count = 0; diff --git a/rpcs3/Emu/Cell/Modules/cellDmux.h b/rpcs3/Emu/Cell/Modules/cellDmux.h index 7c31bbf105..dc17cb3314 100644 --- a/rpcs3/Emu/Cell/Modules/cellDmux.h +++ b/rpcs3/Emu/Cell/Modules/cellDmux.h @@ -33,118 +33,6 @@ enum CellDmuxEsMsgType : s32 CELL_DMUX_ES_MSG_TYPE_FLUSH_DONE = 1, }; -enum CellDmuxPamfM2vLevel : s32 -{ - CELL_DMUX_PAMF_M2V_MP_LL = 0, - CELL_DMUX_PAMF_M2V_MP_ML, - CELL_DMUX_PAMF_M2V_MP_H14, - CELL_DMUX_PAMF_M2V_MP_HL, -}; - -enum CellDmuxPamfAvcLevel : s32 -{ - CELL_DMUX_PAMF_AVC_LEVEL_2P1 = 21, - CELL_DMUX_PAMF_AVC_LEVEL_3P0 = 30, - CELL_DMUX_PAMF_AVC_LEVEL_3P1 = 31, - CELL_DMUX_PAMF_AVC_LEVEL_3P2 = 32, - CELL_DMUX_PAMF_AVC_LEVEL_4P1 = 41, - CELL_DMUX_PAMF_AVC_LEVEL_4P2 = 42, -}; - -struct CellDmuxPamfAuSpecificInfoM2v -{ - be_t reserved1; -}; - -struct CellDmuxPamfAuSpecificInfoAvc -{ - be_t reserved1; -}; - -struct CellDmuxPamfAuSpecificInfoLpcm -{ - u8 channelAssignmentInfo; - u8 samplingFreqInfo; - u8 bitsPerSample; -}; - -struct CellDmuxPamfAuSpecificInfoAc3 -{ - be_t reserved1; -}; - -struct CellDmuxPamfAuSpecificInfoAtrac3plus -{ - be_t reserved1; -}; - -struct CellDmuxPamfAuSpecificInfoUserData -{ - be_t reserved1; -}; - -struct CellDmuxPamfEsSpecificInfoM2v -{ - be_t profileLevel; -}; - -struct CellDmuxPamfEsSpecificInfoAvc -{ - be_t level; -}; - -struct CellDmuxPamfEsSpecificInfoLpcm -{ - be_t samplingFreq; - be_t numOfChannels; - be_t bitsPerSample; -}; - -struct CellDmuxPamfEsSpecificInfoAc3 -{ - be_t reserved1; -}; - -struct CellDmuxPamfEsSpecificInfoAtrac3plus -{ - be_t reserved1; -}; - -struct CellDmuxPamfEsSpecificInfoUserData -{ - be_t reserved1; -}; - -enum CellDmuxPamfSamplingFrequency : s32 -{ - CELL_DMUX_PAMF_FS_48K = 48000, -}; - -enum CellDmuxPamfBitsPerSample : s32 -{ - CELL_DMUX_PAMF_BITS_PER_SAMPLE_16 = 16, - CELL_DMUX_PAMF_BITS_PER_SAMPLE_24 = 24, -}; - -enum CellDmuxPamfLpcmChannelAssignmentInfo : s32 -{ - CELL_DMUX_PAMF_LPCM_CH_M1 = 1, - CELL_DMUX_PAMF_LPCM_CH_LR = 3, - CELL_DMUX_PAMF_LPCM_CH_LRCLSRSLFE = 9, - CELL_DMUX_PAMF_LPCM_CH_LRCLSCS1CS2RSLFE = 11, -}; - -enum CellDmuxPamfLpcmFs : s32 -{ - CELL_DMUX_PAMF_LPCM_FS_48K = 1, -}; - -enum CellDmuxPamfLpcmBitsPerSamples : s32 -{ - CELL_DMUX_PAMF_LPCM_BITS_PER_SAMPLE_16 = 1, - CELL_DMUX_PAMF_LPCM_BITS_PER_SAMPLE_24 = 3, -}; - struct CellDmuxMsg { be_t msgType; // CellDmuxMsgType @@ -163,12 +51,6 @@ struct CellDmuxType be_t reserved[2]; }; -struct CellDmuxPamfSpecificInfo -{ - be_t thisSize; - b8 programEndCodeCb; -}; - struct CellDmuxType2 { be_t streamType; // CellDmuxStreamType @@ -177,7 +59,7 @@ struct CellDmuxType2 struct CellDmuxResource { - be_t memAddr; + vm::bptr memAddr; be_t memSize; be_t ppuThreadPriority; be_t ppuThreadStackSize; @@ -187,7 +69,7 @@ struct CellDmuxResource struct CellDmuxResourceEx { - be_t memAddr; + vm::bptr memAddr; be_t memSize; be_t ppuThreadPriority; be_t ppuThreadStackSize; @@ -227,16 +109,16 @@ struct CellDmuxResource2 be_t shit[4]; }; -using CellDmuxCbMsg = u32(u32 demuxerHandle, vm::ptr demuxerMsg, u32 cbArg); +using CellDmuxCbMsg = u32(u32 demuxerHandle, vm::cptr demuxerMsg, vm::ptr cbArg); -using CellDmuxCbEsMsg = u32(u32 demuxerHandle, u32 esHandle, vm::ptr esMsg, u32 cbArg); +using CellDmuxCbEsMsg = u32(u32 demuxerHandle, u32 esHandle, vm::cptr esMsg, vm::ptr cbArg); // Used for internal callbacks as well template struct DmuxCb { vm::bptr cbFunc; - be_t cbArg; + vm::bptr cbArg; }; using CellDmuxCb = DmuxCb; @@ -250,42 +132,50 @@ struct CellDmuxAttr be_t demuxerVerLower; }; +struct CellDmuxPamfAttr +{ + be_t maxEnabledEsNum; + be_t version; + be_t memSize; +}; + struct CellDmuxEsAttr { be_t memSize; }; +struct CellDmuxPamfEsAttr +{ + be_t auQueueMaxSize; + be_t memSize; + be_t specificInfoSize; +}; + struct CellDmuxEsResource { - be_t memAddr; + vm::bptr memAddr; be_t memSize; }; struct CellDmuxAuInfo { - be_t auAddr; + vm::bptr auAddr; be_t auSize; be_t auMaxSize; - be_t userData; - be_t ptsUpper; - be_t ptsLower; - be_t dtsUpper; - be_t dtsLower; -}; - -struct CellDmuxAuInfoEx -{ - be_t auAddr; - be_t auSize; - be_t reserved; b8 isRap; be_t userData; CellCodecTimeStamp pts; CellCodecTimeStamp dts; }; -struct CellDmuxPamfAttr; -struct CellDmuxPamfEsAttr; +using CellDmuxAuInfoEx = CellDmuxAuInfo; + +struct DmuxAuInfo +{ + CellDmuxAuInfo info; + vm::bptr specific_info; + be_t specific_info_size; +}; using DmuxNotifyDemuxDone = error_code(vm::ptr, u32, vm::ptr); using DmuxNotifyFatalErr = error_code(vm::ptr, u32, vm::ptr); diff --git a/rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp b/rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp index 7c0fd8ec39..cc2fd6af42 100644 --- a/rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp +++ b/rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp @@ -1,6 +1,11 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" +#include "Emu/Cell/lv2/sys_cond.h" +#include "Emu/Cell/lv2/sys_mutex.h" +#include "Emu/Cell/lv2/sys_ppu_thread.h" #include "Emu/Cell/lv2/sys_sync.h" +#include "sysPrxForUser.h" +#include "util/asm.hpp" #include "cellDmuxPamf.h" #include @@ -10,6 +15,24 @@ vm::gvar g_cell_dmux_core_ops_raw_es; LOG_CHANNEL(cellDmuxPamf) +template <> +void fmt_class_string::format(std::string& out, u64 arg) +{ + format_enum(out, arg, [](CellDmuxPamfError value) + { + switch (value) + { + STR_CASE(CELL_DMUX_PAMF_ERROR_BUSY); + STR_CASE(CELL_DMUX_PAMF_ERROR_ARG); + STR_CASE(CELL_DMUX_PAMF_ERROR_UNKNOWN_STREAM); + STR_CASE(CELL_DMUX_PAMF_ERROR_NO_MEMORY); + STR_CASE(CELL_DMUX_PAMF_ERROR_FATAL); + } + + return unknown; + }); +} + inline std::pair dmuxPamfStreamIdToTypeChannel(u16 stream_id, u16 private_stream_id) { if ((stream_id & 0xf0) == 0xe0) @@ -1121,109 +1144,1659 @@ void dmux_pamf_spu_context::save(utils::serial& ar) // PPU thread +template +void DmuxPamfContext::send_spu_command_and_wait(ppu_thread& ppu, bool waiting_for_spu_state, auto&&... cmd_params) +{ + if (!waiting_for_spu_state) + { + // The caller is supposed to own the mutex until the SPU thread has consumed the command, so the queue should always be empty here + ensure(cmd_queue.emplace(type, std::forward(cmd_params)...), "The command queue wasn't empty"); + } + + lv2_obj::sleep(ppu); + + // Block until the SPU thread has consumed the command + cmd_result_queue.wait(); + + if (ppu.check_state()) + { + ppu.state += cpu_flag::again; + return; + } + + be_t result{}; + ensure(cmd_result_queue.pop(result), "The result queue was empty"); + ensure(result == static_cast(type) + 1, "The HLE SPU thread sent an invalid result"); +} + +DmuxPamfElementaryStream* DmuxPamfContext::find_es(u16 stream_id, u16 private_stream_id) +{ + const auto it = dmuxPamfStreamIdToTypeChannel(stream_id, private_stream_id).first == DMUX_PAMF_STREAM_TYPE_INDEX_VIDEO + ? std::ranges::find_if(elementary_streams | std::views::reverse, [&](const auto& es){ return es && es->stream_id == stream_id; }) + : std::ranges::find_if(elementary_streams | std::views::reverse, [&](const auto& es){ return es && es->stream_id == stream_id && es->private_stream_id == private_stream_id; }); + + return it != std::ranges::rend(elementary_streams) ? it->get_ptr() : nullptr; +} + +error_code DmuxPamfContext::wait_au_released_or_stream_reset(ppu_thread& ppu, u64 au_queue_full_bitset, b8& stream_reset_started, dmux_pamf_state& savestate) +{ + if (savestate == dmux_pamf_state::waiting_for_au_released) + { + goto label1_waiting_for_au_released_state; + } + + if (sys_mutex_lock(ppu, mutex, 0) != CELL_OK) + { + return CELL_DMUX_PAMF_ERROR_FATAL; + } + + if (ppu.state & cpu_flag::again) + { + return {}; + } + + if (au_queue_full_bitset) + { + cellDmuxPamf.trace("Access unit queue of elementary stream no. %d is full. Waiting for access unit to be released...", std::countr_zero(au_queue_full_bitset)); + + while (!(au_queue_full_bitset & au_released_bitset) && !stream_reset_requested) + { + savestate = dmux_pamf_state::waiting_for_au_released; + label1_waiting_for_au_released_state: + + if (sys_cond_wait(ppu, cond, 0) != CELL_OK) + { + sys_mutex_unlock(ppu, mutex); + return CELL_DMUX_PAMF_ERROR_FATAL; + } + + if (ppu.state & cpu_flag::again) + { + return {}; + } + } + + cellDmuxPamf.trace("Access unit released"); + } + + stream_reset_started = stream_reset_requested; + stream_reset_requested = false; + + au_released_bitset = 0; + + return sys_mutex_unlock(ppu, mutex) != CELL_OK ? static_cast(CELL_DMUX_PAMF_ERROR_FATAL) : CELL_OK; +} + +template +error_code DmuxPamfContext::set_au_reset(ppu_thread& ppu) +{ + if (sys_mutex_lock(ppu, mutex, 0) != CELL_OK) + { + return CELL_DMUX_PAMF_ERROR_FATAL; + } + + if (ppu.state & cpu_flag::again) + { + return {}; + } + + std::ranges::for_each(elementary_streams | std::views::filter([](auto es){ return !!es; }), [](auto& reset_next_au) { reset_next_au = reset; }, &DmuxPamfElementaryStream::reset_next_au); + + return sys_mutex_unlock(ppu, mutex) == CELL_OK ? static_cast(CELL_OK) : CELL_DMUX_PAMF_ERROR_FATAL; +} + +template +error_code DmuxPamfContext::callback(ppu_thread& ppu, DmuxCb cb, auto&&... args) +{ + std::unique_lock savestate_lock{ g_fxo->get(), std::try_to_lock }; + + if (!savestate_lock.owns_lock()) + { + ppu.state += cpu_flag::again; + return {}; + } + + return cb.cbFunc(ppu, std::forward(args)..., cb.cbArg); +} + +void DmuxPamfContext::run_spu_thread() +{ + hle_spu_thread_id = idm::make(cmd_queue_addr, cmd_result_queue_addr, stream_info_queue_addr, event_queue_addr); +} + +void DmuxPamfContext::exec(ppu_thread& ppu) +{ + // These are repeated a lot in this function, in my opinion using defines here makes it more readable +#define SEND_FATAL_ERR_AND_CONTINUE()\ + savestate = dmux_pamf_state::sending_fatal_err;\ + callback(ppu, notify_fatal_err, _this, CELL_OK); /* LLE uses CELL_OK as error code */\ + if (ppu.state & cpu_flag::again)\ + {\ + return;\ + }\ + continue + +#define RETURN_ON_CPU_FLAG_AGAIN()\ + if (ppu.state & cpu_flag::again)\ + return + + switch (savestate) + { + case dmux_pamf_state::initial: break; + case dmux_pamf_state::waiting_for_au_released: goto label1_waiting_for_au_released_state; + case dmux_pamf_state::waiting_for_au_released_error: goto label2_waiting_for_au_released_error_state; + case dmux_pamf_state::waiting_for_event: goto label3_waiting_for_event_state; + case dmux_pamf_state::starting_demux_done: goto label4_starting_demux_done_state; + case dmux_pamf_state::starting_demux_done_mutex_lock_error: goto label5_starting_demux_done_mutex_lock_error_state; + case dmux_pamf_state::starting_demux_done_mutex_unlock_error: goto label6_starting_demux_done_mutex_unlock_error_state; + case dmux_pamf_state::starting_demux_done_checking_stream_reset: goto label7_starting_demux_done_check_stream_reset_state; + case dmux_pamf_state::starting_demux_done_checking_stream_reset_error: goto label8_start_demux_done_check_stream_reset_error_state; + case dmux_pamf_state::setting_au_reset: goto label9_setting_au_reset_state; + case dmux_pamf_state::setting_au_reset_error: goto label10_setting_au_reset_error_state; + case dmux_pamf_state::processing_event: goto label11_processing_event_state; + case dmux_pamf_state::au_found_waiting_for_spu: goto label12_au_found_waiting_for_spu_state; + case dmux_pamf_state::unsetting_au_cancel: goto label13_unsetting_au_cancel_state; + case dmux_pamf_state::demux_done_notifying: goto label14_demux_done_notifying_state; + case dmux_pamf_state::demux_done_mutex_lock: goto label15_demux_done_mutex_lock_state; + case dmux_pamf_state::demux_done_cond_signal: goto label16_demux_done_cond_signal_state; + case dmux_pamf_state::resuming_demux_mutex_lock: goto label17_resuming_demux_mutex_lock_state; + case dmux_pamf_state::resuming_demux_waiting_for_spu: goto label18_resuming_demux_waiting_for_spu_state; + case dmux_pamf_state::sending_fatal_err: + callback(ppu, notify_fatal_err, _this, CELL_OK); + RETURN_ON_CPU_FLAG_AGAIN(); + } + + for (;;) + { + savestate = dmux_pamf_state::initial; + + stream_reset_started = false; + + // If the access unit queue of an enabled elementary stream is full, wait until the user releases an access unit or requests a stream reset before processing the next event + label1_waiting_for_au_released_state: + + if (wait_au_released_or_stream_reset(ppu, au_queue_full_bitset, stream_reset_started, savestate) != CELL_OK) + { + savestate = dmux_pamf_state::waiting_for_au_released_error; + label2_waiting_for_au_released_error_state: + + callback(ppu, notify_fatal_err, _this, CELL_OK); + } + + RETURN_ON_CPU_FLAG_AGAIN(); + + // Wait for the next event + if (!event_queue.peek(event)) + { + savestate = dmux_pamf_state::waiting_for_event; + label3_waiting_for_event_state: + + cellDmuxPamf.trace("Waiting for the next event..."); + + lv2_obj::sleep(ppu); + event_queue.wait(); + + if (ppu.check_state()) + { + ppu.state += cpu_flag::again; + return; + } + + ensure(event_queue.peek(event)); + } + + cellDmuxPamf.trace("Event type: %d", static_cast(event.type.get())); + + // If the event is a demux done event, set the sequence state to resetting and check for a potential stream reset request again + if (event.type == DmuxPamfEventType::demux_done) + { + savestate = dmux_pamf_state::starting_demux_done; + label4_starting_demux_done_state: + + if (sys_mutex_lock(ppu, mutex, 0) != CELL_OK) + { + savestate = dmux_pamf_state::starting_demux_done_mutex_lock_error; + label5_starting_demux_done_mutex_lock_error_state: + + callback(ppu, notify_fatal_err, _this, CELL_OK); + } + + RETURN_ON_CPU_FLAG_AGAIN(); + + sequence_state = DmuxPamfSequenceState::resetting; + + if (sys_mutex_unlock(ppu, mutex) != CELL_OK) + { + savestate = dmux_pamf_state::starting_demux_done_mutex_unlock_error; + label6_starting_demux_done_mutex_unlock_error_state: + + callback(ppu, notify_fatal_err, _this, CELL_OK); + + RETURN_ON_CPU_FLAG_AGAIN(); + } + + if (!stream_reset_started) + { + savestate = dmux_pamf_state::starting_demux_done_checking_stream_reset; + label7_starting_demux_done_check_stream_reset_state: + + if (wait_au_released_or_stream_reset(ppu, 0, stream_reset_started, savestate) != CELL_OK) + { + savestate = dmux_pamf_state::starting_demux_done_checking_stream_reset_error; + label8_start_demux_done_check_stream_reset_error_state: + + callback(ppu, notify_fatal_err, _this, CELL_OK); + } + + RETURN_ON_CPU_FLAG_AGAIN(); + } + } + + // If the user requested a stream reset, set the reset flag for every enabled elementary stream + if (stream_reset_started) + { + stream_reset_in_progress = true; + + savestate = dmux_pamf_state::setting_au_reset; + label9_setting_au_reset_state: + + if (set_au_reset(ppu) != CELL_OK) + { + savestate = dmux_pamf_state::setting_au_reset_error; + label10_setting_au_reset_error_state: + + callback(ppu, notify_fatal_err, _this, CELL_OK); + } + + RETURN_ON_CPU_FLAG_AGAIN(); + } + + savestate = dmux_pamf_state::processing_event; + label11_processing_event_state: + + switch (event.type) + { + case DmuxPamfEventType::au_found: + { + if (sys_mutex_lock(ppu, mutex, 0) != CELL_OK) + { + SEND_FATAL_ERR_AND_CONTINUE(); + } + + RETURN_ON_CPU_FLAG_AGAIN(); + + label12_au_found_waiting_for_spu_state: + + DmuxPamfElementaryStream* const es = find_es(event.au_found.stream_id, event.au_found.private_stream_id); + + // If the elementary stream of the found access unit is not enabled, don't do anything + if (!es || es->_this.get_ptr() != es || es->es_id != event.au_found.user_data) + { + if (sys_mutex_unlock(ppu, mutex) != CELL_OK) + { + SEND_FATAL_ERR_AND_CONTINUE(); + } + + break; + } + + // If a stream reset was requested, don't notify the user of any found access units that are still in the event queue + // We need to send the SPU thread the address of the first found access unit for each elementary stream still in the event queue, + // so that it can remove the access units from the queue. + if (stream_reset_in_progress) + { + if (es->reset_next_au) + { + send_spu_command_and_wait(ppu, savestate == dmux_pamf_state::au_found_waiting_for_spu, + event.au_found.stream_id, event.au_found.private_stream_id, event.au_found.au_addr); + + if (ppu.state & cpu_flag::again) + { + savestate = dmux_pamf_state::au_found_waiting_for_spu; + return; + } + + es->reset_next_au = false; + } + + if (sys_mutex_unlock(ppu, mutex) != CELL_OK) + { + SEND_FATAL_ERR_AND_CONTINUE(); + } + + break; + } + + const vm::var au_info; + au_info->addr = std::bit_cast>(event.au_found.au_addr); + au_info->size = event.au_found.au_size; + au_info->pts = event.au_found.pts; + au_info->dts = event.au_found.dts; + au_info->user_data = user_data; + au_info->specific_info = es->_this.ptr(&DmuxPamfElementaryStream::au_specific_info); + au_info->specific_info_size = es->au_specific_info_size; + au_info->is_rap = static_cast(event.au_found.is_rap); + + if (!is_raw_es) + { + if (dmuxPamfStreamIdToTypeChannel(event.au_found.stream_id, event.au_found.private_stream_id).first == DMUX_PAMF_STREAM_TYPE_INDEX_LPCM) + { + es->au_specific_info[0] = read_from_ptr(event.au_found.stream_header_buf) >> 4; + es->au_specific_info[1] = read_from_ptr(event.au_found.stream_header_buf) & 0xf; + es->au_specific_info[2] = read_from_ptr(&event.au_found.stream_header_buf[1]) >> 6; + } + } + + if (sys_mutex_unlock(ppu, mutex) != CELL_OK) + { + SEND_FATAL_ERR_AND_CONTINUE(); + } + + if (callback(ppu, es->notify_au_found, es->_this, au_info) != CELL_OK) + { + // If the callback returns an error, the access unit queue for this elementary stream is full + au_queue_full_bitset |= 1ull << es->this_index; + continue; + } + + RETURN_ON_CPU_FLAG_AGAIN(); + + break; + } + case DmuxPamfEventType::demux_done: + { + if (stream_reset_in_progress) + { + stream_reset_in_progress = false; + + savestate = dmux_pamf_state::unsetting_au_cancel; + label13_unsetting_au_cancel_state: + + if (set_au_reset(ppu) != CELL_OK) + { + SEND_FATAL_ERR_AND_CONTINUE(); + } + + RETURN_ON_CPU_FLAG_AGAIN(); + } + + savestate = dmux_pamf_state::demux_done_notifying; + label14_demux_done_notifying_state: + + callback(ppu, notify_demux_done, _this, CELL_OK); + + RETURN_ON_CPU_FLAG_AGAIN(); + + savestate = dmux_pamf_state::demux_done_mutex_lock; + label15_demux_done_mutex_lock_state: + + if (sys_mutex_lock(ppu, mutex, 0) != CELL_OK) + { + SEND_FATAL_ERR_AND_CONTINUE(); + } + + RETURN_ON_CPU_FLAG_AGAIN(); + + if (sequence_state == DmuxPamfSequenceState::resetting) + { + sequence_state = DmuxPamfSequenceState::dormant; + + savestate = dmux_pamf_state::demux_done_cond_signal; + label16_demux_done_cond_signal_state: + + if (sys_cond_signal_all(ppu, cond) != CELL_OK) + { + sys_mutex_unlock(ppu, mutex); + SEND_FATAL_ERR_AND_CONTINUE(); + } + + RETURN_ON_CPU_FLAG_AGAIN(); + } + + if (sys_mutex_unlock(ppu, mutex) != CELL_OK) + { + SEND_FATAL_ERR_AND_CONTINUE(); + } + + break; + } + case DmuxPamfEventType::close: + { + while (event_queue.pop()){} // Clear the event queue + return; + } + case DmuxPamfEventType::flush_done: + { + if (sys_mutex_lock(ppu, mutex, 0) != CELL_OK) + { + SEND_FATAL_ERR_AND_CONTINUE(); + } + + RETURN_ON_CPU_FLAG_AGAIN(); + + DmuxPamfElementaryStream* const es = find_es(event.flush_done.stream_id, event.flush_done.private_stream_id); + const bool valid = es && es->_this.get_ptr() == es && es->es_id == event.flush_done.user_data; + + if (sys_mutex_unlock(ppu, mutex) != CELL_OK) + { + SEND_FATAL_ERR_AND_CONTINUE(); + } + + if (valid) + { + callback(ppu, es->notify_flush_done, es->_this); + + RETURN_ON_CPU_FLAG_AGAIN(); + } + + break; + } + case DmuxPamfEventType::prog_end_code: + { + callback(ppu, notify_prog_end_code, _this); + + RETURN_ON_CPU_FLAG_AGAIN(); + + break; + } + case DmuxPamfEventType::fatal_error: + { + ensure(event_queue.pop()); + + SEND_FATAL_ERR_AND_CONTINUE(); + } + default: + fmt::throw_exception("Invalid event"); + } + + ensure(event_queue.pop()); + + // If there are too many events enqueued, the SPU thread will stop demuxing until it receives a new command. + // Once the event queue size is reduced to two, send a resume command + if (enabled_es_num >= 0 && event_queue.size() == 2) + { + savestate = dmux_pamf_state::resuming_demux_mutex_lock; + label17_resuming_demux_mutex_lock_state: + + if (sys_mutex_lock(ppu, mutex, 0) != CELL_OK) + { + SEND_FATAL_ERR_AND_CONTINUE(); + } + + RETURN_ON_CPU_FLAG_AGAIN(); + + if (enabled_es_num >= 0) + { + ensure(cmd_queue.emplace(DmuxPamfCommandType::resume)); + + savestate = dmux_pamf_state::resuming_demux_waiting_for_spu; + label18_resuming_demux_waiting_for_spu_state: + + lv2_obj::sleep(ppu); + cmd_result_queue.wait(); + + if (ppu.check_state()) + { + ppu.state += cpu_flag::again; + return; + } + + ensure(cmd_result_queue.pop()); + } + + if (sys_mutex_unlock(ppu, mutex) != CELL_OK) + { + SEND_FATAL_ERR_AND_CONTINUE(); + } + } + + au_queue_full_bitset = 0; + } +} + +void dmuxPamfEntry(ppu_thread& ppu, vm::ptr dmux) +{ + dmux->exec(ppu); + + if (ppu.state & cpu_flag::again) + { + ppu.syscall_args[0] = dmux.addr(); + return; + } + + ppu_execute<&sys_ppu_thread_exit>(ppu, CELL_OK); +} + +error_code dmuxPamfVerifyEsSpecificInfo(u16 stream_id, u16 private_stream_id, bool is_avc, vm::cptr es_specific_info) +{ + // The meaning of error code value 5 in here is inconsistent with how it's used elsewhere for some reason + + if (!es_specific_info) + { + return CELL_OK; + } + + switch (dmuxPamfStreamIdToTypeChannel(stream_id, private_stream_id).first) + { + case DMUX_PAMF_STREAM_TYPE_INDEX_VIDEO: + if (is_avc) + { + if (const u32 level = vm::static_ptr_cast(es_specific_info)->level; + level != CELL_DMUX_PAMF_AVC_LEVEL_2P1 && level != CELL_DMUX_PAMF_AVC_LEVEL_3P0 && level != CELL_DMUX_PAMF_AVC_LEVEL_3P1 + && level != CELL_DMUX_PAMF_AVC_LEVEL_3P2 && level != CELL_DMUX_PAMF_AVC_LEVEL_4P1 && level != CELL_DMUX_PAMF_AVC_LEVEL_4P2) + { + return 5; + } + } + else if (vm::static_ptr_cast(es_specific_info)->profileLevel > CELL_DMUX_PAMF_M2V_MP_HL) + { + return 5; + } + + return CELL_OK; + + case DMUX_PAMF_STREAM_TYPE_INDEX_LPCM: + if (const auto [sampling_freq, nch, bps] = *vm::static_ptr_cast(es_specific_info); + sampling_freq != CELL_DMUX_PAMF_FS_48K || (nch != 1u && nch != 2u && nch != 6u && nch != 8u) || (bps != CELL_DMUX_PAMF_BITS_PER_SAMPLE_16 && bps != CELL_DMUX_PAMF_BITS_PER_SAMPLE_24)) + { + return 5; + } + + return CELL_OK; + + case DMUX_PAMF_STREAM_TYPE_INDEX_AC3: + case DMUX_PAMF_STREAM_TYPE_INDEX_ATRACX: + case DMUX_PAMF_STREAM_TYPE_INDEX_USER_DATA: + return CELL_OK; + + default: + return 5; + } +} + +template +u32 dmuxPamfGetAuSpecificInfoSize(u16 stream_id, u16 private_stream_id, bool is_avc) +{ + if constexpr (raw_es) + { + return 0; + } + + switch (dmuxPamfStreamIdToTypeChannel(stream_id, private_stream_id).first) + { + case DMUX_PAMF_STREAM_TYPE_INDEX_VIDEO: + if (is_avc) + { + return 4; // LLE returns four, even though CellDmuxPamfAuSpecificInfoAvc only has a reserved field like the others + } + + return 0; + + case DMUX_PAMF_STREAM_TYPE_INDEX_LPCM: + case DMUX_PAMF_STREAM_TYPE_INDEX_AC3: // LLE returns three, even though CellDmuxPamfAuSpecificInfoAc3 only has a reserved field like the others + return 3; + + case DMUX_PAMF_STREAM_TYPE_INDEX_ATRACX: + case DMUX_PAMF_STREAM_TYPE_INDEX_USER_DATA: + default: + return 0; + } +} + +u32 dmuxPamfGetAuQueueMaxSize(u16 stream_id, u16 private_stream_id) +{ + switch (dmuxPamfStreamIdToTypeChannel(stream_id, private_stream_id).first) + { + case DMUX_PAMF_STREAM_TYPE_INDEX_LPCM: + return 0x100; + + case DMUX_PAMF_STREAM_TYPE_INDEX_VIDEO: + case DMUX_PAMF_STREAM_TYPE_INDEX_AC3: + case DMUX_PAMF_STREAM_TYPE_INDEX_ATRACX: + case DMUX_PAMF_STREAM_TYPE_INDEX_USER_DATA: + return 0x40; + + default: + return 0; + } +} + +u32 dmuxPamfGetLpcmAuSize(vm::cptr lpcm_info) +{ + return lpcm_info->samplingFreq * lpcm_info->bitsPerSample * (lpcm_info->numOfChannels + (lpcm_info->numOfChannels & 1)) / 1600; // Streams with an odd number of channels contain an empty dummy channel +} + +u32 dmuxPamfGetAuQueueBufferSize(u16 stream_id, u16 private_stream_id, bool is_avc, vm::cptr es_specific_info) +{ + switch (dmuxPamfStreamIdToTypeChannel(stream_id, private_stream_id).first) + { + case DMUX_PAMF_STREAM_TYPE_INDEX_VIDEO: + if (is_avc) + { + if (!es_specific_info) + { + return 0x46a870; + } + + switch (vm::static_ptr_cast(es_specific_info)->level) + { + case CELL_DMUX_PAMF_AVC_LEVEL_2P1: return 0xb00c0; + case CELL_DMUX_PAMF_AVC_LEVEL_3P0: return 0x19f2e0; + case CELL_DMUX_PAMF_AVC_LEVEL_3P1: return 0x260120; + case CELL_DMUX_PAMF_AVC_LEVEL_3P2: return 0x35f6c0; + case CELL_DMUX_PAMF_AVC_LEVEL_4P1: return 0x45e870; + case CELL_DMUX_PAMF_AVC_LEVEL_4P2: // Same as below + default: return 0x46a870; + } + } + + if (es_specific_info && vm::static_ptr_cast(es_specific_info)->profileLevel > CELL_DMUX_PAMF_M2V_MP_ML) + { + return 0x255000; + } + + return 0x70000; + + case DMUX_PAMF_STREAM_TYPE_INDEX_LPCM: + { + if (!es_specific_info) + { + return 0x104380; + } + + const u32 nch = vm::static_ptr_cast(es_specific_info)->numOfChannels; + const u32 lpcm_au_size = dmuxPamfGetLpcmAuSize(vm::static_ptr_cast(es_specific_info)); + + if (vm::static_ptr_cast(es_specific_info)->samplingFreq <= 96000) + { + if (nch > 0 && nch <= 2) + { + return 0x20000 + lpcm_au_size; + } + + if (nch <= 6) + { + return 0x60000 + lpcm_au_size; + } + + if (nch <= 8) + { + return 0x80000 + lpcm_au_size; + } + + return lpcm_au_size; + } + + if (nch > 0 && nch <= 2) + { + return 0x60000 + lpcm_au_size; + } + + if (nch <= 6) + { + return 0x100000 + lpcm_au_size; + } + + return lpcm_au_size; + } + case DMUX_PAMF_STREAM_TYPE_INDEX_AC3: + return 0xa000; + + case DMUX_PAMF_STREAM_TYPE_INDEX_ATRACX: + return 0x6400; + + case DMUX_PAMF_STREAM_TYPE_INDEX_USER_DATA: + return 0x160000; + + default: + return 0; + } +} + +template +u32 dmuxPamfGetEsMemSize(u16 stream_id, u16 private_stream_id, bool is_avc, vm::cptr es_specific_info) +{ + return dmuxPamfGetAuSpecificInfoSize(stream_id, private_stream_id, is_avc) * dmuxPamfGetAuQueueMaxSize(stream_id, private_stream_id) + + dmuxPamfGetAuQueueBufferSize(stream_id, private_stream_id, is_avc, es_specific_info) + 0x7f + static_cast(sizeof(DmuxPamfElementaryStream)) + 0xf; +} + +error_code dmuxPamfNotifyDemuxDone(ppu_thread& ppu, [[maybe_unused]] vm::ptr core_handle, error_code error, vm::ptr handle) +{ + handle->notify_demux_done.cbFunc(ppu, handle, error, handle->notify_demux_done.cbArg); + return CELL_OK; +} + +error_code dmuxPamfNotifyProgEndCode(ppu_thread& ppu, [[maybe_unused]] vm::ptr core_handle, vm::ptr handle) +{ + if (handle->notify_prog_end_code.cbFunc) + { + handle->notify_prog_end_code.cbFunc(ppu, handle, handle->notify_prog_end_code.cbArg); + } + + return CELL_OK; +} + +error_code dmuxPamfNotifyFatalErr(ppu_thread& ppu, [[maybe_unused]] vm::ptr core_handle, error_code error, vm::ptr handle) +{ + handle->notify_fatal_err.cbFunc(ppu, handle, error, handle->notify_fatal_err.cbArg); + return CELL_OK; +} + +error_code dmuxPamfEsNotifyAuFound(ppu_thread& ppu, [[maybe_unused]] vm::ptr core_handle, vm::cptr au_info, vm::ptr handle) +{ + const vm::var _au_info; + _au_info->info.auAddr = au_info->addr; + _au_info->info.auSize = au_info->size; + _au_info->info.isRap = au_info->is_rap; + _au_info->info.userData = au_info->user_data; + _au_info->info.pts = au_info->pts; + _au_info->info.dts = au_info->dts; + _au_info->specific_info = au_info->specific_info; + _au_info->specific_info_size = au_info->specific_info_size; + // _au_info->info.auMaxSize is left uninitialized + + return handle->notify_au_found.cbFunc(ppu, handle, _au_info, handle->notify_au_found.cbArg); +} + +error_code dmuxPamfEsNotifyFlushDone(ppu_thread& ppu, [[maybe_unused]] vm::ptr core_handle, vm::ptr handle) +{ + return handle->notify_flush_done.cbFunc(ppu, handle, handle->notify_flush_done.cbArg); +} + error_code _CellDmuxCoreOpQueryAttr(vm::cptr pamfSpecificInfo, vm::ptr pamfAttr) { - cellDmuxPamf.todo("_CellDmuxCoreOpQueryAttr(pamfSpecificInfo=*0x%x, pamfAttr=*0x%x)", pamfSpecificInfo, pamfAttr); + cellDmuxPamf.notice("_CellDmuxCoreOpQueryAttr(pamfSpecificInfo=*0x%x, pamfAttr=*0x%x)", pamfSpecificInfo, pamfAttr); + + if (!pamfAttr || (pamfSpecificInfo && pamfSpecificInfo->thisSize != sizeof(CellDmuxPamfSpecificInfo))) + { + return CELL_DMUX_PAMF_ERROR_ARG; + } + + pamfAttr->maxEnabledEsNum = DMUX_PAMF_MAX_ENABLED_ES_NUM; + pamfAttr->version = DMUX_PAMF_VERSION; + pamfAttr->memSize = sizeof(CellDmuxPamfHandle) + sizeof(DmuxPamfContext) + 0xe7b; return CELL_OK; } -error_code _CellDmuxCoreOpOpen(vm::cptr pamfSpecificInfo, vm::cptr demuxerResource, vm::cptr demuxerResourceSpurs, vm::cptr> notifyDemuxDone, - vm::cptr> notifyProgEndCode, vm::cptr> notifyFatalErr, vm::pptr handle) +error_code DmuxPamfContext::open(ppu_thread& ppu, const CellDmuxPamfResource& res, const DmuxCb& notify_dmux_done, const DmuxCb& notify_prog_end_code, + const DmuxCb& notify_fatal_err, vm::bptr& handle) { - cellDmuxPamf.todo("_CellDmuxCoreOpOpen(pamfSpecificInfo=*0x%x, demuxerResource=*0x%x, demuxerResourceSpurs=*0x%x, notifyDemuxDone=*0x%x, notifyProgEndCode=*0x%x, notifyFatalErr=*0x%x, handle=**0x%x)", + if (res.ppuThreadPriority >= 0xc00u || res.ppuThreadStackSize < 0x1000u || res.spuThreadPriority >= 0x100u || res.numOfSpus != 1u || !res.memAddr || res.memSize < sizeof(DmuxPamfContext) + 0xe7b) + { + return CELL_DMUX_PAMF_ERROR_ARG; + } + + const auto _this = vm::ptr::make(utils::align(+res.memAddr.addr(), 0x80)); + + _this->_this = _this; + _this->this_size = res.memSize; + _this->version = DMUX_PAMF_VERSION; + _this->notify_demux_done = notify_dmux_done; + _this->notify_prog_end_code = notify_prog_end_code; + _this->notify_fatal_err = notify_fatal_err; + _this->resource = res; + _this->unk = 0; + _this->ppu_thread_stack_size = res.ppuThreadStackSize; + _this->au_released_bitset = 0; + _this->stream_reset_requested = false; + _this->sequence_state = DmuxPamfSequenceState::dormant; + _this->max_enabled_es_num = DMUX_PAMF_MAX_ENABLED_ES_NUM; + _this->enabled_es_num = 0; + std::ranges::fill(_this->elementary_streams, vm::null); + _this->next_es_id = 0; + + const vm::var mutex_attr = {{ SYS_SYNC_PRIORITY, SYS_SYNC_NOT_RECURSIVE, SYS_SYNC_NOT_PROCESS_SHARED, SYS_SYNC_NOT_ADAPTIVE, 0, 0, 0, { "_dxpmtx"_u64 } }}; + const vm::var cond_attr = {{ SYS_SYNC_NOT_PROCESS_SHARED, 0, 0, { "_dxpcnd"_u64 } }}; + + if (sys_mutex_create(ppu, _this.ptr(&DmuxPamfContext::mutex), mutex_attr) != CELL_OK + || sys_cond_create(ppu, _this.ptr(&DmuxPamfContext::cond), _this->mutex, cond_attr) != CELL_OK) + { + return CELL_DMUX_PAMF_ERROR_FATAL; + } + + _this->spurs_context_addr = _this.ptr(&DmuxPamfContext::spurs_context); + _this->cmd_queue_addr_ = _this.ptr(&DmuxPamfContext::cmd_queue); + _this->cmd_queue_buffer_addr_ = _this.ptr(&DmuxPamfContext::cmd_queue_buffer); + _this->cmd_queue_addr = _this.ptr(&DmuxPamfContext::cmd_queue); + _this->cmd_result_queue_addr = _this.ptr(&DmuxPamfContext::cmd_result_queue); + _this->stream_info_queue_addr = _this.ptr(&DmuxPamfContext::stream_info_queue); + _this->event_queue_addr = _this.ptr(&DmuxPamfContext::event_queue); + _this->cmd_queue_buffer_addr = _this.ptr(&DmuxPamfContext::cmd_queue_buffer); + _this->cmd_result_queue_buffer_addr = _this.ptr(&DmuxPamfContext::cmd_result_queue_buffer); + _this->event_queue_buffer_addr = _this.ptr(&DmuxPamfContext::event_queue_buffer); + _this->stream_info_queue_buffer_addr = _this.ptr(&DmuxPamfContext::stream_info_queue_buffer); + _this->cmd_queue_addr__ = _this.ptr(&DmuxPamfContext::cmd_queue); + + ensure(std::snprintf(_this->spurs_taskset_name, sizeof(_this->spurs_taskset_name), "_libdmux_pamf_%08x", _this.addr()) == 22); + + _this->cmd_queue.init(_this->cmd_queue_buffer); + _this->cmd_result_queue.init(_this->cmd_result_queue_buffer); + _this->stream_info_queue.init(_this->stream_info_queue_buffer); + _this->event_queue.init(_this->event_queue_buffer); + + // HLE exclusive + _this->savestate = {}; + _this->au_queue_full_bitset = 0; + _this->stream_reset_started = false; + _this->stream_reset_in_progress = false; + + _this->run_spu_thread(); + + handle = _this; + return _this->create_thread(ppu); +} + +error_code _CellDmuxCoreOpOpen(ppu_thread& ppu, vm::cptr pamfSpecificInfo, vm::cptr demuxerResource, vm::cptr demuxerResourceSpurs, vm::cptr> notifyDemuxDone, + vm::cptr> notifyProgEndCode, vm::cptr> notifyFatalErr, vm::pptr handle) +{ + // Block savestates during ppu_execute + std::unique_lock savestate_lock{ g_fxo->get(), std::try_to_lock }; + + if (!savestate_lock.owns_lock()) + { + ppu.state += cpu_flag::again; + return {}; + } + + cellDmuxPamf.notice("_CellDmuxCoreOpOpen(pamfSpecificInfo=*0x%x, demuxerResource=*0x%x, demuxerResourceSpurs=*0x%x, notifyDemuxDone=*0x%x, notifyProgEndCode=*0x%x, notifyFatalErr=*0x%x, handle=**0x%x)", pamfSpecificInfo, demuxerResource, demuxerResourceSpurs, notifyDemuxDone, notifyProgEndCode, notifyFatalErr, handle); - return CELL_OK; + if ((pamfSpecificInfo && pamfSpecificInfo->thisSize != sizeof(CellDmuxPamfSpecificInfo)) + || !demuxerResource + || (demuxerResourceSpurs && !demuxerResourceSpurs->spurs) + || !notifyDemuxDone || !notifyDemuxDone->cbFunc || !notifyDemuxDone->cbArg + || !notifyProgEndCode + || !notifyFatalErr || !notifyFatalErr->cbFunc || !notifyFatalErr->cbArg + || !handle) + { + return CELL_DMUX_PAMF_ERROR_ARG; + } + + ensure(demuxerResource->memAddr.aligned(0x10)); // Not checked on LLE + + const auto _handle = vm::static_ptr_cast(demuxerResource->memAddr); + + _handle->notify_demux_done = *notifyDemuxDone; + _handle->notify_fatal_err = *notifyFatalErr; + _handle->notify_prog_end_code = *notifyProgEndCode; + + if (!pamfSpecificInfo || !pamfSpecificInfo->programEndCodeCb) + { + _handle->notify_prog_end_code.cbFunc = vm::null; + } + + const CellDmuxPamfResource res{ demuxerResource->ppuThreadPriority, demuxerResource->ppuThreadStackSize, demuxerResource->numOfSpus, demuxerResource->spuThreadPriority, + vm::bptr::make(demuxerResource->memAddr.addr() + sizeof(CellDmuxPamfHandle)), demuxerResource->memSize - sizeof(CellDmuxPamfHandle) }; + + const auto demux_done_func = vm::bptr::make(g_fxo->get().func_addr(FIND_FUNC(dmuxPamfNotifyDemuxDone))); + const auto prog_end_code_func = vm::bptr::make(g_fxo->get().func_addr(FIND_FUNC(dmuxPamfNotifyProgEndCode))); + const auto fatal_err_func = vm::bptr::make(g_fxo->get().func_addr(FIND_FUNC(dmuxPamfNotifyFatalErr))); + + const error_code ret = DmuxPamfContext::open(ppu, res, { demux_done_func, _handle }, { prog_end_code_func, _handle }, { fatal_err_func, _handle }, _handle->demuxer); + + *handle = _handle; + + return ret; } -error_code _CellDmuxCoreOpClose(vm::ptr handle) +error_code DmuxPamfContext::close(ppu_thread& ppu) { - cellDmuxPamf.todo("_CellDmuxCoreOpClose(handle=*0x%x)", handle); + if (join_thread(ppu) != CELL_OK) + { + return CELL_DMUX_PAMF_ERROR_FATAL; + } + + ensure(idm::remove(hle_spu_thread_id)); return CELL_OK; } -error_code _CellDmuxCoreOpResetStream(vm::ptr handle) +error_code _CellDmuxCoreOpClose(ppu_thread& ppu, vm::ptr handle) { - cellDmuxPamf.todo("_CellDmuxCoreOpResetStream(handle=*0x%x)", handle); + // The PPU thread is going to use ppu_execute + std::unique_lock savestate_lock{ g_fxo->get(), std::try_to_lock }; + + if (!savestate_lock.owns_lock()) + { + ppu.state += cpu_flag::again; + return {}; + } + + cellDmuxPamf.notice("_CellDmuxCoreOpClose(handle=*0x%x)", handle); + + if (!handle) + { + return CELL_DMUX_PAMF_ERROR_ARG; + } + + return handle->demuxer->close(ppu); +} + +error_code DmuxPamfContext::reset_stream(ppu_thread& ppu) +{ + auto& ar = *ppu.optional_savestate_state; + const u8 savestate = ar.try_read().second; + ar.clear(); + + switch (savestate) + { + case 0: + if (sys_mutex_lock(ppu, mutex, 0) != CELL_OK) + { + return CELL_DMUX_PAMF_ERROR_FATAL; + } + + if (ppu.state & cpu_flag::again) + { + ar(0); + return {}; + } + + if (sequence_state != DmuxPamfSequenceState::running) + { + return sys_mutex_unlock(ppu, mutex) == CELL_OK ? static_cast(CELL_OK) : CELL_DMUX_PAMF_ERROR_FATAL; + } + + [[fallthrough]]; + + case 1: + send_spu_command_and_wait(ppu, savestate); + + if (ppu.state & cpu_flag::again) + { + ar(1); + return {}; + } + + stream_reset_requested = true; + [[fallthrough]]; + + case 2: + if (const error_code ret = sys_cond_signal_to(ppu, cond, static_cast(thread_id)); ret != CELL_OK && ret != static_cast(CELL_EPERM)) + { + sys_mutex_unlock(ppu, mutex); + return CELL_DMUX_PAMF_ERROR_FATAL; + } + + if (ppu.state & cpu_flag::again) + { + ar(2); + return {}; + } + + return sys_mutex_unlock(ppu, mutex) == CELL_OK ? static_cast(CELL_OK) : CELL_DMUX_PAMF_ERROR_FATAL; + + default: + fmt::throw_exception("Unexpected savestate value: 0x%x", savestate); + } +} + +error_code _CellDmuxCoreOpResetStream(ppu_thread& ppu, vm::ptr handle) +{ + cellDmuxPamf.notice("_CellDmuxCoreOpResetStream(handle=*0x%x)", handle); + + if (!handle) + { + return CELL_DMUX_PAMF_ERROR_ARG; + } + + return handle->demuxer->reset_stream(ppu); +} + +error_code DmuxPamfContext::create_thread(ppu_thread& ppu) +{ + const vm::var name = vm::make_str("HLE PAMF demuxer"); + const auto entry = g_fxo->get().func_addr(FIND_FUNC(dmuxPamfEntry)); + + if (ppu_execute<&sys_ppu_thread_create>(ppu, _this.ptr(&DmuxPamfContext::thread_id), entry, +_this.addr(), +resource.ppuThreadPriority, +resource.ppuThreadStackSize, SYS_PPU_THREAD_CREATE_JOINABLE, +name) != CELL_OK) + { + return CELL_DMUX_PAMF_ERROR_FATAL; + } return CELL_OK; } -error_code _CellDmuxCoreOpCreateThread(vm::ptr handle) +error_code _CellDmuxCoreOpCreateThread(ppu_thread& ppu, vm::ptr handle) { - cellDmuxPamf.todo("_CellDmuxCoreOpCreateThread(handle=*0x%x)", handle); + // Block savestates during ppu_execute + std::unique_lock savestate_lock{ g_fxo->get(), std::try_to_lock }; - return CELL_OK; + if (!savestate_lock.owns_lock()) + { + ppu.state += cpu_flag::again; + return {}; + } + + cellDmuxPamf.notice("_CellDmuxCoreOpCreateThread(handle=*0x%x)", handle); + + if (!handle) + { + return CELL_DMUX_PAMF_ERROR_ARG; + } + + return handle->demuxer->create_thread(ppu); } -error_code _CellDmuxCoreOpJoinThread(vm::ptr handle) +error_code DmuxPamfContext::join_thread(ppu_thread& ppu) { - cellDmuxPamf.todo("_CellDmuxCoreOpJoinThread(handle=*0x%x)", handle); + if (sys_mutex_lock(ppu, mutex, 0) != CELL_OK) + { + return CELL_DMUX_PAMF_ERROR_FATAL; + } + + std::ranges::fill_n(elementary_streams, enabled_es_num, vm::null); + + enabled_es_num = -1; + + send_spu_command_and_wait(ppu, false); + + if (sys_mutex_unlock(ppu, mutex) != CELL_OK) + { + return CELL_DMUX_PAMF_ERROR_FATAL; + } + + return sys_ppu_thread_join(ppu, static_cast(thread_id), +vm::var{}) == CELL_OK ? static_cast(CELL_OK) : CELL_DMUX_PAMF_ERROR_FATAL; +} + +error_code _CellDmuxCoreOpJoinThread(ppu_thread& ppu, vm::ptr handle) +{ + // The PPU thread is going to use ppu_execute + std::unique_lock savestate_lock{ g_fxo->get(), std::try_to_lock }; + + if (!savestate_lock.owns_lock()) + { + ppu.state += cpu_flag::again; + return {}; + } + + cellDmuxPamf.notice("_CellDmuxCoreOpJoinThread(handle=*0x%x)", handle); + + if (!handle) + { + return CELL_DMUX_PAMF_ERROR_ARG; + } + + return handle->demuxer->join_thread(ppu); +} + +template +error_code DmuxPamfContext::set_stream(ppu_thread& ppu, vm::cptr stream_address, u32 stream_size, b8 discontinuity, u32 user_data) +{ + auto& ar = *ppu.optional_savestate_state; + const bool waiting_for_spu_state = ar.try_read().second; + ar.clear(); + + if (!waiting_for_spu_state) + { + if (sys_mutex_lock(ppu, mutex, 0) != CELL_OK) + { + return CELL_DMUX_PAMF_ERROR_FATAL; + } + + if (ppu.state & cpu_flag::again) + { + ar(false); + return {}; + } + + this->user_data = user_data; + + if (!stream_info_queue.emplace(stream_address, stream_size, user_data, !discontinuity, raw_es)) + { + return sys_mutex_unlock(ppu, mutex) == CELL_OK ? CELL_DMUX_PAMF_ERROR_BUSY : CELL_DMUX_PAMF_ERROR_FATAL; + } + } + + send_spu_command_and_wait(ppu, waiting_for_spu_state); + + if (ppu.state & cpu_flag::again) + { + ar(true); + return {}; + } + + sequence_state = DmuxPamfSequenceState::running; + + return sys_mutex_unlock(ppu, mutex) == CELL_OK ? static_cast(CELL_OK) : CELL_DMUX_PAMF_ERROR_FATAL; +} + +template +error_code _CellDmuxCoreOpSetStream(ppu_thread& ppu, vm::ptr handle, vm::cptr streamAddress, u32 streamSize, b8 discontinuity, u64 userData) +{ + cellDmuxPamf.trace("_CellDmuxCoreOpSetStream(handle=*0x%x, streamAddress=*0x%x, streamSize=0x%x, discontinuity=%d, userData=0x%llx)", raw_es, handle, streamAddress, streamSize, +discontinuity, userData); + + if (!streamAddress || streamSize == 0) + { + return CELL_DMUX_PAMF_ERROR_ARG; + } + + ensure(!!handle); // Not checked on LLE + + return handle->demuxer->set_stream(ppu, streamAddress, streamSize, discontinuity, static_cast(userData)); +} + +error_code DmuxPamfElementaryStream::release_au(ppu_thread& ppu, vm::ptr au_addr, u32 au_size) const +{ + auto& ar = *ppu.optional_savestate_state; + const u8 savestate = ar.try_read().second; + ar.clear(); + + switch (savestate) + { + case 0: + if (sys_mutex_lock(ppu, demuxer->mutex, 0) != CELL_OK) + { + return CELL_DMUX_PAMF_ERROR_FATAL; + } + + if (ppu.state & cpu_flag::again) + { + ar(0); + return {}; + } + + [[fallthrough]]; + + case 1: + demuxer->send_spu_command_and_wait(ppu, savestate, au_addr, au_size, static_cast>(stream_id), static_cast>(private_stream_id)); + + if (ppu.state & cpu_flag::again) + { + ar(1); + return {}; + } + + demuxer->au_released_bitset |= 1ull << this_index; + [[fallthrough]]; + + case 2: + if (const error_code ret = sys_cond_signal_to(ppu, demuxer->cond, static_cast(demuxer->thread_id)); ret != CELL_OK && ret != static_cast(CELL_EPERM)) + { + sys_mutex_unlock(ppu, demuxer->mutex); + return CELL_DMUX_PAMF_ERROR_FATAL; + } + + if (ppu.state & cpu_flag::again) + { + ar(2); + return {}; + } + + return sys_mutex_unlock(ppu, demuxer->mutex) == CELL_OK ? static_cast(CELL_OK) : CELL_DMUX_PAMF_ERROR_FATAL; + + default: + fmt::throw_exception("Unexpected savestate value: 0x%x", savestate); + } +} + +error_code _CellDmuxCoreOpReleaseAu(ppu_thread& ppu, vm::ptr esHandle, vm::ptr auAddr, u32 auSize) +{ + cellDmuxPamf.trace("_CellDmuxCoreOpReleaseAu(esHandle=*0x%x, auAddr=*0x%x, auSize=0x%x)", esHandle, auAddr, auSize); + + if (!auAddr || auSize == 0) + { + return CELL_DMUX_PAMF_ERROR_ARG; + } + + ensure(!!esHandle); // Not checked on LLE + + return esHandle->es->release_au(ppu, auAddr, auSize); +} + +template +error_code dmuxPamfGetEsAttr(u16 stream_id, u16 private_stream_id, bool is_avc, vm::cptr es_specific_info, CellDmuxPamfEsAttr& attr) +{ + if (dmuxPamfStreamIdToTypeChannel(stream_id, private_stream_id).first == DMUX_PAMF_STREAM_TYPE_INDEX_INVALID) + { + return CELL_DMUX_PAMF_ERROR_UNKNOWN_STREAM; + } + + if (dmuxPamfVerifyEsSpecificInfo(stream_id, private_stream_id, is_avc, es_specific_info) != CELL_OK) + { + return CELL_DMUX_PAMF_ERROR_ARG; + } + + attr.auQueueMaxSize = dmuxPamfGetAuQueueMaxSize(stream_id, private_stream_id); + attr.memSize = dmuxPamfGetEsMemSize(stream_id, private_stream_id, is_avc, es_specific_info); + attr.specificInfoSize = dmuxPamfGetAuSpecificInfoSize(stream_id, private_stream_id, is_avc); return CELL_OK; } template -error_code _CellDmuxCoreOpSetStream(vm::ptr handle, vm::cptr streamAddress, u32 streamSize, b8 discontinuity, u64 userData) +static inline std::tuple get_stream_ids(vm::cptr esFilterId) { - cellDmuxPamf.todo("_CellDmuxCoreOpSetStream(handle=*0x%x, streamAddress=*0x%x, streamSize=0x%x, discontinuity=%d, userData=0x%llx)", raw_es, handle, streamAddress, streamSize, +discontinuity, userData); + if constexpr (raw_es) + { + const auto filter_id = vm::static_ptr_cast(esFilterId); + return { filter_id[2], filter_id[3], filter_id[8] >> 7 }; + } - return CELL_OK; -} - -error_code _CellDmuxCoreOpReleaseAu(vm::ptr esHandle, vm::ptr memAddr, u32 memSize) -{ - cellDmuxPamf.todo("_CellDmuxCoreOpReleaseAu(esHandle=*0x%x, memAddr=*0x%x, memSize=0x%x)", esHandle, memAddr, memSize); - - return CELL_OK; + const auto filter_id = vm::static_ptr_cast(esFilterId); + return { filter_id->filterIdMajor, filter_id->filterIdMinor, filter_id->supplementalInfo1 }; } template error_code _CellDmuxCoreOpQueryEsAttr(vm::cptr esFilterId, vm::cptr esSpecificInfo, vm::ptr attr) { - cellDmuxPamf.todo("_CellDmuxCoreOpQueryEsAttr(esFilterId=*0x%x, esSpecificInfo=*0x%x, attr=*0x%x)", raw_es, esFilterId, esSpecificInfo, attr); + cellDmuxPamf.notice("_CellDmuxCoreOpQueryEsAttr(esFilterId=*0x%x, esSpecificInfo=*0x%x, attr=*0x%x)", raw_es, esFilterId, esSpecificInfo, attr); + if (!esFilterId || !attr) + { + return CELL_DMUX_PAMF_ERROR_ARG; + } + + const auto [stream_id, private_stream_id, is_avc] = get_stream_ids(esFilterId); + + CellDmuxPamfEsAttr es_attr; + + const error_code ret = dmuxPamfGetEsAttr(stream_id, private_stream_id, is_avc, esSpecificInfo, es_attr); + + *attr = es_attr; + attr->memSize += static_cast(sizeof(CellDmuxPamfEsHandle)); + + return ret; +} + +template +error_code DmuxPamfContext::enable_es(ppu_thread& ppu, u16 stream_id, u16 private_stream_id, bool is_avc, vm::cptr es_specific_info, vm::ptr mem_addr, u32 mem_size, const DmuxCb& notify_au_found, + const DmuxCb& notify_flush_done, vm::bptr& es) +{ + auto& ar = *ppu.optional_savestate_state; + const bool waiting_for_spu_state = ar.try_read().second; + ar.clear(); + + if (mem_size < dmuxPamfGetEsMemSize(stream_id, private_stream_id, is_avc, es_specific_info)) + { + return CELL_DMUX_PAMF_ERROR_ARG; + } + + const auto stream_type = dmuxPamfStreamIdToTypeChannel(stream_id, private_stream_id).first; + + if (!waiting_for_spu_state) + { + if (stream_type == DMUX_PAMF_STREAM_TYPE_INDEX_INVALID) + { + return CELL_DMUX_PAMF_ERROR_UNKNOWN_STREAM; + } + + if (dmuxPamfVerifyEsSpecificInfo(stream_id, private_stream_id, is_avc, es_specific_info) != CELL_OK) + { + return CELL_DMUX_PAMF_ERROR_ARG; + } + + if (const error_code ret = sys_mutex_lock(ppu, mutex, 0); ret != CELL_OK) + { + return CELL_DMUX_PAMF_ERROR_FATAL; + } + + if (ppu.state & cpu_flag::again) + { + ar(false); + return {}; + } + + this->is_raw_es = raw_es; + + if (enabled_es_num == max_enabled_es_num) + { + return sys_mutex_unlock(ppu, mutex) == CELL_OK ? CELL_DMUX_PAMF_ERROR_NO_MEMORY : CELL_DMUX_PAMF_ERROR_FATAL; + } + + if (find_es(stream_id, private_stream_id)) + { + // Elementary stream is already enabled + return sys_mutex_unlock(ppu, mutex) == CELL_OK ? CELL_DMUX_PAMF_ERROR_ARG : CELL_DMUX_PAMF_ERROR_FATAL; + } + } + + const be_t au_max_size = [&]() -> be_t + { + switch (stream_type) + { + case DMUX_PAMF_STREAM_TYPE_INDEX_VIDEO: + if (is_avc) + { + if (!es_specific_info || vm::static_ptr_cast(es_specific_info)->level == CELL_DMUX_PAMF_AVC_LEVEL_4P2) + { + return 0xcc000u; + } + + switch (vm::static_ptr_cast(es_specific_info)->level) + { + case CELL_DMUX_PAMF_AVC_LEVEL_2P1: return 0x12900u; + case CELL_DMUX_PAMF_AVC_LEVEL_3P0: return 0x25f80u; + case CELL_DMUX_PAMF_AVC_LEVEL_3P1: return 0x54600u; + case CELL_DMUX_PAMF_AVC_LEVEL_3P2: return 0x78000u; + case CELL_DMUX_PAMF_AVC_LEVEL_4P1: return 0xc0000u; + default: fmt::throw_exception("Unreachable"); // es_specific_info was already checked for invalid values in dmuxPamfVerifyEsSpecificInfo() + } + } + + if (!es_specific_info || vm::static_ptr_cast(es_specific_info)->profileLevel > CELL_DMUX_PAMF_M2V_MP_ML) + { + return 0x12a800u; + } + + return 0x38000u; + + case DMUX_PAMF_STREAM_TYPE_INDEX_LPCM: return dmuxPamfGetLpcmAuSize(vm::static_ptr_cast(es_specific_info)); + case DMUX_PAMF_STREAM_TYPE_INDEX_AC3: return 0xf00u; + case DMUX_PAMF_STREAM_TYPE_INDEX_ATRACX: return 0x1008u; + case DMUX_PAMF_STREAM_TYPE_INDEX_USER_DATA: return 0xa0000u; + default: fmt::throw_exception("Unreachable"); // stream_type was already checked + } + }(); + + const auto _es = vm::bptr::make(utils::align(mem_addr.addr(), 0x10)); + + const auto au_queue_buffer = vm::bptr::make(utils::align(_es.addr() + static_cast(sizeof(DmuxPamfElementaryStream)), 0x80)); + const be_t au_specific_info_size = dmuxPamfGetAuSpecificInfoSize(stream_id, private_stream_id, is_avc); + + send_spu_command_and_wait(ppu, waiting_for_spu_state, stream_id, private_stream_id, is_avc, au_queue_buffer, + dmuxPamfGetAuQueueBufferSize(stream_id, private_stream_id, is_avc, es_specific_info), au_max_size, au_specific_info_size, raw_es, next_es_id); + + if (ppu.state & cpu_flag::again) + { + ar(true); + return {}; + } + + u32 es_idx = umax; + while (elementary_streams[++es_idx]){} // There is guaranteed to be an empty slot, this was already checked above + + _es->_this = _es; + _es->this_size = mem_size; + _es->this_index = es_idx; + _es->demuxer = _this; + _es->notify_au_found = notify_au_found; + _es->notify_flush_done = notify_flush_done; + _es->stream_id = stream_id; + _es->private_stream_id = private_stream_id; + _es->is_avc = is_avc; + _es->au_queue_buffer = au_queue_buffer; + _es->au_max_size = au_max_size; + _es->au_specific_info_size = au_specific_info_size; + _es->reset_next_au = false; + _es->es_id = next_es_id++; + + elementary_streams[es_idx] = _es; + + enabled_es_num++; + + if (sys_mutex_unlock(ppu, mutex) != CELL_OK) + { + return CELL_DMUX_PAMF_ERROR_FATAL; + } + + es = _es; return CELL_OK; } template -error_code _CellDmuxCoreOpEnableEs(vm::ptr handle, vm::cptr esFilterId, vm::cptr esResource, vm::cptr> notifyAuFound, - vm::cptr> notifyFlushDone, vm::cptr esSpecificInfo, vm::pptr esHandle) +error_code _CellDmuxCoreOpEnableEs(ppu_thread& ppu, vm::ptr handle, vm::cptr esFilterId, vm::cptr esResource, vm::cptr> notifyAuFound, + vm::cptr> notifyFlushDone, vm::cptr esSpecificInfo, vm::pptr esHandle) { - cellDmuxPamf.todo("_CellDmuxCoreOpEnableEs(handle=*0x%x, esFilterId=*0x%x, esResource=*0x%x, notifyAuFound=*0x%x, notifyFlushDone=*0x%x, esSpecificInfo=*0x%x, esHandle)", + cellDmuxPamf.notice("_CellDmuxCoreOpEnableEs(handle=*0x%x, esFilterId=*0x%x, esResource=*0x%x, notifyAuFound=*0x%x, notifyFlushDone=*0x%x, esSpecificInfo=*0x%x, esHandle)", raw_es, handle, esFilterId, esResource, notifyAuFound, notifyFlushDone, esSpecificInfo, esHandle); - return CELL_OK; + if (!handle || !esFilterId || !esResource || !esResource->memAddr || esResource->memSize == 0u || !notifyAuFound || !notifyAuFound->cbFunc || !notifyAuFound->cbArg || !notifyFlushDone || !notifyFlushDone->cbFunc || !notifyFlushDone->cbArg) + { + return CELL_DMUX_PAMF_ERROR_ARG; + } + + ensure(!!esHandle && esResource->memAddr.aligned(0x10)); // Not checked on LLE + + const auto es_handle = vm::static_ptr_cast(esResource->memAddr); + + es_handle->notify_au_found = *notifyAuFound; + es_handle->notify_flush_done = *notifyFlushDone; + + const auto au_found_func = vm::bptr::make(g_fxo->get().func_addr(FIND_FUNC(dmuxPamfEsNotifyAuFound))); + const auto flush_done_func = vm::bptr::make(g_fxo->get().func_addr(FIND_FUNC(dmuxPamfEsNotifyFlushDone))); + + const auto [stream_id, private_stream_id, is_avc] = get_stream_ids(esFilterId); + + const error_code ret = handle->demuxer->enable_es(ppu, stream_id, private_stream_id, is_avc, esSpecificInfo, vm::ptr::make(esResource->memAddr.addr() + sizeof(CellDmuxPamfEsHandle)), + esResource->memSize - sizeof(CellDmuxPamfEsHandle), { au_found_func, es_handle }, { flush_done_func, es_handle }, es_handle->es); + + *esHandle = es_handle; + + return ret; } -error_code _CellDmuxCoreOpDisableEs(vm::ptr esHandle) +error_code DmuxPamfElementaryStream::disable_es(ppu_thread& ppu) { - cellDmuxPamf.todo("_CellDmuxCoreOpDisableEs(esHandle=*0x%x)", esHandle); + const auto dmux = demuxer.get_ptr(); - return CELL_OK; + auto& ar = *ppu.optional_savestate_state; + const u8 savestate = ar.try_read().second; + ar.clear(); + + switch (savestate) + { + case 0: + if (sys_mutex_lock(ppu, dmux->mutex, 0) != CELL_OK) + { + return CELL_DMUX_PAMF_ERROR_FATAL; + } + + if (ppu.state & cpu_flag::again) + { + ar(0); + return {}; + } + + if (!dmux->find_es(stream_id, private_stream_id)) + { + // Elementary stream is already disabled + return sys_mutex_unlock(ppu, dmux->mutex) == CELL_OK ? CELL_DMUX_PAMF_ERROR_ARG : CELL_DMUX_PAMF_ERROR_FATAL; + } + + [[fallthrough]]; + + case 1: + dmux->send_spu_command_and_wait(ppu, savestate, static_cast>(stream_id), static_cast>(private_stream_id)); + + if (ppu.state & cpu_flag::again) + { + ar(1); + return {}; + } + + _this = vm::null; + this_size = 0; + demuxer = vm::null; + notify_au_found = {}; + au_queue_buffer = vm::null; + unk = 0; + au_max_size = 0; + + dmux->elementary_streams[this_index] = vm::null; + dmux->enabled_es_num--; + + dmux->au_released_bitset |= 1ull << this_index; + + this_index = 0; + [[fallthrough]]; + + case 2: + if (const error_code ret = sys_cond_signal_to(ppu, dmux->cond, static_cast(dmux->thread_id)); ret != CELL_OK && ret != static_cast(CELL_EPERM)) + { + sys_mutex_unlock(ppu, dmux->mutex); + return CELL_DMUX_PAMF_ERROR_FATAL; + } + + if (ppu.state & cpu_flag::again) + { + ar(2); + return {}; + } + + return sys_mutex_unlock(ppu, dmux->mutex) == CELL_OK ? static_cast(CELL_OK) : CELL_DMUX_PAMF_ERROR_FATAL; + + default: + fmt::throw_exception("Unexpected savestate value: 0x%x", savestate); + } } -error_code _CellDmuxCoreOpFlushEs(vm::ptr esHandle) +error_code _CellDmuxCoreOpDisableEs(ppu_thread& ppu, vm::ptr esHandle) { - cellDmuxPamf.todo("_CellDmuxCoreOpFlushEs(esHandle=*0x%x)", esHandle); + cellDmuxPamf.notice("_CellDmuxCoreOpDisableEs(esHandle=*0x%x)", esHandle); - return CELL_OK; + if (!esHandle) + { + return CELL_DMUX_PAMF_ERROR_ARG; + } + + return esHandle->es->disable_es(ppu); } -error_code _CellDmuxCoreOpResetEs(vm::ptr esHandle) +error_code DmuxPamfElementaryStream::flush_es(ppu_thread& ppu) const { - cellDmuxPamf.todo("_CellDmuxCoreOpResetEs(esHandle=*0x%x)", esHandle); + auto& ar = *ppu.optional_savestate_state; + const bool waiting_for_spu_state = ar.try_read().second; + ar.clear(); - return CELL_OK; + if (!waiting_for_spu_state) + { + if (sys_mutex_lock(ppu, demuxer->mutex, 0) != CELL_OK) + { + return CELL_DMUX_PAMF_ERROR_FATAL; + } + + if (ppu.state & cpu_flag::again) + { + ar(false); + return {}; + } + } + + demuxer->send_spu_command_and_wait(ppu, waiting_for_spu_state, static_cast>(stream_id), static_cast>(private_stream_id)); + + if (ppu.state & cpu_flag::again) + { + ar(true); + return {}; + } + + return sys_mutex_unlock(ppu, demuxer->mutex) == CELL_OK ? static_cast(CELL_OK) : CELL_DMUX_PAMF_ERROR_FATAL; } -error_code _CellDmuxCoreOpResetStreamAndWaitDone(vm::ptr handle) +error_code _CellDmuxCoreOpFlushEs(ppu_thread& ppu, vm::ptr esHandle) { - cellDmuxPamf.todo("_CellDmuxCoreOpResetStreamAndWaitDone(handle=*0x%x)", handle); + cellDmuxPamf.notice("_CellDmuxCoreOpFlushEs(esHandle=*0x%x)", esHandle); - return CELL_OK; + if (!esHandle) + { + return CELL_DMUX_PAMF_ERROR_ARG; + } + + return esHandle->es->flush_es(ppu); +} + +error_code DmuxPamfElementaryStream::reset_es(ppu_thread& ppu) const +{ + auto& ar = *ppu.optional_savestate_state; + const bool waiting_for_spu_state = ar.try_read().second; + ar.clear(); + + if (!waiting_for_spu_state) + { + if (sys_mutex_lock(ppu, demuxer->mutex, 0) != CELL_OK) + { + return CELL_DMUX_PAMF_ERROR_FATAL; + } + + if (ppu.state & cpu_flag::again) + { + ar(false); + return {}; + } + } + + demuxer->send_spu_command_and_wait(ppu, waiting_for_spu_state, static_cast>(stream_id), static_cast>(private_stream_id), vm::null); + + if (ppu.state & cpu_flag::again) + { + ar(true); + return {}; + } + + return sys_mutex_unlock(ppu, demuxer->mutex) == CELL_OK ? static_cast(CELL_OK) : CELL_DMUX_PAMF_ERROR_FATAL; +} + +error_code _CellDmuxCoreOpResetEs(ppu_thread& ppu, vm::ptr esHandle) +{ + cellDmuxPamf.notice("_CellDmuxCoreOpResetEs(esHandle=*0x%x)", esHandle); + + if (!esHandle) + { + return CELL_DMUX_PAMF_ERROR_ARG; + } + + return esHandle->es->reset_es(ppu); +} + +error_code DmuxPamfContext::reset_stream_and_wait_done(ppu_thread& ppu) +{ + // Both sys_cond_wait() and DmuxPamfContext::reset_stream() are already using ppu_thread::optional_savestate_state, so we can't save this function currently + std::unique_lock savestate_lock{ g_fxo->get(), std::try_to_lock }; + + if (!savestate_lock.owns_lock()) + { + ppu.state += cpu_flag::again; + return {}; + } + + if (reset_stream(ppu) != CELL_OK) + { + return CELL_DMUX_PAMF_ERROR_FATAL; + } + + if (ppu.state & cpu_flag::again) + { + return {}; + } + + if (sys_mutex_lock(ppu, mutex, 0) != CELL_OK) + { + return CELL_DMUX_PAMF_ERROR_FATAL; + } + + if (ppu.state & cpu_flag::again) + { + return {}; + } + + while (sequence_state != DmuxPamfSequenceState::dormant) + { + if (sys_cond_wait(ppu, cond, 0) != CELL_OK) + { + sys_mutex_unlock(ppu, mutex); + return CELL_DMUX_PAMF_ERROR_FATAL; + } + + if (ppu.state & cpu_flag::again) + { + return {}; + } + } + + return sys_mutex_unlock(ppu, mutex) == CELL_OK ? static_cast(CELL_OK) : CELL_DMUX_PAMF_ERROR_FATAL; +} + +error_code _CellDmuxCoreOpResetStreamAndWaitDone(ppu_thread& ppu, vm::ptr handle) +{ + cellDmuxPamf.notice("_CellDmuxCoreOpResetStreamAndWaitDone(handle=*0x%x)", handle); + + if (!handle) + { + return CELL_DMUX_PAMF_ERROR_ARG; + } + + return handle->demuxer->reset_stream_and_wait_done(ppu); } template @@ -1267,4 +2840,12 @@ DECLARE(ppu_module_manager::cellDmuxPamf)("cellDmuxPamf", [] REG_HIDDEN_FUNC(_CellDmuxCoreOpFlushEs); REG_HIDDEN_FUNC(_CellDmuxCoreOpResetEs); REG_HIDDEN_FUNC(_CellDmuxCoreOpResetStreamAndWaitDone); + + REG_HIDDEN_FUNC(dmuxPamfNotifyDemuxDone); + REG_HIDDEN_FUNC(dmuxPamfNotifyProgEndCode); + REG_HIDDEN_FUNC(dmuxPamfNotifyFatalErr); + REG_HIDDEN_FUNC(dmuxPamfEsNotifyAuFound); + REG_HIDDEN_FUNC(dmuxPamfEsNotifyFlushDone); + + REG_HIDDEN_FUNC(dmuxPamfEntry); }); diff --git a/rpcs3/Emu/Cell/Modules/cellDmuxPamf.h b/rpcs3/Emu/Cell/Modules/cellDmuxPamf.h index c720fb89c5..dea9fef073 100644 --- a/rpcs3/Emu/Cell/Modules/cellDmuxPamf.h +++ b/rpcs3/Emu/Cell/Modules/cellDmuxPamf.h @@ -661,16 +661,376 @@ using dmux_pamf_spu_thread = named_thread; // PPU thread -struct CellDmuxPamfAttr +// For some reason, cellDmuxPamf doesn't use regular error code values and also has a second set of error codes that's only used internally +enum CellDmuxPamfError { - be_t maxEnabledEsNum; - be_t version; + CELL_DMUX_PAMF_ERROR_BUSY = 1, + CELL_DMUX_PAMF_ERROR_ARG = 2, + CELL_DMUX_PAMF_ERROR_UNKNOWN_STREAM = 3, + CELL_DMUX_PAMF_ERROR_NO_MEMORY = 5, + CELL_DMUX_PAMF_ERROR_FATAL = 6, +}; + +enum CellDmuxPamfM2vLevel +{ + CELL_DMUX_PAMF_M2V_MP_LL = 0, + CELL_DMUX_PAMF_M2V_MP_ML, + CELL_DMUX_PAMF_M2V_MP_H14, + CELL_DMUX_PAMF_M2V_MP_HL, +}; + +enum CellDmuxPamfAvcLevel +{ + CELL_DMUX_PAMF_AVC_LEVEL_2P1 = 21, + CELL_DMUX_PAMF_AVC_LEVEL_3P0 = 30, + CELL_DMUX_PAMF_AVC_LEVEL_3P1 = 31, + CELL_DMUX_PAMF_AVC_LEVEL_3P2 = 32, + CELL_DMUX_PAMF_AVC_LEVEL_4P1 = 41, + CELL_DMUX_PAMF_AVC_LEVEL_4P2 = 42, +}; + +struct CellDmuxPamfAuSpecificInfoM2v +{ + be_t reserved1; +}; + +struct CellDmuxPamfAuSpecificInfoAvc +{ + be_t reserved1; +}; + +struct CellDmuxPamfAuSpecificInfoLpcm +{ + u8 channelAssignmentInfo; + u8 samplingFreqInfo; + u8 bitsPerSample; +}; + +struct CellDmuxPamfAuSpecificInfoAc3 +{ + be_t reserved1; +}; + +struct CellDmuxPamfAuSpecificInfoAtrac3plus +{ + be_t reserved1; +}; + +struct CellDmuxPamfAuSpecificInfoUserData +{ + be_t reserved1; +}; + +struct CellDmuxPamfEsSpecificInfoM2v +{ + be_t profileLevel; +}; + +struct CellDmuxPamfEsSpecificInfoAvc +{ + be_t level; +}; + +struct CellDmuxPamfEsSpecificInfoLpcm +{ + be_t samplingFreq; + be_t numOfChannels; + be_t bitsPerSample; +}; + +struct CellDmuxPamfEsSpecificInfoAc3 +{ + be_t reserved1; +}; + +struct CellDmuxPamfEsSpecificInfoAtrac3plus +{ + be_t reserved1; +}; + +struct CellDmuxPamfEsSpecificInfoUserData +{ + be_t reserved1; +}; + +enum CellDmuxPamfSamplingFrequency +{ + CELL_DMUX_PAMF_FS_48K = 48000, +}; + +enum CellDmuxPamfBitsPerSample +{ + CELL_DMUX_PAMF_BITS_PER_SAMPLE_16 = 16, + CELL_DMUX_PAMF_BITS_PER_SAMPLE_24 = 24, +}; + +enum CellDmuxPamfLpcmChannelAssignmentInfo +{ + CELL_DMUX_PAMF_LPCM_CH_M1 = 1, + CELL_DMUX_PAMF_LPCM_CH_LR = 3, + CELL_DMUX_PAMF_LPCM_CH_LRCLSRSLFE = 9, + CELL_DMUX_PAMF_LPCM_CH_LRCLSCS1CS2RSLFE = 11, +}; + +enum CellDmuxPamfLpcmFs +{ + CELL_DMUX_PAMF_LPCM_FS_48K = 1, +}; + +enum CellDmuxPamfLpcmBitsPerSamples +{ + CELL_DMUX_PAMF_LPCM_BITS_PER_SAMPLE_16 = 1, + CELL_DMUX_PAMF_LPCM_BITS_PER_SAMPLE_24 = 3, +}; + +struct CellDmuxPamfSpecificInfo +{ + be_t thisSize; + b8 programEndCodeCb; +}; + +struct CellDmuxPamfResource +{ + be_t ppuThreadPriority; + be_t ppuThreadStackSize; + be_t numOfSpus; + be_t spuThreadPriority; + vm::bptr memAddr; be_t memSize; }; -struct CellDmuxPamfEsAttr +struct DmuxPamfAuInfo { - be_t auQueueMaxSize; - be_t memSize; - be_t specificInfoSize; + vm::bptr addr; + be_t size; + CellCodecTimeStamp pts; + CellCodecTimeStamp dts; + be_t user_data; + vm::bptr specific_info; + be_t specific_info_size; + b8 is_rap; }; + +CHECK_SIZE(DmuxPamfAuInfo, 0x30); + +constexpr u32 DMUX_PAMF_VERSION = 0x280000; +constexpr s32 DMUX_PAMF_MAX_ENABLED_ES_NUM = 0x40; + +// HLE exclusive, for savestates +enum class dmux_pamf_state : u8 +{ + initial, + waiting_for_au_released, + waiting_for_au_released_error, + waiting_for_event, + starting_demux_done, + starting_demux_done_mutex_lock_error, + starting_demux_done_mutex_unlock_error, + starting_demux_done_checking_stream_reset, + starting_demux_done_checking_stream_reset_error, + setting_au_reset, + setting_au_reset_error, + processing_event, + au_found_waiting_for_spu, + unsetting_au_cancel, + demux_done_notifying, + demux_done_mutex_lock, + demux_done_cond_signal, + resuming_demux_mutex_lock, + resuming_demux_waiting_for_spu, + sending_fatal_err +}; + +enum class DmuxPamfSequenceState : u32 +{ + dormant, + resetting, + running +}; + +struct DmuxPamfElementaryStream; + +class DmuxPamfContext +{ + // HLE exclusive + // These are local variables in the PPU thread function, they're here for savestates + DmuxPamfEvent event; + u64 au_queue_full_bitset; + b8 stream_reset_started; + b8 stream_reset_in_progress; + + u32 hle_spu_thread_id; + dmux_pamf_state savestate; + + [[maybe_unused]] u8 spurs[0xf6b]; // CellSpurs, 0x1000 bytes on LLE + [[maybe_unused]] vm::bptr spurs_addr; // CellSpurs* + [[maybe_unused]] b8 use_existing_spurs; + + [[maybe_unused]] alignas(0x80) u8 spurs_taskset[0x1900]; // CellSpursTaskset + [[maybe_unused]] be_t spurs_task_id; // CellSpursTaskId + vm::bptr spurs_context_addr; + + [[maybe_unused]] u8 reserved1[0x10]; + + vm::bptr _this; + be_t this_size; + be_t version; + + DmuxCb notify_demux_done; + DmuxCb notify_prog_end_code; + DmuxCb notify_fatal_err; + + CellDmuxPamfResource resource; + + be_t thread_id; // sys_ppu_thread_t + + be_t unk; // Unused + + be_t ppu_thread_stack_size; + + be_t au_released_bitset; // Each bit corresponds to an elementary stream, if a bit is set then cellDmuxReleaseAu() was called for that elementary stream + + b8 stream_reset_requested; + + be_t sequence_state; + + be_t max_enabled_es_num; + be_t enabled_es_num; + vm::bptr elementary_streams[DMUX_PAMF_MAX_ENABLED_ES_NUM]; + + be_t mutex; // sys_mutex_t + be_t cond; // sys_cond_t + + vm::bptr> cmd_queue_addr_; // Same as cmd_queue_addr, unused + vm::bptr cmd_queue_buffer_addr_; // Same as cmd_queue_buffer_addr, unused + + vm::bptr> cmd_queue_addr; // CellSpursQueue* + vm::bptr, 1>> cmd_result_queue_addr; // CellSpursQueue* + vm::bptr> stream_info_queue_addr; // CellSpursQueue* + vm::bptr> event_queue_addr; // CellSpursQueue* + + vm::bptr cmd_queue_buffer_addr; + vm::bptr[1]> cmd_result_queue_buffer_addr; + vm::bptr event_queue_buffer_addr; + vm::bptr stream_info_queue_buffer_addr; + + vm::bptr> cmd_queue_addr__; // Same as cmd_queue_addr, unused + + be_t user_data; + + b8 is_raw_es; + + be_t next_es_id; + + char spurs_taskset_name[24]; + + [[maybe_unused]] u8 reserved2[928]; // Unused + + dmux_pamf_hle_spurs_queue cmd_queue; // CellSpursQueue + dmux_pamf_hle_spurs_queue, 1> cmd_result_queue; // CellSpursQueue + dmux_pamf_hle_spurs_queue stream_info_queue; // CellSpursQueue + dmux_pamf_hle_spurs_queue event_queue; // CellSpursQueue + + DmuxPamfCommand cmd_queue_buffer[1]; + alignas(0x80) be_t cmd_result_queue_buffer[1]; + DmuxPamfStreamInfo stream_info_queue_buffer[1]; + DmuxPamfEvent event_queue_buffer[4 + 2 * DMUX_PAMF_MAX_ENABLED_ES_NUM]; + + alignas(0x80) u8 spurs_context[0x36400]; + + + template + void send_spu_command_and_wait(ppu_thread& ppu, bool waiting_for_spu_state, auto&&... cmd_params); + + error_code wait_au_released_or_stream_reset(ppu_thread& ppu, u64 au_queue_full_bitset, b8& stream_reset_started, dmux_pamf_state& savestate); + + template + error_code set_au_reset(ppu_thread& ppu); + + template + static error_code callback(ppu_thread& ppu, DmuxCb cb, auto&&... args); + + friend struct DmuxPamfElementaryStream; + +public: + void run_spu_thread(); + + DmuxPamfElementaryStream* find_es(u16 stream_id, u16 private_stream_id); + + void exec(ppu_thread& ppu); + + static error_code open(ppu_thread& ppu, const CellDmuxPamfResource& res, const DmuxCb& notify_dmux_done, const DmuxCb& notify_prog_end_code, const DmuxCb& notify_fatal_err, vm::bptr& handle); + error_code create_thread(ppu_thread& ppu); + error_code close(ppu_thread& ppu); + error_code reset_stream(ppu_thread& ppu); + error_code join_thread(ppu_thread& ppu); + + template + error_code set_stream(ppu_thread& ppu, vm::cptr stream_address, u32 stream_size, b8 discontinuity, u32 user_data); + + template + error_code enable_es(ppu_thread& ppu, u16 stream_id, u16 private_stream_id, bool is_avc, vm::cptr es_specific_info, vm::ptr mem_addr, u32 mem_size, const DmuxCb& notify_au_found, + const DmuxCb& notify_flush_done, vm::bptr& es); + + error_code reset_stream_and_wait_done(ppu_thread& ppu); +}; + +static_assert(std::is_standard_layout_v && std::is_trivial_v); +CHECK_SIZE_ALIGN(DmuxPamfContext, 0x3d880, 0x80); + +struct CellDmuxPamfHandle +{ + vm::bptr demuxer; + + DmuxCb notify_demux_done; + DmuxCb notify_prog_end_code; + DmuxCb notify_fatal_err; +}; + +CHECK_SIZE(CellDmuxPamfHandle, 0x1c); + +struct DmuxPamfElementaryStream +{ + vm::bptr _this; + be_t this_size; + u8 this_index; + + vm::bptr demuxer; + + DmuxCb notify_au_found; + DmuxCb notify_flush_done; + + be_t stream_id; + be_t private_stream_id; + b8 is_avc; + + vm::bptr au_queue_buffer; + be_t unk; // Likely au_queue_buffer_size, unused + be_t au_max_size; + u8 au_specific_info[0x10]; + be_t au_specific_info_size; + + b8 reset_next_au; + + be_t es_id; + + u8 reserved[72]; + + error_code release_au(ppu_thread& ppu, vm::ptr au_addr, u32 au_size) const; + error_code disable_es(ppu_thread& ppu); + error_code flush_es(ppu_thread& ppu) const; + error_code reset_es(ppu_thread& ppu) const; +}; + +static_assert(std::is_standard_layout_v && std::is_trivial_v); +CHECK_SIZE_ALIGN(DmuxPamfElementaryStream, 0x98, 4); + +struct CellDmuxPamfEsHandle +{ + vm::bptr es; + + DmuxCb notify_au_found; + DmuxCb notify_flush_done; +}; + +CHECK_SIZE(CellDmuxPamfEsHandle, 0x14); diff --git a/rpcs3/Emu/Cell/lv2/sys_prx.cpp b/rpcs3/Emu/Cell/lv2/sys_prx.cpp index f20b6be6cb..f46f3bdafa 100644 --- a/rpcs3/Emu/Cell/lv2/sys_prx.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_prx.cpp @@ -64,7 +64,7 @@ extern const std::map g_prx_list { "libddpdec.sprx", 0 }, { "libdivxdec.sprx", 0 }, { "libdmux.sprx", 0 }, - { "libdmuxpamf.sprx", 0 }, + { "libdmuxpamf.sprx", 1 }, { "libdtslbrdec.sprx", 0 }, { "libfiber.sprx", 0 }, { "libfont.sprx", 0 }, From f2aa3476089378da9f5b5f3d61237455f397bde6 Mon Sep 17 00:00:00 2001 From: capriots <29807355+capriots@users.noreply.github.com> Date: Sat, 27 Sep 2025 17:14:17 +0200 Subject: [PATCH 113/175] cellDmuxPamf: review fixes + improvements --- rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp | 23 ++++++++++++----------- rpcs3/Emu/Cell/Modules/cellDmuxPamf.h | 4 +++- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp b/rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp index cc2fd6af42..19d85c4fb1 100644 --- a/rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp +++ b/rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp @@ -1295,7 +1295,7 @@ void DmuxPamfContext::exec(ppu_thread& ppu) case dmux_pamf_state::setting_au_reset_error: goto label10_setting_au_reset_error_state; case dmux_pamf_state::processing_event: goto label11_processing_event_state; case dmux_pamf_state::au_found_waiting_for_spu: goto label12_au_found_waiting_for_spu_state; - case dmux_pamf_state::unsetting_au_cancel: goto label13_unsetting_au_cancel_state; + case dmux_pamf_state::unsetting_au_reset: goto label13_unsetting_au_reset_state; case dmux_pamf_state::demux_done_notifying: goto label14_demux_done_notifying_state; case dmux_pamf_state::demux_done_mutex_lock: goto label15_demux_done_mutex_lock_state; case dmux_pamf_state::demux_done_cond_signal: goto label16_demux_done_cond_signal_state; @@ -1477,14 +1477,11 @@ void DmuxPamfContext::exec(ppu_thread& ppu) au_info->specific_info_size = es->au_specific_info_size; au_info->is_rap = static_cast(event.au_found.is_rap); - if (!is_raw_es) + if (!is_raw_es && dmuxPamfStreamIdToTypeChannel(event.au_found.stream_id, event.au_found.private_stream_id).first == DMUX_PAMF_STREAM_TYPE_INDEX_LPCM) { - if (dmuxPamfStreamIdToTypeChannel(event.au_found.stream_id, event.au_found.private_stream_id).first == DMUX_PAMF_STREAM_TYPE_INDEX_LPCM) - { - es->au_specific_info[0] = read_from_ptr(event.au_found.stream_header_buf) >> 4; - es->au_specific_info[1] = read_from_ptr(event.au_found.stream_header_buf) & 0xf; - es->au_specific_info[2] = read_from_ptr(&event.au_found.stream_header_buf[1]) >> 6; - } + es->au_specific_info[0] = read_from_ptr(event.au_found.stream_header_buf) >> 4; + es->au_specific_info[1] = read_from_ptr(event.au_found.stream_header_buf) & 0xf; + es->au_specific_info[2] = read_from_ptr(&event.au_found.stream_header_buf[1]) >> 6; } if (sys_mutex_unlock(ppu, mutex) != CELL_OK) @@ -1509,8 +1506,8 @@ void DmuxPamfContext::exec(ppu_thread& ppu) { stream_reset_in_progress = false; - savestate = dmux_pamf_state::unsetting_au_cancel; - label13_unsetting_au_cancel_state: + savestate = dmux_pamf_state::unsetting_au_reset; + label13_unsetting_au_reset_state: if (set_au_reset(ppu) != CELL_OK) { @@ -1763,7 +1760,7 @@ u32 dmuxPamfGetAuQueueMaxSize(u16 stream_id, u16 private_stream_id) u32 dmuxPamfGetLpcmAuSize(vm::cptr lpcm_info) { - return lpcm_info->samplingFreq * lpcm_info->bitsPerSample * (lpcm_info->numOfChannels + (lpcm_info->numOfChannels & 1)) / 1600; // Streams with an odd number of channels contain an empty dummy channel + return lpcm_info->samplingFreq * lpcm_info->bitsPerSample / CHAR_BIT * (lpcm_info->numOfChannels + (lpcm_info->numOfChannels & 1)) / DMUX_PAMF_LPCM_FRAMES_PER_SEC; // Streams with an odd number of channels contain an empty dummy channel } u32 dmuxPamfGetAuQueueBufferSize(u16 stream_id, u16 private_stream_id, bool is_avc, vm::cptr es_specific_info) @@ -2014,6 +2011,8 @@ error_code _CellDmuxCoreOpOpen(ppu_thread& ppu, vm::cptrmemAddr.aligned(0x10)); // Not checked on LLE + ensure(demuxerResource->memSize >= sizeof(CellDmuxPamfHandle)); // Not checked on LLE + ensure(vm::check_addr(demuxerResource->memAddr.addr(), vm::page_readable | vm::page_writable, demuxerResource->memSize)); const auto _handle = vm::static_ptr_cast(demuxerResource->memAddr); @@ -2547,6 +2546,8 @@ error_code _CellDmuxCoreOpEnableEs(ppu_thread& ppu, vm::ptr } ensure(!!esHandle && esResource->memAddr.aligned(0x10)); // Not checked on LLE + ensure(esResource->memSize >= sizeof(CellDmuxPamfEsHandle)); // Not checked on LLE + ensure(vm::check_addr(esResource->memAddr.addr(), vm::page_readable | vm::page_writable, esResource->memSize)); const auto es_handle = vm::static_ptr_cast(esResource->memAddr); diff --git a/rpcs3/Emu/Cell/Modules/cellDmuxPamf.h b/rpcs3/Emu/Cell/Modules/cellDmuxPamf.h index dea9fef073..e04b618785 100644 --- a/rpcs3/Emu/Cell/Modules/cellDmuxPamf.h +++ b/rpcs3/Emu/Cell/Modules/cellDmuxPamf.h @@ -783,6 +783,8 @@ enum CellDmuxPamfLpcmBitsPerSamples CELL_DMUX_PAMF_LPCM_BITS_PER_SAMPLE_24 = 3, }; +constexpr u8 DMUX_PAMF_LPCM_FRAMES_PER_SEC = 200; + struct CellDmuxPamfSpecificInfo { be_t thisSize; @@ -832,7 +834,7 @@ enum class dmux_pamf_state : u8 setting_au_reset_error, processing_event, au_found_waiting_for_spu, - unsetting_au_cancel, + unsetting_au_reset, demux_done_notifying, demux_done_mutex_lock, demux_done_cond_signal, From 4d6da6542e48eaaaef136c94364ccf8df51ba798 Mon Sep 17 00:00:00 2001 From: capriots <29807355+capriots@users.noreply.github.com> Date: Sat, 21 Feb 2026 22:16:39 +0100 Subject: [PATCH 114/175] tests: enable cellDmuxPamf tests in CMakeLists --- rpcs3/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rpcs3/CMakeLists.txt b/rpcs3/CMakeLists.txt index 41597127b8..2aa8120752 100644 --- a/rpcs3/CMakeLists.txt +++ b/rpcs3/CMakeLists.txt @@ -195,6 +195,7 @@ if(BUILD_RPCS3_TESTS) tests/test_address_range.cpp tests/test_rsx_cfg.cpp tests/test_rsx_fp_asm.cpp + tests/test_dmux_pamf.cpp ) target_link_libraries(rpcs3_test @@ -202,6 +203,7 @@ if(BUILD_RPCS3_TESTS) rpcs3_lib rpcs3_emu GTest::gtest + GTest::gmock ) target_include_directories(rpcs3_test From 3616424b26cae2b06081b0f11dc449555cf42c04 Mon Sep 17 00:00:00 2001 From: capriots <29807355+capriots@users.noreply.github.com> Date: Sat, 21 Feb 2026 22:22:21 +0100 Subject: [PATCH 115/175] cellDmuxPamf: fix lv2 mutex + cond not being destroyed on close --- rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp b/rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp index 19d85c4fb1..7281b0edf9 100644 --- a/rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp +++ b/rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp @@ -2048,6 +2048,12 @@ error_code DmuxPamfContext::close(ppu_thread& ppu) ensure(idm::remove(hle_spu_thread_id)); + if (sys_cond_destroy(ppu, cond) != CELL_OK + || sys_mutex_destroy(ppu, mutex) != CELL_OK) + { + return CELL_DMUX_PAMF_ERROR_FATAL; + } + return CELL_OK; } From b839d4d1a6de3e21605ea6f25d53c79a4c031b65 Mon Sep 17 00:00:00 2001 From: capriots <29807355+capriots@users.noreply.github.com> Date: Sat, 21 Feb 2026 22:28:10 +0100 Subject: [PATCH 116/175] cellDmuxPamf: consume guest memory on SPU thread group creation --- rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp | 19 ++++++++++++++++--- rpcs3/Emu/Cell/Modules/cellDmuxPamf.h | 3 ++- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp b/rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp index 7281b0edf9..ba621ac3bd 100644 --- a/rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp +++ b/rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp @@ -1,6 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" #include "Emu/Cell/lv2/sys_cond.h" +#include "Emu/Cell/lv2/sys_memory.h" #include "Emu/Cell/lv2/sys_mutex.h" #include "Emu/Cell/lv2/sys_ppu_thread.h" #include "Emu/Cell/lv2/sys_sync.h" @@ -1916,8 +1917,8 @@ error_code _CellDmuxCoreOpQueryAttr(vm::cptr pamfSpeci return CELL_OK; } -error_code DmuxPamfContext::open(ppu_thread& ppu, const CellDmuxPamfResource& res, const DmuxCb& notify_dmux_done, const DmuxCb& notify_prog_end_code, - const DmuxCb& notify_fatal_err, vm::bptr& handle) +error_code DmuxPamfContext::open(ppu_thread& ppu, const CellDmuxPamfResource& res, vm::cptr res_spurs, const DmuxCb& notify_dmux_done, + const DmuxCb& notify_prog_end_code, const DmuxCb& notify_fatal_err, vm::bptr& handle) { if (res.ppuThreadPriority >= 0xc00u || res.ppuThreadStackSize < 0x1000u || res.spuThreadPriority >= 0x100u || res.numOfSpus != 1u || !res.memAddr || res.memSize < sizeof(DmuxPamfContext) + 0xe7b) { @@ -1967,6 +1968,13 @@ error_code DmuxPamfContext::open(ppu_thread& ppu, const CellDmuxPamfResource& re ensure(std::snprintf(_this->spurs_taskset_name, sizeof(_this->spurs_taskset_name), "_libdmux_pamf_%08x", _this.addr()) == 22); + _this->use_existing_spurs = !!res_spurs; + + if (!res_spurs && g_fxo->get().take(0x40000) != 0x40000) + { + return CELL_DMUX_PAMF_ERROR_FATAL; + } + _this->cmd_queue.init(_this->cmd_queue_buffer); _this->cmd_result_queue.init(_this->cmd_result_queue_buffer); _this->stream_info_queue.init(_this->stream_info_queue_buffer); @@ -2032,7 +2040,7 @@ error_code _CellDmuxCoreOpOpen(ppu_thread& ppu, vm::cptr::make(g_fxo->get().func_addr(FIND_FUNC(dmuxPamfNotifyProgEndCode))); const auto fatal_err_func = vm::bptr::make(g_fxo->get().func_addr(FIND_FUNC(dmuxPamfNotifyFatalErr))); - const error_code ret = DmuxPamfContext::open(ppu, res, { demux_done_func, _handle }, { prog_end_code_func, _handle }, { fatal_err_func, _handle }, _handle->demuxer); + const error_code ret = DmuxPamfContext::open(ppu, res, demuxerResourceSpurs, { demux_done_func, _handle }, { prog_end_code_func, _handle }, { fatal_err_func, _handle }, _handle->demuxer); *handle = _handle; @@ -2048,6 +2056,11 @@ error_code DmuxPamfContext::close(ppu_thread& ppu) ensure(idm::remove(hle_spu_thread_id)); + if (!use_existing_spurs) + { + g_fxo->get().free(0x40000); + } + if (sys_cond_destroy(ppu, cond) != CELL_OK || sys_mutex_destroy(ppu, mutex) != CELL_OK) { diff --git a/rpcs3/Emu/Cell/Modules/cellDmuxPamf.h b/rpcs3/Emu/Cell/Modules/cellDmuxPamf.h index e04b618785..5b42103ca7 100644 --- a/rpcs3/Emu/Cell/Modules/cellDmuxPamf.h +++ b/rpcs3/Emu/Cell/Modules/cellDmuxPamf.h @@ -961,7 +961,8 @@ public: void exec(ppu_thread& ppu); - static error_code open(ppu_thread& ppu, const CellDmuxPamfResource& res, const DmuxCb& notify_dmux_done, const DmuxCb& notify_prog_end_code, const DmuxCb& notify_fatal_err, vm::bptr& handle); + static error_code open(ppu_thread& ppu, const CellDmuxPamfResource& res, vm::cptr res_spurs, const DmuxCb& notify_dmux_done, + const DmuxCb& notify_prog_end_code, const DmuxCb& notify_fatal_err, vm::bptr& handle); error_code create_thread(ppu_thread& ppu); error_code close(ppu_thread& ppu); error_code reset_stream(ppu_thread& ppu); From c5f278ed37f7b3bb60ad4b020077c165e680a39c Mon Sep 17 00:00:00 2001 From: capriots <29807355+capriots@users.noreply.github.com> Date: Sat, 28 Feb 2026 10:59:44 +0100 Subject: [PATCH 117/175] cellDmuxPamf: properly handle streams smaller than 0x800 bytes --- rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp | 22 ++++++++++++++-------- rpcs3/tests/test_dmux_pamf.cpp | 8 ++++++++ 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp b/rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp index ba621ac3bd..99234de01e 100644 --- a/rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp +++ b/rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp @@ -671,19 +671,19 @@ bool dmux_pamf_base::process_next_pack() case state::initial: { // Search for the next pack start code or prog end code - std::span pack{ static_cast(nullptr), PACK_SIZE }; // This initial value is not used, can't be default constructed + std::span pack; for (;;) { - if (stream->empty()) + if (stream->size() < PACK_STUFFING_LENGTH_OFFSET + sizeof(u8)) { stream.reset(); demux_done_notified = on_demux_done(); return true; } - pack = stream->subspan<0, PACK_SIZE>(); - stream = stream->subspan(); + pack = stream->first(std::min(stream->size(), PACK_SIZE)); + stream = stream->subspan(std::min(stream->size(), PACK_SIZE)); // If the input stream is a raw elementary stream, skip everything MPEG-PS related and go straight to elementary stream parsing if (raw_es) @@ -719,6 +719,14 @@ bool dmux_pamf_base::process_next_pack() // Skip over pack header const u8 pack_stuffing_length = read_from_ptr(pack.subspan()) & 0x7; + + // Not checked on LLE, the SPU task would just increment the reading position and read random data in the SPU local store + if (PACK_STUFFING_LENGTH_OFFSET + sizeof(u8) + pack_stuffing_length + PES_HEADER_DATA_LENGTH_OFFSET + sizeof(u8) > pack.size()) + { + cellDmuxPamf.error("Invalid pack stuffing length"); + return false; + } + std::span current_pes_packet = pack.subspan(PACK_STUFFING_LENGTH_OFFSET + sizeof(u8) + pack_stuffing_length); if (read_from_ptr>(current_pes_packet) >> 8 != PACKET_START_CODE_PREFIX) @@ -785,10 +793,8 @@ bool dmux_pamf_base::process_next_pack() return false; } - // The size of the stream is not checked here because if coming from a pack header, it is guaranteed that there is enough space, - // and if coming from a system header or private stream 2, it was already checked above - const u16 pes_packet_length = read_from_ptr>(current_pes_packet.begin() + PES_PACKET_LENGTH_OFFSET) + PES_PACKET_LENGTH_OFFSET + sizeof(u16); - const u8 pes_header_data_length = read_from_ptr(current_pes_packet.begin() + PES_HEADER_DATA_LENGTH_OFFSET) + PES_HEADER_DATA_LENGTH_OFFSET + sizeof(u8); + const u16 pes_packet_length = read_from_ptr>(current_pes_packet.begin(), PES_PACKET_LENGTH_OFFSET) + PES_PACKET_LENGTH_OFFSET + sizeof(u16); + const u8 pes_header_data_length = read_from_ptr(current_pes_packet.begin(), PES_HEADER_DATA_LENGTH_OFFSET) + PES_HEADER_DATA_LENGTH_OFFSET + sizeof(u8); // Not checked on LLE, the SPU task would just increment the reading position and read random data in the SPU local store if (pes_packet_length > current_pes_packet.size() || pes_packet_length <= pes_header_data_length) diff --git a/rpcs3/tests/test_dmux_pamf.cpp b/rpcs3/tests/test_dmux_pamf.cpp index 40a8a02b32..b6fdbf73b4 100644 --- a/rpcs3/tests/test_dmux_pamf.cpp +++ b/rpcs3/tests/test_dmux_pamf.cpp @@ -228,6 +228,14 @@ INSTANTIATE_TEST_SUITE_P(Instance, DmuxPamfInvalidStream, Values []() consteval { auto pack = AVC_SINGLE_PACK_STREAM; pack[0x118] = 0x00; pack[0x119] = 0x03; pack[0x11c] = 0x00; return pack; }() // PES packet header size too large )); +// Since the "pack stuffing length" field only has a size of three bits, this can only occur if the stream is not a multiple of 0x800 bytes large. +// Like the other invalid streams above, LLE does not check for this +TEST_F(DmuxPamfTest, InvalidPackStuffingLength) +{ + demuxer.set_stream({ AVC_SINGLE_PACK_STREAM.cbegin(), AVC_SINGLE_PACK_STREAM.cbegin() + 0x16 }, false); + EXPECT_FALSE(demuxer.process_next_pack()); +} + // Tests if the program end code is properly detected and the corresponding event is fired TEST_F(DmuxPamfTest, ProgEnd) { From 4828d4d2d6128afad95998ce5056e27c3eda3028 Mon Sep 17 00:00:00 2001 From: capriots <29807355+capriots@users.noreply.github.com> Date: Sat, 28 Feb 2026 16:33:08 +0100 Subject: [PATCH 118/175] cellDmuxPamf: review fixes --- rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp | 97 ++++++++++++++----------- 1 file changed, 53 insertions(+), 44 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp b/rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp index 99234de01e..f8fd42f4a4 100644 --- a/rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp +++ b/rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp @@ -308,7 +308,7 @@ u32 dmux_pamf_base::video_stream::parse_stream(std::span stream) // Search for delimiter in cache for (; cache_idx < static_cast(cache.size()); cache_idx++) { - if (const be_t code = read_from_ptr>(buf.data() + cache_idx); + if (const be_t code = read_from_ptr>(buf.data(), cache_idx); (avc && code == AVC_AU_DELIMITER) || (!avc && (code == M2V_PIC_START || code == M2V_SEQUENCE_HEADER || code == M2V_SEQUENCE_END))) { if (current_au.state != access_unit::state::none && (avc || current_au.state != access_unit::state::m2v_sequence)) @@ -438,7 +438,7 @@ u32 dmux_pamf_base::audio_stream::parse_stream(std::span stream) // Search for delimiter in cache for (; cache_idx <= static_cast(cache.size() + std::min(sizeof(u16) - 1, stream.size()) - sizeof(u16)); cache_idx++) { - if (const be_t tmp = read_from_ptr>(buf.data() + cache_idx); current_au.size_info_offset != 0) + if (const be_t tmp = read_from_ptr>(buf.data(), cache_idx); current_au.size_info_offset != 0) { if (--current_au.size_info_offset == 0) { @@ -521,7 +521,7 @@ u32 dmux_pamf_base::user_data_stream::parse_stream_header(std::span pe return umax; } - au_size_unk = read_from_ptr>(pes_packet_data.begin() + 2) - sizeof(u32); + au_size_unk = read_from_ptr>(pes_packet_data.begin(), 2) - sizeof(u32); return 10; } @@ -718,7 +718,7 @@ bool dmux_pamf_base::process_next_pack() } // Skip over pack header - const u8 pack_stuffing_length = read_from_ptr(pack.subspan()) & 0x7; + const u8 pack_stuffing_length = read_from_ptr>(pack, PACK_STUFFING_LENGTH_OFFSET); // Not checked on LLE, the SPU task would just increment the reading position and read random data in the SPU local store if (PACK_STUFFING_LENGTH_OFFSET + sizeof(u8) + pack_stuffing_length + PES_HEADER_DATA_LENGTH_OFFSET + sizeof(u8) > pack.size()) @@ -729,7 +729,7 @@ bool dmux_pamf_base::process_next_pack() std::span current_pes_packet = pack.subspan(PACK_STUFFING_LENGTH_OFFSET + sizeof(u8) + pack_stuffing_length); - if (read_from_ptr>(current_pes_packet) >> 8 != PACKET_START_CODE_PREFIX) + if (read_from_ptr, 8, 24>>(current_pes_packet) != PACKET_START_CODE_PREFIX) { cellDmuxPamf.error("Invalid start code after pack header"); return false; @@ -738,7 +738,7 @@ bool dmux_pamf_base::process_next_pack() // Skip over system header if present if (read_from_ptr>(current_pes_packet) == SYSTEM_HEADER) { - const u32 system_header_length = read_from_ptr>(current_pes_packet.begin() + PES_PACKET_LENGTH_OFFSET) + PES_PACKET_LENGTH_OFFSET + sizeof(u16); + const u32 system_header_length = read_from_ptr>(current_pes_packet.begin(), PES_PACKET_LENGTH_OFFSET) + PES_PACKET_LENGTH_OFFSET + sizeof(u16); // Not checked on LLE, the SPU task would just increment the reading position and read random data in the SPU local store if (system_header_length + PES_HEADER_DATA_LENGTH_OFFSET + sizeof(u8) > current_pes_packet.size()) @@ -763,7 +763,7 @@ bool dmux_pamf_base::process_next_pack() // A system header is optionally followed by a private stream 2 // The first two bytes of the stream are the stream id of a video stream. The next access unit of that stream is a random access point/keyframe - const u16 pes_packet_length = read_from_ptr>(current_pes_packet.begin() + PES_PACKET_LENGTH_OFFSET) + PES_PACKET_LENGTH_OFFSET + sizeof(u16); + const u16 pes_packet_length = read_from_ptr>(current_pes_packet.begin(), PES_PACKET_LENGTH_OFFSET) + PES_PACKET_LENGTH_OFFSET + sizeof(u16); // Not checked on LLE, the SPU task would just increment the reading position and read random data in the SPU local store if (pes_packet_length + PES_HEADER_DATA_LENGTH_OFFSET + sizeof(u8) > current_pes_packet.size()) @@ -772,7 +772,7 @@ bool dmux_pamf_base::process_next_pack() return false; } - if (const u8 channel = read_from_ptr>(current_pes_packet.begin() + PES_PACKET_LENGTH_OFFSET + sizeof(u16)) & 0xf; + if (const u8 channel = read_from_ptr>(current_pes_packet.begin(), PES_PACKET_LENGTH_OFFSET + sizeof(u16)) & 0xf; elementary_stream::is_enabled(elementary_streams[0][channel])) { elementary_streams[0][channel]->set_rap(); @@ -818,23 +818,23 @@ bool dmux_pamf_base::process_next_pack() if (elementary_stream::is_enabled(elementary_streams[type_idx][channel])) { - const s8 pts_dts_flag = read_from_ptr(current_pes_packet.begin() + PTS_DTS_FLAG_OFFSET); + const s8 pts_dts_flag = read_from_ptr(current_pes_packet.begin(), PTS_DTS_FLAG_OFFSET); if (pts_dts_flag < 0) { // The timestamps should be unsigned, but are sign-extended from s32 to u64 on LLE. They probably forgot about integer promotion - const s32 PTS_32_30 = read_from_ptr(current_pes_packet.begin() + 9) >> 1; - const s32 PTS_29_15 = read_from_ptr>(current_pes_packet.begin() + 10) >> 1; - const s32 PTS_14_0 = read_from_ptr>(current_pes_packet.begin() + 12) >> 1; + const s32 PTS_32_30 = read_from_ptr>(current_pes_packet.begin(), 9); + const s32 PTS_29_15 = read_from_ptr, 1, 15>>(current_pes_packet.begin(), 10); + const s32 PTS_14_0 = read_from_ptr, 1, 15>>(current_pes_packet.begin(), 12); elementary_streams[type_idx][channel]->set_pts(PTS_32_30 << 30 | PTS_29_15 << 15 | PTS_14_0); // Bit 32 is discarded } if (pts_dts_flag & 0x40) { - const s32 DTS_32_30 = read_from_ptr(current_pes_packet.begin() + 14) >> 1; - const s32 DTS_29_15 = read_from_ptr>(current_pes_packet.begin() + 15) >> 1; - const s32 DTS_14_0 = read_from_ptr>(current_pes_packet.begin() + 17) >> 1; + const s32 DTS_32_30 = read_from_ptr>(current_pes_packet.begin(), 14); + const s32 DTS_29_15 = read_from_ptr, 1, 15>>(current_pes_packet.begin(), 15); + const s32 DTS_14_0 = read_from_ptr, 1, 15>>(current_pes_packet.begin(), 17); elementary_streams[type_idx][channel]->set_dts(DTS_32_30 << 30 | DTS_29_15 << 15 | DTS_14_0); // Bit 32 is discarded } @@ -1273,16 +1273,7 @@ void DmuxPamfContext::run_spu_thread() void DmuxPamfContext::exec(ppu_thread& ppu) { - // These are repeated a lot in this function, in my opinion using defines here makes it more readable -#define SEND_FATAL_ERR_AND_CONTINUE()\ - savestate = dmux_pamf_state::sending_fatal_err;\ - callback(ppu, notify_fatal_err, _this, CELL_OK); /* LLE uses CELL_OK as error code */\ - if (ppu.state & cpu_flag::again)\ - {\ - return;\ - }\ - continue - + // This is repeated a lot in this function, in my opinion using a define here makes it more readable #define RETURN_ON_CPU_FLAG_AGAIN()\ if (ppu.state & cpu_flag::again)\ return @@ -1308,13 +1299,17 @@ void DmuxPamfContext::exec(ppu_thread& ppu) case dmux_pamf_state::demux_done_cond_signal: goto label16_demux_done_cond_signal_state; case dmux_pamf_state::resuming_demux_mutex_lock: goto label17_resuming_demux_mutex_lock_state; case dmux_pamf_state::resuming_demux_waiting_for_spu: goto label18_resuming_demux_waiting_for_spu_state; - case dmux_pamf_state::sending_fatal_err: - callback(ppu, notify_fatal_err, _this, CELL_OK); - RETURN_ON_CPU_FLAG_AGAIN(); + case dmux_pamf_state::sending_fatal_err: ; // Handled below } for (;;) { + if (savestate == dmux_pamf_state::sending_fatal_err) + { + callback(ppu, notify_fatal_err, _this, CELL_OK); + RETURN_ON_CPU_FLAG_AGAIN(); + } + savestate = dmux_pamf_state::initial; stream_reset_started = false; @@ -1427,7 +1422,8 @@ void DmuxPamfContext::exec(ppu_thread& ppu) { if (sys_mutex_lock(ppu, mutex, 0) != CELL_OK) { - SEND_FATAL_ERR_AND_CONTINUE(); + savestate = dmux_pamf_state::sending_fatal_err; + continue; } RETURN_ON_CPU_FLAG_AGAIN(); @@ -1441,7 +1437,8 @@ void DmuxPamfContext::exec(ppu_thread& ppu) { if (sys_mutex_unlock(ppu, mutex) != CELL_OK) { - SEND_FATAL_ERR_AND_CONTINUE(); + savestate = dmux_pamf_state::sending_fatal_err; + continue; } break; @@ -1468,7 +1465,8 @@ void DmuxPamfContext::exec(ppu_thread& ppu) if (sys_mutex_unlock(ppu, mutex) != CELL_OK) { - SEND_FATAL_ERR_AND_CONTINUE(); + savestate = dmux_pamf_state::sending_fatal_err; + continue; } break; @@ -1486,14 +1484,15 @@ void DmuxPamfContext::exec(ppu_thread& ppu) if (!is_raw_es && dmuxPamfStreamIdToTypeChannel(event.au_found.stream_id, event.au_found.private_stream_id).first == DMUX_PAMF_STREAM_TYPE_INDEX_LPCM) { - es->au_specific_info[0] = read_from_ptr(event.au_found.stream_header_buf) >> 4; - es->au_specific_info[1] = read_from_ptr(event.au_found.stream_header_buf) & 0xf; - es->au_specific_info[2] = read_from_ptr(&event.au_found.stream_header_buf[1]) >> 6; + es->au_specific_info[0] = read_from_ptr>(event.au_found.stream_header_buf); + es->au_specific_info[1] = read_from_ptr>(event.au_found.stream_header_buf); + es->au_specific_info[2] = read_from_ptr>(event.au_found.stream_header_buf, 1); } if (sys_mutex_unlock(ppu, mutex) != CELL_OK) { - SEND_FATAL_ERR_AND_CONTINUE(); + savestate = dmux_pamf_state::sending_fatal_err; + continue; } if (callback(ppu, es->notify_au_found, es->_this, au_info) != CELL_OK) @@ -1518,7 +1517,8 @@ void DmuxPamfContext::exec(ppu_thread& ppu) if (set_au_reset(ppu) != CELL_OK) { - SEND_FATAL_ERR_AND_CONTINUE(); + savestate = dmux_pamf_state::sending_fatal_err; + continue; } RETURN_ON_CPU_FLAG_AGAIN(); @@ -1536,7 +1536,8 @@ void DmuxPamfContext::exec(ppu_thread& ppu) if (sys_mutex_lock(ppu, mutex, 0) != CELL_OK) { - SEND_FATAL_ERR_AND_CONTINUE(); + savestate = dmux_pamf_state::sending_fatal_err; + continue; } RETURN_ON_CPU_FLAG_AGAIN(); @@ -1551,7 +1552,9 @@ void DmuxPamfContext::exec(ppu_thread& ppu) if (sys_cond_signal_all(ppu, cond) != CELL_OK) { sys_mutex_unlock(ppu, mutex); - SEND_FATAL_ERR_AND_CONTINUE(); + + savestate = dmux_pamf_state::sending_fatal_err; + continue; } RETURN_ON_CPU_FLAG_AGAIN(); @@ -1559,7 +1562,8 @@ void DmuxPamfContext::exec(ppu_thread& ppu) if (sys_mutex_unlock(ppu, mutex) != CELL_OK) { - SEND_FATAL_ERR_AND_CONTINUE(); + savestate = dmux_pamf_state::sending_fatal_err; + continue; } break; @@ -1573,7 +1577,8 @@ void DmuxPamfContext::exec(ppu_thread& ppu) { if (sys_mutex_lock(ppu, mutex, 0) != CELL_OK) { - SEND_FATAL_ERR_AND_CONTINUE(); + savestate = dmux_pamf_state::sending_fatal_err; + continue; } RETURN_ON_CPU_FLAG_AGAIN(); @@ -1583,7 +1588,8 @@ void DmuxPamfContext::exec(ppu_thread& ppu) if (sys_mutex_unlock(ppu, mutex) != CELL_OK) { - SEND_FATAL_ERR_AND_CONTINUE(); + savestate = dmux_pamf_state::sending_fatal_err; + continue; } if (valid) @@ -1607,7 +1613,8 @@ void DmuxPamfContext::exec(ppu_thread& ppu) { ensure(event_queue.pop()); - SEND_FATAL_ERR_AND_CONTINUE(); + savestate = dmux_pamf_state::sending_fatal_err; + continue; } default: fmt::throw_exception("Invalid event"); @@ -1624,7 +1631,8 @@ void DmuxPamfContext::exec(ppu_thread& ppu) if (sys_mutex_lock(ppu, mutex, 0) != CELL_OK) { - SEND_FATAL_ERR_AND_CONTINUE(); + savestate = dmux_pamf_state::sending_fatal_err; + continue; } RETURN_ON_CPU_FLAG_AGAIN(); @@ -1650,7 +1658,8 @@ void DmuxPamfContext::exec(ppu_thread& ppu) if (sys_mutex_unlock(ppu, mutex) != CELL_OK) { - SEND_FATAL_ERR_AND_CONTINUE(); + savestate = dmux_pamf_state::sending_fatal_err; + continue; } } From 2573cc5fd08a2d5e4b38768ae1c69779397d70b4 Mon Sep 17 00:00:00 2001 From: capriots <29807355+capriots@users.noreply.github.com> Date: Sat, 7 Mar 2026 16:30:38 +0100 Subject: [PATCH 119/175] cellDmuxPamf: fix stream cache not being consumed in some cases --- rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp b/rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp index f8fd42f4a4..91ee7e2426 100644 --- a/rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp +++ b/rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp @@ -354,9 +354,10 @@ u32 dmux_pamf_base::video_stream::parse_stream(std::span stream) { au_chunk.data = { au_chunk_begin, stream_it }; std::copy_n(cache.begin(), cache_idx, std::back_inserter(au_chunk.cached_data)); - cache.erase(cache.begin(), cache.begin() + cache_idx); } + cache.erase(cache.begin(), cache.begin() + cache_idx); + // Cache the end of the stream if an access unit wasn't completed. There could be the beginning of a delimiter in the last three bytes if (current_au.state != access_unit::state::complete) { @@ -499,9 +500,10 @@ u32 dmux_pamf_base::audio_stream::parse_stream(std::span stream) { au_chunk.data = { au_chunk_begin, stream_it }; std::copy_n(cache.begin(), cache_idx, std::back_inserter(au_chunk.cached_data)); - cache.erase(cache.begin(), cache.begin() + cache_idx); } + cache.erase(cache.begin(), cache.begin() + cache_idx); + // Cache the end of the stream if an access unit wasn't completed. There could be the beginning of a delimiter in the last three bytes if (current_au.state != access_unit::state::complete && current_au.state != access_unit::state::size_mismatch) { From 43b295892ff7c10316bf12f6368026731f071d49 Mon Sep 17 00:00:00 2001 From: RipleyTom Date: Fri, 6 Mar 2026 20:41:02 +0100 Subject: [PATCH 120/175] PPUAnalyzer: Fix SLDI shift operand --- rpcs3/Emu/Cell/PPUAnalyser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpcs3/Emu/Cell/PPUAnalyser.cpp b/rpcs3/Emu/Cell/PPUAnalyser.cpp index 56d4398d09..783ed9e477 100644 --- a/rpcs3/Emu/Cell/PPUAnalyser.cpp +++ b/rpcs3/Emu/Cell/PPUAnalyser.cpp @@ -2535,7 +2535,7 @@ bool ppu_module::analyse(u32 lib_toc, u32 entry, const u32 sec_end, con // SLDI mnemonic reg_state_t rs = get_reg(op.rs); - if (!rs.shift_left(op.sh32, reg_tag_allocator)) + if (!rs.shift_left(sh, reg_tag_allocator)) { unmap_reg(op.ra); } From c38bf70464f3784d3278471c9836912bb05a70e1 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Sun, 8 Mar 2026 13:54:25 +0100 Subject: [PATCH 121/175] cellCamera: improve error logging --- rpcs3/Emu/Cell/Modules/cellCamera.cpp | 10 +++++----- rpcs3/Emu/Cell/lv2/sys_gamepad.cpp | 1 - 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/cellCamera.cpp b/rpcs3/Emu/Cell/Modules/cellCamera.cpp index 096f9330f4..10f9a89cf0 100644 --- a/rpcs3/Emu/Cell/Modules/cellCamera.cpp +++ b/rpcs3/Emu/Cell/Modules/cellCamera.cpp @@ -919,7 +919,7 @@ error_code cellCameraGetAttribute(s32 dev_num, s32 attrib, vm::ptr arg1, vm if (!check_dev_num(dev_num)) { - return CELL_CAMERA_ERROR_PARAM; + return { CELL_CAMERA_ERROR_PARAM, "dev_num=%d", dev_num }; } if (g_cfg.io.camera == camera_handler::null) @@ -935,7 +935,7 @@ error_code cellCameraGetAttribute(s32 dev_num, s32 attrib, vm::ptr arg1, vm if (!arg1) { - return CELL_CAMERA_ERROR_PARAM; + return { CELL_CAMERA_ERROR_PARAM, "arg1=null" }; } if (error_code error = check_resolution(dev_num)) @@ -952,7 +952,7 @@ error_code cellCameraGetAttribute(s32 dev_num, s32 attrib, vm::ptr arg1, vm if (!attr_name) // invalid attributes don't have a name { - return CELL_CAMERA_ERROR_PARAM; + return { CELL_CAMERA_ERROR_PARAM, "attrib=0x%x", attrib }; } if (arg1) @@ -983,7 +983,7 @@ error_code cellCameraSetAttribute(s32 dev_num, s32 attrib, u32 arg1, u32 arg2) if (!check_dev_num(dev_num)) { - return CELL_CAMERA_ERROR_PARAM; + return { CELL_CAMERA_ERROR_PARAM, "dev_num=%d", dev_num }; } if (g_cfg.io.camera == camera_handler::null) @@ -1004,7 +1004,7 @@ error_code cellCameraSetAttribute(s32 dev_num, s32 attrib, u32 arg1, u32 arg2) if (!attr_name) // invalid attributes don't have a name { - return CELL_CAMERA_ERROR_PARAM; + return { CELL_CAMERA_ERROR_PARAM, "attrib=0x%x", attrib }; } g_camera.set_attr(attrib, arg1, arg2); diff --git a/rpcs3/Emu/Cell/lv2/sys_gamepad.cpp b/rpcs3/Emu/Cell/lv2/sys_gamepad.cpp index 26ffbc2696..55fd7cb885 100644 --- a/rpcs3/Emu/Cell/lv2/sys_gamepad.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_gamepad.cpp @@ -67,7 +67,6 @@ u32 sys_gamepad_ycon_is_gem(vm::ptr in, vm::ptr out) // syscall(621,packet_id,u8 *in,u8 *out) Talk:LV2_Functions_and_Syscalls#Syscall_621_.280x26D.29 gamepad_if usage u32 sys_gamepad_ycon_if(u8 packet_id, vm::ptr in, vm::ptr out) { - switch (packet_id) { case 0: From eeda9c7738b729f8ef282e831a484f9cd958c1c1 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Sun, 8 Mar 2026 13:56:49 +0100 Subject: [PATCH 122/175] cellGem: improve quaternion rotation rotate_vector caused wrong results for default_orientation and 0,0,x --- rpcs3/Emu/Io/ps_move_data.cpp | 46 +++++++++++++++++------------------ rpcs3/Emu/Io/ps_move_data.h | 23 ++++++++++++++++++ 2 files changed, 46 insertions(+), 23 deletions(-) diff --git a/rpcs3/Emu/Io/ps_move_data.cpp b/rpcs3/Emu/Io/ps_move_data.cpp index 0a167eed39..bf35f26a19 100644 --- a/rpcs3/Emu/Io/ps_move_data.cpp +++ b/rpcs3/Emu/Io/ps_move_data.cpp @@ -24,34 +24,34 @@ void ps_move_data::reset_sensors() angaccel_world = {}; } +ps_move_data::vect<3> ps_move_data::rotate_vector(const vect<4>& q, const vect<3>& v) +{ + const auto cross = [](const vect<3>& a, const vect<3>& b) + { + return vect<3>({ + a.y() * b.z() - a.z() * b.y(), + a.z() * b.x() - a.x() * b.z(), + a.x() * b.y() - a.y() * b.x() + }); + }; + + // q = (x, y, z, w) + const vect<3> q_vec({q.x(), q.y(), q.z()}); + + // t = 2 * cross(q_vec, v) + const vect<3> t = cross(q_vec, v) * 2.0f; + + // v' = v + w * t + cross(q_vec, t) + const vect<3> v_prime = v + t * q.w() + cross(q_vec, t); + + return v_prime; +} + void ps_move_data::update_orientation(f32 delta_time) { if (!delta_time) return; - // Rotate vector v by quaternion q - const auto rotate_vector = [](const vect<4>& q, const vect<3>& v) - { - const vect<4> qv({0.0f, v.x(), v.y(), v.z()}); - const vect<4> q_inv({q.w(), -q.x(), -q.y(), -q.z()}); - - // t = q * v - vect<4> t; - t.w() = -q.x() * qv.x() - q.y() * qv.y() - q.z() * qv.z(); - t.x() = q.w() * qv.x() + q.y() * qv.z() - q.z() * qv.y(); - t.y() = q.w() * qv.y() - q.x() * qv.z() + q.z() * qv.x(); - t.z() = q.w() * qv.z() + q.x() * qv.y() - q.y() * qv.x(); - - // r = t * q_inv - vect<4> r; - r.w() = -t.x() * q_inv.x() - t.y() * q_inv.y() - t.z() * q_inv.z(); - r.x() = t.w() * q_inv.x() + t.y() * q_inv.z() - t.z() * q_inv.y(); - r.y() = t.w() * q_inv.y() - t.x() * q_inv.z() + t.z() * q_inv.x(); - r.z() = t.w() * q_inv.z() + t.x() * q_inv.y() - t.y() * q_inv.x(); - - return vect<3>({r.x(), r.y(), r.z()}); - }; - if constexpr (use_imu_for_velocity) { // Gravity in world frame diff --git a/rpcs3/Emu/Io/ps_move_data.h b/rpcs3/Emu/Io/ps_move_data.h index 1ae30f5c66..2470e47e8c 100644 --- a/rpcs3/Emu/Io/ps_move_data.h +++ b/rpcs3/Emu/Io/ps_move_data.h @@ -15,6 +15,26 @@ struct ps_move_data template const T& operator[](I i) const { return data[i]; } + vect operator*(f32 s) const + { + vect result = *this; + for (int i = 0; i < Size; ++i) + { + result[i] *= s; + } + return result; + } + + vect operator+(const vect& other) const + { + vect result = *this; + for (int i = 0; i < Size; ++i) + { + result[i] += other[i]; + } + return result; + } + T x() const requires (Size >= 1) { return data[0]; } T y() const requires (Size >= 2) { return data[1]; } T z() const requires (Size >= 3) { return data[2]; } @@ -72,4 +92,7 @@ struct ps_move_data void reset_sensors(); void update_orientation(f32 delta_time); void update_velocity(u64 timestamp, be_t pos_world[4]); + + // Rotate vector v by quaternion q + static vect<3> rotate_vector(const vect<4>& q, const vect<3>& v); }; From 41db06b53f906fbe2941552008ea8b468fa38482 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Sun, 8 Mar 2026 14:00:57 +0100 Subject: [PATCH 123/175] cellGem: fix handle_pos calculation The handle position depends on the sphere position and the orientation --- rpcs3/Emu/Cell/Modules/cellGem.cpp | 49 ++++++++++++++++-------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/cellGem.cpp b/rpcs3/Emu/Cell/Modules/cellGem.cpp index 1a1e8a7d04..f87b4349a1 100644 --- a/rpcs3/Emu/Cell/Modules/cellGem.cpp +++ b/rpcs3/Emu/Cell/Modules/cellGem.cpp @@ -1883,21 +1883,10 @@ static inline void pos_to_gem_state(u32 gem_num, gem_config::gem_controller& con gem_state->pos[2] = controller.distance_mm; gem_state->pos[3] = 0.f; - // TODO: calculate handle position based on our world coordinate and the angles - gem_state->handle_pos[0] = camera_x; - gem_state->handle_pos[1] = camera_y; - gem_state->handle_pos[2] = controller.distance_mm + 10.0f; - gem_state->handle_pos[3] = 0.f; - // Calculate orientation - if (g_cfg.io.move == move_handler::real || (g_cfg.io.move == move_handler::fake && move_data.orientation_enabled)) - { - gem_state->quat[0] = move_data.quaternion.x(); - gem_state->quat[1] = move_data.quaternion.y(); - gem_state->quat[2] = move_data.quaternion.z(); - gem_state->quat[3] = move_data.quaternion.w(); - } - else + ps_move_data::vect<4> quat = move_data.quaternion; + + if (g_cfg.io.move != move_handler::real && !(g_cfg.io.move == move_handler::fake && move_data.orientation_enabled)) { const f32 max_angle_per_side_h = g_cfg.io.fake_move_rotation_cone_h / 2.0f; const f32 max_angle_per_side_v = g_cfg.io.fake_move_rotation_cone_v / 2.0f; @@ -1911,17 +1900,27 @@ static inline void pos_to_gem_state(u32 gem_num, gem_config::gem_controller& con const f32 cy = std::cos(yaw * 0.5f); const f32 sy = std::sin(yaw * 0.5f); - const f32 q_x = sr * cp * cy - cr * sp * sy; - const f32 q_y = cr * sp * cy + sr * cp * sy; - const f32 q_z = cr * cp * sy - sr * sp * cy; - const f32 q_w = cr * cp * cy + sr * sp * sy; - - gem_state->quat[0] = q_x; - gem_state->quat[1] = q_y; - gem_state->quat[2] = q_z; - gem_state->quat[3] = q_w; + quat.x() = sr * cp * cy - cr * sp * sy; + quat.y() = cr * sp * cy + sr * cp * sy; + quat.z() = cr * cp * sy - sr * sp * cy; + quat.w() = cr * cp * cy + sr * sp * sy; } + gem_state->quat[0] = quat.x(); + gem_state->quat[1] = quat.y(); + gem_state->quat[2] = quat.z(); + gem_state->quat[3] = quat.w(); + + // Calculate handle position based on our world coordinate and the current orientation + constexpr ps_move_data::vect<3> offset_local_mm({0.f, 0.f, -45.f}); // handle is ~45 mm below sphere + const ps_move_data::vect<3> offset_world = ps_move_data::rotate_vector(quat, offset_local_mm); + + gem_state->handle_pos[0] = gem_state->pos[0] - offset_world.x(); // Flip x offset + gem_state->handle_pos[1] = gem_state->pos[1] - offset_world.y(); // Flip y offset + gem_state->handle_pos[2] = gem_state->pos[2] + offset_world.z(); + gem_state->handle_pos[3] = 0.f; + + // Calculate velocity if constexpr (!ps_move_data::use_imu_for_velocity) { move_data.update_velocity(shared_data.frame_timestamp_us, gem_state->pos); @@ -1930,6 +1929,10 @@ static inline void pos_to_gem_state(u32 gem_num, gem_config::gem_controller& con { gem_state->vel[i] = move_data.vel_world[i]; gem_state->accel[i] = move_data.accel_world[i]; + + // TODO: maybe this also needs to be adjusted depending on the orientation + gem_state->handle_vel[i] = gem_state->vel[i]; + gem_state->handle_accel[i] = gem_state->accel[i]; } } From 77cbdd82ab02d64bfe95048fcf8be3afd968bcc5 Mon Sep 17 00:00:00 2001 From: RipleyTom Date: Mon, 9 Mar 2026 04:27:50 +0100 Subject: [PATCH 124/175] LLVM 22 fixups From https://releases.llvm.org/22.1.0/docs/ReleaseNotes.html: The alignment argument of the @llvm.masked.load, @llvm.masked.store, @llvm.masked.gather and @llvm.masked.scatter intrinsics has been removed. Instead, the align attribute should be placed on the pointer (or vector of pointers) argument. They also changed(not in changelog for some reason): vpdpbusd_128: [v4i32] -> [v4i32, v4i32, v4i32] to vpdpbusd_128: [v4i32] -> [v4i32, v16i8, v16i8] --- rpcs3/Emu/CPU/CPUTranslator.h | 7 +++++++ rpcs3/Emu/Cell/PPUTranslator.cpp | 8 ++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/rpcs3/Emu/CPU/CPUTranslator.h b/rpcs3/Emu/CPU/CPUTranslator.h index 99ddafde0a..27abb22219 100644 --- a/rpcs3/Emu/CPU/CPUTranslator.h +++ b/rpcs3/Emu/CPU/CPUTranslator.h @@ -3647,7 +3647,14 @@ public: const auto data0 = a.eval(m_ir); const auto data1 = b.eval(m_ir); const auto data2 = c.eval(m_ir); + +#if LLVM_VERSION_MAJOR >= 22 + // LLVM 22+ changed the intrinsic signature from v4i32 to v16i8 for operands 2 and 3 + result.value = m_ir->CreateCall(get_intrinsic(llvm::Intrinsic::x86_avx512_vpdpbusd_128), + {data0, m_ir->CreateBitCast(data1, get_type()), m_ir->CreateBitCast(data2, get_type())}); +#else result.value = m_ir->CreateCall(get_intrinsic(llvm::Intrinsic::x86_avx512_vpdpbusd_128), {data0, data1, data2}); +#endif return result; } diff --git a/rpcs3/Emu/Cell/PPUTranslator.cpp b/rpcs3/Emu/Cell/PPUTranslator.cpp index ddf7d330a0..b12cd9c55d 100644 --- a/rpcs3/Emu/Cell/PPUTranslator.cpp +++ b/rpcs3/Emu/Cell/PPUTranslator.cpp @@ -3681,9 +3681,7 @@ void PPUTranslator::STVLX(ppu_opcode_t op) const auto addr = op.ra ? m_ir->CreateAdd(GetGpr(op.ra), GetGpr(op.rb)) : GetGpr(op.rb); const auto data = pshufb(get_vr(op.vs), build(127, 126, 125, 124, 123, 122, 121, 120, 119, 118, 117, 116, 115, 114, 113, 112) + vsplat(trunc(value(addr) & 0xf))); const auto mask = bitcast(splat(0xffff) << trunc(value(addr) & 0xf)); - const auto ptr = value(GetMemory(m_ir->CreateAnd(addr, ~0xfull))); - const auto align = splat(16); - eval(llvm_calli{"llvm.masked.store.v16i8.p0", {data, ptr, align, mask}}); + m_ir->CreateMaskedStore(data.eval(m_ir), GetMemory(m_ir->CreateAnd(addr, ~0xfull)), llvm::Align(16), mask.eval(m_ir)); } void PPUTranslator::STDBRX(ppu_opcode_t op) @@ -3711,9 +3709,7 @@ void PPUTranslator::STVRX(ppu_opcode_t op) const auto addr = op.ra ? m_ir->CreateAdd(GetGpr(op.ra), GetGpr(op.rb)) : GetGpr(op.rb); const auto data = pshufb(get_vr(op.vs), build(255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, 244, 243, 242, 241, 240) + vsplat(trunc(value(addr) & 0xf))); const auto mask = bitcast(trunc(splat(0xffff) << (value(addr) & 0xf) >> 16)); - const auto ptr = value(GetMemory(m_ir->CreateAnd(addr, ~0xfull))); - const auto align = splat(16); - eval(llvm_calli{"llvm.masked.store.v16i8.p0", {data, ptr, align, mask}}); + m_ir->CreateMaskedStore(data.eval(m_ir), GetMemory(m_ir->CreateAnd(addr, ~0xfull)), llvm::Align(16), mask.eval(m_ir)); } void PPUTranslator::STFSUX(ppu_opcode_t op) From 302e87c920038bae1d35f631b7c3bb8ec909379a Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sat, 21 Feb 2026 21:20:11 +0300 Subject: [PATCH 125/175] rsx/vk: Improve robustness when encountering corrupted shaders --- .../Emu/RSX/Program/FragmentProgramDecompiler.cpp | 3 +++ rpcs3/Emu/RSX/VK/VKDraw.cpp | 14 ++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/rpcs3/Emu/RSX/Program/FragmentProgramDecompiler.cpp b/rpcs3/Emu/RSX/Program/FragmentProgramDecompiler.cpp index c00cef47e6..8f134ebfae 100644 --- a/rpcs3/Emu/RSX/Program/FragmentProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/Program/FragmentProgramDecompiler.cpp @@ -868,8 +868,11 @@ std::string FragmentProgramDecompiler::BuildCode() if (!m_is_valid_ucode) { // If the code is broken, do not compile. Simply NOP main and write empty outputs + m_parr.params[PF_PARAM_UNIFORM].clear(); insertHeader(OS); OS << "\n"; + insertConstants(OS); + OS << "\n"; OS << "void main()\n"; OS << "{\n"; OS << "#if 0\n"; diff --git a/rpcs3/Emu/RSX/VK/VKDraw.cpp b/rpcs3/Emu/RSX/VK/VKDraw.cpp index 634131b13b..b18ebaed3a 100644 --- a/rpcs3/Emu/RSX/VK/VKDraw.cpp +++ b/rpcs3/Emu/RSX/VK/VKDraw.cpp @@ -635,9 +635,16 @@ bool VKGSRender::bind_texture_env() { if (!(textures_ref & 1)) { + // Unused TIU continue; } + if (m_fs_binding_table->ftex_location[i] == umax) + { + // Corrupt shader table + break; + } + vk::image_view* view = nullptr; auto sampler_state = static_cast(fs_sampler_state[i].get()); @@ -707,9 +714,16 @@ bool VKGSRender::bind_texture_env() { if (!(textures_ref & 1)) { + // Unused TIU continue; } + if (m_vs_binding_table->vtex_location[i] == umax) + { + // Corrupt shader + break; + } + if (!rsx::method_registers.vertex_textures[i].enabled()) { const auto view_type = vk::get_view_type(current_vertex_program.get_texture_dimension(i)); From 5f6822042dff8f9324efa6e4775944329d461739 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Mon, 9 Mar 2026 04:10:29 +0300 Subject: [PATCH 126/175] gl: Silence warnings --- rpcs3/Emu/RSX/GL/glutils/common.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rpcs3/Emu/RSX/GL/glutils/common.h b/rpcs3/Emu/RSX/GL/glutils/common.h index a147a6e754..24e62a9189 100644 --- a/rpcs3/Emu/RSX/GL/glutils/common.h +++ b/rpcs3/Emu/RSX/GL/glutils/common.h @@ -87,7 +87,7 @@ namespace gl void set_name(std::string_view name) { m_name = name.data(); - glObjectLabel(Ns, m_id, name.length(), name.data()); + glObjectLabel(Ns, m_id, static_cast(name.length()), name.data()); } std::string_view name() const @@ -97,9 +97,9 @@ namespace gl }; // Very useful util when capturing traces with RenderDoc - static inline void push_debug_label(const char* label) + static inline void push_debug_label(std::string_view label) { - glInsertEventMarkerEXT(static_cast(strlen(label)), label); + glInsertEventMarkerEXT(static_cast(label.size()), label.data()); } // Checks if GL state is still valid From 65320446f019281ed44d240f86b9b9771b2e7e83 Mon Sep 17 00:00:00 2001 From: Ani Date: Mon, 9 Mar 2026 11:34:07 +0100 Subject: [PATCH 127/175] vk: Add 0x13C0 NAVI2 device ID (Raphael Mendocino) This is the iGPU on 9800X3D --- rpcs3/Emu/RSX/VK/vkutils/chip_class.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/rpcs3/Emu/RSX/VK/vkutils/chip_class.cpp b/rpcs3/Emu/RSX/VK/vkutils/chip_class.cpp index de9bf8a124..fd98fe1ca0 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/chip_class.cpp +++ b/rpcs3/Emu/RSX/VK/vkutils/chip_class.cpp @@ -28,6 +28,7 @@ namespace vk table.add(0x7420, 0x743F, chip_class::AMD_navi2x); // Navi 24 (Beige Goby) table.add(0x163F, chip_class::AMD_navi2x); // Navi 2X (Van Gogh) table.add(0x164D, 0x1681, chip_class::AMD_navi2x); // Navi 2X (Yellow Carp) + table.add(0x13C0, chip_class::AMD_navi2x); // Navi 2X (Raphael Mendocino) table.add(0x7440, 0x745F, chip_class::AMD_navi3x); // Navi 31 (Only 744c, NAVI31XTX is confirmed) table.add(0x7460, 0x747F, chip_class::AMD_navi3x); // Navi 32 (Unverified) table.add(0x7480, 0x749F, chip_class::AMD_navi3x); // Navi 33 (Unverified) From e0a0d736c4df546cdf250f534d5b912f239134ae Mon Sep 17 00:00:00 2001 From: Megamouse Date: Tue, 10 Mar 2026 01:45:05 +0100 Subject: [PATCH 128/175] cellGem: remove redundant check --- rpcs3/Emu/Cell/Modules/cellGem.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/cellGem.cpp b/rpcs3/Emu/Cell/Modules/cellGem.cpp index f87b4349a1..2ed6d8911d 100644 --- a/rpcs3/Emu/Cell/Modules/cellGem.cpp +++ b/rpcs3/Emu/Cell/Modules/cellGem.cpp @@ -1609,12 +1609,6 @@ public: return false; } - if (!m_camera_info.bytesize) - { - cellGem.error("gem_tracker: unexpected image size: %d", m_camera_info.bytesize); - return false; - } - m_tracker.set_image_data(m_camera_info.buffer.get_ptr(), m_camera_info.bytesize, m_camera_info.width, m_camera_info.height, m_camera_info.format); m_framenumber++; // using framenumber instead of timestamp since the timestamp could be identical return true; From 0f92ea2578a48ee21aff2430be2d28baefde8c48 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Tue, 10 Mar 2026 01:50:56 +0100 Subject: [PATCH 129/175] cellGem: fix memcpy in cellGemReadExternalPortDeviceInfo It was copying from dst to src, and the wrong size at that --- rpcs3/Emu/Cell/Modules/cellGem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpcs3/Emu/Cell/Modules/cellGem.cpp b/rpcs3/Emu/Cell/Modules/cellGem.cpp index 2ed6d8911d..11cc18e547 100644 --- a/rpcs3/Emu/Cell/Modules/cellGem.cpp +++ b/rpcs3/Emu/Cell/Modules/cellGem.cpp @@ -3619,7 +3619,7 @@ error_code cellGemReadExternalPortDeviceInfo(u32 gem_num, vm::ptr ext_id, v if (!pad->move_data.external_device_read_requested) { *ext_id = controller.ext_id = pad->move_data.external_device_id; - std::memcpy(pad->move_data.external_device_read.data(), ext_info.get_ptr(), CELL_GEM_EXTERNAL_PORT_OUTPUT_SIZE); + std::memcpy(ext_info.get_ptr(), pad->move_data.external_device_read.data(), CELL_GEM_EXTERNAL_PORT_DEVICE_INFO_SIZE); break; } } From 763001ee91c515fc77c050258bba383acb75f25e Mon Sep 17 00:00:00 2001 From: Megamouse Date: Tue, 10 Mar 2026 01:53:51 +0100 Subject: [PATCH 130/175] cellGem: fix gain channels --- rpcs3/Emu/Cell/Modules/cellGem.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/cellGem.cpp b/rpcs3/Emu/Cell/Modules/cellGem.cpp index 11cc18e547..9731474b51 100644 --- a/rpcs3/Emu/Cell/Modules/cellGem.cpp +++ b/rpcs3/Emu/Cell/Modules/cellGem.cpp @@ -770,8 +770,8 @@ namespace gem if constexpr (use_gain) { dst0[0] = static_cast(std::clamp(r * gain_r, 0.0f, 255.0f)); - dst0[1] = static_cast(std::clamp(b * gain_b, 0.0f, 255.0f)); - dst0[2] = static_cast(std::clamp(g * gain_g, 0.0f, 255.0f)); + dst0[1] = static_cast(std::clamp(g * gain_g, 0.0f, 255.0f)); + dst0[2] = static_cast(std::clamp(b * gain_b, 0.0f, 255.0f)); } else { @@ -822,8 +822,8 @@ namespace gem if constexpr (use_gain) { dst0[0] = static_cast(std::clamp(r * gain_r, 0.0f, 255.0f)); - dst0[1] = static_cast(std::clamp(b * gain_b, 0.0f, 255.0f)); - dst0[2] = static_cast(std::clamp(g * gain_g, 0.0f, 255.0f)); + dst0[1] = static_cast(std::clamp(g * gain_g, 0.0f, 255.0f)); + dst0[2] = static_cast(std::clamp(b * gain_b, 0.0f, 255.0f)); } else { @@ -881,9 +881,9 @@ namespace gem const u8* src_data = video_data_in.data(); const u8 alpha = vc.alpha; - const f32 gain_r = vc.gain * vc.blue_gain; + const f32 gain_r = vc.gain * vc.red_gain; const f32 gain_g = vc.gain * vc.green_gain; - const f32 gain_b = vc.gain * vc.red_gain; + const f32 gain_b = vc.gain * vc.blue_gain; // Only RAW8 should be relevant for cellGem unless I'm mistaken if (input_format == CELL_CAMERA_RAW8) From 71f0d5c60233494e7fe2c3f2ff416a00c87480fb Mon Sep 17 00:00:00 2001 From: Megamouse Date: Tue, 10 Mar 2026 03:38:24 +0100 Subject: [PATCH 131/175] cellGem: fix RAW8 to RGBA_320x240 We were basically writing two rows into dst for each other src line. This means we were writing 480 lines in total instead of 240, overwriting one of the lines written in the previous iteration. This led to writing one line out of bounds last iteration. Let's just use a simple debayer technique which perfectly matches here. This also applies the previously missing gain factors. I also tried to first demosaic and then drop every other pixel. The result was comparatively blurred and the performance worse. --- rpcs3/Emu/Cell/Modules/cellGem.cpp | 76 +++++++++++++++++++----------- 1 file changed, 48 insertions(+), 28 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/cellGem.cpp b/rpcs3/Emu/Cell/Modules/cellGem.cpp index 9731474b51..d45dace1ca 100644 --- a/rpcs3/Emu/Cell/Modules/cellGem.cpp +++ b/rpcs3/Emu/Cell/Modules/cellGem.cpp @@ -845,6 +845,53 @@ namespace gem debayer_raw8_impl(src, dst, alpha, gain_r, gain_g, gain_b); } + template + static inline void debayer_raw8_downscale_impl(const u8* src, u8* dst, u8 alpha, f32 gain_r, f32 gain_g, f32 gain_b) + { + constexpr u32 in_pitch = 640; + constexpr u32 out_pitch = 320 * 4; + + // Simple debayer + for (s32 y = 0; y < 240; y++) + { + const u8* src0 = src + y * 2 * in_pitch; + const u8* src1 = src0 + in_pitch; + + u8* dst0 = dst + y * out_pitch; + + for (s32 x = 0; x < 320; x++, dst0 += 4, src0 += 2, src1 += 2) + { + const u8 b = src0[0]; + const u8 g0 = src0[1]; + const u8 g1 = src1[0]; + const u8 r = src1[1]; + const u8 g = (g0 + g1) >> 1; + + if constexpr (use_gain) + { + dst0[0] = static_cast(std::clamp(r * gain_r, 0.0f, 255.0f)); + dst0[1] = static_cast(std::clamp(g * gain_g, 0.0f, 255.0f)); + dst0[2] = static_cast(std::clamp(b * gain_b, 0.0f, 255.0f)); + } + else + { + dst0[0] = r; + dst0[1] = g; + dst0[2] = b; + } + dst0[3] = alpha; + } + } + } + + static void debayer_raw8_downscale(const u8* src, u8* dst, u8 alpha, f32 gain_r, f32 gain_g, f32 gain_b) + { + if (gain_r != 1.0f || gain_g != 1.0f || gain_b != 1.0f) + debayer_raw8_downscale_impl(src, dst, alpha, gain_r, gain_g, gain_b); + else + debayer_raw8_downscale_impl(src, dst, alpha, gain_r, gain_g, gain_b); + } + bool convert_image_format(CellCameraFormat input_format, const CellGemVideoConvertAttribute& vc, const std::vector& video_data_in, u32 width, u32 height, u8* video_data_out, u32 video_data_out_size, u8* buffer_memory, @@ -1183,34 +1230,7 @@ namespace gem { case CELL_CAMERA_RAW8: { - const u32 in_pitch = width; - const u32 out_pitch = width * 4 / 2; - - for (u32 y = 0; y < height - 1; y += 2) - { - const u8* src0 = src_data + y * in_pitch; - const u8* src1 = src0 + in_pitch; - - u8* dst0 = video_data_out + (y / 2) * out_pitch; - u8* dst1 = dst0 + out_pitch; - - for (u32 x = 0; x < width - 1; x += 2, src0 += 2, src1 += 2, dst0 += 4, dst1 += 4) - { - const u8 b = src0[0]; - const u8 g0 = src0[1]; - const u8 g1 = src1[0]; - const u8 r = src1[1]; - - const u8 top[4] = { r, g0, b, alpha }; - const u8 bottom[4] = { r, g1, b, alpha }; - - // Top-Left - std::memcpy(dst0, top, 4); - - // Bottom-Left Pixel - std::memcpy(dst1, bottom, 4); - } - } + debayer_raw8_downscale(src_data, video_data_out, alpha, gain_r, gain_g, gain_b); break; } case CELL_CAMERA_RGBA: From 0603d24a911013051a29b3794567ec75b760de61 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Tue, 10 Mar 2026 05:33:55 +0100 Subject: [PATCH 132/175] Qt: play SND0.AT3 in game lists when a movie would play --- rpcs3/Emu/GameInfo.h | 1 + rpcs3/rpcs3qt/game_list_frame.cpp | 6 ++ rpcs3/rpcs3qt/game_list_grid.cpp | 18 +++++- rpcs3/rpcs3qt/game_list_table.cpp | 18 +++++- rpcs3/rpcs3qt/gui_game_info.h | 1 + rpcs3/rpcs3qt/qt_video_source.cpp | 89 ++++++++++++++++++++++++++- rpcs3/rpcs3qt/qt_video_source.h | 7 +++ rpcs3/rpcs3qt/save_manager_dialog.cpp | 6 ++ rpcs3/util/video_source.h | 1 + 9 files changed, 140 insertions(+), 7 deletions(-) diff --git a/rpcs3/Emu/GameInfo.h b/rpcs3/Emu/GameInfo.h index 3efca1410a..da8b2638ba 100644 --- a/rpcs3/Emu/GameInfo.h +++ b/rpcs3/Emu/GameInfo.h @@ -8,6 +8,7 @@ struct GameInfo std::string path; std::string icon_path; std::string movie_path; + std::string audio_path; std::string name; std::string serial; diff --git a/rpcs3/rpcs3qt/game_list_frame.cpp b/rpcs3/rpcs3qt/game_list_frame.cpp index ea7b87ff6d..5ba31d9d77 100644 --- a/rpcs3/rpcs3qt/game_list_frame.cpp +++ b/rpcs3/rpcs3qt/game_list_frame.cpp @@ -637,6 +637,12 @@ void game_list_frame::OnParsingFinished() game.has_hover_pam = true; } + if (std::string audio_path = sfo_dir + "/SND0.AT3"; file_exists(audio_path)) + { + game.info.audio_path = std::move(audio_path); + game.has_audio_file = true; + } + const QString serial = QString::fromStdString(game.info.serial); m_games_mutex.lock(); diff --git a/rpcs3/rpcs3qt/game_list_grid.cpp b/rpcs3/rpcs3qt/game_list_grid.cpp index a33755ff54..4dfcf9744a 100644 --- a/rpcs3/rpcs3qt/game_list_grid.cpp +++ b/rpcs3/rpcs3qt/game_list_grid.cpp @@ -109,11 +109,23 @@ void game_list_grid::populate( } }); - if (play_hover_movies && (game->has_hover_gif || game->has_hover_pam)) + if (play_hover_movies && (game->has_hover_gif || game->has_hover_pam || game->has_audio_file)) { - item->set_video_path(game->info.movie_path); + bool check_iso = false; - if (!fs::exists(game->info.movie_path) && is_file_iso(game->info.path)) + if (game->has_hover_gif || game->has_hover_pam) + { + item->set_video_path(game->info.movie_path); + check_iso |= !fs::exists(game->info.movie_path); + } + + if (game->has_audio_file) + { + item->set_audio_path(game->info.audio_path); + check_iso |= !fs::exists(game->info.audio_path); + } + + if (check_iso && is_file_iso(game->info.path)) { item->set_iso_path(game->info.path); } diff --git a/rpcs3/rpcs3qt/game_list_table.cpp b/rpcs3/rpcs3qt/game_list_table.cpp index 98b9ef344d..737709dabb 100644 --- a/rpcs3/rpcs3qt/game_list_table.cpp +++ b/rpcs3/rpcs3qt/game_list_table.cpp @@ -299,11 +299,23 @@ void game_list_table::populate( } }); - if (play_hover_movies && (game->has_hover_gif || game->has_hover_pam)) + if (play_hover_movies && (game->has_hover_gif || game->has_hover_pam || game->has_audio_file)) { - icon_item->set_video_path(game->info.movie_path); + bool check_iso = false; - if (!fs::exists(game->info.movie_path) && is_file_iso(game->info.path)) + if (game->has_hover_gif || game->has_hover_pam) + { + icon_item->set_video_path(game->info.movie_path); + check_iso |= !fs::exists(game->info.movie_path); + } + + if (game->has_audio_file) + { + icon_item->set_audio_path(game->info.audio_path); + check_iso |= !fs::exists(game->info.audio_path); + } + + if (check_iso && is_file_iso(game->info.path)) { icon_item->set_iso_path(game->info.path); } diff --git a/rpcs3/rpcs3qt/gui_game_info.h b/rpcs3/rpcs3qt/gui_game_info.h index 08483fa7fb..693483dd6a 100644 --- a/rpcs3/rpcs3qt/gui_game_info.h +++ b/rpcs3/rpcs3qt/gui_game_info.h @@ -21,6 +21,7 @@ struct gui_game_info bool has_custom_icon = false; bool has_hover_gif = false; bool has_hover_pam = false; + bool has_audio_file = false; bool icon_in_archive = false; movie_item_base* item = nullptr; diff --git a/rpcs3/rpcs3qt/qt_video_source.cpp b/rpcs3/rpcs3qt/qt_video_source.cpp index d74d395c58..2d4ce34aa3 100644 --- a/rpcs3/rpcs3qt/qt_video_source.cpp +++ b/rpcs3/rpcs3qt/qt_video_source.cpp @@ -1,11 +1,19 @@ #include "stdafx.h" #include "Emu/System.h" +#include "Emu/system_config.h" #include "qt_video_source.h" #include "Loader/ISO.h" +#include #include +static video_source* s_audio_source = nullptr; +static std::unique_ptr s_audio_player = nullptr; +static std::unique_ptr s_audio_output = nullptr; +static std::unique_ptr s_audio_buffer = nullptr; +static std::unique_ptr s_audio_data = nullptr; + qt_video_source::qt_video_source() : video_source() { @@ -21,6 +29,11 @@ void qt_video_source::set_video_path(const std::string& video_path) m_video_path = QString::fromStdString(video_path); } +void qt_video_source::set_audio_path(const std::string& audio_path) +{ + m_audio_path = QString::fromStdString(audio_path); +} + void qt_video_source::set_iso_path(const std::string& iso_path) { m_iso_path = iso_path; @@ -89,7 +102,6 @@ void qt_video_source::init_movie() m_video_buffer = std::make_unique(&m_video_data); m_video_buffer->open(QIODevice::ReadOnly); m_movie = std::make_unique(m_video_buffer.get()); - } if (!m_movie->isValid()) @@ -179,6 +191,8 @@ void qt_video_source::start_movie() m_media_player->play(); } + start_audio(); + m_active = true; } @@ -196,6 +210,71 @@ void qt_video_source::stop_movie() m_media_player.reset(); m_video_buffer.reset(); m_video_data.clear(); + + stop_audio(); +} + +void qt_video_source::start_audio() +{ + if (m_audio_path.isEmpty() || s_audio_source == this) return; + + if (!s_audio_player) + { + s_audio_output = std::make_unique(); + s_audio_player = std::make_unique(); + s_audio_player->setAudioOutput(s_audio_output.get()); + } + + if (m_iso_path.empty()) + { + s_audio_player->setSource(QUrl::fromLocalFile(m_audio_path)); + } + else + { + iso_archive archive(m_iso_path); + auto audio_file = archive.open(m_audio_path.toStdString()); + const auto audio_size = audio_file.size(); + if (audio_size == 0) return; + + std::unique_ptr old_audio_data = std::move(s_audio_data); + s_audio_data = std::make_unique(audio_size, 0); + audio_file.read(s_audio_data->data(), audio_size); + + if (!s_audio_buffer) + { + s_audio_buffer = std::make_unique(); + } + + s_audio_buffer->setBuffer(s_audio_data.get()); + s_audio_buffer->open(QIODevice::ReadOnly); + s_audio_player->setSourceDevice(s_audio_buffer.get()); + + if (old_audio_data) + { + old_audio_data.reset(); + } + } + + s_audio_output->setVolume(g_cfg.audio.volume.get() / 100.0f); + s_audio_player->play(); + s_audio_source = this; +} + +void qt_video_source::stop_audio() +{ + if (s_audio_source != this) return; + + s_audio_source = nullptr; + + if (s_audio_player) + { + s_audio_player->stop(); + s_audio_player.reset(); + } + + s_audio_output.reset(); + s_audio_buffer.reset(); + s_audio_data.reset(); } QPixmap qt_video_source::get_movie_image(const QVideoFrame& frame) const @@ -288,6 +367,14 @@ void qt_video_source_wrapper::set_video_path(const std::string& video_path) }); } +void qt_video_source_wrapper::set_audio_path(const std::string& audio_path) +{ + Emu.CallFromMainThread([this, path = audio_path]() + { + // TODO + }); +} + void qt_video_source_wrapper::set_active(bool active) { Emu.CallFromMainThread([this, active]() diff --git a/rpcs3/rpcs3qt/qt_video_source.h b/rpcs3/rpcs3qt/qt_video_source.h index ce43d593d7..cda92671a2 100644 --- a/rpcs3/rpcs3qt/qt_video_source.h +++ b/rpcs3/rpcs3qt/qt_video_source.h @@ -19,7 +19,9 @@ public: void set_iso_path(const std::string& iso_path); void set_video_path(const std::string& video_path) override; + void set_audio_path(const std::string& audio_path) override; const QString& video_path() const { return m_video_path; } + const QString& audio_path() const { return m_audio_path; } void get_image(std::vector& data, int& w, int& h, int& ch, int& bpp) override; bool has_new() const override { return m_has_new; } @@ -30,6 +32,9 @@ public: void start_movie(); void stop_movie(); + void start_audio(); + void stop_audio(); + QPixmap get_movie_image(const QVideoFrame& frame) const; void image_change_callback(const QVideoFrame& frame = {}) const; @@ -44,6 +49,7 @@ protected: atomic_t m_has_new = false; QString m_video_path; + QString m_audio_path; std::string m_iso_path; // path of the source archive QByteArray m_video_data{}; QImage m_image{}; @@ -67,6 +73,7 @@ public: virtual ~qt_video_source_wrapper(); void set_video_path(const std::string& video_path) override; + void set_audio_path(const std::string& audio_path) override; void set_active(bool active) override; bool get_active() const override; bool has_new() const override { return m_qt_video_source && m_qt_video_source->has_new(); } diff --git a/rpcs3/rpcs3qt/save_manager_dialog.cpp b/rpcs3/rpcs3qt/save_manager_dialog.cpp index 2dd2a14e86..002df8d527 100644 --- a/rpcs3/rpcs3qt/save_manager_dialog.cpp +++ b/rpcs3/rpcs3qt/save_manager_dialog.cpp @@ -360,6 +360,11 @@ void save_manager_dialog::UpdateList() icon_item->set_video_path(movie_path); } + if (const std::string audio_path = dir_path + "SND0.AT3"; fs::is_file(audio_path)) + { + icon_item->set_audio_path(audio_path); + } + icon_item->set_image_change_callback([this, icon_item](const QVideoFrame& frame) { if (!icon_item) @@ -686,6 +691,7 @@ void save_manager_dialog::UpdateDetails() const SaveDataEntry& save = ::at32(m_save_entries, idx); m_details_icon->set_video_path(icon_item->video_path().toStdString()); + m_details_icon->set_audio_path(icon_item->audio_path().toStdString()); m_details_icon->set_thumbnail(icon_item->data(SaveUserRole::Pixmap).value()); m_details_icon->set_active(false); diff --git a/rpcs3/util/video_source.h b/rpcs3/util/video_source.h index 9449ed238e..a18b564209 100644 --- a/rpcs3/util/video_source.h +++ b/rpcs3/util/video_source.h @@ -9,6 +9,7 @@ public: video_source() {}; virtual ~video_source() {}; virtual void set_video_path(const std::string& video_path) = 0; + virtual void set_audio_path(const std::string& audio_path) = 0; virtual void set_active(bool active) = 0; virtual bool get_active() const = 0; virtual bool has_new() const = 0; From 6d52415d5025a593e643d2a823a392c1a07ec920 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Mon, 9 Mar 2026 17:53:45 +0300 Subject: [PATCH 133/175] gl: Ignore range offset when doing readback operations - OGL desperately needs a functioning DMA layer --- rpcs3/Emu/RSX/GL/GLTextureCache.h | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/rpcs3/Emu/RSX/GL/GLTextureCache.h b/rpcs3/Emu/RSX/GL/GLTextureCache.h index 8bfc92f902..7fb932681b 100644 --- a/rpcs3/Emu/RSX/GL/GLTextureCache.h +++ b/rpcs3/Emu/RSX/GL/GLTextureCache.h @@ -171,14 +171,6 @@ namespace gl { static_cast(src_area.width()), static_cast(src_area.height()), 1 } }; - u32 pbo_offset = 0; - if (valid_range.valid()) - { - const u32 section_base = get_section_base(); - pbo_offset = valid_range.start - section_base; - ensure(valid_range.start >= section_base && pbo_offset <= pbo.size()); - } - bool use_driver_pixel_transform = true; if (get_driver_caps().ARB_compute_shader_supported) [[likely]] { @@ -214,7 +206,7 @@ namespace gl real_pitch = pack_info.size * src->width(); const u64 data_length = pack_info.size * mem_info.image_size_in_texels; - scratch_mem.copy_to(&pbo, reinterpret_cast(out_offset), pbo_offset, data_length); + scratch_mem.copy_to(&pbo, reinterpret_cast(out_offset), 0, data_length); } else { @@ -237,7 +229,7 @@ namespace gl pack_settings.alignment(1); pack_settings.swap_bytes(pack_unpack_swap_bytes); - src->copy_to(pbo, pbo_offset, format, type, 0, src_rgn, pack_settings); + src->copy_to(pbo, 0, format, type, 0, src_rgn, pack_settings); } if (auto error = glGetError()) From 36cdaac3276736b0d0d719ec6948620b92697e18 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Mon, 9 Mar 2026 17:54:05 +0300 Subject: [PATCH 134/175] overlays: Fix image size estimation --- rpcs3/Emu/RSX/Overlays/overlay_controls.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpcs3/Emu/RSX/Overlays/overlay_controls.h b/rpcs3/Emu/RSX/Overlays/overlay_controls.h index f64fdfa47f..350a1c5901 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_controls.h +++ b/rpcs3/Emu/RSX/Overlays/overlay_controls.h @@ -40,7 +40,7 @@ namespace rsx image_info_base() {} virtual ~image_info_base() {} virtual const u8* get_data() const = 0; - virtual usz size_bytes() const { return static_cast(w * h * bpp); } + virtual usz size_bytes() const { return static_cast(w * h * 4); } // UI images get converted to RGBA8 std::span as_span() const { return { get_data(), size_bytes() }; } }; From ab72ce418eb9d0a7b3f0482dbdc47ed565f04e29 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Mon, 9 Mar 2026 18:14:54 +0300 Subject: [PATCH 135/175] gl: Minor enhancements to blitter - Move some functions to cpp. Makes it easier to debug failing image operations - Add fbo validation before blit operations --- rpcs3/Emu/RSX/GL/glutils/blitter.cpp | 15 +++++++++++++++ rpcs3/Emu/RSX/GL/glutils/blitter.h | 12 ++---------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/rpcs3/Emu/RSX/GL/glutils/blitter.cpp b/rpcs3/Emu/RSX/GL/glutils/blitter.cpp index 57998b761d..47c7d7b1ca 100644 --- a/rpcs3/Emu/RSX/GL/glutils/blitter.cpp +++ b/rpcs3/Emu/RSX/GL/glutils/blitter.cpp @@ -8,6 +8,18 @@ namespace gl { blitter* g_hw_blitter = nullptr; + void blitter::init() + { + blit_src.create(); + blit_dst.create(); + } + + void blitter::destroy() + { + blit_dst.remove(); + blit_src.remove(); + } + void blitter::copy_image(gl::command_context&, const texture* src, const texture* dst, int src_level, int dst_level, const position3i& src_offset, const position3i& dst_offset, const size3i& size) const { ensure(src_level == 0); @@ -147,6 +159,9 @@ namespace gl gl::fbo::attachment dst_att{ blit_dst, static_cast(attachment) }; dst_att = *real_dst; + blit_src.check(); + blit_dst.check(); + blit_src.blit(blit_dst, src_rect, dst_rect, target, interp); // Release the attachments explicitly (not doing so causes glitches, e.g Journey Menu) diff --git a/rpcs3/Emu/RSX/GL/glutils/blitter.h b/rpcs3/Emu/RSX/GL/glutils/blitter.h index d7adc1dd14..d56754fcae 100644 --- a/rpcs3/Emu/RSX/GL/glutils/blitter.h +++ b/rpcs3/Emu/RSX/GL/glutils/blitter.h @@ -30,17 +30,9 @@ namespace gl public: - void init() - { - blit_src.create(); - blit_dst.create(); - } + void init(); - void destroy() - { - blit_dst.remove(); - blit_src.remove(); - } + void destroy(); void scale_image(gl::command_context& cmd, const texture* src, texture* dst, areai src_rect, areai dst_rect, bool linear_interpolation, const rsx::typeless_xfer& xfer_info); From 5f86315ae05eea9efe92e1169007cd166a4da231 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Mon, 9 Mar 2026 20:51:27 +0300 Subject: [PATCH 136/175] gl: Fix shader interpreter compilation --- rpcs3/Emu/RSX/GL/GLShaderInterpreter.cpp | 1 + rpcs3/Emu/RSX/VK/VKShaderInterpreter.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/rpcs3/Emu/RSX/GL/GLShaderInterpreter.cpp b/rpcs3/Emu/RSX/GL/GLShaderInterpreter.cpp index c7f9ec2622..fa5b3627c4 100644 --- a/rpcs3/Emu/RSX/GL/GLShaderInterpreter.cpp +++ b/rpcs3/Emu/RSX/GL/GLShaderInterpreter.cpp @@ -300,6 +300,7 @@ namespace gl } builder << "\n" + "#undef TEX_PARAM\n" "#define TEX_PARAM(index) texture_parameters[index + texture_base_index]\n" "#define IS_TEXTURE_RESIDENT(index) (texture_handles[index] < 0xFF)\n" "#define SAMPLER1D(index) sampler1D_array[texture_handles[index]]\n" diff --git a/rpcs3/Emu/RSX/VK/VKShaderInterpreter.cpp b/rpcs3/Emu/RSX/VK/VKShaderInterpreter.cpp index 9315ac1593..7f6db33317 100644 --- a/rpcs3/Emu/RSX/VK/VKShaderInterpreter.cpp +++ b/rpcs3/Emu/RSX/VK/VKShaderInterpreter.cpp @@ -264,6 +264,7 @@ namespace vk } builder << "\n" + "#undef TEX_PARAM\n" "#define TEX_PARAM(index) texture_parameters[index + texture_base_index]\n" "#define IS_TEXTURE_RESIDENT(index) true\n" "#define SAMPLER1D(index) sampler1D_array[index]\n" From 0869ef421d0eecbe977e7ed35c0e59f2d2943bd6 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Mon, 9 Mar 2026 20:51:36 +0300 Subject: [PATCH 137/175] gl: Silence compiler warning --- rpcs3/Emu/RSX/GL/GLTextureCache.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpcs3/Emu/RSX/GL/GLTextureCache.h b/rpcs3/Emu/RSX/GL/GLTextureCache.h index 7fb932681b..d4e50fd066 100644 --- a/rpcs3/Emu/RSX/GL/GLTextureCache.h +++ b/rpcs3/Emu/RSX/GL/GLTextureCache.h @@ -148,7 +148,7 @@ namespace gl } } - void dma_transfer(gl::command_context& cmd, gl::texture* src, const areai& src_area, const utils::address_range32& valid_range, u32 pitch) + void dma_transfer(gl::command_context& cmd, gl::texture* src, const areai& src_area, const utils::address_range32& /*valid_range*/, u32 pitch) { init_buffer(src); glGetError(); From ef70a6e82584d291b889a1ab04f46ecfa7ee032e Mon Sep 17 00:00:00 2001 From: kd-11 Date: Mon, 9 Mar 2026 21:09:25 +0300 Subject: [PATCH 138/175] gl: Move ownership of the global blitter object from texture cache to global --- rpcs3/Emu/RSX/GL/GLGSRender.cpp | 1 + rpcs3/Emu/RSX/GL/GLTexture.cpp | 9 +++++++++ rpcs3/Emu/RSX/GL/GLTexture.h | 1 + rpcs3/Emu/RSX/GL/GLTextureCache.h | 11 ++--------- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index 408ea9f784..4ad9619d7f 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -398,6 +398,7 @@ void GLGSRender::on_init_thread() m_ui_renderer.create(); m_video_output_pass.create(); + gl::init_global_texture_resources(); m_gl_texture_cache.initialize(); m_prog_buffer.initialize diff --git a/rpcs3/Emu/RSX/GL/GLTexture.cpp b/rpcs3/Emu/RSX/GL/GLTexture.cpp index 40c3af180c..5dfc663c68 100644 --- a/rpcs3/Emu/RSX/GL/GLTexture.cpp +++ b/rpcs3/Emu/RSX/GL/GLTexture.cpp @@ -22,6 +22,13 @@ namespace gl legacy_ring_buffer g_upload_transfer_buffer; scratch_ring_buffer g_compute_decode_buffer; scratch_ring_buffer g_deswizzle_scratch_buffer; + blitter g_blitter; + + void init_global_texture_resources() + { + g_blitter.init(); + g_hw_blitter = &g_blitter; + } void destroy_global_texture_resources() { @@ -29,6 +36,8 @@ namespace gl g_upload_transfer_buffer.remove(); g_compute_decode_buffer.remove(); g_deswizzle_scratch_buffer.remove(); + g_blitter.destroy(); + g_hw_blitter = nullptr; } template diff --git a/rpcs3/Emu/RSX/GL/GLTexture.h b/rpcs3/Emu/RSX/GL/GLTexture.h index 10c26dc536..7b3ff73db4 100644 --- a/rpcs3/Emu/RSX/GL/GLTexture.h +++ b/rpcs3/Emu/RSX/GL/GLTexture.h @@ -86,5 +86,6 @@ namespace gl extern std::unique_ptr g_vis_texture; } + void init_global_texture_resources(); void destroy_global_texture_resources(); } diff --git a/rpcs3/Emu/RSX/GL/GLTextureCache.h b/rpcs3/Emu/RSX/GL/GLTextureCache.h index d4e50fd066..6d724c216f 100644 --- a/rpcs3/Emu/RSX/GL/GLTextureCache.h +++ b/rpcs3/Emu/RSX/GL/GLTextureCache.h @@ -431,9 +431,7 @@ namespace gl using gl::viewable_image::viewable_image; }; - blitter m_hw_blitter; std::vector> m_temporary_surfaces; - const u32 max_cached_image_pool_size = 256; private: @@ -815,16 +813,11 @@ namespace gl using baseclass::texture_cache; void initialize() - { - m_hw_blitter.init(); - g_hw_blitter = &m_hw_blitter; - } + {} void destroy() override { clear(); - g_hw_blitter = nullptr; - m_hw_blitter.destroy(); } bool is_depth_texture(u32 rsx_address, u32 rsx_size) override @@ -870,7 +863,7 @@ namespace gl bool blit(gl::command_context& cmd, const rsx::blit_src_info& src, const rsx::blit_dst_info& dst, bool linear_interpolate, gl_render_targets& m_rtts) { - auto result = upload_scaled_image(src, dst, linear_interpolate, cmd, m_rtts, m_hw_blitter); + auto result = upload_scaled_image(src, dst, linear_interpolate, cmd, m_rtts, *g_hw_blitter); if (result.succeeded) { From 8651875e5971a6db9ac7bc253be7493f65f9ef12 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Mon, 9 Mar 2026 22:08:43 +0300 Subject: [PATCH 139/175] gl: Add optional row length to GPU image routines --- rpcs3/Emu/RSX/GL/GLCompute.cpp | 6 ++-- rpcs3/Emu/RSX/GL/GLOverlays.cpp | 3 +- rpcs3/Emu/RSX/GL/GLTexture.cpp | 46 +++++++++++++++---------------- rpcs3/Emu/RSX/GL/GLTexture.h | 4 ++- rpcs3/Emu/RSX/GL/GLTextureCache.h | 6 ++-- 5 files changed, 34 insertions(+), 31 deletions(-) diff --git a/rpcs3/Emu/RSX/GL/GLCompute.cpp b/rpcs3/Emu/RSX/GL/GLCompute.cpp index 5607c149ed..fd31708df7 100644 --- a/rpcs3/Emu/RSX/GL/GLCompute.cpp +++ b/rpcs3/Emu/RSX/GL/GLCompute.cpp @@ -340,7 +340,7 @@ namespace gl void cs_d24x8_to_ssbo::run(gl::command_context& cmd, gl::viewable_image* src, const gl::buffer* dst, u32 out_offset, const coordu& region, const gl::pixel_buffer_layout& layout) { - const auto row_pitch = region.width; + const auto row_pitch = layout.row_length ? layout.row_length : region.width; m_program.uniforms["swap_bytes"] = layout.swap_bytes; m_program.uniforms["output_pitch"] = row_pitch; @@ -390,14 +390,14 @@ namespace gl void cs_rgba8_to_ssbo::run(gl::command_context& cmd, gl::viewable_image* src, const gl::buffer* dst, u32 out_offset, const coordu& region, const gl::pixel_buffer_layout& layout) { - const auto row_pitch = region.width; + const auto row_pitch = layout.row_length ? layout.row_length : region.width; m_program.uniforms["swap_bytes"] = layout.swap_bytes; m_program.uniforms["output_pitch"] = row_pitch; m_program.uniforms["region_offset"] = color2i(region.x, region.y); m_program.uniforms["region_size"] = color2i(region.width, region.height); m_program.uniforms["is_bgra"] = (layout.format == static_cast(gl::texture::format::bgra)); - m_program.uniforms["block_width"] = static_cast(layout.size); + m_program.uniforms["block_width"] = static_cast(layout.block_size); auto data_view = src->get_view(rsx::default_remap_vector.with_encoding(GL_REMAP_IDENTITY), gl::image_aspect::color); diff --git a/rpcs3/Emu/RSX/GL/GLOverlays.cpp b/rpcs3/Emu/RSX/GL/GLOverlays.cpp index 0c4732430c..6be9aba6a0 100644 --- a/rpcs3/Emu/RSX/GL/GLOverlays.cpp +++ b/rpcs3/Emu/RSX/GL/GLOverlays.cpp @@ -551,7 +551,8 @@ namespace gl const pixel_buffer_layout& layout) { const u32 bpp = dst->image()->pitch() / dst->image()->width(); - const u32 row_length = utils::align(dst_region.width * bpp, std::max(layout.alignment, 1)) / bpp; + const u32 aligned_width = utils::align(dst_region.width * bpp, std::max(layout.alignment, 1)) / bpp; + const u32 row_length = layout.row_length ? layout.row_length : aligned_width; program_handle.uniforms["src_pitch"] = row_length; program_handle.uniforms["swap_bytes"] = layout.swap_bytes; diff --git a/rpcs3/Emu/RSX/GL/GLTexture.cpp b/rpcs3/Emu/RSX/GL/GLTexture.cpp index 5dfc663c68..5c85f71c2e 100644 --- a/rpcs3/Emu/RSX/GL/GLTexture.cpp +++ b/rpcs3/Emu/RSX/GL/GLTexture.cpp @@ -166,42 +166,42 @@ namespace gl case texture::internal_format::compressed_rgba_s3tc_dxt1: case texture::internal_format::compressed_rgba_s3tc_dxt3: case texture::internal_format::compressed_rgba_s3tc_dxt5: - return { GL_RGBA, GL_UNSIGNED_BYTE, 1, false }; + return { .format = GL_RGBA, .type = GL_UNSIGNED_BYTE, .block_size = 1, .swap_bytes = false }; case texture::internal_format::r8: - return { GL_RED, GL_UNSIGNED_BYTE, 1, false }; + return { .format = GL_RED, .type = GL_UNSIGNED_BYTE, .block_size = 1, .swap_bytes = false }; case texture::internal_format::r16: - return { GL_RED, GL_UNSIGNED_SHORT, 2, true }; + return { .format = GL_RED, .type = GL_UNSIGNED_SHORT, .block_size = 2, .swap_bytes = true }; case texture::internal_format::r32f: - return { GL_RED, GL_FLOAT, 4, true }; + return { .format = GL_RED, .type = GL_FLOAT, .block_size = 4, .swap_bytes = true }; case texture::internal_format::rg8: - return { GL_RG, GL_UNSIGNED_SHORT, 2, true }; + return { .format = GL_RG, .type = GL_UNSIGNED_SHORT, .block_size = 2, .swap_bytes = true }; case texture::internal_format::rg16: - return { GL_RG, GL_UNSIGNED_SHORT, 2, true }; + return { .format = GL_RG, .type = GL_UNSIGNED_SHORT, .block_size = 2, .swap_bytes = true }; case texture::internal_format::rg16f: - return { GL_RG, GL_HALF_FLOAT, 2, true }; + return { .format = GL_RG, .type = GL_HALF_FLOAT, .block_size = 2, .swap_bytes = true }; case texture::internal_format::rgb565: - return { GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 2, true }; + return { .format = GL_RGB, .type = GL_UNSIGNED_SHORT_5_6_5, .block_size = 2, .swap_bytes = true }; case texture::internal_format::rgb5a1: - return { GL_RGB, GL_UNSIGNED_SHORT_5_5_5_1, 2, true }; + return { .format = GL_RGB, .type = GL_UNSIGNED_SHORT_5_5_5_1, .block_size = 2, .swap_bytes = true }; case texture::internal_format::bgr5a1: - return { GL_RGB, GL_UNSIGNED_SHORT_1_5_5_5_REV, 2, true }; + return { .format = GL_RGB, .type = GL_UNSIGNED_SHORT_1_5_5_5_REV, .block_size = 2, .swap_bytes = true }; case texture::internal_format::rgba4: - return { GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4, 2, false }; + return { .format = GL_BGRA, .type = GL_UNSIGNED_SHORT_4_4_4_4, .block_size = 2, .swap_bytes = false }; case texture::internal_format::rgba8: - return { GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 4, true }; + return { .format = GL_RGBA, .type = GL_UNSIGNED_INT_8_8_8_8_REV, .block_size = 4, .swap_bytes = true }; case texture::internal_format::bgra8: - return { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 4, true }; + return { .format = GL_BGRA, .type = GL_UNSIGNED_INT_8_8_8_8_REV, .block_size = 4, .swap_bytes = true }; case texture::internal_format::rgba16f: - return { GL_RGBA, GL_HALF_FLOAT, 2, true }; + return { .format = GL_RGBA, .type = GL_HALF_FLOAT, .block_size = 2, .swap_bytes = true }; case texture::internal_format::rgba32f: - return { GL_RGBA, GL_FLOAT, 4, true }; + return { .format = GL_RGBA, .type = GL_FLOAT, .block_size = 4, .swap_bytes = true }; case texture::internal_format::depth16: - return { GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 2, true }; + return { .format = GL_DEPTH_COMPONENT, .type = GL_UNSIGNED_SHORT, .block_size = 2, .swap_bytes = true }; case texture::internal_format::depth32f: - return { GL_DEPTH_COMPONENT, GL_FLOAT, 2, true }; + return { .format = GL_DEPTH_COMPONENT, .type = GL_FLOAT, .block_size = 2, .swap_bytes = true }; case texture::internal_format::depth24_stencil8: case texture::internal_format::depth32f_stencil8: - return { GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4, true }; + return { .format = GL_DEPTH_STENCIL, .type = GL_UNSIGNED_INT_24_8, .block_size = 4, .swap_bytes = true }; default: fmt::throw_exception("Unexpected internal format 0x%X", static_cast(format)); } @@ -320,7 +320,7 @@ namespace gl return nullptr; } - switch (pack_info.size) + switch (pack_info.block_size) { case 1: return nullptr; @@ -780,7 +780,7 @@ namespace gl mem_layout.swap_bytes = op.require_swap; mem_layout.format = gl_format; mem_layout.type = gl_type; - mem_layout.size = block_size_in_bytes; + mem_layout.block_size = block_size_in_bytes; // 2. Upload memory to GPU if (!op.require_deswizzle) @@ -1061,7 +1061,7 @@ namespace gl skip_transform = (pack_info.format == unpack_info.format && pack_info.type == unpack_info.type && pack_info.swap_bytes == unpack_info.swap_bytes && - pack_info.size == unpack_info.size); + pack_info.block_size == unpack_info.block_size); } if (skip_transform) [[likely]] @@ -1142,7 +1142,7 @@ namespace gl if (src->aspect() & image_aspect::depth) { // Source is depth, modify unpack rule - if (pack_info.size == 4 && unpack_info.size == 4) + if (pack_info.block_size == 4 && unpack_info.block_size == 4) { unpack_info.swap_bytes = !unpack_info.swap_bytes; } @@ -1150,7 +1150,7 @@ namespace gl else { // Dest is depth, modify pack rule - if (pack_info.size == 4 && unpack_info.size == 4) + if (pack_info.block_size == 4 && unpack_info.block_size == 4) { pack_info.swap_bytes = !pack_info.swap_bytes; } diff --git a/rpcs3/Emu/RSX/GL/GLTexture.h b/rpcs3/Emu/RSX/GL/GLTexture.h index 7b3ff73db4..4a17dae081 100644 --- a/rpcs3/Emu/RSX/GL/GLTexture.h +++ b/rpcs3/Emu/RSX/GL/GLTexture.h @@ -16,9 +16,11 @@ namespace gl { GLenum format; GLenum type; - u8 size; + u32 row_length; + u8 block_size; bool swap_bytes; u8 alignment; + u8 reserved; }; struct image_memory_requirements diff --git a/rpcs3/Emu/RSX/GL/GLTextureCache.h b/rpcs3/Emu/RSX/GL/GLTextureCache.h index 6d724c216f..1a4b4f9e1e 100644 --- a/rpcs3/Emu/RSX/GL/GLTextureCache.h +++ b/rpcs3/Emu/RSX/GL/GLTextureCache.h @@ -186,7 +186,7 @@ namespace gl pack_info.format = static_cast(format); pack_info.type = static_cast(type); - pack_info.size = (src->aspect() & image_aspect::stencil) ? 4 : 2; + pack_info.block_size = (src->aspect() & image_aspect::stencil) ? 4 : 2; pack_info.swap_bytes = true; mem_info.image_size_in_texels = src->width() * src->height(); @@ -204,8 +204,8 @@ namespace gl glBindBuffer(GL_SHADER_STORAGE_BUFFER, GL_NONE); glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); - real_pitch = pack_info.size * src->width(); - const u64 data_length = pack_info.size * mem_info.image_size_in_texels; + real_pitch = pack_info.block_size * src->width(); + const u64 data_length = pack_info.block_size * mem_info.image_size_in_texels; scratch_mem.copy_to(&pbo, reinterpret_cast(out_offset), 0, data_length); } else From 7917520633490458968b833e93131bb5c8207d54 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Mon, 9 Mar 2026 22:20:39 +0300 Subject: [PATCH 140/175] gl: Support packing/unpacking images with padding --- rpcs3/Emu/RSX/GL/GLTexture.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/rpcs3/Emu/RSX/GL/GLTexture.cpp b/rpcs3/Emu/RSX/GL/GLTexture.cpp index 5c85f71c2e..64e451e579 100644 --- a/rpcs3/Emu/RSX/GL/GLTexture.cpp +++ b/rpcs3/Emu/RSX/GL/GLTexture.cpp @@ -372,7 +372,10 @@ namespace gl } } - src->copy_to(*dst, dst_offset, static_cast(pack_info.format), static_cast(pack_info.type), src_level, src_region, {}); + pixel_pack_settings pack_settings{}; + if (pack_info.alignment) pack_settings.alignment(pack_info.alignment); + if (pack_info.row_length) pack_settings.row_length(pack_info.row_length); + src->copy_to(*dst, dst_offset, static_cast(pack_info.format), static_cast(pack_info.type), src_level, src_region, pack_settings); return false; }; @@ -620,8 +623,11 @@ namespace gl glBindBuffer(GL_SHADER_STORAGE_BUFFER, GL_NONE); + pixel_unpack_settings unpack_settings{}; + if (unpack_info.alignment) unpack_settings.alignment(unpack_info.alignment); + if (unpack_info.format) unpack_settings.row_length(unpack_info.row_length); dst->copy_from(*transfer_buf, out_offset, static_cast(unpack_info.format), - static_cast(unpack_info.type), dst_level, dst_region, {}); + static_cast(unpack_info.type), dst_level, dst_region, unpack_settings); } } From aa094ca9487873cb6c960b6e2125f53bb31fc887 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Tue, 10 Mar 2026 03:06:08 +0300 Subject: [PATCH 141/175] gl: Trace memory readback operations to debug tracking when renderdoc compat is enabled - Renderdoc does not show these calls so we need to insert the debug message --- rpcs3/Emu/RSX/GL/glutils/capabilities.cpp | 3 +++ rpcs3/Emu/RSX/GL/glutils/capabilities.h | 1 + rpcs3/Emu/RSX/GL/glutils/image.cpp | 8 ++++++++ 3 files changed, 12 insertions(+) diff --git a/rpcs3/Emu/RSX/GL/glutils/capabilities.cpp b/rpcs3/Emu/RSX/GL/glutils/capabilities.cpp index d6a51beb09..a6999d6f9c 100644 --- a/rpcs3/Emu/RSX/GL/glutils/capabilities.cpp +++ b/rpcs3/Emu/RSX/GL/glutils/capabilities.cpp @@ -2,6 +2,7 @@ #include "capabilities.h" #include "Utilities/StrUtil.h" +#include "Emu/system_config.h" #include @@ -43,6 +44,8 @@ namespace gl all_extensions.emplace(reinterpret_cast(glGetStringi(GL_EXTENSIONS, i))); } + RENDERDOC_debug = !!g_cfg.video.renderdoc_compatiblity; + #define CHECK_EXTENSION_SUPPORT(extension_short_name)\ do {\ if (all_extensions.contains("GL_"#extension_short_name)) {\ diff --git a/rpcs3/Emu/RSX/GL/glutils/capabilities.h b/rpcs3/Emu/RSX/GL/glutils/capabilities.h index 756250430b..cfe104ffbe 100644 --- a/rpcs3/Emu/RSX/GL/glutils/capabilities.h +++ b/rpcs3/Emu/RSX/GL/glutils/capabilities.h @@ -23,6 +23,7 @@ namespace gl bool initialized = false; version_info glsl_version; + bool RENDERDOC_debug = false; bool EXT_direct_state_access_supported = false; bool EXT_depth_bounds_test_supported = false; bool AMD_pinned_memory_supported = false; diff --git a/rpcs3/Emu/RSX/GL/glutils/image.cpp b/rpcs3/Emu/RSX/GL/glutils/image.cpp index e99a6e15b2..7dd3442f84 100644 --- a/rpcs3/Emu/RSX/GL/glutils/image.cpp +++ b/rpcs3/Emu/RSX/GL/glutils/image.cpp @@ -246,6 +246,14 @@ namespace gl pixel_settings.apply(); const auto& caps = get_driver_caps(); + if (caps.RENDERDOC_debug) + { + const auto msg = fmt::format("glGetTextureSubImage('[%u] %s', %u, %u, %u, %u, %u, %u, %u, %u, %u, %d, %p)", + m_id, m_name.c_str(), level, region.x, region.y, region.z, region.width, region.height, region.depth, + static_cast(format), static_cast(type), s32{ smax }, dst.data()); + push_debug_label(msg); + } + if (!region.x && !region.y && !region.z && region.width == m_width && region.height == m_height && region.depth == m_depth) { From 040a79ddd1794bf9ba09b3f0d09cfad1b993038b Mon Sep 17 00:00:00 2001 From: kd-11 Date: Tue, 10 Mar 2026 04:03:17 +0300 Subject: [PATCH 142/175] gl: Improve object annotation for renderdoc debugging --- rpcs3/Emu/RSX/GL/GLRenderTargets.cpp | 2 ++ rpcs3/Emu/RSX/GL/GLRenderTargets.h | 5 +++ rpcs3/Emu/RSX/GL/glutils/image.cpp | 52 ++++++++++++++++++++++++++-- 3 files changed, 57 insertions(+), 2 deletions(-) diff --git a/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp b/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp index 18058842aa..a61fb4b365 100644 --- a/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp +++ b/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp @@ -689,6 +689,8 @@ gl::viewable_image* gl::render_target::get_resolve_target_safe(gl::command_conte static_cast(get_internal_format()), format_class() )); + + resolve_surface->set_name(fmt::format("MSAA_Resolve_%u@0x%x", resolve_surface->id(), base_addr)); } return static_cast(resolve_surface.get()); diff --git a/rpcs3/Emu/RSX/GL/GLRenderTargets.h b/rpcs3/Emu/RSX/GL/GLRenderTargets.h index 9b01746a87..ee3bc03956 100644 --- a/rpcs3/Emu/RSX/GL/GLRenderTargets.h +++ b/rpcs3/Emu/RSX/GL/GLRenderTargets.h @@ -160,6 +160,7 @@ struct gl_render_target_traits std::unique_ptr result(new gl::render_target(width_, height_, samples, static_cast(format.internal_format), RSX_FORMAT_CLASS_COLOR)); + result->set_name(fmt::format("RTV_%u@0x%x", result->id(), address)); result->set_aa_mode(antialias); result->set_native_pitch(static_cast(width) * get_format_block_size_in_bytes(surface_color_format) * result->samples_x); result->set_surface_dimensions(static_cast(width), static_cast(height), static_cast(pitch)); @@ -203,6 +204,7 @@ struct gl_render_target_traits std::unique_ptr result(new gl::render_target(width_, height_, samples, static_cast(format.internal_format), rsx::classify_format(surface_depth_format))); + result->set_name(fmt::format("DSV_%u@0x%x", result->id(), address)); result->set_aa_mode(antialias); result->set_surface_dimensions(static_cast(width), static_cast(height), static_cast(pitch)); result->set_format(surface_depth_format); @@ -238,6 +240,7 @@ struct gl_render_target_traits sink->state_flags = rsx::surface_state_flags::erase_bkgnd; sink->format_info = ref->format_info; + sink->set_name(fmt::format("SINK_%u@0x%x", sink->id(), address)); sink->set_spp(ref->get_spp()); sink->set_native_pitch(static_cast(prev.width) * ref->get_bpp() * ref->samples_x); sink->set_rsx_pitch(ref->get_rsx_pitch()); @@ -325,6 +328,7 @@ struct gl_render_target_traits std::array native_layout = { static_cast(fmt.swizzle.a), static_cast(fmt.swizzle.r), static_cast(fmt.swizzle.g), static_cast(fmt.swizzle.b) }; surface->set_native_component_layout(native_layout); surface->set_format(format); + surface->set_name(fmt::format("RTV_%u@0x%x", surface->id(), address)); int_invalidate_surface_contents(cmd, surface, address, pitch); } @@ -338,6 +342,7 @@ struct gl_render_target_traits usz pitch) { surface->set_format(format); + surface->set_name(fmt::format("DSV_%u@0x%x", surface->id(), address)); int_invalidate_surface_contents(cmd, surface, address, pitch); } diff --git a/rpcs3/Emu/RSX/GL/glutils/image.cpp b/rpcs3/Emu/RSX/GL/glutils/image.cpp index 7dd3442f84..e2f02afdfa 100644 --- a/rpcs3/Emu/RSX/GL/glutils/image.cpp +++ b/rpcs3/Emu/RSX/GL/glutils/image.cpp @@ -19,6 +19,54 @@ namespace gl } } + static const char* gl_type_to_str(texture::type type) + { + switch (type) + { + case texture::type::ubyte: return "GL_UNSIGNED_BYTE"; + case texture::type::ushort: return "GL_UNSIGNED_SHORT"; + case texture::type::uint: return "GL_UNSIGNED_INT"; + case texture::type::ubyte_3_3_2: return "GL_UNSIGNED_BYTE_3_3_2"; + case texture::type::ubyte_2_3_3_rev: return "GL_UNSIGNED_BYTE_2_3_3_REV"; + case texture::type::ushort_5_6_5: return "GL_UNSIGNED_SHORT_5_6_5"; + case texture::type::ushort_5_6_5_rev: return "GL_UNSIGNED_SHORT_5_6_5_REV"; + case texture::type::ushort_4_4_4_4: return "GL_UNSIGNED_SHORT_4_4_4_4"; + case texture::type::ushort_4_4_4_4_rev: return "GL_UNSIGNED_SHORT_4_4_4_4_REV"; + case texture::type::ushort_5_5_5_1: return "GL_UNSIGNED_SHORT_5_5_5_1"; + case texture::type::ushort_1_5_5_5_rev: return "GL_UNSIGNED_SHORT_1_5_5_5_REV"; + case texture::type::uint_8_8_8_8: return "GL_UNSIGNED_INT_8_8_8_8"; + case texture::type::uint_8_8_8_8_rev: return "GL_UNSIGNED_INT_8_8_8_8_REV"; + case texture::type::uint_10_10_10_2: return "GL_UNSIGNED_INT_10_10_10_2"; + case texture::type::uint_2_10_10_10_rev: return "GL_UNSIGNED_INT_2_10_10_10_REV"; + case texture::type::uint_24_8: return "GL_UNSIGNED_INT_24_8"; + case texture::type::float32_uint8: return "GL_FLOAT_32_UNSIGNED_INT_24_8_REV"; + case texture::type::sbyte: return "GL_BYTE"; + case texture::type::sshort: return "GL_SHORT"; + case texture::type::sint: return "GL_INT"; + case texture::type::f16: return "GL_HALF_FLOAT"; + case texture::type::f32: return "GL_FLOAT"; + case texture::type::f64: return "GL_DOUBLE"; + default: return "UNKNOWN"; + } + } + + static const char* gl_format_to_str(texture::format format) + { + switch (format) + { + case texture::format::r: return "GL_RED"; + case texture::format::rg: return "GL_RG"; + case texture::format::rgb: return "GL_RGB"; + case texture::format::rgba: return "GL_RGBA"; + case texture::format::bgr: return "GL_BGR"; + case texture::format::bgra: return "GL_BGRA"; + case texture::format::stencil: return "GL_STENCIL_INDEX"; + case texture::format::depth: return "GL_DEPTH_COMPONENT"; + case texture::format::depth_stencil: return "GL_DEPTH_STENCIL"; + default: return "UNKNOWN"; + } + } + texture::texture(GLenum target, GLuint width, GLuint height, GLuint depth, GLuint mipmaps, GLubyte samples, GLenum sized_format, rsx::format_class format_class) { // Upgrade targets for MSAA @@ -248,9 +296,9 @@ namespace gl if (caps.RENDERDOC_debug) { - const auto msg = fmt::format("glGetTextureSubImage('[%u] %s', %u, %u, %u, %u, %u, %u, %u, %u, %u, %d, %p)", + const auto msg = fmt::format("glGetTextureSubImage('[%u] %s', %u, %u, %u, %u, %u, %u, %u, %s, %s, %d, %p)", m_id, m_name.c_str(), level, region.x, region.y, region.z, region.width, region.height, region.depth, - static_cast(format), static_cast(type), s32{ smax }, dst.data()); + gl_format_to_str(format), gl_type_to_str(type), s32{ smax }, dst.data()); push_debug_label(msg); } From c72d54bd6aa3d7aa21dade03301b297be40d26fc Mon Sep 17 00:00:00 2001 From: kd-11 Date: Tue, 10 Mar 2026 04:03:48 +0300 Subject: [PATCH 143/175] gl: Add guards to catch invalid configuration in image transfer functions --- rpcs3/Emu/RSX/GL/GLCompute.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rpcs3/Emu/RSX/GL/GLCompute.cpp b/rpcs3/Emu/RSX/GL/GLCompute.cpp index fd31708df7..12d10d2368 100644 --- a/rpcs3/Emu/RSX/GL/GLCompute.cpp +++ b/rpcs3/Emu/RSX/GL/GLCompute.cpp @@ -341,6 +341,7 @@ namespace gl void cs_d24x8_to_ssbo::run(gl::command_context& cmd, gl::viewable_image* src, const gl::buffer* dst, u32 out_offset, const coordu& region, const gl::pixel_buffer_layout& layout) { const auto row_pitch = layout.row_length ? layout.row_length : region.width; + ensure(row_pitch >= region.width); m_program.uniforms["swap_bytes"] = layout.swap_bytes; m_program.uniforms["output_pitch"] = row_pitch; @@ -391,6 +392,7 @@ namespace gl void cs_rgba8_to_ssbo::run(gl::command_context& cmd, gl::viewable_image* src, const gl::buffer* dst, u32 out_offset, const coordu& region, const gl::pixel_buffer_layout& layout) { const auto row_pitch = layout.row_length ? layout.row_length : region.width; + ensure(row_pitch >= region.width); m_program.uniforms["swap_bytes"] = layout.swap_bytes; m_program.uniforms["output_pitch"] = row_pitch; @@ -441,6 +443,7 @@ namespace gl { const u32 bpp = dst->image()->pitch() / dst->image()->width(); const u32 row_length = utils::align(dst_region.width * bpp, std::max(layout.alignment, 1)) / bpp; + ensure(row_length >= dst_region.width); m_program.uniforms["swap_bytes"] = layout.swap_bytes; m_program.uniforms["src_pitch"] = row_length; From c7a576edcea465e280c6708d9cb797080890313f Mon Sep 17 00:00:00 2001 From: kd-11 Date: Tue, 10 Mar 2026 04:05:33 +0300 Subject: [PATCH 144/175] gl: Implement proper, sectioned DMA transfers - Allows to transfer partial contents when needed --- rpcs3/Emu/RSX/GL/GLTextureCache.h | 61 +++++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 8 deletions(-) diff --git a/rpcs3/Emu/RSX/GL/GLTextureCache.h b/rpcs3/Emu/RSX/GL/GLTextureCache.h index 1a4b4f9e1e..a4b931186f 100644 --- a/rpcs3/Emu/RSX/GL/GLTextureCache.h +++ b/rpcs3/Emu/RSX/GL/GLTextureCache.h @@ -148,7 +148,7 @@ namespace gl } } - void dma_transfer(gl::command_context& cmd, gl::texture* src, const areai& src_area, const utils::address_range32& /*valid_range*/, u32 pitch) + void dma_transfer(gl::command_context& cmd, gl::texture* src, const areai& src_area, const utils::address_range32& valid_range, u32 pitch) { init_buffer(src); glGetError(); @@ -171,6 +171,14 @@ namespace gl { static_cast(src_area.width()), static_cast(src_area.height()), 1 } }; + u32 pbo_offset = 0; + if (valid_range.valid()) + { + const u32 section_base = get_section_base(); + pbo_offset = valid_range.start - section_base; + ensure(valid_range.start >= section_base && pbo_offset <= pbo.size()); + } + bool use_driver_pixel_transform = true; if (get_driver_caps().ARB_compute_shader_supported) [[likely]] { @@ -188,9 +196,10 @@ namespace gl pack_info.type = static_cast(type); pack_info.block_size = (src->aspect() & image_aspect::stencil) ? 4 : 2; pack_info.swap_bytes = true; + pack_info.row_length = rsx_pitch / pack_info.block_size; - mem_info.image_size_in_texels = src->width() * src->height(); - mem_info.image_size_in_bytes = src->pitch() * src->height(); + mem_info.image_size_in_texels = pack_info.row_length * src_area.height(); + mem_info.image_size_in_bytes = rsx_pitch * src_area.height(); mem_info.memory_required = 0; if (pack_info.type == GL_FLOAT_32_UNSIGNED_INT_24_8_REV) @@ -200,13 +209,15 @@ namespace gl } void* out_offset = copy_image_to_buffer(cmd, pack_info, src, &scratch_mem, 0, 0, src_rgn, &mem_info); + real_pitch = rsx_pitch; glBindBuffer(GL_SHADER_STORAGE_BUFFER, GL_NONE); glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); - real_pitch = pack_info.block_size * src->width(); - const u64 data_length = pack_info.block_size * mem_info.image_size_in_texels; - scratch_mem.copy_to(&pbo, reinterpret_cast(out_offset), 0, data_length); + const u64 data_length = mem_info.image_size_in_bytes - rsx_pitch + (src_area.width() * pack_info.block_size); + ensure(data_length + pbo_offset <= static_cast(pbo.size()), "Memory allocation cannot fit image contents. Report to developers."); + + scratch_mem.copy_to(&pbo, reinterpret_cast(out_offset), pbo_offset, data_length); } else { @@ -225,11 +236,16 @@ namespace gl pack_unpack_swap_bytes = false; } + const auto bpp = src->pitch() / src->width(); + real_pitch = rsx_pitch; + ensure((real_pitch % bpp) == 0); + pixel_pack_settings pack_settings; pack_settings.alignment(1); pack_settings.swap_bytes(pack_unpack_swap_bytes); + pack_settings.row_length(rsx_pitch / bpp); - src->copy_to(pbo, 0, format, type, 0, src_rgn, pack_settings); + src->copy_to(pbo, pbo_offset, format, type, 0, src_rgn, pack_settings); } if (auto error = glGetError()) @@ -270,6 +286,7 @@ namespace gl gl::texture* target_texture = vram_texture; u32 transfer_width = width; u32 transfer_height = height; + u32 transfer_x = 0, transfer_y = 0; if (context == rsx::texture_upload_context::framebuffer_storage) { @@ -315,7 +332,35 @@ namespace gl } } - dma_transfer(cmd, target_texture, {}, {}, rsx_pitch); + const auto valid_range = get_confirmed_range(); + if (const auto section_range = get_section_range(); section_range != valid_range) + { + if (const auto offset = (valid_range.start - get_section_base())) + { + transfer_y = offset / rsx_pitch; + transfer_x = (offset % rsx_pitch) / rsx::get_format_block_size_in_bytes(gcm_format); + + ensure(transfer_width >= transfer_x); + ensure(transfer_height >= transfer_y); + transfer_width -= transfer_x; + transfer_height -= transfer_y; + } + + if (const auto tail = (section_range.end - valid_range.end)) + { + const auto row_count = tail / rsx_pitch; + + ensure(transfer_height >= row_count); + transfer_height -= row_count; + } + } + + areai src_area; + src_area.x1 = static_cast(transfer_x); + src_area.y1 = static_cast(transfer_y); + src_area.x2 = s32(transfer_x + transfer_width); + src_area.y2 = s32(transfer_y + transfer_height); + dma_transfer(cmd, target_texture, src_area, valid_range, rsx_pitch); } /** From 8afa40eaa7d55c158d71baccd693179eb9f06650 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Tue, 10 Mar 2026 16:43:20 +0100 Subject: [PATCH 145/175] rpcn: Fix segfault in rpcn_settings_dialog destructor This will happen if m_rpcn failed to connect in the constructor. --- rpcs3/rpcs3qt/rpcn_settings_dialog.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/rpcs3/rpcs3qt/rpcn_settings_dialog.cpp b/rpcs3/rpcs3qt/rpcn_settings_dialog.cpp index 6de6007b31..cab71be3bc 100644 --- a/rpcs3/rpcs3qt/rpcn_settings_dialog.cpp +++ b/rpcs3/rpcs3qt/rpcn_settings_dialog.cpp @@ -1347,7 +1347,10 @@ rpcn_friends_dialog::rpcn_friends_dialog(QWidget* parent) rpcn_friends_dialog::~rpcn_friends_dialog() { - m_rpcn->remove_friend_cb(friend_callback, this); + if (m_rpcn) + { + m_rpcn->remove_friend_cb(friend_callback, this); + } } bool rpcn_friends_dialog::add_friend_with_error_dialog(const std::string& friend_username) From 3803c864f747b2d64fdb4531c4a78c9c05cc1c87 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Tue, 10 Mar 2026 16:26:40 +0100 Subject: [PATCH 146/175] rpcn: Fix file access error when loading rpcn.yml with version 1 The file was still in use when saving. --- rpcs3/Emu/NP/rpcn_config.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/rpcs3/Emu/NP/rpcn_config.cpp b/rpcs3/Emu/NP/rpcn_config.cpp index 0b5cabe768..6665adbf7d 100644 --- a/rpcs3/Emu/NP/rpcn_config.cpp +++ b/rpcs3/Emu/NP/rpcn_config.cpp @@ -10,8 +10,7 @@ void cfg_rpcn::load() { const std::string path = cfg_rpcn::get_path(); - fs::file cfg_file(path, fs::read); - if (cfg_file) + if (fs::file cfg_file(path, fs::read); cfg_file) { rpcn_log.notice("Loading RPCN config. Path: %s", path); from_string(cfg_file.to_string()); From 9e573a9ff2083800444251a508d9f44800b4e1e6 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Tue, 10 Mar 2026 16:26:56 +0100 Subject: [PATCH 147/175] rpcn: set default version to 2 --- rpcs3/Emu/NP/rpcn_config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpcs3/Emu/NP/rpcn_config.h b/rpcs3/Emu/NP/rpcn_config.h index 3ea6b707b1..113d83e408 100644 --- a/rpcs3/Emu/NP/rpcn_config.h +++ b/rpcs3/Emu/NP/rpcn_config.h @@ -4,7 +4,7 @@ struct cfg_rpcn : cfg::node { - cfg::uint32 version{this, "Version", 1}; + cfg::uint32 version{this, "Version", 2}; cfg::string host{this, "Host", "np.rpcs3.net"}; cfg::string npid{this, "NPID", ""}; cfg::string password{this, "Password", ""}; From 234f2b4648b38e41aa236752e5e5dde1f4af4360 Mon Sep 17 00:00:00 2001 From: Elad <18193363+elad335@users.noreply.github.com> Date: Sat, 7 Mar 2026 09:46:22 +0200 Subject: [PATCH 148/175] Silence sys_memory_get_user_memory_size --- rpcs3/Emu/Cell/lv2/sys_memory.cpp | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/rpcs3/Emu/Cell/lv2/sys_memory.cpp b/rpcs3/Emu/Cell/lv2/sys_memory.cpp index 6110d7d4d5..0f6fb09865 100644 --- a/rpcs3/Emu/Cell/lv2/sys_memory.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_memory.cpp @@ -15,6 +15,18 @@ LOG_CHANNEL(sys_memory); // static shared_mutex s_memstats_mtx; +// This struct is for reduced logging repetition +struct last_reported_memory_stats +{ + struct inner_body + { + u32 prev_total = umax; + u32 prev_avail = umax; + }; + + atomic_t body{}; +}; + lv2_memory_container::lv2_memory_container(u32 size, bool from_idm) noexcept : size(size) , id{from_idm ? idm::last_id() : SYS_MEMORY_CONTAINER_ID_INVALID} @@ -313,8 +325,6 @@ error_code sys_memory_get_user_memory_size(cpu_thread& cpu, vm::ptrget(); @@ -332,6 +342,22 @@ error_code sys_memory_get_user_memory_size(cpu_thread& cpu, vm::ptrget().body.exchange(now); + + if (now.prev_total != out.total_user_memory || now.prev_avail != out.available_user_memory) + { + // Log on change + sys_memory.warning("sys_memory_get_user_memory_size(mem_info=*0x%x): Avail=0x%x, Total=0x%x", mem_info, out.available_user_memory, out.total_user_memory); + } + else + { + sys_memory.trace("sys_memory_get_user_memory_size(mem_info=*0x%x): Avail=0x%x, Total=0x%x", mem_info, out.available_user_memory, out.total_user_memory); + } + cpu.check_state(); *mem_info = out; return CELL_OK; From 9811e1cc3b5bf025ec38551faa81e37035e39bea Mon Sep 17 00:00:00 2001 From: Elad <18193363+elad335@users.noreply.github.com> Date: Sun, 1 Mar 2026 10:07:25 +0200 Subject: [PATCH 149/175] Debugger: Add HW PPU threads view --- rpcs3/Emu/CPU/CPUThread.cpp | 2 +- rpcs3/Emu/Cell/lv2/lv2.cpp | 22 +++++ rpcs3/Emu/Cell/lv2/sys_sync.h | 1 + rpcs3/rpcs3qt/debugger_frame.cpp | 155 +++++++++++++++++++++++++------ rpcs3/rpcs3qt/debugger_frame.h | 7 +- 5 files changed, 156 insertions(+), 31 deletions(-) diff --git a/rpcs3/Emu/CPU/CPUThread.cpp b/rpcs3/Emu/CPU/CPUThread.cpp index e37e6ed0da..3ab011aa04 100644 --- a/rpcs3/Emu/CPU/CPUThread.cpp +++ b/rpcs3/Emu/CPU/CPUThread.cpp @@ -1373,7 +1373,7 @@ std::vector> cpu_thread::dump_callstack_list() const std::string cpu_thread::dump_misc() const { - return fmt::format("Type: %s; State: %s\n", get_class() == thread_class::ppu ? "PPU" : get_class() == thread_class::spu ? "SPU" : "RSX", state.load()); + return fmt::format("%s[0x%x]; State: %s\n", get_class() == thread_class::ppu ? "PPU" : get_class() == thread_class::spu ? "SPU" : "RSX", id, state.load()); } bool cpu_thread::suspend_work::push(cpu_thread* _this) noexcept diff --git a/rpcs3/Emu/Cell/lv2/lv2.cpp b/rpcs3/Emu/Cell/lv2/lv2.cpp index 3b923e8c41..dbe11039e7 100644 --- a/rpcs3/Emu/Cell/lv2/lv2.cpp +++ b/rpcs3/Emu/Cell/lv2/lv2.cpp @@ -2219,6 +2219,28 @@ void lv2_obj::prepare_for_sleep(cpu_thread& cpu) cpu_counter::remove(&cpu); } +ppu_thread* lv2_obj::get_running_ppu(u32 index) +{ + usz thread_count = g_cfg.core.ppu_threads; + + if (index >= thread_count) + { + return nullptr; + } + + auto target = atomic_storage::load(g_ppu); + + for (usz cur = 0; target; target = atomic_storage::load(target->next_ppu), cur++) + { + if (cur == index) + { + return target; + } + } + + return nullptr; +} + void lv2_obj::notify_all() noexcept { for (auto cpu : g_to_notify) diff --git a/rpcs3/Emu/Cell/lv2/sys_sync.h b/rpcs3/Emu/Cell/lv2/sys_sync.h index 0aff5e1e7a..6d55f4b1f0 100644 --- a/rpcs3/Emu/Cell/lv2/sys_sync.h +++ b/rpcs3/Emu/Cell/lv2/sys_sync.h @@ -453,6 +453,7 @@ public: // Can be called before the actual sleep call in order to move it out of mutex scope static void prepare_for_sleep(cpu_thread& cpu); + static ppu_thread* get_running_ppu(u32 index); struct notify_all_t { diff --git a/rpcs3/rpcs3qt/debugger_frame.cpp b/rpcs3/rpcs3qt/debugger_frame.cpp index 7ffe1b32a2..f1dd9cf892 100644 --- a/rpcs3/rpcs3qt/debugger_frame.cpp +++ b/rpcs3/rpcs3qt/debugger_frame.cpp @@ -16,6 +16,7 @@ #include "Emu/IdManager.h" #include "Emu/RSX/RSXThread.h" #include "Emu/RSX/RSXDisAsm.h" +#include "Emu/Cell/lv2/sys_sync.h" #include "Emu/Cell/PPUAnalyser.h" #include "Emu/Cell/PPUDisAsm.h" #include "Emu/Cell/PPUThread.h" @@ -804,12 +805,47 @@ cpu_thread* debugger_frame::get_cpu() return nullptr; } + if (u32 cur = m_choice_units->currentIndex(); cur >= m_hw_ppu_idx && cur < g_cfg.core.ppu_threads + m_hw_ppu_idx) + { + reader_lock lock(lv2_obj::g_mutex); + + const auto ppu = lv2_obj::get_running_ppu(cur - m_hw_ppu_idx); + + if (ppu == m_cpu.get()) + { + // Nothing to do + } + else if (ppu) + { + m_cpu = idm::get_unlocked>(ppu->id); + } + else + { + m_cpu.reset(); + } + } + + if (!!m_disasm != !!m_cpu) + { + // Fixup for HW PPU viewer + if (m_cpu) + { + m_disasm = make_disasm(m_cpu.get(), m_cpu); + } + else + { + m_disasm.reset(); + } + + m_debugger_list->UpdateCPUData(m_disasm); + m_breakpoint_list->UpdateCPUData(m_disasm); + } + // Wait flag is raised by the thread itself, acknowledging exit if (m_cpu) { if (m_cpu->state.all_of(cpu_flag::wait + cpu_flag::exit)) { - m_cpu.reset(); return nullptr; } @@ -823,12 +859,13 @@ cpu_thread* debugger_frame::get_cpu() { if (g_fxo->try_get() != m_rsx || !m_rsx->ctrl || m_rsx->state.all_of(cpu_flag::wait + cpu_flag::exit)) { - m_rsx = nullptr; return nullptr; } + + return m_rsx; } - return m_rsx; + return nullptr; } std::function debugger_frame::make_check_cpu(cpu_thread* cpu, bool unlocked) @@ -922,19 +959,20 @@ std::function debugger_frame::make_check_cpu(cpu_thread* cpu, boo void debugger_frame::UpdateUI() { - const auto cpu = get_cpu(); + auto cpu = get_cpu(); // Refresh at a high rate during initialization (looks weird otherwise) if (m_ui_update_ctr % (cpu || m_ui_update_ctr < 200 || m_debugger_list->m_dirty_flag ? 5 : 50) == 0) { // If no change to instruction position happened, update instruction list at 20hz - ShowPC(); + ShowPC(false, cpu); } if (m_ui_update_ctr % 20 == 0 && !m_thread_list_pending_update) { // Update threads list at 5hz (low priority) UpdateUnitList(); + cpu = get_cpu(); } if (!cpu) @@ -945,12 +983,13 @@ void debugger_frame::UpdateUI() { // Update threads list (thread exited) UpdateUnitList(); + cpu = get_cpu(); } - ShowPC(); + ShowPC(false, cpu); m_last_query_state.clear(); m_last_pc = -1; - DoUpdate(); + DoUpdate(cpu); } } else if (m_ui_update_ctr % 5 == 0 || m_ui_update_ctr < m_ui_fast_update_permission_deadline) @@ -966,7 +1005,7 @@ void debugger_frame::UpdateUI() std::memcpy(m_last_query_state.data(), static_cast(cpu), size_context); m_last_pc = cia; - DoUpdate(); + DoUpdate(cpu); const bool paused = !!(cpu->state & s_pause_flags); @@ -982,7 +1021,7 @@ void debugger_frame::UpdateUI() if (m_ui_update_ctr % 5) { // Call if it hasn't been called before - ShowPC(); + ShowPC(false, cpu); } if (is_using_interpreter(cpu->get_class())) @@ -1022,9 +1061,17 @@ void debugger_frame::UpdateUnitList() } std::vector>> cpu_list; - cpu_list.reserve(threads_created >= threads_deleted ? 0 : threads_created - threads_deleted); + cpu_list.reserve(threads_created >= threads_deleted ? threads_created - threads_deleted : 0); usz reselected_index = umax; + usz hw_ppu_idx = umax; + + if (u32 cur = m_choice_units->currentIndex(); cur >= m_hw_ppu_idx && cur < g_cfg.core.ppu_threads + m_hw_ppu_idx) + { + hw_ppu_idx = cur - m_hw_ppu_idx; + } + + m_hw_ppu_idx = umax; const auto on_select = [&](u32 id, cpu_thread& cpu) { @@ -1033,7 +1080,7 @@ void debugger_frame::UpdateUnitList() // Space at the end is to pad a gap on the right cpu_list.emplace_back(QString::fromStdString((id >> 24 == 0x55 ? "RSX[0x55555555]" : cpu.get_name()) + ' '), std::move(func_cpu)); - if (old_cpu_ptr == std::addressof(cpu)) + if (old_cpu_ptr == std::addressof(cpu) && hw_ppu_idx == umax) { reselected_index = cpu_list.size() - 1; } @@ -1046,6 +1093,40 @@ void debugger_frame::UpdateUnitList() idm::select>(on_select, idm::unlocked); } + m_hw_ppu_idx = cpu_list.size() + 1; // Account for NoThreadString thread + + for (u32 i = 0; i < g_cfg.core.ppu_threads + 0u; i++) + { + std::function get_ppu_at = [index = i, cpu_storage = shared_ptr>()]() mutable + { + reader_lock lock(lv2_obj::g_mutex); + + const auto ppu = lv2_obj::get_running_ppu(index); + + if (ppu == cpu_storage.get()) + { + // Nothing to do + } + else if (ppu) + { + cpu_storage = idm::get_unlocked>(ppu->id); + } + else + { + cpu_storage.reset(); + } + + return cpu_storage.get(); + }; + + if (hw_ppu_idx == i) + { + reselected_index = cpu_list.size(); + } + + cpu_list.emplace_back(tr("HwPPU[%0]: Hardware PPU Thread #%1").arg(i + 1).arg(i + 1), std::move(get_ppu_at)); + } + if (g_fxo->is_init>>()) { idm::select>(on_select, idm::unlocked); @@ -1114,6 +1195,7 @@ void debugger_frame::OnSelectUnit() } cpu_thread* selected = nullptr; + usz hw_ppu_idx = umax; if (m_emu_state != system_state::stopped) { @@ -1135,7 +1217,14 @@ void debugger_frame::OnSelectUnit() if (!selected && !m_rsx && !m_cpu) { - return; + if (u32 cur = m_choice_units->currentIndex(); cur >= m_hw_ppu_idx && cur < g_cfg.core.ppu_threads + m_hw_ppu_idx) + { + hw_ppu_idx = cur - m_hw_ppu_idx; + } + else + { + return; + } } } @@ -1144,6 +1233,15 @@ void debugger_frame::OnSelectUnit() m_rsx = nullptr; m_spu_disasm_memory.reset(); + if (hw_ppu_idx != umax) + { + if (hw_ppu_idx > 1) + { + // Sample PPU + selected = ::at32(m_threads_info, 1)(); + } + } + if (selected) { const u32 cpu_id = selected->id; @@ -1198,8 +1296,8 @@ void debugger_frame::OnSelectUnit() m_debugger_list->UpdateCPUData(m_disasm); m_breakpoint_list->UpdateCPUData(m_disasm); - ShowPC(true); - DoUpdate(); + ShowPC(true, selected); + DoUpdate(selected); UpdateUI(); } @@ -1339,30 +1437,28 @@ void debugger_frame::OnSelectSPUDisassembler() m_debugger_list->UpdateCPUData(m_disasm); m_breakpoint_list->UpdateCPUData(m_disasm); - ShowPC(true); - DoUpdate(); + ShowPC(true, nullptr); + DoUpdate(nullptr); UpdateUI(); }); m_spu_disasm_dialog->show(); } -void debugger_frame::DoUpdate() +void debugger_frame::DoUpdate(cpu_thread* cpu0) { // Check if we need to disable a step over bp - if (const auto cpu0 = get_cpu(); cpu0 && m_last_step_over_breakpoint != umax && cpu0->get_pc() == m_last_step_over_breakpoint) + if (cpu0 && m_last_step_over_breakpoint != umax && cpu0->get_pc() == m_last_step_over_breakpoint) { m_ppu_breakpoint_handler->RemoveBreakpoint(m_last_step_over_breakpoint); m_last_step_over_breakpoint = -1; } - WritePanels(); + WritePanels(cpu0); } -void debugger_frame::WritePanels() +void debugger_frame::WritePanels(cpu_thread* cpu) { - const auto cpu = get_cpu(); - if (!cpu) { m_misc_state->clear(); @@ -1412,7 +1508,9 @@ void debugger_frame::ShowGotoAddressDialog() QLineEdit* expression_input(new QLineEdit(m_goto_dialog)); expression_input->setFont(m_mono); - if (const auto thread = get_cpu(); !thread || thread->get_class() != thread_class::spu) + const auto thread = get_cpu(); + + if (!thread || thread->get_class() != thread_class::spu) { expression_input->setValidator(new HexValidator(expression_input)); } @@ -1436,8 +1534,8 @@ void debugger_frame::ShowGotoAddressDialog() m_goto_dialog->setLayout(vbox_panel); - const auto cpu_check = make_check_cpu(get_cpu()); - const auto cpu = cpu_check(); + const auto cpu_check = make_check_cpu(thread); + const auto cpu = thread; const QFont font = expression_input->font(); // -1 from get_pc() turns into 0 @@ -1544,9 +1642,12 @@ void debugger_frame::ClearCallStack() Q_EMIT CallStackUpdateRequested({}); } -void debugger_frame::ShowPC(bool user_requested) +void debugger_frame::ShowPC(bool user_requested, cpu_thread* cpu0) { - const auto cpu0 = get_cpu(); + if (!cpu0) + { + cpu0 = get_cpu(); + } const u32 pc = (cpu0 ? cpu0->get_pc() : (m_is_spu_disasm_mode ? m_spu_disasm_pc : 0)); diff --git a/rpcs3/rpcs3qt/debugger_frame.h b/rpcs3/rpcs3qt/debugger_frame.h index 6837347c3f..eb22d74680 100644 --- a/rpcs3/rpcs3qt/debugger_frame.h +++ b/rpcs3/rpcs3qt/debugger_frame.h @@ -79,6 +79,7 @@ class debugger_frame : public custom_dock_widget std::shared_ptr m_disasm; // Only shared to allow base/derived functionality shared_ptr m_cpu; rsx::thread* m_rsx = nullptr; + u32 m_hw_ppu_idx = umax; std::shared_ptr m_spu_disasm_memory; u32 m_spu_disasm_origin_eal = 0; u32 m_spu_disasm_pc = 0; @@ -107,8 +108,8 @@ public: void UpdateUI(); void UpdateUnitList(); - void DoUpdate(); - void WritePanels(); + void DoUpdate(cpu_thread* cpu0); + void WritePanels(cpu_thread* cpu); void EnableButtons(bool enable); void ShowGotoAddressDialog(); void PerformGoToRequest(const QString& text_argument); @@ -138,7 +139,7 @@ private Q_SLOTS: void OnSelectUnit(); void OnSelectSPUDisassembler(); void OnRegsContextMenu(const QPoint& pos); - void ShowPC(bool user_requested = false); + void ShowPC(bool user_requested = false, cpu_thread* cpu = nullptr); void EnableUpdateTimer(bool enable) const; void RunBtnPress(); void RegsShowMemoryViewerAction(); From fecb53f86c55fde6e260617f6b1289cabf1687bf Mon Sep 17 00:00:00 2001 From: Elad <18193363+elad335@users.noreply.github.com> Date: Tue, 10 Mar 2026 17:35:23 +0200 Subject: [PATCH 150/175] Fix SaveStates cellDumxPamf regression --- rpcs3/Emu/savestate_utils.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/rpcs3/Emu/savestate_utils.cpp b/rpcs3/Emu/savestate_utils.cpp index 167a060262..9306968dcf 100644 --- a/rpcs3/Emu/savestate_utils.cpp +++ b/rpcs3/Emu/savestate_utils.cpp @@ -23,7 +23,7 @@ struct serial_ver_t std::set compatible_versions; }; -static std::array s_serial_versions; +static std::array s_serial_versions; #define SERIALIZATION_VER(name, identifier, ...) \ \ @@ -40,7 +40,7 @@ static std::array s_serial_versions; return ::s_serial_versions[identifier].current_version;\ } -SERIALIZATION_VER(global_version, 0, 19) // For stuff not listed here +SERIALIZATION_VER(global_version, 0, 20) // For stuff not listed here SERIALIZATION_VER(ppu, 1, 1, 2/*PPU sleep order*/, 3/*PPU FNID and module*/) SERIALIZATION_VER(spu, 2, 1) SERIALIZATION_VER(lv2_sync, 3, 1) @@ -87,6 +87,15 @@ SERIALIZATION_VER(HLE, 25, 1) SERIALIZATION_VER(cellSysutil, 26, 1, 2/*AVC2 Muting,Volume*/) SERIALIZATION_VER(cellDmuxPamf, 27, 1) +// For future modules +SERIALIZATION_VER(cellReserved1, 27, 1) +SERIALIZATION_VER(cellReserved2, 28, 1) +SERIALIZATION_VER(cellReserved3, 29, 1) +SERIALIZATION_VER(cellReserved4, 30, 1) +SERIALIZATION_VER(cellReserved6, 31, 1) +SERIALIZATION_VER(cellReserved7, 32, 1) +SERIALIZATION_VER(cellReserved8, 33, 1) + template <> void fmt_class_string>::format(std::string& out, u64 arg) { From 29346412375d5eba0f5fb8eea721223aa1a1ab44 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Tue, 10 Mar 2026 07:34:45 +0100 Subject: [PATCH 151/175] overlays: support playing audio with video_view --- .../Emu/RSX/Overlays/overlay_save_dialog.cpp | 7 ++++--- rpcs3/Emu/RSX/Overlays/overlay_video.cpp | 19 +++++++++---------- rpcs3/Emu/RSX/Overlays/overlay_video.h | 8 ++++---- rpcs3/rpcs3qt/qt_video_source.cpp | 14 ++++++++++++-- 4 files changed, 29 insertions(+), 19 deletions(-) diff --git a/rpcs3/Emu/RSX/Overlays/overlay_save_dialog.cpp b/rpcs3/Emu/RSX/Overlays/overlay_save_dialog.cpp index 604dee7fc4..2847db969c 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_save_dialog.cpp +++ b/rpcs3/Emu/RSX/Overlays/overlay_save_dialog.cpp @@ -9,10 +9,11 @@ namespace rsx { save_dialog::save_dialog_entry::save_dialog_entry(const std::string& text1, const std::string& text2, const std::string& text3, u8 resource_id, const std::vector& icon_buf, const std::string& video_path) { + const std::string audio_path; // no audio here std::unique_ptr image = resource_id != image_resource_id::raw_image - ? std::make_unique(video_path, resource_id) - : !icon_buf.empty() ? std::make_unique(video_path, icon_buf) - : std::make_unique(video_path, resource_config::standard_image_resource::save); // Fallback + ? std::make_unique(video_path, audio_path, resource_id) + : !icon_buf.empty() ? std::make_unique(video_path, audio_path, icon_buf) + : std::make_unique(video_path, audio_path, resource_config::standard_image_resource::save); // Fallback image->set_size(160, 110); image->set_padding(36, 36, 11, 11); // Square image, 88x88 diff --git a/rpcs3/Emu/RSX/Overlays/overlay_video.cpp b/rpcs3/Emu/RSX/Overlays/overlay_video.cpp index ac6017d35f..44ca1f53ef 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_video.cpp +++ b/rpcs3/Emu/RSX/Overlays/overlay_video.cpp @@ -6,9 +6,9 @@ namespace rsx { namespace overlays { - video_view::video_view(const std::string& video_path, const std::string& thumbnail_path) + video_view::video_view(const std::string& video_path, const std::string& audio_path, const std::string& thumbnail_path) { - init_video(video_path); + init_video(video_path, audio_path); if (!thumbnail_path.empty()) { @@ -17,9 +17,9 @@ namespace rsx } } - video_view::video_view(const std::string& video_path, const std::vector& thumbnail_buf) + video_view::video_view(const std::string& video_path, const std::string& audio_path, const std::vector& thumbnail_buf) { - init_video(video_path); + init_video(video_path, audio_path); if (!thumbnail_buf.empty()) { @@ -28,10 +28,10 @@ namespace rsx } } - video_view::video_view(const std::string& video_path, u8 thumbnail_id) + video_view::video_view(const std::string& video_path, const std::string& audio_path, u8 thumbnail_id) : m_thumbnail_id(thumbnail_id) { - init_video(video_path); + init_video(video_path, audio_path); set_image_resource(thumbnail_id); } @@ -39,13 +39,11 @@ namespace rsx { } - void video_view::init_video(const std::string& video_path) + void video_view::init_video(const std::string& video_path, const std::string& audio_path) { if (video_path.empty()) return; - m_video_source = Emu.GetCallbacks().make_video_source(); - ensure(!!m_video_source); - + m_video_source = ensure(Emu.GetCallbacks().make_video_source()); m_video_source->set_update_callback([this]() { if (m_video_active) @@ -54,6 +52,7 @@ namespace rsx } }); m_video_source->set_video_path(video_path); + m_video_source->set_audio_path(audio_path); } void video_view::set_active(bool active) diff --git a/rpcs3/Emu/RSX/Overlays/overlay_video.h b/rpcs3/Emu/RSX/Overlays/overlay_video.h index 92297dee42..ab148c508d 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_video.h +++ b/rpcs3/Emu/RSX/Overlays/overlay_video.h @@ -19,9 +19,9 @@ namespace rsx class video_view final : public image_view { public: - video_view(const std::string& video_path, const std::string& thumbnail_path); - video_view(const std::string& video_path, const std::vector& thumbnail_buf); - video_view(const std::string& video_path, u8 thumbnail_id); + video_view(const std::string& video_path, const std::string& audio_path, const std::string& thumbnail_path); + video_view(const std::string& video_path, const std::string& audio_path, const std::vector& thumbnail_buf); + video_view(const std::string& video_path, const std::string& audio_path, u8 thumbnail_id); virtual ~video_view(); void set_active(bool active); @@ -30,7 +30,7 @@ namespace rsx compiled_resource& get_compiled() override; private: - void init_video(const std::string& video_path); + void init_video(const std::string& video_path, const std::string& audio_path); usz m_buffer_index = 0; std::array, 2> m_video_info; // double buffer diff --git a/rpcs3/rpcs3qt/qt_video_source.cpp b/rpcs3/rpcs3qt/qt_video_source.cpp index 2d4ce34aa3..8877e00c0c 100644 --- a/rpcs3/rpcs3qt/qt_video_source.cpp +++ b/rpcs3/rpcs3qt/qt_video_source.cpp @@ -335,7 +335,11 @@ void qt_video_source_wrapper::set_video_path(const std::string& video_path) { Emu.CallFromMainThread([this, path = video_path]() { - m_qt_video_source = std::make_unique(); + if (!m_qt_video_source) + { + m_qt_video_source = std::make_unique(); + } + m_qt_video_source->m_image_change_callback = [this](const QVideoFrame& frame) { std::unique_lock lock(m_qt_video_source->m_image_mutex); @@ -371,7 +375,12 @@ void qt_video_source_wrapper::set_audio_path(const std::string& audio_path) { Emu.CallFromMainThread([this, path = audio_path]() { - // TODO + if (!m_qt_video_source) + { + m_qt_video_source = std::make_unique(); + } + + m_qt_video_source->set_audio_path(path); }); } @@ -379,6 +388,7 @@ void qt_video_source_wrapper::set_active(bool active) { Emu.CallFromMainThread([this, active]() { + ensure(m_qt_video_source); m_qt_video_source->set_active(true); }); } From ee01d1186ffe80042a5f61830a6407ac739d07df Mon Sep 17 00:00:00 2001 From: Megamouse Date: Tue, 10 Mar 2026 08:56:04 +0100 Subject: [PATCH 152/175] overlays: play SND0.AT3 during initialization --- rpcs3/Emu/CMakeLists.txt | 1 + rpcs3/Emu/RSX/Overlays/overlay_audio.cpp | 30 ++++++++++++++++++++++ rpcs3/Emu/RSX/Overlays/overlay_audio.h | 23 +++++++++++++++++ rpcs3/Emu/RSX/Overlays/overlay_manager.cpp | 17 ++++++++++++ rpcs3/Emu/RSX/Overlays/overlay_manager.h | 6 +++++ rpcs3/Emu/RSX/RSXThread.cpp | 10 ++++++++ rpcs3/emucore.vcxproj | 4 ++- rpcs3/emucore.vcxproj.filters | 6 +++++ 8 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 rpcs3/Emu/RSX/Overlays/overlay_audio.cpp create mode 100644 rpcs3/Emu/RSX/Overlays/overlay_audio.h diff --git a/rpcs3/Emu/CMakeLists.txt b/rpcs3/Emu/CMakeLists.txt index edb98a6fa8..63951cfe92 100644 --- a/rpcs3/Emu/CMakeLists.txt +++ b/rpcs3/Emu/CMakeLists.txt @@ -500,6 +500,7 @@ target_sources(rpcs3_emu PRIVATE RSX/Overlays/overlays.cpp RSX/Overlays/overlay_animated_icon.cpp RSX/Overlays/overlay_animation.cpp + RSX/Overlays/overlay_audio.cpp RSX/Overlays/overlay_compile_notification.cpp RSX/Overlays/overlay_controls.cpp RSX/Overlays/overlay_cursor.cpp diff --git a/rpcs3/Emu/RSX/Overlays/overlay_audio.cpp b/rpcs3/Emu/RSX/Overlays/overlay_audio.cpp new file mode 100644 index 0000000000..5483a5242e --- /dev/null +++ b/rpcs3/Emu/RSX/Overlays/overlay_audio.cpp @@ -0,0 +1,30 @@ +#include "stdafx.h" +#include "overlay_audio.h" +#include "Emu/System.h" + +namespace rsx +{ + namespace overlays + { + audio_player::audio_player(const std::string& audio_path) + { + init_audio(audio_path); + } + + void audio_player::init_audio(const std::string& audio_path) + { + if (audio_path.empty()) return; + + m_video_source = ensure(Emu.GetCallbacks().make_video_source()); + m_video_source->set_audio_path(audio_path); + } + + void audio_player::set_active(bool active) + { + if (m_video_source) + { + m_video_source->set_active(active); + } + } + } +} diff --git a/rpcs3/Emu/RSX/Overlays/overlay_audio.h b/rpcs3/Emu/RSX/Overlays/overlay_audio.h new file mode 100644 index 0000000000..cb37569225 --- /dev/null +++ b/rpcs3/Emu/RSX/Overlays/overlay_audio.h @@ -0,0 +1,23 @@ +#pragma once + +#include "util/video_source.h" + +namespace rsx +{ + namespace overlays + { + class audio_player + { + public: + audio_player(const std::string& audio_path); + ~audio_player() = default; + + void set_active(bool active); + + private: + void init_audio(const std::string& audio_path); + + std::unique_ptr m_video_source; + }; + } +} diff --git a/rpcs3/Emu/RSX/Overlays/overlay_manager.cpp b/rpcs3/Emu/RSX/Overlays/overlay_manager.cpp index 485a59443e..9ffa9b14e3 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_manager.cpp +++ b/rpcs3/Emu/RSX/Overlays/overlay_manager.cpp @@ -167,6 +167,23 @@ namespace rsx } } + void display_manager::start_audio(const std::string& audio_path) + { + if (audio_path.empty()) + { + m_audio_player.reset(); + return; + } + + m_audio_player = std::make_unique(audio_path); + m_audio_player->set_active(true); + } + + void display_manager::stop_audio() + { + m_audio_player.reset(); + } + void display_manager::on_overlay_activated(const std::shared_ptr& /*item*/) { // TODO: Internal management, callbacks, etc diff --git a/rpcs3/Emu/RSX/Overlays/overlay_manager.h b/rpcs3/Emu/RSX/Overlays/overlay_manager.h index 7146be3dda..e42f3721b3 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_manager.h +++ b/rpcs3/Emu/RSX/Overlays/overlay_manager.h @@ -1,6 +1,7 @@ #pragma once #include "overlays.h" +#include "overlay_audio.h" #include "Emu/IdManager.h" #include "Utilities/mutex.h" @@ -25,6 +26,8 @@ namespace rsx lf_queue m_type_ids_to_remove; atomic_t m_pending_removals_count = 0; + std::unique_ptr m_audio_player; + bool remove_type(u32 type_id); bool remove_uid(u32 uid); @@ -167,6 +170,9 @@ namespace rsx std::function on_input_loop_exit = nullptr, // [optional] What to do with the result if any std::function input_loop_override = nullptr); // [optional] What to do during the input loop. By default calls user_interface::run_input_loop + void start_audio(const std::string& audio_path); + void stop_audio(); + private: struct overlay_input_thread { diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index a8aa7cdf60..7d634de677 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -711,6 +711,11 @@ namespace rsx if (g_cfg.misc.use_native_interface && (g_cfg.video.renderer == video_renderer::opengl || g_cfg.video.renderer == video_renderer::vulkan)) { m_overlay_manager = g_fxo->init(0); + + if (const std::string audio_path = Emu.GetSfoDir(true) + "/SND0.AT3"; fs::is_file(audio_path)) + { + m_overlay_manager->start_audio(audio_path); + } } if (!_ar) @@ -1101,6 +1106,11 @@ namespace rsx thread_ctrl::set_thread_affinity_mask(thread_ctrl::get_affinity_mask(thread_class::rsx)); } + if (auto manager = g_fxo->try_get()) + { + manager->stop_audio(); + } + while (!test_stopped()) { // Wait for external pause events diff --git a/rpcs3/emucore.vcxproj b/rpcs3/emucore.vcxproj index 8df2ef3092..0e07226729 100644 --- a/rpcs3/emucore.vcxproj +++ b/rpcs3/emucore.vcxproj @@ -145,6 +145,7 @@ + @@ -704,6 +705,7 @@ + @@ -1103,4 +1105,4 @@ - + \ No newline at end of file diff --git a/rpcs3/emucore.vcxproj.filters b/rpcs3/emucore.vcxproj.filters index 5ca602fbec..7dfd6a3f34 100644 --- a/rpcs3/emucore.vcxproj.filters +++ b/rpcs3/emucore.vcxproj.filters @@ -1411,6 +1411,9 @@ Loader + + Emu\GPU\RSX\Overlays + @@ -2833,6 +2836,9 @@ Loader + + Emu\GPU\RSX\Overlays + From 6b6dd6c43260311aa5a99c128fd61b442d19865d Mon Sep 17 00:00:00 2001 From: Megamouse Date: Mon, 9 Mar 2026 18:42:13 +0100 Subject: [PATCH 153/175] Qt: Rename Shortcuts to Keyboard Shortcuts --- rpcs3/rpcs3qt/main_window.ui | 2 +- rpcs3/rpcs3qt/shortcut_dialog.ui | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/rpcs3/rpcs3qt/main_window.ui b/rpcs3/rpcs3qt/main_window.ui index 1f6a75c6f7..ba72c86a1e 100644 --- a/rpcs3/rpcs3qt/main_window.ui +++ b/rpcs3/rpcs3qt/main_window.ui @@ -1379,7 +1379,7 @@ - Shortcuts + Keyboard Shortcuts diff --git a/rpcs3/rpcs3qt/shortcut_dialog.ui b/rpcs3/rpcs3qt/shortcut_dialog.ui index efafa998a2..04dbdb2157 100644 --- a/rpcs3/rpcs3qt/shortcut_dialog.ui +++ b/rpcs3/rpcs3qt/shortcut_dialog.ui @@ -11,7 +11,7 @@ - Shortcuts + Keyboard Shortcuts @@ -25,10 +25,10 @@ - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::MinimumExpanding + QSizePolicy::Policy::MinimumExpanding @@ -50,10 +50,10 @@ - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::MinimumExpanding + QSizePolicy::Policy::MinimumExpanding @@ -71,7 +71,7 @@ - QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Save + QDialogButtonBox::StandardButton::Apply|QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Save From e6cf05cfb73e156818685495814b0b7b8edaa97b Mon Sep 17 00:00:00 2001 From: Megamouse Date: Wed, 11 Mar 2026 12:58:09 +0100 Subject: [PATCH 154/175] Qt: Fix log levels tooltip --- rpcs3/rpcs3qt/settings_dialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpcs3/rpcs3qt/settings_dialog.cpp b/rpcs3/rpcs3qt/settings_dialog.cpp index b903db0f52..66f0ae3476 100644 --- a/rpcs3/rpcs3qt/settings_dialog.cpp +++ b/rpcs3/rpcs3qt/settings_dialog.cpp @@ -2497,7 +2497,7 @@ settings_dialog::settings_dialog(std::shared_ptr gui_settings, std SubscribeTooltip(ui->gb_vulkansched, tooltips.settings.vulkan_async_scheduler); // Log levels - SubscribeTooltip(ui->gb_log_levels, tooltips.settings.vulkan_async_scheduler); + SubscribeTooltip(ui->gb_log_levels, tooltips.settings.log_levels); connect(ui->pb_log_levels, &QAbstractButton::clicked, this, [this]() { log_level_dialog* dlg = new log_level_dialog(this, m_emu_settings); From 6f07e8453a8cb84ac400bd96f825751c9cf661c8 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Sat, 10 Jan 2026 18:57:39 +0100 Subject: [PATCH 155/175] Update curl to 8.19.0 --- 3rdparty/curl/curl | 2 +- 3rdparty/curl/libcurl.vcxproj | 28 ++++----- 3rdparty/curl/libcurl.vcxproj.filters | 84 +++++++++++++-------------- 3 files changed, 57 insertions(+), 57 deletions(-) diff --git a/3rdparty/curl/curl b/3rdparty/curl/curl index 400fffa90f..8c908d2d0a 160000 --- a/3rdparty/curl/curl +++ b/3rdparty/curl/curl @@ -1 +1 @@ -Subproject commit 400fffa90f30c7a2dc762fa33009d24851bd2016 +Subproject commit 8c908d2d0a6d32abdedda2c52e90bd56ec76c24d diff --git a/3rdparty/curl/libcurl.vcxproj b/3rdparty/curl/libcurl.vcxproj index dae28be346..4db28782a3 100644 --- a/3rdparty/curl/libcurl.vcxproj +++ b/3rdparty/curl/libcurl.vcxproj @@ -79,12 +79,16 @@ + + + + @@ -106,6 +110,7 @@ + @@ -169,14 +174,13 @@ - + - @@ -184,10 +188,8 @@ - - @@ -204,6 +206,7 @@ + @@ -224,13 +227,11 @@ - - @@ -272,6 +273,7 @@ + @@ -280,6 +282,9 @@ + + + @@ -300,9 +305,7 @@ - - @@ -312,6 +315,7 @@ + @@ -352,7 +356,6 @@ - @@ -367,7 +370,7 @@ - + @@ -376,7 +379,6 @@ - @@ -384,7 +386,6 @@ - @@ -405,6 +406,7 @@ + @@ -418,12 +420,10 @@ - - diff --git a/3rdparty/curl/libcurl.vcxproj.filters b/3rdparty/curl/libcurl.vcxproj.filters index 17f760c54b..d38316e767 100644 --- a/3rdparty/curl/libcurl.vcxproj.filters +++ b/3rdparty/curl/libcurl.vcxproj.filters @@ -204,9 +204,6 @@ Source Files - - Source Files - Source Files @@ -222,9 +219,6 @@ Source Files - - Source Files - Source Files @@ -246,18 +240,12 @@ Source Files - - Source Files - Source Files Source Files - - Source Files - Source Files @@ -318,9 +306,6 @@ Source Files - - Source Files - Source Files @@ -333,9 +318,6 @@ Source Files - - Source Files - Source Files @@ -549,6 +531,27 @@ Source Files + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + @@ -653,9 +656,6 @@ Header Files - - Header Files - Header Files @@ -758,9 +758,6 @@ Header Files - - Header Files - Header Files @@ -791,9 +788,6 @@ Header Files - - Header Files - Header Files @@ -812,9 +806,6 @@ Header Files - - Header Files - Header Files @@ -836,9 +827,6 @@ Header Files - - Header Files - Header Files @@ -887,9 +875,6 @@ Header Files - - Header Files - Header Files @@ -899,9 +884,6 @@ Header Files - - Header Files - Header Files @@ -1103,9 +1085,6 @@ Header Files - - Header Files - Header Files @@ -1121,6 +1100,27 @@ Header Files + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + From 951d47c94c1428a40f1f676129a3ab901bd41860 Mon Sep 17 00:00:00 2001 From: qurious-pixel <62252937+qurious-pixel@users.noreply.github.com> Date: Fri, 13 Mar 2026 21:54:15 -0700 Subject: [PATCH 156/175] Use System Protobuf for Intel Mac --- .ci/build-mac.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/.ci/build-mac.sh b/.ci/build-mac.sh index 300f69cb06..f386866264 100755 --- a/.ci/build-mac.sh +++ b/.ci/build-mac.sh @@ -122,6 +122,7 @@ cmake .. \ -DUSE_SYSTEM_MVK=ON \ -DUSE_SYSTEM_SDL=ON \ -DUSE_SYSTEM_OPENCV=ON \ + -DUSE_SYSTEM_PROTOBUF=ON \ -G Ninja fi From b734ceb2e7ad279567bd2fad88c8e778f27264e9 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Fri, 13 Mar 2026 13:55:10 +0100 Subject: [PATCH 157/175] overlays: allow to reset current setting --- .../HomeMenu/overlay_home_menu_page.cpp | 21 +++++- .../HomeMenu/overlay_home_menu_page.h | 3 + .../HomeMenu/overlay_home_menu_settings.h | 75 ++++++++++++++++--- rpcs3/Emu/localized_string_id.h | 1 + rpcs3/rpcs3qt/localized_emu.h | 1 + 5 files changed, 87 insertions(+), 14 deletions(-) diff --git a/rpcs3/Emu/RSX/Overlays/HomeMenu/overlay_home_menu_page.cpp b/rpcs3/Emu/RSX/Overlays/HomeMenu/overlay_home_menu_page.cpp index edfb932d26..551f3dc82b 100644 --- a/rpcs3/Emu/RSX/Overlays/HomeMenu/overlay_home_menu_page.cpp +++ b/rpcs3/Emu/RSX/Overlays/HomeMenu/overlay_home_menu_page.cpp @@ -11,6 +11,7 @@ namespace rsx : list_view(width, height, use_separators) , parent(parent) , title(title) + , m_reset_btn(120, 30) , m_save_btn(120, 30) , m_discard_btn(120, 30) { @@ -20,15 +21,19 @@ namespace rsx m_config_changed = parent->m_config_changed; } + m_reset_btn.set_image_resource(resource_config::standard_image_resource::select); m_save_btn.set_image_resource(resource_config::standard_image_resource::square); m_discard_btn.set_image_resource(resource_config::standard_image_resource::triangle); + m_reset_btn.set_pos((width - 120) / 2, height + 20); m_save_btn.set_pos(width - 2 * (30 + 120), height + 20); m_discard_btn.set_pos(width - (30 + 120), height + 20); + m_reset_btn.set_text(localized_string_id::HOME_MENU_SETTINGS_RESET_BUTTON); m_save_btn.set_text(localized_string_id::HOME_MENU_SETTINGS_SAVE_BUTTON); m_discard_btn.set_text(localized_string_id::HOME_MENU_SETTINGS_DISCARD_BUTTON); + m_reset_btn.set_font("Arial", 16); m_save_btn.set_font("Arial", 16); m_discard_btn.set_font("Arial", 16); @@ -152,6 +157,7 @@ namespace rsx case pad_button::ls_left: case pad_button::ls_right: case pad_button::cross: + case pad_button::select: { if (const usz index = static_cast(get_selected_index()); index < m_callbacks.size()) { @@ -266,6 +272,7 @@ namespace rsx list_view::translate(_x, _y); m_save_btn.translate(_x, _y); m_discard_btn.translate(_x, _y); + m_reset_btn.translate(_x, _y); } compiled_resource& home_menu_page::get_compiled() @@ -286,10 +293,18 @@ namespace rsx { compiled_resources.add(m_message_box->get_compiled()); } - else if (m_config_changed && *m_config_changed) + else { - compiled_resources.add(m_save_btn.get_compiled()); - compiled_resources.add(m_discard_btn.get_compiled()); + if (show_reset_button()) + { + compiled_resources.add(m_reset_btn.get_compiled()); + } + + if (m_config_changed && *m_config_changed) + { + compiled_resources.add(m_save_btn.get_compiled()); + compiled_resources.add(m_discard_btn.get_compiled()); + } } } diff --git a/rpcs3/Emu/RSX/Overlays/HomeMenu/overlay_home_menu_page.h b/rpcs3/Emu/RSX/Overlays/HomeMenu/overlay_home_menu_page.h index 862baf5062..dcbfcc805f 100644 --- a/rpcs3/Emu/RSX/Overlays/HomeMenu/overlay_home_menu_page.h +++ b/rpcs3/Emu/RSX/Overlays/HomeMenu/overlay_home_menu_page.h @@ -20,6 +20,8 @@ namespace rsx void translate(s16 _x, s16 _y) override; compiled_resource& get_compiled() override; + virtual bool show_reset_button() const { return false; } + bool is_current_page = false; home_menu_page* parent = nullptr; std::string title; @@ -36,6 +38,7 @@ namespace rsx std::vector> m_pages; private: + image_button m_reset_btn; image_button m_save_btn; image_button m_discard_btn; std::vector> m_entries; diff --git a/rpcs3/Emu/RSX/Overlays/HomeMenu/overlay_home_menu_settings.h b/rpcs3/Emu/RSX/Overlays/HomeMenu/overlay_home_menu_settings.h index 9e54cfd441..3bff68138a 100644 --- a/rpcs3/Emu/RSX/Overlays/HomeMenu/overlay_home_menu_settings.h +++ b/rpcs3/Emu/RSX/Overlays/HomeMenu/overlay_home_menu_settings.h @@ -21,6 +21,8 @@ namespace rsx { using home_menu_page::home_menu_page; + bool show_reset_button() const override { return true; } + void add_checkbox(cfg::_bool* setting, localized_string_id loc_id) { ensure(setting && setting->get_is_dynamic()); @@ -30,16 +32,30 @@ namespace rsx add_item(elem, [this, setting](pad_button btn) -> page_navigation { - if (btn != pad_button::cross) return page_navigation::stay; - if (setting) { - const bool value = !setting->get(); - rsx_log.notice("User toggled checkbox in '%s'. Setting '%s' to %d", title, setting->get_name(), value); - setting->set(value); - Emu.GetCallbacks().update_emu_settings(); - if (m_config_changed) *m_config_changed = true; - refresh(); + bool value = setting->get(); + + switch (btn) + { + case pad_button::cross: + value = !value; + break; + case pad_button::select: + value = setting->def; + break; + default: + return page_navigation::stay; + } + + if (value != setting->get()) + { + rsx_log.notice("User toggled checkbox in '%s'. Setting '%s' to %d", title, setting->get_name(), value); + setting->set(value); + Emu.GetCallbacks().update_emu_settings(); + if (m_config_changed) *m_config_changed = true; + refresh(); + } } return page_navigation::stay; @@ -56,12 +72,33 @@ namespace rsx add_item(elem, [this, setting](pad_button btn) -> page_navigation { - if (btn != pad_button::cross) return page_navigation::stay; - if (setting) { + bool set_default = false; + switch (btn) + { + case pad_button::cross: + break; + case pad_button::select: + set_default = true; + break; + default: + return page_navigation::stay; + } + + T value = setting->get(); + + if (set_default) + { + if (value == setting->def) + { + return page_navigation::stay; + } + + value = setting->def; + } + usz new_index = 0; - const T value = setting->get(); const std::string val = fmt::format("%s", value); const std::vector list = setting->to_list(); @@ -70,10 +107,17 @@ namespace rsx const std::string& entry = list[i]; if (entry == val) { + if (set_default) + { + new_index = i; + break; + } + new_index = (i + 1) % list.size(); break; } } + if (const std::string& next_value = ::at32(list, new_index); setting->from_string(next_value)) { rsx_log.notice("User toggled dropdown in '%s'. Setting '%s' to %s", title, setting->get_name(), next_value); @@ -114,6 +158,9 @@ namespace rsx case pad_button::ls_right: value = std::min(value + step_size, maximum); break; + case pad_button::select: + value = setting->def; + break; default: return page_navigation::stay; } @@ -164,6 +211,9 @@ namespace rsx } while (exceptions.contains(value)); break; + case pad_button::select: + value = setting->def; + break; default: return page_navigation::stay; } @@ -205,6 +255,9 @@ namespace rsx case pad_button::ls_right: value = std::min(value + step_size, static_cast(maximum)); break; + case pad_button::select: + value = setting->def; + break; default: return page_navigation::stay; } diff --git a/rpcs3/Emu/localized_string_id.h b/rpcs3/Emu/localized_string_id.h index 9ab9f57a9b..b4ef2516fe 100644 --- a/rpcs3/Emu/localized_string_id.h +++ b/rpcs3/Emu/localized_string_id.h @@ -204,6 +204,7 @@ enum class localized_string_id HOME_MENU_SETTINGS_SAVE_BUTTON, HOME_MENU_SETTINGS_DISCARD, HOME_MENU_SETTINGS_DISCARD_BUTTON, + HOME_MENU_SETTINGS_RESET_BUTTON, HOME_MENU_SETTINGS_AUDIO, HOME_MENU_SETTINGS_AUDIO_MASTER_VOLUME, HOME_MENU_SETTINGS_AUDIO_BACKEND, diff --git a/rpcs3/rpcs3qt/localized_emu.h b/rpcs3/rpcs3qt/localized_emu.h index d05d3e52ee..920f9d9d14 100644 --- a/rpcs3/rpcs3qt/localized_emu.h +++ b/rpcs3/rpcs3qt/localized_emu.h @@ -225,6 +225,7 @@ private: case localized_string_id::HOME_MENU_SETTINGS_SAVE_BUTTON: return tr("Save"); case localized_string_id::HOME_MENU_SETTINGS_DISCARD: return tr("Discard the current settings' changes?"); case localized_string_id::HOME_MENU_SETTINGS_DISCARD_BUTTON: return tr("Discard"); + case localized_string_id::HOME_MENU_SETTINGS_RESET_BUTTON: return tr("To default"); case localized_string_id::HOME_MENU_SETTINGS_AUDIO: return tr("Audio"); case localized_string_id::HOME_MENU_SETTINGS_AUDIO_MASTER_VOLUME: return tr("Master Volume", "Audio"); case localized_string_id::HOME_MENU_SETTINGS_AUDIO_BACKEND: return tr("Audio Backend", "Audio"); From 4542020c869f044fca2bf5b630587e5b47148afb Mon Sep 17 00:00:00 2001 From: Malcolm Date: Tue, 17 Feb 2026 18:27:32 -0500 Subject: [PATCH 158/175] SPU LLVM: ARM64: Use UDOT for emulating SUMB --- rpcs3/Emu/CPU/CPUTranslator.cpp | 7 ++++++ rpcs3/Emu/CPU/CPUTranslator.h | 37 ++++++++++++++++++++++++++++ rpcs3/Emu/Cell/SPULLVMRecompiler.cpp | 13 +++++++++- 3 files changed, 56 insertions(+), 1 deletion(-) diff --git a/rpcs3/Emu/CPU/CPUTranslator.cpp b/rpcs3/Emu/CPU/CPUTranslator.cpp index f799e4b6be..08e8e9ad30 100644 --- a/rpcs3/Emu/CPU/CPUTranslator.cpp +++ b/rpcs3/Emu/CPU/CPUTranslator.cpp @@ -201,6 +201,13 @@ void cpu_translator::initialize(llvm::LLVMContext& context, llvm::ExecutionEngin m_use_vnni = true; m_use_gfni = true; } + +#ifdef ARCH_ARM64 + if (utils::has_dotprod()) + { + m_use_dotprod = true; + } +#endif } llvm::Value* cpu_translator::bitcast(llvm::Value* val, llvm::Type* type) const diff --git a/rpcs3/Emu/CPU/CPUTranslator.h b/rpcs3/Emu/CPU/CPUTranslator.h index 27abb22219..81049c6074 100644 --- a/rpcs3/Emu/CPU/CPUTranslator.h +++ b/rpcs3/Emu/CPU/CPUTranslator.h @@ -3090,6 +3090,9 @@ protected: // For now, setting this flag will speed up SPU verification // but I will remove this later with explicit parralelism - Whatcookie bool m_use_avx = true; + + // ARMv8 SDOT/UDOT + bool m_use_dotprod = false; #else // Allow FMA bool m_use_fma = false; @@ -3658,6 +3661,40 @@ public: return result; } +template + value_t udot(T1 a, T2 b, T3 c) + { + value_t result; + + const auto data0 = a.eval(m_ir); + const auto data1 = b.eval(m_ir); + const auto data2 = c.eval(m_ir); + + // ARM hardware requires the multipliers to be treated as 16-byte vectors + //const auto op1 = bitcast(data1, get_type()); + //const auto op2 = bitcast(data2, get_type()); + + // Use the variadic get_intrinsic to resolve the overloaded AArch64 intrinsic + result.value = m_ir->CreateCall(get_intrinsic(llvm::Intrinsic::aarch64_neon_udot), {data0, data1, data2}); + return result; + } + + template + value_t sdot(T1 a, T2 b, T3 c) + { + value_t result; + + const auto data0 = a.eval(m_ir); + const auto data1 = b.eval(m_ir); + const auto data2 = c.eval(m_ir); + + //const auto op1 = bitcast(data1, get_type()); + //const auto op2 = bitcast(data2, get_type()); + + result.value = m_ir->CreateCall(get_intrinsic(llvm::Intrinsic::aarch64_neon_sdot), {data0, data1, data2}); + return result; + } + template value_t vpermb(T1 a, T2 b) { diff --git a/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp b/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp index d42acd3560..45b4c83ecf 100644 --- a/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp +++ b/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp @@ -5313,13 +5313,24 @@ public: return; } +#ifdef ARCH_ARM64 + if (m_use_dotprod) +#else if (m_use_vnni) +#endif { - const auto [a, b] = get_vrs(op.ra, op.rb); const auto zeroes = splat(0); +#ifdef ARCH_ARM64 + const auto [a, b] = get_vrs(op.ra, op.rb); + const auto ones = splat(0x01); + const auto ax = bitcast(udot(zeroes, a, ones)); + const auto bx = bitcast(udot(zeroes, b, ones)); +#else + const auto [a, b] = get_vrs(op.ra, op.rb); const auto ones = splat(0x01010101); const auto ax = bitcast(vpdpbusd(zeroes, a, ones)); const auto bx = bitcast(vpdpbusd(zeroes, b, ones)); +#endif set_vr(op.rt, shuffle2(ax, bx, 0, 8, 2, 10, 4, 12, 6, 14)); return; } From 16277576089e1733987deeac54b627b25d67d800 Mon Sep 17 00:00:00 2001 From: Malcolm Date: Wed, 18 Feb 2026 23:53:48 -0500 Subject: [PATCH 159/175] SPU LLVM: Emulate GBB with udot/sdot Greatly simplifies GB, GBH, and GBH. Uses udot/sdot with power of two masks to shift values and sum them in a single step, effectively gathering them --- rpcs3/Emu/CPU/CPUTranslator.h | 24 +++-- rpcs3/Emu/Cell/SPULLVMRecompiler.cpp | 139 +++++++++++++++++++++++++++ 2 files changed, 155 insertions(+), 8 deletions(-) diff --git a/rpcs3/Emu/CPU/CPUTranslator.h b/rpcs3/Emu/CPU/CPUTranslator.h index 81049c6074..9b9804fd39 100644 --- a/rpcs3/Emu/CPU/CPUTranslator.h +++ b/rpcs3/Emu/CPU/CPUTranslator.h @@ -3661,6 +3661,7 @@ public: return result; } +#ifdef ARCH_ARM64 template value_t udot(T1 a, T2 b, T3 c) { @@ -3670,11 +3671,6 @@ template const auto data1 = b.eval(m_ir); const auto data2 = c.eval(m_ir); - // ARM hardware requires the multipliers to be treated as 16-byte vectors - //const auto op1 = bitcast(data1, get_type()); - //const auto op2 = bitcast(data2, get_type()); - - // Use the variadic get_intrinsic to resolve the overloaded AArch64 intrinsic result.value = m_ir->CreateCall(get_intrinsic(llvm::Intrinsic::aarch64_neon_udot), {data0, data1, data2}); return result; } @@ -3688,12 +3684,24 @@ template const auto data1 = b.eval(m_ir); const auto data2 = c.eval(m_ir); - //const auto op1 = bitcast(data1, get_type()); - //const auto op2 = bitcast(data2, get_type()); - result.value = m_ir->CreateCall(get_intrinsic(llvm::Intrinsic::aarch64_neon_sdot), {data0, data1, data2}); return result; } + +template + auto addp(T1 a, T2 b) + { + using T_vector = typename is_llvm_expr::type; + const auto data1 = a.eval(m_ir); + const auto data2 = b.eval(m_ir); + + const auto func = get_intrinsic(llvm::Intrinsic::aarch64_neon_addp); + + value_t result; + result.value = m_ir->CreateCall(func, {data1, data2}); + return result; + } +#endif template value_t vpermb(T1 a, T2 b) diff --git a/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp b/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp index 45b4c83ecf..856a039e5e 100644 --- a/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp +++ b/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp @@ -4759,6 +4759,50 @@ public: } const auto a = get_vr(op.ra); + +#ifdef ARCH_ARM64 + // Use dot product instructions with special values to shift then sum results into the preferred slot + if (m_use_dotprod) + { + if (match_vr(op.ra, [&](auto c, auto MP) + { + using VT = typename decltype(MP)::type; + + if (auto [ok, x] = match_expr(c, sext(match]>())); ok) + { + const auto zeroes = splat(0); + + const auto es = zshuffle(bitcast(a), 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 4, 8, 12); + + set_vr(op.rt, sdot(zeroes, es, build( + -0x01, -0x02, -0x04, -0x08, + -0x01, -0x02, -0x04, -0x08, + -0x01, -0x02, -0x04, -0x08, + -0x01, -0x02, -0x04, -0x08 + ))); + return true; + } + return false; + })) + { + return; + } + + const auto zeroes = splat(0); + const auto masked = a & 0x01; + + const auto es = zshuffle(bitcast(masked), 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 4, 8, 12); + + set_vr(op.rt, udot(zeroes, es, build( + 0x01, 0x02, 0x04, 0x08, + 0x01, 0x02, 0x04, 0x08, + 0x01, 0x02, 0x04, 0x08, + 0x01, 0x02, 0x04, 0x08 + ))); + return; + } +#endif + const auto m = zext(bitcast(trunc(a))); set_vr(op.rt, insert(splat(0), 3, eval(m))); } @@ -4774,6 +4818,54 @@ public: } const auto a = get_vr(op.ra); + +#ifdef ARCH_ARM64 + // Use dot product instructions with special values to shift then sum results into the preferred slot + if (m_use_dotprod) + { + if (match_vr(op.ra, [&](auto c, auto MP) + { + using VT = typename decltype(MP)::type; + + if (auto [ok, x] = match_expr(c, sext(match]>())); ok) + { + const auto zeroes = splat(0); + + const auto es = zshuffle(bitcast(a), 16, 16, 16, 16, 16, 16, 16, 16, 0, 2, 4, 6, 8, 10, 12, 14); + + const auto extracted = sdot(zeroes, es, build( + -0x01, -0x02, -0x04, -0x08, + -0x10, -0x20, -0x40, -0x80, + -0x01, -0x02, -0x04, -0x08, + -0x10, -0x20, -0x40, -0x80 + )); + + set_vr(op.rt, addp(zeroes, bitcast(extracted))); + return true; + } + return false; + })) + { + return; + } + + const auto zeroes = splat(0); + const auto masked = a & 0x01; + + const auto es = zshuffle(bitcast(masked), 16, 16, 16, 16, 16, 16, 16, 16, 0, 2, 4, 6, 8, 10, 12, 14); + + const auto extracted = udot(zeroes, es, build( + 0x01, 0x02, 0x04, 0x08, + 0x10, 0x20, 0x40, 0x80, + 0x01, 0x02, 0x04, 0x08, + 0x10, 0x20, 0x40, 0x80 + )); + + set_vr(op.rt, addp(zeroes, bitcast(extracted))); + return; + } +#endif + const auto m = zext(bitcast(trunc(a))); set_vr(op.rt, insert(splat(0), 3, eval(m))); } @@ -4782,6 +4874,53 @@ public: { const auto a = get_vr(op.ra); +#ifdef ARCH_ARM64 + // Use dot product instructions with special values to shift then sum results into the preferred slot + if (m_use_dotprod) + { + if (match_vr(op.ra, [&](auto c, auto MP) + { + using VT = typename decltype(MP)::type; + + if (auto [ok, x] = match_expr(c, sext(match]>())); ok) + { + const auto zeroes = splat(0); + + const auto extracted = sdot(zeroes, a, build( + -0x01, -0x02, -0x04, -0x08, + -0x10, -0x20, -0x40, -0x80, + -0x01, -0x02, -0x04, -0x08, + -0x10, -0x20, -0x40, -0x80 + )); + + const auto es = zshuffle(bitcast(extracted), 16, 16, 16, 16, 16, 16, 16, 16, 0, 8, 4, 12, 16, 16, 16, 16); + const auto zeroes16 = splat(0); + set_vr(op.rt, addp(zeroes16, bitcast(es))); + return true; + } + return false; + })) + { + return; + } + + const auto zeroes = splat(0); + const auto masked = a & 0x01; + + const auto extracted = udot(zeroes, masked, build( + 0x01, 0x02, 0x04, 0x08, + 0x10, 0x20, 0x40, 0x80, + 0x01, 0x02, 0x04, 0x08, + 0x10, 0x20, 0x40, 0x80 + )); + + const auto es = zshuffle(bitcast(extracted), 16, 16, 16, 16, 16, 16, 16, 16, 0, 8, 4, 12, 16, 16, 16, 16); + const auto zeroes16 = splat(0); + set_vr(op.rt, addp(zeroes16, bitcast(es))); + return; + } +#endif + if (m_use_gfni) { const auto as = zshuffle(a, 7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8); From 5274210ba8307f1c0a45a8398d3ba9e9c8840f19 Mon Sep 17 00:00:00 2001 From: jfleezy23 Date: Sun, 15 Mar 2026 01:53:07 -0700 Subject: [PATCH 160/175] VK: scale auto shader compiler workers on wide CPUs --- rpcs3/Emu/RSX/VK/VKPipelineCompiler.cpp | 44 ++++++++++++++++--------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/rpcs3/Emu/RSX/VK/VKPipelineCompiler.cpp b/rpcs3/Emu/RSX/VK/VKPipelineCompiler.cpp index 26e0b64098..99462e0602 100644 --- a/rpcs3/Emu/RSX/VK/VKPipelineCompiler.cpp +++ b/rpcs3/Emu/RSX/VK/VKPipelineCompiler.cpp @@ -216,16 +216,27 @@ namespace vk return {}; } - void initialize_pipe_compiler(int num_worker_threads) - { - if (num_worker_threads == 0) - { - // Select optimal number of compiler threads - const auto hw_threads = utils::get_thread_count(); - if (hw_threads > 12) - { - num_worker_threads = 6; - } + void initialize_pipe_compiler(int num_worker_threads) + { + if (num_worker_threads == 0) + { + // Select a conservative but modern default for async pipeline compilation. + // Older heuristics topped out too early on high-core CPUs and left large + // shader bursts queued longer than necessary. + const auto hw_threads = utils::get_thread_count(); + + if (hw_threads >= 24) + { + num_worker_threads = 12; + } + else if (hw_threads >= 16) + { + num_worker_threads = 8; + } + else if (hw_threads > 12) + { + num_worker_threads = 6; + } else if (hw_threads > 8) { num_worker_threads = 4; @@ -234,11 +245,14 @@ namespace vk { num_worker_threads = 2; } - else - { - num_worker_threads = 1; - } - } + else + { + num_worker_threads = 1; + } + + rsx_log.notice("Async pipeline compiler auto-selected %d worker(s) for %u host thread(s).", + num_worker_threads, hw_threads); + } ensure(num_worker_threads >= 1); ensure(g_render_device); // "Cannot initialize pipe compiler before creating a logical device" From 9733d8c8572ba6c32a830e0fc251f7220ddc71b6 Mon Sep 17 00:00:00 2001 From: Ani Date: Sun, 22 Feb 2026 15:37:20 +0100 Subject: [PATCH 161/175] config: Move FSR CAS out of Vulkan subcategory FSR1 was already implemented for OpenGL as well, so this setting is no longer exclusive to the Vulkan render --- rpcs3/Emu/RSX/GL/upscalers/fsr1/fsr_pass.cpp | 2 +- rpcs3/Emu/RSX/Overlays/HomeMenu/overlay_home_menu_settings.cpp | 2 +- rpcs3/Emu/RSX/VK/upscalers/fsr1/fsr_pass.cpp | 2 +- rpcs3/Emu/system_config.h | 2 +- rpcs3/rpcs3qt/emu_settings_type.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/rpcs3/Emu/RSX/GL/upscalers/fsr1/fsr_pass.cpp b/rpcs3/Emu/RSX/GL/upscalers/fsr1/fsr_pass.cpp index cfd7b1cc08..75e2d3f3db 100644 --- a/rpcs3/Emu/RSX/GL/upscalers/fsr1/fsr_pass.cpp +++ b/rpcs3/Emu/RSX/GL/upscalers/fsr1/fsr_pass.cpp @@ -152,7 +152,7 @@ namespace gl void rcas_pass::configure() { // 0 is actually the sharpest with 2 being the chosen limit. Each progressive unit 'halves' the sharpening intensity. - auto cas_attenuation = 2.f - (g_cfg.video.vk.rcas_sharpening_intensity / 50.f); + auto cas_attenuation = 2.f - (g_cfg.video.rcas_sharpening_intensity / 50.f); FsrRcasCon(&m_constants_buf[0], cas_attenuation); } } diff --git a/rpcs3/Emu/RSX/Overlays/HomeMenu/overlay_home_menu_settings.cpp b/rpcs3/Emu/RSX/Overlays/HomeMenu/overlay_home_menu_settings.cpp index c0e3a72b6f..34999eb775 100644 --- a/rpcs3/Emu/RSX/Overlays/HomeMenu/overlay_home_menu_settings.cpp +++ b/rpcs3/Emu/RSX/Overlays/HomeMenu/overlay_home_menu_settings.cpp @@ -44,7 +44,7 @@ namespace rsx add_dropdown(&g_cfg.video.output_scaling, localized_string_id::HOME_MENU_SETTINGS_VIDEO_OUTPUT_SCALING); if (g_cfg.video.renderer == video_renderer::vulkan && g_cfg.video.output_scaling == output_scaling_mode::fsr) { - add_unsigned_slider(&g_cfg.video.vk.rcas_sharpening_intensity, localized_string_id::HOME_MENU_SETTINGS_VIDEO_RCAS_SHARPENING, " %", 1); + add_unsigned_slider(&g_cfg.video.rcas_sharpening_intensity, localized_string_id::HOME_MENU_SETTINGS_VIDEO_RCAS_SHARPENING, " %", 1); } add_checkbox(&g_cfg.video.stretch_to_display_area, localized_string_id::HOME_MENU_SETTINGS_VIDEO_STRETCH_TO_DISPLAY); diff --git a/rpcs3/Emu/RSX/VK/upscalers/fsr1/fsr_pass.cpp b/rpcs3/Emu/RSX/VK/upscalers/fsr1/fsr_pass.cpp index 869dba6fa9..fbd4e868f9 100644 --- a/rpcs3/Emu/RSX/VK/upscalers/fsr1/fsr_pass.cpp +++ b/rpcs3/Emu/RSX/VK/upscalers/fsr1/fsr_pass.cpp @@ -176,7 +176,7 @@ namespace vk void rcas_pass::configure(const vk::command_buffer& cmd) { // 0 is actually the sharpest with 2 being the chosen limit. Each progressive unit 'halves' the sharpening intensity. - auto cas_attenuation = 2.f - (g_cfg.video.vk.rcas_sharpening_intensity / 50.f); + auto cas_attenuation = 2.f - (g_cfg.video.rcas_sharpening_intensity / 50.f); FsrRcasCon(&m_constants_buf[0], cas_attenuation); vkCmdPushConstants(cmd, m_program->layout(), VK_SHADER_STAGE_COMPUTE_BIT, 0, push_constants_size, m_constants_buf); diff --git a/rpcs3/Emu/system_config.h b/rpcs3/Emu/system_config.h index 8ccf91db0e..1f13629878 100644 --- a/rpcs3/Emu/system_config.h +++ b/rpcs3/Emu/system_config.h @@ -177,6 +177,7 @@ struct cfg_root : cfg::node cfg::_enum output_scaling{ this, "Output Scaling Mode", output_scaling_mode::bilinear, true }; cfg::_bool record_with_overlays{ this, "Record With Overlays", true, true }; cfg::_bool disable_hardware_texel_remapping{ this, "Disable Hardware ColorSpace Remapping", false, true }; + cfg::uint<0, 100> rcas_sharpening_intensity{ this, "FidelityFX CAS Sharpening Intensity", 50, true }; struct node_vk : cfg::node { @@ -187,7 +188,6 @@ struct cfg_root : cfg::node cfg::_bool force_primitive_restart{ this, "Force primitive restart flag" }; cfg::_enum exclusive_fullscreen_mode{ this, "Exclusive Fullscreen Mode", vk_exclusive_fs_mode::unspecified}; cfg::_bool asynchronous_texture_streaming{ this, "Asynchronous Texture Streaming 2", false }; - cfg::uint<0, 100> rcas_sharpening_intensity{ this, "FidelityFX CAS Sharpening Intensity", 50, true }; cfg::_enum asynchronous_scheduler{ this, "Asynchronous Queue Scheduler", vk_gpu_scheduler_mode::safe }; cfg::uint<256, 65536> vram_allocation_limit{ this, "VRAM allocation limit (MB)", 65536, false }; cfg::_bool use_rebar_upload_heap{ this, "Use Re-BAR for GPU uploads", true, false }; diff --git a/rpcs3/rpcs3qt/emu_settings_type.h b/rpcs3/rpcs3qt/emu_settings_type.h index 67238571d3..73ed86e267 100644 --- a/rpcs3/rpcs3qt/emu_settings_type.h +++ b/rpcs3/rpcs3qt/emu_settings_type.h @@ -317,11 +317,11 @@ inline static const std::map settings_location { emu_settings_type::DisableAsyncHostMM, { "Video", "Disable Asynchronous Memory Manager"}}, { emu_settings_type::RecordWithOverlays, { "Video", "Record With Overlays"}}, { emu_settings_type::DisableHWTexelRemapping, { "Video", "Disable Hardware ColorSpace Remapping"}}, + { emu_settings_type::FsrSharpeningStrength, { "Video", "FidelityFX CAS Sharpening Intensity"}}, // Vulkan { emu_settings_type::VulkanAsyncTextureUploads, { "Video", "Vulkan", "Asynchronous Texture Streaming 2"}}, { emu_settings_type::VulkanAsyncSchedulerDriver, { "Video", "Vulkan", "Asynchronous Queue Scheduler"}}, - { emu_settings_type::FsrSharpeningStrength, { "Video", "Vulkan", "FidelityFX CAS Sharpening Intensity"}}, { emu_settings_type::ExclusiveFullscreenMode, { "Video", "Vulkan", "Exclusive Fullscreen Mode"}}, { emu_settings_type::UseReBAR, { "Video", "Vulkan", "Use Re-BAR for GPU uploads"}}, From 60eb1ce2ecf95cd9de7f7ebf54eb234de9fd4960 Mon Sep 17 00:00:00 2001 From: Ani Date: Sun, 22 Feb 2026 15:38:42 +0100 Subject: [PATCH 162/175] config: Fix naming of Asynchronous Texture Streaming Rename from 'Asynchronous Texture Streaming 2' to 'Asynchronous Texture Streaming' --- rpcs3/Emu/system_config.h | 2 +- rpcs3/rpcs3qt/emu_settings_type.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rpcs3/Emu/system_config.h b/rpcs3/Emu/system_config.h index 1f13629878..89da08e884 100644 --- a/rpcs3/Emu/system_config.h +++ b/rpcs3/Emu/system_config.h @@ -187,7 +187,7 @@ struct cfg_root : cfg::node cfg::_bool force_fifo{ this, "Force FIFO present mode" }; cfg::_bool force_primitive_restart{ this, "Force primitive restart flag" }; cfg::_enum exclusive_fullscreen_mode{ this, "Exclusive Fullscreen Mode", vk_exclusive_fs_mode::unspecified}; - cfg::_bool asynchronous_texture_streaming{ this, "Asynchronous Texture Streaming 2", false }; + cfg::_bool asynchronous_texture_streaming{ this, "Asynchronous Texture Streaming", false }; cfg::_enum asynchronous_scheduler{ this, "Asynchronous Queue Scheduler", vk_gpu_scheduler_mode::safe }; cfg::uint<256, 65536> vram_allocation_limit{ this, "VRAM allocation limit (MB)", 65536, false }; cfg::_bool use_rebar_upload_heap{ this, "Use Re-BAR for GPU uploads", true, false }; diff --git a/rpcs3/rpcs3qt/emu_settings_type.h b/rpcs3/rpcs3qt/emu_settings_type.h index 73ed86e267..b2014dd7bc 100644 --- a/rpcs3/rpcs3qt/emu_settings_type.h +++ b/rpcs3/rpcs3qt/emu_settings_type.h @@ -320,7 +320,7 @@ inline static const std::map settings_location { emu_settings_type::FsrSharpeningStrength, { "Video", "FidelityFX CAS Sharpening Intensity"}}, // Vulkan - { emu_settings_type::VulkanAsyncTextureUploads, { "Video", "Vulkan", "Asynchronous Texture Streaming 2"}}, + { emu_settings_type::VulkanAsyncTextureUploads, { "Video", "Vulkan", "Asynchronous Texture Streaming"}}, { emu_settings_type::VulkanAsyncSchedulerDriver, { "Video", "Vulkan", "Asynchronous Queue Scheduler"}}, { emu_settings_type::ExclusiveFullscreenMode, { "Video", "Vulkan", "Exclusive Fullscreen Mode"}}, { emu_settings_type::UseReBAR, { "Video", "Vulkan", "Use Re-BAR for GPU uploads"}}, From b24524fc753ca4584a1da93d25dc0bda21852e13 Mon Sep 17 00:00:00 2001 From: Ani Date: Sun, 22 Feb 2026 15:40:12 +0100 Subject: [PATCH 163/175] config: Fix naming of SPU XFloat Accuracy Rename from 'XFloat Accuracy' to 'SPU XFloat Accuracy' --- rpcs3/Emu/system_config.h | 2 +- rpcs3/rpcs3qt/emu_settings_type.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rpcs3/Emu/system_config.h b/rpcs3/Emu/system_config.h index 89da08e884..3d7dba8798 100644 --- a/rpcs3/Emu/system_config.h +++ b/rpcs3/Emu/system_config.h @@ -61,7 +61,7 @@ struct cfg_root : cfg::node cfg::uint<0, 16> mfc_transfers_shuffling{ this, "MFC Commands Shuffling Limit", 0 }; cfg::uint<0, 10000> mfc_transfers_timeout{ this, "MFC Commands Timeout", 0, true }; cfg::_bool mfc_shuffling_in_steps{ this, "MFC Commands Shuffling In Steps", false, true }; - cfg::_enum spu_xfloat_accuracy{ this, "XFloat Accuracy", xfloat_accuracy::approximate, false }; + cfg::_enum spu_xfloat_accuracy{ this, "SPU XFloat Accuracy", xfloat_accuracy::approximate, false }; cfg::_int<-1, 14> ppu_128_reservations_loop_max_length{ this, "Accurate PPU 128-byte Reservation Op Max Length", 0, true }; // -1: Always accurate, 0: Never accurate, 1-14: max accurate loop length cfg::_int<-64, 64> stub_ppu_traps{ this, "Stub PPU Traps", 0, true }; // Hack, skip PPU traps for rare cases where the trap is continueable (specify relative instructions to skip) cfg::_bool precise_spu_verification{ this, "Precise SPU Verification", false }; // Disables use of xorsum based spu verification if enabled. diff --git a/rpcs3/rpcs3qt/emu_settings_type.h b/rpcs3/rpcs3qt/emu_settings_type.h index b2014dd7bc..a3e47fe733 100644 --- a/rpcs3/rpcs3qt/emu_settings_type.h +++ b/rpcs3/rpcs3qt/emu_settings_type.h @@ -241,7 +241,7 @@ inline static const std::map settings_location { emu_settings_type::AccurateClineStores, { "Core", "Accurate Cache Line Stores"}}, { emu_settings_type::AccurateRSXAccess, { "Core", "Accurate RSX reservation access"}}, { emu_settings_type::FIFOAccuracy, { "Core", "RSX FIFO Fetch Accuracy"}}, - { emu_settings_type::XFloatAccuracy, { "Core", "XFloat Accuracy"}}, + { emu_settings_type::XFloatAccuracy, { "Core", "SPU XFloat Accuracy"}}, { emu_settings_type::MFCCommandsShuffling, { "Core", "MFC Commands Shuffling Limit"}}, { emu_settings_type::SetDAZandFTZ, { "Core", "Set DAZ and FTZ"}}, { emu_settings_type::SPUBlockSize, { "Core", "SPU Block Size"}}, From 0bb6299e39c904722e5297fd46dc6f423a86dc4d Mon Sep 17 00:00:00 2001 From: Ani Date: Sun, 22 Feb 2026 15:41:55 +0100 Subject: [PATCH 164/175] ui: Specify Anti-Aliasing as MSAA --- rpcs3/rpcs3qt/settings_dialog.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpcs3/rpcs3qt/settings_dialog.ui b/rpcs3/rpcs3qt/settings_dialog.ui index 76a418298d..7a5e8b6865 100644 --- a/rpcs3/rpcs3qt/settings_dialog.ui +++ b/rpcs3/rpcs3qt/settings_dialog.ui @@ -473,7 +473,7 @@ - Anti-Aliasing + Anti-Aliasing (MSAA) From bc58dff7154ad014df6ea606bc3c77af141bec84 Mon Sep 17 00:00:00 2001 From: Ani Date: Sun, 22 Feb 2026 15:52:48 +0100 Subject: [PATCH 165/175] ui: Rename depth buffers to depth buffer Removes ambiguity between config and ui --- rpcs3/rpcs3qt/settings_dialog.ui | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rpcs3/rpcs3qt/settings_dialog.ui b/rpcs3/rpcs3qt/settings_dialog.ui index 7a5e8b6865..4ced973883 100644 --- a/rpcs3/rpcs3qt/settings_dialog.ui +++ b/rpcs3/rpcs3qt/settings_dialog.ui @@ -2674,14 +2674,14 @@ - Read Depth Buffers + Read Depth Buffer - Write Depth Buffers + Write Depth Buffer From 7712584bd492796784d971edf11c4dffb1f6a317 Mon Sep 17 00:00:00 2001 From: AniLeo Date: Sun, 8 Mar 2026 10:46:51 +0100 Subject: [PATCH 166/175] ui: Merge exit/boot game dialog options --- rpcs3/rpcs3qt/settings_dialog.cpp | 5 ----- rpcs3/rpcs3qt/settings_dialog.ui | 9 +-------- rpcs3/rpcs3qt/tooltips.h | 3 +-- 3 files changed, 2 insertions(+), 15 deletions(-) diff --git a/rpcs3/rpcs3qt/settings_dialog.cpp b/rpcs3/rpcs3qt/settings_dialog.cpp index 66f0ae3476..d206a40de8 100644 --- a/rpcs3/rpcs3qt/settings_dialog.cpp +++ b/rpcs3/rpcs3qt/settings_dialog.cpp @@ -2165,7 +2165,6 @@ settings_dialog::settings_dialog(std::shared_ptr gui_settings, std SubscribeTooltip(ui->cb_custom_colors, tooltips.settings.custom_colors); SubscribeTooltip(ui->cb_show_welcome, tooltips.settings.show_welcome); SubscribeTooltip(ui->cb_show_exit_game, tooltips.settings.show_exit_game); - SubscribeTooltip(ui->cb_show_boot_game, tooltips.settings.show_boot_game); SubscribeTooltip(ui->cb_show_pkg_install, tooltips.settings.show_pkg_install); SubscribeTooltip(ui->cb_show_pup_install, tooltips.settings.show_pup_install); SubscribeTooltip(ui->cb_show_obsolete_cfg_dialog, tooltips.settings.show_obsolete_cfg); @@ -2273,7 +2272,6 @@ settings_dialog::settings_dialog(std::shared_ptr gui_settings, std ui->cb_show_welcome->setChecked(m_gui_settings->GetValue(gui::ib_show_welcome).toBool()); ui->cb_show_exit_game->setChecked(m_gui_settings->GetValue(gui::ib_confirm_exit).toBool()); - ui->cb_show_boot_game->setChecked(m_gui_settings->GetValue(gui::ib_confirm_boot).toBool()); ui->cb_show_pkg_install->setChecked(m_gui_settings->GetValue(gui::ib_pkg_success).toBool()); ui->cb_show_pup_install->setChecked(m_gui_settings->GetValue(gui::ib_pup_success).toBool()); ui->cb_show_obsolete_cfg_dialog->setChecked(m_gui_settings->GetValue(gui::ib_obsolete_cfg).toBool()); @@ -2305,9 +2303,6 @@ settings_dialog::settings_dialog(std::shared_ptr gui_settings, std connect(ui->cb_show_exit_game, &QCheckBox::toggled, [this](bool checked) { m_gui_settings->SetValue(gui::ib_confirm_exit, checked); - }); - connect(ui->cb_show_boot_game, &QCheckBox::toggled, [this](bool checked) - { m_gui_settings->SetValue(gui::ib_confirm_boot, checked); }); connect(ui->cb_show_pkg_install, &QCheckBox::toggled, [this](bool checked) diff --git a/rpcs3/rpcs3qt/settings_dialog.ui b/rpcs3/rpcs3qt/settings_dialog.ui index 4ced973883..3b6a5b5776 100644 --- a/rpcs3/rpcs3qt/settings_dialog.ui +++ b/rpcs3/rpcs3qt/settings_dialog.ui @@ -4007,14 +4007,7 @@ - Show Exit Game Dialog - - - - - - - Show Boot Game Dialog + Show Exit Game Confirmation diff --git a/rpcs3/rpcs3qt/tooltips.h b/rpcs3/rpcs3qt/tooltips.h index b56e093dff..def114e4dd 100644 --- a/rpcs3/rpcs3qt/tooltips.h +++ b/rpcs3/rpcs3qt/tooltips.h @@ -216,8 +216,7 @@ public: const QString tty_limit = tr("Sets the maximum amount of blocks that the TTY can display.\nThis usually equals the number of lines.\nSet 0 in order to remove the limit."); const QString stylesheets = tr("Changes the overall look of RPCS3.\nChoose a stylesheet and click Apply to change between styles."); const QString show_welcome = tr("Shows the initial welcome screen upon starting RPCS3."); - const QString show_exit_game = tr("Shows a confirmation dialog when the game window is being closed."); - const QString show_boot_game = tr("Shows a confirmation dialog when a game was booted while another game is running."); + const QString show_exit_game = tr("Shows a confirmation dialog when the game window is being closed and when a game was booted while another game is running."); const QString show_pkg_install = tr("Shows a dialog when packages were installed successfully."); const QString show_pup_install = tr("Shows a dialog when firmware was installed successfully."); const QString show_obsolete_cfg = tr("Shows a dialog when obsolete settings were found."); From 86f453f67702b150c922f2379f138e7142e86b98 Mon Sep 17 00:00:00 2001 From: AniLeo Date: Sun, 8 Mar 2026 11:02:20 +0100 Subject: [PATCH 167/175] ui: Merge pkg/pup install dialog options --- rpcs3/rpcs3qt/settings_dialog.cpp | 5 ----- rpcs3/rpcs3qt/settings_dialog.ui | 9 +-------- rpcs3/rpcs3qt/tooltips.h | 3 +-- 3 files changed, 2 insertions(+), 15 deletions(-) diff --git a/rpcs3/rpcs3qt/settings_dialog.cpp b/rpcs3/rpcs3qt/settings_dialog.cpp index d206a40de8..add8f3e798 100644 --- a/rpcs3/rpcs3qt/settings_dialog.cpp +++ b/rpcs3/rpcs3qt/settings_dialog.cpp @@ -2166,7 +2166,6 @@ settings_dialog::settings_dialog(std::shared_ptr gui_settings, std SubscribeTooltip(ui->cb_show_welcome, tooltips.settings.show_welcome); SubscribeTooltip(ui->cb_show_exit_game, tooltips.settings.show_exit_game); SubscribeTooltip(ui->cb_show_pkg_install, tooltips.settings.show_pkg_install); - SubscribeTooltip(ui->cb_show_pup_install, tooltips.settings.show_pup_install); SubscribeTooltip(ui->cb_show_obsolete_cfg_dialog, tooltips.settings.show_obsolete_cfg); SubscribeTooltip(ui->cb_show_same_buttons_dialog, tooltips.settings.show_same_buttons); SubscribeTooltip(ui->cb_show_restart_hint, tooltips.settings.show_restart_hint); @@ -2273,7 +2272,6 @@ settings_dialog::settings_dialog(std::shared_ptr gui_settings, std ui->cb_show_welcome->setChecked(m_gui_settings->GetValue(gui::ib_show_welcome).toBool()); ui->cb_show_exit_game->setChecked(m_gui_settings->GetValue(gui::ib_confirm_exit).toBool()); ui->cb_show_pkg_install->setChecked(m_gui_settings->GetValue(gui::ib_pkg_success).toBool()); - ui->cb_show_pup_install->setChecked(m_gui_settings->GetValue(gui::ib_pup_success).toBool()); ui->cb_show_obsolete_cfg_dialog->setChecked(m_gui_settings->GetValue(gui::ib_obsolete_cfg).toBool()); ui->cb_show_same_buttons_dialog->setChecked(m_gui_settings->GetValue(gui::ib_same_buttons).toBool()); ui->cb_show_restart_hint->setChecked(m_gui_settings->GetValue(gui::ib_restart_hint).toBool()); @@ -2308,9 +2306,6 @@ settings_dialog::settings_dialog(std::shared_ptr gui_settings, std connect(ui->cb_show_pkg_install, &QCheckBox::toggled, [this](bool checked) { m_gui_settings->SetValue(gui::ib_pkg_success, checked); - }); - connect(ui->cb_show_pup_install, &QCheckBox::toggled, [this](bool checked) - { m_gui_settings->SetValue(gui::ib_pup_success, checked); }); connect(ui->cb_show_obsolete_cfg_dialog, &QCheckBox::toggled, [this](bool checked) diff --git a/rpcs3/rpcs3qt/settings_dialog.ui b/rpcs3/rpcs3qt/settings_dialog.ui index 3b6a5b5776..eefc4e499c 100644 --- a/rpcs3/rpcs3qt/settings_dialog.ui +++ b/rpcs3/rpcs3qt/settings_dialog.ui @@ -4014,14 +4014,7 @@ - Show PKG Installation Dialog - - - - - - - Show PUP Installation Dialog + Show PKG/PUP Installation Result diff --git a/rpcs3/rpcs3qt/tooltips.h b/rpcs3/rpcs3qt/tooltips.h index def114e4dd..6152506c1d 100644 --- a/rpcs3/rpcs3qt/tooltips.h +++ b/rpcs3/rpcs3qt/tooltips.h @@ -217,8 +217,7 @@ public: const QString stylesheets = tr("Changes the overall look of RPCS3.\nChoose a stylesheet and click Apply to change between styles."); const QString show_welcome = tr("Shows the initial welcome screen upon starting RPCS3."); const QString show_exit_game = tr("Shows a confirmation dialog when the game window is being closed and when a game was booted while another game is running."); - const QString show_pkg_install = tr("Shows a dialog when packages were installed successfully."); - const QString show_pup_install = tr("Shows a dialog when firmware was installed successfully."); + const QString show_pkg_install = tr("Shows a dialog when packages and firmware were installed successfully."); const QString show_obsolete_cfg = tr("Shows a dialog when obsolete settings were found."); const QString show_same_buttons = tr("Shows a dialog in the game pad configuration when the same button was assigned twice."); const QString show_restart_hint = tr("Shows a dialog when RPCS3 is ready to restart after an update."); From 5a921bca462516029a0c171f624382bdf7460f88 Mon Sep 17 00:00:00 2001 From: AniLeo Date: Sun, 8 Mar 2026 12:11:54 +0100 Subject: [PATCH 168/175] ui: Allow toggling pad navigation on BSD --- rpcs3/rpcs3qt/settings_dialog.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/rpcs3/rpcs3qt/settings_dialog.cpp b/rpcs3/rpcs3qt/settings_dialog.cpp index add8f3e798..d25d3ad9fb 100644 --- a/rpcs3/rpcs3qt/settings_dialog.cpp +++ b/rpcs3/rpcs3qt/settings_dialog.cpp @@ -2177,7 +2177,6 @@ settings_dialog::settings_dialog(std::shared_ptr gui_settings, std SubscribeTooltip(ui->cb_global_pad_navigation, tooltips.settings.global_navigation); ui->cb_pad_navigation->setChecked(m_gui_settings->GetValue(gui::nav_enabled).toBool()); ui->cb_global_pad_navigation->setChecked(m_gui_settings->GetValue(gui::nav_global).toBool()); -#if defined(_WIN32) || defined(__linux__) || defined(__APPLE__) connect(ui->cb_pad_navigation, &QCheckBox::toggled, [this](bool checked) { m_gui_settings->SetValue(gui::nav_enabled, checked); @@ -2186,9 +2185,6 @@ settings_dialog::settings_dialog(std::shared_ptr gui_settings, std { m_gui_settings->SetValue(gui::nav_global, checked); }); -#else - ui->gb_gui_pad_input->setEnabled(false); -#endif // Discord: SubscribeTooltip(ui->useRichPresence, tooltips.settings.use_rich_presence); From 9bdacc64aae4e390200563859cf1a8a1f27e6b6a Mon Sep 17 00:00:00 2001 From: AniLeo Date: Sun, 8 Mar 2026 12:12:56 +0100 Subject: [PATCH 169/175] config: Enable pad navigation by default --- rpcs3/rpcs3qt/gui_settings.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpcs3/rpcs3qt/gui_settings.h b/rpcs3/rpcs3qt/gui_settings.h index 21a46259c2..bdc6401031 100644 --- a/rpcs3/rpcs3qt/gui_settings.h +++ b/rpcs3/rpcs3qt/gui_settings.h @@ -315,7 +315,7 @@ namespace gui const gui_save sc_shortcuts = gui_save(sc, "shortcuts", QVariantMap()); - const gui_save nav_enabled = gui_save(navigation, "pad_input_enabled", false); + const gui_save nav_enabled = gui_save(navigation, "pad_input_enabled", true); const gui_save nav_global = gui_save(navigation, "allow_global_pad_input", false); } From 67a67feb68426c72850f26813ecfea63f636ba54 Mon Sep 17 00:00:00 2001 From: AniLeo Date: Sun, 8 Mar 2026 12:42:28 +0100 Subject: [PATCH 170/175] ui: A-Z order advanced tab settings --- rpcs3/rpcs3qt/settings_dialog.ui | 98 ++++++++++++++++---------------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/rpcs3/rpcs3qt/settings_dialog.ui b/rpcs3/rpcs3qt/settings_dialog.ui index eefc4e499c..8e6c64e1d3 100644 --- a/rpcs3/rpcs3qt/settings_dialog.ui +++ b/rpcs3/rpcs3qt/settings_dialog.ui @@ -2414,13 +2414,6 @@ Core - - - - Debug Console Mode - - - @@ -2431,7 +2424,7 @@ - Accurate RSX reservation access + Accurate RSX Reservation Access @@ -2442,6 +2435,27 @@ + + + + Anti-Cheat Savestates Mode + + + + + + + Debug Console Mode + + + + + + + Delay each odd MFC Command + + + @@ -2471,30 +2485,16 @@ - + - Delay each odd MFC Command - - - - - - - Anti-Cheat Savestates Mode + Silence All Logs - SPU-Compatible Savestates Mode - - - - - - - Silence All Logs + SPU Compatible Savestates Mode @@ -2672,30 +2672,16 @@ - + - Read Depth Buffer + Allow Host GPU Labels (Experimental) - + - Write Depth Buffer - - - - - - - Read Color Buffers - - - - - - - Handle RSX memory tiling + Disable MSL Fast Math @@ -2707,16 +2693,30 @@ - + - Allow Host GPU Labels (Experimental) + Force Hardware MSAA Resolve - + - Force Hardware MSAA Resolve + Handle RSX Memory Tiling + + + + + + + Read Depth Buffer + + + + + + + Read Color Buffers @@ -2728,9 +2728,9 @@ - + - Disable MSL Fast Math + Write Depth Buffer From 90ebc7f319b81ae2dae419ed5af7a720c089dbf6 Mon Sep 17 00:00:00 2001 From: AniLeo Date: Sun, 8 Mar 2026 13:07:11 +0100 Subject: [PATCH 171/175] ui: Move Accurate DFMA to debug --- rpcs3/rpcs3qt/settings_dialog.ui | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/rpcs3/rpcs3qt/settings_dialog.ui b/rpcs3/rpcs3qt/settings_dialog.ui index 8e6c64e1d3..601ea5ec92 100644 --- a/rpcs3/rpcs3qt/settings_dialog.ui +++ b/rpcs3/rpcs3qt/settings_dialog.ui @@ -2414,13 +2414,6 @@ Core - - - - Accurate DFMA - - - @@ -4334,6 +4327,13 @@ Core + + + + Accurate DFMA + + + From e2a26f937fc0c1a670ad28fcc7f106b40624b804 Mon Sep 17 00:00:00 2001 From: AniLeo Date: Sun, 8 Mar 2026 13:09:33 +0100 Subject: [PATCH 172/175] ui: Move PPU Non-Java Fixup to debug --- rpcs3/rpcs3qt/settings_dialog.ui | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/rpcs3/rpcs3qt/settings_dialog.ui b/rpcs3/rpcs3qt/settings_dialog.ui index 601ea5ec92..5e38fd787d 100644 --- a/rpcs3/rpcs3qt/settings_dialog.ui +++ b/rpcs3/rpcs3qt/settings_dialog.ui @@ -2463,13 +2463,6 @@ - - - - PPU Non-Java Mode Fixup - - - @@ -4397,6 +4390,13 @@ + + + + PPU Non-Java Mode Fixup + + + From 8587fca5dbffd3334e52feb237df06ccd9b0b7db Mon Sep 17 00:00:00 2001 From: AniLeo Date: Sun, 8 Mar 2026 13:36:27 +0100 Subject: [PATCH 173/175] ui: Move SPU Loop Detection to advanced --- rpcs3/rpcs3qt/settings_dialog.ui | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/rpcs3/rpcs3qt/settings_dialog.ui b/rpcs3/rpcs3qt/settings_dialog.ui index 5e38fd787d..f663266206 100644 --- a/rpcs3/rpcs3qt/settings_dialog.ui +++ b/rpcs3/rpcs3qt/settings_dialog.ui @@ -181,22 +181,6 @@ - - - - Additional Settings - - - - - - Enable SPU loop detection - - - - - - @@ -2463,6 +2447,13 @@ + + + + Enable SPU loop detection + + + From 315f88b0e48e97f7e6d0dc007e4ff6b509f37577 Mon Sep 17 00:00:00 2001 From: Ani Date: Mon, 9 Mar 2026 16:50:45 +0100 Subject: [PATCH 174/175] ui: Split overlay settings, A-Z order emulator tab settings --- rpcs3/rpcs3qt/settings_dialog.ui | 149 ++++++++++++++++--------------- 1 file changed, 79 insertions(+), 70 deletions(-) diff --git a/rpcs3/rpcs3qt/settings_dialog.ui b/rpcs3/rpcs3qt/settings_dialog.ui index f663266206..30100b7935 100644 --- a/rpcs3/rpcs3qt/settings_dialog.ui +++ b/rpcs3/rpcs3qt/settings_dialog.ui @@ -2922,16 +2922,16 @@ - + - Exit RPCS3 when process finishes + Enable GameMode - + - Pause emulation on RPCS3 focus loss + Exit RPCS3 when process finishes @@ -2949,6 +2949,13 @@ + + + + Pause emulation on RPCS3 focus loss + + + @@ -2956,69 +2963,6 @@ - - - - Show trophy popups - - - - - - - Show RPCN popups - - - - - - - Show shader compilation hint - - - - - - - Show PPU compilation hint - - - - - - - Show autosave/autoload hint - - - - - - - Show analog limiter toggle hint - - - - - - - Show pressure intensity toggle hint - - - - - - - Show mouse and keyboard toggle hint - - - - - - - Show capture hints - - - @@ -3033,17 +2977,82 @@ + + + + + + + Overlay Settings + + - Record with overlays + Record and screenshot with overlays - + - Enable GameMode + Show analog limiter toggle hint + + + + + + + Show autosave/autoload hint + + + + + + + Show capture hints + + + + + + + Show mouse and keyboard toggle hint + + + + + + + Show netplay popups + + + + + + + Show pressure intensity toggle hint + + + + + + + Show PPU compilation hint + + + + + + + Show shader compilation hint + + + + + + + Show trophy popups From 5714eb0ba537dc7efe5b50e9e6d08f8e66b12dfb Mon Sep 17 00:00:00 2001 From: Ani Date: Sat, 14 Mar 2026 17:44:50 +0100 Subject: [PATCH 175/175] config/ui: Unify Shader Mode values Have the same values between UI and Config for easing automatic configuration --- rpcs3/Emu/system_config_types.cpp | 6 +++--- rpcs3/rpcs3qt/emu_settings.cpp | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/rpcs3/Emu/system_config_types.cpp b/rpcs3/Emu/system_config_types.cpp index 7c9c5ef592..beb13db4d5 100644 --- a/rpcs3/Emu/system_config_types.cpp +++ b/rpcs3/Emu/system_config_types.cpp @@ -522,9 +522,9 @@ void fmt_class_string::format(std::string& out, u64 arg) { switch (value) { - case shader_mode::recompiler: return "Shader Recompiler"; - case shader_mode::async_recompiler: return "Async Shader Recompiler"; - case shader_mode::async_with_interpreter: return "Async with Shader Interpreter"; + case shader_mode::recompiler: return "Legacy Recompiler (single-threaded)"; + case shader_mode::async_recompiler: return "Async Recompiler (multi-threaded)"; + case shader_mode::async_with_interpreter: return "Async Recompiler with Shader Interpreter"; case shader_mode::interpreter_only: return "Shader Interpreter only"; } diff --git a/rpcs3/rpcs3qt/emu_settings.cpp b/rpcs3/rpcs3qt/emu_settings.cpp index c686394c10..22cf9b4032 100644 --- a/rpcs3/rpcs3qt/emu_settings.cpp +++ b/rpcs3/rpcs3qt/emu_settings.cpp @@ -1054,9 +1054,9 @@ QString emu_settings::GetLocalizedSetting(const QString& original, emu_settings_ case emu_settings_type::ShaderMode: switch (static_cast(index)) { - case shader_mode::recompiler: return tr("Legacy (single threaded)", "Shader Mode"); - case shader_mode::async_recompiler: return tr("Async (multi threaded)", "Shader Mode"); - case shader_mode::async_with_interpreter: return tr("Async with Shader Interpreter", "Shader Mode"); + case shader_mode::recompiler: return tr("Legacy Recompiler (single-threaded)", "Shader Mode"); + case shader_mode::async_recompiler: return tr("Async Recompiler (multi-threaded)", "Shader Mode"); + case shader_mode::async_with_interpreter: return tr("Async Recompiler with Shader Interpreter", "Shader Mode"); case shader_mode::interpreter_only: return tr("Shader Interpreter only", "Shader Mode"); } break;